Skip to content

Commit 5876d84

Browse files
author
Luc Maisonobe
committed
Added derivatives evaluation for field Hermite interpolator.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1449822 13f79535-47bb-0310-9956-ffa450edef68
1 parent 171d317 commit 5876d84

2 files changed

Lines changed: 80 additions & 4 deletions

File tree

src/main/java/org/apache/commons/math3/analysis/interpolation/FieldHermiteInterpolator.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,49 @@ public T[] value(T x) throws NoDataException {
149149

150150
}
151151

152+
/** Interpolate value and first derivatives at a specified abscissa.
153+
* @param x interpolation abscissa
154+
* @param order maximum derivation order
155+
* @return interpolated value and derivatives (value in row 0,
156+
* 1<sup>st</sup> derivative in row 1, ... n<sup>th</sup> derivative in row n)
157+
* @exception NoDataException if sample is empty
158+
*/
159+
public T[][] derivatives(T x, int order) throws NoDataException {
160+
161+
// safety check
162+
if (abscissae.isEmpty()) {
163+
throw new NoDataException(LocalizedFormats.EMPTY_INTERPOLATION_SAMPLE);
164+
}
165+
166+
final T zero = x.getField().getZero();
167+
final T one = x.getField().getOne();
168+
final T[] tj = MathArrays.buildArray(x.getField(), order + 1);
169+
tj[0] = zero;
170+
for (int i = 0; i < order; ++i) {
171+
tj[i + 1] = tj[i].add(one);
172+
}
173+
174+
final T[][] derivatives =
175+
MathArrays.buildArray(x.getField(), order + 1, topDiagonal.get(0).length);
176+
final T[] valueCoeff = MathArrays.buildArray(x.getField(), order + 1);
177+
valueCoeff[0] = x.getField().getOne();
178+
for (int i = 0; i < topDiagonal.size(); ++i) {
179+
T[] dividedDifference = topDiagonal.get(i);
180+
final T deltaX = x.subtract(abscissae.get(i));
181+
for (int j = order; j >= 0; --j) {
182+
for (int k = 0; k < derivatives[j].length; ++k) {
183+
derivatives[j][k] =
184+
derivatives[j][k].add(dividedDifference[k].multiply(valueCoeff[j]));
185+
}
186+
valueCoeff[j] = valueCoeff[j].multiply(deltaX);
187+
if (j > 0) {
188+
valueCoeff[j] = valueCoeff[j].add(tj[j].multiply(valueCoeff[j - 1]));
189+
}
190+
}
191+
}
192+
193+
return derivatives;
194+
195+
}
196+
152197
}

src/test/java/org/apache/commons/math3/analysis/interpolation/FieldHermiteInterpolatorTest.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public void testZero() {
3636
for (int x = -10; x < 10; x++) {
3737
BigFraction y = interpolator.value(new BigFraction(x))[0];
3838
Assert.assertEquals(BigFraction.ZERO, y);
39+
BigFraction[][] derivatives = interpolator.derivatives(new BigFraction(x), 1);
40+
Assert.assertEquals(BigFraction.ZERO, derivatives[0][0]);
41+
Assert.assertEquals(BigFraction.ZERO, derivatives[1][0]);
3942
}
4043
}
4144

@@ -48,6 +51,11 @@ public void testQuadratic() {
4851
for (double x = -10; x < 10; x += 1.0) {
4952
BigFraction y = interpolator.value(new BigFraction(x))[0];
5053
Assert.assertEquals((x - 1) * (x - 2), y.doubleValue(), 1.0e-15);
54+
BigFraction[][] derivatives = interpolator.derivatives(new BigFraction(x), 3);
55+
Assert.assertEquals((x - 1) * (x - 2), derivatives[0][0].doubleValue(), 1.0e-15);
56+
Assert.assertEquals(2 * x - 3, derivatives[1][0].doubleValue(), 1.0e-15);
57+
Assert.assertEquals(2, derivatives[2][0].doubleValue(), 1.0e-15);
58+
Assert.assertEquals(0, derivatives[3][0].doubleValue(), 1.0e-15);
5159
}
5260
}
5361

@@ -57,9 +65,27 @@ public void testMixedDerivatives() {
5765
interpolator.addSamplePoint(new BigFraction(0), new BigFraction[] { new BigFraction(1) }, new BigFraction[] { new BigFraction(2) });
5866
interpolator.addSamplePoint(new BigFraction(1), new BigFraction[] { new BigFraction(4) });
5967
interpolator.addSamplePoint(new BigFraction(2), new BigFraction[] { new BigFraction(5) }, new BigFraction[] { new BigFraction(2) });
60-
Assert.assertEquals(new BigFraction(1), interpolator.value(new BigFraction(0))[0]);
61-
Assert.assertEquals(new BigFraction(4), interpolator.value(new BigFraction(1))[0]);
62-
Assert.assertEquals(new BigFraction(5), interpolator.value(new BigFraction(2))[0]);
68+
BigFraction[][] derivatives = interpolator.derivatives(new BigFraction(0), 5);
69+
Assert.assertEquals(new BigFraction( 1), derivatives[0][0]);
70+
Assert.assertEquals(new BigFraction( 2), derivatives[1][0]);
71+
Assert.assertEquals(new BigFraction( 8), derivatives[2][0]);
72+
Assert.assertEquals(new BigFraction(-24), derivatives[3][0]);
73+
Assert.assertEquals(new BigFraction( 24), derivatives[4][0]);
74+
Assert.assertEquals(new BigFraction( 0), derivatives[5][0]);
75+
derivatives = interpolator.derivatives(new BigFraction(1), 5);
76+
Assert.assertEquals(new BigFraction( 4), derivatives[0][0]);
77+
Assert.assertEquals(new BigFraction( 2), derivatives[1][0]);
78+
Assert.assertEquals(new BigFraction( -4), derivatives[2][0]);
79+
Assert.assertEquals(new BigFraction( 0), derivatives[3][0]);
80+
Assert.assertEquals(new BigFraction( 24), derivatives[4][0]);
81+
Assert.assertEquals(new BigFraction( 0), derivatives[5][0]);
82+
derivatives = interpolator.derivatives(new BigFraction(2), 5);
83+
Assert.assertEquals(new BigFraction( 5), derivatives[0][0]);
84+
Assert.assertEquals(new BigFraction( 2), derivatives[1][0]);
85+
Assert.assertEquals(new BigFraction( 8), derivatives[2][0]);
86+
Assert.assertEquals(new BigFraction( 24), derivatives[3][0]);
87+
Assert.assertEquals(new BigFraction( 24), derivatives[4][0]);
88+
Assert.assertEquals(new BigFraction( 0), derivatives[5][0]);
6389
}
6490

6591
@Test
@@ -230,10 +256,15 @@ private PolynomialFunction randomPolynomial(int degree, Random random) {
230256
}
231257

232258
@Test(expected=NoDataException.class)
233-
public void testEmptySample() {
259+
public void testEmptySampleValue() {
234260
new FieldHermiteInterpolator<BigFraction>().value(BigFraction.ZERO);
235261
}
236262

263+
@Test(expected=NoDataException.class)
264+
public void testEmptySampleDerivative() {
265+
new FieldHermiteInterpolator<BigFraction>().derivatives(BigFraction.ZERO, 1);
266+
}
267+
237268
@Test(expected=IllegalArgumentException.class)
238269
public void testDuplicatedAbscissa() {
239270
FieldHermiteInterpolator<BigFraction> interpolator = new FieldHermiteInterpolator<BigFraction>();

0 commit comments

Comments
 (0)