How to simplify for loop in MATLAB?

1 回表示 (過去 30 日間)
JIANG YUN
JIANG YUN 2015 年 11 月 27 日
コメント済み: Stepp Gyogi 2015 年 12 月 1 日
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

採用された回答

Stepp Gyogi
Stepp Gyogi 2015 年 11 月 27 日
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 件のコメント
Stepp Gyogi
Stepp Gyogi 2015 年 12 月 1 日
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.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeGenetic Algorithm についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by