Sympy - 简化领域内的表达

Sympy - Simplify expression within domain

Sympy 能否自动简化包含如下项的表达式:

cos(x)/(cos(x)**2)**(1/2)

在我感兴趣的域中可以简化为 1 0 <= x <= pi/2 ?

(可以在该域中简化的其他术语示例:acos(cos(x)); sqrt(sin(x)**2); sqrt(cos(2*x) + 1); 等.)

您可以替换具有您想要的假设的交易品种:

In [27]: e = cos(x)/(cos(x)**2)**(S(1)/2) + cos(x)                                                                     

In [28]: e                                                                                                             
Out[28]: 
            cos(x)   
cos(x) + ────────────
            _________
           ╱    2    
         ╲╱  cos (x) 

In [29]: cosx = Dummy('cosx', positive=True)                                                                           

In [30]: e.subs(cos(x), cosx).subs(cosx, cos(x))                                                                       
Out[30]: cos(x) + 1

如果你知道表达式中的函数(如sincostan),你可以根据这个 :

from sympy import *

x = symbols("x", positive=True)
ex = cos(x)/(cos(x)**2)**(S(1)/2)
ex = refine(ex, Q.positive(sin(x)))
ex = refine(ex, Q.positive(cos(x)))
ex = refine(ex, Q.positive(tan(x)))
print(ex)

请注意,Q.positive(x*(pi/2-x)) 在三角函数的简化过程中没有帮助,即使这正是您通常想要的。

但是,如果您可能有像 polygamma 这样疯狂的功能怎么办?根据我的理解,以下适用于 ex 的一些任意选择。

如果表达式之前已经由SymPy生成了,那不会有问题,但是如果你手动输入表达式,我建议使用S(1)/2Rational(1, 2)来描述一半。

from sympy import *

# define everything as it would have come from previous code
# also define another variable y to be positive
x, y = symbols("x y", positive=True)
ex = cos(x)/(cos(x)**2)**(S(1)/2)

# If you can, always try to use S(1) or Rational(1, 2)
# if you are defining fractions.
# If it's already a pre-calculated variable in sympy, 
# it will already understand it as a half, and you 
# wouldn't have any problems.
# ex = cos(x)/(cos(x)**2)**(S(1)/2)

# if x = arctan(y) and both are positive,
# then we have implicitly that 0 < x < pi/2
ex = simplify(ex.replace(x, atan(y)))
# revert back to old variable x if x is still present
ex = simplify(ex.replace(y, tan(x)))
print(ex)

这个技巧也可以用来定义其他范围。例如,如果您想要 1 < x,那么您可以 x = exp(y) 其中 y = Symbol("y", positive=True).

我认为 subs() 也可以代替 replace() 但我只是喜欢强制替换,因为 SymPy 有时可以忽略某些变量类型(如列表)的 subs() 命令和东西。