File size: 4,056 Bytes
fb0e940
 
 
 
9f13c80
 
 
 
 
 
fb0e940
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f13c80
 
 
 
 
 
fb0e940
 
9f13c80
 
 
 
 
 
fb0e940
 
 
 
 
 
 
 
 
 
 
 
 
9f13c80
 
 
 
 
 
 
 
fb0e940
 
 
9f13c80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fb0e940
9f13c80
fb0e940
 
 
 
 
 
 
 
 
 
9f13c80
fb0e940
 
330c40e
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
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 interpolate_and_plot(x_input, y_input, x_predict):
    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)
    
    if len(x) == 2:
        y_interp = linear_interpolation(x, y, x_interp)
        method = "Linear"
    elif len(x) == 3:
        y_interp = quadratic_interpolation(x, y, x_interp)
        method = "Quadratic"
    else:
        y_interp = lagrange_interpolation(x, y, x_interp)
        method = "Lagrange"
    
    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')
    ax.set_ylabel('y')
    ax.set_title(f'{method} Interpolation')
    ax.legend()
    ax.grid(True)
    
    # 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 fig, f'<p style="color: red;">{error_msg}</p>'
            
            if len(x) == 2:
                y_predict = linear_interpolation(x, y, [x_predict])[0]
            elif len(x) == 3:
                y_predict = quadratic_interpolation(x, y, [x_predict])[0]
            else:
                y_predict = lagrange_interpolation(x, y, [x_predict])[0]
            
            ax.scatter([x_predict], [y_predict], color='green', s=100, label='Predicted point')
            ax.legend()
            
            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>'
    
    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)")
    ],
    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. The method will be chosen based on the number of points:\n2 points: Linear, 3 points: Quadratic, >3 points: Lagrange. \nOptionally, enter an x value (between min and max of input x values) to predict its corresponding y value."
)

iface.launch()