Why Numerical Integration Matters
A velocity sensor records how a vehicle's speed changes over time. Total distance is an integral, but the sensor provides samples rather than an antiderivative. A simulator has a similar problem when it can evaluate a response at a chosen input yet cannot integrate the response symbolically. Numerical integration turns those evaluations into an approximation of accumulated change.
This lesson computes a real, finite-interval integral $I=\int_a^b f(x)\,dx$. It covers the composite trapezoidal rule, composite Simpson's rule, adaptive Simpson integration, Gaussian quadrature, and Monte Carlo integration. You will trace their sampling and weighting decisions, implement all five in three languages, and distinguish an actual error, an estimated error, and statistical uncertainty.
The first four methods exploit regularity in a one-dimensional function. Monte Carlo recasts an integral as an expectation and is especially useful when extending to many dimensions. None of these implementations automatically handles infinite intervals or an undefined endpoint; such problems need a transformation or a specialized method.
Numerical integration approximates accumulated signed area by evaluating $f$ at selected points and combining those values with weights. The central choices are where to sample, how to weight the samples, and what evidence supports the requested accuracy.
Core Concepts and Terminology
For $a\lt b$, a quadrature rule has the form $Q=\sum_i w_i f(x_i)$. The nodes $x_i$ specify evaluations and the weights $w_i$ include interval scaling. This is a dot product of two vectors, not a linear system: no matrix elimination or pivoting is required. Reversing the endpoints changes the integral's sign, while an uncertainty magnitude stays nonnegative.
On $[0,1]$, Simpson's single-panel approximation to $f(x)=x^4$ uses nodes $0,1/2,1$ and weights $1/6,4/6,1/6$. Its result is $5/24\approx0.208333$, while the exact integral is $1/5=0.2$. The diagram shows both the sample vector and the weighted sum.
| Term | Concrete meaning | Role |
|---|---|---|
| Integrand | $f(x)=x^4$ | Function being integrated. |
| Signed integral | $\int_0^1x^4\,dx=1/5$ | Target accumulation; reversing limits gives $-1/5$. |
| Node | $x_i=1/2$ | A point where the function is evaluated. |
| Weight | Simpson's midpoint weight is $4/6$ on $[0,1]$ | Determines each sample's contribution. |
| Subdivision count | $n$ equal subintervals; $h=(b-a)/n$ | Controls a composite grid's resolution. |
| Simpson panel | Two adjacent subintervals, with three nodes | Do not confuse the panel count with $n$. |
| Actual error | $\lvert Q-I\rvert$ | Available only when a reference value or rigorous enclosure is known. |
| Adaptive error estimate | $\lvert S_2-S_1\rvert/15$ | A local diagnostic based on Simpson refinement. |
| Absolute tolerance | $\tau\gt0$ | Adaptive target in the integral's units. |
| Monte Carlo standard error | $(b-a)s/\sqrt{N}$ for ordered endpoints | Estimated sampling uncertainty, not a deterministic bound. |
| Degree of exactness | Three-node Gauss–Legendre integrates degree at most $5$ exactly in exact arithmetic | Describes a rule's polynomial behavior. |
Integration is signed: regions below the axis contribute negatively. If the application asks for geometric area, integrate $\lvert f(x)\rvert$ or split at sign changes. Also distinguish errors in the measured or simulated function from errors introduced by quadrature; refining a grid cannot repair an inaccurate model.
How Numerical Integration Works, Step by Step
1. Establish the domain and numerical contract. Validate finite endpoints and a finite representable interval width. Require a positive subdivision count, an even $n\ge2$ for composite Simpson, a positive finite adaptive tolerance, or at least two Monte Carlo samples when estimating a variance. The programs normalize reversed endpoints internally and apply the orientation sign to the final estimate. A zero-length interval returns zero without evaluating the function after validating the method's parameters.
2. Choose how to sample and combine values. The five methods use different information:
- Composite trapezoidal: join adjacent samples by straight lines and integrate those segments. With $f_i=f(a+ih)$, use $T_n=h[f_0/2+\sum_{i=1}^{n-1}f_i+f_n/2]$. It works naturally with equally spaced measured data.
- Composite Simpson: fit a quadratic through each group of three nodes on an equally spaced grid. With even $n$, use $S_n=(h/3)[f_0+f_n+4\sum_{i\text{ odd}}f_i+2\sum_{i\text{ even},\,0\lt i\lt n}f_i]$. Although the interpolant is quadratic, symmetry makes the rule exact for cubics.
- Adaptive Simpson: compare a coarse Simpson panel with two half-panels, then refine only where their disagreement exceeds a local tolerance budget.
- Gaussian quadrature: choose nodes and weights jointly to maximize polynomial exactness. The implementations use a fixed three-node Gauss–Legendre rule, optionally repeated over equal panels.
- Monte Carlo: sample positions uniformly, average their function values, and multiply by interval length. The sample variance supplies an estimated standard error.
3. For adaptive Simpson, reuse three cached values and evaluate only two new ones. On a current interval $[\ell,r]$ with midpoint $m$, define
$$ S_1=\frac{r-\ell}{6}[f(\ell)+4f(m)+f(r)]. $$
Evaluate the quarter points $q_\ell=(\ell+m)/2$ and $q_r=(m+r)/2$. Compute one Simpson value on each half, and let their sum be $S_2$. Set $\Delta=S_2-S_1$, estimate $e=\lvert\Delta\rvert/15$, and use the corrected value $Q=S_2+\Delta/15$ when accepting that interval.
Why divide by $15$? In the smooth asymptotic regime, halving Simpson's step divides its leading error by $2^4=16$. Thus $I-S_2\approx(S_2-S_1)/15$. This estimates the error of the uncorrected refined value; adding the correction often improves the approximation further. It is an estimate rather than a proof for an arbitrary integrand.
4. Accept or split without losing the interval's budget. If $e\le\tau_{\mathrm{local}}$, add the corrected value to the total. Otherwise split into two child intervals, give each half the parent's tolerance budget, and preserve cached endpoint and midpoint values. The code uses an explicit depth-first stack of ordinary arrays. It pushes the right child first so the left child is processed first.
The initial interval has remaining depth $D$. A remaining depth of zero still permits the two new evaluations needed for a comparison, but prevents further splitting. If its estimate exceeds its budget, return a best-effort contribution and set status depth. If rounding prevents distinct quarter points, keep the available coarse contribution, mark its error unavailable with infinity, and return status stalled. Underflow of a required child tolerance budget also produces stalled. An ok status means every terminal interval passed the estimator test; it does not certify the actual error.
flowchart TD
A["Validate domain, tolerance, and depth"] --> B{"Zero interval?"}
B -->|Yes| Z["Return zero without evaluations"]
B -->|No| C["Cache endpoints and midpoint; push interval"]
C --> D["Pop one interval"]
D --> E{"Distinct quarter points?"}
E -->|No| F["Keep coarse value; flag stalled"]
E -->|Yes| G["Evaluate two points; compute refined value and error"]
G --> H{"Error within local budget?"}
H -->|Yes| I["Accumulate corrected value and error estimate"]
H -->|No| J{"Depth and child budget available?"}
J -->|No| K["Accumulate best effort; flag depth or stalled"]
J -->|Yes| L["Push children with half budgets and cached values"]
F --> M{"Stack empty?"}
I --> M
K --> M
L --> M
M -->|No| D
M -->|Yes| N["Apply orientation; return estimate, error, count, status"]
The diagram describes the adaptive method. If even the initial midpoint is not representable strictly inside the interval, the code uses the two endpoint values for a best-effort trapezoid and reports stalled. A nonfinite function value or checked arithmetic result raises an exception in every implementation.
5. Map Gaussian nodes correctly. On the reference interval $[-1,1]$, three-node Gauss–Legendre has nodes $t=-\sqrt{3/5},0,\sqrt{3/5}$ and weights $5/9,8/9,5/9$. For a physical panel $[\ell,r]$, let $c=(\ell+r)/2$ and $d=(r-\ell)/2$. Then
$$ \int_\ell^r f(x)\,dx\approx d\sum_{j=1}^{3} w_j f(c+d t_j). $$
The factor $d$ is the change-of-variable Jacobian. Forgetting it scales every answer incorrectly. The code evaluates the equivalent expression $\ell+d(1+t_j)$ to avoid summing two large endpoints. General $q$-node Gauss–Legendre uses roots of the degree-$q$ Legendre polynomial and is exact through degree $2q-1$; the supplied programs tabulate only $q=3$.
6. Track Monte Carlo uncertainty alongside its average. For independent uniform $U_i$ on $[0,1]$, set $X_i=a+(b-a)U_i$ and $Y_i=f(X_i)$. Then
$$ \widehat I_N=(b-a)\overline Y,\qquad s^2=\frac{1}{N-1}\sum_{i=1}^N(Y_i-\overline Y)^2,\qquad \widehat{\operatorname{SE}}=\lvert b-a\rvert\sqrt{\frac{s^2}{N}}. $$
The code uses Welford's online mean and centered-sum update, avoiding storage of all samples. Its small deterministic generator exists to make the three languages reproduce the same sample stream; the statistical theory assumes independent sampling with finite variance. An approximate normal interval such as $\widehat I_N\pm1.96\widehat{\operatorname{SE}}$ needs those assumptions and an adequate sample size, and is not a guaranteed enclosure.
Worked Example with a Full Trace
Compute $I=\int_0^1x^4\,dx=1/5$. For a small fixed grid with $n=2$, $h=1/2$ and samples $0,1/16,1$, the trapezoidal rule gives $T_2=9/32=0.28125$. Simpson gives $S_2=5/24\approx0.2083333333$. For the adaptive trace, call that coarse single-panel value $S_1$; here the subscripts distinguish coarse and refined estimates rather than the composite grid count.
Run adaptive Simpson with total tolerance $\tau=10^{-4}$ and maximum depth $D=10$. The table lists every distinct evaluated node, sorted by position. The actual evaluation order in the programs is $0,1,1/2,1/4,3/4,1/8,3/8,5/8,7/8$.
| Node $x$ | Exact $f(x)=x^4$ | First used for |
|---|---|---|
| $0$ | $0$ | Initial left endpoint |
| $1/8$ | $1/4096$ | Left child's new quarter point |
| $1/4$ | $1/256$ | Root's new quarter point; then cached |
| $3/8$ | $81/4096$ | Left child's new quarter point |
| $1/2$ | $1/16$ | Initial midpoint; then shared boundary |
| $5/8$ | $625/4096$ | Right child's new quarter point |
| $3/4$ | $81/256$ | Root's new quarter point; then cached |
| $7/8$ | $2401/4096$ | Right child's new quarter point |
| $1$ | $1$ | Initial right endpoint |
The complete decision trace has one rejected root interval and two accepted children:
| Interval | Local budget | Coarse $S_1$ | Left and right half-panel values | Refined $S_2$ | $\Delta$ | $e=\lvert\Delta\rvert/15$ | Decision and contribution |
|---|---|---|---|---|---|---|---|
| $[0,1]$ | $1/10000$ | $5/24$ | $5/768$, $149/768$ | $77/384$ | $-1/128$ | $1/1920$ | Split: estimate exceeds budget |
| $[0,1/2]$ | $1/20000$ | $5/768$ | $5/24576$, $149/24576$ | $77/12288$ | $-1/4096$ | $1/61440$ | Accept $S_2+\Delta/15=1/160$ |
| $[1/2,1]$ | $1/20000$ | $149/768$ | $1013/24576$, $3749/24576$ | $2381/12288$ | $-1/4096$ | $1/61440$ | Accept $S_2+\Delta/15=31/160$ |
The final sum is $1/160+31/160=1/5$. The reported error estimate is $1/30720\approx0.0000325520833$, and the evaluation count is $9$. Both leaves pass their $0.00005$ budgets, so the status is ok. For this quartic, the correction cancels the entire Simpson truncation error in exact arithmetic; the positive reported diagnostic is not the actual error of the corrected result.
The three-node Gaussian rule also integrates this quartic exactly in exact arithmetic, using only three evaluations. Its physical nodes are $[1-\sqrt{3/5}]/2$, $1/2$, and $[1+\sqrt{3/5}]/2$, with physical weights $5/18,4/9,5/18$.
For a tiny Monte Carlo arithmetic example, suppose the two sampled uniform values happen to be $1/4$ and $3/4$. Their function values are $1/256$ and $81/256$, so the integral estimate is $41/256=0.16015625$. The sample variance is $25/512$, and its estimated standard error is $5/32=0.15625$. This deliberately small sample illustrates the calculation; it is separate from the seeded generator used by the programs.
Trace It by Hand
At the root interval, the comparison gives $e=1/1920\approx0.0005208333$. Predict whether it is accepted for $\tau=10^{-4}$, which new nodes are evaluated next, and how many total evaluations are needed when both children pass.
Reveal: reject the root, assign each child tolerance $0.00005$, and process the left child first. Its new nodes are $1/8,3/8$; the right child's are $5/8,7/8$. Starting from three initial samples and adding two at each of three processed tree nodes gives $3+2\times3=9$ evaluations.
Now set maximum depth to zero with the same tolerance. The corrected quartic answer is still $0.2$ up to rounding, but the status must be depth: the root's error estimate failed and refinement was prohibited. A coincidentally accurate answer does not justify claiming the tolerance test passed.
Implementation in Python, C++, and Java
Each panel is a complete program with the same arithmetic and sample configuration. trapezoidal and simpson take the number of uniform subintervals; gauss3 takes the number of Gaussian panels, with three evaluations per panel. Adaptive Simpson takes an absolute tolerance and a maximum depth in $[0,30]$. Monte Carlo takes a sample count and an integer seed in $[1,2147483646]$.
Adaptive output contains the estimate, the sum of terminal error diagnostics, the number of function evaluations, and status ok, depth, or stalled. A stalled interval whose quarter points cannot be formed contributes an infinite error diagnostic. Fixed rules return a scalar without pretending to supply a checked error bound. Monte Carlo returns the estimate and a nonnegative standard error. Java uses the names adaptiveSimpson and monteCarlo; their logic matches the corresponding snake-case functions.
The Gaussian rule and the adaptive stack use ordinary nested arrays. Quadrature has no matrix pivoting step. Every function evaluation is checked for a finite value; checked nonfinite arithmetic and invalid parameters raise an exception. The examples assume magnitudes where the remaining floating-point sums are meaningful. These implementations do not turn arbitrary singular functions into valid finite-interval inputs.
All five integrate $x^4$ on $[0,1]$. Use $1000$ trapezoidal subintervals, $10$ Simpson subintervals, adaptive tolerance $10^{-8}$ with depth $20$, one three-node Gaussian panel, and $100000$ Monte Carlo samples with seed $1$. The adaptive sample uses a tighter tolerance than the hand trace. Its reported diagnostic is about $7.9473\times10^{-9}$ with $65$ function evaluations.
All three programs print:
trapezoidal: integral = 0.200000, check = PASSsimpson: integral = 0.200013, check = PASSadaptive: integral = 0.200000, check = PASSgauss3: integral = 0.200000, check = PASSmonte-carlo: integral = 0.199877, check = PASSadaptive status = okmonte-carlo standard error = 0.000842all methods = PASS
Each deterministic check compares against the independently known $I=0.2$ with an explicit threshold in the driver. In particular, the trapezoidal actual error is about $3.333333\times10^{-7}$, so rounding its answer to six decimal places hides its remaining error. The Monte Carlo check compares this particular seeded run's actual error with five estimated standard errors; it is a reproducible demonstration check, not an accuracy guarantee for future samples.
The reproducible sample stream uses $s_{k+1}=16807s_k\bmod2147483647$ and $u_k=s_k/2147483647$. The first four states from seed $1$ are $16807$, $282475249$, $1622650073$, and $984943658$. C++ and Java use 64-bit integer multiplication so the generator update does not overflow. This compact illustrative generator is kept explicit so a language's default random-number generator cannot silently change the sample input.
Complexity, Correctness, and Invariants
Let $C_f$ be the cost of one function evaluation, $L=\lvert b-a\rvert$, $h=L/n$, $P$ the number of Gaussian panels, $N$ the Monte Carlo sample count, and $D$ the maximum adaptive depth. The following errors concern exact-arithmetic quadrature under the stated smoothness assumptions; roundoff and input-model error are additional effects.
| Method | Evaluations and time on a nonzero interval | Error or uncertainty behavior | Auxiliary space |
|---|---|---|---|
| Composite trapezoidal | Exactly $n+1$ evaluations; $\Theta((n+1)C_f)$ | If $\lvert f''\rvert\le M_2$, actual error at most $Lh^2M_2/12$ | $O(1)$ |
| Composite Simpson | Exactly $n+1$ evaluations; $\Theta((n+1)C_f)$ with even $n$ | If $\lvert f^{(4)}\rvert\le M_4$, actual error at most $Lh^4M_4/180$ | $O(1)$ |
| Adaptive Simpson | If $V$ tree nodes are fully compared, $3+2V$ evaluations; best case $5$ | Local diagnostic is $\lvert S_2-S_1\rvert/15$; worst-case full tree has $2^{D+2}+1$ evaluations and $O(2^D C_f)$ time | $O(D+1)$ with the depth-first stack |
| Composite three-node Gauss–Legendre | Exactly $3P$ evaluations; $\Theta(P C_f)$ | Exact through degree $5$; for $f\in C^6$, error at most $L(L/P)^6 M_6/2016000$ when $\lvert f^{(6)}\rvert\le M_6$ | $O(1)$ |
| Plain Monte Carlo | Exactly $N$ evaluations; $\Theta(N C_f)$ | Under independent uniform sampling, variance $L^2\operatorname{Var}(Y)/N$, hence root-mean-square error $O(N^{-1/2})$ | $O(1)$ with online variance |
For fixed rules and a fixed sample count, best, average, and worst work are the same because the loop counts do not depend on function values. All methods return in $O(1)$ time on a validated zero-length interval. Adaptive work depends on where the integrand needs resolution; there is no distribution-free average tree size. The depth bound guarantees termination, including a reported failure to meet the diagnostic target. Unrepresentable quarter points can terminate some branches earlier than the full-tree count.
The trapezoidal and Simpson bounds imply $n=O(\varepsilon^{-1/2})$ and $n=O(\varepsilon^{-1/4})$, respectively, for fixed interval and derivative bounds when targeting absolute error $\varepsilon$. Composite three-node Gauss–Legendre has $P=O(\varepsilon^{-1/6})$ under its sixth-derivative bound. Plain Monte Carlo requires $N=O(\varepsilon^{-2})$ for a fixed root-mean-square target when its variance is finite. These rates compare different assumptions and constants; Monte Carlo's rate alone does not depend on dimension, but the variance and evaluation cost can depend strongly on dimension.
Why fixed rules are correct under their assumptions. Trapezoidal and Simpson rules integrate their local interpolation formulas, then sum over a partition. Their derivative remainder terms supply the stated error bounds. Gaussian nodes are roots of an orthogonal polynomial. Dividing any polynomial of degree at most $2q-1$ into a multiple of that degree-$q$ polynomial plus a lower-degree remainder explains the $2q-1$ exactness: the multiple integrates to zero by orthogonality and vanishes at the nodes, while the interpolatory rule integrates the remainder exactly.
Why adaptive bookkeeping is correct. Accepted leaves together with pending stack intervals form a disjoint partition of the original interval, apart from shared endpoints. Splitting replaces one interval by two children without a gap or overlap; halving the parent's tolerance preserves the total assigned budget. The accumulated integral is the sum of accepted leaf approximations, never the sum of both an ancestor and its descendants. If every leaf estimate passes, the sum of estimates is at most the original tolerance in exact arithmetic. That proves the budget bookkeeping, not that the estimator cannot miss a feature.
Why Monte Carlo is unbiased in its ideal sampling model. A uniform point $X$ on $[a,b]$ satisfies $\mathbb E[f(X)]=I/(b-a)$ for ordered endpoints. Linearity of expectation gives $\mathbb E[\widehat I_N]=I$. Independence gives the variance reduction by $N$; finite variance is needed for the stated root-mean-square result. A finite pseudorandom stream approximates this sampling model and does not make those probabilistic statements deterministic guarantees.
Adaptive integration preserves a partition of the domain and a conserved tolerance budget: each split replaces one interval by two children whose budgets sum to the parent's. This justifies adding terminal contributions and error diagnostics, while actual accuracy still depends on whether the local error model describes the integrand.
Variants, Pitfalls, and Optimizations
A small refinement difference can miss a narrow feature. Consider the continuous triangular bump $f(x)=\max(0,1-\lvert x-0.30\rvert/0.01)$ on $[0,1]$. It is nonzero only on $(0.29,0.31)$ and has exact integral $0.01$. Adaptive Simpson's first five nodes are $0,1/4,1/2,3/4,1$, all with value zero. Both estimates are zero, so the code returns ok with zero estimated error and an incorrect integral. Supplying breakpoints $0.29,0.30,0.31$ and integrating the linear pieces exposes the feature.
This is a limitation of finite sampling, not just of the triangular function: an unobserved smooth bump can produce the same issue. If known physics or data indicates a discontinuity, a corner, a narrow peak, or a rapid oscillation, split or transform the problem before relying on a local estimator. Refinement tests compare what has been sampled, not everything between samples.
Respect the input data. Standard composite Simpson requires equal spacing and an even subdivision count. It cannot be applied to arbitrary unevenly spaced measurements with the same $1,4,2,4,\ldots,1$ weights. A nonuniform trapezoid, $\sum_i (x_{i+1}-x_i)(y_i+y_{i+1})/2$, works directly with ordered irregular samples. Interpolation of noisy data adds a modeling decision; more quadrature evaluations of that interpolant do not create new measurements.
Use specialized variants when their assumptions fit. Adaptive Gauss–Kronrod pairs reuse samples to compare different-degree rules and are common in general-purpose integrators. Romberg extrapolates a sequence of trapezoidal grids on smooth problems. Periodic smooth integrands can make the trapezoidal rule exceptionally efficient. Endpoint singularities may benefit from a substitution, Gauss–Jacobi weights, or tanh–sinh quadrature. Highly oscillatory integrals often need oscillation-aware techniques rather than a generic tolerance decrease.
Improve Monte Carlo by reducing variance. Stratification, antithetic samples, control variates, and importance sampling can lower variance for suitable integrands. With an importance density $p(x)$, sample from $p$ and average $f(X)/p(X)$ over the domain where the integral receives contributions; the density must be positive there and the reweighted variance must be controlled. Quasi-Monte Carlo uses low-discrepancy points, and its error analysis differs from the independent-sample standard-error formula. Correlated samples also need a different uncertainty calculation.
Handle floating-point limits honestly. Add relative tolerance only with an appropriate absolute tolerance, especially near cancellation where the integral is close to zero. Compensated or pairwise summation can improve long sums. Cache shared nodes in adaptive rules; when doubling a trapezoidal grid, reuse all old samples. Never silently accept a maximum-depth exit as meeting the target. Treat an observed zero Monte Carlo sample variance cautiously: it can mean the samples missed a small region rather than that the integrand is constant.
An adaptive error estimate and a Monte Carlo standard error are different quantities, and neither is automatically a rigorous bound. Check depth and stagnation statuses, include interval scaling, preserve Simpson's spacing requirements, and test for features that the chosen nodes may miss.
Practice Problems and Real-World Use
Start with exact polynomial integrals so mistakes in weights, orientation, and scaling are visible. Then move to smooth transcendental functions, deliberately hidden features, and stochastic examples. Record evaluation counts as well as runtime: the cost of calling a simulation can dominate the arithmetic inside the integrator.
| Problem or system | Concrete task | Idea tested | Difficulty |
|---|---|---|---|
| Polynomial rule checks | Integrate $x^k$ for $k=0,\ldots,6$ on several intervals | Trapezoidal, Simpson, and Gaussian exactness limits | Easy |
| Velocity samples | Estimate displacement from equally and unequally spaced samples | Data interpretation, units, and valid weights | Easy |
| Adaptive quartic trace | Reproduce the $9$-evaluation $x^4$ run, then reduce the depth limit | Cached values, local budgets, and honest failure reporting | Medium |
| Smooth exponential | Integrate $e^x$ on $[0,1]$ and compare with $e-1$ | Grid refinement and observed convergence rates | Medium |
| Hidden triangular bump | Integrate the bump supported on $[0.29,0.31]$ with and without breakpoints | An estimator can miss an unsampled feature | Medium |
| Probability normalization | Integrate a bounded-domain density model and compare with its intended total | Normalization, tails, and model error versus quadrature error | Medium |
| Rendering a pixel | Average a continuous light-transport contribution over random samples | Monte Carlo variance and sample cost | Hard |
| Multidimensional response model | Estimate an expectation over a bounded parameter box | Dimension, variance reduction, and uncertainty reporting | Hard |
For further reading, NIST's quadrature chapter gives the classical rules, Gaussian quadrature, and remainder formulas. SciPy's Simpson documentation distinguishes sampled-data integration and its spacing-dependent exactness. Art Owen's Simple Monte Carlo chapter develops the sampling model and error estimation. Their assumptions should be checked against the data or callable function before interpreting a reported accuracy figure.