【问题标题】:Avoiding loops in MatLab code (barycentric weights)避免 MatLab 代码中的循环(重心权重)
【发布时间】:2012-10-16 03:46:34
【问题描述】:

在学习了 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 中学习所有矢量化技巧的唯一方法就是看看它们是如何在上述各种场景中使用的。

【问题讨论】:

    标签: matlab loops interpolation vectorization


    【解决方案1】:

    在matlab中必须要有创意才能避免for循环:

    [X,Y] =meshgrid(x,x)
    Z = X - Y
    w =1./prod(Z+eye(length(x)))
    

    【讨论】:

    • 非常感谢您的意见。我真的很感激:)
    【解决方案2】:

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

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

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

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

    MATLABbing 快乐!

    布雷特

    【讨论】:

    • 非常感谢您的意见,布雷特。我很感激!我还必须同意,阅读大量矢量化的 MatLab 代码通常会令人困惑且难以可视化。在 Java 上花了三个月的时间后,我可以阅读长段代码并理解其中的每一步,因为编程语言非常清晰和直观。我现在已经用 MatLab 工作了六个月,当其他人编写的代码包含许多矢量化技巧时,我仍然无法阅读它们。有时我真的希望 MatLab 能更快地使用循环,这样我就可以坚持下去!
    【解决方案3】:

    我可以看到矢量化的吸引力,但我经常问自己,当我在一个月后回到代码中并且必须破译所有那些 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 在这里是一个行向量。

    【讨论】:

    • 非常感谢!非常感谢您的意见。 Java 对我来说更直观,我猜 :)
    猜你喜欢
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多