我使用二分法实现了用一个变量找到方程的根。那里的本质是:段被分成两半几次。如果段中间的函数为零或小于指定的错误,则找到根。否则,我们继续划分,然后将其左、右“边界”作为段的边界。
我将结果的输出组织在一个包装函数中,这样这个输出功能就不会影响主任务执行时间的计算——寻找根。
除其他事项外,还需要指示迭代次数(段被分成两半的次数)。正如我现在所做的(我自己也明白出了什么问题),它不起作用。错误:
NameError:名称“计数器”未定义
怎样成为?编码:
import numpy as np
def print_dichotomy(dichotomy):
def wrapper(a,b,n, eps):
print('Корни по методу дихотомии находятся в точках:')
print(', '.join(map(lambda x: f'{x:.4f}', res)))
print('Количество итераций: ', counter) # ЗДЕСЬ ОШИБКА
return wrapper
def f(x):
return 1.2-np.log(x)-4*np.cos(2*x)
@print_dichotomy
def dichotomy (a,b,n, eps): # отрезок от a до b делим на n частей, погрешность eps
"""
Функция отделения и уточнения корня
"""
assert a!=0, 'a равно 0'
assert b!=0, 'b равно 0'
# сначала отделим корни
grid=np.linspace(a, b, n)
# далее уточним корни
counter=0
for x,y in zip(grid, grid[1:]):
if f(x) * f(y) > 0: # если на отрезке нет корня, смотрим следующий
continue
root = None
while ( abs(f(y)-f(x)) )>eps: # пока отрезок больше заданной погрешности, выполняем нижестоящие операции:
mid = (y+x)/2 # получаем середину отрезка
if f(mid) == 0 or f(mid)<eps: # если функция в середине отрезка равну нулю или меньше погрешности:
root = mid # корень равен серединному значению
counter+=1
break
elif (f(mid) * f(x)) < 0: # иначе если произведение функции в середине отрезка на функцию в т. а <0
y = mid # серединой становится точка b
else:
x = mid #в другом случае - точка а
if root:
yield root
您收到错误,因为 counter 是二分法函数的局部变量。它只存在于这个函数的范围内。在这个函数之外,这个变量是不可见的。
并且由于二分法函数没有返回计数器变量的值作为其工作的结果,无论如何,在函数结束时,计数器变量不再存在。
因此,您需要重新定义 counter ,使其不在本地范围内,而是在全局范围内。为此,您可以在二分法函数中使用全局语句。这不是最漂亮的解决方案,但它会解决您的问题。因此,counter变成了一个全局变量,我们在调用二分法函数之前对其进行了初始化。现在我们可以在执行二分法函数后使用计数器变量的值。
我想提请注意的第二点是,我没有看到您调用传递给它的函数的包装函数内部。因此,出现另一个错误,即未定义 res 变量。相反,您只需调用 print_dichotomy 函数的参数中收到的原始函数。
由于上述原因,代码可能如下所示: