Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Part 1: Finite Differences and Discrete Calculus

Foundations of Discrete Computing | Numerical Methods Module 1 | COMP 521

Learning Objectives

By the end of this section, you will be able to:


Introduction: Why Numerical Derivatives Matter

Why this matters: numerical derivatives are not a side topic in computational astrophysics. They sit inside orbit integration, stellar structure, radiative transfer, optimization, and data analysis.

In continuous mathematics, derivatives tell us how a quantity changes at an instant. In computational science, we almost never have access to that exact instantaneous limit. We have function values at nearby points, finite precision arithmetic, and algorithms that must make a choice about how close is “close enough.”

Derivatives appear everywhere in the astrophysical problems we care about:

Most real scientific problems do not hand us a closed-form answer. We discretize, approximate, and compute. That move from the continuous world to the discrete world is where the central paradox of this reading lives.


The Core Problem

Why this matters: if you do not understand the core derivative paradox, every later conversation about truncation error, round-off error, and algorithm design will feel like disconnected rules.

The mathematical definition of the derivative is

f′(x)=lim⁡h→0f(x+h)−f(x)h.f'(x) = \lim_{h \to 0}\frac{f(x+h)-f(x)}{h}.

This equation is compact, but it mixes three ideas that we must separate carefully:

Mathematics wants h→0h \to 0; computers require h>0h > 0.

Here is a compact worked example before we derive anything formal. Let

f(x)=x2.f(x) = x^2.

The exact derivative is

f′(x)=2x,f'(x) = 2x,

so at x=3x = 3 the true answer is f′(3)=6f'(3)=6.

If we use the forward-difference idea with h=0.5h=0.5,

f(3.5)−f(3)0.5=12.25−90.5=6.5.\frac{f(3.5)-f(3)}{0.5} = \frac{12.25-9}{0.5} = 6.5.

If we shrink to h=0.1h=0.1,

f(3.1)−f(3)0.1=9.61−90.1=6.1.\frac{f(3.1)-f(3)}{0.1} = \frac{9.61-9}{0.1} = 6.1.

The approximation improves as hh gets smaller, but it is still not exact because we have not taken the true limit.

as $h$ shrinks, the secant slope moves toward the tangent slope, but the figure never lets the discrete secant become the exact limit

Figure 1:What to notice: as hh shrinks, the secant slope moves toward the tangent slope, but the figure never lets the discrete secant become the exact limit. That visual gap is the paradox of numerical differentiation: smaller hh improves the approximation, but the computer still works with a finite step.

Open full-size figure

On a real computer, we also need to remember that numbers are stored in floating-point form. Double precision gives roughly 16 decimal digits of relative precision near numbers of order unity, but that does not mean every subtraction preserves 16 useful digits.

If hh is too small, then x+hx+h may round to the same floating-point value as xx. If f(x+h)f(x+h) and f(x)f(x) are nearly equal, the subtraction

f(x+h)−f(x)f(x+h)-f(x)

can lose most of the significant digits we care about. This is catastrophic cancellation.


Intuition: Why Taylor Series?

Why this matters: Taylor series gives us a controlled way to connect a continuous function to nearby discrete samples. It is the mathematical bridge between calculus and computation.

Student mental model: Taylor series is a local decoder ring. It tells us exactly what information is hidden inside the nearby function values f(x+h)f(x+h), f(x−h)f(x-h), f(x+2h)f(x+2h), and so on.

Around the point xx, the Taylor expansion of a smooth function is

f(x+h)=f(x)+hf′(x)+h22f′′(x)+h36f′′′(x)+O(h4).f(x+h)=f(x)+h f'(x)+\frac{h^2}{2}f''(x)+\frac{h^3}{6}f'''(x)+O(h^4).

This equation says that the value at x+hx+h contains the function value, the slope, the curvature, and higher-order corrections. Computationally, that is exactly what we need: if we rearrange this expansion, we can isolate f′(x)f'(x) and understand the error we introduce when we truncate the rest.

