File size: 6,461 Bytes
4c33e3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445aec6
4c33e3f
445aec6
4c33e3f
445aec6
4c33e3f
445aec6
4c33e3f
 
 
 
 
 
 
 
 
 
 
445aec6
4c33e3f
 
 
 
 
 
 
 
 
 
445aec6
4c33e3f
 
 
 
 
 
 
 
445aec6
4c33e3f
 
 
32467cc
 
4c33e3f
445aec6
4c33e3f
 
 
 
 
32467cc
 
445aec6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c33e3f
445aec6
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
import gradio as gr
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt

# Define symbolic variable for polynomial operations
x = sp.symbols('x')

# Function to generate a LaTeX template for a polynomial based on its degree
def generate_polynomial_template(degree):
    terms = [f"a_{{{i}}}x^{degree - i}" for i in range(degree)]
    terms.append(f"a_{{{degree}}}")
    return "$$" + " + ".join(terms) + " = 0$$"

# Function to load example coefficients for a given polynomial degree
def load_poly_example(degree):
    examples = {
        1: "3 9",
        2: "1 -3 2",
        3: "1 -6 11 -6",
        4: "1 0 -5 0 4",
        5: "1 -9 3 8 1 8",
        6: "1 -9 3 8 1 8 3",
        7: "1 -9 3 8 1 8 6 2",
        8: "1 -9 3 8 1 8 2 3 7"
    }
    return examples.get(degree, "")

# Function to solve the polynomial equation and generate a graph
def solve_polynomial(degree, coeff_string, real_only):
    try:
        coeffs = list(map(float, coeff_string.strip().split()))
        if len(coeffs) != degree + 1:
            return f"⚠️ Please enter exactly {degree + 1} coefficients.", None, None

        poly = sum([coeffs[i] * x**(degree - i) for i in range(degree + 1)])
        simplified = sp.simplify(poly)
        factored = sp.factor(simplified)
        roots = sp.solve(sp.Eq(simplified, 0), x)

        if real_only:
            roots = [r for r in roots if sp.im(r) == 0]

        roots_output = "$$\n" + "\\ ".join(
            [f"r_{{{i}}} = {sp.latex(sp.nsimplify(r, rational=True))}" for i, r in enumerate(roots, 1)]
        ) + "\n$$"

        steps_output = f"""
### Polynomial Expression
$$ {sp.latex(poly)} = 0 $$
### Simplified
$$ {sp.latex(simplified)} = 0 $$
### Factored
$$ {sp.latex(factored)} = 0 $$
### Roots {'(Only Real)' if real_only else '(All Roots)'}
{roots_output}
        """

        x_vals = np.linspace(-10, 10, 400)
        y_vals = np.polyval(coeffs, x_vals)

        fig, ax = plt.subplots(figsize=(6, 4))
        ax.plot(x_vals, y_vals, label="Polynomial", color="blue")
        ax.axhline(0, color='black', linewidth=0.5)
        ax.axvline(0, color='black', linewidth=0.5)
        ax.grid(True)
        ax.set_title("Graph of the Polynomial")
        ax.set_xlabel("x")
        ax.set_ylabel("f(x)")
        ax.legend()

        return steps_output, fig, ""
    except Exception as e:
        return f"❌ Error: {e}", None, ""

# Function to create the Polynomial Solver tab with Gradio components
def polynomial_tab():
    with gr.Tab("Polynomial Solver"):
        # Row for displaying the equation template and real roots checkbox
        with gr.Row():
            template_display = gr.Markdown(value=generate_polynomial_template(2))
            real_checkbox = gr.Checkbox(label="Show Only Real Roots", value=False)

        # Row for selecting the polynomial degree and entering coefficients
        with gr.Row():
            degree_slider = gr.Slider(1, 8, value=2, step=1, label="Select Degree of Polynomial Equation")
            coeff_input = gr.Textbox(label="Enter Coefficients (space-separated)", placeholder="e.g. 1 -3 2")

        # Row for example and preview buttons
        with gr.Row():
            example_btn = gr.Button("Load Example")
            preview_poly_button = gr.Button("Preview Equation")

        # Row for displaying the confirmed equation
        with gr.Row():
            poly_equation_display = gr.Markdown()

        # Row for confirm and cancel buttons
        with gr.Row():
            confirm_poly_btn = gr.Button("Display Solution", visible=False)
            cancel_poly_btn = gr.Button("Make Changes in Equation", visible=False)

        # Markdown component to display step-by-step solution
        steps_md = gr.Markdown()

        # Plot component to display the polynomial graph
        plot_output = gr.Plot()

        # Textbox to display errors (initially hidden)
        error_box = gr.Textbox(visible=False)

        # Function to preview the polynomial equation based on user input
        def preview_polynomial(degree, coeff_string, real_only):
            try:
                coeffs = list(map(float, coeff_string.strip().split()))
                if len(coeffs) != degree + 1:
                    return f"⚠️ Please enter exactly {degree + 1} coefficients.", gr.update(visible=False), gr.update(visible=False), "", None
                poly = sum([coeffs[i] * x**(degree - i) for i in range(degree + 1)])
                eq_latex = f"### ✅ Confirm Polynomial\n\n$$ {sp.latex(poly)} = 0 $$"
                return eq_latex, gr.update(visible=True), gr.update(visible=True), "", None
            except Exception as e:
                return f"❌ Error parsing coefficients: {e}", gr.update(visible=False), gr.update(visible=False), "", None

        # Event handler for preview button click
        preview_poly_button.click(
            fn=preview_polynomial,
            inputs=[degree_slider, coeff_input, real_checkbox],
            outputs=[poly_equation_display, confirm_poly_btn, cancel_poly_btn, steps_md, plot_output]
        )

        # Function to handle cancellation of the preview
        def cancel_poly():
            return gr.update(visible=False), gr.update(visible=False), "", "", None

        # Event handler for cancel button click
        cancel_poly_btn.click(
            fn=cancel_poly,
            inputs=[],
            outputs=[confirm_poly_btn, cancel_poly_btn, poly_equation_display, steps_md, plot_output]
        )

        # Event handler for confirm button click to solve and display results
        confirm_poly_btn.click(
            fn=solve_polynomial,
            inputs=[degree_slider, coeff_input, real_checkbox],
            outputs=[steps_md, plot_output, error_box]
        )

        # Event handler to update the template when the degree slider changes
        degree_slider.change(fn=generate_polynomial_template, inputs=degree_slider, outputs=template_display)

        # Event handler to load an example when the example button is clicked
        example_btn.click(fn=load_poly_example, inputs=degree_slider, outputs=coeff_input)

        # Initialize the template display with the default degree (2) on load
        template_display.value = generate_polynomial_template(2)

    return template_display, real_checkbox, degree_slider, coeff_input, example_btn, preview_poly_button, poly_equation_display, confirm_poly_btn, cancel_poly_btn, steps_md, plot_output, error_box