- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在尝试使符号替换变得更快时遇到了很多麻烦 - 也就是说,用 in 替换符号表达式中的变量并得到一个 double 值。
我正在创建一个复杂的函数 f,并计算它的雅可比 df。这是一个合理的速度,我可以将它保存到一个文件中。但是当我尝试使用 matlabFunction 甚至 disp 或 fprintf 时,系统挂起并且无法继续进行(即使当 matlabFunction 设置为未优化时)。这是一个主要问题,因为我需要能够进行合理快速的替换。
f 向量是 24 个元素,雅可比矩阵是 24 x 78(虽然这里只显示 70 个变量,所以这可以压缩到 70 列;我怀疑这是问题所在)。
我也知道 f 和 df 的某些元素在单独访问时很简单并且可以正常工作,但是无法显示 f 和 df 的某些更复杂的元素。我想它们很长,但由于它们计算得很好,所以它们不能转换为 matlabFunction 或显示对我来说没有意义。
更奇怪的是,我可以用 in 替换我所有的符号变量,但是完全替换的 f 向量的最终显示(比如,通过 disp),或者转换为 double(通过 double( ))似乎需要永远.
如果您想使用 .mat 文件,可以获取它 here (filedropper 链接,它是 288kb)。我该怎么做才能在合理的时间内写出这个文件?
最佳答案
注意:我是从你的评论的角度来关注问题的:
It is the result of a matrix multiplication and addition. I have tried simplifying it along the way, using the simplify command, but that's been incredibly slow. I have succeeded once in writing f to a file unoptimized (no luck for df) - it took 2 hours - but then evaluating it took 0.8 seconds, which is too slow. I need to be able to perform evaluation in about 0.02 seconds.
我开始查看您的 f
中的元素,直到 f(12)
为止都很简单。然而,f(13)
释放了 hell :
>> 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 时间而不占用内存。
预处理:
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
的解析器,或者更可能的是,您在操作期间耗尽了内存。当我尝试简化
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
和 cos
,每个。
现在,如果我们假设这是一个正确的大概数字,并且如果我们假设您的函数具有类似的操作分布,那么您正在查看函数的 40080434
个字符,即17 个等效的 f(13)
单位。这表明,即使您可以转换为适当的 matlab 函数,您的运行时也只是调用 f
(我们还没有查看 df
完全)至少需要 0.1-0.2 秒。
鉴于您问题的性质,我不确定是否有解决方法。我可能会尝试在 python
中使用 sympy
做同样的事情,在那里你也可以转换为 lambda
(相当于 python 的匿名函数)用于数值计算。如果那个会成功,那么至少您可以尽快使用您的函数。
在发布我不太乐观的答案后,我相信我已经成功地将您的函数转换为匿名函数。它很脏,但它似乎可以工作。
首先,您将函数转换为上述字符串,然后使用 symvar
提取变量名。然后使用这些函数名创建一个函数定义;不幸的是,我只能使用 eval
破解它。 应该有一种更优雅的方式,但无论如何我们对可实现的运行时间很感兴趣。
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 个这样的功能。您可能永远无法获得所希望的加速。
(无论如何,我确实开始了
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
在这整个磨难之后的错误,所以它的成功也可能取决于你对“成功”的定义;)
关于matlab - 打印 syms/matlabFunction 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33174917/
我想计算两个变量的函数的微分。例如: ax^2 + by^2 + cxy 所以我这样做: a = 1 b = 1 c = 1 syms x y f f = a*x^2 + b*y^2 + c*x*y
问题 我试图用符号区分一个函数与两个不同的变量,然后为每个导数创建一个函数文件。一个函数文件有效,另一个无效,因为 matlabFunction 错误处理了积分变量。 我的方法 生成函数文件的代码(起
我在计算物理课上广泛使用了 matlabFunction,我希望有人能帮助我理解这个命令到底发生了什么(是 matlabFunction命令?)。我读过what the MathWorks websi
我在尝试使符号替换变得更快时遇到了很多麻烦 - 也就是说,用 in 替换符号表达式中的变量并得到一个 double 值。 我正在创建一个复杂的函数 f,并计算它的雅可比 df。这是一个合理的速度,我可
我是一名优秀的程序员,十分优秀!