Как улучшить функцию? Написал программу для решения нелинейных уравнений, но решает только простые, при вводе мат.функций просто зависает, помогите
from tkinter import *
import tkinter as tk
import math
import matplotlib.pyplot as plt
import numpy as np
win = Tk()
f_entry = tk.Entry(win, width=50)
a_entry = tk.Entry(win, width=20)
b_entry = tk.Entry(win, width=20)
result_label_delenie = tk.Label(win, text='Root value: ')
err_label = tk.Label(win, text='', foreground="Red")
def init_gui():
win.title('Нелинейные уравнения')
win.geometry('500x500')
f_label = tk.Label(win, text='Функция:')
f_label.pack()
f_entry.pack()
a_label = tk.Label(win, text='Начальная точка')
a_label.pack()
a_entry.pack()
b_label = tk.Label(win, text='Конечная точка')
b_label.pack()
b_entry.pack()
err_label.pack()
err_label.pack()
calc_button = tk.Button(win, text='Calculate', command=button_handler)
calc_button.pack()
result_label_delenie.pack()
return win
def chord_method(f, a, b, eps) -> float:
# метод хорд
fa, fb = f(a), f(b)
iter = 0
while abs(b - a) > eps:
c = (a*fb - b*fa) / (fb - fa)
fc = f(c)
if fc == 0:
return c
elif fa*fc < 0:
b, fb = c, fc
else:
a, fa = c, fc
return (a + b) / 2
def tangent_method(f, dummy, x0, eps) -> float:
# метод касательных
f0 = f(x0)
iter = 0
df = lambda x: (f(x + eps) - f(x)) / eps
while abs(f0) > eps:
iter += 1
x0 -= f0 / df(x0)
f0 = f(x0)
return x0
def bisection_method(f, a, b, eps) -> float:
"""
Метод половинного деления для нахождения одного корня
"""
fa = f(a)
fb = f(b)
iter = 0
while (b - a) / 2 > eps:
c = (a + b) / 2
fc = f(c)
iter += 1
if abs(fc) < 0.1:
return c
elif fa * fc < 0:
b = c
fb = fc
else:
a = c
fa = fc
def button_handler():
try:
f_str = f_entry.get()
a = float(a_entry.get())
b = float(b_entry.get())
except:
err_label.config(text='Ошибка')
return
if a > b:
err_label.config(text='Ошибка')
return
elif len(f_str) == 0:
err_label.config(text='Ошибка')
return
else:
err_label.config(text='')
func = lambda x: eval(f_str, {'__builtins__': None, 'x': x}, math.__dict__)
result_label_delenie.config(text=solve_equation(func, a, b))
plot_function(func, a, b)
def solve_equation(user_f, a, b, eps = 1e-6) -> str:
results = []
funcs = [('Метод касательных', tangent_method)
, ('Метод хорд', chord_method)
, ('Метод половинного деления', bisection_method)]
for func in funcs:
results.append(func[0] + ': ')
try:
results.append(str(func[1](user_f, a, b, eps)))
except Exception as ex:
results.append(str(ex))
finally:
results.append('\n')
return ''.join(results)
def plot_function(f, a, b):
x = np.linspace(a, b, 1000)
y = f(x)
plt.plot(x, y)
ax = plt.gca()
ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
plt.xlabel('x')
plt.ylabel('y')
plt.title('График функции')
plt.show()
if __name__ == "__main__":
win = init_gui()
win.mainloop()
Источник: Stack Overflow на русском