How to simplify for loop in MATLAB?

2 views (last 30 days)
From the Image, there are 15 internal points(A-O) and 20 outline points(1-20).
I want to collect data from each internal point to each outline points. That means i will have 15*20=300 data at the end.
I'm going to use 4 for loop to do it, but I think can use Matrix and array to simplify it.
Is there any solutions?
Here is my code
the problem is
  1. My code only can calculate for example,first round on point(1,1). the result i get is not only from 1,1 to each outline points but also form (1,1)to every internal point. I only want the distance form internal to outline...
  2. Is there any easy way to simplify to program as i want to increase the length and width of rectangular later. what if the length is 11 and width is 6,there will be 1700 data at end.
for x = 1:(a-1);
for y = 1:(b-1);
for m = 0:a;
for n = 0:b;
ratio = (y - n) / (x - m);
sum = ((x - m)^ 2) +((y - n)^ 2);
l = sum^0.5;
X = sprintf('the distance between two points is %.2d', l);
disp(X);
if n == b
end;
end
end
end
end

Accepted Answer

Stepp Gyogi
Stepp Gyogi on 27 Nov 2015
Hi,
Imho, vectorization is the key to avoiding these 4 loops which might be very costly.
The following code works on my end, even for larger matrix sizes.
Enjoy,
Tepp.
a = 7; % in your example, a is the width
b = 5; % in your example, b is the height


% manually create the outer positions index row vector
outerIdx = [ b:-1:1, b+1:b:b*(a-2)+1, b*(a-1)+1:b*a, b*(a-1):-b:b*2 ];


% the inner positions index column vector is specific for the two first
% columns (up then down), after that it is repeated with an offset.
% we first create the specific pattern for positions A, B, C, D, E, F :
abcdefIdx = [ 2*b-1:-1:b+2; 2*b+2:3*b-1 ]';


% the pattern is repeated for columns 1 and 2, create a vector oneTwos that
% looks like [ 1, 2, 1, 2, 1, 2, ... ]
oneTwos = reshape( [ ones( 1, floor( ( a - 1 ) / 2 ) ); ones( 1, floor( ( a - 1 ) / 2 ) ) * 2 ], 1, a + mod( a, 2 ) - 2 );


% repeat the pattern and add to each column the offset
innerIdx = bsxfun( @plus, abcdefIdx( :, oneTwos( 1, 1 : a + mod( a, 2 ) - 2 ) ), kron( 0:(a + mod( a, 2 ) - 2)/2 - 1, 2 * [b b] ) );


% adjust width of pattern if a is odd because 2-column pattern was repeated
if ( mod( a, 2 ) )
innerIdx( :, end ) = [];
end


% make this innerIdx a column vector for use in bsxfun
innerIdx = innerIdx( : );


% initialize random points x and y along a [b x a] matrix
x = rand( b, a );
y = rand( b, a );


% we can now vectorize calculations for ratio and l :
ratio = bsxfun( @minus, y( innerIdx ), y( outerIdx ) ) ./ bsxfun( @minus, x( innerIdx ), x( outerIdx ) );
l = ( bsxfun( @minus, x( innerIdx ), x( outerIdx ) ) .^ 2 + bsxfun( @minus, y( innerIdx ), y( outerIdx ) ) .^ 2 ) .^ 0.5;


% both l and ratio are now a [( ( b-2 )*(a-2) ) x ( 2*b+2*( a-2 ) )] matrix
% we can either display the whole matrix
disp( l );
% or print a reduction (e.g. mean)
fprintf( 'the average distance between two points is %.2f\n', mean( mean( l ) ) );
% or plot the distribution (for fun ;-) )
figure;hist( l( : ), 20 );
  1 Comment
Stepp Gyogi
Stepp Gyogi on 1 Dec 2015
Hello,
I haven't heard back from you (but I see you posted a follow-up with another subject since then) : does this answer your question ?
Tepp.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!