1

I have the following two matrices

c=[1 0 1.05 
   1 3 2.05
   1 6 2.52
   1 9 0.88
   2 0 2.58
   2 3 0.53
   2 6 3.69
   2 9 0.18
   3 0 3.22
   3 3 1.88
   3 6 3.98]

f=[1 6 3.9
   1 9 9.1
   1 12 9
   2 0 0.3
   2 3 0.9
   2 6 1.2
   2 9 2.5
   3 0 2.7]

And the final matrix should be

n=[1 6 2.52 3.9
   1 9 0.88 9.1
   2 0 2.58 0.3
   2 3 0.53 0.9
   2 6 3.69 1.2
   2 9 0.18 2.5
   3 0 3.22 2.7]

The code I used gives as a result only the last row of the previous matrix [n].

for j=1
  for i=1:rs1
     for k=1
          for l=1:rs2
               if f(i,j)==c(l,k) && f(i,j+1)==c(l,k+1)                 
                  n=[f(i,j),f(i,j+1),f(i,j+2), c(l,k+2)];
               end
          end
      end 
   end
 end

Can anyone help me on this? Is there something more simple?

Thanks in advance

5 Answers 5

1

You should learn to use set operations and avoid loops wherever possible. Here intersect could be extremely useful:

[u, idx_c, idx_f] = intersect(c(:, 1:2) , f(:, 1:2), 'rows');
n = [c(idx_c, :), f(idx_f, end)];

Explanation: by specifying the 'rows' flag, intersect finds the common rows in c and f, and their indices are given in idx_c and idx_f respectively. Use vector subscripting to extract matrix n.

Example

Let's use the example from your question:

c = [1 0 1.05;
     1 3 2.05
     1 6 2.52
     1 9 0.88
     2 0 2.58
     2 3 0.53
     2 6 3.69
     2 9 0.18
     3 0 3.22
     3 3 1.88
     3 6 3.98];

f = [1 6 3.9
     1 9 9.1
     1 12 9
     2 0 0.3
     2 3 0.9
     2 6 1.2
     2 9 2.5
     3 0 2.7];

[u, idx_c, idx_f] = intersect(c(:, 1:2) , f(:, 1:2), 'rows');
n = [c(idx_c, :), f(idx_f, end)];

This should yield the desired result:

n =
    1.0000    6.0000    2.5200    3.9000
    1.0000    9.0000    0.8800    9.1000
    2.0000         0    2.5800    0.3000
    2.0000    3.0000    0.5300    0.9000
    2.0000    6.0000    3.6900    1.2000
    2.0000    9.0000    0.1800    2.5000
    3.0000         0    3.2200    2.7000
Sign up to request clarification or add additional context in comments.

1 Comment

That's what I found two days ago and I used this function finally. Very helpful indeed. Thanks anyway!
1

According to this answer on Mathworks support you can use join from the statistics toolbox, specifically in your case, an inner join.

Unfortunately I don't have access to my computer with matlab on it, but give it a try and let us know how/if it works.

Comments

1

You can reduce the number of loops by comparing both the first and second columns of at once, then using the "all" function to only collapse the values if they both match. The following snippet replicates the "n" array you had provided.

n = [];
for r1 = 1:size(c, 1)
    for r2 = 1:size(f,1)
        if all(c(r1, [1 2]) == f(r2, [1 2]))
            n(end+1, 1:4) = [c(r1,:) f(r2,3)];
        end
    end    
end

Comments

1

If you insist on doing this in a loop you need to give n the proper dimension according to the loop counter you are using, or concatenate it to itself of each iteration (this can be very slow for big matrices). For example, writing:

for j=1
  for i=1:rs1
    for k=1
      for l=1:rs2
           m=m+1;
           if f(i,j)==c(l,k) && f(i,j+1)==c(l,k+1)                 
              n(m,:)=[f(i,j),f(i,j+1),f(i,j+2), c(l,k+2)];
           end
       end
    end 
  end
end

will save into the m-th row the for numbers when the loop reaches a counter value of m.

However, just be aware that this can be done also without a nested loop and an if condition, in a vectorized way. For example, instead of the condition if f(i,j)==c(l,k)... you can use ismember etc...

Comments

0

How about without any for loops at all (besides in native code)

mf = size(f,1);
mc = size(c,1);
a = repmat(c(:,1:2),1,mf);
b = repmat(reshape((f(:,1:2))',1,[]),mc,1);
match = a == b;
match = match(:, 1 : 2 : 2*mf) & match(:, 2 : 2 : 2*mf);

crows = nonzeros(diag(1:mc) * match);
frows = nonzeros(match * diag(1:mf));

n = [c(crows,:),f(frows,3)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.