Spaces:
Sleeping
Sleeping
File size: 7,829 Bytes
fb0e940 9f13c80 fb0e940 da45c29 9f13c80 fb0e940 9f13c80 fb0e940 da45c29 fb0e940 da45c29 fb0e940 da45c29 fb0e940 da45c29 fb0e940 9f13c80 da45c29 9f13c80 da45c29 9f13c80 da45c29 9f13c80 fb0e940 da45c29 9f13c80 fb0e940 da45c29 fb0e940 9f13c80 fb0e940 da45c29 fb0e940 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
def create_error_plot(error_message):
fig, ax = plt.subplots(figsize=(10, 6))
ax.text(0.5, 0.5, error_message, color='red', fontsize=16, ha='center', va='center', wrap=True)
ax.axis('off')
return fig
def linear_interpolation(x, y, x_interp):
return np.interp(x_interp, x, y)
def quadratic_interpolation(x, y, x_interp):
coeffs = np.polyfit(x, y, 2)
return np.polyval(coeffs, x_interp)
def lagrange_interpolation(x, y, x_interp):
n = len(x)
y_interp = np.zeros_like(x_interp, dtype=float)
for i in range(n):
p = y[i]
for j in range(n):
if i != j:
p = p * (x_interp - x[j]) / (x[i] - x[j])
y_interp += p
return y_interp
def newton_forward_interpolation(x, y, x_interp):
n = len(x)
h = x[1] - x[0] # Assuming uniform spacing for simplicity
F = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
F[i][0] = y[i]
for j in range(1, n):
for i in range(n - j):
F[i][j] = F[i+1][j-1] - F[i][j-1]
def newton_forward(x_val):
u = (x_val - x[0]) / h
result = y[0]
term = 1
for i in range(1, n):
term *= (u - i + 1) / i
result += term * F[0][i]
return result
return np.array([newton_forward(xi) for xi in x_interp])
def newton_backward_interpolation(x, y, x_interp):
n = len(x)
h = x[1] - x[0] # Assuming uniform spacing for simplicity
F = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
F[i][0] = y[i]
for j in range(1, n):
for i in range(n - 1, j - 1, -1):
F[i][j] = F[i][j-1] - F[i-1][j-1]
def newton_backward(x_val):
u = (x_val - x[-1]) / h
result = y[-1]
term = 1
for i in range(1, n):
term *= (u + i - 1) / i
result += term * F[n-1][i]
return result
return np.array([newton_backward(xi) for xi in x_interp])
def create_and_edit_plot(x, y, x_interp, y_interp, method, plot_title, x_label, y_label, legend_position, label_size, x_predict=None, y_predict=None):
fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(x, y, color='red', label='Input points')
ax.plot(x_interp, y_interp, label=f'{method} interpolant')
ax.set_xlabel(x_label, fontsize=label_size)
ax.set_ylabel(y_label, fontsize=label_size)
ax.set_title(plot_title, fontsize=label_size + 2)
ax.legend(loc=legend_position, fontsize=label_size - 2)
ax.tick_params(axis='both', which='major', labelsize=label_size - 2)
ax.grid(True)
if x_predict is not None and y_predict is not None:
ax.scatter([x_predict], [y_predict], color='green', s=100, label='Predicted point')
ax.legend(loc=legend_position, fontsize=label_size - 2)
return fig
def interpolate_and_plot(x_input, y_input, x_predict, method, plot_title, x_label, y_label, legend_position, label_size):
try:
x = np.array([float(val.strip()) for val in x_input.split(',')])
y = np.array([float(val.strip()) for val in y_input.split(',')])
except ValueError:
error_msg = "Error: Invalid input. Please enter comma-separated numbers."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
if len(x) != len(y):
error_msg = "Error: Number of x and y values must be the same."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
if len(x) < 2:
error_msg = "Error: At least two points are required for interpolation."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
x_interp = np.linspace(min(x), max(x), 100)
# Interpolation method selection
if method == "Linear":
if len(x) < 2:
error_msg = "Error: At least two points are required for linear interpolation."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
y_interp = linear_interpolation(x, y, x_interp)
elif method == "Quadratic":
if len(x) < 3:
error_msg = "Error: At least three points are required for quadratic interpolation."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
y_interp = quadratic_interpolation(x, y, x_interp)
elif method == "Lagrange":
y_interp = lagrange_interpolation(x, y, x_interp)
elif method == "Newton Forward":
if not np.allclose(np.diff(x), x[1] - x[0]):
error_msg = "Error: Newton Forward method requires uniform x spacing."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
y_interp = newton_forward_interpolation(x, y, x_interp)
elif method == "Newton Backward":
if not np.allclose(np.diff(x), x[1] - x[0]):
error_msg = "Error: Newton Backward method requires uniform x spacing."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
y_interp = newton_backward_interpolation(x, y, x_interp)
else:
error_msg = "Error: Invalid interpolation method selected."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
# Predict y value for given x
if x_predict is not None:
try:
x_predict = float(x_predict)
if x_predict < min(x) or x_predict > max(x):
error_msg = f"Error: Prediction x value must be between {min(x)} and {max(x)}."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
y_predict = np.interp(x_predict, x_interp, y_interp)
fig = create_and_edit_plot(x, y, x_interp, y_interp, method, plot_title, x_label, y_label, legend_position, label_size, x_predict, y_predict)
return fig, f"Predicted y value for x = {x_predict}: {y_predict:.4f}"
except ValueError:
error_msg = "Error: Invalid input for x prediction. Please enter a number."
return create_error_plot(error_msg), f'<p style="color: red;">{error_msg}</p>'
fig = create_and_edit_plot(x, y, x_interp, y_interp, method, plot_title, x_label, y_label, legend_position, label_size)
return fig, None
iface = gr.Interface(
fn=interpolate_and_plot,
inputs=[
gr.Textbox(label="X values (comma-separated)"),
gr.Textbox(label="Y values (comma-separated)"),
gr.Number(label="X value to predict (optional)", value=lambda: None),
gr.Radio(["Linear", "Quadratic", "Lagrange", "Newton Forward", "Newton Backward"], label="Interpolation Method", value="Linear"),
gr.Textbox(label="Plot Title", value="Interpolation Plot"),
gr.Textbox(label="X-axis Label", value="x"),
gr.Textbox(label="Y-axis Label", value="y"),
gr.Dropdown(["best", "upper right", "upper left", "lower left", "lower right", "right", "center left", "center right", "lower center", "upper center", "center"], label="Legend Position", value="best"),
gr.Slider(minimum=8, maximum=24, step=1, label="Label Size", value=12)
],
outputs=[
gr.Plot(label="Interpolation Plot"),
gr.HTML(label="Result or Error Message")
],
title="Interpolation App",
description="Enter x and y values to see the interpolation graph. Choose the interpolation method using the radio buttons. Optionally, enter an x value (between min and max of input x values) to predict its corresponding y value. Note: Newton Forward and Backward methods require uniform x spacing. You can also customize the plot labels, legend position, and label size."
)
iface.launch() |