python - SymPy 中 1/x 的集成
问题描述
我认为 SymPy 在积分 1/x 时返回 log(x) 而不是 log(abs(x)) 很好。这使它变得简单,并让用户担心标志。
但是,在某些情况下它会导致错误的答案。例如,
from sympy import *
x = Symbol('x')
integrate(cos(x)**2/sin(x), x)
结果是
log(cos(x) - 1)/2 - log(cos(x) + 1)/2 + cos(x)
虽然它应该(显然?)
log(1 - cos(x))/2 - log(1 + cos(x))/2 + cos(x)
是否有一种解决方法可以产生第二个答案?
解决方案
缺席abs
不仅仅是为了“保持简单”。正如 SymPy 首席开发人员所写,
SymPy 不会返回
log(abs(x))
for,integrate(1/x)
因为它对复数无效。相反,答案在积分常数(可能很复杂)之前是正确的。默认情况下,所有 SymPy 操作都假定变量是复杂的。
其余链接问题也与您的问题有关。从某种角度来看, log(cos(x) - 1)
: 与积分结果一样有效log(1 - cos(x))
:这两个表达式之间的差异是I*pi
,它被积分常数吸收了。此外,cos(x)
对于复数 x,可能大于 1,例如cos(I) = 1.54...
也就是说,以下是一种强制对数中的常数项为非负数的方法。
def fix_logs(expr):
replacements = {}
for a in expr.atoms(log):
if a.args[0].as_coeff_add()[0].is_negative:
replacements[a] = log(-a.args[0]) + log(-1)
return expr.xreplace(replacements)
下面是它的工作原理:
rv = integrate(cos(x)**2/sin(x), x)
rv2 = fix_logs(rv)
rv3 = Add(*fix_logs(rv2).as_coeff_add(x)[1])
这里的 rv、rv2 和 rv3 是:
log(cos(x) - 1)/2 - log(cos(x) + 1)/2 + cos(x)
log(-cos(x) + 1)/2 - log(cos(x) + 1)/2 + cos(x) + I*pi/2
log(-cos(x) + 1)/2 - log(cos(x) + 1)/2 + cos(x)
该函数fix_logs
不会删除 log(-1) 部分,因为它可能很重要:x*log(x-1)
成为x*(log(1-x) + I*pi/2)
不能简单删除常量的地方。但如果需要,可以删除附加常数,如 的计算所示rv3
。
推荐阅读
- amazon-web-services - 如何配置 AWS Cloudwatch 事件规则以检查服务账户的 IAM 角色?
- javascript - 手风琴表一个js
- azure-devops - Azure CI/D 构建管道未构建所有项目
- odoo - 如何对 QWEB 报告(Odoo 13)中的行求和?
- android - 用于录制音频按钮的 setOnTouchListener 在 Android 中无法正常工作
- windows - Windows 批处理脚本:仅对文件夹进行排序并处理第一个文件夹
- android - 无法使用键盘导航导航到滚动视图之外的按钮
- bootstrap-4 - svelte 和 sveltestrap - 选择输入的问题
- javascript - 模态关闭后的Javascript FullCalendar refetchEvents V5
- c# - Blazor Web 应用程序的移动容器