1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.numbers.complex;
19
20 import java.io.BufferedReader;
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.ObjectInputStream;
26 import java.io.ObjectOutputStream;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.function.Consumer;
30
31 import org.apache.commons.numbers.core.Precision;
32
33 import org.junit.jupiter.api.Assertions;
34
35
36
37
38 public final class TestUtils {
39
40
41
42
43
44 public enum TestDataFlagOption {
45
46 IGNORE,
47
48 LOAD
49 }
50
51
52
53
54 private TestUtils() {
55 }
56
57
58
59
60
61
62
63
64
65 public static void assertSame(Complex expected, Complex actual) {
66 Assertions.assertEquals(expected.getReal(), actual.getReal());
67 Assertions.assertEquals(expected.getImaginary(), actual.getImaginary());
68 }
69
70
71
72
73
74
75
76
77
78 public static void assertEquals(Complex expected, Complex actual, double delta) {
79 Assertions.assertEquals(expected.getReal(), actual.getReal(), delta);
80 Assertions.assertEquals(expected.getImaginary(), actual.getImaginary(), delta);
81 }
82
83
84
85
86
87
88
89
90 public static Object serializeAndRecover(Object o) {
91 try {
92
93 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
94 final ObjectOutputStream so = new ObjectOutputStream(bos);
95 so.writeObject(o);
96
97
98 final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
99 final ObjectInputStream si = new ObjectInputStream(bis);
100 return si.readObject();
101 } catch (final IOException ioe) {
102 return null;
103 } catch (final ClassNotFoundException cnfe) {
104 return null;
105 }
106 }
107
108
109
110
111
112
113
114 public static void checkSerializedEquality(Object object) {
115 final Object object2 = serializeAndRecover(object);
116 Assertions.assertEquals(object, object2, "Equals check");
117 Assertions.assertEquals(object.hashCode(), object2.hashCode(), "HashCode check");
118 }
119
120
121
122
123
124
125
126
127
128
129 public static void assertRelativelyEquals(double expected, double actual, double relativeError) {
130 assertRelativelyEquals(null, expected, actual, relativeError);
131 }
132
133
134
135
136
137
138
139
140
141
142
143 public static void assertRelativelyEquals(String msg, double expected, double actual, double relativeError) {
144 if (Double.isNaN(expected)) {
145 Assertions.assertTrue(Double.isNaN(actual), msg);
146 } else if (Double.isNaN(actual)) {
147 Assertions.assertTrue(Double.isNaN(expected), msg);
148 } else if (Double.isInfinite(actual) || Double.isInfinite(expected)) {
149 Assertions.assertEquals(expected, actual, relativeError);
150 } else if (expected == 0.0) {
151 Assertions.assertEquals(actual, expected, relativeError, msg);
152 } else {
153 final double absError = Math.abs(expected) * relativeError;
154 Assertions.assertEquals(expected, actual, absError, msg);
155 }
156 }
157
158
159
160
161
162
163
164
165
166 public static void assertContains(String msg, Complex[] values, Complex z, double epsilon) {
167 for (final Complex value : values) {
168 if (Precision.equals(value.getReal(), z.getReal(), epsilon) &&
169 Precision.equals(value.getImaginary(), z.getImaginary(), epsilon)) {
170 return;
171 }
172 }
173 Assertions.fail(msg + " Unable to find " + z);
174 }
175
176
177
178
179
180
181
182
183 public static void assertContains(Complex[] values, Complex z, double epsilon) {
184 assertContains(null, values, z, epsilon);
185 }
186
187
188
189
190
191
192
193
194
195 public static void assertContains(String msg, double[] values, double x, double epsilon) {
196 for (final double value : values) {
197 if (Precision.equals(value, x, epsilon)) {
198 return;
199 }
200 }
201 Assertions.fail(msg + " Unable to find " + x);
202 }
203
204
205
206
207
208
209
210
211 public static void assertContains(double[] values, double x, double epsilon) {
212 assertContains(null, values, x, epsilon);
213 }
214
215
216 public static void assertEquals(String msg, Complex[] expected, Complex[] observed, double tolerance) {
217 final StringBuilder out = new StringBuilder(msg);
218 if (expected.length != observed.length) {
219 out.append("\n Arrays not same length. \n");
220 out.append("expected has length ");
221 out.append(expected.length);
222 out.append(" observed length = ");
223 out.append(observed.length);
224 Assertions.fail(out.toString());
225 }
226 boolean failure = false;
227 for (int i = 0; i < expected.length; i++) {
228 if (!Precision.equalsIncludingNaN(expected[i].getReal(), observed[i].getReal(), tolerance)) {
229 failure = true;
230 out.append("\n Real elements at index ");
231 out.append(i);
232 out.append(" differ. ");
233 out.append(" expected = ");
234 out.append(expected[i].getReal());
235 out.append(" observed = ");
236 out.append(observed[i].getReal());
237 }
238 if (!Precision.equalsIncludingNaN(expected[i].getImaginary(), observed[i].getImaginary(), tolerance)) {
239 failure = true;
240 out.append("\n Imaginary elements at index ");
241 out.append(i);
242 out.append(" differ. ");
243 out.append(" expected = ");
244 out.append(expected[i].getImaginary());
245 out.append(" observed = ");
246 out.append(observed[i].getImaginary());
247 }
248 }
249 if (failure) {
250 Assertions.fail(out.toString());
251 }
252 }
253
254
255
256
257
258 public static void updateCounts(double value, long[] counts, double[] quartiles) {
259 if (value < quartiles[0]) {
260 counts[0]++;
261 } else if (value > quartiles[2]) {
262 counts[3]++;
263 } else if (value > quartiles[1]) {
264 counts[2]++;
265 } else {
266 counts[1]++;
267 }
268 }
269
270
271
272
273
274
275
276 public static int eliminateZeroMassPoints(int[] densityPoints, double[] densityValues) {
277 int positiveMassCount = 0;
278 for (int i = 0; i < densityValues.length; i++) {
279 if (densityValues[i] > 0) {
280 positiveMassCount++;
281 }
282 }
283 if (positiveMassCount < densityValues.length) {
284 final int[] newPoints = new int[positiveMassCount];
285 final double[] newValues = new double[positiveMassCount];
286 int j = 0;
287 for (int i = 0; i < densityValues.length; i++) {
288 if (densityValues[i] > 0) {
289 newPoints[j] = densityPoints[i];
290 newValues[j] = densityValues[i];
291 j++;
292 }
293 }
294 System.arraycopy(newPoints, 0, densityPoints, 0, positiveMassCount);
295 System.arraycopy(newValues, 0, densityValues, 0, positiveMassCount);
296 }
297 return positiveMassCount;
298 }
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329 public static List<Complex[]> loadTestData(String name, TestDataFlagOption option,
330 Consumer<String> flaggedDataConsumer) {
331 final List<Complex[]> data = new ArrayList<>();
332 try (BufferedReader input = new BufferedReader(
333 new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(name)))) {
334 for (String line = input.readLine(); line != null; line = input.readLine()) {
335 line = preprocessTestData(line, option, flaggedDataConsumer);
336 if (line == null) {
337 continue;
338 }
339 final String[] parts = line.split(" ");
340 if ((parts.length & 0x1) == 1) {
341 Assertions.fail("Odd count of numbers on the line: " + line);
342 }
343 final Complex[] numbers = new Complex[parts.length / 2];
344 for (int i = 0; i < parts.length; i += 2) {
345 final double a = Double.parseDouble(parts[i]);
346 final double b = Double.parseDouble(parts[i + 1]);
347 numbers[i / 2] = Complex.ofCartesian(a, b);
348 }
349 data.add(numbers);
350 }
351 } catch (NumberFormatException | IOException e) {
352 Assertions.fail("Failed to load test data: " + name, e);
353 }
354 return data;
355 }
356
357
358
359
360
361
362
363
364
365
366
367 private static String preprocessTestData(String line, TestDataFlagOption option,
368 Consumer<String> flaggedDataConsumer) {
369
370 if (line.isEmpty() || line.charAt(0) == '#') {
371 return null;
372 }
373 if (line.charAt(0) == ';') {
374 switch (option) {
375 case LOAD:
376
377 line = line.substring(1);
378 break;
379 case IGNORE:
380 default:
381 if (flaggedDataConsumer != null) {
382 flaggedDataConsumer.accept(line.substring(1));
383 }
384
385 line = null;
386 }
387 }
388 return line;
389 }
390 }