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
如果你知道表达式中的函数(如sin
、cos
和tan
),你可以根据这个 :
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)/2
或Rational(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()
命令和东西。
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
如果你知道表达式中的函数(如sin
、cos
和tan
),你可以根据这个
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)/2
或Rational(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()
命令和东西。