Audit Methods and Reproducibility · Chapter V-05

Trace an Equation Through Code

A printed equation becomes a computational result through a chain of data transformations, functions, branches, and parameters. The audit follows that lineage from economic primitives to final output and checks whether normalizations, support restrictions, derivative formulas, and approximation choices remain invariant along the path.

Conceptual map

  1. V-05.01Computational lineage
  2. V-05.02Reading model code
  3. V-05.03Economic invariants
  4. V-05.04Derivative and approximation checks
  5. V-05.05Missing inputs

1. A printed equation has a computational lineage

The audit follows variables from source fields through transformations, branches, solver calls, and aggregations to the released number.

For each output, record a directed lineage: raw field and unit, cleaning rule, model primitive, parameter normalization, numerical function, aggregation weight, and display transformation. Configuration files and default arguments are inputs. A hard-coded fallback is an input whenever its branch can execute.

Definition 1 · Computational invariant

An invariant is a mathematical property that should hold at a named program boundary: probabilities sum to one, quantities remain in support, a residual is below tolerance, an objective decreases, or a transformation preserves declared units. The test states its numerical tolerance and norm.

2. Stable code can preserve an exact model identity

For utilities \(v\in \mathbb{R}^{J}\) and scale \(\sigma>0\), multinomial-logit shares are

\[s_{j}=\operatorname{exp}[(v_{j}-m)/\sigma ] / \sum _{k}\operatorname{exp}[(v_{k}-m)/\sigma ], \quad m=\operatorname{max}_{k}v_{k}.\](1)

Subtracting \(m\) prevents overflow and leaves the mathematical shares unchanged. For utilities (1000,1001,1002) at \(\sigma=1\), direct exponentiation overflows in ordinary double precision, while (1) yields approximately (0.090031,0.244728,0.665241) and sums to one.

Proposition 1 · Shift invariance and derivative

For any scalar \(c\), \(s(v+c1)=s(v)\). Its Jacobian is \(\partial s_{j}/\partial v_{k}=s_{j}(1\{j=k\}-s_{k})/\sigma\).

Proof. A common shift multiplies every exponential numerator and the denominator by \(\operatorname{exp}(c/\sigma)\), which cancels. Differentiating the normalized exponential gives the diagonal numerator derivative and the denominator derivative; collecting terms yields the stated Jacobian. ∎

3. Derivative tests need scale-aware steps

At \(v\)=(0,1,2), the analytic Jacobian has row sums and column sums equal to zero, reflecting probability normalization and shift invariance. A centered finite difference with step \(h\) compares \([s(v+he_{k})-s(v-he_{k})]/(2h)\) with the analytic column.

Truncation error falls like \(h^{2}\) for smooth shares, while roundoff grows as \(h\) becomes extremely small. Testing several steps and reporting the minimum and local slope is stronger than accepting one arbitrary tolerance. Automatic differentiation checks the implemented computational graph and can reproduce an implementation error shared with the level function.

4. Equivalent formulas can have different domains and errors

Failure case · Stabilization applied after exponentiation

Computing \(\operatorname{exp}(v)\) and then dividing by \(\operatorname{exp}(\operatorname{max} v)\) has already overflowed. The subtraction must occur before the exponential.

At \(\sigma=0\) the smooth formula is undefined; a limit becomes an argmax rule with a tie convention. Empty choice sets make the denominator zero. Missing alternatives change the normalization. Integer division, silent unit conversion, clipping, and NaN replacement can violate the printed equation. Random-number seeds do not control nondeterministic kernels or unrecorded data ordering. A code audit checks executed branches with coverage evidence and verifies that the displayed rounding occurs after model calculation.

5. Implementation, exercises, and sources

Start from one released cell and trace backward to source records. Annotate shapes, units, support, and parameter origins. Add assertions at function boundaries, compare analytic and numerical derivatives, test invariances by metamorphic inputs, and exercise every economically meaningful branch. Retain the exact command and configuration producing the artifact.

Download the volume verification script →

Exercises

  1. Reproduce the stable shares for (1000,1001,1002).
  2. Verify every row and column sum of the analytic Jacobian is zero.
  3. Construct a test detecting whether a price measured in cents was passed to a coefficient estimated per dollar.
Partial solutions

1. Subtract 1002 and evaluate exponentials of \(-2\), \(-1\), and zero. 2. Summing across \(k\) uses \(\sum s_{k}=1\); summing across \(j\) uses the same identity. 3. Compare outputs after multiplying price by 100 and dividing the coefficient by 100; a unit-consistent implementation is invariant.

  1. Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms.Stable evaluation and rounding error.
  2. Kenneth Train, Discrete Choice Methods with Simulation, Chapters 2–3.Logit probabilities and normalization.
  3. Greg Wilson et al. (2014), “Best Practices for Scientific Computing,” PLoS Biology 12, e1001745.Executable tests and computational traceability.

6. Audit checkpoint

Released cell, raw source, units, shapes, cleaning rule, configuration, defaults, executed branches, support assertions, normalization, stable formula, \(\sigma\) boundary, empty sets, missing alternatives, analytic derivative, step sweep, norm and tolerance, automatic-differentiation scope, clipping, NaN handling, random-state control, display rounding, and exact execution command.

7. Scope boundary

The chapter covers equation-to-code lineage and deterministic numerical tests. Whole-program verification, compiler correctness, and hardware fault tolerance require other methods.

Prerequisites