Extreme Optimization™: Complexity made simple.

Numerical Components
for .NET

  • Home
  • •
  • Features
    • Math Library
    • Vector and Matrix Library
    • Statistics Library
    • Performance
    • Usability
  • •
  • Documentation
    • Introduction
    • Math Library User's Guide
    • Vector and Matrix Library User's Guide
    • Statistics Library User's Guide
    • Reference
  • •
  • Support
    • Frequently Asked Questions
    • QuickStart Samples
    • Sample Applications
    • Downloads
  • •
  • Blog
  • •
  • Company
    • About us
    • Testimonials
    • Customers
    • Press Releases
    • Careers
    • Contact us
Introduction
Expand Mathematics Library User's GuideMathematics Library User's Guide
Expand Vector and Matrix Library User's GuideVector and Matrix Library User's Guide
Expand Statistics Library User's GuideStatistics Library User's Guide
Expand ReferenceReference
  • Home
    • Features
    • Solutions
    • Documentation
    • QuickStart Samples
    • Sample Applications
    • Downloads
    • Technical Support
    • Download trial
    • How to buy
    • Blog
    • Company
    • Resources
  • Documentation
    • Introduction
    • Mathematics Library User's Guide
    • Vector and Matrix Library User's Guide
    • Statistics Library User's Guide
    • Reference
  • Mathematics Library User's Guide
    • General Classes
    • Complex Numbers
    • Arbitrary Precision Arithmetic
    • Curves
    • Curve Fitting
    • Solving Equations
    • Optimization
    • Calculus
    • Fast Fourier Transforms
    • Special Functions
    • Generic Arithmetic
    • Appendices
  • Curves
    • Curve Basics
    • Simple Curves
    • Polynomials
    • Chebyshev Expansions
    • Piecewise Curves and Cubic Splines
    • Comparing Curve classes and RealFunction delegates
  • Piecewise Curves and Cubic Splines
Collapse imageExpand ImageCopy imageCopyHover image
       




Piecewise Curves and Cubic Splines

A piecewise curve is a curve that has a different definition on each of a number of intervals. The Extreme Optimization Mathematics Library for .NET supports piecewise constants, lines, and cubic splines.

The PiecewiseCurve class

The PiecewiseCurve class is the abstract base class for all classes that implement piecewise curves. It defines a number of properties shared by all piecewise curve classes. PiecewiseCurve is itself derived from Curve.

The Degree property specifies the number of pieces that make up the piecewise curve. The x-values that define the boundaries of the pieces are passed to the constructor. The x-values must be listed in ascending order, or an exception will be thrown. Most commonly, the y-values at the boundaries are also specified at the time of construction. An x-value together with its corresponding y-value are called a data point.

A number of methods allow you to get and set the x and y values of an existing piecewise curve. The GetXValue(Int32) and GetYValue(Int32) methods take the zero-based index of the data point and return the specified value. The GetDataPoint(Int32) method does the same and returns a Point structure.

Corresponding to these are SetXValue, SetYValue and SetDataPoint method, which set the x-value, the y-value of both x and y-value of the specified data point to the given value. Care should be taken that the x values remain in ascending order. To set multiple values at once, you can use the SetXValues(array<Int32>[]()[], array<Double>[]()[]), SetYValues(array<Int32>[]()[], array<Double>[]()[]) or SetDataPoints(array<Int32>[]()[], array<Point>[]()[]) method. These methods take two arguments: an integer array of indices, and a Double or Point array. These methods are useful when setting a single x value would cause the x values to be no longer in ascending order.

The Parameters collection of a piecewise curve has a special structure. The first n+1 parameters are the boundaries of the intervals, where n is the number of intervals. The next n+1 values are the y-values corresponding to the boundaries of the interval. Any remaining parameters further define the shape of the curve.

Since PiecewiseCurve is an abstract class, it cannot be instantiated directly. Three classes inherit from PiecewiseCurve, and represent piecewise constant and linear curves, and cubic splines.

Piecewise Constant Curves

The PiecewiseConstantCurve class represents a piecewise constant curve, a curve that is constant over each interval. The curve is left-continuous. This means that on each interval, the function value at the left or lower bound is equal to the constant value over the interval. The function value at the right or upper bound is equal to the value of the curve on the next interval.

