Combinations of array rows with exclusion

3 views (last 30 days)
I've a question that maybe has an "easy" solution. I've searched (and I still am) but haven't found yet. Can anyone could help me or point out a solution for this?
I've a result of fixed pairs (latitude longitude) for a n points / rows (usually 8 or 10 max number of points/pair of rows), now i need to combine this fixed pairs from n-1,n-2,...n-k, until n-k = 4 (minimum number of points/pair of rows). For instance, If have an array of 6x2:
[20 10;20 15;20 30;22 15;25 10; 30 10], i would need to have a first combination set of 5 rows leaving one out, then select another 5 set of rows, leaving other row out and including the first one, until every 5 set of possible row selections have been made and stored in another array with all combinations. Then, from the initail 6 row array set, I would need to select 4 rows of pairs, in the same manner i did for the selection and combination of 5 rows, until every possible 4 rows pairs of 6 have been combined.
Each row pair / point is fixed. Lat long of point 1 must always be the same lat long pair.
Maybe this is hard to do, but if anyone has some kind of solution for this it would be very helpfull
Thank you so much,
Pedro
  2 Comments
Jorg Woehl
Jorg Woehl on 8 Mar 2021
Hi Pedro, if I understand you correctly you want to create all possible subarrays of your initial n-by-2 array, creating n (n-1)-by-2 arrays by leaving one row out. For example, [row1; row2; row3; row4; row5; row6] becomes [row2; row3; row4; row5; row6] or [row1; row3; row4; row5; row6] or ..., and so on.
You then said these subarrays are to be "stored in another array with all previous combinations" - how exactly? Do you want them all to be concatenated into one 30-by-2 array, one after another? Or stored in a 5-by-2-by-6 array?
Pedro Miguel Silva Pinto
Pedro Miguel Silva Pinto on 8 Mar 2021
Edited: Pedro Miguel Silva Pinto on 8 Mar 2021
Hi Jorg Woehl,
Thank you so much for the reply. Yes you are right. The combinations should be stored as sub-arrays, for instance in another variable. The important thing is that n-1 combinations (for instance, groups of 5 rows combinations taken from a 6 row array) should be stored in sub-array of multipls of 5 rows (in case of the 5 group combinations) and n-2 combinations of rows (in the case of groups of 4 rows combination should be stored in another subarray).
It is expected that, n-1 group of rows combination should have less combinations than the n-2 group of combinations, unttil n-k = 4. Yes, the n (n-1)-by-2, could be stored in 3 Dimension array, like 5x2 multiples on [5*m , : , 1 ] and the combination of 4 groups in [4*m , : , 2]. Like in general it should be something like [(n-1)*m, : , 1:(n-1)], being m the number of possible combinations of each (n-1) group without repeating a group.
I don't know if manage to explaine myself.
But, the principle like you said: [ row1; row2; row3; row4; row5; row6] becomes [row2; row3; row4; row5; row6] or [row1; row3; row4; row5; row6] or ..., and so on. Then is [row1 row2 row3 row4], [row1 row2 row3 row5], [row1 row2 row3 row6], [row2 row3 row4 row5], [row2 row3 row4 row6],..., all the possible combinations rows without reapeating a group of 4 rows or 5 rows etc,
It doesn't matter the order of combinations, it only matters that the group of rows doesn't repeat itself.
Thank you so much

Sign in to comment.

Accepted Answer

Jorg Woehl
Jorg Woehl on 8 Mar 2021
Edited: Jorg Woehl on 8 Mar 2021
This answer does not have any of the duplicates that are present in my previous answer:
A = [20 10;20 15;20 30;22 15;25 10; 30 10];
k = size(A,1)-4; % max. number of rows to delete
r = [];
for i = 1:k
r = rowsToDelete(size(A,1), r);
for j = 1:size(r,2)
subA = A;
subA(r{j},:) = []; % delete the rows stored in r{j}
cellArr{i}(:,:,j) = subA ; % ... and store the result in B
end
end
function newr = rowsToDelete(n,r)
if isempty(r)
% set rows-to-delete to 1, 2, ..., n
for i = 1:n
newr{i} = i;
end
else
idx = 1;
for i = 1:size(r,2)
% add another row to delete to existing ones
for j = r{i}(end)+1:n
newr{idx} = [r{i}, j];
idx = idx+1;
end
end
end
end
  2 Comments
