Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Differentiate3 to Interpolation #1093

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/Numerics.Tests/InterpolationTests/CubicSplineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,20 @@ public void CheckNaturalSplineMinMaxValuesPerformance()
}
}

/// <summary>
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
/// </summary>
[TestCase(-10, -8.1428571428571423)]
[TestCase(-5, -8.1428571428571423)]
[TestCase(0, -10.714285714285715)]
[TestCase(5, 2.1428571428571423)]
[TestCase(10, 2.1428571428571423)]
public void ThirdDerivative(double x, double expected)
{
IInterpolation it = CubicSpline.InterpolateNatural(_t, _y);
Assert.AreEqual(expected, it.Differentiate3(x));
}

/// <summary>
/// Generates a set of points representing an oscilating decaying function
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/Numerics.Tests/InterpolationTests/LinearSplineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
// </copyright>

using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random;
using NUnit.Framework;

namespace MathNet.Numerics.Tests.InterpolationTests
Expand All @@ -54,6 +55,16 @@ public void FirstDerivative()
Assert.That(ip.Differentiate(3.0), Is.EqualTo(1.0));
}

/// <summary>
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
/// </summary>
public void ThirdDerivative(double x, double expected)
{
var rnd = new SystemRandomSource(10);
IInterpolation it = LinearSpline.Interpolate(_t, _y);
Assert.AreEqual(0, it.Differentiate3(rnd.NextDouble()));
}

[Test]
public void DefiniteIntegral()
{
Expand Down
56 changes: 56 additions & 0 deletions src/Numerics.Tests/InterpolationTests/LogLinearTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// <copyright file="CubicSplineTest.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2016 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.
// </copyright>

using MathNet.Numerics.Interpolation;
using NUnit.Framework;

namespace MathNet.Numerics.Tests.InterpolationTests
{
[TestFixture, Category("Interpolation")]
public class LogLinearTest
{
readonly double[] _t = { 1.0, 2.0, 3.0, 4.0, 5.0 };
readonly double[] _y = { 1.0, 4.0, 9.0, 16.0, 25.0 };

/// <summary>
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
/// </summary>
[TestCase(0, 0.66604930397785889)]
[TestCase(1, 2.6641972159114355)]
[TestCase(2, 2.1330961922715468)]
[TestCase(3, 1.7142371101090121)]
[TestCase(4, 1.4222075877044038d)]
[TestCase(5, 2.2221993557881312d)]
public void ThirdDerivative(double x, double expected)
{
IInterpolation it = LogLinear.Interpolate(_t, _y);
Assert.AreEqual(expected, it.Differentiate3(x));
}
}
}
56 changes: 56 additions & 0 deletions src/Numerics.Tests/InterpolationTests/QuadraticSplineTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// <copyright file="QuadraticSplineTest.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
// Copyright (c) 2009-2016 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.
// </copyright>

using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random;
using NUnit.Framework;

namespace MathNet.Numerics.Tests.InterpolationTests
{
[TestFixture, Category("Interpolation")]
public class QuadraticSplineTest
{
readonly double[] _x = { -20.0, -10.0, -5.0, 0, 5.0, 10.0, 20.0 };
readonly double[] _c0 = { -3.0, -2.0, 1.0, 0.0, 1.0, 2.0 };
readonly double[] _c1 = { -2.0, -1.0, 0.0, 1.0, 2.0, 3.0 };
readonly double[] _c2 = { -1.0, 0.0, 1.0, 2.0, 3.0, 4.0 };

/// <summary>
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
/// </summary>
[Test]
public void ThirdDerivative()
{
var rnd = new SystemRandomSource(10);
IInterpolation it = new QuadraticSpline(_x, _c0, _c1, _c2);

Assert.AreEqual(0, it.Differentiate3(rnd.NextDouble()));
}
}
}
11 changes: 10 additions & 1 deletion src/Numerics.Tests/InterpolationTests/StepInterpolationTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="LinearSplineTest.cs" company="Math.NET">
// <copyright file="StepInterpolationTest.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
Expand Down Expand Up @@ -29,6 +29,7 @@

using System;
using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random;
using NUnit.Framework;

namespace MathNet.Numerics.Tests.InterpolationTests
Expand Down Expand Up @@ -56,6 +57,14 @@ public void FirstDerivative()
Assert.That(ip.Differentiate(4.0), Is.EqualTo(0.0));
}

public void ThirdDerivative()
{
var rnd = new SystemRandomSource(10);
var x = rnd.NextDouble();
IInterpolation ip = new StepInterpolation(_t, _y);
Assert.That(ip.Differentiate(x), Is.EqualTo(ip.Differentiate(x)));
}

[Test]
public void DefiniteIntegral()
{
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/Barycentric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ public double Interpolate(double t)
/// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();

/// <summary>
/// Differentiate three times at point t. NOT SUPPORTED.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();

/// <summary>
/// Indefinite integral at point t. NOT SUPPORTED.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ public double Interpolate(double t)
/// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();

/// <summary>
/// Differentiate three times at point t. NOT SUPPORTED.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();

/// <summary>
/// Indefinite integral at point t. NOT SUPPORTED.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/Numerics/Interpolation/CubicSpline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,17 @@ public double Differentiate2(double t)
return 2*_c2[k] + x*6*_c3[k];
}

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t)
{
int k = LeftSegmentIndex(t);
return 6*_c3[k];
}

/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/IInterpolation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ public interface IInterpolation
/// <returns>Interpolated second derivative at point t.</returns>
double Differentiate2(double t);

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
double Differentiate3(double t);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a method to IInterpolation is a breaking change since IInterpolation is a public interface that consumers of the library can and do implement.
Might be better to leave it out of the interface but keep the method for the classes for which the method is supported.


/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/LinearSpline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ public double Differentiate(double t)
/// <returns>Interpolated second derivative at point t.</returns>
public double Differentiate2(double t) => 0d;

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t) => 0d;

/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
18 changes: 18 additions & 0 deletions src/Numerics/Interpolation/LogLinear.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,24 @@ public double Differentiate2(double t)
return secondDerivative;
}

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t)
{
var linearFirstDerivative = _spline.Differentiate(t);
var linearSecondDerivative = _spline.Differentiate2(t);
var linearThirdDerivative = _spline.Differentiate3(t);

var thirdDerivative = Differentiate2(t) * linearFirstDerivative +
2 * Differentiate(t) * linearSecondDerivative +
Interpolate(t) * linearThirdDerivative;

return thirdDerivative;
}

/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
30 changes: 30 additions & 0 deletions src/Numerics/Interpolation/NevillePolynomialInterpolation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,36 @@ public double Differentiate2(double t)
return ddx[0];
}

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t)
{
var x = new double[_y.Length];
var dx = new double[_y.Length];
var ddx = new double[_y.Length];
var dddx = new double[_y.Length];
_y.CopyTo(x, 0);

for (int level = 1; level < x.Length; level++)
{
for (int i = 0; i < x.Length - level; i++)
{
double hp = t - _x[i + level];
double ho = _x[i] - t;
double den = _x[i] - _x[i + level];
dddx[i] = ((hp * dddx[i]) + (3 * ddx[i]) + (ho * dddx[i + 1]) - (3 * ddx[i + 1])) / den;
ddx[i] = ((hp * ddx[i]) + (2 * dx[i]) + (ho * ddx[i + 1]) - (2 * dx[i + 1])) / den;
dx[i] = ((hp * dx[i]) + x[i] + (ho * dx[i + 1]) - x[i + 1]) / den;
x[i] = ((hp * x[i]) + (ho * x[i + 1])) / den;
}
}

return dddx[0];
}

/// <summary>
/// Indefinite integral at point t. NOT SUPPORTED.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/QuadraticSpline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ public double Differentiate2(double t)
return 2*_c2[k];
}

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t) => 0d;

/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/StepInterpolation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ public double Differentiate(double t)
/// <returns>Interpolated second derivative at point t.</returns>
public double Differentiate2(double t) => Differentiate(t);

/// <summary>
/// Differentiate three times at point t.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
public double Differentiate3(double t) => Differentiate2(t);

/// <summary>
/// Indefinite integral at point t.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Numerics/Interpolation/TransformedInterpolation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ public static TransformedInterpolation Interpolate(
/// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();

/// <summary>
/// Differentiate three times at point t. NOT SUPPORTED.
/// </summary>
/// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated third derivative at point t.</returns>
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();

/// <summary>
/// Indefinite integral at point t. NOT SUPPORTED.
/// </summary>
Expand Down