Finding all possible row combinations of a matrix that add to zero

Hello,
I'm looking for a general way to find all possible row combinations of a matrix that add to zero.
For instance, for the matrix
A = [-1 0 0 ; 1 0 0 ; 1 -1 0 ; 0 1 -1 ; 0 1 -1; 0 0 1];
the following 6 row combinations would all sum to zero
A(1,:)+A(2,:)
A(1,:)+A(3,:)+A(4,:)+A(6,:)
A(1,:)+A(3,:)+A(5,:)+A(6,:)
-A(2,:)+A(3,:)+A(4,:)+A(6,:)
-A(2,:)+A(3,:)+A(5,:)+A(6,:)
-A(4,:)+A(5,:)
Does MATLAB have any built-in functions that can help me do this? Generating all possible row combinations and testing to see which ones sum to zero seems like it would be extremely computationally intensive.
Thanks,
Kevin

 Réponse acceptée

Azzi Abdelmalek
Azzi Abdelmalek le 21 Fév 2013
Modifié(e) : Azzi Abdelmalek le 21 Fév 2013
Edit2
A = [-1 0 0 ; 1 0 0 ; 1 -1 0 ; 0 1 -1 ; 0 1 -1; 0 0 1];
n=size(A,1);
idx=logical(npermutek([0 1],n));
p=size(idx,1);
out=cell(p,1);
for k=1:p
out{k}=sum(A(idx(k,:),:),1);
end
You can get you sum in a matrix 647x3
M=cell2mat(out)

5 commentaires

I'm confused by your answer. I just ran this code. What is supposed to be the variable here that stores all possible row combinations summing to zero? I don't see any variable like that after running the code.
out{1} is the first sum
out{2} is the second sum
.
.
.
out{64} is the last sum
Sorry there is typo in
out{k}=sum(A(idx(k,:),:));
Look at the edited answer
There is another error, it's
sum(A(idx(k,:),:),1)
instead of
sum(A(idx(k,:),:)
Look at the second Edit
Kevin Bachovchin
Kevin Bachovchin le 21 Fév 2013
Modifié(e) : Kevin Bachovchin le 21 Fév 2013
Ok, it works now, but the code doesn't seem to pick up on solutions that involve subtraction.
The following should also be solutions -A(2,:)+A(3,:)+A(4,:)+A(6,:)
-A(2,:)+A(3,:)+A(5,:)+A(6,:)
-A(4,:)+A(5,:)

Connectez-vous pour commenter.

Plus de réponses (4)

Azzi Abdelmalek
Azzi Abdelmalek le 21 Fév 2013
Modifié(e) : Azzi Abdelmalek le 21 Fév 2013
Ok try this
Edit
A = [-1 0 0 ;1 0 0; 1 -1 0 ; 0 1 -1 ; 0 1 -1; 0 0 1];
n=size(A,1)
idx1=npermutek([0 -1 1],n);
p=size(idx1,1);
out=cell(p,1);
for k=1:p
out{k}=sum(bsxfun(@times,A,idx1(k,:)'),1);
end
M=cell2mat(out)
find(~any(M,2))

10 commentaires

I'm not sure what the code is doing wrong, but out has 17 rows that are [0 0 0]. It should only have the 6 solutions I mentioned above.
Are you sur of your result?
Look at the different combinaisons that give 0;
idx1(find(~any(M,2)),:)
each row corresponds to one combinaison
Kevin Bachovchin
Kevin Bachovchin le 21 Fév 2013
Modifié(e) : Kevin Bachovchin le 21 Fév 2013
I suppose it could be looked at that since
A(1,:)+A(2,:) = 0
-A(4,:)+A(5,:) = 0
then A(1,:)+A(2,:)-A(4,:)+A(5,:)=0 for example.
However, for my specific purpose, I would not like sums of individual solutions to also be solutions.
In the same regard, I would also not like solutions that are negatives of each other for my specific purpose.
There is just one individual which is equal to zero, the first one.
I'm not sure what you mean. When you add the first and second rows together for instance, that forms [0 0 0].
Yes I know, what do you mean?
I mean that since A1+A2 and -A4+A5 are solutions, it is undesirable for my specific purpose to also have -Al-A2, A4-A5, A1+A2-A4+A5, -Al-A2-A4+A5, A1+A2+A4-A5, -Al-A2+A4-A5 returned as solutions as well.
Ok, You did not specify that in your question. You should give all information in your question to avoid wasting of time.
Sorry, the issue with sums of solutions didn't occur to me until I saw it. Seems like there is no difference in the result of the code from before though. Still 17 elements in find(~any(M,2)).

Connectez-vous pour commenter.

Try this
A = [-1 0 0 ;1 0 0; 1 -1 0 ; 0 1 -1 ; 0 1 -1; 0 0 1];
n=size(A,1)
idx1=npermutek([0 -1 1],n);
p=size(idx1,1);
out=cell(p,1);
for k=1:p
out{k}=sum(bsxfun(@times,A,idx1(k,:)'),1);
end
M=cell2mat(out)
ii=find(~any(M,2))
idx2=idx1(ii,:)
for k=1:size(idx2,1)
jj{k}=find(idx2(k,:))
end
for k=1:numel(jj)
iddx{k}=find(cellfun(@(x) isequal(x,jj{k}),jj))
ee(k)=iddx{k}(1)
end
result=idx2(unique(ee),:)

1 commentaire

This fixed the problem of both positives and negatives being solutions (ie, A1+A2 and -A1-A2). One thing it did not fix is sums of individual solutions being solutions (for instance, since -A1-A2 and -A4+A5 are both solutions, then -A1-A2-A4+A5 is also given as a solution but this solution is unwanted for my specific purpose because it corresponds to a non-physical solution for my application.)

Connectez-vous pour commenter.

Azzi Abdelmalek
Azzi Abdelmalek le 22 Fév 2013
Modifié(e) : Azzi Abdelmalek le 22 Fév 2013
Try this code
A = [-1 0 0 ;1 0 0; 1 -1 0 ; 0 1 -1 ; 0 1 -1; 0 0 1];
n=size(A,1)
idx1=npermutek([0 -1 1],n);
p=size(idx1,1);
out=cell(p,1);
for k=1:p
out{k}=sum(bsxfun(@times,A,idx1(k,:)'),1);
end
M=cell2mat(out);
ii=find(~any(M,2));
idx2=idx1(ii,:);
for k=1:size(idx2,1);
jj{k}=find(idx2(k,:));
end
for k=1:numel(jj);
iddx{k}=find(cellfun(@(x) isequal(x,jj{k}),jj));
ee(k)=iddx{k}(1);
end
result=idx2(unique(ee),:);
n=size(result,1);
test=0;
ii=1;
while test==0
ii=ii+1;
a=find(result(ii,:));
c=result(ii,a);
e=result(:,a);
f=find(ismember(e,c,'rows'));
f(1)=[];
if ~isempty(f);
result(f,:)=[];
n=n-1;
end
if ii==n-1
test=1;
end
end
result

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by