Table of Contents

Sliding Technique

The Sliding Technique enables Chebyshev approximation of high-dimensional functions by decomposing them into a sum of low-dimensional interpolants. This sidesteps the curse of dimensionality at the cost of losing cross-group interactions.

Motivation

A full tensor Chebyshev interpolant on \(n\) dimensions with \(m\) nodes per dimension requires \(m^n\) function evaluations. For \(n = 10\) and \(m = 11\), that is over 25 billion evaluations — clearly infeasible.

The sliding technique partitions the dimensions into small groups and builds a separate Chebyshev interpolant (a slide) for each group, with all other dimensions fixed at a pivot point. The source-function call count becomes one pivot evaluation plus the sum of the group grid sizes, rather than the full tensor product.

Algorithm

Given a function \(f: \mathbb{R}^n \to \mathbb{R}\), a pivot point \(\mathbf{z} = (z_1, \ldots, z_n)\), and a partition of dimensions into \(k\) groups [3, Ch. 7]:

  1. Evaluate the pivot value \(v = f(\mathbf{z})\).
  2. For each group \(i\), build a slide \(s_i\) — a ChebyshevApproximation on the group's dimensions, with all other dimensions fixed at their pivot values.
  3. Evaluate using the additive formula:
\[ f(\mathbf{x}) \approx v + \sum_{i=1}^{k} \bigl[ s_i(\mathbf{x}_{G_i}) - v \bigr] \]

where \(\mathbf{x}_{G_i}\) denotes the components of \(\mathbf{x}\) belonging to group \(i\). Equivalently, this is \(\sum_i s_i(\mathbf{x}_{G_i}) - (k-1)v\).

This is a first-order anchored decomposition over the chosen groups. Related anchored-ANOVA work shows that the anchor point can strongly affect accuracy [4], so treat pivotPoint as a modelling choice and validate points away from that pivot.

Mental model

full point x = [x0 x1 | x2 x3 | x4 x5]
                 slide 0   slide 1   slide 2

pivot z fixes every coordinate outside the active slide.
Each slide learns how its own group changes the pivot value.
The final value adds those group effects together.

This is why Slider is fast: the build cost is a sum of group grids. It is also why Slider is a modelling approximation: interactions between two different groups are not represented.

Additive 3D example

For a separable function such as:

\[ f(x_1, x_2, x_3) = \sin(x_1) + \cos(x_2) + \tan(x_3) \]

use a domain that stays away from the singularities of tan, for example [-1, 1] in each dimension. With pivot \(\mathbf{z} = (0, 0, 0)\) and singleton partition [[0], [1], [2]], Slider does not build one 3D tensor. It builds three 1D Chebyshev interpolants:

s1(x1): vary x1, hold x2 = 0, x3 = 0
s2(x2): vary x2, hold x1 = 0, x3 = 0
s3(x3): vary x3, hold x1 = 0, x2 = 0

The stored pivot value is:

\[ v = f(0, 0, 0) \]

After fitting, evaluating at \((a, b, c)\) means:

\[ f(a,b,c) \approx v + [s_1(a)-v] + [s_2(b)-v] + [s_3(c)-v] \]

or equivalently:

\[ f(a,b,c) \approx s_1(a) + s_2(b) + s_3(c) - 2v \]

So with 20 nodes per dimension:

Dense 3D Chebyshev tensor: 20 * 20 * 20 = 8,000 source calls
Slider singleton slides:   20 + 20 + 20 + 1 pivot = 61 source calls

For this additive function, the singleton partition matches the function structure. The remaining error is ordinary 1D Chebyshev interpolation error inside sin, cos, and tan. If the function were \(\sin(x_1 x_2) + \tan(x_3)\) instead, singleton slides would miss the \(x_1 x_2\) coupling; use partition [[0, 1], [2]] or compare against ChebyshevTT.

When to Use Sliding

Sliding works well when:

  • The function is additively separable or nearly so (e.g., \(\sin(x_1) + \sin(x_2) + \sin(x_3)\)).
  • Cross-group interactions are weak relative to within-group effects.
  • The number of dimensions is too large for full tensor interpolation (say, \(n > 6\)).

Sliding does not work well when:

  • Variables in different groups are strongly coupled (e.g., Black-Scholes where \(S\), \(T\), and \(\sigma\) interact multiplicatively).
  • High accuracy is required far from the pivot point.

Alternative: Tensor Train. For general (non-separable) high-dimensional functions, consider ChebyshevTT. TT-Cross captures cross-variable coupling that the sliding decomposition misses, at the cost of using finite differences for derivatives instead of analytical spectral differentiation. See Tensor Train Interpolation.

Choosing a Partition

The partition is part of the model, not just a performance setting. Use this workflow before trusting a slider in production:

  1. Start from domain knowledge. Put variables with known multiplicative, nonlinear, or regime-dependent interactions in the same group.
  2. Keep groups as small as accuracy allows. A group with dimensions (0, 1, 2) costs n0 * n1 * n2 evaluations for that slide.
  3. Validate away from the pivot, especially near corners where several groups move at once.
  4. If held-out error is high but each slide's ErrorEstimate() is low, suspect missing cross-group interaction and regroup variables.
  5. If regrouping makes one group too large, compare against ChebyshevTT, which can represent general coupling with adaptive rank instead of an explicit partition.

For example, if \(f = x_1^3 x_2^2 + x_3\), group \((x_1, x_2)\) in one slide and \(x_3\) in another.

Usage

Basic construction

using ChebyshevSharp;

// Additively separable function
double MyFunc(double[] x, object? _)
    => Math.Sin(x[0]) + Math.Sin(x[1]) + Math.Sin(x[2]);

var slider = new ChebyshevSlider(
    function: MyFunc,
    numDimensions: 3,
    domain: new[] { new[] { -1.0, 1.0 }, new[] { -1.0, 1.0 }, new[] { -1.0, 1.0 } },
    nNodes: new[] { 11, 11, 11 },
    partition: new[] { new[] { 0 }, new[] { 1 }, new[] { 2 } },  // each dim is its own slide
    pivotPoint: new[] { 0.0, 0.0, 0.0 }
);
slider.Build();

// Evaluate function value
double val = slider.Eval(new[] { 0.5, 0.3, -0.2 }, new[] { 0, 0, 0 });

// Evaluate derivative w.r.t. x0
double dfdx0 = slider.Eval(new[] { 0.5, 0.3, -0.2 }, new[] { 1, 0, 0 });

Multi-dimensional slides

For functions with within-group coupling, use larger groups:

double G(double[] x, object? _)
    => Math.Pow(x[0], 3) * Math.Pow(x[1], 2) + Math.Sin(x[2]) + Math.Sin(x[3]);

var slider = new ChebyshevSlider(
    function: G,
    numDimensions: 4,
    domain: new[] { new[] { -2.0, 2.0 }, new[] { -2.0, 2.0 },
                    new[] { -1.0, 1.0 }, new[] { -1.0, 1.0 } },
    nNodes: new[] { 12, 12, 8, 8 },
    partition: new[] { new[] { 0, 1 }, new[] { 2 }, new[] { 3 } },  // 2D + 1D + 1D
    pivotPoint: new[] { 0.0, 0.0, 0.0, 0.0 }
);
slider.Build();

Build cost comparison

// Full tensor: 12 * 12 * 8 * 8 = 9,216 evaluations
// Sliding slides: 12*12 + 8 + 8 = 160 slide-grid evaluations
// Build also evaluates the pivot once, so source calls are 161.
Console.WriteLine($"Slider build evaluations: {slider.TotalBuildEvals}");

TotalBuildEvals reports only the slide-grid evaluations. Add one more source call for the pivot value when estimating total build-time calls to your function.

Validate the partition

Always compare the slider against the original function on points that were not used during the build. Test points that move several groups at once, because those are the cases most likely to expose missing cross-group terms:

double maxAbs = 0.0;
var rng = new Random(123);

for (int i = 0; i < 100; i++)
{
    double[] p = new double[4];
    for (int d = 0; d < 4; d++)
    {
        double lo = slider.Domain[d][0], hi = slider.Domain[d][1];
        p[d] = lo + (hi - lo) * rng.NextDouble();
    }

    double exact = G(p, null);
    double approx = slider.Eval(p, new[] { 0, 0, 0, 0 });
    maxAbs = Math.Max(maxAbs, Math.Abs(approx - exact));
}

Console.WriteLine($"held-out max abs error = {maxAbs:E2}");
Console.WriteLine($"slide interpolation diagnostic = {slider.ErrorEstimate():E2}");

The runnable examples/SliderPartitionValidation project compares a good pairwise partition with an intentionally weak singleton partition. It is the best starting point for adapting this validation pattern.

Multi-output evaluation

Compute function value and derivatives at the same point:

double[] results = slider.EvalMulti(
    new[] { 0.5, 0.3, -0.2, 0.1 },
    new[] {
        new[] { 0, 0, 0, 0 },  // function value
        new[] { 1, 0, 0, 0 },  // d/dx0
        new[] { 0, 0, 1, 0 },  // d/dx2
    }
);

