Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Alternative to this for loop.

Subject: Alternative to this for loop.

From: Pstrang Rzekle

Date: 16 Jun, 2011 15:26:02

Message: 1 of 4

Can anyone come up with code equivalent to the following for loop?

m1 should be a 100x3 matrix.

  for n = 1:100
      d(n,:) = (acos((m1(n,1).*m1(:,1)) ...
                        + (m1(n,2).*m1(:,2)) ...
                        + (m1(n,3).*m1(:,3))))';
  end

The result d should be a 100x100 matrix. Each row of d is the distance to all the other indices of m1. Obviously the distance to itself is 0, so I would expect diagonal marching zeros down the matrix.

Big thanks!

Subject: Alternative to this for loop.

From: TideMan

Date: 16 Jun, 2011 21:03:04

Message: 2 of 4

On Jun 17, 3:26 am, "Pstrang Rzekle"
<pstrang_w_rzekle.re.move.th....@yahoo.com> wrote:
> Can anyone come up with code equivalent to the following for loop?
>
> m1 should be a 100x3 matrix.
>
>   for n = 1:100
>       d(n,:) = (acos((m1(n,1).*m1(:,1)) ...
>                         + (m1(n,2).*m1(:,2)) ...
>                         + (m1(n,3).*m1(:,3))))';
>   end
>
> The result d should be a 100x100 matrix.  Each row of d is the distance to all the other indices of m1. Obviously the distance to itself is 0, so I would expect diagonal marching zeros down the matrix.
>
> Big thanks!

Think about it..............
You have a 100x3 matrix and you want to generate a 100x100 matrix by
combining it with itself.
Looking at your equation above, do you see a pattern?
If I define m2=m1'; then your equation can be re-written:
    m1(:,1)* m2(1,n) + m1(:,2)*m2(2,n) + m1(:,3)*m2(3,n)
so the inside indexes match.
Now, vectorising that is obvious, isn't it?

Subject: Alternative to this for loop.

From: Roger Stafford

Date: 16 Jun, 2011 22:14:07

Message: 3 of 4

"Pstrang Rzekle" wrote in message <itd7aa$hl2$1@newscl01ah.mathworks.com>...
> Can anyone come up with code equivalent to the following for loop?
>
> m1 should be a 100x3 matrix.
>
> for n = 1:100
> d(n,:) = (acos((m1(n,1).*m1(:,1)) ...
> + (m1(n,2).*m1(:,2)) ...
> + (m1(n,3).*m1(:,3))))';
> end
>
> The result d should be a 100x100 matrix. Each row of d is the distance to all the other indices of m1. Obviously the distance to itself is 0, so I would expect diagonal marching zeros down the matrix.
>
> Big thanks!
- - - - - - - - - -
  There is a numerical weakness in this method of computing angles. When the unit vectors are very nearly in the same or opposite directions, there is a loss of accuracy. Just look at a plot of 'acos' between -1 and +1 to see why.

  For that reason I tend to recommend a more robust formula using the 'atan2' function, even though it is more expensive computation-wise:

 a = atan2(norm(cross(v1,v2)),dot(v1,v2));

It has the added advantage that neither v1 nor v2 need be normalized.

  To apply this to your case you could either use for loops or do the following:

 n = size(m1,1);
 [I,J] = ndgrid(1:n);
 d = reshape(sqrt(sum(cross(m1(I,:),m1(J,:),2).^2,2)),n,n);
 d = atan2(d,m1*m1.');

  Note that you cannot expect the diagonal to have exact zeros since there will inevitably be rounding errors in the calculations.

Roger Stafford

Subject: Alternative to this for loop.

From: Pstrang Rzekle

Date: 16 Jun, 2011 22:58:04

Message: 4 of 4

Thank you gentlemen! I'll do some testing now.

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us