Interpolation

The Interpolation class provides static methods for fast, one-dimensional interpolation of tabulated data. It offers two complementary approaches: quick methods for single-point evaluation, and curve generator factories for reusable interpolating curves.

Quick Methods vs. Curve Generators

The Interpolation class provides two ways to interpolate data, each suited to different scenarios:

Comparison of interpolation approaches

Aspect

Quick Methods

Curve Generators

Use case

Single-point evaluation

Repeated evaluations, resampling

Performance

No allocations, fast for one-off queries

Reusable object, efficient for multiple queries

Capabilities

Evaluation only

Evaluation, derivatives, integration, resampling

Example method

Linear(Double[], Double[], Double, ExtrapolationMode, Double)

PiecewiseLinearCurve(Double[], Double[])

Quick Methods are ideal when you need to interpolate at a single point without storing a curve object. They operate directly on arrays and perform no allocations. Examples include Linear, Cubic, and Nearest.

The following example demonstrates basic quick method usage:

C#
// Define some data points
double[] x = new double[] { 0.0, 1.0, 2.0, 3.0 };
double[] y = new double[] { 0.0, 2.0, 4.0, 3.0 };

// Linear interpolation at x=1.5
double yq1 = Numerics.NET.Interpolation.Linear(x, y, 1.5);
Console.WriteLine($"Linear interpolation at x=1.5: {yq1}");

Quick methods also support different out-of-range behaviors through the ExtrapolationMode parameter:

C#
// Handling out-of-range values with different modes
double yq3 = Numerics.NET.Interpolation.Linear(x, y, 3.5, 
    OutOfRangeMode.Clamp);
Console.WriteLine($"Linear with Clamp at x=3.5: {yq3}");

double yq4 = Numerics.NET.Interpolation.Linear(x, y, 3.5, 
    OutOfRangeMode.Fill, fillValue: -1.0);
Console.WriteLine($"Linear with Fill at x=3.5: {yq4}");

Curve Generators create reusable curve objects that can be evaluated at multiple points efficiently. They also support additional operations like differentiation, integration, and bulk resampling. Examples include PiecewiseLinearCurve(Double[], Double[]), CubicSpline(Double[], Double[]), and MonotoneCubicSpline(Double[], Double[]).

This example shows how to create a reusable cubic spline curve and evaluate it at multiple points:

C#
// Define some data points
double[] x = new double[] { 0.0, 1.0, 2.0, 3.0, 4.0 };
double[] y = new double[] { 0.0, 2.0, 4.0, 3.0, 5.0 };

// Create a reusable cubic spline curve
CubicSpline spline = Numerics.NET.Interpolation.CubicSpline(x, y);

// Evaluate at multiple points
double y1 = spline.ValueAt(1.5);
double y2 = spline.ValueAt(2.5);
Console.WriteLine($"Spline at x=1.5: {y1}, at x=2.5: {y2}");

Curves can be efficiently resampled at many query points using the Resample(IInterpolator, Double[]) method:

C#
// Resample at many points efficiently
double[] xq = new double[] { 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5 };
double[] ys = Numerics.NET.Interpolation.Resample(spline, xq);
Console.WriteLine("Resampled values:");
for (int i = 0; i < xq.Length; i++)
{
    Console.WriteLine($"  x={xq[i]}: y={ys[i]:F4}");
}

Coordinate Transformations

The PiecewiseInterpolatingCurve class supports interpolation in transformed coordinate spaces. This is useful for data that varies exponentially, sigmoidally, or follows other nonlinear relationships.

The following transform modes are available through specialized factory methods:

Coordinate transformation modes

Transform

Factory Method

Use Case

Log-linear

LogLinearCurve(Double[], Double[])

Data varying logarithmically with x (e.g., frequency response)

Log-log

LogLogCurve(Double[], Double[])

Power-law relationships (y ∝ xk)

Logit-linear

LogitLinearCurve(Double[], Double[])

Probability data, sigmoid relationships (y ∈ (0,1))

Decibel (amplitude)

