File size: 12,521 Bytes
f0ef9a7 d205b24 0b98965 d205b24 542d9ae d205b24 f0ef9a7 d205b24 |
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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
import streamlit as st
from PIL import Image
import pandas as pd
import numpy as np
import math
st.set_page_config(page_title="Numerical Methods Solver", layout="centered")
# Sidebar navigation
image = Image.open("src/ii.jpg")
st.sidebar.image(image, use_container_width=True)
# Sidebar navigation
st.sidebar.title("Navigation")
page = st.sidebar.radio("Go to", ["Overview", "Tutorial", "Solver"])
if page == "Overview":
st.image('src/okay-i-will-it.jpg', width = 600)
st.title("\U0001F4D8 Numerical Methods Solver")
st.markdown("""
#### ๐ Welcome!
This app helps you understand and solve **ordinary differential equations** (ODEs) using numerical methods.
---
#### ๐ What You Can Do:
- Solve **ordinary differential equations (ODEs)** using methods like Euler, Runge-Kutta, Milne, and more
- Solve **systems of linear equations** using Gauss Elimination, Gauss-Jordan, Gauss-Seidel, Jacobi, and LU Decomposition
- Visualize **step-by-step calculations**
- Input your own function, step size, and initial conditions
- Get results up to 4โ5 decimal places
---
#### ๐ Who Is This For?
- Students studying **Numerical Analysis** or **Linear Algebra**
- Educators who want a visual teaching tool
- Anyone learning how numerical methods work under the hood
---
#### ๐ก Supported Methods (So Far)
**ODE Methods:**
- Euler's Method (Explicit)
- Euler's Method (Implicit)
- Heunโs Method (Improved Euler)
- Runge-Kutta 4th Order (RK4)
- Taylor Series Method (1st order)
- Milne's Predictor-Corrector Method
**Linear Algebraic Methods:**
- Gauss Elimination Method
- Gauss-Jordan Method
- Gauss-Seidel Iterative Method
- Jacobi Iteration Method
- LU Decomposition Method
---
#### ๐ง How It Works:
For ODEs:
- Provide a function of `x` and `y`
- Set initial values `xโ`, `yโ`, step size `h`, and number of steps `n`
For Linear Equations:
- Provide matrix `A` and vector `b` from your system of equations
The app will:
- Compute approximated values step by step
- Display intermediate and final results
""")
elif page == "Solver":
st.title("\U0001F9EE Numerical Methods Solver")
algebraic_methods = [
"Gauss Elimination Method",
"Gauss-Jordan Method",
"Gauss-Seidel Iterative Method",
"Jacobi Iteration Method",
"LU Decomposition Method"
]
ode_methods = [
"Euler (Explicit)",
"Euler (Implicit)",
"Heunโs Method (Improved Euler)",
"Runge-Kutta 4th Order (RK4)",
"Taylor Series Method",
"Milne's Predictor-Corrector Method"
]
method_type = st.radio("Choose a Method Category:", ["ODE Methods", "Algebraic Methods"])
if method_type == "ODE Methods":
method = st.selectbox("Choose a Numerical Method:", ode_methods)
col1, col2 = st.columns(2)
with col1:
x0 = st.number_input("Initial x (xโ):", value=0.0, format="%.5f")
h = st.number_input("Step size (h):", value=0.1, format="%.5f")
with col2:
f_str = st.text_input("Enter f(x, y):", "x + y")
y0 = st.number_input("Initial y (yโ):", value=1.0, format="%.5f")
n = st.number_input("Number of steps:", value=5, step=1)
st.markdown("### ๐ Click below to solve")
compute = st.button("๐ Compute Solution")
if compute:
try:
f = lambda x, y: eval(f_str, {"x": x, "y": y, "math": math})
x_vals = [x0]
y_vals = [y0]
x = x0
y = y0
results = [{"Step": 0, "x": round(x, 5), "y": round(y, 5)}]
if method == "Milne's Predictor-Corrector Method":
# Generate first 3 points using RK4
k1 = h * f(x, y)
k2 = h * f(x + h/2, y + k1/2)
k3 = h * f(x + h/2, y + k2/2)
k4 = h * f(x + h, y + k3)
y1 = y + (k1 + 2*k2 + 2*k3 + k4) / 6
x1 = x + h
k1 = h * f(x1, y1)
k2 = h * f(x1 + h/2, y1 + k1/2)
k3 = h * f(x1 + h/2, y1 + k2/2)
k4 = h * f(x1 + h, y1 + k3)
y2 = y1 + (k1 + 2*k2 + 2*k3 + k4) / 6
x2 = x1 + h
k1 = h * f(x2, y2)
k2 = h * f(x2 + h/2, y2 + k1/2)
k3 = h * f(x2 + h/2, y2 + k2/2)
k4 = h * f(x2 + h, y2 + k3)
y3 = y2 + (k1 + 2*k2 + 2*k3 + k4) / 6
x3 = x2 + h
xs = [x, x1, x2, x3]
ys = [y, y1, y2, y3]
results = [{"Step": i, "x": round(xs[i], 5), "y": round(ys[i], 5)} for i in range(4)]
for i in range(4, int(n) + 1):
f_n3 = f(xs[i-3], ys[i-3])
f_n2 = f(xs[i-2], ys[i-2])
f_n1 = f(xs[i-1], ys[i-1])
f_n = f(xs[i-0], ys[i-0])
# Predictor
y_pred = ys[i-4] + (4*h/3)*(2*f_n2 - f_n1 + 2*f_n)
x_new = xs[i-1] + h
# Corrector
f_pred = f(x_new, y_pred)
y_corr = ys[i-2] + (h/3)*(f_n1 + 4*f_n + f_pred)
xs.append(x_new)
ys.append(y_corr)
results.append({"Step": i, "x": round(x_new, 5), "y": round(y_corr, 5)})
else:
for i in range(1, int(n)+1):
if method == "Euler (Explicit)":
y = y + h * f(x, y)
x = x + h
elif method == "Euler (Implicit)":
y_new = y + h * f(x + h, y)
y = y_new
x = x + h
elif method == "Heunโs Method (Improved Euler)":
y_predict = y + h * f(x, y)
slope_avg = (f(x, y) + f(x + h, y_predict)) / 2
y = y + h * slope_avg
x = x + h
elif method == "Runge-Kutta 4th Order (RK4)":
k1 = h * f(x, y)
k2 = h * f(x + h/2, y + k1/2)
k3 = h * f(x + h/2, y + k2/2)
k4 = h * f(x + h, y + k3)
y += (k1 + 2*k2 + 2*k3 + k4) / 6
x += h
elif method == "Taylor Series Method":
y = y + h * f(x, y)
x = x + h
results.append({"Step": i, "x": round(x, 5), "y": round(y, 5)})
x_vals.append(x)
y_vals.append(y)
st.subheader(f"๐ Results using {method}")
df = pd.DataFrame(results)
st.dataframe(df)
except Exception as e:
st.error(f"โ ๏ธ Error in function input: {e}")
elif method_type == "Algebraic Methods":
method = st.selectbox("Choose a Linear Algebra Method:", algebraic_methods)
st.write("Enter your coefficient matrix A and RHS vector b (1 equation per line).")
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")
b_str = st.text_area("Enter vector b (e.g., 8\\n-11\\n-3):", "8\n-11\n-3")
if st.button("๐ Solve System"):
try:
A = np.array([list(map(float, row.strip().split())) for row in A_str.strip().split('\n')])
b = np.array([float(num) for num in b_str.strip().split('\n')])
n = len(b)
if method == "Gauss Elimination Method":
for i in range(n):
for j in range(i + 1, n):
factor = A[j][i] / A[i][i]
A[j] = A[j] - factor * A[i]
b[j] = b[j] - factor * b[i]
x_sol = np.zeros(n)
for i in range(n - 1, -1, -1):
x_sol[i] = (b[i] - np.dot(A[i][i + 1:], x_sol[i + 1:])) / A[i][i]
elif method == "Gauss-Jordan Method":
aug = np.hstack((A, b.reshape(-1,1)))
for i in range(n):
aug[i] = aug[i] / aug[i][i]
for j in range(n):
if i != j:
aug[j] = aug[j] - aug[j][i] * aug[i]
x_sol = aug[:, -1]
elif method == "Gauss-Seidel Iterative Method":
x_sol = np.zeros(n)
for _ in range(25):
for i in range(n):
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]
elif method == "Jacobi Iteration Method":
x_sol = np.zeros(n)
for _ in range(25):
x_new = np.copy(x_sol)
for i in range(n):
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]
x_sol = x_new
elif method == "LU Decomposition Method":
L = np.zeros_like(A)
U = np.zeros_like(A)
for i in range(n):
L[i][i] = 1
for j in range(i, n):
U[i][j] = A[i][j] - sum(L[i][k] * U[k][j] for k in range(i))
for j in range(i + 1, n):
L[j][i] = (A[j][i] - sum(L[j][k] * U[k][i] for k in range(i))) / U[i][i]
y = np.zeros(n)
for i in range(n):
y[i] = b[i] - np.dot(L[i, :i], y[:i])
x_sol = np.zeros(n)
for i in range(n - 1, -1, -1):
x_sol[i] = (y[i] - np.dot(U[i, i+1:], x_sol[i+1:])) / U[i][i]
df_result = pd.DataFrame({"Variable": [f"x{i + 1}" for i in range(n)], "Value": x_sol})
st.success("โ
System Solved Successfully")
st.dataframe(df_result)
except Exception as e:
st.error(f"โ ๏ธ Error in matrix input: {e}")
elif page == "Tutorial":
st.title("๐ How to Use This Solver")
st.markdown("")
st.markdown("---")
st.markdown("")
st.markdown("### ๐ข ODE Methods Input")
st.markdown("""
These methods solve differential equations like dy/dx = f(x, y).
**Required Inputs:**
- `f(x, y)` โ The function to solve (e.g., `x + y`, `x * y`, `math.exp(x)`)
- `Initial xโ` โ Starting x-value (e.g., 0)
- `Initial yโ` โ Starting y-value (e.g., 1)
- `Step size (h)` โ E.g., 0.1
- `Number of steps (n)` โ How many iterations (e.g., 5)
**Function Rules:**
- You can use basic operators: `+`, `-`, `*`, `/`, `**`
- You can use math functions like `math.sin(x)`, `math.exp(x)` โ include `math.` prefix!
""")
st.markdown("")
st.markdown("---")
st.markdown("")
st.markdown("### ๐งฎ Algebraic Methods Input")
st.markdown("""
These methods solve systems like Ax = b.
**Required Inputs:**
- **Matrix A** โ Coefficients of your equations
Example:
```
2 1 -1
-3 -1 2
-2 1 2
```
- **Vector b** โ Right-hand side values
Example:
```
8
-11
-3
```
This represents:
```
2xโ + 1xโ - 1xโ = 8
-3xโ - 1xโ + 2xโ = -11
-2xโ + 1xโ + 2xโ = -3
```
โ
Avoid extra spaces. Match the number of rows in A and b.
""")
st.markdown("---")
st.info("Make sure matrix A is square and matches vector b in dimensions for algebraic methods.")
st.success("You're all set! Head to the Solver tab to try it out.")
st.markdown("---")
st.markdown("<h8 style='text-align: LEFT; font-family:montserrat'>Numerical Method Solver built with โค๏ธ by Datapsalm</h8>", unsafe_allow_html=True)
|