1
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Should 'rint' be replaced by 'r_int' on line 2? $\endgroup$ – user7440 Jan 13 at 21:02
  • $\begingroup$ Do you want $y$ to be negative? $\endgroup$ – user7440 Jan 13 at 21:03
2
$\begingroup$
rmid = 0.5*(r_int + r_ot); 
rlen = 0.5*(r_ot - r_int);
cc = double(abs(circ - rmid) <= rlen);
$\endgroup$
  • $\begingroup$ It solved it, can you pls provide an explanation? $\endgroup$ – Jones G Jan 13 at 21:25
  • $\begingroup$ 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. $\endgroup$ – user7440 Jan 13 at 21:55
2
$\begingroup$

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 );
```
$\endgroup$
  • $\begingroup$ that worked as well! $\endgroup$ – Jones G Jan 13 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.