Class ChebyshevSpline
- Namespace
- ChebyshevSharp
- Assembly
- ChebyshevSharp.dll
Piecewise Chebyshev interpolation with user-specified knots. Partitions the domain into sub-intervals at interior knots and builds an independent ChebyshevApproximation on each piece. Query points are routed to the appropriate piece for evaluation.
public class ChebyshevSpline
- Inheritance
-
ChebyshevSpline
- Inherited Members
Remarks
This is the correct approach when the target function has known singularities (kinks, discontinuities) at specific locations: place knots at those locations so that each piece is smooth, restoring spectral convergence.
Constructors
ChebyshevSpline(Func<double[], object?, double>, int, double[][], int[], double[][], int, object?, bool, int?, IProgress<int>?)
Create a new ChebyshevSpline.
public ChebyshevSpline(Func<double[], object?, double> function, int numDimensions, double[][] domain, int[] nNodes, double[][] knots, int maxDerivativeOrder = 2, object? additionalData = null, bool deferBuild = false, int? nWorkers = null, IProgress<int>? progress = null)
Parameters
functionFunc<double[], object, double>Function to approximate: f(point, data) -> double.
numDimensionsintNumber of input dimensions.
domaindouble[][]Bounds for each dimension as double[ndim][2].
nNodesint[]Number of Chebyshev nodes per dimension per piece.
knotsdouble[][]Interior knots for each dimension. Empty array for no knots.
maxDerivativeOrderintMaximum derivative order to support (default 2).
additionalDataobjectOptional user data object threaded through every f(point, data) call during Build.
deferBuildboolIf true, skip eager build. Call SetOriginalFunctionValues(double[]) to finish construction.
nWorkersint?Number of parallel workers for function evaluation. null = sequential; -1 = ProcessorCount; positive = exact count.
progressIProgress<int>Optional progress reporter; receives cumulative evaluation count across all pieces.
Remarks
Thread safety: the user-supplied function must be thread-safe when nWorkers is non-null.
ChebyshevSpline(Func<double[], object?, double>, int, double[][], int[][], double[][], int, object?, bool, int?, IProgress<int>?)
Create a piecewise Chebyshev spline with per-sub-interval node counts.
public ChebyshevSpline(Func<double[], object?, double> function, int numDimensions, double[][] domain, int[][] nNodesNested, double[][] knots, int maxDerivativeOrder = 2, object? additionalData = null, bool deferBuild = false, int? nWorkers = null, IProgress<int>? progress = null)
Parameters
functionFunc<double[], object, double>Function to approximate.
numDimensionsintNumber of input dimensions.
domaindouble[][]Bounds per dimension.
nNodesNestedint[][]Nested array: nNodesNested[d][i] is the node count for piece i along dim d. Length per dim must equal knots[d].Length + 1.
knotsdouble[][]Interior knots per dimension. Required (no default) when using nested form.
maxDerivativeOrderintMaximum derivative order to support (default 2).
additionalDataobjectOptional user data object threaded through every f(point, data) call during Build.
deferBuildboolIf true, skip eager build. Call SetOriginalFunctionValues(double[]) to finish construction.
nWorkersint?Number of parallel workers for function evaluation. null = sequential; -1 = ProcessorCount; positive = exact count.
progressIProgress<int>Optional progress reporter; receives cumulative evaluation count across all pieces.
Remarks
Thread safety: the user-supplied function must be thread-safe when nWorkers is non-null.
ChebyshevSpline(Func<double[], object?, double>, int, double[][], int?[]?, double[][]?, double?, int, int, object?, bool, int?, IProgress<int>?)
Create a piecewise Chebyshev spline with optional error-driven auto-N construction.
public ChebyshevSpline(Func<double[], object?, double> function, int numDimensions, double[][] domain, int?[]? nNodes = null, double[][]? knots = null, double? errorThreshold = null, int maxN = 64, int maxDerivativeOrder = 2, object? additionalData = null, bool deferBuild = false, int? nWorkers = null, IProgress<int>? progress = null)
Parameters
functionFunc<double[], object, double>Function to approximate.
numDimensionsintNumber of input dimensions.
domaindouble[][]Bounds per dimension.
nNodesint?[]Number of nodes per dimension; null entries signal auto-N. Pass null to make every dim auto-N (requires errorThreshold).
knotsdouble[][]Interior knots per dimension. Null defaults to empty arrays (single piece per dim).
errorThresholddouble?Finite positive target supremum-norm error per piece. Required if any nNodes entry is null.
maxNintCap on nodes per dimension during the doubling loop (default 64, must be at least 3).
maxDerivativeOrderintMaximum derivative order to support (default 2).
additionalDataobjectOptional user data object threaded through every f(point, data) call during Build.
deferBuildboolIf true, skip eager build. Call SetOriginalFunctionValues(double[]) to finish construction.
nWorkersint?Number of parallel workers for function evaluation. null = sequential; -1 = ProcessorCount; positive = exact count.
progressIProgress<int>Optional progress reporter; receives cumulative evaluation count across all pieces.
Remarks
Thread safety: the user-supplied function must be thread-safe when nWorkers is non-null.
Properties
BuildTime
Wall-clock time (seconds) for the most recent Build() call.
public double BuildTime { get; }
Property Value
Built
Whether Build() has been called.
public bool Built { get; }
Property Value
Domain
Domain bounds for each dimension, as [lo, hi] pairs.
public double[][] Domain { get; }
Property Value
- double[][]
ErrorThreshold
Target supremum-norm error for per-piece auto-N construction. Null in fixed-N mode.
public double? ErrorThreshold { get; }
Property Value
Function
Function used by Build(bool). Null for objects restored from saved numerical state or created by value-based/transformation APIs.
public Func<double[], object?, double>? Function { get; }
Property Value
Knots
Interior knots per dimension. Each sub-array is sorted ascending.
public double[][] Knots { get; }
Property Value
- double[][]
MaxDerivativeOrder
Maximum supported derivative order.
public int MaxDerivativeOrder { get; }
Property Value
MaxN
Maximum nodes per dimension per piece for the auto-N doubling loop. Default 64.
public int MaxN { get; }
Property Value
NNodes
Number of Chebyshev nodes per dimension per piece.
public int[] NNodes { get; }
Property Value
- int[]
NumDimensions
Number of input dimensions.
public int NumDimensions { get; }
Property Value
NumPieces
Total number of pieces (Cartesian product of per-dimension intervals).
public int NumPieces { get; }
Property Value
TotalBuildEvals
Total number of function evaluations used during build.
public int TotalBuildEvals { get; }
Property Value
Methods
AutoKnots(Func<double[], object?, double>, int, double[][], int[], int, object?, string?, double, int, int, int?, IProgress<int>?, bool)
Heuristically place knots at curvature spikes, then build the resulting ChebyshevSpline.
public static ChebyshevSpline AutoKnots(Func<double[], object?, double> function, int numDimensions, double[][] domain, int[] numNodes, int maxOrderDerivative = 2, object? additionalData = null, string? descriptor = null, double thresholdFactor = 5, int maxKnotsPerDim = 5, int nScanPoints = 200, int? nWorkers = null, IProgress<int>? progress = null, bool verbose = false)
Parameters
functionFunc<double[], object, double>f(point, additionalData) → double; must return finite at every scan point.
numDimensionsintNumber of input dimensions.
domaindouble[][]Bounds for each dimension as double[ndim][2].
numNodesint[]Per-piece node counts; same shape as the regular ctor.
maxOrderDerivativeintMax derivative order. Default 2.
additionalDataobjectOptional user data threaded through f calls.
descriptorstringOptional free-form descriptor.
thresholdFactordoubleFinite positive spike threshold factor; threshold = thresholdFactor × mean(|d²f|). Default 5.0.
maxKnotsPerDimintCap on knots per dimension. Default 5. Zero means no auto-knots.
nScanPointsintNumber of scan points per dim. Default 200; must be at least 3.
nWorkersint?See ChebyshevSpline ctor.
progressIProgress<int>See ChebyshevSpline ctor.
verboseboolIf true, print scan progress.
Returns
- ChebyshevSpline
A built ChebyshevSpline with the discovered candidate knots.
Remarks
When nWorkers is non-null, function may be
invoked concurrently from multiple threads. Functions that capture mutable state
must use locks or external synchronization, or pass nWorkers: null.
Build(bool)
Build all pieces by evaluating the function on each sub-domain.
public void Build(bool verbose = true)
Parameters
verboseboolIf true, print build progress.
Exceptions
- InvalidOperationException
If this object has no callable Function.
- ArgumentException
If the function returns NaN or Infinity while building a piece.
Clone()
Returns a deep copy of this spline. The source Function callable is not duplicated; clones cannot be rebuilt without re-supplying the function. All precomputed pieces and state are deep-copied.
public ChebyshevSpline Clone()
Returns
- ChebyshevSpline
A fully independent ChebyshevSpline with Function set to null.
ErrorEstimate()
Estimate the supremum-norm interpolation error. Returns the maximum error estimate across all pieces.
public double ErrorEstimate()
Returns
- double
The maximum per-piece coefficient-decay error estimate.
Exceptions
- InvalidOperationException
If Build(bool) has not been called.
Eval(double[], int)
Evaluate at point using a previously-registered derivative id.
public double Eval(double[] point, int derivativeId)
Parameters
pointdouble[]Evaluation point.
derivativeIdintId returned by GetDerivativeId(int[]).
Returns
- double
Interpolated value at the given derivative order.
Exceptions
- ArgumentOutOfRangeException
Thrown when
derivativeIdhas not been registered.
Eval(double[], int[])
Evaluate the spline approximation at a point.
public double Eval(double[] point, int[] derivativeOrder)
Parameters
pointdouble[]Evaluation point inside the full declared domain.
derivativeOrderint[]Derivative order for each dimension (0 = function value).
Returns
- double
Approximated function value or derivative.
Exceptions
- InvalidOperationException
If Build(bool) has not been called.
- ArgumentException
If the point or derivative-order shape is invalid, or if a derivative is requested exactly at a knot.
- ArgumentOutOfRangeException
If a point coordinate is outside the declared domain or a derivative order exceeds MaxDerivativeOrder.
EvalBatch(double[][], int[])
Evaluate at multiple points, grouping by piece for efficiency.
public double[] EvalBatch(double[][] points, int[] derivativeOrder)
Parameters
pointsdouble[][]Evaluation points inside the declared domain (N x numDimensions).
derivativeOrderint[]Derivative order for each dimension.
Returns
- double[]
Approximated values at each point.
Exceptions
- InvalidOperationException
If Build(bool) has not been called.
- ArgumentException
If any point or derivative-order shape is invalid, or if a derivative is requested exactly at a knot.
- ArgumentOutOfRangeException
If a point coordinate is outside the declared domain or a derivative order exceeds MaxDerivativeOrder.
EvalMulti(double[], int[][])
Evaluate multiple derivative orders at one point, sharing weights.
public double[] EvalMulti(double[] point, int[][] derivativeOrders)
Parameters
pointdouble[]Evaluation point inside the full declared domain.
derivativeOrdersint[][]Each inner array specifies derivative order per dimension.
Returns
- double[]
One result per derivative order.
Exceptions
- InvalidOperationException
If Build(bool) has not been called.
- ArgumentException
If the point or derivative-order shape is invalid, or if a derivative is requested exactly at a knot.
- ArgumentOutOfRangeException
If a point coordinate is outside the declared domain or a derivative order exceeds MaxDerivativeOrder.
Extrude(params (int dimIndex, double[] bounds, int nNodes)[])
Add new dimensions where the function is constant.
public ChebyshevSpline Extrude(params (int dimIndex, double[] bounds, int nNodes)[] extrudeParams)
Parameters
Returns
- ChebyshevSpline
A new, higher-dimensional spline (already built).
FromValues(double[][], int, double[][], int[], double[][], int)
Create a spline from pre-computed function values on each piece.
public static ChebyshevSpline FromValues(double[][] pieceValues, int numDimensions, double[][] domain, int[] nNodes, double[][] knots, int maxDerivativeOrder = 2)
Parameters
pieceValuesdouble[][]Function values for each piece. Length must equal total pieces.
numDimensionsintNumber of dimensions.
domaindouble[][]Lower and upper bounds for each dimension.
nNodesint[]Number of Chebyshev nodes per dimension per piece.
knotsdouble[][]Knot positions for each dimension.
maxDerivativeOrderintMaximum derivative order (default 2).
Returns
- ChebyshevSpline
A fully built spline with no callable source function attached.
Exceptions
- ArgumentException
If the piece count or a piece tensor length does not match the spline grid, or if input values are invalid.
GetAdditionalData()
Returns the user-supplied additionalData object passed to the constructor,
or null if none was provided. Same value is threaded through every f(point, data)
call during Build(bool).
public object? GetAdditionalData()
Returns
GetConstructorType()
Returns one of: "function" (Build), "from_values" (FromValues factory), "load" (Load), or "clone" (Clone).
public string GetConstructorType()
Returns
GetDerivativeId(int[])
Register or look up a derivative-orders tuple. Returns a stable
session-local int id for the same orders. Used in conjunction with
the Eval(point, derivativeId) overload.
public int GetDerivativeId(int[] orders)
Parameters
ordersint[]Derivative order per dimension.
Returns
- int
A stable int id for this orders tuple (0-based, assigned in registration order).
GetDescriptor()
Get the descriptor previously set via SetDescriptor(string); null if unset.
public string? GetDescriptor()
Returns
GetErrorThreshold()
Return the error threshold passed to the constructor, or null in fixed-N mode.
public double? GetErrorThreshold()
Returns
GetEvaluationPoints()
Flat row-major array of all spline piece evaluation points, concatenated sequentially. Length is GetNumEvaluationPoints() * NumDimensions. Result is lazily built and cached internally.
public double[] GetEvaluationPoints()
Returns
- double[]
A snapshot of concatenated piece node coordinates, flattened in row-major order.
GetMaxDerivativeOrder()
Maximum derivative order this spline supports.
public int GetMaxDerivativeOrder()
Returns
GetNumEvaluationPoints()
Total number of evaluation points across all spline pieces.
public int GetNumEvaluationPoints()
Returns
- int
The sum of GetNumEvaluationPoints() from each piece.
GetSpecialPoints()
Get the knots (special points) used for spline construction.
public double[][]? GetSpecialPoints()
Returns
- double[][]
Interior knots per dimension, or null if no interior knots were used.
GetUsedNs()
Per-dimension Chebyshev node counts actually used per piece.
public int[] GetUsedNs()
Returns
- int[]
Integrate(int[]?, (double lo, double hi)[]?)
Integrate the spline over one or more dimensions.
public object Integrate(int[]? dims = null, (double lo, double hi)[]? bounds = null)
Parameters
dimsint[]Dimensions to integrate out. Null = all.
bounds(double lo, double hi)[]Sub-interval bounds per dim. Null = full domain.
Returns
- object
Scalar if all dims integrated, otherwise a lower-dimensional spline.
IsConstructionFinished()
True if Build(bool)/FromValues(double[][], int, double[][], int[], double[][], int)/Load(string) completed.
public bool IsConstructionFinished()
Returns
Load(string)
Load a previously saved spline from a file. Auto-detects binary (.pcb magic) vs JSON format.
public static ChebyshevSpline Load(string path)
Parameters
pathstringPath to the saved file.
Returns
- ChebyshevSpline
The restored spline.
Exceptions
- InvalidDataException
If a .pcb file has a non-spline class tag or if the serialized state is malformed.
Maximize(int?, Dictionary<int, double>?)
Find the maximum value of the spline along a dimension.
public (double value, double location) Maximize(int? dim = null, Dictionary<int, double>? fixedDims = null)
Parameters
dimint?Dimension along which to maximize.
fixedDimsDictionary<int, double>For multi-D, dict of dim_index -> value for all other dims.
Returns
Minimize(int?, Dictionary<int, double>?)
Find the minimum value of the spline along a dimension.
public (double value, double location) Minimize(int? dim = null, Dictionary<int, double>? fixedDims = null)
Parameters
dimint?Dimension along which to minimize.
fixedDimsDictionary<int, double>For multi-D, dict of dim_index -> value for all other dims.
Returns
Nodes(int, double[][], int[], double[][])
Generate Chebyshev nodes for every piece without evaluating any function.
public static SplineNodeInfo Nodes(int numDimensions, double[][] domain, int[] nNodes, double[][] knots)
Parameters
numDimensionsintNumber of dimensions.
domaindouble[][]Lower and upper bounds for each dimension.
nNodesint[]Number of Chebyshev nodes per dimension per piece.
knotsdouble[][]Knot positions for each dimension (may be empty).
Returns
- SplineNodeInfo
A SplineNodeInfo with per-piece node info.
Exceptions
- ArgumentException
If dimensions, domains, knots, or node counts are invalid, or if any piece grid is too large to materialize.
PeekFormatVersion(string)
Read the major version byte of a .pcb binary file without deserializing the body. Useful for forward-compat tooling.
public static int PeekFormatVersion(string path)
Parameters
pathstringPath to a .pcb file.
Returns
- int
The major format version (currently 1).
Exceptions
- FileNotFoundException
Thrown if the path does not exist.
- InvalidDataException
Thrown if the file is not a .pcb file (no magic header) or is shorter than 12 bytes.
Roots(int?, Dictionary<int, double>?)
Find all roots of the spline along a specified dimension.
public double[] Roots(int? dim = null, Dictionary<int, double>? fixedDims = null)
Parameters
dimint?Dimension along which to find roots.
fixedDimsDictionary<int, double>For multi-D, dict of dim_index -> value for all other dims.
Returns
- double[]
Sorted array of root locations.
Save(string, string)
Save the built spline to a file.
public void Save(string path, string format = "json")
Parameters
pathstringDestination file path.
formatstring"json" (default) or "binary". Binary writes the documented .pcb primitive layout and requires shared flat, non-nested nNodes across all pieces.
SetDescriptor(string)
Set a free-form descriptor string for this spline.
public void SetDescriptor(string descriptor)
Parameters
descriptorstring
SetOriginalFunctionValues(double[])
Populate this spline's tensor values from a precomputed flat array.
Used after constructing with deferBuild: true. Uses the same
per-piece construction path as the FromValues factory.
Values are concatenated in flat piece-index C-order: piece 0 values first, then piece 1, etc.
public void SetOriginalFunctionValues(double[] values)
Parameters
valuesdouble[]Flat array concatenating all pieces' values in piece-flat-index order.
Exceptions
- ArgumentNullException
Thrown when
valuesis null.- ArgumentException
Thrown when values length does not match the expected total across all pieces.
- InvalidOperationException
Thrown when the spline is already constructed.
Slice(params (int dimIndex, double value)[])
Fix one or more dimensions at given values, reducing dimensionality.
public ChebyshevSpline Slice(params (int dimIndex, double value)[] sliceParams)
Parameters
Returns
- ChebyshevSpline
A new, lower-dimensional spline (already built).
SobolIndices()
Compute variance-based sensitivity indices aggregated across spline pieces. Per-piece coefficients are computed under the Chebyshev measure on each piece's local domain. The piecewise aggregation includes local polynomial variance, between-piece mean variance, and interactions between interval membership and local Chebyshev modes. For a single-piece spline, this reduces to the SobolIndices() index values.
public SobolResult SobolIndices()
Returns
- SobolResult
A SobolResult with per-dim FirstOrder, TotalOrder, and Chebyshev-weighted global Variance.
Exceptions
- InvalidOperationException
If Build(bool) has not been called.
ToReprString()
Compact string representation.
public string ToReprString()
Returns
ToString()
Returns a string that represents the current object.
public override string ToString()
Returns
- string
A string that represents the current object.
WithSpecialPoints(Func<double[], object?, double>, int, double[][], double[][], int[][]?, int[]?, double?, int, int)
Create a ChebyshevSpline with kinks declared via specialPoints
(a more user-friendly name than knots when the function has known non-smooth points).
Functionally equivalent to passing the same values as knots to a regular constructor.
public static ChebyshevSpline WithSpecialPoints(Func<double[], object?, double> function, int numDimensions, double[][] domain, double[][] specialPoints, int[][]? nNodesNested = null, int[]? nNodes = null, double? errorThreshold = null, int maxN = 64, int maxDerivativeOrder = 2)
Parameters
functionFunc<double[], object, double>Function to approximate.
numDimensionsintNumber of input dimensions.
domaindouble[][]Bounds per dimension.
specialPointsdouble[][]Per-dim list of kink locations. Equivalent to knots; outer length must equal
numDimensions.nNodesNestedint[][]Per-sub-interval node counts (per dim, per piece). Mutually exclusive with
errorThreshold.nNodesint[]Flat per-dim node counts (shared across pieces). Mutually exclusive with
nNodesNestedanderrorThreshold.errorThresholddouble?Finite positive target error per piece. Mutually exclusive with
nNodes/nNodesNested.maxNintCap on doubling-loop nodes per dimension (default 64).
maxDerivativeOrderintMaximum derivative order to support (default 2).
Returns
- ChebyshevSpline
An unbuilt ChebyshevSpline ready for
Build().
Remarks
Declaring special points changes the representation from one dense
tensor to a piecewise spline, so this factory returns an unbuilt
ChebyshevSpline directly. Exactly one of
nNodesNested, nNodes, or
errorThreshold must be supplied.
Operators
operator +(ChebyshevSpline, ChebyshevSpline)
Add two splines with the same grid and knots.
public static ChebyshevSpline operator +(ChebyshevSpline a, ChebyshevSpline b)
Parameters
Returns
operator /(ChebyshevSpline, double)
Divide spline by a scalar.
public static ChebyshevSpline operator /(ChebyshevSpline a, double scalar)
Parameters
aChebyshevSplinescalardouble
Returns
operator *(ChebyshevSpline, double)
Multiply spline by a scalar.
public static ChebyshevSpline operator *(ChebyshevSpline a, double scalar)
Parameters
aChebyshevSplinescalardouble
Returns
operator *(double, ChebyshevSpline)
Multiply scalar by spline.
public static ChebyshevSpline operator *(double scalar, ChebyshevSpline a)
Parameters
scalardoubleaChebyshevSpline
Returns
operator -(ChebyshevSpline, ChebyshevSpline)
Subtract two splines with the same grid and knots.
public static ChebyshevSpline operator -(ChebyshevSpline a, ChebyshevSpline b)
Parameters
Returns
operator -(ChebyshevSpline)
Negate spline.
public static ChebyshevSpline operator -(ChebyshevSpline a)