MATLAB求解微分方程如何消去root函数简化符号表达式
问题原因
你拿到的带root()的结果不是求解错误,这是MATLAB符号运算的默认显示逻辑:当求解过程涉及三次及以上多项式的根时,系统会用root(多项式, z, k)作为第k个根的占位符,不会自动展开成显式形式,所以看起来冗余杂乱。
可行解决方案
方法1:保留原有dsolve逻辑,一行代码消去root
不需要重写求解代码,只需要在得到解之后用vpa()做可变精度化简,就能把所有root占位符替换成显式数值,得到结构清晰的闭式解。把你原代码最后一行替换为:
[x1, x2, x3] = dsolve(eqns, start_cond); % 第二个参数是有效数字位数,工程场景下取5-6位足够,可按需调整 s1 = vpa(simplify(expand(x1)), 5); s2 = vpa(simplify(expand(x2)), 5); s3 = vpa(simplify(expand(x3)), 5);
运行后输出的解会完全消去root项,结构就是你预期的:由对应齐次系统特征根的指数暂态项,加上和输入同频率的正弦稳态项组成,可读性很高。
补充说明:如果你非要精确的根式符号解,可以调用rewrite或者先显式求解特征方程的根再代换,但三次方程的根式表达式本身极其冗长,没有实际使用价值,绝大多数场景下用vpa得到的有限精度显式解完全够用。
方法2:换用拉普拉斯变换求解,从根源避免root占位
对于线性定常微分方程组,拉普拉斯变换法求解逻辑更透明,不会出现root占位的问题,代码如下:
syms s t f = 0.5; u = sin(2.5*t + f); % 列写状态空间矩阵 A = [-3, 0.2, 2; -1, -1.2, 1.4; -0.4, 0, -0.3]; B = [1; 0; 0]; % 拉普拉斯变换求零状态响应 U_lap = laplace(u); X_lap = (s*eye(3) - A) \ B * U_lap; % 逆变换得到时域解 x1 = ilaplace(X_lap(1), s, t); x2 = ilaplace(X_lap(2), s, t); x3 = ilaplace(X_lap(3), s, t); % 化简为5位有效数字的显式形式 s1 = vpa(simplify(x1),5);
这个方法得到的解和dsolve的结果完全等价,求解过程中会自动做部分分式展开,直接输出显式时域表达式,不会出现root占位符。
正确性验证
拿到解之后可以直接代回原方程校验:
% 代入方程计算残差 res1 = diff(x1,t) - (-3*x1 + 0.2*x2 + 2*x3 + u); res2 = diff(x2,t) - (-1*x1 -1.2*x2 +1.4*x3); res3 = diff(x3,t) - (-0.4*x1 -0.3*x3); % 化简残差,结果为0即证明解正确 simplify([res1,res2,res3])
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

