Milkmaid and Cow Problem Display Matplotlib
unknown
python
a year ago
4.5 kB
7
Indexable
import numpy as np import matplotlib.pyplot as plt import scipy.optimize from matplotlib.widgets import Slider import random from matplotlib import style def find_root(a, b, x_1, x_2, y_1, y_2, tol=1e-5, max_iter=100): if distanceDeriv(a, x_1, x_2, y_1, y_2) * distanceDeriv(b, x_1, x_2, y_1, y_2) > 0: return None # No root in this interval for _ in range(max_iter): c = (a + b) / 2 if distanceDeriv(c, x_1, x_2, y_1, y_2) == 0 or (b - a) / 2 < tol: return c # Found the root within tolerance if distanceDeriv(c, x_1, x_2, y_1, y_2) * distanceDeriv(a, x_1, x_2, y_1, y_2) < 0: b = c else: a = c return (a + b) / 2 # Return the midpoint as an approximation def secureRoot(a, b, x_1, x_2, y_1, y_2): root = None while root is None: root = find_root(a, b, x_1, x_2, y_1, y_2, tol=1e-5, max_iter=100) if distanceDeriv((root-0.0000001), x_1, x_2, y_1, y_2) < 0 and distanceDeriv((root+0.0000001), x_1, x_2, y_1, y_2) > 0 and root is not None: return root if root is None: while root is None: a = random.randint(-10, 10) b = random.randint(-10, 10) if a > b: a = random.randint(-10, 10) b = random.randint(-10, 10) root = find_root(a, b, x_1, x_2, y_1, y_2, tol=1e-5, max_iter=100) return root # Create the figure and axis fig, ax = plt.subplots() plt.subplots_adjust(bottom=0.30) def f(x): return x**2 def df(x): return 2*x def distanceDeriv(x, x_1, x_2, y_1, y_2): return ((x-x_1)+df(x)*(f(x)-y_1))/(((x-x_1)**2+(f(x)-y_1)**2)**(1/2)) + ((x-x_2)+df(x)*(f(x)-y_2))/(((x-x_2)**2+(f(x)-y_2)**2)**(1/2)) # Define the initial values for a, b, and c initial_x_1 = 1.0 initial_x_2 = 1.0 initial_y_1 = 0.0 initial_y_2 = 0.0 InitialPointsX = [initial_x_1, initial_x_2, secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2)] InitialPointsY = [initial_y_1, initial_y_2, f(secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2))] # Define the function to plot x = np.linspace(-10, 10, 400) initial_y = distanceDeriv(x, initial_x_1, initial_x_2, initial_y_1, initial_y_2) #Uncomment this if you wanna see the derivative function #line, = ax.plot(x, initial_y, label='D\'(x)') PointandLine1, = ax.plot([initial_x_1, secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2)], [initial_y_1, f(secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2))], 'ro-') PointandLine2, = ax.plot([secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2), initial_x_2], [f(secureRoot(-10, 10, initial_x_1, initial_x_2, initial_y_1, initial_y_2)), initial_y_2], 'ro-') # Define sliders slider_x_1 = Slider(plt.axes([0.1, 0.20, 0.8, 0.03]), label='x_1', valmin=x.min(), valmax=x.max(), valinit=initial_x_1, valstep=0.1) slider_x_2 = Slider(plt.axes([0.1, 0.10, 0.8, 0.03]), label='x_2', valmin=x.min(), valmax=x.max(), valinit=initial_x_2, valstep=0.1) slider_y_1 = Slider(plt.axes([0.1, 0.15, 0.8, 0.03]), label='y_1', valmin=-f(x.min()), valmax=f(x.max()), valinit=initial_y_1, valstep=0.1) slider_y_2 = Slider(plt.axes([0.1, 0.05, 0.8, 0.03]), label='y_2', valmin=-f(x.min()), valmax=f(x.max()), valinit=initial_y_2, valstep=0.1) ax.plot(x,f(x)) cow = ax.annotate("Cow", xy=(initial_x_2, initial_y_2), xytext=(initial_x_2-0.55, initial_y_2+3)) milkmaid = ax.annotate("Milkmaid", xy=(initial_x_1, initial_y_1), xytext=(initial_x_1-1.25, initial_y_1+3)) #Define function to update plot when sliders change def update(val): x_1 = slider_x_1.val x_2 = slider_x_2.val y_1 = slider_y_1.val y_2 = slider_y_2.val root = secureRoot(-10, 10, x_1, x_2, y_1, y_2) y = distanceDeriv(x, x_1, x_2, y_1, y_2) #Uncomment this if you wanna see the derivative function #line.set_ydata(y) #line.set_label('D\'(x)') PointandLine1.set_xdata([x_1, root]) PointandLine1.set_ydata([y_1, f(root)]) PointandLine2.set_xdata([root, x_2]) PointandLine2.set_ydata([f(root), y_2]) print(root) cow.set_x(x_2-0.55) cow.set_y(y_2+3) milkmaid.set_x(x_1-1.25) milkmaid.set_y(y_1+3) plt.draw() slider_x_1.on_changed(update) slider_x_2.on_changed(update) slider_y_1.on_changed(update) slider_y_2.on_changed(update) plt.show()
Editor is loading...
Leave a Comment