The backward expansion is equally important:

f(x−h)=f(x)−hf′(x)+h22f′′(x)−h36f′′′(x)+O(h4).f(x-h)=f(x)-h f'(x)+\frac{h^2}{2}f''(x)-\frac{h^3}{6}f'''(x)+O(h^4).

Now we have a menu of nearby samples, and we can combine them in clever ways. Some combinations keep the O(h)O(h) error term. Others cancel it. The design of a finite-difference formula is really the design of a Taylor-series cancellation pattern.


Forward Difference

Why this matters: forward difference is the simplest derivative approximation, and it appears naturally whenever we only know values at the current point and points ahead.

The forward Taylor expansion is

f(x+h)=f(x)+hf′(x)+h22f′′(x)+h36f′′′(x)+O(h4).f(x+h)=f(x)+h f'(x)+\frac{h^2}{2}f''(x)+\frac{h^3}{6}f'''(x)+O(h^4).

This expansion tells us how a one-sided sample at x+hx+h mixes the derivative we want with curvature and higher-order contamination.

Subtract f(x)f(x) from both sides:

f(x+h)−f(x)=hf′(x)+h22f′′(x)+h36f′′′(x)+O(h4).f(x+h)-f(x)=h f'(x)+\frac{h^2}{2}f''(x)+\frac{h^3}{6}f'''(x)+O(h^4).

The left-hand side is now a computable change in the function value over one forward step.

Now divide by hh:

f(x+h)−f(x)h=f′(x)+h2f′′(x)+h26f′′′(x)+O(h3).\frac{f(x+h)-f(x)}{h}=f'(x)+\frac{h}{2}f''(x)+\frac{h^2}{6}f'''(x)+O(h^3).

This turns the finite change into a secant slope, while the remaining Taylor terms reveal the bias we introduced.

Finally, solve for the derivative:

f′(x)=f(x+h)−f(x)h−h2f′′(x)−h26f′′′(x)+O(h3).f'(x)=\frac{f(x+h)-f(x)}{h}-\frac{h}{2}f''(x)-\frac{h^2}{6}f'''(x)+O(h^3).

So the forward-difference approximation is

f′(x)≈f(x+h)−f(x)h.f'(x)\approx \frac{f(x+h)-f(x)}{h}.

This means the leading truncation error is proportional to hh, so forward difference is a first-order method:

Etrunc,forward(h)=O(h).E_{\mathrm{trunc,forward}}(h)=O(h).

Computationally, that statement tells us that halving hh only halves the leading truncation error. Forward difference is simple and useful, but not especially accurate.

For the earlier quadratic example with f(x)=x2f(x)=x^2, x=3x=3, and h=0.1h=0.1, we found the approximation 6.1 instead of 6.0. That 0.1 error is exactly the kind of first-order behavior the Taylor analysis predicts.

The leading h2f′′(x)\frac{h}{2}f''(x) term is the computational price of using a one-sided stencil: curvature leaks directly into the estimate.

Forward difference is simple, but its one-sided bias leaves a first-order error.


Backward Difference

Why this matters: backward difference becomes the natural choice near right-hand boundaries, or whenever “past” values are available but “future” values are not.

Start from the backward Taylor expansion:

f(x−h)=f(x)−hf′(x)+h22f′′(x)−h36f′′′(x)+O(h4).f(x-h)=f(x)-h f'(x)+\frac{h^2}{2}f''(x)-\frac{h^3}{6}f'''(x)+O(h^4).

This time we are reading the same local information from the point behind xx instead of the point ahead of it.

Rearrange:

f(x)−f(x−h)=hf′(x)−h22f′′(x)+h36f′′′(x)+O(h4).f(x)-f(x-h)=h f'(x)-\frac{h^2}{2}f''(x)+\frac{h^3}{6}f'''(x)+O(h^4).

