Consider three row vectors in Matlab, A
, B
, C
, each with size 1xJ
. I want to construct a matrix D
of size Kx3
listing every triplets (a,b,c)
such that:
a
is the position inA
ofA(a)
.b
is the position inB
ofB(b)
.A(a)-B(b)
is an element ofC
.c
is the position inC
ofA(a)-B(b)
.A(a)
andB(b)
are different fromInf
,-Inf
.
For example,
A=[-3 3 0 Inf -Inf];
B=[-2 2 0 Inf -Inf];
C=[Inf -Inf -1 1 0];
D=[1 1 3; %-3-(-2)=-1
2 2 4; % 3-2=1
3 3 5]; % 0-0=0
I would like this code to be efficient, because in my real example I have to repeat it many times.
This question relates to my previous question here, but now I'm looking for the positions of the elements.
CodePudding user response:
You can use combvec
(or any number of alternatives) to get all pairings of indices a
and b
for the corresponding arrays A
and B
. Then it's simply a case of following your criteria
- Find the differences
- Check which differences are in
C
- Remove elements you don't care about
Like so:
% Generate all index pairings
D = combvec( 1:numel(A), 1:numel(B) ).';
% Calculate deltas
delta = A(D(:,1)) - B(D(:,2));
delta = delta(:); % make it a column
% Get delta index in C (0 if not present)
[~,D(:,3)] = ismember(delta,C);
% If A or B are inf then the delta is Inf or NaN, remove these
idxRemove = isinf(delta) | isnan(delta) | D(:,3) == 0;
D(idxRemove,:) = [];
For your example, this yields the expected results from the question.
You said that A
and B
are at most 7 elements long, so you have up to 49 pairings to check. This isn't too bad, but readers should be careful that the pairings can grow quickly for larger inputs.