Skip to content

Commit 6115680

Browse files
committed
Added Differentiate3 to Interpolation
1 parent f196418 commit 6115680

15 files changed

+254
-0
lines changed

src/Numerics.Tests/InterpolationTests/CubicSplineTest.cs

+14
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,20 @@ public void CheckNaturalSplineMinMaxValuesPerformance()
269269
}
270270
}
271271

272+
/// <summary>
273+
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
274+
/// </summary>
275+
[TestCase(-10, -8.1428571428571423)]
276+
[TestCase(-5, -8.1428571428571423)]
277+
[TestCase(0, -10.714285714285715)]
278+
[TestCase(5, 2.1428571428571423)]
279+
[TestCase(10, 2.1428571428571423)]
280+
public void ThirdDerivative(double x, double expected)
281+
{
282+
IInterpolation it = CubicSpline.InterpolateNatural(_t, _y);
283+
Assert.AreEqual(expected, it.Differentiate3(x));
284+
}
285+
272286
/// <summary>
273287
/// Generates a set of points representing an oscilating decaying function
274288
/// </summary>

src/Numerics.Tests/InterpolationTests/LinearSplineTest.cs

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// </copyright>
2929

3030
using MathNet.Numerics.Interpolation;
31+
using MathNet.Numerics.Random;
3132
using NUnit.Framework;
3233

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

