【问题标题】:Simplifying function by removing a loop通过删除循环来简化功能
【发布时间】:2017-12-22 01:02:19
【问题描述】:

摆脱循环来简化函数的最佳方法是什么?

function Q = gs(f, a, b)

X(4) = sqrt((3+2*sqrt(6/5))/7);
X(3) = sqrt((3-2*sqrt(6/5))/7);
X(2) = -sqrt((3-2*sqrt(6/5))/7);
X(1) = -sqrt((3+2*sqrt(6/5))/7);

W(4) = (18-sqrt(30))/36;
W(3) = (18+sqrt(30))/36;
W(2) = (18+sqrt(30))/36;
W(1) = (18-sqrt(30))/36;
Q = 0;
for i = 1:4
   W(i) = (W(i)*(b-a))/2;
   X(i) = ((b-a)*X(i)+(b+a))/2;
   Q = Q + W(i) * f(X(i));
end


end

有没有办法使用任何类似矢量的解决方案来代替for 循环?

【问题讨论】:

  • (我对 matlab 的工作方式记忆模糊,但是)您可以制作 W 和 X 向量,然后将它们与所需的值相乘。
  • 我的回答有帮助吗?

标签: matlab loops optimization


【解决方案1】:

sum 是你这里最好的朋友。此外,声明一些常量和创建向量也很有用:

function Q = gs(f, a, b)
c = sqrt((3+2*sqrt(6/5))/7);
d = sqrt((3-2*sqrt(6/5))/7);
e = (18-sqrt(30))/36;
g = (18+sqrt(30))/36;

X = [-c -d d c];
W = [e g g e];

W = ((b - a) / 2) * W;
X = ((b - a)*X + (b + a)) / 2;
Q = sum(W .* f(X));

end

请注意,MATLAB 喜欢处理逐元素操作,因此关键是用在循环中看到的缩放因子缩放 WX 中的所有元素来替换最后的 for 循环.此外,使用元素乘法 (.*) 是关键。这当然假设f 可以以元素方式处理事情。如果没有,则无法避免 for 循环。

我强烈建议您在开始您的 MATLAB 之旅之前查阅有关元素操作的 MATLAB 教程:https://www.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html

【讨论】:

  • 在代码的第 5 行,您为 f 分配了一个标量数值,但在 end 之前的最后一行您写了 f(X) - 其中一个是错字吗?
  • @nekomatic 是的。谢谢。我改变了其中一个变量
  • 另外,如果f 只能处理标量输入,您仍然可以使用Q = sum(W .* arrayfun(f, X)) 避免显式循环。
  • @nekomatic 我仍然会使用循环。 arrayfun 性能较慢。 stackoverflow.com/q/12522888/3250829。对于这个小型阵列,您可能看不到它,但对于较大的阵列,您肯定会看到性能下降。
猜你喜欢
  • 1970-01-01
  • 2015-04-10
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 2016-10-25
相关资源
最近更新 更多