如何在 matlab 中加快此函数评估?

计算科学 matlab 浮点
2021-12-16 19:11:44

现在我的代码有一半的运行时间是在很多点上评估一个大函数,每次评估大约需要 20 秒

该函数由一堆简单的操作组成,看起来像

Ux = ((1./72).*(x.^2+y.^2+z.^2).^(-5./2).*((-5).*x.*(4.*x.^4+3.*y.^2.*( ...
  y.^2+z.^2)+x.^2.*(7.*y.^2+z.^2)).*gx^2+(-10).*y.*(3.*x.^4+5.* ...
  x.^2.*y.^2+2.*y.^2.*(y.^2+z.^2)).*gx.*gy+5.*x.*(x.^4+3.*y.^2.* ...
  z.^2+x.^2.*(y.^2+z.^2)).*gy^2)); 

有什么办法可以加快速度吗?此外,它花费了 10% 的函数评估来连接这些大型矩阵

U =[Ux;Uy;Uz];

有什么技巧可以加快这类评估的速度吗?

2个回答

我看到您正在做一些冗余计算,例如y.^2+z.^2计算 4 次,y.^2z.^2计算 9-10 次。假设您有足够的内存,您可以定义一组变量y2=y.^2,并将一些计算成本推送到内存中。这将为您节省大量时间。z2=y.^2y2pz2=y2+z2;

MATLAB 是一种以列为主的语言。查看您的代码,UxUy似乎Uz是行向量,并且您将它们放在彼此之上U =[Ux;Uy;Uz];那会很慢。如果可能,定义U =[Ux',Uy',Uz'];应该减少连接所花费的时间。

你试过arrayfun吗?如果数组真的很大(顺便说一句,我们说的是多大?),分配所有这些临时数组可能会节省 arrayfun 的成本。

此外,您可以预先分配 U 并一次填充一个块,而不是连接。