How to vectorize 2 nested for loop with one complex condition in the inner loop?

Octave calculations is too slow specially when you deal with scientific calculations that can span a very very large matrix, even just iterating. I have to vectorize it to speed up the calculation.

Vectorizing a 1xn matrix would just be easy by following

for i = 1:n
if (a(i) > 5)
a(i) -= 20
endif
endfor


https://octave.org/doc/v4.0.1/Basic-Vectorization.html

But I dont have any clue when the matrix becomes nxm. My sample code is shown below.

segs = 1000000;
r_int = 100;
r_ot = 2000;
x = linspace (0, 1000, segs);
y = linspace (0, -1000, segs);
[xx, yy] = meshgrid (x, y);
circ = xx.*yy;
circ_matrix = zeros(segs,segs);

#this needs vectorization
for j = 1:segs
for i = 1:segs
if((r_int<=circ(i,j)) &&(circ(i,j)<=r_ot))
circ_matrix(i,j)=1;
endif;
endfor;
endfor;


I have marked the code that needs vectorization

Some things tried:

circ_matrix((r_int<=circ) &&(circ<=r_ot))=1;


but did not work

• Should 'rint' be replaced by 'r_int' on line 2? – user7440 Jan 13 '20 at 21:02
• Do you want $y$ to be negative? – user7440 Jan 13 '20 at 21:03

rmid = 0.5*(r_int + r_ot);
rlen = 0.5*(r_ot - r_int);
cc = double(abs(circ - rmid) <= rlen);

• It solved it, can you pls provide an explanation? – Jones G Jan 13 '20 at 21:25
• As mentioned in the comment below, a boolean is converted in 0 or 1. So the test is checking whether any value in $circ$ belongs to the interval [r_int, r_ot]. Whenever you have a test inside your loop(s) to vectorize, the expression proposed for 'cc' ask Matlab to test on a matrix --- i.e. to vectorize the test. Matlab will perform the tests component-wise. – user7440 Jan 13 '20 at 21:55

Another approach is to use the fact that true is equal to $$1$$ and false is equal to $$0$$. If both conditions in the if statement are met, the result is $$1$$, otherwise it's $$0$$.

segs = 1000000;
r_int = 100;
r_ot = 2000;
x = linspace (0, 1000, segs);
y = linspace (0, -1000, segs);
[xx, yy] = meshgrid (x, y);
circ = xx.*yy;

circ_matrix = ( r_int<=circ ) .* ( circ <=r_ot );
$$$$
`
• that worked as well! – Jones G Jan 13 '20 at 21:55