The PiecewiseConstantCurve class has three constructors. The first constructor takes two Double arrays as arguments. The first array contains the x-values of the data points. The second array contains the y-values. As mentioned before, the x values must be provided in ascending order. The second constructor takes two Vector objects, with the same meaning as before. The third constructor has only one argument: an array of Point structures. The following example illlustrates the use of these constructors:

C# Copy imageCopy
double[] xValues = {1, 2, 4, 6};
double[] yValues = {1, 3, 4, 2};
PiecewiseConstantCurve constant1 =    new PiecewiseConstantCurve(xValues, yValues);
GeneralVector xVector = Vector.Create(xValues);
GeneralVector yVector = Vector.Create(yValues);
PiecewiseConstantCurve constant2 =    new PiecewiseConstantCurve(xVector, yVector);
Point[] dataPoints = new Point[]
   {new Point(1, 1), new Point(2, 3), new Point(3, 4), 
    new Point(4, 3), new Point(5, 4), new Point(6, 2)};
PiecewiseConstantCurve constant3 =    new PiecewiseConstantCurve(dataPoints);
Visual Basic Copy imageCopy
Dim xValues As Double() = {1, 2, 3, 4, 5, 6}
Dim yValues As Double() = {1, 3, 4, 3, 4, 2}
Dim constant1 As PiecewiseConstantCurve =    New PiecewiseConstantCurve(xValues, yValues)
Dim xVector As GeneralVector = Vector.Create(xValues)
Dim yVector As GeneralVector = Vector.Create(yValues)
Dim constant2 As PiecewiseConstantCurve =    New PiecewiseConstantCurve(xVector, yVector)
Dim dataPoints As Point() = New Point() _
    {New Point(1, 1), New Point(2, 3), New Point(3, 4), _
     New Point(4, 3), New Point(5, 4), New Point(6, 2)}
Dim constant3 As PiecewiseConstantCurve =    New PiecewiseConstantCurve(dataPoints)

PiecewiseConstantCurve implements most methods and properties of the Curve class.

The ValueAt(Double) method returns the value of the curve at a specified point. If the point is the upper bound of an interval, the value is the constant value of the next interval. If the x value is less than the lower bound of the first interval, the value is that of the first interval. If the x value is greater than the upper bound of the last interval, the value is that at the upper bound.

The SlopeAt(Double) method returns the derivative. For most values, it is equal to 0. The only exception is on the boundary of an interval, when the curve is discontinuous. In this case, the result is Double.NaN.

C# Copy imageCopy
Console.WriteLine("constant1.ValueAt(2) = {0}", constant1.ValueAt(2));
Console.WriteLine("constant1.SlopeAt(2) = {0}", constant1.SlopeAt(2));
Visual Basic Copy imageCopy
Console.WriteLine("constant1.ValueAt(2) = {0}", constant1.ValueAt(2))
Console.WriteLine("constant1.SlopeAt(2) = {0}", constant1.SlopeAt(2))

Integral(Double, Double) evaluates the definite integral over a specified interval. The integral is calculated exactly. The GetDerivative()()() method is not available.

Piecewise Linear Curves

The PiecewiseLinearCurve class represents a piecewise linear curve, a curve that interpolates linearly between a set of data points. Linear interpolation of tabulated data is the most common application of piecewise linear curves or functions.

The PiecewiseLinearCurve class has three constructors. The first constructor takes two Double arrays as arguments. The first array contains the x-values of the data points. The second array contains the y-values. As mentioned before, the x values must be provided in ascending order. The second constructor takes two Vector objects, with the same meaning as before. The third constructor has only one argument: an array of Point structures. The following example illlustrates the use of these constructors:

C# Copy imageCopy
double[] xValues = {1, 2, 4, 6};
double[] yValues = {1, 3, 4, 2};
PiecewiseLinearCurve line1 =    new PiecewiseLinearCurve(xValues, yValues);
GeneralVector xVector = Vector.Create(xValues);
GeneralVector yVector = Vector.Create(yValues);
PiecewiseLinearCurve line2 =    new PiecewiseLinearCurve(xVector, yVector);
Point[] dataPoints = new Point[]
   {new Point(1, 1), new Point(2, 3), new Point(3, 4), 
    new Point(4, 3), new Point(5, 4), new Point(6, 2)};
