简体   繁体   English

如何在Matlab中向量化'for'循环

[英]How to vectorize the 'for' loop in Matlab

I am writing a Matlab application that computes some sort of matrix. 我正在编写一个可计算某种矩阵的Matlab应用程序。 I'm trying to replace the for loops in my program with vector-based calculations, however, I'm stuck. 我试图用基于矢量的计算替换程序中的for循环,但是,我陷入了困境。

So far, I have figured that this simple sample part of code: 到目前为止,我已经弄清楚了这个简单的代码示例部分:

kernel = zeros(5,5,5);
offset = 3;
sig=1;

for x=-2:2
    for y=-2:2
        for z=-2:2
            IN = x.^2/(sig^2) + y.^2/(sig^2) + z.^2/(sig^2); 
            kernel(offset+x, offset+y, offset+z) = exp(-IN/2);
        end
    end
end

can be replaced with such a construction: 可以用这样的结构代替:

[x,y,z] = ndgrid(-2:2,-2:2,-2:2);
IN = x.^2/(sig^2) + y.^2/(sig^2) + z.^2/(sig^2); 
kernel = exp(-IN/2);

and give the same results. 并给出相同的结果。 But what if I need to make some small alteration: 但是,如果我需要做一些小改动怎么办:

kernel = zeros(5,5,5);
offset = 3;   
sig=1;

%sample 3x3 matrix
R=magic(3)/10; 

for x=-2:2
    for y=-2:2
        for z=-2:2

            % calculation of new x, y, z
            point = [x,y,z]*R;   

            IN = (point(1)^2 )/(sig^2) + (point(2)^2)/(sig^2) + (point(3)^2)/(sig^2);
            kernel(offset+x, offset+y, offset+z) = exp(-IN/2);
        end
    end
end

How can I speed up this construction? 我怎样才能加快施工速度? Can it be easily vectorized? 可以很容易地将其向量化吗? I'm quite new to Matlab, so I would appreciate any help. 我是Matlab的新手,所以我将不胜感激。 Thanks a lot! 非常感谢!

One option is to use arrayfun . 一种选择是使用arrayfun

sig=1;

%sample 3x3 matrix
R=magic(3)/10;

[x,y,z] = ndgrid(-2:2,-2:2,-2:2);
kernel = arrayfun(@(x, y, z) exp(-(norm([x,y,z]*R/sig)^2)/2), x,y,z);

Explanation: 说明:

arrayfun takes a function that acts on scalar input(s) to produce scalar output(s), as well as arrays of inputs to pass to the function. arrayfun一个作用在标量输入上的函数以产生标量输出,以及要传递给该函数的输入数组。 Then it loops over input arrays, runs your function on each one, and puts the output of each in the corresponding entry in the output matrix(-es). 然后,它遍历输入数组,在每个数组上运行您的函数,并将每个数组的输出放入输出矩阵(-es)的相应条目中。 So arrayfun basically does the nested looping that's slowing everything down for you. 因此, arrayfun基本上会执行嵌套循环,这会降低您的工作速度。

In this example, I also used a anonymous function (also called lambda function) to do the work in the inner-most loop. 在此示例中,我还使用了匿名函数 (也称为lambda函数)在最内层的循环中进行工作。 Since lambda functions need to be a single expression in Matlab, I had to rewrite the inner loop a little bit (using simple algebraic manipulations). 由于lambda函数必须是Matlab中的单个表达式,因此我不得不稍微重写一下内部循环(使用简单的代数操作)。 If you need to use arrayfun with a function that isn't easily expressed as a lambda, you can always write that function in a separate .m file and pass it to arrayfun . 如果需要将arrayfun与不容易表示为lambda的函数一起使用,则始终可以将该函数写入单独的.m文件中,并将其传递给arrayfun

EDIT: note that you don't have to pre-allocate kernel anymore, and you also don't need offset . 编辑:请注意,您不必再预先分配kernel ,也不需要offset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM