diff --git a/src/Numerics/Interpolation/Algorithms/EquidistantPolynomialInterpolation.cs b/src/Numerics/Interpolation/Algorithms/EquidistantPolynomialInterpolation.cs new file mode 100644 index 00000000..e7ec2d4e --- /dev/null +++ b/src/Numerics/Interpolation/Algorithms/EquidistantPolynomialInterpolation.cs @@ -0,0 +1,229 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Interpolation.Algorithms +{ + using System; + using System.Collections.Generic; + + /// + /// Barycentric Polynomial Interpolation where the given sample points are equidistant. + /// + /// + /// This algorithm neither supports differentiation nor integration. + /// + public class EquidistantPolynomialInterpolation : IInterpolation + { + /// + /// Internal Barycentric Interpolation + /// + private readonly BarycentricInterpolation _barycentric; + + /// + /// Initializes a new instance of the EquidistantPolynomialInterpolation class. + /// + public EquidistantPolynomialInterpolation() + { + _barycentric = new BarycentricInterpolation(); + } + + /// + /// Initializes a new instance of the EquidistantPolynomialInterpolation class. + /// + /// Left bound of the sample point interval. + /// Right bound of the sample point interval. + /// Sample Values x(t) where t is equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) + public EquidistantPolynomialInterpolation( + double leftBound, + double rightBound, + IList sampleValues) + { + _barycentric = new BarycentricInterpolation(); + Initialize(leftBound, rightBound, sampleValues); + } + + /// + /// Initializes a new instance of the EquidistantPolynomialInterpolation class. + /// + /// Equidistant Sample Points t = a+(b-a)*i/(n-1) + /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) + public EquidistantPolynomialInterpolation( + IList samplePoints, + IList sampleValues) + { + _barycentric = new BarycentricInterpolation(); + Initialize(samplePoints, sampleValues); + } + + /// + /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). + /// + /// + /// + bool IInterpolation.SupportsDifferentiation + { + get { return false; } + } + + /// + /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). + /// + /// + bool IInterpolation.SupportsIntegration + { + get { return false; } + } + + /// + /// Initialize the interpolation method with the given sampls in the interval [leftBound,rightBound]. + /// + /// Left bound of the sample point interval. + /// Right bound of the sample point interval. + /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) + public void Initialize( + double leftBound, + double rightBound, + IList sampleValues) + { + if (null == sampleValues) + { + throw new ArgumentNullException("sampleValues"); + } + + if (sampleValues.Count < 1) + { + throw new ArgumentOutOfRangeException("sampleValues"); + } + + var samplePoints = new double[sampleValues.Count]; + samplePoints[0] = leftBound; + double step = (rightBound - leftBound) / (samplePoints.Length - 1); + for (int i = 1; i < samplePoints.Length; i++) + { + samplePoints[i] = samplePoints[i - 1] + step; + } + + var weights = EvaluateBarycentricWeights(sampleValues.Count); + + _barycentric.Initialize(samplePoints, sampleValues, weights); + } + + /// + /// Initialize the interpolation method with the given sample set (no sorting assumed). + /// + /// Equidistant Sample Points t = a+(b-a)*i/(n-1) + /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) + public void Initialize( + IList samplePoints, + IList sampleValues) + { + if (null == sampleValues) + { + throw new ArgumentNullException("sampleValues"); + } + + var weights = EvaluateBarycentricWeights(sampleValues.Count); + + _barycentric.Initialize(samplePoints, sampleValues, weights); + } + + /// + /// Evaluate the barycentric weights as used + /// internally by this interpolation algorithm. + /// + /// Count of Sample Values x(t). + /// Barycentric Weight Vector + public static double[] EvaluateBarycentricWeights( + int sampleCount) + { + if (sampleCount < 1) + { + throw new ArgumentOutOfRangeException("sampleCount"); + } + + var weights = new double[sampleCount]; + weights[0] = 1.0; + for (int i = 1; i < weights.Length; i++) + { + weights[i] = -(weights[i - 1] * (weights.Length - i)) / i; + } + + return weights; + } + + /// + /// Interpolate at point t. + /// + /// Point t to interpolate at. + /// Interpolated value x(t). + public double Interpolate(double t) + { + return _barycentric.Interpolate(t); + } + + /// + /// Differentiate at point t. + /// + /// Point t to interpolate at. + /// Interpolated first derivative at point t. + /// + /// + double IInterpolation.Differentiate(double t) + { + throw new NotSupportedException(); + } + + /// + /// Differentiate at point t. + /// + /// Point t to interpolate at. + /// Interpolated value x(t) + /// Interpolated second derivative at point t. + /// Interpolated first derivative at point t. + /// + /// + double IInterpolation.Differentiate( + double t, + out double interpolatedValue, + out double secondDerivative) + { + throw new NotSupportedException(); + } + + /// + /// Integrate up to point t. + /// + /// Right bound of the integration interval [a,t]. + /// Interpolated definite integral over the interval [a,t]. + /// + double IInterpolation.Integrate(double t) + { + throw new NotSupportedException(); + } + } +} diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index a2febb99..8e8c3add 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -59,6 +59,7 @@ +