PiecewiseLinearCurve line3 =    new PiecewiseLinearCurve(dataPoints);
Visual Basic Copy imageCopy
Dim xValues As Double() = {1, 2, 3, 4, 5, 6}
Dim yValues As Double() = {1, 3, 4, 3, 4, 2}
Dim line1 As PiecewiseLinearCurve =    New PiecewiseLinearCurve(xValues, yValues)
Dim xVector As GeneralVector = Vector.Create(xValues)
Dim yVector As GeneralVector = Vector.Create(yValues)
Dim line2 As PiecewiseLinearCurve =    New PiecewiseLinearCurve(xVector, yVector)
Dim dataPoints As Point() = New Point() _
    {New Point(1, 1), New Point(2, 3), New Point(3, 4), _
     New Point(4, 3), New Point(5, 4), New Point(6, 2)}
Dim line3 As PiecewiseLinearCurve =    New PiecewiseLinearCurve(dataPoints)

PiecewiseLinearCurve implements most methods and properties of the Curve class.

The ValueAt(Double) method returns the value of the curve at a specified point. The line on the first interval is extended to the left. The line on the last interval is extended to the right. If the x value is less than the lower bound of the first interval, the value is that of the linear function on the first interval extended to the left. If the x value is greater than the upper bound of the last interval, the value is that of the linear function on the last interval extended to the right.

The SlopeAt(Double) method returns the derivative. For most values, it is equal to the slope on the line segment. The only exception is on the boundary of an interval, when the line segments on either side of the point have different slopes. In this case, the result is Double.NaN.

C# Copy imageCopy
Console.WriteLine("line1.ValueAt(2) = {0}", line1.ValueAt(2));
Console.WriteLine("line1.SlopeAt(2) = {0}", line1.SlopeAt(2));
Visual Basic Copy imageCopy
Console.WriteLine("line1.ValueAt(2) = {0}", line1.ValueAt(2))
Console.WriteLine("line1.SlopeAt(2) = {0}", line1.SlopeAt(2))

Integral(Double, Double) evaluates the definite integral over a specified interval. The integral is calculated exactly. The GetDerivative()()() method is not available.

Cubic Splines

The CubicSpline class represents a cubic spline, a piecewise curve that is a cubic polynomial on each interval. The function value, the first and second derivative are all continuous accross intervals. This gives cubic splines a smooth appearance.

The continuity conditions are not enough to define the spline curve completely. Two more conditions must be imposed. Each type of condition leads to another type of spline. The Extreme Optimization Mathematics Library for .NET supports the two most common types of splines: natural splines and clamped splines.

A natural spline is obtained by letting the slope at the ends be free to find the position that minimizes the oscillations of the curve. This is done by setting the second derivative of the spline to zero at the end points. There is only one natural spline for a set of data points. No additional information needs to be provided.

A clamped spline has a fixed slope at the end points. The slopes at the end points must be specified.

Cubic splines are often used for interpolation, and are often preferred over polynomials, especially when the number of data points is large.

The CubicSpline class has two sets of three constructors, one set for natural splines, and one for clamped splines. Let's discuss the constructors for natural splines first.

The first constructor takes two Double arrays as arguments. The first array contains the x-values of the data points. The second array contains the y-values. As mentioned before, the x values must be provided in ascending order. The second constructor takes two Vector objects, with the same meaning as before. The third constructor has only one argument: an array of Point structures. The following example illlustrates the use of these constructors:

C# Copy imageCopy
double[] xValues = {1, 2, 3, 4, 5, 6};
double[] yValues = {1, 3, 4, 3, 4, 2};
CubicSpline naturalSpline1 = new CubicSpline(xValues, yValues);
GeneralVector xVector = Vector.Create(xValues);
GeneralVector yVector = Vector.Create(yValues);
CubicSpline naturalSpline2 = new CubicSpline(xVector, yVector);
Point[] dataPoints = new Point[]
    {new Point(1, 1), new Point(2, 3), new Point(3, 4),
     new Point(4, 3), new Point(5, 4), new Point(6, 2)};
CubicSpline naturalSpline3 = new CubicSpline(dataPoints);
Visual Basic Copy imageCopy
Dim xValues As Double() = {1, 2, 3, 4, 5, 6}
Dim yValues As Double() = {1, 3, 4, 3, 4, 2}
Dim naturalSpline1 As CubicSpline = New CubicSpline(xValues, yValues)
Dim xVector As GeneralVector = New CubicSpline(xValues)
Dim yVector As GeneralVector = New CubicSpline(yValues)
Dim naturalSpline2 As CubicSpline = New CubicSpline(xVector, yVector)
Dim dataPoints As Point()  = New Point[]
     {New Point(1, 1), New Point(2, 3), New Point(3, 4),
     New Point(4, 3), New Point(5, 4), New Point(6, 2)}
Dim naturalSpline3 As CubicSpline = New CubicSpline(dataPoints)

To construct a clamped spline, the same three options are available, but two additional parameters are required: the slopes at the left and right end point. The following example constructs a clamped cubic spline through the same data points as above, and forces the slope at the lower bound to be -1, and the slope at the upper bound to be 1:

C# Copy imageCopy
double[] xValues = {1, 2, 3, 4, 5, 6};
double[] yValues = {1, 3, 4, 3, 4, 2};
CubicSpline clampedSpline1 = new CubicSpline(xValues, yValues, -1, 1);
GeneralVector xVector = Vector.Create(xValues);
GeneralVector yVector = Vector.Create(yValues);
CubicSpline clampedSpline2 = new CubicSpline(xVector, yVector, -1, 1);
Point[] dataPoints = new Point[]
    {new Point(1, 1), new Point(2, 3), new Point(3, 4),
     new Point(4, 3), new Point(5, 4), new Point(6, 2)};
CubicSpline clampedSpline3 = new CubicSpline(dataPoints, -1, 1);
Visual Basic Copy imageCopy
Dim xValues As Double() = {1, 2, 3, 4, 5, 6}
Dim yValues As Double() = {1, 3, 4, 3, 4, 2}
Dim clampedSpline1 As CubicSpline = New CubicSpline(xValues, yValues, -1, 1)
Dim xVector As GeneralVector = New CubicSpline(xValues)
Dim yVector As GeneralVector = New CubicSpline(yValues)
Dim clampedSpline2 As CubicSpline = New CubicSpline(xVector, yVector, -1, 1)
Dim dataPoints As Point()  = New Point[]
     {New Point(1, 1), New Point(2, 3), New Point(3, 4),
     New Point(4, 3), New Point(5, 4), New Point(6, 2)}
Dim clampedSpline3 As CubicSpline = New CubicSpline(dataPoints, -1, 1)

Once created, there is no real difference between natural and clamped cubic splines.

CubicSpline implements most methods and properties of the Curve class.

The ValueAt(Double) method returns the value of the spline at a specified point. If the x value is less than the lower bound of the first interval, the value is that of the cubic polynomial on the first interval extended to the left. If the x value is greater than the upper bound of the last interval, the value is that of the cubic polynomial on the last interval extended to the right.

The SlopeAt(Double) method returns the derivative. It is defined everywhere. The GetDerivative()()() method is not available.

C# Copy imageCopy
Console.WriteLine("naturalSpine1.ValueAt(2) = {0}", naturalSpine1.ValueAt(2));
Console.WriteLine("naturalSpine1.SlopeAt(2) = {0}", naturalSpine1.SlopeAt(2));
Visual Basic Copy imageCopy
Console.WriteLine("naturalSpine1.ValueAt(2) = {0}", naturalSpine1.ValueAt(2))
Console.WriteLine("naturalSpine1.SlopeAt(2) = {0}", naturalSpine1.SlopeAt(2))

Integral(Double, Double) evaluates the definite integral over a specified interval. The integral is calculated exactly and efficiently. In fact, a common application of cubic splines is the approximation of the integral of a tabulated function. The example below illustrates this procedure:

C# Copy imageCopy
double[] xValues = {1, 2, 3, 4, 5, 6};
double[] yValues = {1, 3, 4, 3, 4, 2};
CubicSpline spline1 = new CubicSpline(xValues, yValues);
double integral = spline1.Integral(2.2, 5.4);
Visual Basic Copy imageCopy
Dim xValues As Double() = {1, 2, 3, 4, 5, 6}
Dim yValues As Double() = {1, 3, 4, 3, 4, 2}
Dim spline1 As CubicSpline = New CubicSpline(xValues, yValues)
Dim integral As Double = spline1.Integral(2.2, 5.4)

This type of approximation turns out to be of good quality in most cases.

Send comments on this topic to support@extremeoptimization.com

Copyright © 2003-2010, Extreme Optimization. All rights reserved.
Extreme Optimization, Complexity made simple, M#, and M Sharp are trademarks of ExoAnalytics Inc.
Microsoft, Visual C#, Visual Basic, Visual Studio, Visual Studio.NET, and the Optimized for Visual Studio logo
are registered trademarks of Microsoft Corporation.