开发者

Can this piece of matlab script be vectorized further?

开发者 https://www.devze.com 2023-01-07 10:51 出处:网络
So what I am trying to do with this code is find all pixels on a line of an image that are below a certain threshold. The problem, however, is that this code is executed in a double for loop (yeah I k

So what I am trying to do with this code is find all pixels on a line of an image that are below a certain threshold. The problem, however, is that this code is executed in a double for loop (yeah I know :( ), once for each pixel, so it's very slow. I'm wondering if there's anything else I can do.

Some tips would be great, as I'm pretty new to MATLAB optimization, and I know only the basics (try not to use loops, or call scripts many times in inner functions, etc). If this doesn't work out, I might have to resort to MEX files, and that'll be harder to maintain for the other researchers in my group. Thank you!

for y = 1:y_len
    for x = 1:x_len
        %//...do stuff to calc slope and offset for the line, 
                %//this can be vectorized pretty easily.

        yIndices = xIndices.*slope + offset;
        yIndices = round(yIndices);

        yIndices = yIndices + 1;
        xIndices = xIndices + 1;
        valid_points = (yIndices <= 308) & (yIndices > 0);

        %this line is bottle necking----------------------------------------
        valid_points = yIndices(valid_points)+(xIndices(valid_points)-1)*308;
        %-------------------------------------------------------------------

        valid_points = valid_points(phaseMask_R(valid_points));
        t_vals = abs(phase_R(valid_points)-currentPhase);
        point_vals = [XsR(valid_points);YsR(valid_points)] - 1;
        matchedPtsCoordsR = point_vals(:,(t_vals<phaseThreshold) |(abs(192-t_vals)<phaseThreshold));

        matchedIndex = size(matchedPtsCoordsR,2);
        if(matchedIndex ==0)
          continue
        end

        centersMinMaxR = zeros(1,matchedIndex);
        cmmIndexR = 1;
        for a = 1:matchedInde开发者_开发知识库x;
          if(a==1)
            avgPosition = matchedPtsCoordsR(:,a);
            centersMinMaxR(1,1) =1;
          else
            currentPosition = matchedPtsCoordsR(:,a);


            %also very slow----------------------------------------------
            distance = sum(abs(currentPosition-avgPosition));
            %------------------------------------------------------------
            if(distance>4) % We are now likely in a different segment.
              centersMinMaxR(2,cmmIndexR) = a-1;
              cmmIndexR = cmmIndexR + 1;
              centersMinMaxR(1,cmmIndexR) = a;
            end
            avgPosition = matchedPtsCoordsR(:,a);
          end
        end

        centersMinMaxR(2,cmmIndexR) = a;
        centersR = round(sum(centersMinMaxR)/2);

        %//...do stuff with centersR
                    %//I end up concatenating all the centersR into a 
                    %//large vector arrray with the start and end of 
                    %//each segment.


First off, MatLab Profiler is your best friend and it I assume you know about it because you know what line is bottle necking.

A quick fix to remove the double loop is to use the : command. Instead of using a double loop, you can use a single loop but calculate along an entire dimension for each row or column index. For a simple example:

m = magic(2);
slope = 5;

m =
     1     3
     4     2

m(1,:) * slope  =
     5    15

m(:,1) * slope =
     5
    20

Instead of using jagged arrays, use sparse arrays. Matlab has built-in support for them:

Matlab Create Sparse Array

Matlab Sparse Matrix Operations

UPDATE

In regard to the pro-cons of using a sparse vs normal array: Sparse vs Normal Array Matlab

Sparse matrices are a true boon for the person who uses truly sparse matrices, but 25% non-zeros is simply not "sparse" enough for any gain in most cases.

Look for more updates as I have more time to review your code :p

0

精彩评论

暂无评论...
验证码 换一张
取 消