Again, the goal is to isolate a computable finite change before dividing by the step size.

Then divide by hh:

f(x)−f(x−h)h=f′(x)−h2f′′(x)+h26f′′′(x)+O(h3).\frac{f(x)-f(x-h)}{h}=f'(x)-\frac{h}{2}f''(x)+\frac{h^2}{6}f'''(x)+O(h^3).

This secant slope now looks backward, so the sign of the leading bias changes.

Solving for f′(x)f'(x) gives

f′(x)=f(x)−f(x−h)h+h2f′′(x)−h26f′′′(x)+O(h3).f'(x)=\frac{f(x)-f(x-h)}{h}+\frac{h}{2}f''(x)-\frac{h^2}{6}f'''(x)+O(h^3).

So the backward-difference approximation is

f′(x)≈f(x)−f(x−h)h.f'(x)\approx \frac{f(x)-f(x-h)}{h}.

Like forward difference, backward difference has first-order truncation error:

Etrunc,backward(h)=O(h).E_{\mathrm{trunc,backward}}(h)=O(h).

The sign of the leading error term differs from the forward case, but the key computational message is the same: this method is still first-order accurate.

Backward difference has the same order as forward difference; only the direction changes.


Central Difference

Why this matters: central difference is the default first derivative in many scientific codes because symmetry cancels the largest truncation term.

Student mental model: forward and backward difference each lean to one side. Central difference stands in the middle and asks the left and right samples to balance each other.

Write both Taylor expansions:

f(x+h)=f(x)+hf′(x)+h22f′′(x)+h36f′′′(x)+h424f(4)(x)+O(h5),f(x+h)=f(x)+h f'(x)+\frac{h^2}{2}f''(x)+\frac{h^3}{6}f'''(x)+\frac{h^4}{24}f^{(4)}(x)+O(h^5),

This first expansion shows what the forward sample contributes.

f(x−h)=f(x)−hf′(x)+h22f′′(x)−h36f′′′(x)+h424f(4)(x)+O(h5).f(x-h)=f(x)-h f'(x)+\frac{h^2}{2}f''(x)-\frac{h^3}{6}f'''(x)+\frac{h^4}{24}f^{(4)}(x)+O(h^5).

The backward sample contains the same even-power terms, which is exactly what symmetry needs in order to cancel them.

Subtract the second equation from the first:

f(x+h)−f(x−h)=2hf′(x)+2h36f′′′(x)+O(h5).f(x+h)-f(x-h)=2h f'(x)+\frac{2h^3}{6}f'''(x)+O(h^5).

The even-power terms disappear, so the largest truncation contribution is now much smaller.

Now divide by 2h2h:

f(x+h)−f(x−h)2h=f′(x)+h26f′′′(x)+O(h4).\frac{f(x+h)-f(x-h)}{2h}=f'(x)+\frac{h^2}{6}f'''(x)+O(h^4).

This symmetric secant slope already has second-order accuracy built into it.

Solving for f′(x)f'(x) gives

f′(x)=f(x+h)−f(x−h)2h−h26f′′′(x)+O(h4).f'(x)=\frac{f(x+h)-f(x-h)}{2h}-\frac{h^2}{6}f'''(x)+O(h^4).

So the central-difference approximation is

f′(x)≈f(x+h)−f(x−h)2h.f'(x)\approx \frac{f(x+h)-f(x-h)}{2h}.

Its leading truncation error is proportional to h2h^2:

Etrunc,central(h)=O(h2).E_{\mathrm{trunc,central}}(h)=O(h^2).

Computationally, that means halving hh reduces the leading truncation error by about a factor of 4, not just a factor of 2.

For f(x)=x2f(x)=x^2, central difference at x=3x=3 is especially illuminating:

f(3+h)−f(3−h)2h=(3+h)2−(3−h)22h=6.\frac{f(3+h)-f(3-h)}{2h}=\frac{(3+h)^2-(3-h)^2}{2h}=6.