58+
/// <summary>
59+
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
60+
/// </summary>
61+
public void ThirdDerivative(double x, double expected)
62+
{
63+
var rnd = new SystemRandomSource(10);
64+
IInterpolation it = LinearSpline.Interpolate(_t, _y);
65+
Assert.AreEqual(0, it.Differentiate3(rnd.NextDouble()));
66+
}
67+
5768
[Test]
5869
public void DefiniteIntegral()
5970
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// <copyright file="CubicSplineTest.cs" company="Math.NET">
2+
// Math.NET Numerics, part of the Math.NET Project
3+
// http://numerics.mathdotnet.com
4+
// http://github.com/mathnet/mathnet-numerics
5+
//
6+
// Copyright (c) 2009-2016 Math.NET
7+
//
8+
// Permission is hereby granted, free of charge, to any person
9+
// obtaining a copy of this software and associated documentation
10+
// files (the "Software"), to deal in the Software without
11+
// restriction, including without limitation the rights to use,
12+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the
14+
// Software is furnished to do so, subject to the following
15+
// conditions:
16+
//
17+
// The above copyright notice and this permission notice shall be
18+
// included in all copies or substantial portions of the Software.
19+
//
20+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27+
// OTHER DEALINGS IN THE SOFTWARE.
28+
// </copyright>
29+
30+
using MathNet.Numerics.Interpolation;
31+
using NUnit.Framework;
32+
33+
namespace MathNet.Numerics.Tests.InterpolationTests
34+
{
35+
[TestFixture, Category("Interpolation")]
36+
public class LogLinearTest
37+
{
38+
readonly double[] _t = { 1.0, 2.0, 3.0, 4.0, 5.0 };
39+
readonly double[] _y = { 1.0, 4.0, 9.0, 16.0, 25.0 };
40+
41+
/// <summary>
42+
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
43+
/// </summary>
44+
[TestCase(0, 0.66604930397785889)]
45+
[TestCase(1, 2.6641972159114355)]
46+
[TestCase(2, 2.1330961922715468)]
47+
[TestCase(3, 1.7142371101090121)]
48+
[TestCase(4, 1.4222075877044038d)]
49+
[TestCase(5, 2.2221993557881312d)]
50+
public void ThirdDerivative(double x, double expected)
51+
{
52+
IInterpolation it = LogLinear.Interpolate(_t, _y);
53+
Assert.AreEqual(expected, it.Differentiate3(x));
54+
}
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// <copyright file="LinearSplineTest.cs" company="Math.NET">
2+
// Math.NET Numerics, part of the Math.NET Project
3+
// http://numerics.mathdotnet.com
4+
// http://github.com/mathnet/mathnet-numerics
5+
//
6+
// Copyright (c) 2009-2016 Math.NET
7+
//
8+
// Permission is hereby granted, free of charge, to any person
9+
// obtaining a copy of this software and associated documentation
10+
// files (the "Software"), to deal in the Software without
11+
// restriction, including without limitation the rights to use,
12+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the
14+
// Software is furnished to do so, subject to the following
15+
// conditions:
16+
//
17+
// The above copyright notice and this permission notice shall be
18+
// included in all copies or substantial portions of the Software.
19+
//
20+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27+
// OTHER DEALINGS IN THE SOFTWARE.
28+
// </copyright>
29+
30+
using MathNet.Numerics.Interpolation;
31+
using MathNet.Numerics.Random;
32+
using NUnit.Framework;
33+
34+
namespace MathNet.Numerics.Tests.InterpolationTests
35+
{
36+
[TestFixture, Category("Interpolation")]
37+
public class QuadraticSplineTest
38+
{
39+
readonly double[] _x = { -20.0, -10.0, -5.0, 0, 5.0, 10.0, 20.0 };
40+
readonly double[] _c0 = { -3.0, -2.0, 1.0, 0.0, 1.0, 2.0 };
41+
readonly double[] _c1 = { -2.0, -1.0, 0.0, 1.0, 2.0, 3.0 };
42+
readonly double[] _c2 = { -1.0, 0.0, 1.0, 2.0, 3.0, 4.0 };
43+
44+
/// <summary>
45+
/// Verifies that the 3rd derivative matches the given value at all the provided sample points.
46+
/// </summary>
47+
[Test]
48+
public void ThirdDerivative()
49+
{
50+
var rnd = new SystemRandomSource(10);
51+
IInterpolation it = new QuadraticSpline(_x, _c0, _c1, _c2);
52+
53+
Assert.AreEqual(0, it.Differentiate3(rnd.NextDouble()));
54+
}
55+
}
56+
}

src/Numerics.Tests/InterpolationTests/StepInterpolationTest.cs

+9
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
using System;
3131
using MathNet.Numerics.Interpolation;
32+
using MathNet.Numerics.Random;
3233
using NUnit.Framework;
3334

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

60+
public void ThirdDerivative()
61+
{
62+
var rnd = new SystemRandomSource(10);
63+
var x = rnd.NextDouble();
64+
IInterpolation ip = new StepInterpolation(_t, _y);
65+
Assert.That(ip.Differentiate(x), Is.EqualTo(ip.Differentiate(x)));
66+
}
67+
5968
[Test]
6069
public void DefiniteIntegral()
6170
{

src/Numerics/Interpolation/Barycentric.cs

+7
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,13 @@ public double Interpolate(double t)
334334
/// <returns>Interpolated second derivative at point t.</returns>
335335
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
336336

337+
/// <summary>
338+
/// Differentiate three times at point t. NOT SUPPORTED.
339+
/// </summary>
340+
/// <param name="t">Point t to interpolate at.</param>
341+
/// <returns>Interpolated third derivative at point t.</returns>
342+
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();
343+
337344
/// <summary>
338345
/// Indefinite integral at point t. NOT SUPPORTED.
339346
/// </summary>

src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs

+7
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ public double Interpolate(double t)
182182
/// <returns>Interpolated second derivative at point t.</returns>
183183
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
184184

185+
/// <summary>
186+
/// Differentiate three times at point t. NOT SUPPORTED.
187+
/// </summary>
188+
/// <param name="t">Point t to interpolate at.</param>
189+
/// <returns>Interpolated third derivative at point t.</returns>
190+
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();
191+
185192
/// <summary>
186193
/// Indefinite integral at point t. NOT SUPPORTED.
187194
/// </summary>

src/Numerics/Interpolation/CubicSpline.cs

+11
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,17 @@ public double Differentiate2(double t)
579579
return 2*_c2[k] + x*6*_c3[k];
580580
}
581581

582+
/// <summary>
583+
/// Differentiate three times at point t.
584+
/// </summary>
585+
/// <param name="t">Point t to interpolate at.</param>
586+
/// <returns>Interpolated third derivative at point t.</returns>
587+
public double Differentiate3(double t)
588+
{
589+
int k = LeftSegmentIndex(t);
590+
return 6*_c3[k];
591+
}
592+
582593
/// <summary>
583594
/// Indefinite integral at point t.
584595
/// </summary>

src/Numerics/Interpolation/IInterpolation.cs

+7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ public interface IInterpolation
6565
/// <returns>Interpolated second derivative at point t.</returns>
6666
double Differentiate2(double t);
6767

68+
/// <summary>
69+
/// Differentiate three times at point t.
70+
/// </summary>
71+
/// <param name="t">Point t to interpolate at.</param>
72+
/// <returns>Interpolated third derivative at point t.</returns>
73+
double Differentiate3(double t);
74+
6875
/// <summary>
6976
/// Indefinite integral at point t.
7077
/// </summary>

src/Numerics/Interpolation/LinearSpline.cs

+7
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ public double Differentiate(double t)
152152
/// <returns>Interpolated second derivative at point t.</returns>
153153
public double Differentiate2(double t) => 0d;
154154

155+
/// <summary>
156+
/// Differentiate three times at point t.
157+
/// </summary>
158+
/// <param name="t">Point t to interpolate at.</param>
159+
/// <returns>Interpolated third derivative at point t.</returns>
160+
public double Differentiate3(double t) => 0d;
161+
155162
/// <summary>
156163
/// Indefinite integral at point t.
157164
/// </summary>

src/Numerics/Interpolation/LogLinear.cs

+18
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,24 @@ public double Differentiate2(double t)
152152
return secondDerivative;
153153
}
154154

155+
/// <summary>
156+
/// Differentiate three times at point t.
157+
/// </summary>
158+
/// <param name="t">Point t to interpolate at.</param>
159+
/// <returns>Interpolated third derivative at point t.</returns>
160+
public double Differentiate3(double t)
161+
{
162+
var linearFirstDerivative = _spline.Differentiate(t);
163+
var linearSecondDerivative = _spline.Differentiate2(t);
164+
var linearThirdDerivative = _spline.Differentiate3(t);
165+
166+
var thirdDerivative = Differentiate2(t) * linearFirstDerivative +
167+
2 * Differentiate(t) * linearSecondDerivative +
168+
Interpolate(t) * linearThirdDerivative;
169+
170+
return thirdDerivative;
171+
}
172+
155173
/// <summary>
156174
/// Indefinite integral at point t.
157175
/// </summary>

src/Numerics/Interpolation/NevillePolynomialInterpolation.cs

+30
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,36 @@ public double Differentiate2(double t)
197197
return ddx[0];
198198
}
199199

