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