Cubic Splines in C# QuickStart Sample
Illustrates using natural and clamped cubic splines for interpolation using classes in the Numerics.NET.LinearAlgebra namespace in C#.
This sample is also available in: Visual Basic, F#, IronPython.
Overview
This QuickStart sample demonstrates how to create and work with cubic splines in Numerics.NET. Cubic splines provide smooth interpolation through a set of data points by constructing piecewise cubic polynomials.
The sample shows several key aspects of working with splines:
- Creating natural splines with zero second derivatives at endpoints
- Creating clamped splines with specified slopes at endpoints
- Creating Akima splines that minimize oscillations
- Creating Hermite splines with specified derivatives at each point
- Accessing and modifying spline parameters
- Evaluating splines and their derivatives at arbitrary points
- Finding tangent lines and computing definite integrals
- Working with the piecewise nature of spline curves
Through practical code examples, you’ll learn how to choose appropriate spline types for different interpolation needs and how to use the key methods and properties of the CubicSpline class. The sample includes examples of both basic usage and more advanced features like derivative calculation and integration.
The code
using System;
// The CubicSpline class resides in the
// Numerics.NET.Curves namespace.
using Numerics.NET.Curves;
// Illustrates creating natural and clamped cubic splines using
// the CubicSpline class in the Numerics.NET.Curves
// namespace.
// The license is verified at runtime. We're using
// a 30 day trial key here. For more information, see
// https://numerics.net/trial-key
Numerics.NET.License.Verify("your-trial-key-here");
// A cubic spline is a piecewise curve that is made up
// of pieces of cubic polynomials. Its value as well as its first
// derivative are continuous, giving it a smooth appearance.
//
// Cubic splines are implemented by the CubicSpline class,
// which inherits from PiecewiseCurve.
//
// For an example of piecewise constant and piecewise
// linear curves, see the PiecewiseCurves QuickStart
// Sample.
//
//
// Creating Cubic Splines
//
// In order to define a spline curve completely, two extra
// conditions must be imposed.
// 'Natural' splines have zero second derivatives at the
// end points. This is the default.
// The data points are specified as double arrays containing
// the x and y values:
double[] xValues = {1, 2, 3, 4, 5, 6};
double[] yValues = {1, 3, 4, 3, 4, 2};
CubicSpline naturalSpline = new CubicSpline(xValues, yValues);
// There is also a static method that constructs natural splines:
naturalSpline = CubicSpline.CreateNatural(xValues, yValues);
// 'Clamped' splines have a fixed slope or first derivative at the
// leftmost and rightmost points. The slopes are specified as
// two extra parameters in the constructor:
CubicSpline clampedSpline = new CubicSpline(xValues, yValues, -1, 1);
// Here is the factory method:
clampedSpline = CubicSpline.CreateClamped(xValues, yValues, -1, 1);
// 'Akima' splines minimize the oscillations in the interpolating
// curve. The constructor takes an extra argument of type
// CubicSplineKind:
CubicSpline akimaSpline = new CubicSpline(xValues, yValues, CubicSplineKind.Akima);
// The factory method does not require the extra parameter:
akimaSpline = CubicSpline.CreateAkima(xValues, yValues);
// Hermite splines have fixed values for the first derivative at each
// data point. The first derivatives must be supplied as an array
// or list:
double[] yPrimeValues = { 0, 1, -1, 1, 0, -1 };
CubicSpline hermiteSpline = new CubicSpline(xValues, yValues, yPrimeValues);
// Likewise for the factory method:
hermiteSpline = CubicSpline.CreateHermiteInterpolant(xValues, yValues, yPrimeValues);
//
// Curve Parameters
//
// The shape of any curve is determined by a set of parameters.
// These parameters can be retrieved and set through the
// Parameters collection. The number of parameters for a curve
// is given by this collection's Count property.
//
// Cubic splines have 2n+2 parameters, where n is the number of
// data points. The first n parameters are the x-values. The next
// n parameters are the y-values. The last two parameters are
// the values of the derivative at the first and last point. For natural
// splines, these parameters are unused.
Console.WriteLine("naturalSpline.Parameters.Count = {0}",
naturalSpline.Parameters.Count);
// Parameters can easily be retrieved:
Console.WriteLine("naturalSpline.Parameters[0] = {0}",
naturalSpline.Parameters[0]);
// Parameters can also be set:
naturalSpline.Parameters[0] = 1;
//
// Piecewise curve methods and properties
//
// The NumberOfIntervals property returns the number of subintervals
// on which the curve has unique definitions.
Console.WriteLine("Number of intervals: {0}",
naturalSpline.NumberOfIntervals);
// The IndexOf method returns the index of the interval
// that contains a specific value.
Console.WriteLine($"naturalSpline.IndexOf(1.4) = {naturalSpline.IndexOf(1.4)}");
// The method returns -1 when the value is smaller than the lower bound
// of the first interval, and NumberOfIntervals if the value is equal to or larger than
// the upper bound of the last interval.
//
// Curve Methods
//
// The ValueAt method returns the y value of the
// curve at the specified x value:
Console.WriteLine($"naturalSpline.ValueAt(2.4) = {naturalSpline.ValueAt(2.4)}");
// The SlopeAt method returns the slope of the curve
// a the specified x value:
Console.WriteLine($"naturalSpline.SlopeAt(2) = {naturalSpline.SlopeAt(2)}");
// You can verify that the clamped spline has the correct slope at the end points:
Console.WriteLine($"clampedSpline.SlopeAt(1) = {clampedSpline.SlopeAt(1)}");
Console.WriteLine($"clampedSpline.SlopeAt(6) = {clampedSpline.SlopeAt(6)}");
// Cubic splines do not have a defined derivative. The GetDerivative method
// returns a GeneralCurve:
Curve derivative = naturalSpline.GetDerivative();
Console.WriteLine($"Type of derivative: {derivative.GetType().ToString()}");
Console.WriteLine($"derivative(2) = {derivative.ValueAt(2)}");
// You can get a Line that is the tangent to a curve
// at a specified x value using the TangentAt method:
Polynomial tangent = clampedSpline.TangentAt(2);
Console.WriteLine("Slope of tangent line at 2 = {0}",
tangent.Parameters[1]);
// The integral of a spline curve can be calculated exactly. This technique is
// often used to approximate the integral of a tabulated function:
Console.WriteLine("Integral of naturalSpline between 1.4 and 4.6 = {0}",
naturalSpline.Integral(1.4, 4.6));
Console.Write("Press Enter key to exit...");
Console.ReadLine();