1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.analysis.function;
19
20 import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21 import org.apache.commons.math4.legacy.analysis.differentiation.DerivativeStructure;
22 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23 import org.apache.commons.math4.legacy.exception.NullArgumentException;
24 import org.apache.commons.math4.core.jdkmath.JdkMath;
25 import org.apache.commons.numbers.core.Precision;
26 import org.junit.Assert;
27 import org.junit.Test;
28
29
30
31
32 public class HarmonicOscillatorTest {
33 private final double EPS = Math.ulp(1d);
34
35 @Test
36 public void testSomeValues() {
37 final double a = -1.2;
38 final double w = 0.34;
39 final double p = 5.6;
40 final UnivariateFunction f = new HarmonicOscillator(a, w, p);
41
42 final double d = 0.12345;
43 for (int i = 0; i < 10; i++) {
44 final double v = i * d;
45 Assert.assertEquals(a * JdkMath.cos(w * v + p), f.value(v), 0);
46 }
47 }
48
49 @Test
50 public void testDerivative() {
51 final double a = -1.2;
52 final double w = 0.34;
53 final double p = 5.6;
54 final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
55
56 for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
57 final double d = 0.12345;
58 for (int i = 0; i < 10; i++) {
59 final double v = i * d;
60 final DerivativeStructure h = f.value(new DerivativeStructure(1, maxOrder, 0, v));
61 for (int k = 0; k <= maxOrder; ++k) {
62 final double trigo;
63 switch (k % 4) {
64 case 0:
65 trigo = +JdkMath.cos(w * v + p);
66 break;
67 case 1:
68 trigo = -JdkMath.sin(w * v + p);
69 break;
70 case 2:
71 trigo = -JdkMath.cos(w * v + p);
72 break;
73 default:
74 trigo = +JdkMath.sin(w * v + p);
75 break;
76 }
77 Assert.assertEquals(a * JdkMath.pow(w, k) * trigo,
78 h.getPartialDerivative(k),
79 Precision.EPSILON);
80 }
81 }
82 }
83 }
84
85 @Test(expected=NullArgumentException.class)
86 public void testParametricUsage1() {
87 final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
88 g.value(0, null);
89 }
90
91 @Test(expected=DimensionMismatchException.class)
92 public void testParametricUsage2() {
93 final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
94 g.value(0, new double[] {0});
95 }
96
97 @Test(expected=NullArgumentException.class)
98 public void testParametricUsage3() {
99 final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
100 g.gradient(0, null);
101 }
102
103 @Test(expected=DimensionMismatchException.class)
104 public void testParametricUsage4() {
105 final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
106 g.gradient(0, new double[] {0});
107 }
108
109 @Test
110 public void testParametricValue() {
111 final double amplitude = 2;
112 final double omega = 3;
113 final double phase = 4;
114 final HarmonicOscillator f = new HarmonicOscillator(amplitude, omega, phase);
115
116 final HarmonicOscillator.Parametric g = new HarmonicOscillator.Parametric();
117 Assert.assertEquals(f.value(-1), g.value(-1, new double[] {amplitude, omega, phase}), 0);
118 Assert.assertEquals(f.value(0), g.value(0, new double[] {amplitude, omega, phase}), 0);
119 Assert.assertEquals(f.value(2), g.value(2, new double[] {amplitude, omega, phase}), 0);
120 }
121
122 @Test
123 public void testParametricGradient() {
124 final double amplitude = 2;
125 final double omega = 3;
126 final double phase = 4;
127 final HarmonicOscillator.Parametric f = new HarmonicOscillator.Parametric();
128
129 final double x = 1;
130 final double[] grad = f.gradient(1, new double[] {amplitude, omega, phase});
131 final double xTimesOmegaPlusPhase = omega * x + phase;
132 final double a = JdkMath.cos(xTimesOmegaPlusPhase);
133 Assert.assertEquals(a, grad[0], EPS);
134 final double w = -amplitude * x * JdkMath.sin(xTimesOmegaPlusPhase);
135 Assert.assertEquals(w, grad[1], EPS);
136 final double p = -amplitude * JdkMath.sin(xTimesOmegaPlusPhase);
137 Assert.assertEquals(p, grad[2], EPS);
138 }
139 }