Не получается достигнуть указанной точности по функции
Никак не получается доработать программу так, чтобы достигались обе указанные точности: и по функции и по аргументу. Причем если вы посмотрите, можете сказать, что точности достигаются. Но когда я выбираю интервал [-15;15] (например, чтобы вошли все корни), то точности для 4 корня оказываются не достигнуты... Не понимаю в чем проблема.
def main(np):
import time
# Определение функции
def f(x):
return 8 * np.cos(x) - x - 6
# Метод дихотомии
def dichotomy(f, a, b, eps1, eps2):
# Начальные значения функции в точках a и b
fa = f(a)
fb = f(b)
if fa * fb >= 0:
raise ValueError("Функция должна иметь разные знаки на концах интервала [a, b].")
iter_col = 0
func_eval_col = 2 # Так как функцию уже вычислили дважды выше
x_prev = a
x_curr = b
x_next = (a + b) / 2.0
# Список для хранения предыдущих значений корней
x_vals = [x_prev, x_curr]
while (abs(b - a) / 2.0 >= eps1) or ((abs(f(x_next))) >= eps2):
iter_col += 1
x_next = (a + b) / 2.0 # Середина интервала
fc = f(x_next)
func_eval_col += 1 # Увеличение количества вычислений функции
# Изменение границ интервала
if fa * fc < 0:
b = x_next
fb = fc
else:
a = x_next
fa = fc
x_vals.append(x_next) # Добавление текущего значения в список
# Вычисление параметра сходимости
if len(x_vals) >= 3:
alpha = abs((x_vals[-1] - x_vals[-2]) / (x_vals[-2] - x_vals[-3]))
else:
alpha = None
root = (a + b) / 2.0 # Корень - середина интервала
# Погрешность
error = abs(b - a) / 2.0
func_error = abs(f(root)) # Абсолютное значение функции в корне
return {
"root": root,
"f(root)": f(root),
"iterations": iter_col,
"function_evaluations_dichotomy": func_eval_col, # Количество вычислений функции в методе дихотомии
"convergence_param": alpha,
"error": error,
"func_error": func_error
}
# Поиск всех корней на интервале [a, b]
def find_all_roots(f, a, b, eps1, eps2, step):
start_time = time.time() # Время начала выполнения программы
roots = []
total_iterations = 0
total_func_evals_dichotomy = 0 # Количество вычислений функции в методе дихотомии
func_eval_separation = 0 # Счетчик вычислений функции при отделении корней
x = a
fx = f(x) # Первоначальное вычисление функции
func_eval_separation += 1
while x < b:
next_x = x + step
next_fx = f(next_x)
func_eval_separation += 1
if fx * next_fx < 0: # Проверка смены знака функции на интервале
try:
root_data = dichotomy(f, x, next_x, eps1, eps2)
roots.append(root_data)
total_iterations += root_data['iterations']
total_func_evals_dichotomy += root_data['function_evaluations_dichotomy']
except ValueError:
pass # Пропуск интервала, если нет смены знака
x = next_x
fx = next_fx
total_time_end = time.time() - start_time # Общее время выполнения программы
return {
"roots": roots,
"total_iterations": total_iterations,
"total_func_evals_dichotomy": total_func_evals_dichotomy,
"func_eval_separation": func_eval_separation,
"total_time_elapsed": total_time_end
}
# Ввод данных
a = float(input("Введите начало интервала a: "))
b = float(input("Введите конец интервала b: "))
eps1 = float(input("Введите точность по аргументу через точку: "))
eps2 = float(input("Введите точность по функции через точку: "))
step = 1.47
# Поиск корней
results = find_all_roots(f, a, b, eps1, eps2, step)
# Вывод результатов
if results["roots"]:
for i, root_data in enumerate(results["roots"], 1):
print(f"Корень {i}: ξ = {root_data['root']:.5f}")
print(f"Значение функции f(ξ): {root_data['f(root)']:.5f}")
print(f"Погрешность по аргументу: {root_data['error']:.{len(str(root_data['error']).replace('.', '').replace('-', ''))}e}")
print(f"Погрешность по функции: {root_data['func_error']:.{len(str(root_data['func_error']).replace('.', '').replace('-', ''))}e}") # Вывод ошибки по функции
print(f"Параметр сходимости α: {root_data['convergence_param']:.2f}")
print()
print(f"Общее количество итераций n: {results['total_iterations']}")
print(f"Количество вычислений функции при отделении корней: {results['func_eval_separation']}")
print(f"Количество вычислений функции в методе дихотомии: {results['total_func_evals_dichotomy']}")
print(f"Общее количество вычислений функции f(x): {results['func_eval_separation'] + results['total_func_evals_dichotomy']}")
print(f"Общее время счета: {results['total_time_elapsed']:.10f} секунд")
else:
print("На данном интервале корней нет.")
input("Нажмите любую клавишу для завершения программы")