使用 SymPy 的程序出错
Error from program using SymPy
我想使用 SymPy 包来求四阶多项式方程的根。随后,我想将这些根绘制为多项式方程参数的函数。我已经写了下面的代码。它似乎计算一切都很好,但我无法绘制结果,因为我收到错误 "x and y are not of the same dimension"。我想这和我使用SymPy有关系,因为通常它总是这样工作的。
from sympy import *
from math import *
from numpy import *
import pylab as lab
def RootFunc(root, m, c0, r, En):
A = 2*(m**2 - 0.25 - c0**2)/r**2 + 4
B = 8*En*c0/r
C = -4 - 4*En**2 + ((c0**2 + m**2 -.25)/r**2 + 2)**2
return root.subs([(a,A),(b,B),(c,C)])
# Define necessary symbols
x = symbols('x')
a, b, c = symbols('a b c')
En, r = symbols("En r")
# Fix constants
m = 0
c0 = -2
# Solve equation
eq = x**4 + a*x**2 + b*x + c
sol = solve(eq,x)
root1 = sol[0]
grid = linspace(1,10,10)
sol1 = [RootFunc(root1, m, c0, r, .5) for r in grid]
lab.figure(1)
lab.plot(grid,sol1)
lab.show()
您确定您 运行 与您在这里给我们的脚本相同吗?
我这么说是因为我可以逐字复制和粘贴您的示例,而且它绝对没有问题。
检查完毕后,您能否post请问您使用的 Python、SymPy、NumPy 和 Matplotlib 是哪个版本?
编辑: 我认为当您提出您的第一个最小工作示例 (MWE) 时,在翻译过程中有些东西丢失了。您的 MWE 中的解决方案具有实际价值,因此它与您的实际程序没有相同的问题。但是,解决方案:
这里的主要问题是这一行
sol1 = [RootFunc(root1, m, c0, help, .5) for help in grid]
RootFunc
在这种情况下 returns a sympy.core.add.Add
其中 pylab
没有概念,因此无法绘制。在您的 MWE 中,您认识到这是问题所在,并尝试在 return 值上调用 N()
和 real()
。不幸的是,这只是将 sympy.core.add.Add
对象包装在 NumPy 数组中。当 Pylab 尝试绘制此数组时,它会找到一个它没有概念的 sympy.core.add.Add
对象,因此只会抛出错误。
幸运的是,SymPy 允许您使用 int()
、float()
或 complex()
将 sympy.core.add.Add
对象转换为数字。由于您的根很复杂,您应该在 return 值上使用 complex()
,然后使用 .real
.
获得真正的组件
因此,为了让它也能正常工作,您只需将上面的行更改为
sol1 = [complex(RootFunc(root1, m, c0, help, .5)).real for help in grid]
Edit2: 关于样式的简要说明。您在代码中使用了很多通配符导入(例如 from numpy import *
),如果您是唯一使用该代码的人,这很好,毕竟它确实使它更整洁。
但是,如果您要 post 访问这样的论坛,请尝试使用合格的导入(就像您为 pylab
所做的那样),这样我们就不会不必费力地阅读您曾经使用过的所有模块的文档来尝试弄清楚您在做什么。
另一件事:当你遇到这样的问题时,在 python shell 中逐行执行并检查类型(使用 type()
)和变量的值(print()
或 repr()
)。为此,我强烈建议您学习如何使用 IPython,因为它真的很有帮助。
您的导入可能会破坏一些东西。你能试试这个吗:
import sympy as sy
import numpy as np
import pylab as lab
def RootFunc(root, A, B):
return root.subs([(a,A),(b,B)])
# Define necessary symbols
x = sy.symbols('x')
a, b = sy.symbols('a b')
# Solve equation
eq = x**4 + a*x**2 + b*x
sol = sy.solve(eq,x)
root1 = sol[1] # first element is trivial solution, so take second one
grid = np.linspace(1,10,10)
sol1 = [np.real(sy.N(RootFunc(root1, 1, x))) for x in grid]
lab.figure(1)
lab.plot(grid,sol1)
lab.show()
我想使用 SymPy 包来求四阶多项式方程的根。随后,我想将这些根绘制为多项式方程参数的函数。我已经写了下面的代码。它似乎计算一切都很好,但我无法绘制结果,因为我收到错误 "x and y are not of the same dimension"。我想这和我使用SymPy有关系,因为通常它总是这样工作的。
from sympy import *
from math import *
from numpy import *
import pylab as lab
def RootFunc(root, m, c0, r, En):
A = 2*(m**2 - 0.25 - c0**2)/r**2 + 4
B = 8*En*c0/r
C = -4 - 4*En**2 + ((c0**2 + m**2 -.25)/r**2 + 2)**2
return root.subs([(a,A),(b,B),(c,C)])
# Define necessary symbols
x = symbols('x')
a, b, c = symbols('a b c')
En, r = symbols("En r")
# Fix constants
m = 0
c0 = -2
# Solve equation
eq = x**4 + a*x**2 + b*x + c
sol = solve(eq,x)
root1 = sol[0]
grid = linspace(1,10,10)
sol1 = [RootFunc(root1, m, c0, r, .5) for r in grid]
lab.figure(1)
lab.plot(grid,sol1)
lab.show()
您确定您 运行 与您在这里给我们的脚本相同吗?
我这么说是因为我可以逐字复制和粘贴您的示例,而且它绝对没有问题。
检查完毕后,您能否post请问您使用的 Python、SymPy、NumPy 和 Matplotlib 是哪个版本?
编辑: 我认为当您提出您的第一个最小工作示例 (MWE) 时,在翻译过程中有些东西丢失了。您的 MWE 中的解决方案具有实际价值,因此它与您的实际程序没有相同的问题。但是,解决方案:
这里的主要问题是这一行
sol1 = [RootFunc(root1, m, c0, help, .5) for help in grid]
RootFunc
在这种情况下 returns a sympy.core.add.Add
其中 pylab
没有概念,因此无法绘制。在您的 MWE 中,您认识到这是问题所在,并尝试在 return 值上调用 N()
和 real()
。不幸的是,这只是将 sympy.core.add.Add
对象包装在 NumPy 数组中。当 Pylab 尝试绘制此数组时,它会找到一个它没有概念的 sympy.core.add.Add
对象,因此只会抛出错误。
幸运的是,SymPy 允许您使用 int()
、float()
或 complex()
将 sympy.core.add.Add
对象转换为数字。由于您的根很复杂,您应该在 return 值上使用 complex()
,然后使用 .real
.
因此,为了让它也能正常工作,您只需将上面的行更改为
sol1 = [complex(RootFunc(root1, m, c0, help, .5)).real for help in grid]
Edit2: 关于样式的简要说明。您在代码中使用了很多通配符导入(例如 from numpy import *
),如果您是唯一使用该代码的人,这很好,毕竟它确实使它更整洁。
但是,如果您要 post 访问这样的论坛,请尝试使用合格的导入(就像您为 pylab
所做的那样),这样我们就不会不必费力地阅读您曾经使用过的所有模块的文档来尝试弄清楚您在做什么。
另一件事:当你遇到这样的问题时,在 python shell 中逐行执行并检查类型(使用 type()
)和变量的值(print()
或 repr()
)。为此,我强烈建议您学习如何使用 IPython,因为它真的很有帮助。
您的导入可能会破坏一些东西。你能试试这个吗:
import sympy as sy
import numpy as np
import pylab as lab
def RootFunc(root, A, B):
return root.subs([(a,A),(b,B)])
# Define necessary symbols
x = sy.symbols('x')
a, b = sy.symbols('a b')
# Solve equation
eq = x**4 + a*x**2 + b*x
sol = sy.solve(eq,x)
root1 = sol[1] # first element is trivial solution, so take second one
grid = np.linspace(1,10,10)
sol1 = [np.real(sy.N(RootFunc(root1, 1, x))) for x in grid]
lab.figure(1)
lab.plot(grid,sol1)
lab.show()