所以,我在 Matlab 中有一个非常长的符号表达式,我想将其复制/粘贴到 JavaScript 代码中,以动画显示它的数值解。问题是,当我宁愿让 Matlab 将其表示为 A*A 时,我的代码中的某些地方会得到指数(主要是 ^2)。
我有多种(且不同的)表达式,例如
cos(th2t)^2
我宁愿表达为
cos(th2t)*cos(th2t)
有什么办法可以做到这一点吗?另一种方法是随后使用文本编辑器搜索 2 的幂并替换它,但有多种不同的表达式,因此需要一些时间...
这是我最终得到的表达式之一的示例:
(J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31))
最佳答案
如果您想依赖 ** 运算符,史蒂夫的答案应该可以正常工作。然而,由于该运算符不受官方支持,并且该解决方案不能直接回答OP的问题,因此这里有一个可以扩展符号表达式中的指数的函数。
function [ text ] = remove_powers( exp )
%Cleans the powers from T, and return expanded text representation
% Define functions
enclose =@(t) ['(' t ')'];
expand_pow=@(b,p) strjoin(strcat(cell(1,p),enclose(char(b))),'*');
count_pow=@(s) arrayfun(@(k) count(char(s(k)),'^'), 1:length(s));
sym2str = @(s) strrep(char(s), ' ', '');
% Check for fractions
[N,D]=numden(exp);
if ~isequal(D,sym(1))
% pass up the num and den
text = [remove_powers(N) '/' enclose(remove_powers(D))];
else
% Split a into subterms
Ts = children(exp);
% Clean children
has_pow=count_pow(Ts)>0;
text = sym2str(exp);
if sum(count_pow(Ts))<count_pow(exp)
% We have removed a power, clean it, expand it, and pass up
text = expand_pow(remove_powers(Ts(1)),Ts(2));
else
% Just clean the unclean children and pass up
for t=Ts(has_pow)
text = strrep(text,sym2str(t),remove_powers(t));
end
end
end
end
该函数使用children
Matlab 中的函数递归地清理每个子表达式并在父表达式中替换它(作为文本)。这种方法比使用正则表达式更好,因为它避免了解析语法的问题,正如 Steve 在关于 cos(x^2+2*y)^2
的评论中提到的那样。
这是一个很好的例子:
syms x y real
exp = cos(x^2+2*y)^2;
cleaned_exp = remove_powers(exp)
输出:(cos(2*y+(x)*(x)))*(cos(2*y+(x)*(x)))
请注意,由于 Matlab 正在进行解析,因此无需解析“^”运算符的优先顺序,而使用正则表达式可能很难实现这一点。
测试 OP 的示例:
syms ddth1t dth1t th1t ddth2t dth2t th2t w11 w12 w13 J11 J31 real
exp = (J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31));
cleaned_exp = remove_powers(exp);
isequal(sym(cleaned_exp),exp) % This should be 1
count(cleaned_exp,'^') % This should be 0
正如预期的那样,新表达式与原始表达式等效,但没有“^”符号。
关于matlab - 在 Matlab 中将 A^2 表示为 A * A,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42984343/