For a quadratic, the method is exact because the odd-power cancellation leaves no truncation error in the first derivative estimate.

Central difference uses symmetry to cancel the largest truncation term.


The Power of Symmetry

Why this matters: symmetry is one of the most powerful accuracy upgrades in numerical analysis, and central difference is your first clear example of it.

Central difference improves accuracy by pairing points symmetrically around xx. Even-order terms in the Taylor expansions cancel, leaving a smaller leading error term. Symmetry therefore changes the truncation order without changing the underlying approximation problem.

This pattern appears again and again:

What symmetry is really buying you is cancellation of systematic bias. In computational language: the approximation is still finite, but it is less one-sided.


Higher-Order Methods

Why this matters: when the function is smooth and extra function evaluations are affordable, higher-order methods can reduce truncation error dramatically.

By combining more Taylor expansions, we can cancel more unwanted terms. A standard fourth-order central difference for the first derivative is

f′(x)≈−f(x+2h)+8f(x+h)−8f(x−h)+f(x−2h)12h.f'(x)\approx \frac{-f(x+2h)+8f(x+h)-8f(x-h)+f(x-2h)}{12h}.

Its leading truncation error behaves like

Etrunc,central4(h)=O(h4).E_{\mathrm{trunc,central4}}(h)=O(h^4).

Computationally, this formula spends more function evaluations to buy a much smaller truncation error in the smooth-function regime. That trade is often worthwhile, but only if round-off and function noise do not dominate first.

If the function is noisy, non-smooth, or expensive to evaluate, higher order is not automatically better. A formally high-order method can still perform worse in practice if the assumptions behind the Taylor expansion are not satisfied.

Forward, central, and fourth-order central derivative errors decrease with step size before rounding changes their trends.

Figure 2:What to notice: the right-hand truncation regime has slopes that match the theory — forward behaves like O(h)O(h), central like O(h2)O(h^2), and fourth-order central like O(h4)O(h^4). The left-hand round-off upturn shows why higher order does not rescue you once subtraction error dominates.

Open full-size figure


The Fundamental Trade-off / Optimal hh

Why this matters: the best step size is not “the smallest one you can think of.” It is the one that balances two different error mechanisms.

There are two competing effects:

For forward difference, the leading truncation and round-off model is

Etotal(h)≈h2∣f′′(x)∣+ϵmachine∣f(x)∣h.E_{\mathrm{total}}(h)\approx \frac{h}{2}\lvert f''(x)\rvert + \frac{\epsilon_{\mathrm{machine}}\lvert f(x)\rvert}{h}.

This equation says that one part of the error prefers smaller hh, while the other prefers larger hh. The total error curve is therefore U-shaped.

Differentiate with respect to hh and set the derivative to zero:

dEtotaldh=12∣f′′(x)∣−ϵmachine∣f(x)∣h2=0.\frac{dE_{\mathrm{total}}}{dh}=\frac{1}{2}\lvert f''(x)\rvert-\frac{\epsilon_{\mathrm{machine}}\lvert f(x)\rvert}{h^2}=0.

Solving for the minimizing step size gives

hopt≈2ϵmachine∣f(x)∣∣f′′(x)∣.h_{\mathrm{opt}} \approx \sqrt{\frac{2\epsilon_{\mathrm{machine}}\lvert f(x)\rvert}{\lvert f''(x)\rvert}}.

If the local scales of ∣f(x)∣\lvert f(x)\rvert and ∣f′′(x)∣\lvert f''(x)\rvert are comparable for a particular problem, then forward difference often lands near

hopt∝ϵmachine1/2.h_{\mathrm{opt}} \propto \epsilon_{\mathrm{machine}}^{1/2}.

In double precision, that is roughly 10-8. This is order-of-magnitude guidance for well-scaled smooth problems, not a universal law for every function.

For central difference, the truncation term is smaller, so the model changes to

