datapsalm commited on
Commit
d205b24
ยท
verified ยท
1 Parent(s): 8446974

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +315 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,317 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ from PIL import Image
3
+ import pandas as pd
4
+ import numpy as np
5
+ import math
6
+
7
+ st.set_page_config(page_title="Numerical Methods Solver", layout="centered")
8
+
9
+ # Sidebar navigation
10
+ image = Image.open("ii.jpg")
11
+ st.sidebar.image(image, use_container_width=True)
12
+
13
+ # Sidebar navigation
14
+ st.sidebar.title("Navigation")
15
+ page = st.sidebar.radio("Go to", ["Overview", "Tutorial", "Solver"])
16
+ if page == "Overview":
17
+ st.image('okay-i-will-it.jpg', width = 600)
18
+ st.title("\U0001F4D8 Numerical Methods Solver")
19
+ st.markdown("""
20
+ #### ๐Ÿ‘‹ Welcome!
21
+ This app helps you understand and solve **ordinary differential equations** (ODEs) using numerical methods.
22
+
23
+ ---
24
+ #### ๐Ÿ” What You Can Do:
25
+ - Solve **ordinary differential equations (ODEs)** using methods like Euler, Runge-Kutta, Milne, and more
26
+ - Solve **systems of linear equations** using Gauss Elimination, Gauss-Jordan, Gauss-Seidel, Jacobi, and LU Decomposition
27
+ - Visualize **step-by-step calculations**
28
+ - Input your own function, step size, and initial conditions
29
+ - Get results up to 4โ€“5 decimal places
30
+
31
+ ---
32
+ #### ๐Ÿ“Œ Who Is This For?
33
+ - Students studying **Numerical Analysis** or **Linear Algebra**
34
+ - Educators who want a visual teaching tool
35
+ - Anyone learning how numerical methods work under the hood
36
+
37
+ ---
38
+ #### ๐Ÿ’ก Supported Methods (So Far)
39
+ **ODE Methods:**
40
+ - Euler's Method (Explicit)
41
+ - Euler's Method (Implicit)
42
+ - Heunโ€™s Method (Improved Euler)
43
+ - Runge-Kutta 4th Order (RK4)
44
+ - Taylor Series Method (1st order)
45
+ - Milne's Predictor-Corrector Method
46
+
47
+ **Linear Algebraic Methods:**
48
+ - Gauss Elimination Method
49
+ - Gauss-Jordan Method
50
+ - Gauss-Seidel Iterative Method
51
+ - Jacobi Iteration Method
52
+ - LU Decomposition Method
53
+
54
+ ---
55
+ #### ๐Ÿง  How It Works:
56
+ For ODEs:
57
+ - Provide a function of `x` and `y`
58
+ - Set initial values `xโ‚€`, `yโ‚€`, step size `h`, and number of steps `n`
59
+
60
+ For Linear Equations:
61
+ - Provide matrix `A` and vector `b` from your system of equations
62
+
63
+ The app will:
64
+ - Compute approximated values step by step
65
+ - Display intermediate and final results
66
+ """)
67
+
68
+ elif page == "Solver":
69
+ st.title("\U0001F9EE Numerical Methods Solver")
70
+
71
+ algebraic_methods = [
72
+ "Gauss Elimination Method",
73
+ "Gauss-Jordan Method",
74
+ "Gauss-Seidel Iterative Method",
75
+ "Jacobi Iteration Method",
76
+ "LU Decomposition Method"
77
+ ]
78
+ ode_methods = [
79
+ "Euler (Explicit)",
80
+ "Euler (Implicit)",
81
+ "Heunโ€™s Method (Improved Euler)",
82
+ "Runge-Kutta 4th Order (RK4)",
83
+ "Taylor Series Method",
84
+ "Milne's Predictor-Corrector Method"
85
+ ]
86
+
87
+ method_type = st.radio("Choose a Method Category:", ["ODE Methods", "Algebraic Methods"])
88
+
89
+ if method_type == "ODE Methods":
90
+ method = st.selectbox("Choose a Numerical Method:", ode_methods)
91
+ col1, col2 = st.columns(2)
92
+
93
+ with col1:
94
+ x0 = st.number_input("Initial x (xโ‚€):", value=0.0, format="%.5f")
95
+ h = st.number_input("Step size (h):", value=0.1, format="%.5f")
96
+
97
+ with col2:
98
+ f_str = st.text_input("Enter f(x, y):", "x + y")
99
+ y0 = st.number_input("Initial y (yโ‚€):", value=1.0, format="%.5f")
100
+ n = st.number_input("Number of steps:", value=5, step=1)
101
+
102
+ st.markdown("### ๐Ÿ”„ Click below to solve")
103
+ compute = st.button("๐Ÿ” Compute Solution")
104
+
105
+ if compute:
106
+ try:
107
+ f = lambda x, y: eval(f_str, {"x": x, "y": y, "math": math})
108
+ x_vals = [x0]
109
+ y_vals = [y0]
110
+ x = x0
111
+ y = y0
112
+ results = [{"Step": 0, "x": round(x, 5), "y": round(y, 5)}]
113
+
114
+ if method == "Milne's Predictor-Corrector Method":
115
+ # Generate first 3 points using RK4
116
+ k1 = h * f(x, y)
117
+ k2 = h * f(x + h/2, y + k1/2)
118
+ k3 = h * f(x + h/2, y + k2/2)
119
+ k4 = h * f(x + h, y + k3)
120
+ y1 = y + (k1 + 2*k2 + 2*k3 + k4) / 6
121
+ x1 = x + h
122
+
123
+ k1 = h * f(x1, y1)
124
+ k2 = h * f(x1 + h/2, y1 + k1/2)
125
+ k3 = h * f(x1 + h/2, y1 + k2/2)
126
+ k4 = h * f(x1 + h, y1 + k3)
127
+ y2 = y1 + (k1 + 2*k2 + 2*k3 + k4) / 6
128
+ x2 = x1 + h
129
+
130
+ k1 = h * f(x2, y2)
131
+ k2 = h * f(x2 + h/2, y2 + k1/2)
132
+ k3 = h * f(x2 + h/2, y2 + k2/2)
133
+ k4 = h * f(x2 + h, y2 + k3)
134
+ y3 = y2 + (k1 + 2*k2 + 2*k3 + k4) / 6
135
+ x3 = x2 + h
136
+
137
+ xs = [x, x1, x2, x3]
138
+ ys = [y, y1, y2, y3]
139
+ results = [{"Step": i, "x": round(xs[i], 5), "y": round(ys[i], 5)} for i in range(4)]
140
+
141
+ for i in range(4, int(n) + 1):
142
+ f_n3 = f(xs[i-3], ys[i-3])
143
+ f_n2 = f(xs[i-2], ys[i-2])
144
+ f_n1 = f(xs[i-1], ys[i-1])
145
+ f_n = f(xs[i-0], ys[i-0])
146
+
147
+ # Predictor
148
+ y_pred = ys[i-4] + (4*h/3)*(2*f_n2 - f_n1 + 2*f_n)
149
+ x_new = xs[i-1] + h
150
+ # Corrector
151
+ f_pred = f(x_new, y_pred)
152
+ y_corr = ys[i-2] + (h/3)*(f_n1 + 4*f_n + f_pred)
153
+
154
+ xs.append(x_new)
155
+ ys.append(y_corr)
156
+ results.append({"Step": i, "x": round(x_new, 5), "y": round(y_corr, 5)})
157
+ else:
158
+ for i in range(1, int(n)+1):
159
+ if method == "Euler (Explicit)":
160
+ y = y + h * f(x, y)
161
+ x = x + h
162
+ elif method == "Euler (Implicit)":
163
+ y_new = y + h * f(x + h, y)
164
+ y = y_new
165
+ x = x + h
166
+ elif method == "Heunโ€™s Method (Improved Euler)":
167
+ y_predict = y + h * f(x, y)
168
+ slope_avg = (f(x, y) + f(x + h, y_predict)) / 2
169
+ y = y + h * slope_avg
170
+ x = x + h
171
+ elif method == "Runge-Kutta 4th Order (RK4)":
172
+ k1 = h * f(x, y)
173
+ k2 = h * f(x + h/2, y + k1/2)
174
+ k3 = h * f(x + h/2, y + k2/2)
175
+ k4 = h * f(x + h, y + k3)
176
+ y += (k1 + 2*k2 + 2*k3 + k4) / 6
177
+ x += h
178
+ elif method == "Taylor Series Method":
179
+ y = y + h * f(x, y)
180
+ x = x + h
181
+
182
+ results.append({"Step": i, "x": round(x, 5), "y": round(y, 5)})
183
+ x_vals.append(x)
184
+ y_vals.append(y)
185
+
186
+ st.subheader(f"๐Ÿ“Š Results using {method}")
187
+ df = pd.DataFrame(results)
188
+ st.dataframe(df)
189
+ except Exception as e:
190
+ st.error(f"โš ๏ธ Error in function input: {e}")
191
+
192
+ elif method_type == "Algebraic Methods":
193
+ method = st.selectbox("Choose a Linear Algebra Method:", algebraic_methods)
194
+
195
+ st.write("Enter your coefficient matrix A and RHS vector b (1 equation per line).")
196
+ A_str = st.text_area("Enter matrix A (e.g., 2 1 -1\\n-3 -1 2\\n-2 1 2):", "2 1 -1\n-3 -1 2\n-2 1 2")
197
+ b_str = st.text_area("Enter vector b (e.g., 8\\n-11\\n-3):", "8\n-11\n-3")
198
+
199
+ if st.button("๐Ÿ” Solve System"):
200
+ try:
201
+ A = np.array([list(map(float, row.strip().split())) for row in A_str.strip().split('\n')])
202
+ b = np.array([float(num) for num in b_str.strip().split('\n')])
203
+ n = len(b)
204
+
205
+ if method == "Gauss Elimination Method":
206
+ for i in range(n):
207
+ for j in range(i + 1, n):
208
+ factor = A[j][i] / A[i][i]
209
+ A[j] = A[j] - factor * A[i]
210
+ b[j] = b[j] - factor * b[i]
211
+ x_sol = np.zeros(n)
212
+ for i in range(n - 1, -1, -1):
213
+ x_sol[i] = (b[i] - np.dot(A[i][i + 1:], x_sol[i + 1:])) / A[i][i]
214
+ elif method == "Gauss-Jordan Method":
215
+ aug = np.hstack((A, b.reshape(-1,1)))
216
+ for i in range(n):
217
+ aug[i] = aug[i] / aug[i][i]
218
+ for j in range(n):
219
+ if i != j:
220
+ aug[j] = aug[j] - aug[j][i] * aug[i]
221
+ x_sol = aug[:, -1]
222
+ elif method == "Gauss-Seidel Iterative Method":
223
+ x_sol = np.zeros(n)
224
+ for _ in range(25):
225
+ for i in range(n):
226
+ x_sol[i] = (b[i] - np.dot(A[i, :i], x_sol[:i]) - np.dot(A[i, i+1:], x_sol[i+1:])) / A[i, i]
227
+ elif method == "Jacobi Iteration Method":
228
+ x_sol = np.zeros(n)
229
+ for _ in range(25):
230
+ x_new = np.copy(x_sol)
231
+ for i in range(n):
232
+ x_new[i] = (b[i] - np.dot(A[i, :i], x_sol[:i]) - np.dot(A[i, i+1:], x_sol[i+1:])) / A[i, i]
233
+ x_sol = x_new
234
+ elif method == "LU Decomposition Method":
235
+ L = np.zeros_like(A)
236
+ U = np.zeros_like(A)
237
+ for i in range(n):
238
+ L[i][i] = 1
239
+ for j in range(i, n):
240
+ U[i][j] = A[i][j] - sum(L[i][k] * U[k][j] for k in range(i))
241
+ for j in range(i + 1, n):
242
+ L[j][i] = (A[j][i] - sum(L[j][k] * U[k][i] for k in range(i))) / U[i][i]
243
+ y = np.zeros(n)
244
+ for i in range(n):
245
+ y[i] = b[i] - np.dot(L[i, :i], y[:i])
246
+ x_sol = np.zeros(n)
247
+ for i in range(n - 1, -1, -1):
248
+ x_sol[i] = (y[i] - np.dot(U[i, i+1:], x_sol[i+1:])) / U[i][i]
249
+
250
+ df_result = pd.DataFrame({"Variable": [f"x{i + 1}" for i in range(n)], "Value": x_sol})
251
+ st.success("โœ… System Solved Successfully")
252
+ st.dataframe(df_result)
253
+
254
+ except Exception as e:
255
+ st.error(f"โš ๏ธ Error in matrix input: {e}")
256
+
257
+ elif page == "Tutorial":
258
+ st.title("๐Ÿ“˜ How to Use This Solver")
259
+ st.markdown("")
260
+ st.markdown("---")
261
+ st.markdown("")
262
+ st.markdown("### ๐Ÿ”ข ODE Methods Input")
263
+ st.markdown("""
264
+ These methods solve differential equations like dy/dx = f(x, y).
265
+
266
+ **Required Inputs:**
267
+ - `f(x, y)` โ€” The function to solve (e.g., `x + y`, `x * y`, `math.exp(x)`)
268
+ - `Initial xโ‚€` โ€” Starting x-value (e.g., 0)
269
+ - `Initial yโ‚€` โ€” Starting y-value (e.g., 1)
270
+ - `Step size (h)` โ€” E.g., 0.1
271
+ - `Number of steps (n)` โ€” How many iterations (e.g., 5)
272
+
273
+ **Function Rules:**
274
+ - You can use basic operators: `+`, `-`, `*`, `/`, `**`
275
+ - You can use math functions like `math.sin(x)`, `math.exp(x)` โ€” include `math.` prefix!
276
+ """)
277
+
278
+ st.markdown("")
279
+ st.markdown("---")
280
+ st.markdown("")
281
+
282
+ st.markdown("### ๐Ÿงฎ Algebraic Methods Input")
283
+ st.markdown("""
284
+ These methods solve systems like Ax = b.
285
+
286
+ **Required Inputs:**
287
+ - **Matrix A** โ€” Coefficients of your equations
288
+ Example:
289
+ ```
290
+ 2 1 -1
291
+ -3 -1 2
292
+ -2 1 2
293
+ ```
294
+ - **Vector b** โ€” Right-hand side values
295
+ Example:
296
+ ```
297
+ 8
298
+ -11
299
+ -3
300
+ ```
301
+
302
+ This represents:
303
+ ```
304
+ 2xโ‚ + 1xโ‚‚ - 1xโ‚ƒ = 8
305
+ -3xโ‚ - 1xโ‚‚ + 2xโ‚ƒ = -11
306
+ -2xโ‚ + 1xโ‚‚ + 2xโ‚ƒ = -3
307
+ ```
308
+
309
+ โœ… Avoid extra spaces. Match the number of rows in A and b.
310
+ """)
311
+
312
+ st.markdown("---")
313
+ st.info("Make sure matrix A is square and matches vector b in dimensions for algebraic methods.")
314
+ st.success("You're all set! Head to the Solver tab to try it out.")
315
 
316
+ st.markdown("---")
317
+ st.markdown("<h8 style='text-align: LEFT; font-family:montserrat'>Numerical Method Solver built with โค๏ธ by Datapsalm</h8>", unsafe_allow_html=True)