Sympy - 简化域内的表达式 [英] Sympy - Simplify expression within domain

查看:26
本文介绍了Sympy - 简化域内的表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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); 等)

解决方案

如果您知道表达式中的函数(例如 sincostan),您可以根据这个堆栈溢出问题:

from sympy import *x = 符号(x",正=真)ex = cos(x)/(cos(x)**2)**(S(1)/2)ex = 精炼(ex, Q.positive(sin(x)))ex = 精炼(ex,Q.positive(cos(x)))ex = 精炼(ex,Q.positive(tan(x)))打印(例如)

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

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

如果表达式之前已经由 SymPy 生成就没有问题,但是如果您手动输入表达式,我建议使用 S(1)/2Rational(1, 2) 描述一半.

from sympy import *# 定义所有内容,因为它来自之前的代码# 还定义另一个变量 y 为正x, y = 符号(x y",正=真)ex = cos(x)/(cos(x)**2)**(S(1)/2)# 如果可以,请始终尝试使用 S(1) 或 Rational(1, 2)# 如果你正在定义分数.# 如果已经是 sympy 中预先计算好的变量,#它已经理解了一半,而你#不会有任何问题.# ex = cos(x)/(cos(x)**2)**(S(1)/2)# 如果 x = arctan(y) 并且两者都是正数,# 那么我们隐含地认为 0 <×<π/2ex = 简化(ex.replace(x, atan(y)))# 如果 x 仍然存在,则恢复到旧变量 xex = 简化(ex.replace(y, tan(x)))打印(例如)

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

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

Can Sympy automatically simplify an expression that includes terms like this one:

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

which can be simplified to 1 in the domain that I am interested in 0 <= x <= pi/2 ?

(Examples of other terms that could be simplified in that domain: acos(cos(x)); sqrt(sin(x)**2); sqrt(cos(2*x) + 1); etc.)

解决方案

If you know the functions that are in your expression (such as sin, cos and tan), you can do the following according to this stack overflow question:

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)

Note that Q.positive(x*(pi/2-x)) did not help in the process of simplification for trig functions even though this is exactly what you want in general.

But what if you might have crazy functions like polygamma? The following works for some arbitrary choices for ex according to my understanding.

It wouldn't be a problem if the expression was already generated before by SymPy, but if you are inputting the expression manually, I suggest using S(1)/2 or Rational(1, 2) to describe one half.

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)

This trick can also be used to define other ranges. For example, if you wanted 1 < x, then you could have x = exp(y) where y = Symbol("y", positive=True).

I think subs() will also work instead of replace() but I just like to be forceful with substitutions, since SymPy can sometimes ignore the subs() command for some variable types like lists and stuff.

这篇关于Sympy - 简化域内的表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