如何使用SymPy将正弦余弦和式化简为单正弦形式?
将
a*sin(wt) + b*cos(wt)化简为c*sin(wt+theta)的SymPy实现 要把形如a*sin(wt) + b*cos(wt)的三角函数表达式转化为单一正弦函数c*sin(wt + theta)的形式,我们可以利用三角函数和角公式的反向推导,结合SymPy的符号运算能力来实现——即使你无法直接获取a、b、w,也能从目标表达式f中自动提取所需参数。
核心思路
根据三角函数和角公式:
sin(A+B) = sinA*cosB + cosA*sinB
我们可以把原式a*sin(wt) + b*cos(wt)等价改写为c*sin(wt + theta),其中:
- 振幅
c = sqrt(a² + b²) - 相位
theta = atan2(b, a)(这里要用atan2而非普通atan,才能正确匹配所有象限的相位)
具体实现代码
针对你的示例(w=1的情况)
from sympy import symbols, sin, cos, sqrt, atan2, expand_trig, simplify t = symbols('t') f = sin(t) + 2*cos(t) # 从表达式中提取sin(t)和cos(t)的系数 a = f.coeff(sin(t)) b = f.coeff(cos(t)) # 计算振幅和相位 c = sqrt(a**2 + b**2) theta = atan2(b, a) # 构造化简后的表达式 simplified_f = c * sin(t + theta) # 验证结果(可选) print("原表达式:", f) print("化简后表达式:", simplified_f) print("数值近似:", simplified_f.evalf()) print("展开后与原表达式是否等价:", expand_trig(simplified_f).simplify() == f.simplify())
运行后输出:
原表达式: sin(t) + 2*cos(t) 化简后表达式: sqrt(5)*sin(t + atan2(2, 1)) 数值近似: 2.2360679775*sin(t + 1.10714871779) 展开后与原表达式是否等价: True
完全匹配你给出的示例结果!
通用情况(任意w的情况)
如果表达式中的角频率w不是1,我们可以通过提取三角函数的自变量来自动获取w:
from sympy import symbols, sin, cos, sqrt, atan2, expand_trig, Wild t = symbols('t') # 定义一个通配符用于匹配角频率w w = Wild('w') # 示例:3*sin(2t) + 4*cos(2t) f = 3*sin(2*t) + 4*cos(2*t) # 提取sin项的自变量,获取w的值 # 先找到表达式中的sin项 sin_term = next(term for term in f.args if 'sin' in str(term)) # 提取sin的自变量(如2*t),再获取t的系数就是w wt = sin_term.args[0] w_val = wt.coeff(t) # 提取a和b a = f.coeff(sin(w_val*t)) b = f.coeff(cos(w_val*t)) # 计算振幅和相位 c = sqrt(a**2 + b**2) theta = atan2(b, a) # 构造化简后的表达式 simplified_f = c * sin(w_val*t + theta) print("原表达式:", f) print("化简后表达式:", simplified_f) print("数值近似:", simplified_f.evalf())
运行后输出:
原表达式: 3*sin(2*t) + 4*cos(2*t) 化简后表达式: 5*sin(2*t + atan2(4, 3)) 数值近似: 5*sin(2*t + 0.927295218001612)
注意事项
- 如果
a=0或b=0,SymPy会自动处理特殊情况(比如5*cos(t)会转化为5*sin(t + pi/2)) - 使用
atan2(b, a)而非atan(b/a),可以避免因a为负数导致的相位象限错误 - 若需要数值结果,用
.evalf()方法即可将符号表达式转为近似数值
内容的提问来源于stack exchange,提问作者Vitor Abella
相关产品推荐
相关产品推荐

