Numerical Treatment of ODE
The population models built earlier each came with a closed-form solution: Malthusian growth gave a clean exponential, the logistic model an explicit S-curve, the saturation model an exponential approach to a limit. Being able to write the solution down as a formula is the comfortable case, and also the rare one. The overwhelming majority of ordinary differential equations have no closed-form solution at all — there is simply no finite combination of elementary functions that satisfies them. The moment a model grows past a textbook example, this is what happens, and the only way forward is to compute an approximate solution numerically, step by step. This page is about how that is done, and about the ways it can go wrong.
Initial value problems and boundary value problems
A differential equation on its own does not pin down a single solution — it describes a whole family of curves, one for each way of fixing the constants of integration. To single out the one solution we actually want, the equation has to be paired with side conditions. The population-dynamics models are exactly this: one or several ODEs together with enough extra conditions to make the solution unique. There are two standard ways to supply those conditions, and they split ODE problems into two families.
The first fixes the solution at the start of the time interval — we are told the state at the beginning and asked how the system develops from there.
An initial value problem (IVP) is an ODE together with the value of its solution at the start of the time interval. In the scalar case,
and for a system of coupled ODEs,
The condition is the initial value: the known state at the starting time , from which the solution is propagated forward.
This is the population-dynamics setting from before. The initial value plays exactly the role the starting population did — the headcount we measure at the outset and then watch evolve. So is not just a piece of notation; it is the concrete starting datum, the analog of , that turns the whole family of solution curves into the single one we care about.
The second family fixes the solution at both ends of the interval — we are told where the trajectory starts and where it must end, and asked to find the path between.
A boundary value problem (BVP) is an ODE together with values of its solution at both endpoints of the interval, rather than at the start alone — for instance at the left end and at the right.
The optimal trajectory of a space shuttle is the standard example: the craft leaves a known launch point and must arrive at a prescribed target, and the problem is to find the flight path joining the two. Most of what follows concerns initial value problems, which are the natural shape for population dynamics; boundary value problems are taken up later, once the machinery for IVPs is in place.
Reading the prototype
A few features of the prototype are worth drawing out, because the notation hides some choices.
The right-hand side is not the of the population models. There, named the per-capita growth rate — the factor multiplying the population in . Here is the entire right-hand side of the ODE: the whole expression for , the rate of change itself. Same letter, a different job.
The unknown may be a single scalar function of time or a vector of several functions stacked together. The system form above is the vector case written out component by component: populations evolving at once, where — as is typical in these models — each species’ rate of change depends on all the others. The coupled predator–prey and competition systems are of exactly this shape, first-order equations sharing one set of unknowns.
And every equation here is first-order: only the first derivative appears, never or anything higher. That is a genuine simplification, and it is not as restrictive as it looks. A higher-order equation — the damped oscillator’s , for instance — can be folded back into this first-order form by introducing the lower derivatives as extra unknowns, a reduction taken up later in this chapter. So the first-order IVP is not a special case; it is the standard form everything else is converted into.
One last case is worth flagging. If happens to depend only on and not on — that is, — then the ODE is no longer really a differential equation to be solved but a plain integration, , with nothing to do beyond evaluating an integral. The interesting case, and the one that forces the numerical machinery of this page, is the usual one: depends on the unknown itself, tying the rate of change at each instant to the current state, so the solution cannot be had by integrating a known function of alone.
A short excursus: discretization
Before any method can run, there is a gap to bridge. A model lives in the continuum — real-valued quantities, smooth functions, an unbroken interval of time — but a computer is a finite machine that can hold only finitely many numbers and perform only finitely many operations. Every numerical method therefore begins with the same move.
Discretization is the transition from the continuum to the discrete and finite: replacing objects that take uncountably many values — the real numbers, a continuous function, an interval of time — with finite, machine-representable stand-ins.
This happens at several levels, and it is worth seeing each one, because the approximations they introduce are the ultimate source of the errors the rest of this page has to control.
Representing numbers
The first thing to discretize is the real number line itself. A machine cannot store an arbitrary real number — between any two reals lie uncountably many others, and only finitely many fit in memory. There are three standard schemes, differing in how they trade off range (how large and small the representable numbers go) against resolution (how finely spaced they are):
- Integer arithmetic keeps only whole numbers, so the spacing is always exactly one. Nothing between two integers can be stored: a value like has no slot, and a division such as silently drops its remainder. For continuous quantities that is hopelessly coarse.
- Fixed-point arithmetic narrows the spacing to let fractions in. It pins the radix point at a fixed position and keeps a fixed number of digits after it, so the machine really stores an integer such as but reads it as (the point is just understood to sit two places in). Now fractions fit — but the spacing it buys is uniform across the whole range: choose a step of and every representable number sits from its neighbor, near zero and near a million alike. That is the wrong place to spend precision. Out among large values the fixed step is far finer than anyone needs, while near zero that same step is too coarse to resolve anything smaller than itself. What you actually want is fine steps for small numbers and coarse steps for large ones, and a single absolute spacing can never be both.
- Floating-point arithmetic fixes that imbalance by letting the radix point “float” to wherever the digits are needed, so both the range and the resolution vary with the number’s size. The spacing now scales with magnitude — tight near zero, wide out among large values — but the relative precision stays the same everywhere: the same handful of significant digits whether the quantity is tiny or huge. This is what makes it possible to hold both very large and very small numbers sensibly, and it is what essentially all scientific computation uses.
The floating-point idea has a precise definition.
The floating-point numbers in base with mantissa digits form the set
The integer is the mantissa, carrying the significant digits; the integer is the exponent, which scales them; and is the base. The bound forces a nonzero mantissa to have exactly digits — no leading zeros — so every number has one normalized representation.
A real machine cannot store arbitrarily large or small exponents, so it keeps only the machine numbers, the floating-point numbers whose exponent lies in a fixed range :
Because the exponent is bounded, this set is finite and has a smallest and a largest element. The smallest positive machine number is the smallest mantissa at the smallest exponent, , and the largest machine number is the largest mantissa at the largest exponent, . A value beyond either bound cannot be stored: it underflows to zero if it is too small, or overflows if it is too large.
Take and , so the mantissa always carries three decimal digits ( when nonzero) and the exponent slides the decimal point. Then , , and are all representable, each with the same three significant digits. With the exponent bounded by, say, , the smallest positive machine number is then and the largest is . Outside that window a value cannot be stored at all — it underflows to zero or overflows.
Resolution — accuracy is relative
The single most important property of a floating-point system is how finely it resolves numbers, and the key fact is that it does so relatively, not absolutely.
The resolution of a floating-point system is the maximal relative distance between neighboring representable numbers,
Here is where it comes from. Take two neighboring machine numbers with the same exponent . Their mantissas differ by one, so the numbers themselves are and , and subtracting leaves an absolute gap of just between them. To turn that into a relative gap, divide it by the value itself, . This fraction is largest where the value is smallest, and the smallest a normalized mantissa is allowed to be is (the lower bound built into the definition). Putting that worst case in, the cancels top and bottom:
So the relative gap never exceeds . The absolute spacing itself grows as the numbers grow, so neighbors far out on the line are spaced far apart while neighbors near zero are packed tightly together, but the relative spacing stays capped at everywhere. This is exactly the behavior one wants: precision is proportional to magnitude, the same handful of significant digits whether the quantity is tiny or huge.
With and , the resolution is , one part in a hundred. Near , consecutive machine numbers sit an absolute apart. Near they are , an absolute gap of , a thousand times wider. Yet the relative gap is in both places: three significant digits, wherever you look on the line.
Beyond numbers
Discretization does not stop at the numbers. The same move — replace an infinite or continuous object with a finite one — is applied to functions and to the operations of calculus:
- An infinite series is cut off after finitely many terms, turning it into a polynomial. The sine, for example, is computed in practice not from its defining infinite series but from a truncated polynomial that agrees with it closely on the range of interest.
- A continuous interval of time is replaced by a finite grid of discrete points , and the solution is sought only at those points rather than at every instant.
- A derivative — defined as a limit, an inherently continuous notion — is replaced by a difference quotient taken over a small but finite step.
The difference quotient approximates the derivative of at by the slope of a chord over a small finite step , instead of the limiting slope of the tangent:
The derivative is the limit of this ratio as ; keeping small but positive is what makes it computable. This last substitution is the seed of the whole numerical treatment of ODEs — it turns from a statement about instantaneous rates into a rule that steps the solution forward one finite at a time. But every one of these discretizations — rounded numbers, truncated series, finite steps in place of limits — buys that computability at the price of some error. Keeping those errors identified and under control is what the next two sections are about, and what the rest of the page ultimately depends on.
Rounding and round-off error
A numerical algorithm picks up error from several sources. The most basic one is built into floating-point arithmetic itself: a real number that is not a machine number cannot be stored exactly and must be replaced by one that can.
Every real that is not itself a machine number falls strictly between two that are — its nearest representable neighbors below and above,
If happens to be a machine number, both neighbors coincide with itself; otherwise sits between and , and storing it means choosing one of the two. That choice is made by a rounding map.
Rounding is a map that replaces each real number with a machine number. It has three defining properties:
- surjective (every target value is hit) — each machine number is the rounding of some real, if only of itself, so no representable value is left unreachable;
- idempotent (applying it twice changes nothing the second time) — a number that is already a machine number is left alone, for every , so ;
- monotonic (order-preserving) — if then , so rounding never flips the order of two numbers.
Which of the two neighbors actually returns is fixed by the rounding mode:
- rounding up always takes the upper neighbor, , i.e. it rounds toward ;
- rounding down always takes the lower neighbor, , i.e. it rounds toward ;
- correct rounding (round to nearest) takes whichever neighbor is closer, with a fixed tie-breaking rule for the exact midpoint between them;
- truncating (round toward zero) simply cuts the number off, keeping the leading digits and throwing away the rest. Since dropping digits only ever shrinks the magnitude, this lands on the neighbor nearer to zero. That matches rounding down for positive values, but for negative ones it rounds the opposite way: truncates to , whereas rounding down would give .
Whatever the mode, the price of storing is the gap between it and the machine number chosen for it.
The round-off error is the discrepancy introduced when a real number is replaced by its machine representation. Measured relative to , it is bounded by the resolution: at most for the directed modes (up, down, truncation), and at most for correct rounding to the nearest — which, by always taking the closer neighbor, can never be off by more than half the spacing to a neighbor.
Arithmetic on machine numbers
Rounding is not a one-time cost paid only on input. Even when both operands are machine numbers, the result of an arithmetic operation usually is not — multiply two three-digit numbers and the exact product can need six digits — so it has to be rounded back into as well. The idealized model of this is clean:
Under ideal arithmetic, each elementary operation is carried out as if in exact arithmetic and only its result is rounded to a machine number:
The tilde marks the machine operation as distinct from the exact one it approximates.
This is the behavior the IEEE floating-point standard prescribes — though, as a technological matter, not every computer implements it faithfully. For error analysis it is handier to weaken the exact equality into a bound: every machine operation returns the true result perturbed by a small relative amount,
The perturbation depends on the operands, but its size is always controlled. The here is big-O notation, read “on the order of ”: it means the bound is at most some fixed constant times the resolution , so it stays proportional to and shrinks right along with it as the precision improves. A single rounding, then, is utterly harmless. The real question is what happens when millions of them compound over a long computation: do the individual errors stay independent and roughly cancel, or do they reinforce and grow? Estimating that accumulated influence is the job of round-off error analysis, and the standard worked example is Horner’s method for evaluating a polynomial — the classic case for tracing how round-off builds up across a long chain of multiply–add steps.
Further sources of errors
Round-off is the most basic source of error, but it is not the only one, and on modern hardware it is rarely the worst. Double-precision arithmetic carries so many significant digits that the resolution is minuscule, so the errors that actually dominate a real computation usually come not from the number format but from the deliberate approximations a method makes. Three of these are worth naming.
The discretization error is the error from solving a problem on a discrete set of points instead of on the underlying continuum — sampling a continuous function at grid points, or stepping an ODE forward in finite jumps rather than continuously.
This is the direct cost of the discretization that every method on this page relies on, and it is the one these methods spend most of their effort controlling. Once a concrete method is in hand, the discretization error splits into a local part (made in a single step) and a global part (accumulated across all steps), and the central questions become how fast each shrinks as the step size goes to zero.
The truncation error is the error from stopping an iterative process after finitely many steps, instead of running it to its (often infinite) completion.
This takes a few common shapes. A series computed term by term has to be cut off after terms, leaving out the infinite tail — the same series-to-polynomial truncation seen earlier, now viewed as a source of error. Root-finding by Newton’s method likewise produces only a sequence of ever-better approximations to a true root; the iteration has to be stopped somewhere, either after a fixed number of steps or once the change from one step to the next becomes insignificant, and whatever distance remains to the exact root is truncation error.
The data error is the error already present in the input: the data fed to a computation are often measurements, and measurements are inexact.
Data error is different in kind from the other two — it has nothing to do with the algorithm or the machine, but is baked into the problem before any computation starts. It cannot be reduced by a better method or finer precision, only carried along, and how much it grows or shrinks as it passes through a computation turns out to be a property of the problem itself, taken up later on this page.
Round-off, discretization, truncation, data — each is a separate way the computed answer can drift from the true one, and a sound numerical method has to keep an eye on all of them at once.
One-step methods
With the machinery in place, we can build the first actual solvers. They all share one shape: start from the known initial value and march forward, producing the solution at one grid point after another. The simplest family computes each new point using only the single point just before it.
A one-step method advances the solution of an initial value problem one grid point at a time, computing the next value from the current value alone — no earlier points enter the step. Each step has the form
where is the step size and the increment function is the method’s estimate of the average rate of change across the step.
The whole design problem is bottled up in : every one-step method on this page — Euler, Heun, Runge–Kutta — keeps the skeleton new value = old value + step size estimated growth and differs only in how it estimates that growth. Keep that template in mind; it is the single thread running through everything below. (Methods that do reuse older points — the multistep methods — come later in this chapter.)
Two symbols that look alike: versus
One notational point underlies everything that follows. The function , with its time argument in parentheses, is always the exact solution — the true trajectory the ODE and initial value pin down uniquely. We never actually have it, except at the starting point ; in the interesting cases there is no formula to evaluate it with. The subscripted , with an index and no parentheses, is always the computed approximation at the grid point , and — close, but in general not equal.
Each approximation is built on the previous one. Only the first value is exact, ; every step after that feeds the method its own previous output, so is built from the approximation , not from the true . That is how error compounds. The exact never enters the computation — it appears only in the analysis, as the yardstick the computed is judged against.
The Euler method
The starting point is the difference quotient from the discretization excursus — replacing a derivative by a slope over a small finite step is the finite-differences approximation. It says the derivative over that step is approximately the slope of the chord,
The prototype IVP says that this same derivative equals . Setting the two equal and solving for the value one step ahead turns a statement about instantaneous rates into a recipe for moving forward:
Read it in the running template: the population a short time from now equals the population now, , plus the time elapsed times the growth rate estimated at the current instant. Here is the start of the time interval and the known initial value — the headcount we measure at the outset. We do not know the true rate over the whole step, so we use the only rate we have: the one at the point we are standing on.
Nothing forces us to stop after one step. Having landed on an estimate at , we treat it as the new “current” point and repeat, and repeat again. That iteration is the Euler method.
The Euler method (also called the explicit or forward Euler method) solves the IVP , by stepping
starting from . Each step follows the slope of the solution at the current point for one step of length . It is the one-step method whose increment function is simply .
This is the move from continuum to discrete made concrete: one continuous equation, valid at every instant, becomes a sequence of discrete equations, one per grid point. The grid covers a finite range , the spacing between neighboring points is the step size , and the method hands back the solution only at — never in between.
That the Euler method runs — that the recurrence mechanically produces a value at every grid point — is clear. Whether what it produces is any good is not, and three questions decide it. They organize the rest of this section.
- Does it converge? As the step size shrinks, , do the computed points close in on the true solution of the ODE? A method that refuses to improve no matter how fine the grid is worthless; this is the bare minimum we demand, and the next section makes it precise as consistency and convergence.
- How fast does it converge? Suppose it does converge. Halving the step size doubles the work — does it buy enough accuracy to be worth it? If halving only halves the error, progress is painfully slow; if it cuts the error to a quarter or a sixteenth, refinement pays off fast. This is the method’s order, and it is the single number that separates Euler from Heun from Runge–Kutta.
- Is there a largest safe step? Going finer is accurate but expensive; going coarser is cheap but risky. Is there a sharp threshold — a maximal below which the method behaves and above which it falls apart? The tension is real: forecasting two seconds ahead in one step is fine, leaping two months ahead in one step is meaningless, and somewhere between lies a limit. Pinning that limit down is the subject of stability and stiffness, later on this page.
The first two questions are answered next. The third has to wait — it turns out to depend on the method and the equation together, in ways that take real work to untangle.
Discretization error: local, global, and what “convergence” means
There is a second route to the Euler formula that comes not from the difference quotient but from calculus, and it has the advantage of exposing the error directly. Take the exact solution and expand it one step ahead with a Taylor series:
The remainder collects every higher-order term — the ones carrying and beyond. Over a short step those terms are small, so we drop them; and we replace with , since the ODE says the rate equals and is the value we actually have at that step. What is left is exactly the Euler step. The same method, reached two ways: the difference quotient is the numerical route, the truncated Taylor series the analytic one. The Taylor route makes plain what we threw away — the remainder — and that discarded remainder is the error. Measuring it is the whole game.
That error comes in two flavors, and telling them apart is the key conceptual step.
The local discretization error measures the error made in a single step, under the assumption that the step starts from a point exactly on the true solution. Feeding the exact solution into one step of the scheme and comparing the resulting difference quotient with the true rate ,
The maximum runs over the whole interval , so is the worst single-step defect anywhere on it. Crucially, here is the exact solution, not the computed approximation — the local error asks how well one clean step would do, with no inherited error from before.
Reading the formula: the fraction is the scheme’s difference quotient — the slope Euler would use if it sat exactly on the true curve at time — and is the rate the ODE actually prescribes there. Their difference is how far the finite-step slope deviates from the true derivative, sampled on the exact solution. The maximum over then takes the largest such deviation anywhere on the interval, so is a single worst-case figure for the whole run.
The global discretization error measures the actual gap between the computed solution and the exact one, accumulated across all steps from the start:
Unlike the local error, this carries no “assume we start on the true curve” caveat — is the approximation our method actually produced, inheriting every error made on every step before it, and is the true solution at the same time.
The distinction is the difference between the error this one step introduces (local, measured as if the past were perfect) and the error you are actually stuck with (global, the real distance from truth at ). One would expect the global error to be vastly larger than the local one — after all, it is a running total of many local mistakes, so naively it should pile up step after step without bound. It does not, and the reason is the whole reason numerical methods are usable at all: the per-step errors do not march in lockstep. Some push the estimate above the true curve, some below; they partly cancel rather than purely accumulate. If they really did add up relentlessly, the global error would explode and no amount of computing would give a trustworthy answer. (Exactly when this benign cancellation fails — when errors reinforce instead — is the stability question flagged above.)
Both definitions need the exact solution , which in general we do not have. So to actually measure the error, we supply a stand-in for : either rerun the same problem on a much finer grid and treat that high-resolution result as the “truth,” or test the method on one of the rare problems whose exact solution is known in closed form (the population models from earlier are exactly such cases). Comparing the computed against that reference is how and get evaluated in practice.
Now the two minimum demands on a method can be stated cleanly.
A method is consistent if its local discretization error vanishes as the step size shrinks,
This is the necessary minimum: in the limit of infinitely fine steps, a single step makes asymptotically no error. A method that fails even this is approximating the wrong equation.
Consistency is the weak condition — it only controls one step at a time, and says nothing about what happens once many steps are chained together. It guarantees that each individual step, taken in isolation, can be made as accurate as we like by shrinking . But many small errors can still combine into a large one, so “every step is nearly right” does not by itself force “the final answer is nearly right.” For that we need the accumulated error to vanish — the stronger property, convergence.
A method is convergent if its global discretization error vanishes as the step size shrinks,
This is the property that actually matters: refine the grid and the computed solution closes in on the true one everywhere on , accumulated error and all. Convergence is strictly stronger than consistency — and, as a warning sounded later, consistency alone does not imply it.
Both properties say the error eventually disappears, but neither says how fast. That rate is the practically decisive quantity, and it has a name.
The order of a method is the power controlling how fast its discretization errors shrink with the step size:
A higher order means faster convergence. Concretely, halving the step size shrinks the error by a factor of : order turns a halved step into a halved error, order into a quarter, order into a sixteenth. This is the precise answer to “how much does halving the step buy?” — and the number that ranks one method against another.
The here is ordinary big-O notation — the same one met earlier for round-off, read “on the order of.” Writing just says the error stays below some fixed constant times once is small. The two senses of order then line up exactly: the order of a method is the exponent sitting inside that big-O bound, so it is the same notion as big-O’s “order of magnitude,” not a clashing second use of the word.
Comparing the two errors, step by step
A picture makes the local-versus-global distinction concrete. Plot time along the horizontal axis at the grid points and the solution value along the vertical. The red curve is the true solution of the original IVP, the one passing through the initial value . The Euler points are obtained by the calculation rule, each one a tangent-line step: from the current point, follow the local slope straight for one step of width .
The other colored curves are the subtle part, and the source of the “where did those come from?” confusion. Each one is the exact solution of the same ODE, but launched from a computed point rather than from . The green curve is the true trajectory that would unfold if the system were restarted exactly at ; the blue one is the true trajectory restarted at ; the black one restarted at . The label "" means precisely “the solution curve satisfying .” They are not extra numerical outputs — they are the exact-solution family, one member through each point the method actually produced.
With that, the two errors are read straight off the figure:
- Local discretization error (the short bars): at each step, the vertical gap between the Euler point and the exact curve that passes through the previous point . It is “local” because it measures one Euler step against the true trajectory launched from where that step began — exactly the “assume the past was perfect” definition above.
- Global discretization error (the tall bars): the vertical gap between the Euler point and the red true solution. It is the error you are really carrying — the full distance from the original trajectory, every inherited mistake included.
A last caution about the figure. Drawn this way, the tall global-error bars seem to grow without limit, step after step. That impression is an artifact of one particular example. In general the global error can grow, shrink, or oscillate as you march along — the partial cancellation of local errors discussed above means it need not balloon. If it genuinely grew without bound, numerical integration would be pointless; that it usually does not is what makes the whole enterprise work.
Order, and getting more of it: the Heun method
For the Euler method, as long as the second derivative and the partial derivative (how the rate responds to a change in the state ) stay bounded — never running off to infinity anywhere on — the analysis above pins down the order exactly: it is consistent of first order, , and convergent of first order, . In the language just built, means halving the step size only halves the error — honest, but slow. And the warning attached to the convergence definition bites here too: there exist methods that are perfectly consistent yet do not converge, so first-order consistency is reassuring but not the end of the story.
Slow convergence is the practical problem. To reach a target accuracy with Euler you may need a punishingly small step, and small steps mean many of them — high computational cost. The cure is a higher order: a method with reaches the same accuracy with far larger steps, because halving now quarters the error. So we want order, and the question is how to manufacture it.
One route is staring at us. The Taylor derivation of Euler dropped the remainder after the first-derivative term; keep the next term instead and you get a higher-order method directly. The trouble is that the next term carries , which by the chain rule unpacks into derivatives of itself — and the term after that into still more. The formulas grow ugly fast, and they demand that you supply derivatives of by hand. For a real model that is often impractical.
The alternative sidesteps derivatives entirely: instead of evaluating higher derivatives of at one point, evaluate itself at several points within the step and combine the results. Methods built this way are the Runge–Kutta methods, and the simplest one above Euler is the method of Heun.
The idea follows the running template — new value = old value + step size estimated growth — and improves only the growth estimate. Euler uses a single slope, , sampled at the start of the step. But the true rate changes across the step, and trusting the starting slope alone systematically lags. The natural fix is to average the slope at the start with the slope at the end of the step — an arithmetic mean of the two derivatives, which tracks the curve far better than either endpoint alone.
There is one obstruction: the slope at the end is , and is the very thing we are trying to compute — we do not know it yet. Heun’s resolution is to predict the endpoint with a cheap Euler step, then use that prediction to evaluate the ending slope:
The Heun method (also called the improved or explicit trapezoidal Euler method) averages the slope at the start of the step with the slope at a predicted endpoint:
The inner expression is an ordinary Euler step — a provisional guess at used only to estimate the ending slope. Averaging the two slopes makes the method consistent and convergent of second order, , which means halving the step size now cuts the error to a quarter rather than only to a half.
The payoff is concrete: where Euler’s error halves when you halve the step, Heun’s quarters. The cost is two evaluations of per step instead of one — a trade almost always worth making.
Runge–Kutta methods
Heun is the first rung of a ladder. Push the same idea further — sample at more points inside the step and take a cleverly weighted average — and you climb to higher and higher order. The whole family is the Runge–Kutta methods, and its most famous member, often meant when someone says simply “the Runge–Kutta method,” uses four slope samples.
The classical fourth-order Runge–Kutta method (RK4) advances one step by a weighted average of four slope samples:
with
It is consistent and convergent of fourth order, , which means each halving of the step cuts the error to a sixteenth.
The four samples read as a sequence of ever-better guesses at the slope across the step: is the slope at the start (plain Euler); is the slope at the midpoint, reached by stepping there with ; is the midpoint slope again, but reached using the improved ; and is the slope at the endpoint, reached using . The weighting leans on the two midpoint estimates, which carry the most information about the step’s average behavior. Fourth order is the headline: RK4 reaches accuracies with modest steps that Euler could only dream of — which is why it is the workhorse default for non-stiff problems (what makes a problem stiff is taken up later on this page, alongside stability). The price is four evaluations of per step, and the same template still holds: new value = old value + step size (weighted) estimated growth.
Euler, Heun, and Runge–Kutta are numerical integration rules in disguise. Integrating the ODE across one step turns it from a differential statement into an integral one,
so producing the next value is really a matter of approximating that integral — a problem called quadrature (numerical integration). Each method corresponds to a classical quadrature rule for the area under : Euler is the rectangle rule (one sample, the left endpoint), Heun is the trapezoidal rule (average of the two endpoints), and RK4 mirrors Simpson’s rule (endpoints plus a doubly-weighted midpoint). This is why some texts speak of integrating an ODE rather than solving it — the two phrasings name the same act, viewed through the difference quotient or through the integral.
Where the integral form comes from
Integrate both sides of over the step . The left side is the integral of a derivative, which by the fundamental theorem of calculus is just the net change ; the right side is . Rearranging gives the boxed identity. Every one-step method is then a choice of how to approximate that one integral from samples of — which is exactly what a quadrature rule is.
Multistep methods
The Runge–Kutta ladder buys order by sampling at more points inside each step — RK4 calls four times per step. That accounting hides where the real cost lives. The arithmetic that combines the samples is trivial; the expense is the evaluations of themselves. When is a tidy formula — a polynomial, a sine — an evaluation is nearly free and four of them cost nothing to worry about. But is the entire right-hand side of the model, and for a serious model it can be enormous: if a single evaluation of is itself a multi-hour supercomputer run (a weather forecast, say), then RK4’s four-evaluations-per-step is not the difference between 10 and 40 milliseconds but between six hours and a full day. At that scale the natural question is whether order can be bought without paying for extra evaluations of .
It can — by looking the other way in time. Runge–Kutta manufactures its extra slope samples by probing forward into the step, and every probe is a fresh evaluation. But the method has already evaluated at the previous grid points on earlier steps, and those numbers are just sitting there. Reusing that history instead of computing new samples buys higher order essentially for free.
Before writing one down, a shorthand the rest of this page leans on: write
for the slope the method computes at grid point . Once is known, is one evaluation of , and a method that reuses history is one that keeps the old values around rather than recomputing them.
A multistep method (also called an -step method) advances an initial value problem using not just the current point but several previous ones: is computed from and their already-evaluated slopes . This is the contrast to a one-step method, which uses alone. The explicit interpolatory family built this way is the Adams–Bashforth method.
The prominent representative is the second-order Adams–Bashforth method, which reaches one step into the past:
It still fits the running template — new value = old value + step size estimated growth — and differs only in the growth estimate: it extrapolates from the last two slopes and instead of probing new ones. The only fresh slope a step needs is — the other one, , is reused from the previous step — so a whole step costs one evaluation of , the same as Euler — yet the method is second order, the same as Heun, which costs two.
Where does the come from? The integral form from the remark above is the key. Producing means approximating , and the multistep idea is to replace the integrand by a polynomial that is cheap to integrate exactly.
Given already-computed grid points , , let be the unique polynomial of degree that passes through all of them — it interpolates the slope history. A multistep method then steps by integrating in place of the true integrand :
The polynomial is fixed by data we already have, and integrating a polynomial is exact and instant, so the only cost is the interpolation itself — no new evaluation of . The number of points sets the order:
- : is a constant through the single point , and integrating it recovers — the Euler method.
- : is the line through and , and integrating it over the next step gives exactly the rule above.
- general : order , at the fixed price of one evaluation of per step.
That is the payoff Runge–Kutta could not offer: more order without more evaluations.
Starting up: the first few steps
The cheapness comes with a debt at the very beginning. A -step method needs past points before it can take a step, but at the start of the integration only the initial value is on hand — there is no history yet to reuse.
The fix is to bootstrap. Run a one-step method (or a smaller multistep method) for the first few steps, just long enough to generate the missing and their slopes, and then switch to the full multistep method once enough history has accumulated. With a sufficiently accurate starter this preserves the method’s order: the startup phase is a handful of steps and does not spoil the asymptotics.
There is also a disadvantage shared by every method so far, explicit one-step and multistep alike: the step size often has to be kept very small — not for accuracy, but to stop the computation from going unstable. Push too large and the computed solution sprouts spurious oscillations that bear no resemblance to the true trajectory. Why this happens, and why it is a property of the method rather than the problem, is the subject of the stability discussion later on this page; for now the consequence is what matters. Small steps mean many steps, and many steps mean high computational cost. The remedy — methods that stay well-behaved at large step sizes — is implicit methods.
Implicit methods
Every method up to here shares a structural feature that is easy to overlook because it is so convenient: each computes from a formula whose right-hand side contains only things already known. Plug in (and any history) and read off directly.
A method is explicit if its step formula computes the new value directly from quantities already known — the current and past points and their slopes. The unknown appears only on the left-hand side, so a single evaluation of the formula produces it. Euler, Heun, RK4, and Adams–Bashforth are all explicit.
The alternative is to let appear on the right-hand side as well — to use the not-yet-known new slope in the very formula meant to produce .
A method is implicit if its step formula uses the new value on the right-hand side too, typically through the new slope . The formula no longer hands over directly; it states a (generally nonlinear) equation that must satisfy, which then has to be solved.
Applying this to the interpolation idea — interpolating through the previous points and the new grid point — gives the implicit multistep family.
The Adams–Moulton method is the implicit counterpart of Adams–Bashforth: it interpolates the slope through the previous grid points together with the new point , then integrates. Including the new point raises the order for the same number of stored points, at the cost of making implicit. Its members for the first few orders are
The first-order member is important enough to have its own name.
The implicit Euler method (also called the backward Euler method) is the implicit one-step scheme
It mirrors the explicit Euler method but evaluates the slope at the end of the step, , instead of the start. Because sits inside on the right, each step requires solving an equation for .
The second-order Adams–Moulton member, averaging the start and end slopes, is the implicit trapezoidal method — the same trapezoidal average the Heun method used, but with the exact end slope rather than a predicted one.
That “solving an equation” is the catch. Since is generally nonlinear, is the unknown of a nonlinear equation, and there are two ways to extract it:
- Brute force: solve the nonlinear equation directly each step, e.g. by a Newton iteration for the root . Accurate, but a full root-find per step is costly.
- Predictor–corrector: the easier and far more common route, taken up next.
The trade-off is the whole reason to go implicit. A single implicit step costs much more than an explicit one — you are solving an equation, not just “stepping further.” But, as the stability and stiffness sections will show, implicit methods stay well-behaved at far larger step sizes (sometimes a hundred times larger) with no loss of accuracy, so they need far fewer steps. Whether that is a net win depends on the problem: many cheap steps versus a few expensive ones. There is no universal rule, but for the hard cases coming up — stiff problems — implicit methods turn from merely attractive into necessary.
Predictor–corrector
The cheap way around the implicit equation is almost obvious once stated. If the obstruction is that we do not yet know to put into the right-hand side, then estimate it first with an explicit method and use that estimate wherever the true was needed. An implicit step becomes two explicit ones — approximating the approximation.
A predictor–corrector method evaluates an implicit scheme in two explicit stages:
- the predictor computes a preliminary value with a suitable explicit method;
- the corrector substitutes into the right-hand side of the implicit rule — wherever the unknown was needed — and evaluates it to get the final .
Both stages are explicit, so the whole step is computed directly; yet the result inherits the character of the underlying implicit method.
This is not a new trick — it is exactly what the Heun method already did: its predictor is a plain Euler step and its corrector is the implicit trapezoidal rule evaluated at that prediction,
Seen this way, Heun is the predictor–corrector pairing of explicit Euler with the second-order Adams–Moulton rule.
The accounting comes out well. A predictor–corrector step costs about twice an explicit step — one evaluation for the predictor, one for the corrector — instead of the open-ended cost of a full Newton solve, while keeping the large-step-size advantage of the implicit method it imitates. So the assessment of implicit methods, fairly stated: a single step is more expensive (solving an equation, or running two explicit stages, rather than just “going further”), but the number of steps is generally much smaller because larger step sizes are admissible, and the total cost can come out lower.
Higher-order equations and systems
Two loose ends remain before leaving the methods behind, and both reduce to one move: everything so far was written for a scalar first-order equation, and both the vector case and the higher-order case fold back into it.
Systems first, because they need almost nothing new. The population models with several interacting species are systems of first-order ODEs, and the entire machinery above — Euler, Heun, RK4, multistep, implicit — carries over verbatim. The recipe is identical; only the objects change. Wherever a scalar appeared, read a vector ; wherever the scalar slope appeared, read the vector-valued right-hand side. The step formulas stay the same symbol for symbol, and everything provable for one ODE holds for a system by reading the scalars as vectors.
Higher-order equations take one extra step. The population models only ever involved the first derivative, but mechanics routinely produces the second — acceleration, hence force — as in the damped oscillator derived among the population models. The prototype on this page is first-order by design, and the first-order paragraph earlier promised that higher-order equations fold back into it. Here is how.
An ODE of order is reduced to a system of first-order ODEs by naming the lower derivatives as auxiliary variables:
An -th order equation then becomes the first-order system
The first equations are just the definitions of the auxiliary variables (); only the last carries the original dynamics.
The reduction trades order for size: an -th order scalar equation becomes a first-order system of equations. Nothing is lost and no new solver is needed — the order is gone, absorbed into a slightly larger system, which the methods above already handle. This is why the first-order IVP is not a narrow special case but the standard form every ODE is converted into.
What makes an ODE hard to solve
Convergence and order describe a method working as intended: refine the grid and the answer improves, at a predictable rate. But several things can still derail a real computation, and they are worth separating because they have different owners. Some trouble belongs to the problem — baked in before any method is chosen — and some belongs to the method. The rest of this page works through three such phenomena: ill-conditioning, instability, and stiffness. Keeping straight which is a property of the problem and which of the method is the whole point, and a summary table at the end lays them side by side.
Ill-conditioning
The first phenomenon has nothing to do with the algorithm at all. It is a property of the problem.
The condition of a problem measures the sensitivity of its solution to changes in the input data — how far the output can move when the input is perturbed slightly. It is a property of the problem itself, not of any algorithm used to solve it. A problem is well-conditioned if small input changes cause only small output changes, and ill-conditioned if a tiny blur in the input can produce a totally different result.
Ill-conditioning is the close quantitative cousin of an ill-posed problem: an ill-posed problem fails outright to depend continuously on its data, while an ill-conditioned one depends on them continuously but so steeply that, in finite precision, it behaves almost as badly. Such problems are very hard to treat numerically, because exact input is almost never available — and an example makes the danger concrete.
Consider the second-order ODE
with the two initial conditions a second-order equation needs,
Its exact solution is the gentle decay — substitute and check: , , so , with and as required. Many different ODEs share this same plain exponential decay as their solution; this is one engineered to.
Now blur the input by the tiniest amount. Suppose the first initial condition is off by an infinitesimal — say , a perturbation so small the problem is, for every practical purpose, unchanged:
Solving again gives
At first glance this looks reassuringly close to the original. The first term is , and the second carries the microscopic coefficient . Surely negligible.
It is not. The second term hides a positive exponential, , and in the long run that changes everything. No matter how minuscule its coefficient, an exponentially growing factor eventually overwhelms an exponentially decaying one: there is always a time beyond which dwarfs the term, however small is (and the larger is, the faster that runaway term grows). So the two solutions do not merely differ slightly — they part ways completely:
The true solution decays to zero; the infinitesimally perturbed one blows up to infinity.
This is ill-conditioning in its purest form, and it is exactly why numerical methods have to worry. The exact input is rarely available — initial data come from measurements (the data error), and intermediate results pick up round-off along the way — so some perturbation is unavoidable. For a well-conditioned problem that is harmless; for an ill-conditioned one it is fatal, and no choice of method or precision can rescue it, because the trouble lives in the problem, not the algorithm. It is also why careful people working from slightly different data can reach completely opposite conclusions — and why ill-conditioning is such a convenient excuse: when nothing can be done, nothing is anyone’s fault.
Stability
Ill-conditioning lets the problem off the hook for the method. The next phenomenon is the reverse: a well-conditioned problem, no excuses available, that a method still gets badly wrong. This is where the gap left open earlier finally gets filled.
Recall the warning attached to convergence: a method can be consistent — each isolated step accurate in the limit — without being convergent, because consistency says nothing about whether inherited errors stay under control as steps are chained. The property that controls them, and so bridges consistency and convergence, is stability. The sharpest way to see why it is needed is a method that is consistent and yet not convergent.
To pin the blame on the method, take a problem that is impeccably well-conditioned:
whose exact solution
starts at and decays smoothly to the limit as , the term dying away. The problem is well-conditioned: perturbing the start to shifts the solution by only , an error that itself shrinks with time. Small input error, small and shrinking output error — the good case.
Now solve it with the midpoint rule.
The midpoint rule is the explicit two-step method
obtained by approximating the derivative at with a symmetric difference quotient over the double step, , centered on rather than reaching forward from it. Spanning two steps, it needs two starting values, and .
Substituting turns it into the explicit recurrence
started from and the exact second value . Mechanically it runs without complaint. But watch what it produces deep into the integration:
| step size | computed values |
|---|---|
The true solution sits placidly at . The computed one swings between large negative and large positive values, growing in amplitude — and, crucially, refining the step size does not cure it. Shrinking from to only postpones the blow-up; the oscillation still takes over and the values still explode. At every step size, eventually, it goes wrong.
The picture makes the failure unmistakable:
The exact solution is the flat curve resting at . The midpoint approximations start out tracking it, then each peels away into growing oscillations — the larger the step size, the sooner the departure. Even the finest step () only holds the line longer before a swelling oscillation envelope takes over. A method for which this kind of blow-up simply cannot happen is called stable; one for which it can is unstable. And the lesson of the figure is that instability is not a flaw in the model or the data — the problem here is flawless — but purely a matter of having chosen the wrong algorithm.
A numerical method is stable if errors already present — round-off, inherited discretization error — stay bounded as the computation proceeds, rather than being amplified from step to step. Instability is the failure of this: small errors get magnified each step until the computed solution is overrun by strong, growing oscillations whose shape bears no resemblance to the true trajectory. Such a result is not acceptable — it cannot even be read as the exact solution of a slightly perturbed problem. Stability is a property of the method (together with its step size), not of the problem.
The midpoint rule is the cautionary case laid bare. It is consistent — its symmetric difference quotient genuinely approximates the first derivative as — yet it is not convergent, as the blow-up showed, and on an interval unbounded to the right the failure persists no matter how small is. Consistency without stability is not enough.
What is enough is the two together. This is the relation that closes the gap consistency left open:
Consistency + Stability = Convergence. Neither half suffices alone. Consistency makes each isolated step accurate; stability keeps inherited errors from being amplified; only together do they force the accumulated error to vanish — that is, convergence — and at that with the order preserved (a consistent, stable method of order is convergent of order ). The midpoint rule fails precisely because it has the first property without the second.
Stability usually comes at a price — frequently a condition that the step size be small enough, sometimes very small (this is the source of the small-step requirement flagged back at the multistep methods). Which methods are stable is partly settled wholesale:
- all explicit one-step methods (Euler, Heun, RK4) are stable;
- the midpoint rule is not;
- the Adams–Bashforth and Adams–Moulton multistep families are stable as -step methods for .
Stiffness
The third phenomenon is the subtlest, because it strikes a method that has every good property and still fails. Consider another well-conditioned problem:
with exact solution
This solution is almost boring. The term collapses to nothing almost instantly — by it is already about — so the curve drops from to in a razor-thin initial layer and then sits flat at for the entire rest of the domain. Practically a horizontal line.
Apply the explicit Euler method:
The behavior is governed entirely by the factor raised to the -th power. If the term decays and as it should (at exactly, and the term oscillates forever without decaying); but — which happens as soon as — makes grow in magnitude and flip sign each step, so the computed solution oscillates and diverges, instead of resting at the flat line .
Here is the unsettling part. Explicit Euler is consistent; it is stable, like every explicit one-step method; and consistency plus stability give convergence. It has the full set of guarantees — and it diverges anyway.
A problem is stiff if an unimportant component of its solution — typically a fast transient that quickly dies away — forces a numerical method to use a ridiculously small step size across the entire domain, making the computation absurdly expensive even though the solution is almost everywhere trivial. Stiffness is a property of the problem (rooted in its solution carrying widely separated time scales), not of the method.
That is exactly what happens here: the negligible, short-lived term — utterly insignificant after the first sliver of the interval — dictates a step size over the whole domain, just to keep the method from exploding. To reproduce what is essentially the constant , the method is forced into thousands of tiny steps. Enormous effort, trivial answer.
The resolution of the paradox is that consistency, stability, and convergence are asymptotic properties: they all carry the silent qualifier “for sufficiently small .” Convergence is a statement in big-O form — like a complexity bound, it describes the limit and promises nothing for a finite above the threshold. None of the guarantees is violated by the blow-up; the computation has simply not yet entered the asymptotic regime where they take effect, and for this problem the entry ticket — — is punishingly small. This is the case for all explicit methods, which makes them unsuitable for stiff ODEs.
The remedy is implicit methods. Apply the implicit Euler method to the same problem, evaluating the slope at the new point:
Now the controlling factor is , which lies strictly between and for every positive . The term always decays, the solution always settles to — no oscillations, convergent at any step size. The tiny-step tyranny is gone, and one can take large steps to trace the flat line cheaply.
The reason is structural. An explicit method builds its approximation out of polynomials in — and a polynomial (other than a constant) always runs off to as its argument grows, so it cannot mimic a bounded, decaying solution once the step is large. An implicit method instead produces rational functions, and a rational function like stays bounded — it tends to as rather than blowing up — so it can track confined behavior at large step sizes. That is the deeper reason large steps work for implicit methods and fail for explicit ones. Ergo: for stiff ODEs, always use implicit methods.
The three phenomena at a glance
Three separate things, then, can make the numerical solution of an ODE hard, and the practical first question for each is always the same: whose fault is it — the problem’s or the method’s?
- Bad conditioning is a threatening property of the underlying problem, with nothing to do with the method at all. In the extreme it leaves very few numerical options, because no algorithm can undo a sensitivity baked into the problem.
- Instability is a threatening property of the method — it can, for instance, force tiny steps or blow up outright. Here implicit methods are often superior to explicit ones.
- Stiffness is a threatening property of the problem, but a tractable one: implicit methods handle it, and in fact for a stiff problem they are not just preferable but absolutely necessary.
The same split organizes the method properties met along the way. The table below gathers everything, sorted by what it is a property of — because that is what tells you whether a better algorithm can fix it (method properties) or whether you are stuck coping with it (problem properties).
| Concept | Property of | What it captures | Can the algorithm fix it? |
|---|---|---|---|
| consistency | the method | each single step’s error vanishes as | yes — pick a consistent method |
| order | the method | the rate at which the error shrinks | yes — pick a higher-order method |
| stability | the method (+ step size) | errors stay bounded instead of being amplified step to step | yes — pick a stable method (or shrink ) |
| convergence | the method | the global error vanishes as — and equals consistency + stability | yes — it follows from the two above |
| conditioning | the problem | sensitivity of the solution to perturbations of the input | no — baked into the problem; cope, don’t cure |
| stiffness | the problem | a fast, unimportant solution component forcing tiny steps | partly — implicit methods cope with it cheaply |
The one relation worth carrying away from all of this binds the method properties together: consistency + stability = convergence. Consistency alone (the midpoint rule had it) is not enough; stability is the second ingredient that turns locally-accurate steps into a globally-correct answer.
Boundary value problems
Everything so far has been about initial value problems — the natural shape for population dynamics, where the state is known at the start and propagated forward. The boundary value problem (BVP) set aside at the very beginning is a different animal, and it needs a different machine.
The defining contrast is informational. An IVP hands you everything at one end and lets you march: from the state at you read off the slope and step forward, point by point. A BVP fixes the solution at both ends and asks for the path between, so there is nothing to march from — you cannot step left to right when the constraint that pins the trajectory down lives at the far end you have not reached yet. The fix is to stop marching and instead discretize the whole interval at once, turning the differential equation into a system of equations solved simultaneously.
A useful rule of thumb sets the stage: an ODE needs as many side conditions as its order to have a unique solution. A BVP supplies two conditions (one at each end), so it generically pairs with a second-order equation. The general second-order BVP is
Rather than the general , take the linear special case — linear because, although it has products like , the unknown and its derivatives appear only to the first power and never multiplied together:
The simplest sub-case, with , is the one to build the method on; under exactly those conditions the BVP is guaranteed a unique solution.
Discretizing the second derivative
Lay a grid over the interval. With subintervals the step size is , and the grid points are
The first derivative already had a difference quotient; the second derivative needs its own.
The second difference quotient approximates the second derivative of at from three equally spaced samples a step apart:
It is symmetric about , using the point itself and one neighbor on each side.
Where the three-point formula comes from
A second derivative is the derivative of the first derivative, so apply a difference quotient twice. A forward step gives the slope just after , and a backward step the slope just before it:
The second derivative is the rate of change of the slope, so take the difference of these two and divide by again:
Both neighbors and enter because the formula is built from one slope reaching forward and one reaching back — the second derivative measures how those two slopes differ.
For the special case , the linear ODE reads . Writing the second difference quotient at each interior grid point and abbreviating , turns the single ODE into a discrete equation at every interior point:
The index runs only over the interior points : the two endpoints and are already known — that is what “boundary value” means — so they need no equation. That leaves equations for exactly the unknown interior values : a square linear system. Each equation couples a point only to its immediate neighbors, so the system is tridiagonal, and whether it can be solved comes down to the properties of its matrix.
The tridiagonal system
Multiplying each interior equation through by clears the denominators and produces clean integer-like coefficients. The difference part loses its (becoming ) while the term picks one up (becoming ):
For the first interior point () the term is a known number, so it moves to the right; likewise at . That is why the first and last right-hand sides carry an extra boundary term. The whole system is
Every row has just three nonzero entries (two at the ends) — the diagonal and its two neighbors — the signature of a tridiagonal matrix.
The condition now pays off. It makes every diagonal entry strictly larger than , while the off-diagonal magnitudes in each row sum to at most . The diagonal therefore dominates its row.
A square matrix is strictly diagonally dominant if in every row the diagonal entry outweighs all the off-diagonal entries combined in magnitude:
A strictly diagonally dominant matrix is always invertible, so the linear system has a unique solution for every right-hand side.
So the matrix here is strictly diagonally dominant, hence invertible — the discretized BVP can always be solved, for any data. Beyond that it is symmetric (the off-diagonals are all ) and positive definite, the well-behaved combination that makes the system cheap and stable to solve. The eigenvalues of the matrix are what ultimately govern how fast the discrete solution converges to the true one as the grid is refined — here at second order.
First derivatives: central differences and upwinding
Dropping the assumption lets the first derivative back into the equation, and it has to be discretized too. The natural choice is symmetric, straddling the point.
The central difference approximates the first derivative by a symmetric quotient straddling the point, accurate to second order:
This is the very same symmetric quotient that defined the midpoint rule — and that rule was unstable as an IVP time-stepper, blowing up no matter how small the step. The interesting twist is that here it is perfectly acceptable: in the BVP setting the whole grid is solved at once as one linear system rather than marched forward in time, so the step-to-step error amplification that wrecked the midpoint rule never gets a chance to act.
Substituting the central difference for and the second difference quotient for into the full linear ODE , then clearing denominators, gives the interior difference equation
Assembling the difference equation
Rearrange the ODE as and insert both quotients at :
Multiply through by and collect the three unknowns. The coefficient gathers from the second-difference term and from the central-difference term; the coefficient gathers and ; the coefficient gathers and . That is the displayed equation.
It still yields a tridiagonal matrix with three nonzero entries per row — but the off-diagonals are no longer a tidy . Diagonal dominance now needs the step small enough that , so that stays nonnegative and the off-diagonals still sum to . Push the step past that and dominance — and with it the guarantee of a unique solution — can fail. Small steps again, the recurring tax.
The common escape is to discretize the first derivative one-sidedly instead, in the direction the coefficient points.
The upwind discretization approximates the first derivative by a one-sided difference whose direction is chosen by the sign of the coefficient :
It always produces a strictly diagonally dominant, invertible system, whatever the step size — but it is only first-order accurate, a step down from the central difference’s second order.
So the trade is explicit: the central difference is more accurate but conditionally solvable, the upwind difference is unconditionally solvable but less accurate.
Kinds of boundary conditions
The conditions used so far prescribe the value of at each end. That is one of several standard kinds, and each reshapes the system’s first and last rows a little differently.
A Dirichlet boundary condition prescribes the value of the solution at a boundary point, e.g. . The boundary value is known outright, so it is not an unknown of the system — it moves to the right-hand side.
A Neumann boundary condition prescribes the first derivative at a boundary point, , rather than the value. The boundary value itself is now unknown and stays in the system.
A Neumann condition is discretized with the help of a virtual point just outside the interval. Writing the central difference for the prescribed slope at and solving for the ghost value,
and then substituting that into the second difference quotient at the boundary eliminates the virtual point:
Because the boundary values and are no longer given, they become additional unknowns, and the system grows accordingly.
A periodic boundary condition identifies the two ends, requiring the solution to take the same value at both: . The trajectory closes up on itself.
The shooting method
Discretizing the whole interval is not the only way. A completely different approach turns the BVP back into the kind of problem we already know how to solve.
The shooting method reduces a boundary value problem to a sequence of initial value problems. It replaces the unknown far-end condition with a guessed initial slope — the shooting angle — integrates the resulting IVP forward, and adjusts until the trajectory lands on the prescribed endpoint.
The name is literal. Imagine aiming a shell from your position at a distant target: you know where you are firing from and where you want to land, but not the launch angle that connects them. So you pick an angle, fire, see where the shot falls, correct, and fire again — converging on the angle that hits. Replacing the endpoint constraint by a launch angle is exactly the trick.
Concretely, the BVP
is replaced by the IVP with the known start value but an unknown starting slope,
and the task becomes: find the value whose forward solution satisfies the missing end condition,
This is reminiscent of an inverse problem — we are hunting for the input (the angle ) that produces a desired output (hitting ) — and it is solved by iteration, much like a Newton iteration, with one IVP integrated per iteration step. Like the predictor–corrector idea, it trades a single hard solve for a few cheaper, well-understood ones.
Summary
Population dynamics has served as the first fully worked continuous example, and it splits into the two halves the whole course turns on.
The modeling half — developed among the models for population dynamics — derived a sequence of models of increasing fidelity for different scenarios, from unconstrained Malthusian growth through the logistic and saturation models to coupled multi-species systems, all expressed as initial value problems of ordinary differential equations, and studied for what they say qualitatively: existence of solutions, stationary states, long-term behavior.
The simulation half is this page. Because the direct analytic route generally fails — most ODEs have no closed-form solution — the models have to be solved numerically, and that demanded a careful look at how: discretization and its errors; the one-step, multistep, and implicit methods that march an initial value problem forward; the conditioning, stability, and stiffness phenomena that decide whether the march succeeds; and finally the finite-difference and shooting techniques that handle boundary value problems. Modeling poses the equations; simulation extracts the numbers when no formula will.