200+
/// <summary>
201+
/// Differentiate three times at point t.
202+
/// </summary>
203+
/// <param name="t">Point t to interpolate at.</param>
204+
/// <returns>Interpolated third derivative at point t.</returns>
205+
public double Differentiate3(double t)
206+
{
207+
var x = new double[_y.Length];
208+
var dx = new double[_y.Length];
209+
var ddx = new double[_y.Length];
210+
var dddx = new double[_y.Length];
211+
_y.CopyTo(x, 0);
212+
213+
for (int level = 1; level < x.Length; level++)
214+
{
215+
for (int i = 0; i < x.Length - level; i++)
216+
{
217+
double hp = t - _x[i + level];
218+
double ho = _x[i] - t;
219+
double den = _x[i] - _x[i + level];
220+
dddx[i] = ((hp * dddx[i]) + (3 * ddx[i]) + (ho * dddx[i + 1]) - (3 * ddx[i + 1])) / den;
221+
ddx[i] = ((hp * ddx[i]) + (2 * dx[i]) + (ho * ddx[i + 1]) - (2 * dx[i + 1])) / den;
222+
dx[i] = ((hp * dx[i]) + x[i] + (ho * dx[i + 1]) - x[i + 1]) / den;
223+
x[i] = ((hp * x[i]) + (ho * x[i + 1])) / den;
224+
}
225+
}
226+
227+
return dddx[0];
228+
}
229+
200230
/// <summary>
201231
/// Indefinite integral at point t. NOT SUPPORTED.
202232
/// </summary>

src/Numerics/Interpolation/QuadraticSpline.cs

+7
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ public double Differentiate2(double t)
110110
return 2*_c2[k];
111111
}
112112

113+
/// <summary>
114+
/// Differentiate three times at point t.
115+
/// </summary>
116+
/// <param name="t">Point t to interpolate at.</param>
117+
/// <returns>Interpolated third derivative at point t.</returns>
118+
public double Differentiate3(double t) => 0d;
119+
113120
/// <summary>
114121
/// Indefinite integral at point t.
115122
/// </summary>

src/Numerics/Interpolation/StepInterpolation.cs

+7
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ public double Differentiate(double t)
139139
/// <returns>Interpolated second derivative at point t.</returns>
140140
public double Differentiate2(double t) => Differentiate(t);
141141

142+
/// <summary>
143+
/// Differentiate three times at point t.
144+
/// </summary>
145+
/// <param name="t">Point t to interpolate at.</param>
146+
/// <returns>Interpolated third derivative at point t.</returns>
147+
public double Differentiate3(double t) => Differentiate2(t);
148+
142149
/// <summary>
143150
/// Indefinite integral at point t.
144151
/// </summary>

src/Numerics/Interpolation/TransformedInterpolation.cs

+7
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ public static TransformedInterpolation Interpolate(
146146
/// <returns>Interpolated second derivative at point t.</returns>
147147
double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
148148

149+
/// <summary>
150+
/// Differentiate three times at point t. NOT SUPPORTED.
151+
/// </summary>
152+
/// <param name="t">Point t to interpolate at.</param>
153+
/// <returns>Interpolated third derivative at point t.</returns>
154+
double IInterpolation.Differentiate3(double t) => throw new NotSupportedException();
155+
149156
/// <summary>
150157
/// Indefinite integral at point t. NOT SUPPORTED.
151158
/// </summary>

0 commit comments

Comments
 (0)