代数表达式的符号简化,由复数组成

huangapple go评论68阅读模式
英文:

Symbolic simplification of algebraic expressions composed of complex numbers

问题

对于表达式 expr1expr2,您观察到 simplify 函数的输出不同,尽管这两个表达式在代数上是相等的。要使 simplifyexpr1expr2 的结果相同,您可以使用 powsimp 函数,如下所示:

from sympy import *

expr1 = 3*(2 - 11*I)**Rational(1, 3)*(2 + 11*I)**Rational(2, 3)
expr2 = 3*((2 - 11*I)*(2 + 11*I))**Rational(1, 3)*(2 + 11*I)**Rational(1, 3)

expr1 = powsimp(expr1)
expr2 = powsimp(expr2)

print("expr1 = {0}".format(expr1))
print("expr2 = {0}\n".format(expr2))
print("simplify(expr1) = {0}".format(simplify(expr1)))
print("simplify(expr2) = {0}\n".format(simplify(expr2))
print("expand(expr1) = {0}".format(expand(expr1)))
print("expand(expr2) = {0}\n".format(expand(expr2))
print("expr1.equals(expr2) = {0}".format(expr1.equals(expr2)))

这将使用 powsimp 函数将幂次表达式进行简化,使 expr1expr2 的简化结果相同。

希望这有助于解决您的问题。

英文:

I have a question concerning the symbolic simplification of algebraic expressions composed of complex numbers. I have executed the following Python script:

from sympy import *

expr1 = 3*(2 - 11*I)**Rational(1, 3)*(2 + 11*I)**Rational(2, 3)
expr2 = 3*((2 - 11*I)*(2 + 11*I))**Rational(1, 3)*(2 + 11*I)**Rational(1, 3)

print("expr1 = {0}".format(expr1))
print("expr2 = {0}\n".format(expr2))
print("simplify(expr1) = {0}".format(simplify(expr1)))
print("simplify(expr2) = {0}\n".format(simplify(expr2)))
print("expand(expr1) = {0}".format(expand(expr1)))
print("expand(expr2) = {0}\n".format(expand(expr2)))
print("expr1.equals(expr2) = {0}".format(expr1.equals(expr2)))

The output is:

expr1 = 3*(2 - 11*I)**(1/3)*(2 + 11*I)**(2/3)
expr2 = 3*((2 - 11*I)*(2 + 11*I))**(1/3)*(2 + 11*I)**(1/3)

simplify(expr1) = 3*(2 - 11*I)**(1/3)*(2 + 11*I)**(2/3)
simplify(expr2) = 15*(2 + 11*I)**(1/3)

expand(expr1) = 3*(2 - 11*I)**(1/3)*(2 + 11*I)**(2/3)
expand(expr2) = 15*(2 + 11*I)**(1/3)

expr1.equals(expr2) = True

My questions is why the simplifications does not work for expr1 but
works for expr2 thoug the expressions are algebraically equal.
What has to be done to get the same result from simplify for expr1 as for expr2?

Thanks in advance for your replys.

Kind regards

Klaus

答案1

得分: 1

你可以使用最小多项式将代数数放入规范表示:

In [30]: x = symbols('x')

In [31]: p1 = minpoly(expr1, x, polys=True)

In [32]: p2 = minpoly(expr2, x, polys=True)

In [33]: p1
Out[33]: Poly(x**2 - 60*x + 1125, x, domain='QQ')

In [34]: p2
Out[34]: Poly(x**2 - 60*x + 1125, x, domain='QQ')

In [35]: [r for r in p1.all_roots() if p1.same_root(r, expr1)]
Out[35]: [30 + 15ⅈ]

In [36]: [r for r in p2.all_roots() if p2.same_root(r, expr2)]
Out[36]: [30 + 15ⅈ]

这种方法对于通过代数运算表示代数数的任何两个表达式都应该适用:它们要么给出完全相同的结果,要么它们是不同的数。

英文:

You can use the minimal polynomial to place algebraic numbers into a canonical representation:

In [30]: x = symbols('x')

In [31]: p1 = minpoly(expr1, x, polys=True)

In [32]: p2 = minpoly(expr2, x, polys=True)

In [33]: p1
Out[33]: Poly(x**2 - 60*x + 1125, x, domain='QQ')

In [34]: p2
Out[34]: Poly(x**2 - 60*x + 1125, x, domain='QQ')

In [35]: [r for r in p1.all_roots() if p1.same_root(r, expr1)]
Out[35]: [30 + 15⋅ⅈ]

In [36]: [r for r in p2.all_roots() if p2.same_root(r, expr2)]
Out[36]: [30 + 15⋅ⅈ]

This method should work for any two expressions representing algebraic numbers through algebraic operations: either they give the precise same result or they are distinct numbers.

答案2

得分: 0

这段代码中,主要是讨论SymPy库中的根式处理和表达式相等性的问题。以下是其中的翻译部分:

  • 对于 expr1,它在“名义上”有效,因为当在根式中的乘积展开时,得到的立方根为125,而这被报告为5。但SymPy试图谨慎地将根式合并在一个公共指数下,这不是通常有效的操作(例如,root(-1, 3)*root(-1,3) != root(1, 3),因为使用了根的主值)。但如果你希望底数在一个公共指数下合并,你可以使用 powsimp 强制执行:
from sympy.abc import x, y
from sympy import powsimp, root
powsimp(root(x,3)*root(y,3), force=True)

这将得到 (x*y)**(1/3)

  • 但这仅在指数相同时有效,如果指数不同,例如:
powsimp(root(x,3)*root(y,3)**2, force=True)

这将得到 x**(1/3)*y**(2/3)

  • 作者提到了使用 equals 来比较两个表达式是否相同。通过解 expr1 - expr2,可以找到与之相同的表达式。

  • 最后,作者使用 numertogetherpowsimpexpand 来展示两个表达式相等。最终证明了这两个表达式是相同的。

希望这有助于理解代码中的内容。

英文:

It works (but nominally) for expr1 because when the product in the radical is expanded you get the cube root of 125 which is reported as 5. But SymPy tries to be careful about putting radicals together under a common exponent, an operation that is not generally valid (e.g. root(-1, 3)*root(-1,3) != root(1, 3) because the principle values are used for the roots. But if you want the bases to combine under a common exponent, you can force it to happen with powsimp:

>>> from sympy.abc import x, y
>>> from sympy import powsimp, root, solve, numer, together
>>> powsimp(root(x,3)*root(y,3), force=True)
(x*y)**(1/3)

But that only works if the exponents are the same:

>>> powsimp(root(x,3)*root(y,3)**2, force=True)
x**(1/3)*y**(2/3)

As you saw, equals was able to show that the two expressions were the same. One way this could be done is to solve for root(2 + 11*I, 3) and see if any of the resulting expression are the same:

>>> solve(expr1 - expr2, root(2 + 11*I,3))
[0, 5/(2 - 11*I)**(1/3)]

We can check the non-zero candidate:

>>> numer(together(_[1]-root(2+11*I,3)))
-(2 - 11*I)**(1/3)*(2 + 11*I)**(1/3) + 5
>>> powsimp(_, force=True)
5 - ((2 - 11*I)*(2 + 11*I))**(1/3)
>>> expand(_)
0

So we have shown (with force) that the expression was the same as that for which we solved. (And, as Oscar showed while I was writing this, minpoly is a nice candidate when it works: e.g. minpoly(expr1-expr2) -> x which means expr1 == expr2.)

huangapple
  • 本文由 发表于 2023年2月19日 08:27:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497274.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定