A beautiful, interactive, zero-dependency workbench for solving equations numerically.
Designed for Numerical Analysis students — type any equation, watch the algorithm converge in real time, and export a print-ready report (or an animated GIF) in one tap.
Supports Bisection, False Position, Newton-Raphson, and Secant — with Fixed-point iteration and more on the way (see 🗺️ Roadmap).
- ✨ Features
- 🗺️ Roadmap
- 📐 How the Bracketing Methods Work (Bisection & False Position)
- 📐 How Newton-Raphson & Secant Work
- 🧮 Built-in Equation Examples
- ⌨️ Equation Syntax Guide
- 🚀 Getting Started
- 📱 Mobile Ready
- 📥 Export Feature
- 🔒 Security
- 🛠 Tech Stack
- 📁 Project Structure
- 🙋 FAQ
- 📝 License
| 🔢 | Feature | Description |
|---|---|---|
| 🎯 | Smart Auto-Bracket Detection | Automatically scans 0 → +1000 first for a positive bracket, then falls back to −1000 → 0 — so functions like 1-x·cos(x) land on [4, 5] not [-3, -2]. A "prefer negative" toggle reverses the priority when you need it. Newton-Raphson and Secant reuse the same scanner to suggest starting guesses, with no sign-change requirement. |
| ✍️ | Natural Equation Input | Type equations the way you write them: xtan(x)-1, lnx-cosx, 3x^3-7x+5 — the smart preprocessor handles implicit multiplication and bare-function notation |
| 🔀 | Four Solving Methods | Switch between Bisection, False Position, Newton-Raphson, and Secant from the sheet index — each with its own input shape, iteration table, and worked math, all sharing one page |
| 📐 | Symbolic Derivatives | Newton-Raphson computes f′(x) automatically via Math.js's symbolic differentiation — no manual calculus required |
| 🎞️ | Animated Graph | Watch the bracket narrow (or the tangent/secant line converge) in real time with a built-in step player — go forward, back, or let it play automatically |
| 🎬 | GIF Export | Download the animated graph itself — replaying every step — as a shareable GIF, encoded entirely client-side |
| 📊 | Full Iteration Table | Every method's exact columns: a/b/f(a)/f(b)/c/f(c) for bracketing, a/f(a)/f′(a)/c/f(c) for Newton-Raphson, x₀/x₁/f(x₀)/f(x₁)/x₂/f(x₂) for Secant — plus Absolute Error, Relative Error, and a position sparkline |
| ✅ | IVT Verification | Bisection and False Position automatically verify f(a)·f(b) < 0 before solving; Newton-Raphson and Secant skip this since neither actually requires it |
| 🛑 | Flexible Stop Criteria | Default: stops as soon as two consecutive c values look identical at the chosen precision — fast and intuitive. Also supports fixed iteration count, custom tolerance ε, and a legacy full-precision mode — same options across all four methods |
| 🌍 | True Root Mode | Provide the known true root to get exact absolute and relative errors per iteration |
| 📥 | One-Tap Export | Download a full landscape PNG image or multi-page PDF — works perfectly on mobile too |
| 📱 | Mobile-First Design | 44px touch targets, stacked layouts, portrait-safe export — built for phones first |
| 🔐 | Security Hardened | CSP headers, XSS-safe rendering, input length limits, MIME validation, whitelisted radio values |
| 💡 | 20 Built-in Examples | 10 bracketing examples plus 5 each for Newton-Raphson and Secant — from simple cubics to transcendental equations |
| Method | Status |
|---|---|
| Bisection | ✅ Shipped |
| False Position | ✅ Shipped |
| Newton-Raphson | ✅ Shipped |
| Secant | ✅ Shipped |
| Fixed-point iteration | 🔜 Next up — already has a slot in the sidebar (05) |
| Lagrange interpolation | 🔜 Planned |
| Newton's divided-difference interpolation | 💡 Idea backlog |
| Gauss-Seidel / Jacobi (linear systems) | 💡 Idea backlog |
| Runge-Kutta (ODEs) | 💡 Idea backlog |
Non-method ideas (dark/light theme, share-by-URL, CSV/LaTeX table export, complex-root warnings, Bangla language support) are tracked in 🤝 Contributing → Ideas for Contributions.
Each new method gets its own engine-*.js file (see 📁 Project Structure) and merges into the shared method registry in core.js — the page shell, export pipeline, and stop-criteria UI are all reused as-is.
The Bisection Method (also called the binary search method for roots) is a bracketing algorithm that repeatedly halves an interval until the root is isolated to within a desired tolerance.
If
Given: f(x), bracket [a, b] where f(a)·f(b) < 0
Repeat:
1. c ← (a + b) / 2 ← midpoint
2. if f(c) = 0 → root found!
3. if f(a)·f(c) < 0 → b ← c ← root in left half
4. else → a ← c ← root in right half
5. until c stops changing (or max iterations reached)
Each iteration halves the bracket, so after
To guarantee
| Step | a | b | c = (a+b)/2 | f(c) | New bracket |
|---|---|---|---|---|---|
| 1 | 0.0000 | 1.0000 | 0.5000 | +0.3776 | [0.5, 1.0] |
| 2 | 0.5000 | 1.0000 | 0.7500 | −0.0183 | [0.5, 0.75] |
| 3 | 0.5000 | 0.7500 | 0.6250 | +0.1860 | [0.625, 0.75] |
| 4 | 0.6250 | 0.7500 | 0.6875 | +0.0838 | [0.6875, 0.75] |
| 5 | 0.6875 | 0.7500 | 0.7188 | +0.0327 | [0.7188, 0.75] |
| … | … | … | … | … | … |
| 14 | 0.7391 | 0.7391 | 0.7391 | ≈ 0 | ✅ c repeated — converged |
Root:
At 4 decimal places the solver stops around step 14 once c stabilises to
0.7391. Switch to the Full machine precision stop mode if you need all 52 steps.
False Position (regula falsi) uses the exact same bracket-narrowing structure and IVT prerequisite as Bisection — the only difference is the formula for c:
Bisection: c = (a + b) / 2 ← always the midpoint
False Position: c = (a·f(b) − b·f(a)) / (f(b) − f(a)) ← secant-line x-intercept
Because it aims straight at the x-intercept of the line through (a, f(a)) and (b, f(b)), False Position usually converges faster on curves that bend gently — but it can stagnate (one endpoint gets stuck for many iterations) on curves that are heavily concave near the root. The app implements both so you can compare them on the same equation.
Both of these are open methods — unlike Bisection/False Position, neither one requires a bracket [a, b] with f(a)·f(b) < 0. They walk forward from a starting guess (or two) with no sign-change requirement at all, which usually makes them converge much faster — but, unlike the bracketing methods, they aren't guaranteed to converge.
Given one starting guess a, each step draws the tangent line at (a, f(a)) and jumps to where that line crosses zero:
Given: f(x), f'(x), and a starting guess a₀
Repeat:
1. c ← a − f(a) / f'(a) ← tangent line's x-intercept
2. if f(c) = 0 → root found!
3. a ← c ← shift forward for the next step
4. until c stops changing (or max iterations reached)
f′(x) is computed symbolically (via Math.js's derivative()), so you never have to differentiate by hand — the app shows you the computed derivative in the solution box.
Convergence is quadratic near the root — roughly doubling the number of correct digits each step, far faster than either bracketing method. The tradeoff: it needs f'(x) ≠ 0, and a poor starting guess can make it diverge, cycle, or jump to the wrong root entirely (this app auto-detects a starting guess by scanning for a sign change and seeding from whichever endpoint's f-value is closer to zero — a heuristic, not a guarantee).
Given two starting guesses x₀ and x₁ (which do not need opposite signs), each step draws the line through the last two points and jumps to where it crosses zero:
Given: f(x), two starting guesses x₀, x₁ (with f(x₀) ≠ f(x₁))
Repeat:
1. x₂ ← (x₀·f(x₁) − x₁·f(x₀)) / (f(x₁) − f(x₀))
2. if f(x₂) = 0 → root found!
3. x₀ ← x₁, x₁ ← x₂ ← both points slide forward
4. until x₂ stops changing (or max iterations reached)
⚠️ This is the exact same formula as False Position — the difference is entirely in step 3. False Position keeps a genuine bracket and only replaces the endpoint on the same side as the new sign (which can make one endpoint "stick" for many steps); Secant has no bracket to maintain, so it always slides both points forward, unconditionally.
Convergence is superlinear (order ≈ 1.618, the golden ratio) — slower than Newton-Raphson since it approximates the derivative from two points instead of computing it exactly, but it needs no derivative at all. Like Newton-Raphson, it isn't guaranteed to converge — if f(x₀) = f(x₁) the line is horizontal and the method stalls, which the app detects and reports.
| Method | Starting point(s) | Steps to converge* |
|---|---|---|
| Newton-Raphson | a = 1.5 |
3 |
| Secant | x₀ = 1, x₁ = 2 |
6 |
* to 6 decimal places, using the default "c repeats" stop mode — illustrates the quadratic vs. superlinear convergence gap described above.
The app ships with 10 ready-to-solve equations accessible from the Examples panel. Click any row to load it instantly.
📂 View All 10 Examples
1 · Classic Cubic
f(1) = -2 < 0
f(2) = +4 > 0 ✓ IVT satisfied
2 · Cubic — Two Positive Coefficients
3 · Cubic with Negative Root ⭐ New
Requires a negative bracket — enter manually as
a = -2,b = -1, or enable "Prefer negative x range" in auto-detect mode.
f(−2) = −5 < 0
f(−1) = +9 > 0 ✓ IVT satisfied
4 · Transcendental (Trig)
5 · Exponential
6 · Square Root of 2
Classic benchmark — converges to
$\sqrt{2}$ with no floating-point tricks.
7 · Sine
8 · x · tan(x) ⭐ New
You can type this as
xtan(x)-1— the app auto-inserts the*.
9 · Natural Log vs Cosine
Type as
ln(x)-cos(x)or shorthandlnx-cosx. Note: in this appln(x)is always the natural log andlog(x)is always base-10.
10 · Mixed Exponential
Uses the
econstant: typee^x - x^2 - 2.
📂 View Newton-Raphson Examples (5)
| # | Equation | Starting guess | Root |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | has two roots — the guess steers which one | ||
| 5 |
📂 View Secant Examples (5)
| # | Equation | Starting points | Root |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 |
You can type equations naturally — the input parser handles many common shorthand notations automatically.
| Math | Type this | Notes |
|---|---|---|
x^3 |
Power operator | |
3x^2 or 3*x^2
|
Implicit coefficient multiply | |
sqrt(x) |
Square root | |
e^x or exp(x)
|
Euler's number | |
ln(x) or lnx
|
Natural log — use ln, not log
|
|
log(x) or log10(x) or logx
|
Base-10 log | |
sin(x) |
Trig functions | |
x*tan(x) or xtan(x)
|
⭐ Implicit multiply before function | |
cos(x) or cosx
|
⭐ Bare-variable function shorthand | |
pi |
Pi constant | |
e |
Euler's number as constant | |
| $ | x | $ |
⚠️ lnvslog— this parser deliberately separates them:ln(x)is always the natural log,log(x)is always base-10 (same aslog10(x)). This matches how most Numerical Analysis textbooks write it.
The app runs a two-step preprocessor before evaluating, so these all work:
Input → Parsed as
─────────────────────────────────
xtan(x)-1 → x*tan(x)-1
2sin(x)+cos(x) → 2*sin(x)+cos(x)
lnx-cosx → ln(x)-cos(x) (natural log)
logx-cosx → log10(x)-cos(x) (base-10 log)
sinx^2 → sin(x)^2
log10x → log10(x)
3x^3-7x+5 → 3*x^3-7*x+5 (mathjs implicit multiply)
Bounds accept the same math expressions:
pi → 3.14159…
2*pi → 6.28318…
sqrt(2) → 1.41421…
e → 2.71828…
-2 → −2 (negative bounds fully supported ✓)
Step 1 ── Pick a method
Choose Bisection, False Position, Newton-Raphson, or Secant
from the sheet index (sidebar) or the mobile nav.
Step 2 ── Enter f(x)
Type your equation, e.g. cos(x) - x
The validation dot turns green when the syntax is valid ●
Step 3 ── Set your starting bracket / guess(es)
Bisection & False Position:
○ Auto-detect → scans positive x first (0 → +1000),
falls back to negative if nothing found.
Two optional sub-toggles:
☐ Prefer tighter decimal bracket
☐ Prefer negative x range (scan − side first)
○ Set a and b myself → type your own bounds (decimals, pi, -2, etc.)
Newton-Raphson:
○ Suggest a starting guess automatically (same scanner, picks
whichever endpoint is closer to f(x) = 0)
○ Set the initial guess myself → no sign change required
Secant:
○ Suggest two starting points automatically
○ Set x₀ and x₁ myself → they do not need opposite signs
Step 4 ── Set stop criterion (optional)
● When c stops changing → DEFAULT — stops as soon as two consecutive
approximations display the same value at
the chosen precision
○ Iterations → exactly N steps
○ Tolerance ε → stops when AE ≤ ε
○ Full machine precision → legacy mode, runs until the change between
steps is below ~4 × machine epsilon
Step 5 ── Click SOLVE
The prerequisite check (IVT for bracketing methods), full iteration
table, and graph all appear instantly.
Step 6 ── Animate (optional)
Use ◀ ▶ buttons or ▷ Play to step through the algorithm visually.
Step 7 ── Export
Tap "Download as image" or "Download as PDF" for a landscape report,
or "Download as GIF" to save the animated graph itself.
The app is designed with mobile-first principles:
- 44px minimum touch targets on all interactive elements (WCAG 2.5.5)
- Stacked export buttons — full-width, easy to tap
- IVT rows collapse vertically so nothing overflows on narrow screens
- 2-column reading grid instead of a long horizontal strip
- Hero diagram hidden on very small phones to save space
- Mobile navigation bar for jumping between app sections
- Touch-friendly table — scrolls horizontally with momentum
On a phone, the iteration table is clipped inside a scroll container. Standard screen-capture approaches would produce a narrow portrait image missing most columns.
This app solves that by building a dedicated off-screen 1120px landscape panel at capture time — the exported PNG/PDF is always full landscape with every column visible, regardless of what your device screen size is.
After solving, tap either export button to download a complete, print-ready report.
The exported file includes:
| Section | Content |
|---|---|
| Header | Equation, date, root approximation, iteration count, stop reason |
| IVT Banner | f(a) and f(b) values, sign check confirmation |
| Iteration Table | All columns: n, a, b, f(a), f(b), c, f(c), AE, RE |
| Footer Note | Error formula used (bound or true root) |
| Credit Line | Author + generation date |
PNG — Landscape, 2× scale (retina quality), ~1120×auto px
PDF — Landscape A4, auto multi-page if the table is very long
Next to the graph's playback controls, "Download as GIF" replays every step of the current run and encodes it into an animated GIF, entirely in your browser — nothing is uploaded anywhere. Under the hood it steps through the graph frame by frame (same as clicking ▶ Play), rasterizes each frame, and hands them to gif.js for encoding. The button shows live progress (Frame 3/7…) while it works, and the graph returns to whichever step you were on once the download starts.
This is a client-side math tool. No data is ever sent to any server. The following hardening has been applied:
| Layer | Implementation |
|---|---|
| Content Security Policy | <meta http-equiv="Content-Security-Policy"> — blocks scripts/frames from unknown origins |
| X-Content-Type-Options | nosniff — prevents MIME-type sniffing attacks |
| Referrer Policy | no-referrer — no URL leakage on external links |
| XSS Prevention | All user-supplied strings are passed through escHtml() before any innerHTML insertion. Escapes &, <, >, ", ' |
| Input Length Limits | f(x) capped at 500 characters; bound expressions capped at 200 characters — prevents ReDoS on the regex preprocessor |
| Radio Button Whitelisting | bracketMode and stopMode values are checked against explicit allowlists before use — cannot be injected |
| parseVal Guard | Strings over 200 chars are rejected before reaching math.evaluate() |
| Download MIME Validation | dl() validates blob type is image/png, application/pdf, or image/gif before creating the anchor |
| Filename Sanitisation | Downloaded filenames are stripped of unsafe characters via regex |
| SQL Injection | Not applicable — this is a fully client-side application with no database or backend |
| Sandboxed Math Eval | All expression evaluation is done via Math.js which provides its own sandboxed parser — eval() is never called on user input |
| Library | Version | Purpose |
|---|---|---|
| Math.js | 14.x | Expression parsing, sandboxed evaluation, and symbolic differentiation (Newton-Raphson) |
| html2canvas | 1.4.1 | DOM → Canvas for image export |
| jsPDF | 3.0.3 | Canvas → PDF export |
| gif.js | 0.2.0 | Client-side animated GIF encoding for the graph export |
| IBM Plex Sans / Mono | — | Typography (Google Fonts) |
Zero build tooling. No Webpack, Vite, Rollup, npm, or Node.js required. All libraries are loaded from cdnjs.cloudflare.com.
numerical-analysis-workbench/
│
├── index.html ← page markup & layout
├── styles.css ← all styling (design tokens, components, responsive)
├── core.js ← shared math utilities, method registry, export/GIF plumbing, page chrome
├── engine-bracketing.js ← Bisection & False Position engines, graph, table
├── engine-open.js ← Newton-Raphson & Secant engines, graph, table
├── concern.html ← Academic Integrity & Usage Policy page
├── favicon.svg ← browser tab icon
│
└── assets/
├── banner.svg
└── screenshots/
├── 01-desktop-full.png
├── 02-solution-ivt.png
├── 03-graph-step4.png
├── 04-iteration-table.png
├── 05-mobile.png
└── 06-export-pdf.png
The app is zero-dependency static files — no build step, no npm, no server. Drop the folder anywhere and open index.html.
Adding a new method means creating a new engine-*.js (or extending an existing one if it shares the same input shape), merging its methods into NAW.METHODS via Object.assign, and subscribing to NAW.onMethodChange() to hook up its own hero demo and result-clearing. See engine-open.js for a worked example of plugging a second engine into the shared registry.
Why did the solver stop after only ~13 steps?
That's the new default behaviour — "When c stops changing". The solver compares consecutive midpoints at your chosen decimal precision (default: 4 places). Once two consecutive steps show the exact same displayed value, the root is resolved to that precision and there's nothing left to narrow.
This is mathematically correct: if c looks the same in two rows, you have your answer to the digits you can see.
If you need more steps — for a class assignment that asks for exactly N iterations, or to see the full convergence trail — switch the stop criterion to "A fixed number of steps" or "Full machine precision" before clicking Solve.
Why does my equation show a red dot?
The validation dot turns red when Math.js cannot parse the expression. Common fixes:
- Use
*for multiplication:2*xnot2 x(space alone won't work) - Use
^for powers:x^3notx³ - Functions need parentheses:
sin(x)notsin x— or use the shorthandsinx - Division:
x/2notx÷2 - Natural log: use
ln(x)—log(x)is base-10 in this app
Why does auto-detect sometimes not find a bracket?
The scanner checks whole-number steps from 0 to +1000 (positive pass), then −1000 to 0 (negative fallback). It will fail if:
- The function has no real roots in that range
- The root is at a discontinuity (e.g.
tan(x)has sign changes at asymptotes that look like roots) - The function requires a very small bracket that the whole-number scan skips over
Switch to "I'll set a and b myself" and enter bounds you know contain a root.
Auto-detect keeps returning a positive bracket — I need a negative one
By design, the scanner tries positive x values first. To force it to prefer the negative side, tick "Prefer negative x range" under the auto-detect option before clicking Solve. The scanner will then complete the negative sweep first and return the smallest-magnitude negative bracket it finds.
Can I use negative values for a and b?
Yes! Negative bounds are fully supported in manual mode. Just type `-2` for `a` and `-1` for `b`. The example `3x^3 - 7x + 5` uses `[-2, -1]` because its only real root is ≈ −1.834.
What's the difference between AE and RE in the table?
- AE (Absolute Error): If you provided a true root →
|c − true_root|. Otherwise, it depends on the method: Bisection/False Position use(b − a) / 2(the guaranteed bound from the bracket width); Newton-Raphson and Secant use|c − previous guess|(the change between successive approximations) since there's no bracket to bound the error — this is a useful indicator of convergence, but not a guaranteed bound the way the bracketing methods' is. - RE (Relative Error):
AE / |c|— gives the error as a fraction of the approximation.
Newton-Raphson gave me an error about f′(x) ≈ 0 — what happened?
The tangent line at your current guess is (nearly) flat, so `a − f(a)/f'(a)` would divide by ~zero or send the next guess flying off to somewhere unhelpful. This is a real limitation of Newton-Raphson, not a bug — try a different starting guess, ideally one closer to where you expect the root to be.
Secant method says the line is horizontal — what does that mean?
It means `f(x₀) = f(x₁)` for your current pair of points, so the line through them has no slope and never crosses zero. Pick two starting points where the function takes different values — this is why the app's auto-suggest scans for a sign change even though Secant doesn't strictly require one.
Do Newton-Raphson and Secant need f(a)·f(b) < 0 like the bracketing methods?
No — that's the whole point of calling them "open" methods. Newton-Raphson only needs one starting guess with `f'(x) ≠ 0`; Secant only needs two distinct starting points with different `f` values. Neither requires the two ends to have opposite signs. The app's auto-suggest still reuses the same sign-change scanner for convenience (it's a decent way to land near a root), but it's not a mathematical requirement the way IVT is for Bisection/False Position.
The export looks different on my phone vs desktop — is that normal?
The app UI adapts for mobile screens. However, the exported file is always identical — it's rendered from a dedicated off-screen 1120px landscape panel, not a screenshot of what you see on screen. So the PDF/PNG will always contain every column in landscape format regardless of your device.
Can I host this on my own domain?
Absolutely. Upload all the root-level files together to any static host:
index.html styles.css core.js engine-bracketing.js engine-open.js concern.html favicon.svg
- GitHub Pages (free)
- Netlify (free, drag-and-drop)
- Vercel (free)
- Any shared hosting with FTP access
| Property | Bisection | False Position | Newton-Raphson | Secant |
|---|---|---|---|---|
| Convergence | Linear — guaranteed | Linear (often faster in practice) — guaranteed | Quadratic near the root — not guaranteed | Superlinear (order ≈ 1.618) — not guaranteed |
| Error after n steps | No fixed bound — can stagnate on one side | Roughly doubles correct digits each step (once close) | Digits grow by factor ≈1.618 each step (once close) | |
| Needs |
f(a)·f(b) < 0, f continuous |
f(a)·f(b) < 0, f continuous |
one guess, f'(x) ≠ 0
|
two distinct guesses, f(x₀) ≠ f(x₁)
|
| Failure conditions | f not continuous on [a,b], or f(a)·f(b) ≥ 0
|
Same as Bisection; can stagnate near strongly one-sided curvature | flat derivative, poor guess → divergence, cycling, or wrong root | horizontal secant line, divergence |
| Steps for 6 decimal places (typical) | ≈ 20 (bracket width 1) | Often fewer, varies with curvature | ≈ 4–6 | ≈ 6–8 |
Contributions are welcome! Here's how:
# 1. Fork and clone
git clone https://github.com/mehedyk/Numerical-Analysis.git
# 2. Create a feature branch
git checkout -b feature/my-new-method
# 3. Make your changes
# - New methods go in engine-*.js (see engine-bracketing.js for a bracket-
# style template, or engine-open.js for a starting-guess-style template)
# - Shared utilities go in core.js
# - UI/layout changes go in index.html + styles.css
# 4. Test by opening index.html in a browser (no build needed)
# 5. Submit a pull request- False Position method ✓
- Newton-Raphson method ✓
- Secant method ✓
- GIF export of the animated graph ✓
- Fixed-point iteration
- Lagrange interpolation
- Newton's divided-difference interpolation
- Gauss-Seidel / Jacobi (linear systems)
- Runge-Kutta (ODEs)
- Dark/light theme toggle
- Share-by-URL (encode equation in URL hash)
- Copy table as LaTeX / CSV
- Complex root detection warning
- Bangla language support 🇧🇩
MIT License
Copyright (c) 2026 S.M. Mehedy Kawser
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.





