Sympy `factor` 和 `simplify` 不能正常工作?
Sympy `factor` and `simplify` not working properly?
由于我正在做一个涉及平方根的项目,我需要将平方根简化到最大。但是,某些平方根表达式不会产生不理想的结果。请考虑检查此示例:
>>> from sympy import * # just an example don't tell me that import * is obsolete
>>> x1 = simplify(factor(sqrt(3 + 2*sqrt(2))))
>>> x1 # notice that factoring doesn't work
sqrt(2*sqrt(2) + 3)
>>> x2 = sqrt(2) + 1
>>> x2
sqrt(2) + 1
>>> x1 == x2
False
>>> N(x1)
2.41421356237309
>>> N(x2)
2.41421356237309
>>> N(x1) == N(x2)
True
如您所见,数字实际上是相等的,但 numpy 无法识别这一点,因为它无法对 x1 进行因式分解和化简。那么我如何获得 x1 的简化形式,以便相等性是正确的,而不必将它们转换为浮点数?
提前致谢。
感谢 Oscar Benjamin,我正在寻找的功能是 sqrtdenest
:
>>> from sympy import *
>>> sqrtdenest(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)
希望这个回答能对其他人有所帮助
当您使用嵌套的 sqrt
表达式时,sqrtdenest
是一个不错的选择。但是一个很好的后备使用是 nsimplify
,它在某些情况下可能更有用。由于这可以给出与输入不完全相同的答案,所以我喜欢使用这个“安全”函数来进行简化:
def safe_nsimplify(x):
from sympy import nsimplify
if x.is_number:
ns = nsimplify(x)
if ns != x and x.equals(ns):
return ns
return x
>>> from sympy import sqrt, sqrtdenest
>>> eq = (-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5))
>>> simplify(eq)
(-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5)) <-- no change
>>> sqrtdenest(eq)
-sqrt(2)/(2*sqrt(sqrt(5) + 5)) + sqrt(10)/(2*sqrt(sqrt(5) + 5)) <-- worse
>>> safe_nsimplify(eq)
sqrt(1 - 2*sqrt(5)/5) <-- better
看你的表情
>>> safe_nsimplify(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)
如果您想在更大的表达式中找到此类表达式,您可以使用
>>> from sympy import bottom_up, tan
>>> bottom_up(tan(eq), safe_nsimplify)
tan(sqrt(1 - 2*sqrt(5)/5))
接受 sqrtdenest
的结果 可能 比
中使用 nsimplify
更有利
def safe_nsimplify(x):
from sympy import nsimplify, sqrtdenest, Pow, S
if x.is_number:
if isinstance(x, Pow) and x.exp is S.Half:
ns = sqrtdenest(x)
if ns != x:
return ns
ns = nsimplify(x)
if ns != x and x.equals(ns):
return ns
return x
由于我正在做一个涉及平方根的项目,我需要将平方根简化到最大。但是,某些平方根表达式不会产生不理想的结果。请考虑检查此示例:
>>> from sympy import * # just an example don't tell me that import * is obsolete
>>> x1 = simplify(factor(sqrt(3 + 2*sqrt(2))))
>>> x1 # notice that factoring doesn't work
sqrt(2*sqrt(2) + 3)
>>> x2 = sqrt(2) + 1
>>> x2
sqrt(2) + 1
>>> x1 == x2
False
>>> N(x1)
2.41421356237309
>>> N(x2)
2.41421356237309
>>> N(x1) == N(x2)
True
如您所见,数字实际上是相等的,但 numpy 无法识别这一点,因为它无法对 x1 进行因式分解和化简。那么我如何获得 x1 的简化形式,以便相等性是正确的,而不必将它们转换为浮点数?
提前致谢。
感谢 Oscar Benjamin,我正在寻找的功能是 sqrtdenest
:
>>> from sympy import *
>>> sqrtdenest(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)
希望这个回答能对其他人有所帮助
当您使用嵌套的 sqrt
表达式时,sqrtdenest
是一个不错的选择。但是一个很好的后备使用是 nsimplify
,它在某些情况下可能更有用。由于这可以给出与输入不完全相同的答案,所以我喜欢使用这个“安全”函数来进行简化:
def safe_nsimplify(x):
from sympy import nsimplify
if x.is_number:
ns = nsimplify(x)
if ns != x and x.equals(ns):
return ns
return x
>>> from sympy import sqrt, sqrtdenest
>>> eq = (-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5))
>>> simplify(eq)
(-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5)) <-- no change
>>> sqrtdenest(eq)
-sqrt(2)/(2*sqrt(sqrt(5) + 5)) + sqrt(10)/(2*sqrt(sqrt(5) + 5)) <-- worse
>>> safe_nsimplify(eq)
sqrt(1 - 2*sqrt(5)/5) <-- better
看你的表情
>>> safe_nsimplify(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)
如果您想在更大的表达式中找到此类表达式,您可以使用
>>> from sympy import bottom_up, tan
>>> bottom_up(tan(eq), safe_nsimplify)
tan(sqrt(1 - 2*sqrt(5)/5))
接受 sqrtdenest
的结果 可能 比
nsimplify
更有利
def safe_nsimplify(x):
from sympy import nsimplify, sqrtdenest, Pow, S
if x.is_number:
if isinstance(x, Pow) and x.exp is S.Half:
ns = sqrtdenest(x)
if ns != x:
return ns
ns = nsimplify(x)
if ns != x and x.equals(ns):
return ns
return x