1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.fitting;
23
24 import org.hipparchus.analysis.function.HarmonicOscillator;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.exception.MathIllegalStateException;
27 import org.hipparchus.util.FastMath;
28 import org.hipparchus.util.MathUtils;
29 import org.junit.jupiter.api.Test;
30
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Random;
34
35 import static org.junit.jupiter.api.Assertions.assertEquals;
36 import static org.junit.jupiter.api.Assertions.assertThrows;
37 import static org.junit.jupiter.api.Assertions.assertTrue;
38
39 class HarmonicCurveFitterTest {
40
41
42
43 @Test
44 void testPreconditions1() {
45 assertThrows(MathIllegalArgumentException.class, () -> {
46 HarmonicCurveFitter.create().fit(new WeightedObservedPoints().toList());
47 });
48 }
49
50 @Test
51 void testNoError() {
52 final double a = 0.2;
53 final double w = 3.4;
54 final double p = 4.1;
55 final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
56
57 final WeightedObservedPoints points = new WeightedObservedPoints();
58 for (double x = 0.0; x < 1.3; x += 0.01) {
59 points.add(1, x, f.value(x));
60 }
61
62 final HarmonicCurveFitter fitter = HarmonicCurveFitter.create();
63 final double[] fitted = fitter.fit(points.toList());
64 assertEquals(a, fitted[0], 1.0e-13);
65 assertEquals(w, fitted[1], 1.0e-13);
66 assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1e-13);
67
68 final HarmonicOscillator ff = new HarmonicOscillator(fitted[0], fitted[1], fitted[2]);
69 for (double x = -1.0; x < 1.0; x += 0.01) {
70 assertTrue(FastMath.abs(f.value(x) - ff.value(x)) < 1e-13);
71 }
72 }
73
74 @Test
75 void test1PercentError() {
76 final Random randomizer = new Random(64925784252L);
77 final double a = 0.2;
78 final double w = 3.4;
79 final double p = 4.1;
80 final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
81
82 final WeightedObservedPoints points = new WeightedObservedPoints();
83 for (double x = 0.0; x < 10.0; x += 0.1) {
84 points.add(1, x, f.value(x) + 0.01 * randomizer.nextGaussian());
85 }
86
87 final HarmonicCurveFitter fitter = HarmonicCurveFitter.create();
88 final double[] fitted = fitter.fit(points.toList());
89 assertEquals(a, fitted[0], 7.6e-4);
90 assertEquals(w, fitted[1], 2.7e-3);
91 assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.3e-2);
92 }
93
94 @Test
95 void testTinyVariationsData() {
96 final Random randomizer = new Random(64925784252L);
97
98 final WeightedObservedPoints points = new WeightedObservedPoints();
99 for (double x = 0.0; x < 10.0; x += 0.1) {
100 points.add(1, x, 1e-7 * randomizer.nextGaussian());
101 }
102
103 final HarmonicCurveFitter fitter = HarmonicCurveFitter.create();
104 fitter.fit(points.toList());
105
106
107
108 }
109
110 @Test
111 void testInitialGuess() {
112 final Random randomizer = new Random(45314242L);
113 final double a = 0.2;
114 final double w = 3.4;
115 final double p = 4.1;
116 final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
117
118 final WeightedObservedPoints points = new WeightedObservedPoints();
119 for (double x = 0.0; x < 10.0; x += 0.1) {
120 points.add(1, x, f.value(x) + 0.01 * randomizer.nextGaussian());
121 }
122
123 final HarmonicCurveFitter fitter = HarmonicCurveFitter.create()
124 .withStartPoint(new double[] { 0.15, 3.6, 4.5 });
125 final double[] fitted = fitter.fit(points.toList());
126 assertEquals(a, fitted[0], 1.2e-3);
127 assertEquals(w, fitted[1], 3.3e-3);
128 assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.7e-2);
129 }
130
131 @Test
132 void testUnsorted() {
133 Random randomizer = new Random(64925784252L);
134 final double a = 0.2;
135 final double w = 3.4;
136 final double p = 4.1;
137 final HarmonicOscillator f = new HarmonicOscillator(a, w, p);
138
139
140 final int size = 100;
141 final double[] xTab = new double[size];
142 final double[] yTab = new double[size];
143 for (int i = 0; i < size; i++) {
144 xTab[i] = 0.1 * i;
145 yTab[i] = f.value(xTab[i]) + 0.01 * randomizer.nextGaussian();
146 }
147
148
149 for (int i = 0; i < size; i++) {
150 int i1 = randomizer.nextInt(size);
151 int i2 = randomizer.nextInt(size);
152 double xTmp = xTab[i1];
153 double yTmp = yTab[i1];
154 xTab[i1] = xTab[i2];
155 yTab[i1] = yTab[i2];
156 xTab[i2] = xTmp;
157 yTab[i2] = yTmp;
158 }
159
160
161 final WeightedObservedPoints points = new WeightedObservedPoints();
162 for (int i = 0; i < size; ++i) {
163 points.add(1, xTab[i], yTab[i]);
164 }
165
166 final HarmonicCurveFitter fitter = HarmonicCurveFitter.create();
167 final double[] fitted = fitter.fit(points.toList());
168 assertEquals(a, fitted[0], 7.6e-4);
169 assertEquals(w, fitted[1], 3.5e-3);
170 assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.5e-2);
171 }
172
173 @Test
174 void testMath844() {
175 assertThrows(MathIllegalStateException.class, () -> {
176 final double[] y = {0, 1, 2, 3, 2, 1,
177 0, -1, -2, -3, -2, -1,
178 0, 1, 2, 3, 2, 1,
179 0, -1, -2, -3, -2, -1,
180 0, 1, 2, 3, 2, 1, 0};
181 final List<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
182 for (int i = 0; i < y.length; i++) {
183 points.add(new WeightedObservedPoint(1, i, y[i]));
184 }
185
186
187
188
189
190
191 new HarmonicCurveFitter.ParameterGuesser(points);
192 });
193 }
194 }