4

在学习了 Java 的基本编程之后,我发现对于当前的算法课程过渡到 MatLab 最困难的部分是避免循环。我知道在 MatLab 中有很多巧妙的方法可以对操作进行矢量化,但是我的思维是如此“卡在”循环思维中,以至于我发现很难直观地了解如何对代码进行矢量化。一旦向我展示了它是如何完成的,这对我来说很有意义,但我自己并不那么容易看到它。目前,我有以下代码用于查找拉格朗日插值中使用的重心权重:

function w = barycentric_weights(x);
% The function is used to find the weights of the
% barycentric formula based on a given grid as input.

n = length(x);
w = zeros(1,n);

% Calculating the weights
for i = 1:n
    prod = 1;
    for j = 1:n
        if i ~= j
            prod = prod*(x(i) - x(j));
        end
    end
    w(i) = prod;
end
w = 1./w;

我很确定在 MatLab 中一定有更聪明的方法可以做到这一点,但我就是想不出。如果有人有任何提示,我将非常感激:)。而我在 MatLab 中学习所有矢量化技巧的唯一方法就是看看它们是如何在各种场景中使用的,例如上述。

4

3 回答 3

3

在matlab中必须有创意以避免for循环:

[X,Y] =meshgrid(x,x)
Z = X - Y
w =1./prod(Z+eye(length(x)))
于 2012-10-25T21:48:57.907 回答
3

Kristian,有很多方法可以对代码进行矢量化。你已经得到了两个。(我同意 shakinfree 的观点:你应该始终考虑 1)以非矢量化形式运行需要多长时间(这样你就会知道通过矢量化可以节省多少时间);2)矢量化可能需要多长时间(这样你会更好地了解它是否值得你花时间;3)你会调用它多少次(再次:是否值得做);3) 可读性。正如 shakinfree 建议的那样,您不想在一年后回到您的代码并为您已实现的内容挠头。至少要确保你的评论很好。

但是在元级别上,当您决定需要通过矢量化来提高运行时性能时,首先从小(3x1 ?)数组开始,并确保您准确了解每次迭代发生的情况。然后,花一些时间阅读本文档,并点击相关链接:

http://www.mathworks.com/help/releases/R2012b/symbolic/code-performance.html

它将帮助您确定何时以及如何进行矢量化。

快乐的 MATLABbing!

布雷特

于 2012-10-25T22:08:32.940 回答
2

我可以看到矢量化的吸引力,但我经常问自己,当我在一个月后回到代码并不得不破译所有那些 repmat 乱码时,它实际上节省了多少时间。我认为您当前的代码干净清晰,除非性能非常关键,否则我不会乱用它。但在这里回答你的问题是我的最大努力:

function w = barycentric_weights_vectorized(x)
    n = length(x);
    w = 1./prod(eye(n) + repmat(x,n,1) - repmat(x',1,n),1);
end

希望有帮助!

我假设x这里是一个行向量。

于 2012-10-25T21:47:12.490 回答