Etotal(h)≈h26∣f′′′(x)∣+ϵmachine∣f(x)∣h.E_{\mathrm{total}}(h)\approx \frac{h^2}{6}\lvert f'''(x)\rvert + \frac{\epsilon_{\mathrm{machine}}\lvert f(x)\rvert}{h}.

Now the minimizing step size is

hopt≈(3ϵmachine∣f(x)∣∣f′′′(x)∣)1/3.h_{\mathrm{opt}} \approx \left(\frac{3\epsilon_{\mathrm{machine}}\lvert f(x)\rvert}{\lvert f'''(x)\rvert}\right)^{1/3}.

So central difference typically prefers

hopt∝ϵmachine1/3,h_{\mathrm{opt}} \propto \epsilon_{\mathrm{machine}}^{1/3},

which is larger than the forward-difference optimum. Computationally, that is excellent news: central difference is both more accurate in truncation error and less sensitive to having an extremely tiny step.

For a fourth-order central derivative, the same balancing logic leads to the scaling

hopt∝ϵmachine1/5.h_{\mathrm{opt}} \propto \epsilon_{\mathrm{machine}}^{1/5}.

That scaling will appear again in the executable code below, but again as heuristic guidance rather than a guaranteed best choice for every function and every scale.

Two error models show truncation, amplified rounding, their sum, and visible minima for first- and second-order methods.

Figure 3:Both minima are visible. The curves use the illustrative model E(h)=Ahp+Bϵ/hE(h)=Ah^p+B\epsilon/h with A=B=1A=B=1 and binary64 machine epsilon. Dashed curves show truncation; dotted curves show amplified rounding; solid curves show their sum. Differentiating this model gives h∗=(Bϵ/(pA))1/(p+1)h_*=(B\epsilon/(pA))^{1/(p+1)}. The minimum changes with the coefficients as well as the order. Actual function-evaluation errors can be irregular and can partly cancel, so these are explanatory curves, not fitted error guarantees. Compare them with the executable refinement experiment below.

Open full-size figure

For forward difference in double precision, it is common to get on the order of 8 correct digits in a well-scaled smooth problem. That is useful guidance, but it is not a universal accuracy ceiling for every derivative calculation.

The best hh is a balance between truncation and round-off, not the smallest possible step.

Before running any examples below, we need one shared setup cell. It defines the imports and helper functions used throughout the rest of the reading, so if you restart the kernel this is the first cell to rerun.


Interactive Exploration

Why this matters: the best way to internalize the error trade-off is to vary hh yourself and watch different methods succeed or fail.

In COMP 521, we do this exploration directly in executable Python rather than through a separate browser demo. The goal is the same: choose a function, a point xx, a method, and a log-scaled step size hh, then compare what your prediction says to what the calculation actually does.

This cell reuses the shared helper functions defined earlier. It computes the absolute derivative error for three methods, and you should expect a right-hand truncation regime, a left-hand round-off upturn, and lower curves for higher-order methods while the smooth-function assumptions hold.

<Figure size 800x500 with 1 Axes>

What to notice: for large hh, the right side of each curve is truncation-dominated, and the slopes reflect method order. As hh becomes extremely small, each curve turns upward because round-off takes over. The minimum of each curve is the computational version of the U-shaped total-error story.

Interpretation: the right side of the plot is the truncation regime, where method order controls the slope. The left-side upturn is round-off error. The bottom of each curve is the experimentally visible version of the U-shaped total-error logic from the previous section.


Practical Algorithm for Choosing hh

