使用SymPy求解方程组时程序卡顿,需获取解析解
求解二维向量环方程组时Jupyter卡顿的解决方法
问题场景
尝试求解含θ2、θ5两个未知量的向量环方程组,运行Jupyter时程序无限卡顿,无法得到解析解。原代码如下:
import numpy as np import sympy as smp #Enable LaTex display smp.init_printing() L1,L2,L3,L4,L5,theta1,theta2,theta3,theta4,theta5=smp.symbols('L1,L2,L3,L4,L5,theta1,theta2,theta3,theta4,theta5') def position_vectors(): R1=np.array([L1*smp.cos(theta1),L1*smp.sin(theta1)]) R2=np.array([L2*smp.cos(theta2),L2*smp.sin(theta2)]) R3=np.array([L3*smp.cos(theta3),L3*smp.sin(theta3)]) R4=np.array([L4*smp.cos(theta4),L4*smp.sin(theta4)]) R5=np.array([L5*smp.cos(theta5),L5*smp.sin(theta5)]) return smp.Matrix([R1,R2,R3,R4,R5]) R=position_vectors() print('Vector Matrix:') display(R) i_comps=smp.Eq(R[1,0]+R[2,0]+R[3,0]-R[0,0]-R[4,0],0) j_comps=smp.Eq(R[1,1]+R[2,1]+R[3,1]-R[0,1]-R[4,1],0) print('Vector Loop Equations:') display(i_comps) display(j_comps) theta_solutions=smp.solve([i_comps,j_comps],[theta2,theta5],dict=True) print(theta_solutions)
问题原因
- 混用numpy数组与sympy符号:numpy数组对sympy符号的兼容性差,会导致生成的表达式冗余复杂,大幅降低sympy的求解效率。
- 方程组形式未优化:直接求解含两个三角函数未知量的方程,sympy需要处理大量复杂的三角恒等变换,容易陷入计算瓶颈。
优化后的代码
核心思路
- 移除numpy依赖,直接用sympy构造向量,减少表达式冗余
- 将方程整理为线性组合形式,通过平方消元把二元三角方程组转化为一元方程,降低求解难度
import sympy as smp smp.init_printing() # 定义符号变量 L1,L2,L3,L4,L5,theta1,theta2,theta3,theta4,theta5 = smp.symbols('L1 L2 L3 L4 L5 theta1 theta2 theta3 theta4 theta5') # 直接用sympy构造位置向量,避免numpy干扰 def position_vectors(): R1 = smp.Matrix([L1*smp.cos(theta1), L1*smp.sin(theta1)]) R2 = smp.Matrix([L2*smp.cos(theta2), L2*smp.sin(theta2)]) R3 = smp.Matrix([L3*smp.cos(theta3), L3*smp.sin(theta3)]) R4 = smp.Matrix([L4*smp.cos(theta4), L4*smp.sin(theta4)]) R5 = smp.Matrix([L5*smp.cos(theta5), L5*smp.sin(theta5)]) return smp.Matrix([R1, R2, R3, R4, R5]) R = position_vectors() print('Vector Matrix:') display(R) # 整理向量环方程,将含theta2的项单独放在等式一侧 eq1 = smp.Eq(L2*smp.cos(theta2), L1*smp.cos(theta1) + L5*smp.cos(theta5) - L3*smp.cos(theta3) - L4*smp.cos(theta4)) eq2 = smp.Eq(L2*smp.sin(theta2), L1*smp.sin(theta1) + L5*smp.sin(theta5) - L3*smp.sin(theta3) - L4*smp.sin(theta4)) print('整理后的向量环方程:') display(eq1) display(eq2) # 对两个方程平方后相加,消去theta2,得到仅含theta5的方程 eq_squared = smp.expand(eq1.lhs**2 + eq2.lhs**2 - eq1.rhs**2 - eq2.rhs**2) eq_theta5 = smp.Eq(eq_squared, 0) print('消元后关于theta5的方程:') display(eq_theta5) # 求解theta5的解析解 sol_theta5 = smp.solve(eq_theta5, theta5, dict=True) print('theta5的解析解:') display(sol_theta5) # 将theta5的解回代,求解对应的theta2 if sol_theta5: full_solutions = [] for sol in sol_theta5: subbed_eq = eq1.subs(sol) theta2_sol = smp.solve(subbed_eq, theta2, dict=True)[0] full_solutions.append({**sol, **theta2_sol}) print('theta2与theta5的对应解析解:') display(full_solutions)
效果说明
优化后的代码避免了numpy与sympy的兼容性问题,同时通过消元简化了求解逻辑,能快速输出方程组的解析解,满足报告撰写的需求。
内容的提问来源于stack exchange,提问作者remusconnor
相关产品推荐
相关产品推荐

