"Karl " <karllandheer@gmail.com> wrote in message <iu0994$j6$1@newscl01ah.mathworks.com>...
> Hi, I want to average the values in a 616x1216 matrix in rings around a particular point (the centre of the ring, obviously). Currently my program uses a few nested loops to do this but it is very slow as I know MATLAB was not built for iteration. Here is my current code:
>
> j0 = 305;
> k0 = 672;
> rmin = Rod(RodCounter)j0+1; %the smallest radius possible is defined by the region directly above the tungsten bar
> for r = rmin:NumberOfRows/2; %loop through all possible circles
> i = i +1;
> %calculate the angle this scatter is taking place at using the
> %knowledge that the pixel is 200um by 200um
> angles(i) = atan((r*pixelSize)/targetDistance)*180/pi;
> t(i) = i;
> A(i) = 0.;
> C(i) = 0;
> for j = 1:NumberOfRows
> for k = 1:NumberOfColumns
> R_sq = (jj0)^2 + (kk0)^2;
> if (R_sq > (r1)^2 & (R_sq <= r^2))
> if (j > Rod(RodCounter))  (j < Rod(1))
> A(i) = A(i) + RawImage(j,k);
> C(i) = C(i) + 1;
> H(i) = A(i)./C(i); %normalize the scatter profile
> end
> end
> end
> end
> end
>
> I was wondering how I would go about doing this without the loops? Something using mesh grid seems possible but I don't quite understand the function (and have read the help on it)... Or really how it would apply to my case. Anyways thank you very much for your help!
           
The inefficiency in this code is not due to the for loops per se. It is mainly caused by a shortcoming in the algorithmic procedure used. For each possible ring you are scanning over the entire matrix to pick up pixels that lie in just that particular ring. It would be far more efficient to scan over the matrix only once and for each pixel decide which ring it lies in, continually updating an entire vector of A and C values for all possible rings as you go. In other words when you are dealing with the jth row and kth column do this:
r = floor(sqrt((jj0)^2 + (kk0)^2))
That tells you which ring the pixel lies in and the appropriate A and C can then be updated. When you are finished, then A can be divided by C. Of course you need some kind of safeguards to avoid choosing rings that run off the edge of the matrix.
Actually it is possible to vectorize even this procedure to avoid the remaining two for loops, but my guess is that the major gain in efficiency will come from avoiding the scanning of the entire matrix for each ring.
One reminder: when using for loops always preallocate any vectors you plan to use therein so as to avoid causing them to grow one element per trip through the loop(s). That makes the memory allocator in matlab unhappy and recalcitrant.
Roger Stafford
