matlab - 在 Matlab 中将 A^2 表示为 A * A

标签 matlab substitution exponent

所以,我在 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/

相关文章:

r - 使用替换在 R 表达式中进行变量替换

awk - 如何减少文本文件中的所有数组索引?

c# - 将具有指数表示法的数字从字符串转换为 double 或十进制

matlab - Matlab 的秩函数在小的整数值矩阵上的 "inconsistent"行为感到惊讶

matlab - 将矩阵划分为 10 个子矩阵

matlab - 数组中最大值和最小值的索引

regex - 删除 Google 表格中 <> 内单元格中的所有内容

matlab - 为堆叠条形图中的每个部分设置不同的颜色

python - 所有数字的乘法(2个数字之间)python

matlab - 在 Matlab 中,如何使用 formatSpec 格式化运算符指定指数中的位数?