二元非线性ODE是否存在简易解析解?Sympy求解结果简化探讨
问题背景
我有一组相对简单的二元非线性微分方程组:
- $\frac{dx_1}{dt} = \frac{u_1 - u_3}{A}$
- $\frac{dx_2}{dt} = u_1 u_2 - \frac{u_3 x_2}{x_1 A}$
尝试用SymPy求解解析解,代码如下:
from sympy import symbols, Function, Eq, dsolve x1, x2 = symbols('x1, x2', cls=Function) t, u1, u2, u3, A, x1_init, x2_init = symbols('t, u1, u2, u3, A, x1_init, x2_init') ode_system = [ Eq(x1(t).diff(t), (u1 - u3) / A), Eq(x2(t).diff(t), u1 * u2 - u3 * x2(t) / (x1(t) * A)) ] ics = {x1(0): x1_init, x2(0): x2_init} sol = dsolve(ode_system, [x1(t), x2(t)], ics=ics)
SymPy求出的解中,$x_1(t)$符合预期:
In [2]: sol[0] Out[2]: Eq(x1(t), x1_init + t*(u1 - u3)/A)
但$x_2(t)$的解非常复杂且包含分段函数:
In [3]: sol[1] Out[3]: Eq(x2(t), u1*u2*Piecewise((exp(u1*log(A*x1_init + t*u1 - t*u3)/(u1 - u3))/u1, Ne(u1, 0)), (log(A*x1_init + t*u1 - t*u3)/(u1 - u3), True))*exp(-u3*log(A*x1_init + t*u1 - t*u3)/(u1 - u3)) - (u1*u2*Piecewise((exp(u1*log(A*C1)/(u1 - u3))/u1, Ne(u1, 0)), (log(A*C1)/(u1 - u3), True)) - x2_init*(A*x1_init)**(u3/(u1 - u3)))*exp(-u3*log(A*x1_init + t*u1 - t*u3)/(u1 - u3)))
想请教:是否存在特定条件下的明显简化方式?还是这个解确实就是如此复杂的分段函数?
解答
首先简化$x_1(t)$的表达式,令$X(t) = A x_1(t) = A x_{1,\text{init}} + t(u_1 - u_3)$,原方程组的第二个方程可改写为一阶线性非齐次微分方程:
$$\frac{dx_2}{dt} + \frac{u_3}{X(t)} x_2 = u_1 u_2$$
用积分因子法求解,积分因子为$\mu(t) = \exp\left( \int \frac{u_3}{X(t)} dt \right)$,分情况讨论可得到大幅简化的解:
情况1:$u_1 \neq u_3$
此时$X(t)$是一次函数,积分得积分因子$\mu(t) = X(t)^{\frac{u_3}{u_1 - u_3}}$,代入线性方程通解公式计算后,结合初始条件可得:
$$x_2(t) = u_2 \left( A x_{1,\text{init}} + t(u_1 - u_3) \right) + \left( x_{2,\text{init}} - u_2 A x_{1,\text{init}} \right) \left( \frac{A x_{1,\text{init}}}{A x_{1,\text{init}} + t(u_1 - u_3)} \right)^{\frac{u_3}{u_1 - u_3}}$$
情况2:$u_1 = u_3$
此时$X(t) = A x_{1,\text{init}}$(常数),第二个方程变为常系数线性方程,求解后得:
$$x_2(t) = u_2 A x_{1,\text{init}} + \left( x_{2,\text{init}} - u_2 A x_{1,\text{init}} \right) \exp\left( -\frac{u_1 t}{A x_{1,\text{init}}} \right)$$
情况3:$u_1 = 0$
对应SymPy解中的分段分支,此时$X(t) = A x_{1,\text{init}} - u_3 t$,第二个方程为齐次线性方程,求解后得:
$$x_2(t) = x_{2,\text{init}} \cdot \frac{A x_{1,\text{init}}}{A x_{1,\text{init}} - u_3 t}$$
该结果可归为情况1的特例(对情况1公式取$u_1 \to 0$的极限即可验证),SymPy单独分出分支是为了避免分母为0的计算问题。
总结
SymPy给出的分段解是为了覆盖所有参数取值场景,但通过手动推导可拆分为上述几个清晰的简化形式:
- $u_1 \neq u_3$时,解为多项式加幂函数的组合;
- $u_1 = u_3$时,解退化为指数函数形式;
- $u_1 = 0$时,解为简单的反比例形式。
这些形式比SymPy直接输出的结果更易理解,核心是先解出$x_1(t)$后代入第二个方程,用一阶线性微分方程的积分因子法手动推导,避开符号计算工具生成的冗余表达式。
内容的提问来源于stack exchange,提问作者Bill

