在循环

时间:2016-01-11 19:42:22

标签: matlab symbolic-math

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

这和我能够做到的一样快。 **** matlabFunction和subs比这慢。 下面的代码是我的解决方案,它是一个循环。在我的较大代码中,函数f和point 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

1 个答案:

答案 0 :(得分:0)

有几种方法可以在这类问题上大幅提升速度:

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

关于您的编码:

  • 不要将“x”重新声明为每个循环的符号,这是很昂贵的。
  • 这是什么“map2mat”然后是“addPar”的东西?
  • 字符串处理函数对运行时来说很糟糕。坚持一种语言。符号工具箱是枫木,你不需要进行愚蠢的手工解析,以使其与MatLab的其余部分一起使用。