Pedro Miguel Silva Pinto
Pedro Miguel Silva Pinto on 9 Mar 2021
Edited: Pedro Miguel Silva Pinto on 10 Mar 2021
Hi Jorg Woehl,
Thank you for all the work you did. Amazing. Your math is right. We can check it here:
C(n,r)=(nr)=n! / (r!(nr)!) , using n=8 and taking out of the "bag" combinations of 6 rows (r=6), we will then have C(n,r)=C(8,6) = =8! / (6!(8−6)!) = =8! / (6!×2!) = 28
If then take 5 rows (r=5)
C(n,r)=C(8,5)==8! / (5!(85)!)=8! / (5!×3!)= 56
https://www.calculatorsoup.com/calculators/discretemathematics/combinations.php
Perfect! Thanks for all the help, your code is working nicely. For me though, I'm learning that I'm not getting a better GDOP taking out satellites from the initial epcoh by epoch set. Learning the hard way! Nevertheless, I'm learning and I couldn't do it without your help!! I think someone said that learning is also failure...
Thank you so much and all the best for your brilliant life!
Jorg Woehl
Jorg Woehl on 9 Mar 2021
Edited: Jorg Woehl on 10 Mar 2021
Hi Pedro,
Thank you for your kind words. It is good to hear that you got everything working, even if the result is not what you had hoped for. But that's what research is all about (I am a research scientist myself).
I have received an email where you asked about how to access the combinations in the cell array, which I wanted to briefly answer for the benefit of other users (even though you have found the solution):
cellArr{1} contains six 5-by-2 matrices that can be accessed with cellArr{1}(:,:,1) through cellArr{1}(:,:,6). Same for the fifteen 4-by-2 matrices contained in cellArr{2}, you can access them at cellArr{2}(:,:,i), where i is an index from 1 to 15 or size(cellArr{2},3), and so on.

Sign in to comment.

More Answers (1)

Jorg Woehl
Jorg Woehl on 8 Mar 2021
OK, so how about this?
A = [20 10;20 15;20 30;22 15;25 10; 30 10];
cellArr{1} = deleteOneRow(A);
for i = 2:size(A,1)-4
cellArr{i} = deleteOneRow(cellArr{i-1});
end
function B = deleteOneRow(A)
rows = size(A,1);
cols = size(A,2);
matrices = size(A,3);
B = NaN([rows-1, cols, rows*matrices]);
for n=1:matrices
for row=1:rows
subA = A(:,:,n); % read one matrix from the array
subA(row,:) = []; % delete one row from it
B(:,:,(n-1)*size(A,1)+row) = subA; % ... and store it in B
end
end
end
The output is contained in the cell array cellArr. cellArr{1} gives you all possible (n-1)-by-2 matrices, cellArr{2} all possible (n-2)-by-2 matrices, and so on. This also works with A being larger than 6-by-2, such as 7-by-2, 8-by-2 etc.
  4 Comments
Pedro Miguel Silva Pinto
Pedro Miguel Silva Pinto on 8 Mar 2021
Edited: Pedro Miguel Silva Pinto on 8 Mar 2021
uau i didn't noticed that. I was just setting me up to include your code (with some testing) in all code picture to see how it was working. Thank you for being so kind and helpfull. If you aren't in the matlab team, you could/deserve very well to be. Nevertheless thank you again and matlab team for this help center.
Jorg Woehl
Jorg Woehl on 8 Mar 2021
Almost done... will post later tonight (after a meeting).

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!