为什么 sympy 的 lambdify 函数在我的案例中会抛出错误?
Why does the lambdify function from sympy throw an error in my case?
错误在于lambdify函数。由于某种原因,它说语法错误。
这正是所说的:
File "D:\Anaconda\lib\site-packages\sympy\utilities\lambdify.py", line 434, in lambdify func = eval(lstr, namespace).
程序在用户输入公差后立即崩溃。这是一个牛顿法程序(或者至少是我的尝试)。任何关于如何改进此代码的建议也将不胜感激。
我为 f
和 dfdx
输入的内容如下:
x**3 + 3*x + 5
和
3*x**2 + 3
分别。至于v0
和eps
,我分别输入1
和0.000001
。无论我输入什么,程序都会以上述错误终止(假设它使用 x 作为变量,否则它会说未定义,就是这样)。
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f = lambda x : eval('input("Enter the function: ")')
dfdx = lambda x : eval('input("Enter the derivative: ")')
x=sympy.symbols('x')
func = sympy.lambdify(f,x)
deriv = sympy.lambdify(f,x)
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value)/deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
Newton(func,deriv,v0,eps)
AFAIU 你狡猾的计划是首先使用 Python 解释器从用户的字符串构建一个函数(使用 input
),然后使用 SymPy 从中构建一个可重用的函数。您的代码存在一些问题,最重要的可能是您错误地获取了 SymPy 方法的签名。
另外,提供 dfdx
作为输入的想法对我来说也不太好。如果原始函数 f
有一个很好的导数可以计算,SymPy 可能可以自己计算它。
所以如果你修正了一些明显的错误,你可能会得到这样的代码:
Python 3.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: eval(input("Enter the function: "))
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print (Newton(func, deriv, v0, eps))
Python 2.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: input("Enter the function: ")
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print Newton(func, deriv, v0, eps)
您输入的内容
1
0.000001
x**3 + 3*x + 5
产生以下输出:
(-1.154171557329764, 5)
2.x 和 3.x 版本之间的主要区别在于 input
in 2.x calls eval
inside while input
in 3.x 没有。
错误在于lambdify函数。由于某种原因,它说语法错误。 这正是所说的:
File "D:\Anaconda\lib\site-packages\sympy\utilities\lambdify.py", line 434, in lambdify func = eval(lstr, namespace).
程序在用户输入公差后立即崩溃。这是一个牛顿法程序(或者至少是我的尝试)。任何关于如何改进此代码的建议也将不胜感激。
我为 f
和 dfdx
输入的内容如下:
x**3 + 3*x + 5
和
3*x**2 + 3
分别。至于v0
和eps
,我分别输入1
和0.000001
。无论我输入什么,程序都会以上述错误终止(假设它使用 x 作为变量,否则它会说未定义,就是这样)。
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f = lambda x : eval('input("Enter the function: ")')
dfdx = lambda x : eval('input("Enter the derivative: ")')
x=sympy.symbols('x')
func = sympy.lambdify(f,x)
deriv = sympy.lambdify(f,x)
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value)/deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
Newton(func,deriv,v0,eps)
AFAIU 你狡猾的计划是首先使用 Python 解释器从用户的字符串构建一个函数(使用 input
),然后使用 SymPy 从中构建一个可重用的函数。您的代码存在一些问题,最重要的可能是您错误地获取了 SymPy 方法的签名。
另外,提供 dfdx
作为输入的想法对我来说也不太好。如果原始函数 f
有一个很好的导数可以计算,SymPy 可能可以自己计算它。
所以如果你修正了一些明显的错误,你可能会得到这样的代码:
Python 3.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: eval(input("Enter the function: "))
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print (Newton(func, deriv, v0, eps))
Python 2.x
import sympy
import sys
v0 = int(input("Please enter the v0 value: "))
eps = float(input("Please enter the tolerance: "))
f_inp = lambda x: input("Enter the function: ")
x = sympy.symbols('x')
f_symb = f_inp(x)
func = sympy.lambdify(x, f_symb)
deriv = sympy.lambdify(x, sympy.diff(f_symb, x))
def Newton(func, deriv, v0, eps):
f_value = func(v0)
iteration_counter = 0
while abs(f_value) > eps and iteration_counter < 100:
try:
v0 = v0 - float(f_value) / deriv(v0)
except ZeroDivisionError:
print ("Error! - derivative zero for x = ", v0)
sys.exit(1) # Abort with error
f_value = func(v0)
iteration_counter += 1
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1
return v0, iteration_counter
print Newton(func, deriv, v0, eps)
您输入的内容
1
0.000001
x**3 + 3*x + 5
产生以下输出:
(-1.154171557329764, 5)
2.x 和 3.x 版本之间的主要区别在于 input
in 2.x calls eval
inside while input
in 3.x 没有。