File size: 2,948 Bytes
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
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt

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):
    x = np.array([float(val.strip()) for val in x_input.split(',')])
    y = np.array([float(val.strip()) for val in y_input.split(',')])
    
    if len(x) != len(y):
        return "Error: Number of x and y values must be the same.", None
    
    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"
    
    plt.figure(figsize=(10, 6))
    plt.scatter(x, y, color='red', label='Input points')
    plt.plot(x_interp, y_interp, label=f'{method} interpolant')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title(f'{method} Interpolation')
    plt.legend()
    plt.grid(True)
    
    # Predict y value for given x
    if x_predict is not None:
        if x_predict < min(x) or x_predict > max(x):
            return plt, f"Error: Prediction x value must be between {min(x)} and {max(x)}."
        
        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]
        
        plt.scatter([x_predict], [y_predict], color='green', s=100, label='Predicted point')
        plt.legend()
        
        return plt, f"Predicted y value for x = {x_predict}: {y_predict:.4f}"
    
    return plt, 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.Textbox(label="Predicted Y value")
    ],
    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.\n Optionally, enter an x value (between min and max of input x values) to predict its corresponding y value."
)

iface.launch()