Table of Contents

Error-Driven Construction

ChebyshevApproximation and ChebyshevSpline can choose node counts from an errorThreshold. Pass null for each dimension you want auto-sized. The build starts auto-sized dimensions at 3 nodes, evaluates the dense grid, and doubles the worst-contributing growable dimension until both the coefficient-tail estimate and an off-grid validation pass are at or below errorThreshold.

If every auto-sized dimension reaches maxN first, the build returns the best interpolant it constructed and sets BuildWarning.

errorThreshold must be finite and greater than zero. Use maxN to cap runtime, not NaN, infinity, zero, or a negative threshold.

Quick Start

using ChebyshevSharp;

// Auto-N: every dim resolves automatically.
var cheb = new ChebyshevApproximation(
    function: (x, _) => Math.Sin(x[0]) + Math.Cos(x[1]),
    numDimensions: 2,
    domain: new[] { new[] { -1.0, 1.0 }, new[] { -1.0, 1.0 } },
    nNodes: null,
    errorThreshold: 1e-8);
cheb.Build(verbose: true);  // [auto-N] nNodes=[3, 3], error=...
                            // [auto-N] validation error=...
                            // [auto-N] nNodes=[6, 3], error=...
                            // ...

// Mixed: fix dim 1 at 15, auto-size dim 0 against the threshold.
var mixed = new ChebyshevApproximation(
    function: (x, _) => Math.Sin(8 * x[0]) + Math.Cos(x[1]),
    numDimensions: 2,
    domain: new[] { new[] { -1.0, 1.0 }, new[] { -1.0, 1.0 } },
    nNodes: new int?[] { null, 15 },
    errorThreshold: 1e-6);

Capacity Pre-Check (GetOptimalN1)

Before committing to a multi-dimensional build, you can size a single dimension:

int n = ChebyshevApproximation.GetOptimalN1(
    function: (x, _) => Math.Sin(x[0]),
    domain: (-1.0, 1.0),
    errorThreshold: 1e-8);
// n is the first doubling-loop candidate that satisfies the threshold,
// or maxN if the threshold is not met before the cap.

Acceptance Check

The coefficient-tail estimate is a fast convergence heuristic, not a proof. Before auto-N accepts a candidate grid, ChebyshevSharp evaluates the original function on denser Type-I probe nodes along each auto-sized dimension and compares those values with the interpolant. This catches aliasing cases where the last coefficient is accidentally small on an under-resolved grid.

The validation pass adds function evaluations to NEvaluations, so an auto-N build can report more evaluations than the final dense grid size alone.

Spline Per-Piece Threshold

ChebyshevSpline applies the threshold per piece — kink-adjacent pieces refine more than smooth ones automatically:

var spl = new ChebyshevSpline(
    function: (x, _) => Math.Abs(x[0]),
    numDimensions: 1,
    domain: new[] { new[] { -1.0, 1.0 } },
    nNodes: null,
    knots: new[] { new[] { 0.0 } },
    errorThreshold: 1e-6);
spl.Build();
// Each piece in spl.Pieces hits the threshold.

When the Cap Bites

If maxN is reached before the threshold is satisfied on any auto dim, BuildWarning is set and the build returns the best result it could achieve. The interpolant is still usable; you should either raise maxN or relax the threshold.

var cheb = new ChebyshevApproximation(
    function: (x, _) => Math.Sin(50 * x[0]),
    numDimensions: 1,
    domain: new[] { new[] { -1.0, 1.0 } },
    nNodes: null,
    errorThreshold: 1e-12,
    maxN: 16);
cheb.Build();
if (cheb.BuildWarning != null) Console.Error.WriteLine(cheb.BuildWarning);