5.4.25 · D5Scientific Computing (Python)
Question bank — Implementing root-finding from scratch — Newton-Raphson, bisection
True or false — justify
Bisection is guaranteed to find a root of any function on once .
False. It needs continuous on ; the guarantee comes from the Intermediate Value Theorem, which requires no jumps. On over the signs flip but there is no root — the "crossing" is a vertical asymptote.
If then there is definitely no root in .
False. It only means bisection cannot start. A parabola like on has yet holds two roots — an even number of crossings hides the sign change.
Newton-Raphson always needs fewer -evaluations than bisection to hit a tolerance.
False in cost, even when true in step count. Each Newton step costs one and one evaluation, so a single iteration is roughly twice as expensive; the win only shows once quadratic convergence kicks in near the root.
Quadratic convergence means the error is squared each step, so the error shrinks no matter where you start.
False. The law is a local statement — it only holds once is small. Far away, can be bigger than , so the "squaring" makes things worse, not better.
Halving the tolerance costs bisection one extra iteration.
True. Steps scale like ; dividing by 2 adds exactly to that count — one more bit of accuracy per step.
Newton's method is a special case of Fixed-point iteration.
True. Writing , Newton is just iterating ; a root of is a fixed point of , and is exactly why it converges quadratically.
The Secant method is just Newton with the derivative replaced by a slope through two points.
True. It swaps for , needing no derivative; the price is slower (order , not 2) convergence.
Bisection's convergence rate depends on the shape of .
False. The bracket width halves every step regardless of — the rate is always exactly . Only the starting width and where the root sits inside affect the constant, not the ratio.
Spot the error
"I'll store fa once, then each loop check if f(a)*f(m) < 0." — what's wrong?
You recompute
f(a) every iteration (wasted calls) — and worse, after you move a, that fresh f(a) is a new value while your logic may still assume the old sign. Compare the stored fa against fm and update fa only when you keep the left endpoint."My bisection returned the midpoint even though f(a)f(b)>0, so it still works."
A red flag. With no sign change the returned midpoint is meaningless — there may be no root at all. The routine must raise on a bad bracket, not silently hand back a number.
"Newton diverged, so my derivative formula must be wrong." — is that the only cause?
No. Even a correct diverges if is far away, if (a giant step), or if the iterates cycle. Check the starting guess and flat-derivative cases before suspecting an algebra bug.
"To stop Newton I test f(x) == 0."
Floating point arithmetic almost never lands exactly on 0, so this rarely triggers and you loop to
maxit. Test abs(step) < tol (or abs(f(x)) < tol) — a neighbourhood, not an exact hit."Bisection stops when f(m) == 0, so the (b-a)/2 < tol check is redundant."
Backwards. The exact-zero case is the rare one; the width test is what normally ends the loop. Remove it and bisection runs to
maxit on almost every real problem."I passed bisection(f, 2, 1, ...) (a>b) and got garbage."
The width is now negative, so
(b-a)/2 < tol is true immediately and you exit on step zero. Bisection assumes ; either sort the endpoints or document the precondition."Newton on starting at is fine, it's a nice smooth function."
, so the very first step divides by zero — the tangent is horizontal and never meets the x-axis. Smoothness doesn't save you; a zero derivative does you in.
Why questions
Why does bisection get one bit of accuracy per step, no more, no less?
Each step halves the interval, and halving means the leading uncertain binary digit becomes known — exactly one bit. This ties bisection conceptually to Binary search, which also discards half the space each comparison.
Why does Newton need at the root for quadratic convergence?
The error law carries ; if this constant blows up. Geometrically the root is a tangent touch (a repeated root), the tangent line is nearly flat, and convergence degrades to merely linear.
Why is Taylor Series the right tool to explain Newton's speed, rather than just drawing the tangent?
The tangent picture shows what Newton does; the Taylor expansion of about quantifies the leftover error term , telling us how fast. The picture gives intuition, the series gives the exponent.
Why can a hybrid like brentq beat both pure methods?
It keeps a guaranteed bracket (bisection's safety) but tries fast interpolation inside it (Newton/secant-like speed), falling back to a bisection step whenever the fast guess would leave the bracket — you get robustness and speed. See scipy.optimize.
Why does scipy.optimize.brentq not need a derivative even though Newton does?
Brent uses the Secant method and inverse-quadratic interpolation, both of which estimate curvature from function values alone — no callback required, which is why it's the go-to for black-box functions.
Why is "step size below tolerance" a better stopping test than "function value below tolerance"?
Near a steep root a tiny -error gives a large , so an test may never trigger; near a flat root a large -error gives a tiny , so an test stops too early. The step measures actual position change and behaves more predictably.
Edge cases
What happens in bisection when the root sits exactly at an endpoint, e.g. ?
Then , not , so the bracket test fails and the loop never runs — you'd lose a real root. That's why you check and return endpoints before the loop.
What does Newton do on starting anywhere but the root?
It diverges — each step overshoots to the opposite side, farther out: . The root at 0 has an infinite-slope tangent, so the linear model is a lie and the iterates run away. Bisection would have nailed it.
Two roots sit inside one bracket, e.g. on vs — what does bisection give?
On there is one sign change so it finds ; on signs match () so it refuses to start. Bisection finds a root inside a valid odd-crossing bracket, never promises which if you sneak in an even count.
A perfectly flat plateau: during Newton — what should code do?
Division by zero (flat tangent, no x-intercept). Raise an error or nudge the guess; blindly computing yields
inf/nan and silently corrupts the run.Newton cycles: forever — is that possible?
Yes. For some and starting points the tangent bounces between two values and never converges (e.g. certain odd functions symmetric about the root). Only a
maxit guard saves you — the step size never shrinks below tol.The bracket is astronomically wide, say — is bisection still fine?
Yes, just slower by the log: width needs about steps for . Linear-per-bit means even enormous brackets cost only tens of iterations — robustness barely notices the size.
What if returns a NaN somewhere in the bracket (e.g. for negative )?
Every sign comparison with NaN is
False, so bisection may repeatedly keep the wrong half and converge to a garbage value. Guard against NaN/inf function outputs; a valid bracket assumes is defined on all of .Recall One-line summary
Bisection trades speed for an ironclad guarantee (needs continuity + a sign change); Newton trades the guarantee for quadratic speed (needs a derivative, a good start, and a non-flat root). Every trap above is one of those preconditions being quietly violated.