EvalMulti is a convenience API for requesting several derivative orders with one validation pass. Unlike dense VectorizedEvalMulti, it evaluates each requested order through the relevant slide rather than sharing a full-tensor barycentric contraction.

Derivatives

The slider supports analytical derivatives through its slides. Only the slide containing the differentiated dimension contributes:

\[ \frac{\partial}{\partial x_j} f(\mathbf{x}) \approx \frac{\partial}{\partial x_j} s_i(\mathbf{x}_{G_i}) \]

where \(j \in G_i\). The pivot value \(v\) is constant and drops out.

Cross-group derivatives are zero

Because slides are independent functions of disjoint variable groups, mixed partial derivatives across groups are exactly zero. For example, with partition [[0, 1], [2]]:

  • \(\frac{\partial^2 f}{\partial x_0 \partial x_1}\) — computed within the [0, 1] slide (correct)
  • \(\frac{\partial^2 f}{\partial x_0 \partial x_2}\) — returns 0 (\(x_0\) and \(x_2\) are in different slides)

This is mathematically correct for the sliding approximation, but may differ from the true function's cross-derivatives. If cross-group sensitivities matter, group those variables together or use full tensor interpolation.

Error Estimation

ErrorEstimate() returns the sum of per-slide Chebyshev error estimates. This measures the interpolation error within each slide but does not capture the cross-group interaction error inherent in the sliding decomposition.

double err = slider.ErrorEstimate();

For exactly additively separable functions, this is the relevant interpolation diagnostic. For coupled functions, the actual error may be larger because the decomposition itself cannot represent cross-group interaction terms.

Accuracy near and far from pivot

The sliding approximation is usually most accurate near the pivot point. As the evaluation point moves away from the pivot in multiple groups simultaneously, cross-coupling errors can accumulate. Always validate with held-out points, especially near domain boundaries and in regions where several grouped variables move together.

Serialization

ChebyshevSlider supports Save and Load with the same JSON format used by the other classes:

slider.Save("slider.json");
var loaded = ChebyshevSlider.Load("slider.json");

The loaded slider is fully functional for evaluation, derivatives, error estimation, integration, roots/optimization, extrusion, slicing, and arithmetic. The original function reference is not retained (Function is null after load).

Extrusion and Slicing

ChebyshevSlider supports the same Extrude and Slice operations as ChebyshevApproximation and ChebyshevSpline.

Extrude adds new dimensions as singleton slide groups with constant tensor values equal to PivotValue. The new dimension contributes nothing to the sliding sum:

var slider4d = slider3d.Extrude((3, new[] { 0.0, 5.0 }, 9));

Slice fixes a dimension at a specific value, reducing dimensionality. For single-dimension groups, the slide is evaluated and absorbed into the remaining slides. For multi-dimension groups, the underlying ChebyshevApproximation is sliced:

var slider2d = slider3d.Slice((0, 0.5));

See Advanced Usage for more on extrusion and slicing.

Arithmetic Operators

Sliders on the same grid support pointwise arithmetic:

var sum    = slider1 + slider2;
var diff   = slider1 - slider2;
var neg    = -slider1;
var scaled = slider1 * 2.0;
var halved = slider1 / 2.0;

Both operands must have the same dimensions, domain, node counts, partition, and pivot point. The result's PivotValue is computed from the operands' pivot values (e.g., addition adds them).

Choosing the Right Class

Scenario Class Build Cost
Smooth function, low dimensions (1--5D) ChebyshevApproximation \(\prod_i n_i\)
Function with discontinuities/singularities ChebyshevSpline \(\text{pieces} \times \prod_i n_i\)
High dimensions, additively separable ChebyshevSlider \(1 + \sum_g \prod_{i \in g} n_i\) source calls
High dimensions, general coupling ChebyshevTT \(O(d \cdot n \cdot r^2)\)

Method availability. ChebyshevSlider does not support Nodes(), FromValues(), or EvalBatch(). It does support integration, roots, minimization, and maximization. Roots and optimization slice the slider to a 1-D proxy before delegating to the standard Chebyshev calculus routines.

References

  1. Trefethen, L. N. (2013). Approximation Theory and Approximation Practice. SIAM.
  2. Berrut, J.-P. & Trefethen, L. N. (2004). "Barycentric Lagrange Interpolation." SIAM Review 46(3):501-517.
  3. Ruiz, I. & Zeron, M. (2022). Machine Learning for Risk Calculations: A Practitioner's View. Wiley Finance.
  4. Zhang, Z., Choi, M. & Karniadakis, G. E. (2011). "Anchor Points Matter in ANOVA Decomposition." In Spectral and High Order Methods for Partial Differential Equations, Lecture Notes in Computational Science and Engineering 76, 347-355.