DecibelAmplitudeCurve(Double[], Double[])

Audio and signal processing (20×log₁₀)

Decibel (power)

DecibelPowerCurve(Double[], Double[])

Power measurements (10×log₁₀)

Transformations are applied once during construction, and the inverse transformation is applied during evaluation. This ensures that interpolation is performed in the appropriate space while input and output remain in the original units.

The following example demonstrates log-linear interpolation for frequency response data:

C#
// Example: Frequency response data (log-spaced frequencies)
double[] frequencies = new double[] { 1.0, 10.0, 100.0, 1000.0 };
double[] gains = new double[] { 10.0, 50.0, 200.0, 1000.0 };

// Create a log-linear curve (linear in log-frequency space)
PiecewiseInterpolatingCurve curve = 
    Numerics.NET.Interpolation.LogLinearCurve(frequencies, gains);

// Interpolate at intermediate frequency
double gainAt50Hz = curve.ValueAt(50.0);
Console.WriteLine($"Gain at 50 Hz: {gainAt50Hz:F2}");

For power-law relationships where both axes should be logarithmic, use log-log interpolation:

C#
// For log-log (power law relationships)
double[] x = new double[] { 1.0, 10.0, 100.0 };
double[] y = new double[] { 1.0, 100.0, 10000.0 }; // y = x^2

PiecewiseInterpolatingCurve logLogCurve = 
    Numerics.NET.Interpolation.LogLogCurve(x, y);

double yAt5 = logLogCurve.ValueAt(5.0);
Console.WriteLine($"Log-log interpolation at x=5: {yAt5:F2}");

Periodic Interpolation

Periodic interpolation is useful for data that repeats with a fixed period, such as daily temperature cycles, seasonal patterns, or angular positions in rotating machinery.

The PeriodicLinearCurve(Double[], Double[], Double) method creates a curve that wraps query points modulo the specified period. Values outside the initial range [x₀, x₀ + period) are automatically mapped back into range before interpolation. The curve is seamless at the period boundaries.

  Note

For periodic data, ensure that the first and last y-values are equal (or nearly equal) to avoid discontinuities at the seam.

The following example demonstrates periodic interpolation for a daily temperature cycle:

C#
// Example: Temperature variation over 24 hours
double[] times = new double[] { 0, 6, 12, 18, 24 };
double[] temperatures = new double[] { 10, 8, 20, 15, 10 };

// Create a periodic curve with period=24 hours
PiecewiseInterpolatingCurve curve = 
    Numerics.NET.Interpolation.PeriodicLinearCurve(
        times, temperatures, period: 24.0);

// Query at various times - automatically wraps
double temp0 = curve.ValueAt(0);
double temp24 = curve.ValueAt(24);  // Same as at 0
double temp30 = curve.ValueAt(30);  // Wraps to hour 6

Console.WriteLine($"Temperature at hour 0: {temp0}°C");
Console.WriteLine($"Temperature at hour 24: {temp24}°C");
Console.WriteLine($"Temperature at hour 30: {temp30}°C");

Circular (Angular) Interpolation

Circular interpolation handles angular data correctly by accounting for the wraparound at 360° (or 2π radians). This prevents interpolation artifacts when angles cross the discontinuity boundary.

The CircularLinearCurve(Double[], Double[], Boolean) method creates a curve that unwraps angles during construction to minimize discontinuities, then wraps the interpolated result back to the standard range. This produces smooth interpolation across angle boundaries (e.g., from 359° to 1°).

Common applications include:

  • Compass headings and wind directions

  • Phase angles in signal processing

  • Rotational positions and orientations

  • Periodic angular measurements

The following example demonstrates circular interpolation for wind direction data that crosses the 360°/0° boundary:

C#
// Example: Wind direction over time
// Angles cross the 360°/0° boundary
double[] times = new double[] { 0, 1, 2, 3, 4 };
double[] headings = new double[] { 350, 355, 5, 10, 15 };

