Sympy中的简化集

问题描述 投票:0回答:1

我想知道是否存在将sympy.set实例简化为“最简单”形式的通用方法,例如最小化set操作的嵌套,理想情况下将表达式简化为一系列的并集和补码。例如:

>>> from sympy.abc import x,y
>>> from sympy import S
>>> from sympy.calculus.util import continuous_domain
>>>
>>>
>>> f = (1-x)/(2+x) - 3*(x-y)/(1+x+y)
>>>
>>> continuous_domain(f, x, S.Reals)
Union(Complement(Interval.open(-oo, -2), Union(Complement(Intersection(FiniteSet(-2, -y - 1), Reals), FiniteSet((y - 3)/4 - sqrt(y**2 + 22*y + 13)/4, (y - 3)/4 + sqrt(y**2 + 22*y + 13)/4)), Intersection(FiniteSet(-y - 1), Reals))), Complement(Interval.open(-2, oo), Union(Complement(Intersection(FiniteSet(-2, -y - 1), Reals), FiniteSet((y - 3)/4 - sqrt(y**2 + 22*y + 13)/4, (y - 3)/4 + sqrt(y**2 + 22*y + 13)/4)), Intersection(FiniteSet(-y - 1), Reals))))
>>>
>>> # Display the answer with pretty printing
>>> from sympy import init_printing
>>> init_printing()
>>> 
>>> continuous_domain(f, x, S.Reals)
⎛           ⎛                 ⎛                     ⎧            ________________             ________________ ⎫⎞⎞⎞   ⎛          ⎛                 ⎛                     ⎧            ________________             ________________ ⎫⎞⎞⎞
⎜           ⎜                 ⎜                     ⎪           ╱  2                         ╱  2              ⎪⎟⎟⎟   ⎜          ⎜                 ⎜                     ⎪           ╱  2                         ╱  2              ⎪⎟⎟⎟
⎜           ⎜                 ⎜                     ⎨ y - 3   ╲╱  y  + 22⋅y + 13   y - 3   ╲╱  y  + 22⋅y + 13  ⎬⎟⎟⎟   ⎜          ⎜                 ⎜                     ⎨ y - 3   ╲╱  y  + 22⋅y + 13   y - 3   ╲╱  y  + 22⋅y + 13  ⎬⎟⎟⎟
⎜(-∞, -2) \ ⎜(ℝ ∩ {-y - 1}) ∪ ⎜(ℝ ∩ {-2, -y - 1}) \ ⎪ ───── - ───────────────────, ───── + ─────────────────── ⎪⎟⎟⎟ ∪ ⎜(-2, ∞) \ ⎜(ℝ ∩ {-y - 1}) ∪ ⎜(ℝ ∩ {-2, -y - 1}) \ ⎪ ───── - ───────────────────, ───── + ─────────────────── ⎪⎟⎟⎟
⎝           ⎝                 ⎝                     ⎩   4              4             4              4          ⎭⎠⎠⎠   ⎝          ⎝                 ⎝                     ⎩   4              4             4              4          ⎭⎠⎠⎠

这让我感到解决方案极为复杂,也可以写成一系列的补码和联合:

>>> Reals - FiniteSet(-y-1) - FiniteSet(-2) + FiniteSet((y - 3)/4 - sqrt(y**2 + 22*y + 13)/4, (y - 3)/4 + sqrt(y**2 + 22*y + 13)/4)
                     ⎧        ________________             ________________     ⎫
                     ⎪       ╱  2                         ╱  2                  ⎪
                     ⎨ y   ╲╱  y  + 22⋅y + 13    3  y   ╲╱  y  + 22⋅y + 13    3 ⎬
(ℝ \ {-2, -y - 1}) ∪ ⎪ ─ - ─────────────────── - ─, ─ + ─────────────────── - ─ ⎪
                     ⎩ 4            4            4  4            4            4 ⎭

我已经搜索了文档,但是没有找到任何方法来简化诸如此类的复杂集合表达式。是否存在这样的方法?如果没有,我该如何编写一个函数来完成此任务?

我正在寻找一种尽可能通用的解决方案,并希望将其应用于除此以外的许多情况,这只是一个示例。显然,集合的“最简单”表示形式不是很好定义的,但是就sympy而言,我认为我们可以说它应该使用最少数量的集合对象来表征集合,并且应该使集合元素的重复最少。例如,上面的初始输出多次调用Reals集合,而实际上只需要一次调用Reals,然后顺序应用任何排除项或包含项,直到对该集合进行完全表征。

python set sympy symbolic-math
1个回答
0
投票

自上一发行版(1.5)以来,这似乎在sympy master上有所改善。与主人我得到

In [1]: from sympy.calculus.util import continuous_domain                                                                         

In [2]: x, y = symbols('x, y')                                                                                                    

In [3]: f = (1-x)/(2+x) - 3*(x-y)/(1+x+y)                                                                                         

In [4]: continuous_domain(f, x, S.Reals)                                                                                          
Out[4]: ((-∞, -2) \ (ℝ ∩ {-y - 1})) ∪ ((-2, ∞) \ (ℝ ∩ {-y - 1}))

您可以通过声明y为真实值来改善这一点:

In [5]: x, y = symbols('x, y', real=True)                                                                                         

In [6]: f = (1-x)/(2+x) - 3*(x-y)/(1+x+y)                                                                                         

In [7]: continuous_domain(f, x, S.Reals)                                                                                          
Out[7]: ((-∞, -2) ∪ (-2, ∞)) \ {-y - 1}
© www.soinside.com 2019 - 2024. All rights reserved.