MATLAB Answers

Cartesian product of list

21 views (last 30 days)
Hello,
I have 4 vectors A, B, C, D with
A=1:6; B=1:5; C=1:10; D=1:4; % in real case, the max values i.e 6, 5, 10 and 4, are not always equal to those values but always integers
ADBC = allcomb(A,D,B,C); % each row corresponds to an experimental condition involving one of each parameter A, B, C, D
Now, I want to reorganize ADBC elements (row) in order to build a new matrix ABCD = allcomb(A,B,C,D);
As an example, I have ADBC = [2 2 3 1], which means A=2, B=3, C=1 and D=2;
The question is what is the row of ABCD corresponding to the same condition (A=2, B=3, C=1, D=2) if it was organized as ABCD, i.e [2 3 1 2] ?
Here is the answer :
A=1:6; B=1:5; C=1:10; D=1:4; % in real case, the max values i.e 6, 5, 10 and 4, are not always equal to those values but always integers
ABCD = allcomb(A,B,C,D); % https://fr.mathworks.com/matlabcentral/fileexchange/10064-allcomb-varargin
ADBC = allcomb(A,D,B,C); % each row corresponds to an experimental condition involving one of each parameter A, B, C, D
i = 0; crush = 1;
while crush ~= 4 % because I seek for 4 values [i j k m]
i=i+1;
check = find(ADBC(i,:) == [2 2 3 1]); % in order "ADBC"
crush = length(check);
end
ADBC(i,:)
i % 271
i = 0; crush2 = 1;
while crush2 ~= 4 % because I seek for 4 values [i j k m]
i=i+1;
check2 = find(ABCD(i,:) == [2 3 1 2]); % after sorting ex1 elements in order"ABCD"
crush2 = length(check2);
end
ABCD(i,:)
i % 282
So I would like to rebuilt the transfer function between the known ADBC and the rebuilt ABCD.
So, I guess I should write a loop (from 1 to 6*5*10*4=1200) to scan each ADBC element (ex1), get the old position (271 in the example), then sort the element with respect to "ABCD" order, then get the new position in case of ABCD vector (282 in the example).
So ABCD(282) = ADBC(271).
Can anyone simplify this approach ?
How to generalize to any ACBD, ADBC, ABDC, ... (24 cases) to rebuild ABCD in any case ? ABCD is my goal.

  0 Comments

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 14 Jan 2019
This seems like a very odd thing to want to do, but it can be easily achieved with ismember:
[~, whereinADBC] = ismember(ABCD, ADBC, 'rows');

  3 Comments

Guillaume
Guillaume on 14 Jan 2019
comment by laurent jalabert mistakenly posted as an answer moved here:
Thank you Guillaume for your valuable help.
yes I know it is odd, but my overall problem is much more complex (I have already 1300 lines of code). I am trying to discretize my problem in a sum of simple problems. So writing in the forum helps me a lot to formulate simple problems. Then in this logic, yes, I have some odd requests because any of my colleagues at work can help me. My problem is too specific. Then the forum is really a chance for me to share my problem, and try to improve.
I tried your code, but I found that the maximum value of whereinADBC is 1194, and I expected to be 1200. However, there are 1200 values in the vectors ADBC and ABCD. The size of whereinADBC is [1200 1]. I don't know why some value of whereinADBC are 0.
correction from my post : ABCD(282) = ADBC(271) is not correct. Replace it with :
--> ABCD(282,:) = ADBC(271,:)
Guillaume
Guillaume on 14 Jan 2019
I didn't think this through properly. The columns need to be reordered before calling ismember:
[~, whereinADBC] = ismember(ABCD(:, [1 4 2 3]), ADBC, 'rows')
laurent jalabert
laurent jalabert on 14 Jan 2019
Fantastic !!! Thank you Guillaume !!!

Sign in to comment.

More Answers (0)

Categories

Products


Release

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by