// Create a circular curve for angles in degrees
PiecewiseInterpolatingCurve curve = 
    Numerics.NET.Interpolation.CircularLinearCurve(
        times, headings, degrees: true);

// Interpolate at intermediate time
// This correctly interpolates across the 360°/0° boundary
double heading0_5 = curve.ValueAt(0.5);
double heading1_5 = curve.ValueAt(1.5);

Console.WriteLine($"Heading at t=0.5: {heading0_5:F1}°");
Console.WriteLine($"Heading at t=1.5: {heading1_5:F1}°");

Inverse Interpolation

Inverse interpolation finds the x-coordinate corresponding to a given y-value. This is useful for finding thresholds, solving equations, and reversing functional relationships.

For strictly monotone data, use InverseLinear(Double[], Double[], Double), which uses efficient binary search.

For non-monotone data where multiple solutions may exist, use:

The following example demonstrates inverse interpolation for monotone data:

C#
// Example: Find x for a given y
double[] x = new double[] { 0, 1, 2, 3, 4 };
double[] y = new double[] { 0, 2, 5, 7, 10 };

// Find x where y=6 (monotone data)
double xAtY6 = Numerics.NET.Interpolation.InverseLinear(x, y, 6.0);
Console.WriteLine($"x where y=6: {xAtY6:F4}");

For non-monotone data, use specialized methods to select which solution to return:

C#
// For non-monotone data, use specialized methods
double[] xNonMono = new double[] { 0, 1, 2, 3, 4 };
double[] yNonMono = new double[] { 0, 3, 1, 4, 2 };

// Find the x closest to 2.5 where y=2
double xNear = Numerics.NET.Interpolation.InverseLinearNear(
    xNonMono, yNonMono, y: 2.0, x: 2.5);
Console.WriteLine($"x nearest to 2.5 where y=2: {xNear:F4}");

Quick Methods and Curve Generator Mapping

Multidimensional Interpolation (2D and Beyond)

In addition to one-dimensional interpolation, the Interpolation class provides factory methods for interpolating functions of two or more variables. There are two main approaches depending on the structure of your data:

Grid-Based Interpolation

When data is sampled on a rectilinear grid (structured, axis-aligned), use grid-based interpolation methods. These are highly efficient and support various interpolation schemes including nearest-neighbor, linear (multilinear), and cubic spline interpolation.

The Interpolation class provides factory methods for creating grid interpolators:

  • GridNearestInterpolator – Nearest-neighbor interpolation on N-dimensional grids

  • GridLinearInterpolator – Multilinear interpolation (bilinear in 2D, trilinear in 3D, etc.)

  • GridCubicInterpolator(IReadOnlyList<IReadOnlyList<Double>>, IReadOnlyList<Double>, ExtrapolationMode) – Cubic spline interpolation for 2D and 3D grids

  • GridCubicTensorSplineInterpolator(IReadOnlyList<IReadOnlyList<Double>>, IReadOnlyList<Double>, ExtrapolationMode) – General tensor-product cubic spline interpolation for any dimension

Grid interpolation is ideal for image processing, volumetric data, lookup tables, and any data naturally aligned with coordinate axes. For more details on grid interpolation methods, boundary conditions, and examples, see Interpolation on Rectilinear Grids.

Scattered Data Interpolation

When data points are irregularly distributed and not aligned to a grid, use scattered data interpolation methods. These methods work with arbitrary point locations in 2D or higher dimensions.

The Interpolation class provides factory methods for scattered interpolation:

  • ScatteredNearestInterpolator – Nearest-neighbor interpolation for scattered points in any dimension

  • ScatteredRbfInterpolator(Matrix<Double>, Vector<Double>, RbfOptions) – Radial basis function (RBF) interpolation for smooth approximation in any dimension

  • ScatteredLinear2DInterpolator – Delaunay triangulation-based linear interpolation for 2D scattered data

Scattered interpolation is useful for sensor data, GPS measurements, weather station observations, and any irregularly sampled data. For more information on scattered interpolation methods and examples, see Interpolation of Scattered Data.

See Also