Why this matters: in real code, you rarely know f′′(x)f''(x) or f′′′(x)f'''(x) ahead of time, so you need a practical scale-aware heuristic instead of the exact symbolic optimum.

The most important practical idea is that hh should scale with the magnitude of the problem. A step size that makes sense near x=1x=1 does not make sense automatically near x=1.496×1013 cmx=1.496\times 10^{13}\,\mathrm{cm}.

This section reuses the shared helper functions defined earlier. The point now is not to re-read the implementation, but to watch how a scale-aware heuristic behaves on concrete examples.

Worked Example 1: f(x)=x2f(x)=x^2 at x=3x=3

Why this matters: this is the cleanest first test because the exact derivative is simple and central difference on a quadratic exposes the power of symmetry immediately.

The exact derivative is

ddx(x2)=2x,\frac{d}{dx}(x^2)=2x,

so at x=3x=3,

f′(3)=6.f'(3)=6.

This gives us an exact reference value, so the only question is how each stencil misses it.

This cell reuses the shared helper functions defined earlier. It computes three derivative estimates at the same hh, and you should expect forward and backward to lean in opposite directions while central benefits from symmetry.

forward  approx =  6.100  abs error = 1.000e-01
backward approx =  5.900  abs error = 1.000e-01
central  approx =  6.000  abs error = 5.329e-15

Interpretation: forward and backward differences lean in opposite directions because they are one-sided. Central difference lands exactly on the true derivative here because the symmetry cancels the relevant truncation term for a quadratic.

Worked Example 2: f(x)=sin⁡xf(x)=\sin x at x=1 radx=1\,\mathrm{rad}

Why this matters: this example is smooth, familiar, and lets us see how the same method behaves across several choices of hh.

The exact derivative is

ddx(sin⁡x)=cos⁡x,\frac{d}{dx}(\sin x)=\cos x,

so at x=1 radx=1\,\mathrm{rad},

f′(1)=cos⁡(1)≈0.5403023059 rad−1.f'(1)=\cos(1)\approx 0.5403023059\,\mathrm{rad}^{-1}.

This gives us a smooth benchmark where shrinking hh helps at first and then eventually hurts.

This cell reuses the shared helper functions defined earlier. It checks one method across several step sizes, and the important pattern is the improvement-then-breakdown sequence rather than any single printed number.

Method = central
h =  1.0e-01  approx = 0.539402252170  abs error = 9.001e-04
h =  1.0e-03  approx = 0.540302215818  abs error = 9.005e-08
h =  1.0e-06  approx = 0.540302305896  abs error = 2.772e-11
h =  1.0e-10  approx = 0.540302247387  abs error = 5.848e-08

Interpretation: shrinking hh helps only until round-off error becomes important. That turning point is the numerical version of the paradox we started with.

Worked Example 3: Why hh Must Scale With the Problem

Why this matters: in astrophysics, the same code often sees variables that differ by many orders of magnitude. A single hard-coded hh is rarely defensible.

Consider these representative scales:

If xx is a radius or mass coordinate, the perturbation should reflect the size of that coordinate. A dimensionless h=10−6h=10^{-6} means very different things at those scales.

This cell reuses the shared helper functions defined earlier. It computes scale-aware step sizes for three representative coordinates, and you should expect the recommended perturbation to grow with the magnitude of the physical variable.

lab length (cm)               x = 1.000e+00  h_forward = 1.490e-08  h_central = 6.055e-06
orbital radius (1 AU in cm)   x = 1.496e+13  h_forward = 2.229e+05  h_central = 9.059e+07
enclosed mass (1 Msun in g)   x = 1.989e+33  h_forward = 2.964e+25  h_central = 1.204e+28

Interpretation: the algorithm is not claiming these are physically perfect step sizes for every application. It is enforcing a necessary first principle: a numerically meaningful perturbation should scale with the magnitude of the quantity being perturbed.


Bridge to Part 2

Why this matters: we have treated round-off error as a real force in the problem, but we have not yet unpacked where it comes from.

You now know the central paradox of numerical differentiation:

In Part 2, we will zoom in on the floating-point system itself. We will look at machine epsilon directly, see why decimal intuition fails in binary arithmetic, and study the mechanisms behind catastrophic cancellation and error propagation. That is the next layer of the same story, not a separate topic.

Next: Part 2 - Numbers Aren’t Real