评估循环中的变化函数

Evaluate a changing function in loop

我正在编写一个代码,在循环中生成一个函数 f。这个函数 f 在每个循环中都会发生变化,例如从 f = x + 2x 到 f = 3x^2 + 1(随机),我想在每个循环中的不同点评估 f。我已经尝试使用 subs、eval、matlabFunction 等,但它仍然 运行 很慢。你会如何以最有效的方式解决这样的问题?

这是我能做到的最快速度了。 ****matlabFunction 和 subs 比这慢。 下面的代码是我的解决方案,它是一个循环。在我较大的代码中,函数 f 和点 x0 在每个循环中都会发生变化,因此您可以想象为什么我希望它尽可能快地运行。如果有人可以解决这个问题并给我任何指示,我将不胜感激。如果我的编码很糟糕,请随时告诉我:D

x = sym('x',[2,1]);
f = [x(1)-x(1)cos(x(2)), x(2)-3x(2)^2*cos(x(1))];
J = jacobian(f,x);
x0 = [2,1];
N=length(x0); % Number of equations

%% Transform into string
fstr = map2mat(char(f));
Jstr = map2mat(char(J));

% replace every occurence of 'xi' with 'x(i)'
Jstr = addPar(Jstr,N);
fstr = addPar(fstr,N);

x = x0;

phi0 = eval(fstr)
J = eval(Jstr)

function str = addPar(str,N)

% pstr = addPar(str,N)
% Transforms every occurence of xi in str into x(i)
% N is the maximum value of i
% replace every occurence of xi with x(i)
% note that we do this backwards to avoid x10 being
% replaced with x(1)0

for i=N:-1:1
is = num2str(i);
xis = ['x' is];
xpis = ['x(' is ')'];
str = strrep(str,xis,xpis);
end

function r = map2mat(r)

% MAP2MAT Maple to MATLAB string conversion.
% Lifted from the symbolic toolbox source code
% MAP2MAT(r) converts the Maple string r containing
% matrix, vector, or array to a valid MATLAB string.
%
% Examples: map2mat(matrix([[a,b], [c,d]]) returns
% [a,b;c,d]
% map2mat(array([[a,b], [c,d]]) returns
% [a,b;c,d]
% map2mat(vector([[a,b,c,d]]) returns
% [a,b,c,d]
% Deblank.

r(findstr(r,' ')) = [];

% Special case of the empty matrix or vector
if strcmp(r,'vector([])') | strcmp(r,'matrix([])') | ...
strcmp(r,'array([])')
r = [];
else
% Remove matrix, vector, or array from the string.
r = strrep(r,'matrix([[','['); r = strrep(r,'array([[','[');
r = strrep(r,'vector([','['); r = strrep(r,'],[',';');
r = strrep(r,']])',']'); r = strrep(r,'])',']');
end

有几种方法可以大大提高解决此类问题的速度:

  • java GUI 前端使一切变慢。返回到版本 2010a 或更早版本。回到它基于 C 或 fortran 的时候。 MATLAB 脚本 运行 与将其放入 MATLAB "compiler".
  • 一样快
  • 如果您有 MatLab 编译器(或生成器,我忘了是哪个)但没有编码器,那么您可以处理您的代码并使其 运行 快几倍而无需修改代码。
  • 将其写入文件,然后将其作为函数调用。我这样做是为了改变 finite-element 表达式,如此庞大的丑陋数学使得 $y = 3x^2 +1$ 看起来很简单。因为它给了我稳定的速度提升。
  • 矢量化,矢量化,矢量化。它曾经可靠地提供 10 到 12 倍的速度提升。将其拉出循环。 java,我认为,通过让一切变得更慢来掩盖这一点。
  • 你有"profiled"你的功能来确保"eval"或类似的问题吗?如果你修复 "eval" 而你的瓶颈在别处,那么你就会有问题。
  • 如果您可以在 eval 和 subs 之间做出选择,请坚持使用 eval。 subs 为您提供符号解决方案,而不是数字解决方案。
  • 如果有一个干净的方法来拥有多个 MatLab 运行ning 实例,特别是如果您有一个体面的 core-rich cpu 而 MatLab 没有充分利用,那么获得几个他们去。如果您在教育机构工作,则可以在同一系统上尝试 运行 多个不同的版本(2010a、2010b、2009a...)。我(模糊地)记得当我这样做时他们没有发生碰撞。 运行 超过 8 个开始放慢速度而不是改善速度。如果您使用文件来共享控制权,请确保它们不会在文件访问上发生冲突。
  • 您可以在 LabVIEW(不是 MathScript,不是 MatLab)中编写程序,因为它是一种编译语言,有时代码可以 运行 快 1000 倍。
  • 你可以把所有的数字都变成一个矩阵 activity。这取决于您的代码,但如果您可以随机填充矩阵中的列,然后将其矩阵乘以矩阵 $ \left[ 1, x, x^{2}, ...\right] $,那可能是比您当前的方程处理水平快数百或数千倍,并且仍在 MatLab 中。

关于你的编码:

  • 不要在每个循环中都将 "x" 重新声明为一个符号,这很昂贵。
  • 这是什么 "map2mat" 然后 "addPar" 东西?
  • 字符串处理函数在 运行 时间里太糟糕了。坚持一种语言。符号工具箱是 maple,您无需进行愚蠢的 hand-made 解析即可使其与 MatLab 的其余部分一起使用。