about the problem 'Unable to generate code for piecewise for use in anonymous functions', thanks

조회 수: 35 (최근 30일)
hello, every
my code
syms l xita miu h n t1 gfi
fai = pi-2*atan(l*sind(xita)/(h+l*cosd(xita)));
ti=t1*exp(-(gfi+1)*miu*(fai));
ui1i=[(-1)^(gfi-1)*(h+2*l*cosd(xita));-1*l*sind(xita)];
dfui1i=diff(ui1i,xita);
qti=-1*ti*ui1i'/sqrt(ui1i(1)^2+ui1i(2)^2)*dfui1i;
qt=symsum(qti,gfi,1,n);
F=matlabFunction(qt);
does not work.
I got this error:
Error using symengine
Unable to generate code for piecewise for use in anonymous functions.
Error in sym/matlabFunction>mup2mat (line 404)
res = mupadmex('symobj::generateMATLAB',r.s,ano,spa,0);
Error in sym/matlabFunction>mup2matcell (line 374)
r = mup2mat(c{1},true,sparseMat);
Error in sym/matlabFunction (line 188)
body = mup2matcell(funs, opts.Sparse);
Could you please help me with this issue?
thank you!

채택된 답변

Walter Roberson
Walter Roberson 2021년 9월 9일
The message is correct: piecewise() cannot be built into an anonymous funciton. However it can be coded into a function if you tell matlabFunction to write to a file.
syms l xita miu h n t1 gfi
assume(n, 'integer')
assumeAlso(n>=1)
Pi = sym(pi);
fai = Pi-2*atan(l*sind(xita)/(h+l*cosd(xita)));
ti = t1*exp(-(gfi+1)*miu*(fai));
ui1i = [(-1)^(gfi-1)*(h+2*l*cosd(xita)); -1*l*sind(xita)];
dfui1i = diff(ui1i,xita);
qti = simplify(-1*ti*ui1i'/sqrt(ui1i(1)^2+ui1i(2)^2)*dfui1i)
qti = 
qt = symsum(qti,gfi,1,n);
qt
qt = 
tn = [tempname, '.m'];
F = matlabFunction(qt, 'file', tn, 'optimize', true)
F = function_handle with value:
@tpd90ebd4f_b5a5_4140_8679_8b7468e23d90
type(tn)
function qt = tpd90ebd4f_b5a5_4140_8679_8b7468e23d90(h,l,miu,n,t1,xita) %TPD90EBD4F_B5A5_4140_8679_8B7468E23D90 % QT = TPD90EBD4F_B5A5_4140_8679_8B7468E23D90(H,L,MIU,N,T1,XITA) % This function was generated by the Symbolic Math Toolbox version 8.7. % 09-Sep-2021 10:27:32 t3 = conj(h); t4 = abs(l); t5 = conj(xita); t6 = miu.*pi; t7 = l.^2; t8 = n+1.0; t11 = 1.0./l; t15 = (xita.*pi)./1.8e+2; t9 = t4.^2; t10 = exp(t6); t12 = -t6; t14 = t6.*t8; t16 = (t5.*pi)./1.8e+2; t17 = cos(t15); t18 = sin(t15); t13 = 1.0./t10; t19 = cos(t16); t20 = sin(t16); t21 = l.*t17; t22 = t18.^2; t25 = t3.*t18.*2.0; t23 = t21.*2.0; t24 = h+t21; t27 = t7.*t22; t32 = t9.*t11.*t17.*t20; t33 = t9.*t11.*t18.*t19.*4.0; t26 = h+t23; t28 = 1.0./t24; t34 = -t32; t29 = t26.^2; t30 = l.*t18.*t28; t40 = t25+t33+t34; t31 = atan(t30); t36 = t27+t29; t35 = miu.*t31.*2.0; t38 = 1.0./sqrt(t36); t37 = exp(t35); t39 = t13.*t37; if (t39 == 1.0) qt = (l.*n.*t1.*t38.*t40.*pi)./1.8e+2; elseif (t39 ~= 1.0) qt = (l.*t1.*t39.*pi.*exp(t8.*t12).*1.0./sqrt(t27+(h+t23).^2).*(t10.*exp(t8.*t35)-t37.*exp(t14)).*(t25+t33+t34).*(-1.0./1.8e+2))./(t10-t37); else qt = NaN; end
You can use a different file name for tn -- the one tempname() I use here generates a random file name in a temporary directory.
Be careful: when you code generate for piecewise() into a file, then the result is not a vectorized function !
  댓글 수: 5
Walter Roberson
Walter Roberson 2021년 9월 10일
By the way: the special condition that leads to the branch, is arguably true when
xita = 180 - (180*acos(h/l))/pi
But that has to be taken in the limit, and one side of the limit has a different value.
Under that condition, in the limit, the denominator of namely becomes 0, but the numerator is positive so that becomes infinity, and arctan(infinity) is pi/2 which is the condition that leads to . So division by 0 but in the context of an arctan that knows how to deal with infinity, so no actual singularity in context. Which is why you can get a solution under that condition without an exception.
If there is some constraint such that xita cannot pass through that value, then you could
children(qt,2)
and use that instead of qt: it will not need piecewise() in that case. But if it can pass through that value then you need the full expression.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Interpolation에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by