注意:我从您的评论的角度集中讨论了这个问题:
它是矩阵乘法和加法的结果。我一直尝试使用简化命令来简化它,但这非常慢。我曾经成功地将 f 写入未优化的文件(df 不走运) - 花了 2 小时 - 但后来评估它花了 0.8 秒,这太慢了。我需要能够在大约 0.02 秒内执行评估。
我开始研究你的元素f
,这很简单f(12)
。然而,f(13)
释放地狱:
>> inp.f(13)
ans =
(2289*l4)/100 - (11371197146449238679*l3)/8112963841460668169578900514406400 - (2289*l2)/100 + (11371197146449238679*l5)/8112963841460668169578900514406400 - (2289*l8)/100 - (11371197146449238679*l9)/8112963841460668169578900514406400 + (2289*l10)/100 + (11371197146449238679*l11)/8112963841460668169578900514406400 - (2289*l14)/100 - (11371197146449238679*l15)/8112963841460668169578900514406400 + (2289*l16)/100 + (11371197146449238679*l17)/8112963841460668169578900514406400 - (2289*l20)/100 - (11371197146449238679*l21)/8112963841460668169578900514406400 + (2289*l22)/100 + (11371197146449238679*l23)/8112963841460668169578900514406400 - (2289*l26)/100 - (11371197146449238679*l27)/8112963841460668169578900514406400 + (2289*l28)/100 + (11371197146449238679*l29)/8112963841460668169578900514406400 - (2289*l32)/100 - (11371197146449238679*l33)/8112963841460668169578900514406400 + (2289*l34)/100 + (11371197146449238679*l35)/8112963841460668169578900514406400 - h1*(((cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2)) + (sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2))*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - cos(x5/2)^2*cos(x6/2)*sin(x6/2))*(((x17*(cos(x4/2)*cos(x5/2)*(cos(x6/2)*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) + sin(x6/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2))) - cos(x5/2)*sin(x4/2)*(cos(x6/2)*(cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2)) + sin(x6/2)*(cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2)))))/2 - (x18*(cos(x4/2)^2*cos(x5/2)^2 + cos(x5/2)^2*sin(x4/2)^2 + sin(x5/2)^2))/2 + (x16*(sin(x5/2)*(cos(x5/2)^2*cos(x6/2)^2 + cos(x5/2)^2*sin(x6/2)^2 + sin(x5/2)^2) + cos(x5/2)*sin(x4/2)*(cos(x5/2)*sin(x4/2)*sin(x5/2) + cos(x5/2)*cos(x6/2)*(cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2)) - cos(x5/2)*sin(x6/2)*(cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))) + cos(x4/2)*cos(x5/2)*(cos(x4/2)*cos(x5/2)*sin(x5/2) - cos(x5/2)*cos(x6/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + cos(x5/2)*sin(x6/2)*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)))))/2 - (x19*cos(x5/2)*sin(x4/2))/2)*((LEG_MASS*((cos(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + cos(x5/2)*cos(x6/2)*sin(x7/2))*((cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(x2/2 - BASE_ORIGIN_Z*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - (cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*sin(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) - (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(x1/2 + BASE_ORIGIN_Z*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*cos(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) + cos(x5/2)*sin(x4/2)*(x3/2 - sin(x5/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4) + BASE_ORIGIN_Z*cos(x4/2)*cos(x5/2) - cos(x5/2)*sin(x4/2)*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2))) - (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*((sin(x5/2)*sin(x7/2) - cos(x4/2)*cos(x5/2)*cos(x7/2))*(x3/2 - sin(x5/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4) + BASE_ORIGIN_Z*cos(x4/2)*cos(x5/2) - cos(x5/2)*sin(x4/2)*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2)) - (cos(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + cos(x5/2)*cos(x6/2)*sin(x7/2))*(x1/2 + BASE_ORIGIN_Z*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*cos(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) + (cos(x7/2)*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - cos(x5/2)*sin(x6/2)*sin(x7/2))*(x2/2 - BASE_ORIGIN_Z*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - (cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*sin(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4))))*(sin(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) - cos(x5/2)*cos(x6/2)*cos(x7/2)) - LEG_MASS*((sin(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) - cos(x5/2)*cos(x6/2)*cos(x7/2))*((cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(x2/2 - BASE_ORIGIN_Z*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - (cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*sin(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) - (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(x1/2 + BASE_ORIGIN_Z*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*cos(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) + cos(x5/2)*sin(x4/2)*(x3/2 - sin(x5/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4) + BASE_ORIGIN_Z*cos(x4/2)*cos(x5/2) - cos(x5/2)*sin(x4/2)*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2))) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*((cos(x7/2)*sin(x5/2) + cos(x4/2)*cos(x5/2)*sin(x7/2))*(x3/2 - sin(x5/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4) + BASE_ORIGIN_Z*cos(x4/2)*cos(x5/2) - cos(x5/2)*sin(x4/2)*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2)) + (sin(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) - cos(x5/2)*cos(x6/2)*cos(x7/2))*(x1/2 + BASE_ORIGIN_Z*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*cos(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) - (sin(x7/2)*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) + cos(x5/2)*cos(x7/2)*sin(x6/2))*(x2/2 - BASE_ORIGIN_Z*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - (cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*sin(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4))))*(cos(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + cos(x5/2)*cos(x6/2)*sin(x7/2)) + LEG_MASS*(cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*((cos(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + cos(x5/2)*cos(x6/2)*sin(x7/2))*((cos(x7/2)*sin(x5/2) + cos(x4/2)*cos(x5/2)*sin(x7/2))*(x3/2 - sin(x5/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4) + BASE_ORIGIN_Z*cos(x4/2)*cos(x5/2) - cos(x5/2)*sin(x4/2)*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2)) + (sin(x7/2)*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) - cos(x5/2)*cos(x6/2)*cos(x7/2))*(x1/2 + BASE_ORIGIN_Z*(sin(x4/2)*sin(x6/2) + cos(x4/2)*cos(x6/2)*sin(x5/2)) + (cos(x4/2)*sin(x6/2) - cos(x6/2)*sin(x4/2)*sin(x5/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + cos(x5/2)*cos(x6/2)*(BASE_ORIGIN_X - BASE_LINK_EXTENTS_X/4)) - (sin(x7/2)*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) + cos(x5/2)*cos(x7/2)*sin(x6/2))*(x2/2 - BASE_ORIGIN_Z*(cos(x6/2)*sin(x4/2) - cos(x4/2)*sin(x5/2)*sin(x6/2)) - (cos(x4/2)*cos(x6/2) + sin(x4/2)*sin(x5/2)*sin(x6/2))*(BASE_LINK_EXTENTS_Y/2 - BASE_ORIGIN_Y + LEG_LINK_EXTENTS_Y/2) + [...] ... Output truncated. Text exceeds maximum line length of 25,000 characters for Command Window display.
(实际输出被截断以适应 SO 的 30k 字符限制,但你明白了)
我敢打赌解析器matlabFunction
并不适合如此大规模的投入。其中还有一些奇怪的东西:比如整数字符串文字的顺序8e33
.
所以我仔细研究了你的功能。幸运的是,您可以将函数转换为字符串,然后对其进行处理,这只会占用 CPU 时间,而不占用内存。
Preproc:
for k=1:24
fstring2{k}=char(inp.f(k));
end
函数长度:
>> cellfun(@length,fstring2)
ans =
Columns 1 through 12
11 11 11 11 11 11 11 11 11 11 11 11
Columns 13 through 24
2301006 2300241 2299996 8425640 8416273 8424306 1375443 1305245 1302440 1237876 1381084 1310884
休斯顿,我们遇到了麻烦。
这些巨大的符号函数破坏了解析器matlabFunction
,或者更可能的是,您在操作过程中耗尽了内存。当我尝试时我确实做到了simplify
f(13)
,几秒钟内就丢失了 8 GB 的一半。
正如概念验证一样,我尝试模拟您的函数中涉及的计算工作。我检查了f(13)
(第一只野兽)。有关所涉及操作的一些信息:
>> length(strfind(char(inp.f(13)),'*'))
ans =
134710
>> length(strfind(char(inp.f(13)),'+'))
ans =
36932
>> length(strfind(char(inp.f(13)),'-'))
ans =
26855
>> length(strfind(char(inp.f(13)),'/'))
ans =
183380
>> length(strfind(char(inp.f(13)),'ln'))
ans =
0
>> length(strfind(char(inp.f(13)),'exp'))
ans =
0
>> length(strfind(char(inp.f(13)),'cos'))
ans =
78700
>> length(strfind(char(inp.f(13)),'sin'))
ans =
84142
我尝试对涉及类似数量操作的模拟计算进行计时:
x=zeros(36000,1);
tic;
for k=1:36000
x(k)=(((sin(sin(((cos(cos(3.1+2.1)*3.1)*6.1)*5.1)*9.1)/4.1)/3.1)/6.1)/5.1)/8.1;
end
toc;
Elapsed time is 0.010895 seconds.
这涉及到36000
补充,144000
乘法,180000
部门和72000
打电话给sin
and cos
, each.
现在,如果我们假设这是一个正确的大概数字,并且如果我们假设您的函数具有类似的操作分布,那么您将看到40080434
函数的字符,相当于 17 个f(13)
单位。这表明即使你可以转换为适当的 matlab 函数,你的运行时间只是调用f
(我们还没有看过df
根本)至少需要 0.1-0.2 秒。
由于您的问题的性质,我不确定是否有解决方法。我可能会尝试使用同样的方法sympy
in python
,您还可以在那里转换为lambda
(Python 中匿名函数的等价物)用于数值计算。如果that会成功,那么至少你可以尽快使用你的功能。
UPDATE
在发布我不太乐观的答案后,我相信我已经成功地将您的函数转换为匿名函数。它很脏,但似乎有用。
首先将函数转换为上面的字符串,然后使用symvar
提取变量名称。然后使用这些函数名称创建函数定义;不幸的是我只能使用它来破解它eval
. There should是一种更优雅的方式,但无论如何我们对可实现的运行时间感兴趣。
varcell=symvar(fstring2{13}); %variables of inp.f(13)
vars2=strcat(varcell,','); %add a comma to each var
vars3=[vars2{:}]; %put them into a single string
vars3=vars3(1:end-1); %remove trailing comma
f13=eval(['@(' v3 ') ' fstring2{13}]); %this is your numeric function
这种转换很麻烦,但匿名函数的实际构造很快,而且对内存也不太费劲。虚拟运行时间:
>> tic; ftry(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58), toc
ans =
1.1417e+06
Elapsed time is 0.069252 seconds.
它可以变得更加用户友好,例如允许在函数中进行数组操作,或者将所有 58 个输入作为单个数组输入传递。但你的运行时间是一样的。这只是一项功能,大约有 17 个功能。您可能永远无法获得您所希望的加速。
(无论如何,我确实开始得到
线程“AWT-EventQueue-0”中的异常 java.lang.OutOfMemoryError:Java 堆空间
在这整个磨难之后出现错误,所以它success可能还取决于您对“成功”的定义;)