python - 如何修复 TypeError:“添加”对象不可调用?
问题描述
def f(x):
f='exp(x)-x-2'
y=eval(f)
print(y)
return y
def bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2):
x=a
result_a=f(a)
x=b
result_b=f(b)
if (f.evalf(a)*f.evalf(b)>=0):
print("Interval [a,b] does not contain a zero ")
exit()
zeta=min(epsilon1,epsilon2)/10
x=a
while(f_line(x)>0):
if(x<b or x>-b):
x=x+zeta
else:
stop
ak=a
bk=b
xk=(ak+bk)/2
k=0
if (f(xk)*f(ak)<0):
ak=ak
bk=xk
if (f(xk)*f(bk)<0):
ak=xk
bk=bk
k=k+1
from sympy import *
import math
x=Symbol('x')
f=exp(x)-x-2
f_line=f.diff(x)
f_2lines=f_line.diff(x)
print("Derivative of f:", f_line)
print("2nd Derivative of f:", f_2lines)
a=int(input('Beginning of interval: '))
b=int(input('End of interval: '))
epsilon1=input('1st tolerance: ')
epsilon2=input('2nd tolerance: ')
bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2)
该程序是实施二分法的尝试。我试过写两个函数:
第一个 f 应该接收可能包含或不包含根(a 和 b)的区间的极值,并返回在这一点上评估的函数的值。
第二个,二等分,应该接收函数、函数的一阶和二阶导数、区间的极值 (a,b) 和两个容差 (epsilon1,epsilon2)。
我想要做的是将每个值a和b,一次一个,作为函数f的参数,它应该返回f(a)和f(b);也就是说,函数在每个点 a 和 b 中的值。
然后,它应该测试两个条件:1)如果在区间的极端函数值具有相反的符号。如果他们不这样做,该方法将不会在此时间间隔内收敛,那么程序应该终止。
if(f.evalf(a)*f.evalf(b)>=0)
exit()
2)
while(f_line(x)>0): #while the first derivative of the function evaluated in x is positive
if(x<b or x>-b): #This should test whether x belongs to the interval [a,b]
x=x+zeta #If it does, x should receive x plus zeta
else:
stop
在这个循环结束时,我的目标是确定一阶导数是否严格为正(我还没有做负例)。
问题:我收到了错误
Traceback (most recent call last):
File "bissec.py", line 96, in <module>
bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2)
File "bissec.py", line 41, in bissection
result_a=f(a)
TypeError: 'Add' object is not callable
如何正确调用该函数,以便它为每个需要的 x 返回函数的值(在本例中为 f(x)=exp(x)-x-2)?也就是说,我如何评估 f(a) 和 f(b)?
解决方案
好的,所以我已经弄清楚您的程序在哪里失败了,我有 4 个原因。
首先,你的问题的主要主题是,如果你想评估一个函数f
以获得一个确定x
的值,比如说a
,你需要使用f.subs(x, a).evalf()
,正如SymPy 文档中描述的那样。您以两种不同的方式使用:f.evalf(2)
和f_line(a)
; 两者都是错误的,需要用正确的语法代替。
其次,如果您想停止 while 循环,您应该使用break
代码中所写的关键字,而不是“停止”。
第三,避免对变量和函数使用相同的名称。在您的f
函数中,您还用作f
变量的名称。在bissection
函数中,您f
作为参数传递并尝试调用该f
函数。那也会失败。相反,我已将f
函数更改为f_calc
,并在其中应用了我第一点的正确语法。
第四,您的epsilon1
和epsilon2
输入缺少float()
转换。我已经添加了。
现在,我还编辑了您的代码以使用良好实践并应用PEP8。
此代码应修复您遇到的此错误以及其他一些错误:
from sympy import *
def func_calc(func, x, val):
"""Evaluate a given function func, whose varible is x, with value val"""
return func.subs(x, val).evalf()
def bissection(x, f, f_line, f_2lines, a, b, epsilon1, epsilon2):
"""Applies the Bissection Method"""
result_a = func_calc(f, x, a)
result_b = func_calc(f, x, b)
if (result_a * result_b >= 0):
print("Interval [a,b] does not contain a zero")
exit()
zeta = min(epsilon1, epsilon2) / 10
x_val = a
while(func_calc(f_line, x, a) > 0):
if(-b < x_val or x_val < b):
x_val = x_val + zeta
else:
break # the keyword you're looking for is break, instead of "stop"
print(x_val)
ak = a
bk = b
xk = (ak + bk) / 2
k = 0
if (func_calc(f, x, xk) * func_calc(f, x, ak) < 0):
ak = ak
bk = xk
if (func_calc(f, x, xk) * func_calc(f, x, bk) < 0):
ak = xk
bk = bk
k = k + 1
def main():
x = Symbol('x')
f = exp(x) - x - 2
f_line = f.diff(x)
f_2lines = f_line.diff(x)
print("Derivative of f:", f_line)
print("2nd Derivative of f:", f_2lines)
a = int(input('Beginning of interval: '))
b = int(input('End of interval: '))
epsilon1 = float(input('1st tolerance: '))
epsilon2 = float(input('2nd tolerance: '))
bissection(x, f, f_line, f_2lines, a, b, epsilon1, epsilon2)
if __name__ == '__main__':
main()
推荐阅读
- javascript - 更新嵌套数组中的元素,不可变
- c++ - 检查基类对象的子类 - 继承
- swift - 关于 swift 中的通用柯里化
- python - 无法使用 Flask 和 Nameko 连接到 RabbitMQ
- google-cloud-platform - 使用面部识别来识别照片集中有多少个独特的面孔
- spring - 如何在 Redis 会话中使用 Spring Boot 身份验证
- java - 构造函数 PlainTextByLineStream(StringReader) 未定义
- swift - 分离视图控制器的数据不起作用
- r - R正则表达式匹配字符串的开头和结尾,忽略中间
- bash - 在使用 '=~' 的 Bash 测试中如何匹配 '[default]'?