-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
357 lines (325 loc) · 23.1 KB
/
Copy pathindex.html
File metadata and controls
357 lines (325 loc) · 23.1 KB
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>(function(){try{if(localStorage.getItem('naw-theme')==='light')document.documentElement.dataset.theme='light';}catch(e){}})();</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Numerical Analysis Workbench</title>
<meta name="description" content="An interactive numerical analysis workbench. Solve root-finding problems with the bisection method, step by step, with animated visuals and exportable solutions." />
<!-- Security headers -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob: https://fonts.googleapis.com https://fonts.gstatic.com https://cdnjs.cloudflare.com; img-src 'self' data: blob: https://img.youtube.com; frame-src https://www.youtube-nocookie.com; object-src 'none';">
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta http-equiv="Referrer-Policy" content="no-referrer">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Sans+Condensed:wght@500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to content</a>
<div class="shell">
<nav class="sheet-index" aria-label="Numerical methods">
<div class="brand">
<svg class="brand-mark" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<rect x="1" y="1" width="30" height="30" rx="3" stroke="#3D6694" stroke-width="1.5"/>
<line x1="6" y1="22" x2="26" y2="22" stroke="#AEC0D6" stroke-width="1.2" stroke-dasharray="2 2"/>
<circle cx="16" cy="22" r="2.6" fill="#C9784B"/>
<line x1="6" y1="22" x2="6" y2="9" stroke="#AEC0D6" stroke-width="1.2"/>
<line x1="26" y1="22" x2="26" y2="13" stroke="#AEC0D6" stroke-width="1.2"/>
<path d="M6 22 C 10 6, 20 6, 26 13" stroke="#7FA68C" stroke-width="1.4" fill="none"/>
</svg>
<div class="brand-text">Numerical Analysis<small>Workbench</small></div>
<button type="button" class="theme-toggle-btn" aria-pressed="false" aria-label="Switch between light and dark theme">
<svg class="theme-toggle-icon icon-sun" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
<svg class="theme-toggle-icon icon-moon" viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
<span class="theme-toggle-label">Dark</span>
</button>
</div>
<div class="index-label-row">
<p class="index-label">Sheet index</p>
<button type="button" class="sheet-toggle-btn" id="sheet-list-toggle" aria-expanded="true" aria-controls="sheet-list">Hide</button>
</div>
<ul class="sheet-list" id="sheet-list">
<li class="sheet-item active" data-method="bisection" role="button" tabindex="0"><span class="num">01</span> Bisection method</li>
<li class="sheet-item" data-method="falseposition" role="button" tabindex="0"><span class="num">02</span> False position method</li>
<li class="sheet-item" data-method="newton" role="button" tabindex="0"><span class="num">03</span> Newton–Raphson</li>
<li class="sheet-item" data-method="secant" role="button" tabindex="0"><span class="num">04</span> Secant method</li>
<li class="sheet-item disabled"><span class="num">05</span> Fixed-point iteration <span class="soon">soon</span></li>
<li class="sheet-item disabled"><span class="num">06</span> Lagrange interpolation <span class="soon">soon</span></li>
<li class="sheet-item" data-method="ludecomp" role="button" tabindex="0"><span class="num">07</span> LU decomposition</li>
<li class="sheet-item" data-method="numdiff" role="button" tabindex="0"><span class="num">08</span> Numerical differentiation</li>
<li class="sheet-item" data-method="gauss" role="button" tabindex="0"><span class="num">09</span> Gaussian elimination</li>
</ul>
<div class="sidebar-foot">
Built by <a href="https://mehedy.netlify.app/" target="_blank" rel="noopener">S.M. Mehedy Kawser</a><br>
Sheet rev. 2026.3<br>
<a href="https://github.com/mehedyk/Numerical-Analysis" target="_blank" rel="noopener">★ Found this useful? Star it on GitHub</a>
</div>
<div class="tutorial-video-section">
<p class="index-label">Tutorial video</p>
<div class="tutorial-video" id="tutorial-video" data-video-id="KBs5DitzTOA">
<button type="button" class="tutorial-video-thumb" id="tutorial-video-thumb" aria-label="Play tutorial video on YouTube">
<img src="https://img.youtube.com/vi/KBs5DitzTOA/hqdefault.jpg" alt="" loading="lazy" />
<span class="play-badge" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
</span>
</button>
</div>
<p class="tutorial-video-caption">How to use this workbench, step by step.</p>
</div>
</nav>
<div class="mobile-nav" aria-label="Numerical methods">
<button class="active" type="button" data-method="bisection">01 Bisection</button>
<button type="button" data-method="falseposition">02 False position</button>
<button type="button" data-method="newton">03 Newton–Raphson</button>
<button type="button" data-method="secant">04 Secant</button>
<button type="button" data-method="ludecomp">07 LU decomp.</button>
<button type="button" data-method="numdiff">08 Num. diff.</button>
<button type="button" data-method="gauss">09 Gauss elim.</button>
<button type="button" class="theme-toggle-btn theme-toggle-btn--mobile" aria-pressed="false" aria-label="Switch between light and dark theme">
<svg class="theme-toggle-icon icon-sun" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
<svg class="theme-toggle-icon icon-moon" viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
<span class="theme-toggle-label">Dark</span>
</button>
</div>
<main class="workbench" id="main-content">
<!-- ── HERO ──────────────────────────────────────────────────── -->
<section class="hero" id="hero-section">
<div>
<h1 id="hero-title">Bisection method,<br>drawn out <span class="accent">step by step</span>.</h1>
<p class="hero-sub" id="hero-sub">Give it an equation and a bracket, and watch the interval close in on the root — one halving at a time, with every approximation and error logged along the way.</p>
<div class="hero-meta">
<span><b>Method</b> <span id="meta-method-val">Bisection (bracketing)</span></span>
<span><b>Order</b> <span id="meta-order-val">Linear convergence</span></span>
<span><b>Needs</b> <span id="meta-needs-val">sign change on [a, b]</span></span>
</div>
</div>
<div class="hero-plate">
<div class="hero-plate-label"><span id="hero-plate-fx">Live demo — f(x) = x³ − x − 2</span><span id="hero-step-label">step 1</span></div>
<svg id="hero-graph" viewBox="0 0 520 240" role="img" aria-label="Animated demo of the bisection method narrowing in on a root"></svg>
</div>
</section>
<!-- ── INPUT PANEL ───────────────────────────────────────────── -->
<section class="panel" aria-labelledby="input-heading">
<div class="panel-head">
<h2 id="input-heading">Set up the problem</h2>
<span class="plate-tag">Sheet 01 / Input</span>
</div>
<div class="panel-body">
<form id="bisection-form" novalidate>
<div class="field" id="fx-field">
<label for="fx-input">f(x) =</label>
<div class="fx-row">
<input type="text" id="fx-input" name="fx" placeholder="x^3 - 4*x - 9" autocomplete="off" inputmode="text" aria-describedby="fx-hint" />
<span class="validity-dot" id="fx-validity" aria-hidden="true"></span>
</div>
<p class="field-hint" id="fx-hint">Use <code>x</code> as the variable — powers, trig, logs, roots, and the constants <code>e</code> and <code>pi</code> are all supported. <button type="button" class="example-link" id="load-example">Load an example</button></p>
<details class="tutorial">
<summary>How do I type my equation?</summary>
<div class="tutorial-body">
<p>The parser reads standard math notation. A few examples:</p>
<table class="syntax-table">
<thead><tr><th>You want</th><th>Type this</th></tr></thead>
<tbody>
<tr><td>Powers</td><td><code>x^3</code>, <code>x^2</code></td></tr>
<tr><td>Multiplication</td><td><code>4*x</code> (or just <code>4x</code>)</td></tr>
<tr><td>Square root</td><td><code>sqrt(x)</code></td></tr>
<tr><td>Trig functions</td><td><code>sin(x)</code>, <code>cos(x)</code>, <code>tan(x)</code></td></tr>
<tr><td>Implicit trig</td><td><code>x*tan(x)</code> or shorthand <code>xtan(x)</code></td></tr>
<tr><td>Exponential eˣ</td><td><code>exp(x)</code> or <code>e^x</code></td></tr>
<tr><td>Natural log</td><td><code>ln(x)</code> or shorthand <code>lnx</code></td></tr>
<tr><td>Base-10 log</td><td><code>log(x)</code> or <code>log10(x)</code> or shorthand <code>logx</code></td></tr>
<tr><td>Constants</td><td><code>pi</code>, <code>e</code> (Euler's number ≈ 2.71828)</td></tr>
<tr><td>Absolute value</td><td><code>abs(x)</code></td></tr>
</tbody>
</table>
<div class="note-box info">The bounds a and b also accept expressions: type <code>e</code>, <code>pi</code>, <code>2*pi</code>, <code>sqrt(2)</code>, etc. Negative values like <code>-2</code> are allowed — enter them freely in manual mode.</div>
<div class="note-box" style="margin-top:8px;"><code>ln(x)</code> and <code>log(x)</code> are kept separate in this parser: <code>ln(x)</code> is always the <em>natural</em> log, and <code>log(x)</code> is always <em>base-10</em> (same as <code>log10(x)</code>).</div>
</div>
</details>
</div>
<!-- ── MATRIX A (Sheets 07 & 09 — revealed by their engines) ── -->
<fieldset id="matrix-fieldset" hidden>
<legend>Matrix A</legend>
<textarea id="matrix-input" rows="4" spellcheck="false" autocomplete="off" placeholder="2 1 -1 8 -3 -1 2 -11 -2 1 2 -3"></textarea>
<p class="field-hint matrix-hint">One row per line = one equation: coefficients of x, y, z… then the right-hand side. Cells separated by spaces or commas — expressions like <code>pi</code>, <code>sqrt(2)</code>, <code>-1/2</code> all work. Leave out the extra column for pure reduction. Square sizes from 2×2 up to 6×6.</p>
</fieldset>
<!-- ── BRACKET [a, b] ──────────────────────────────────── -->
<fieldset id="bracket-fieldset">
<legend id="bracket-legend">Bracket [a, b]</legend>
<div class="stop-options" id="bracket-mode-options">
<!-- Option 1: auto-detect -->
<div class="stop-option active-mode" data-mode="bracket-auto">
<input type="radio" name="bracketMode" id="bracket-mode-auto" value="auto" checked />
<label class="opt-label" for="bracket-mode-auto" id="bracket-auto-label">Find a and b automatically</label>
<span class="field-hint" id="bracket-auto-hint" style="margin:0;">scans f(x) for a sign change near the curve</span>
<!-- Sub-toggle row: fine decimal + prefer negative -->
<div class="bracket-sub-toggles">
<label for="bracket-fine-toggle" class="bracket-sub-label">
<input type="checkbox" id="bracket-fine-toggle" class="bracket-sub-check" />
Prefer a tighter decimal bracket over whole numbers
</label>
<label for="bracket-neg-toggle" class="bracket-sub-label">
<input type="checkbox" id="bracket-neg-toggle" class="bracket-sub-check" />
Prefer negative x range <span class="bracket-sub-hint">(scan negative side first)</span>
</label>
</div>
</div>
<!-- Option 2: manual -->
<div class="stop-option" data-mode="bracket-manual">
<input type="radio" name="bracketMode" id="bracket-mode-manual" value="manual" />
<label class="opt-label" for="bracket-mode-manual" id="bracket-manual-label">I'll set a and b myself</label>
<span class="field-hint" id="bracket-manual-hint" style="margin:0;">type your own bounds below — negative values like −2 are allowed</span>
</div>
</div>
</fieldset>
<!-- bounds inputs -->
<div class="field-row">
<div class="field" id="a-field">
<label for="a-input" id="a-input-label">a (lower bound)</label>
<input type="text" id="a-input" name="a" placeholder="auto-detected on Solve" autocomplete="off" disabled />
</div>
<div class="field" id="b-field-wrap">
<label for="b-input" id="b-input-label">b (upper bound)</label>
<input type="text" id="b-input" name="b" placeholder="auto-detected on Solve" autocomplete="off" disabled />
</div>
<div class="field" id="true-root-field">
<label for="true-root-input">True root (optional)</label>
<input type="text" id="true-root-input" name="trueRoot" placeholder="if known, enables AE/RE" autocomplete="off" />
</div>
<div class="field" id="h-field-wrap" hidden>
<label for="h-input">Step size h</label>
<input type="text" id="h-input" name="h" placeholder="e.g. 0.1 or pi/100" autocomplete="off" />
<p class="field-hint" style="margin-top:6px;">spacing between sample points — usually positive, must be nonzero</p>
</div>
<div class="field">
<label for="precision-input">Decimal places</label>
<input type="number" id="precision-input" name="precision" min="1" max="8" step="1" value="4" />
<p class="field-hint" style="margin-top:6px;">shown after the decimal point, anywhere from 1 to 8</p>
</div>
</div>
<p class="field-hint" id="bracket-found-hint" hidden style="margin:-8px 0 18px;"></p>
<!-- ── STOP CRITERIA ───────────────────────────────────── -->
<fieldset id="stop-fieldset">
<legend>Stop after…</legend>
<div class="stop-options" id="stop-options">
<!-- Default: c-repeat -->
<div class="stop-option active-mode" data-mode="c-repeat">
<input type="radio" name="stopMode" id="mode-crepeat" value="c-repeat" checked />
<label class="opt-label" for="mode-crepeat">When c stops changing <span class="stop-badge stop-badge--default">default</span></label>
<span class="field-hint stop-option-hint">stops as soon as two consecutive midpoints are identical — the most natural convergence signal</span>
</div>
<!-- Fixed iteration count -->
<div class="stop-option" data-mode="iterations">
<input type="radio" name="stopMode" id="mode-iter" value="iterations" />
<label class="opt-label" for="mode-iter">A fixed number of steps</label>
<input type="number" class="sub-input" id="iter-count" min="1" max="500" placeholder="e.g. 6" disabled />
</div>
<!-- Tolerance -->
<div class="stop-option" data-mode="tolerance">
<input type="radio" name="stopMode" id="mode-tol" value="tolerance" />
<label class="opt-label" for="mode-tol">An error tolerance</label>
<input type="number" class="sub-input" id="tol-value" step="any" min="0" placeholder="e.g. 0.001" disabled />
</div>
<!-- Legacy: machine precision -->
<div class="stop-option" data-mode="auto">
<input type="radio" name="stopMode" id="mode-auto" value="auto" />
<label class="opt-label" for="mode-auto">Run to full machine precision <span class="stop-badge">legacy</span></label>
<span class="field-hint stop-option-hint">original behaviour — narrows until the bracket width is below 4 × machine epsilon (may take 50 + steps)</span>
</div>
</div>
</fieldset>
<div class="btn-row">
<button type="submit" class="btn btn--primary" id="solve-btn">Solve</button>
<button type="button" class="btn btn--ghost" id="reset-btn">Reset</button>
</div>
<div class="status-msg" id="status-msg" hidden role="alert"></div>
</form>
</div>
</section>
<!-- ── SOLUTION BOX ──────────────────────────────────────────── -->
<section class="panel" id="solution-section" hidden aria-labelledby="sol-heading" aria-live="polite">
<div class="panel-head">
<h2 id="sol-heading">Solution analysis</h2>
<span class="plate-tag">Sheet 01 / Solution</span>
</div>
<div class="panel-body">
<div id="sol-box" class="sol-inner"></div>
</div>
</section>
<!-- ── VISUALIZATION ─────────────────────────────────────────── -->
<section class="panel" id="viz-section" hidden aria-labelledby="viz-heading">
<div class="panel-head">
<h2 id="viz-heading">Visualizing the bracket</h2>
<span class="plate-tag">Sheet 01 / Plot</span>
</div>
<div class="panel-body">
<div class="viz-wrap">
<svg id="bisection-graph" viewBox="0 0 800 420" role="img" aria-label="Plot of f(x) with the narrowing bisection bracket"></svg>
</div>
<div class="reading-row">
<div class="reading"><b id="read-a-label">a</b><span id="read-a">—</span></div>
<div class="reading"><b id="read-b-label">b</b><span id="read-b">—</span></div>
<div class="reading c-value"><b id="c-reading-label">c (midpoint)</b><span id="read-c">—</span></div>
<div class="reading"><b id="read-fc-label">f(c)</b><span id="read-fc">—</span></div>
<div class="reading converged" id="read-converged-wrap" hidden><b>status</b><span id="read-converged">—</span></div>
</div>
<div class="viz-controls">
<button type="button" class="btn btn-icon" id="step-prev" aria-label="Previous step" disabled>‹</button>
<button type="button" class="btn btn-icon" id="play-pause" aria-label="Play">▶</button>
<button type="button" class="btn btn-icon" id="step-next" aria-label="Next step" disabled>›</button>
<select class="speed-select" id="speed-select" aria-label="Playback speed">
<option value="1400">Slow</option>
<option value="800" selected>Normal</option>
<option value="400">Fast</option>
</select>
<button type="button" class="btn" id="export-gif-btn" title="Download the animated graph, replaying every step, as a GIF">Download as GIF</button>
<span class="step-indicator" id="step-indicator">Step 0 of 0</span>
</div>
</div>
</section>
<!-- ── ITERATION TABLE ───────────────────────────────────────── -->
<section class="panel" id="table-section" hidden aria-labelledby="table-heading">
<div class="panel-head">
<h2 id="table-heading">Iteration log</h2>
<span class="plate-tag">Sheet 01 / Record</span>
</div>
<div class="panel-body">
<div class="table-scroll" id="capture-target">
<p id="capture-summary" style="font-family:var(--font-mono);font-size:.84rem;color:var(--ink-dim);margin-bottom:14px;"></p>
<table class="iter-table" id="iter-table">
<thead><tr id="iter-thead-row"></tr></thead>
<tbody id="iter-tbody"></tbody>
</table>
<p class="table-note" id="table-note"></p>
</div>
<div class="export-row">
<button type="button" class="btn" id="export-image-btn">Download as image</button>
<button type="button" class="btn" id="export-pdf-btn">Download as PDF</button>
<span class="export-note">Exports include the equation, bracket check, and full iteration log.</span>
</div>
</div>
</section>
<footer class="site-foot">
<span>Numerical Analysis Workbench . All rights reserved © 2026.</span>
<span style="display:flex;gap:18px;align-items:center;flex-wrap:wrap;">
<a href="https://github.com/mehedyk/Numerical-Analysis" target="_blank" rel="noopener">★ Give it a star on GitHub</a>
<a href="concern.html" target="_blank" rel="noopener" style="color:var(--ink-faint);font-weight:400;font-size:.78rem;opacity:.7;">Academic Integrity & Usage Policy</a>
<span>Built by <a href="https://mehedy.netlify.app/" target="_blank" rel="noopener">S.M. Mehedy Kawser</a></span>
</span>
</footer>
</main>
</div><!-- .shell -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/14.8.1/math.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/3.0.3/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gif.js/0.2.0/gif.js"></script>
<script src="core.js" defer></script>
<script src="engine-bracketing.js" defer></script>
<script src="engine-open.js" defer></script>
<script src="engine-matrix.js" defer></script>
<script src="engine-diff.js" defer></script>
<script src="engine-gauss.js" defer></script>
</body>
</html>