ECnoise#

ecnoise reads m + 1 values of one scalar function, with m + 1 >= 4, and builds the forward-difference table. The default is m = 8 (nine samples). The level-k estimate is

σ_k = sqrt( γ_k * mean_i (Δ^k f_i)^2 ),    γ_k = (k!)^2 / (2k)!

The returned noise is the smallest k whose column changes sign and whose three estimates σ_k, σ_{k+1}, σ_{k+2} lie within a factor of 4. Moré and Wild, SIAM J. Sci. Comput. 33, 1292 (2011), https://doi.org/10.1137/100786125.

inform 1 means that level was accepted. inform 2 means at least half of the first differences are zero; the reference code retries at 100 h. inform 3 means the samples differ in the leading digit, or no column meets the test; the reference code retries at h / 100. A backend-declared value uses inform 0 and does not build the table.

h is the distance between consecutive samples, the spacing in the ECnoise.m stencil f(x - kh), ..., f(x + kh). It is not the half-width of the stencil. sample_noise places x + (i - m/2) h u for i = 0, ..., m, with u the unit vector along the supplied direction.

The table does not supply a derivative. Its high differences are the noise, of size O(eps / h^k). |f''| and the third-derivative scale |T| are separate central differences, Moré and Wild, ACM Trans. Math. Softw. 38, 19 (2012), Algorithm 5.1, https://doi.org/10.1145/2168773.2168777. The forward step and the gradient probe that those scales imply are clamped to [max(1e-16, 4 ulp(max |x_i|)), 1].

Gradient noise is the table applied to g(x + i h u) · w. One unit vector w is drawn from a counter keyed by (seed, component) and is reused at every stencil point. The normal variate uses pure-Rust libm, so the projection does not depend on the platform libm or on the thread count. For any covariance Σ, E[(g · w)²] = tr(Σ) / n because w is uniform on the sphere. The Euclidean noise is sqrt(n) times that projection noise.

How to estimate the noise, choose the step, and stop on the floor is in the how-to.