W05: From differential equations to trustworthy simulation
On this page
- Prerequisites and observable goals
- The central question: what is the simulation supposed to reproduce?
- Explicit Euler: a reasonable local approximation with a global weakness
- Velocity Verlet: split the acceleration update
- A small complete step
- Accuracy, stability, and model adequacy are separate
- Independent practice
- Complete solutions: W05
- Retention and readiness
Prerequisites and observable goals#
M25, A05–A06, vectors, units, and W01’s state-update distinction.
Derive two discrete methods from a continuous model; analyze stability and energy separately; validate against an analytic trajectory and a step-halving experiment.
The central question: what is the simulation supposed to reproduce?#
A simulation consists of at least three objects: a mathematical model, a numerical method, and a particular implementation. The model specifies a continuous law under assumptions. The method approximates that law using finite steps. The implementation stores finite-precision state and executes updates. A defect in any layer can give wrong results, and testing one layer does not automatically validate the others.
Use a unit-mass harmonic oscillator as a bounded example. Position is , velocity , and angular frequency . The equations are
The exact solution is and in the chosen position units. Position and velocity do not have interchangeable units; has units inverse time, so is an acceleration. This model idealizes a restoring force proportional to displacement, with no damping, driving force, collision, or changing parameter.
Define energy per unit mass . Differentiating along the exact solution gives
Conservation follows from the specified equations. It does not prove that an arbitrary animation or numerical integrator conserves that energy.
Explicit Euler: a reasonable local approximation with a global weakness#
Using the old state for both right sides yields
For small , each resembles the first terms of a Taylor expansion. But substitute both into the discrete energy:
The cross terms cancel; the remaining squared-step terms are positive. Thus . For every nonzero positive step, this method gains energy on a nonzero state. Reducing reduces the drift over a fixed interval, but no positive fixed step makes this scheme energy-stable for arbitrarily many oscillations. “The force points inward” is not enough to prevent numerical growth.
This is not a claim that Euler is useless. It is a precise warning about one model and long-time behavior. For a decaying scalar equation , its stability condition is different. Analyze the differential equation and the update matrix actually being used.
Velocity Verlet: split the acceleration update#
An acceleration depending on position suggests a half velocity update, a position update, then the remaining half velocity update:
The second half uses the new position. Store the intermediate explicitly; casually overwriting values may define another method. Expanding gives
This matrix has determinant 1 and trace . Its eigenvalues lie on the unit circle with distinct oscillatory modes for . For , a real eigenvalue has magnitude greater than 1 and some states grow. At , a repeated eigenvalue can have a nontrivial Jordan block, so the endpoint does not supply a safe bounded-oscillation guarantee. Use the strict interval.
For , this scheme exactly preserves, in real arithmetic, the positive quadratic expression
It generally does not preserve the original exactly. Because is positive definite in this range, it bounds and over arbitrarily many exact-arithmetic steps. Floating-point roundoff and changing step sizes introduce further issues. The distinction between a modified invariant and exact physical energy is important, not a technicality.
A small complete step#
With , the half velocity is . Position becomes . Final velocity is . Compare with exact and . These errors are small but nonzero. The computed physical energy is
not exactly . The modified energy is both before and after the step in exact rational arithmetic. Check the equations rather than describing any tiny numerical change as “energy conservation.”
Accuracy, stability, and model adequacy are separate#
A stable method can still have a phase error: the oscillation stays bounded but peaks at the wrong times. Under the Verlet stability relation, the numerical phase angle satisfies . Its effective frequency differs from for nonzero step. Energy bounds alone do not guarantee accurate event times or positions.
For a fixed final time , compute with steps and compare all methods at that same time. A second-order method in its asymptotic regime often has error ratios approaching 4, because the global error scales like . A ratio is evidence under a model, not proof of the order for every input. Roundoff, a near-zero leading error coefficient, instability, or a changed final time can spoil the naive interpretation. Use known analytic solutions where available; use independent methods and convergence studies for harder cases.
Even a highly accurate solution of this oscillator model would not validate a real suspension, vehicle, robot, or orbital system. The physical model may lack damping, nonlinearity, external forces, measurement uncertainty, and safety constraints. The lab is a reproducible numerical experiment, not safety-critical controller software. Later T04/T05 and GP2 reuse the same discipline of explicit assumptions and fault boundaries in other domains.
Independent practice#
F foundation C standard course work T transfer S optional stretch L runnable lab or project. Attempt the complete set before opening its solutions.
Derive the Euler energy multiplier for the oscillator without skipping cross terms. Starting at energy with , give the exact energy after 10 steps in terms of a power, and explain why a plausible-looking path does not establish conservation.
Carry out one velocity-Verlet step for . Compute both physical energies and the modified energies before and after. Which quantity is exactly preserved by the real-arithmetic update?
Use the Verlet matrix’s determinant and trace to derive the strict stable-oscillation condition. Explain why determinant 1 alone is insufficient, and why the endpoint should not be included in a general boundedness claim.
A report compares a run ending at time 10 with a smaller-step run ending at time 10.03 and claims a convergence ratio from their final positions. Diagnose the problem and design a corrected validation using analytic position, velocity, phase/event timing, and energy.
Implement the bounded oscillator lab in integration_code/starters/simulation.py. Validate finite state, positive step/frequency, and a bounded integer step count. Return timestamped position, velocity, and physical energy. Compare to analytic values at a fixed final time, perform step halving, and include one deliberately unstable step-size test described as a diagnostic rather than a production operating mode.
Optional small hints
For .02, calculate the half-step velocity before the new position. For .03, the characteristic polynomial is . For .04, first make the compared physical question identical.
Complete solutions: W05#
Compare the first step where your work differs. A corrected answer is not yet an independent success.
W05.01Show solution
A systematic numerical energy source
Expanding gives . The mixed terms sum to zero. Factor the remainder as and divide by two. After 10 steps the energy is exactly in ideal arithmetic, about . A short plotted trajectory can hide a roughly 10.5% energy gain; visual plausibility is not the conservation equation. Different plot scales and viewing intervals can hide or amplify the apparent defect.
Back to W05.01W05.02Show solution
Modified conservation is not identical physical conservation
The half velocity is . New position is . New velocity is . Physical energy begins at and ends at . With , the modified position coefficient is . Initially ; afterward it is . Exact decimal rational calculation verifies this equality. The physical energy changed, even though the modified invariant did not.
Back to W05.02W05.03Show solution
Area preservation alone does not bound an orbit
Let . The trace lies strictly between and 2 precisely when . With determinant 1, the roots are conjugate unit-modulus numbers in that range, giving bounded oscillatory powers of this fixed matrix. A determinant-one matrix such as instead expands one direction exponentially; determinant alone controls area, not every length. At the matrix is , whose powers include a term proportional to the number of steps when the velocity component is nonzero. Thus the endpoint can grow linearly in position. This is a linear-model real-arithmetic statement, not a general adaptive-integrator theorem.
Back to W05.03W05.04Show solution
Compare the same modeled event at the same time
The two final positions answer different time queries. A phase shift of .03 can dominate discretization differences, so their ratio is not an order estimate. Choose a fixed and step counts with , or use an explicitly analyzed final shortened step/interpolation. Compare position and velocity with and , study maximum errors over matched timestamps, estimate event/phase timing separately, and report physical versus modified energy. Repeat with smaller steps until the expected ratio is plausible above roundoff. State model assumptions and do not interpret convergence to the wrong physical model as validation of reality.
Back to W05.04W05.05Show solution
A reproducible reference
The reference implements the three updates in their stated order and records the old initial state as well as later samples. The analytic helper provides an independently derived target rather than another integrator with the same potential bug. Nonfinite values are rejected; bounded inputs do not imply that every allowed step is stable, so the caller must analyze .
"""W05: velocity Verlet for x''=-omega^2*x, unit mass, fixed time step."""
import math
def verlet(x=1.,v=0.,omega=1.,dt=.1,steps=100):
if not all(math.isfinite(z) for z in (x,v,omega,dt)) or omega<=0 or dt<=0:
raise ValueError("finite state, positive frequency and step required")
if type(steps) is not int or not 0<=steps<=100000:
raise ValueError("bounded nonnegative step count required")
energy0=.5*(v*v+omega*omega*x*x)
if not math.isfinite(energy0):
raise ValueError("initial energy is not finite; rescale the problem")
rows=[(0.,x,v,energy0)]
for k in range(1,steps+1):
half=v-.5*dt*omega*omega*x
new_x=x+dt*half
new_v=half-.5*dt*omega*omega*new_x
x,v=new_x,new_v
energy=.5*(v*v+omega*omega*x*x)
if not all(math.isfinite(z) for z in (x,v,energy,k*dt)):
raise ValueError("nonfinite trajectory; check step and scale")
rows.append((k*dt,x,v,energy))
return rows
def exact(t,x0=1.,v0=0.,omega=1.):
if not all(math.isfinite(z) for z in (t,x0,v0,omega)) or omega<=0:
raise ValueError("finite inputs and positive frequency required")
phase=omega*t
if not math.isfinite(phase):
raise ValueError("nonfinite phase; rescale the problem")
result=(x0*math.cos(phase)+(v0/omega)*math.sin(phase),
-omega*x0*math.sin(phase)+v0*math.cos(phase))
if not all(math.isfinite(z) for z in result):
raise ValueError("nonfinite analytic state; rescale the problem")
return result
if __name__=='__main__':
for dt in (.1,.05,.025):
t,x,v,e=verlet(dt=dt,steps=round(1/dt))[-1]
target=exact(t)
print(dt,math.hypot(x-target[0],v-target[1]),e)Tests include the first step, invalid inputs, energy behavior, and fixed-time error ratios under step halving. They establish selected numerical behavior for this oscillator. They do not prove the absence of all accumulated roundoff or validate a physical system. Record units, frequency, initial conditions, step count, and final time with the resulting table so a reader can reproduce the exact question.
Back to W05.05Retention and readiness#
Explain why a locally plausible derivative step can create global energy growth. Name the conserved quantity actually checked. Before trusting a simulation, state model error, discretization error, and finite-precision error separately.