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 org.apache.commons.rng.UniformRandomProvider;
21 import org.apache.commons.rng.simple.RandomSource;
22 import org.junit.jupiter.api.Assertions;
23 import org.junit.jupiter.api.Test;
24
25 import java.math.BigDecimal;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.function.BiFunction;
29 import java.util.function.Predicate;
30 import java.util.function.ToDoubleFunction;
31 import java.util.function.UnaryOperator;
32
33
34
35
36
37
38
39
40 class CStandardTest {
41
42 private static final double inf = Double.POSITIVE_INFINITY;
43 private static final double negInf = Double.NEGATIVE_INFINITY;
44 private static final double nan = Double.NaN;
45 private static final double max = Double.MAX_VALUE;
46 private static final double piOverFour = Math.PI / 4.0;
47 private static final double piOverTwo = Math.PI / 2.0;
48 private static final double threePiOverFour = 3.0 * Math.PI / 4.0;
49 private static final Complex oneZero = complex(1, 0);
50 private static final Complex zeroInf = complex(0, inf);
51 private static final Complex zeroNegInf = complex(0, negInf);
52 private static final Complex zeroNaN = complex(0, nan);
53 private static final Complex zeroPiTwo = complex(0.0, piOverTwo);
54 private static final Complex negZeroZero = complex(-0.0, 0);
55 private static final Complex negZeroNaN = complex(-0.0, nan);
56 private static final Complex infZero = complex(inf, 0);
57 private static final Complex infNaN = complex(inf, nan);
58 private static final Complex infInf = complex(inf, inf);
59 private static final Complex infPiTwo = complex(inf, piOverTwo);
60 private static final Complex infThreePiFour = complex(inf, threePiOverFour);
61 private static final Complex infPiFour = complex(inf, piOverFour);
62 private static final Complex infPi = complex(inf, Math.PI);
63 private static final Complex negInfInf = complex(negInf, inf);
64 private static final Complex negInfZero = complex(negInf, 0);
65 private static final Complex negInfNaN = complex(negInf, nan);
66 private static final Complex negInfPi = complex(negInf, Math.PI);
67 private static final Complex nanInf = complex(nan, inf);
68 private static final Complex nanNegInf = complex(nan, negInf);
69 private static final Complex nanZero = complex(nan, 0);
70 private static final Complex nanPiTwo = complex(nan, piOverTwo);
71 private static final Complex piTwoNaN = complex(piOverTwo, nan);
72 private static final Complex piNegInf = complex(Math.PI, negInf);
73 private static final Complex piTwoNegInf = complex(piOverTwo, negInf);
74 private static final Complex piTwoNegZero = complex(piOverTwo, -0.0);
75 private static final Complex threePiFourNegInf = complex(threePiOverFour, negInf);
76 private static final Complex piFourNegInf = complex(piOverFour, negInf);
77 private static final Complex NAN = complex(nan, nan);
78 private static final Complex maxMax = complex(max, max);
79 private static final Complex maxNan = complex(max, nan);
80 private static final Complex nanMax = complex(nan, max);
81
82
83 private static final double[] finite;
84
85 private static final double[] positiveFinite;
86
87 private static final double[] nonZeroFinite;
88
89 private static final double[] nonZeroPositiveFinite;
90
91 private static final double[] nonZero;
92
93 static {
94
95
96 final int size = 13;
97 finite = new double[size * 2];
98 positiveFinite = new double[size];
99 for (int i = 0; i < size; i++) {
100 final double v = i * 0.5;
101 finite[i * 2] = -v;
102 finite[i * 2 + 1] = v;
103 positiveFinite[i] = v;
104 }
105
106
107 nonZeroFinite = Arrays.copyOfRange(finite, 2, finite.length);
108 nonZeroPositiveFinite = Arrays.copyOfRange(positiveFinite, 1, positiveFinite.length);
109
110 nonZero = Arrays.copyOf(nonZeroFinite, nonZeroFinite.length + 2);
111 nonZero[nonZeroFinite.length] = Double.POSITIVE_INFINITY;
112 nonZero[nonZeroFinite.length + 1] = Double.NEGATIVE_INFINITY;
113
114
115 Arrays.sort(finite);
116 Arrays.sort(nonZeroFinite);
117 Arrays.sort(nonZero);
118 }
119
120
121
122
123 private enum FunctionType {
124
125 ODD,
126
127 EVEN,
128
129 NONE;
130 }
131
132
133
134
135 private enum UnspecifiedSign {
136
137 REAL {
138 @Override
139 Complex removeSign(Complex c) {
140 return negative(c.getReal()) ? complex(-c.getReal(), c.getImaginary()) : c;
141 }
142 },
143
144 IMAGINARY {
145 @Override
146 Complex removeSign(Complex c) {
147 return negative(c.getImaginary()) ? complex(c.getReal(), -c.getImaginary()) : c;
148 }
149 },
150
151 REAL_IMAGINARY {
152 @Override
153 Complex removeSign(Complex c) {
154 return IMAGINARY.removeSign(REAL.removeSign(c));
155 }
156 },
157
158 NONE {
159 @Override
160 Complex removeSign(Complex c) {
161 return c;
162 }
163 };
164
165
166
167
168
169
170
171 abstract Complex removeSign(Complex c);
172
173
174
175
176
177
178
179
180
181
182
183
184
185 private static boolean negative(double d) {
186 return d < 0 || Double.doubleToLongBits(d) == Double.doubleToLongBits(-0.0);
187 }
188 }
189
190
191
192
193
194
195
196
197 private static void assertComplex(Complex c1, Complex c2) {
198
199 Assertions.assertEquals(c2.getReal(), c1.getReal(), 0.0, "real");
200 Assertions.assertEquals(c2.getImaginary(), c1.getImaginary(), 0.0, "imaginary");
201 }
202
203
204
205
206
207
208
209
210
211
212
213 private static void assertOperation(Complex c1, Complex c2,
214 BiFunction<Complex, Complex, Complex> operation, String operationName,
215 Predicate<Complex> expected, String expectedName) {
216 final Complex z = operation.apply(c1, c2);
217 Assertions.assertTrue(expected.test(z),
218 () -> String.format("%s expected: %s %s %s = %s", expectedName, c1, operationName, c2, z));
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 private static void assertConjugateEquality(UnaryOperator<Complex> operation) {
251
252
253
254 final double[] parts = {Double.NEGATIVE_INFINITY, -1, -0.0, 0.0, 1,
255 Double.POSITIVE_INFINITY, Double.NaN};
256 for (final double x : parts) {
257 for (final double y : parts) {
258
259 if (!Double.isNaN(y)) {
260 assertConjugateEquality(complex(x, y), operation, UnspecifiedSign.NONE);
261 }
262 }
263 }
264
265 final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
266 for (int i = 0; i < 100; i++) {
267 final double x = next(rng);
268 final double y = next(rng);
269 assertConjugateEquality(complex(x, y), operation, UnspecifiedSign.NONE);
270 }
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 private static void assertConjugateEquality(Complex z,
288 UnaryOperator<Complex> operation, UnspecifiedSign sign) {
289 final Complex c1 = operation.apply(z.conj());
290 final Complex c2 = operation.apply(z).conj();
291 final Complex t1 = sign.removeSign(c1);
292 final Complex t2 = sign.removeSign(c2);
293
294
295 if (!equals(t1.getReal(), t2.getReal()) ||
296 !equals(t1.getImaginary(), t2.getImaginary())) {
297 Assertions.fail(
298 String.format("Conjugate equality failed (z=%s). Expected: %s but was: %s (Unspecified sign = %s)",
299 z, c1, c2, sign));
300 }
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 private static void assertFunctionType(UnaryOperator<Complex> operation, FunctionType type) {
317
318
319
320
321
322 if (type == FunctionType.NONE) {
323 return;
324 }
325
326
327 final double[] parts = {-2, -1, -0.0, 0.0, 1, 2};
328 for (final double x : parts) {
329 for (final double y : parts) {
330 assertFunctionType(complex(x, y), operation, type, UnspecifiedSign.NONE);
331 }
332 }
333
334 final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
335 for (int i = 0; i < 100; i++) {
336 final double x = next(rng);
337 final double y = next(rng);
338 assertFunctionType(complex(x, y), operation, type, UnspecifiedSign.NONE);
339 }
340 }
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 private static void assertFunctionType(Complex z,
359 UnaryOperator<Complex> operation, FunctionType type, UnspecifiedSign sign) {
360 final Complex c1 = operation.apply(z);
361 Complex c2 = operation.apply(z.negate());
362 if (type == FunctionType.ODD) {
363 c2 = c2.negate();
364 }
365 final Complex t1 = sign.removeSign(c1);
366 final Complex t2 = sign.removeSign(c2);
367
368
369 if (!equals(t1.getReal(), t2.getReal()) ||
370 !equals(t1.getImaginary(), t2.getImaginary())) {
371 Assertions.fail(
372 String.format("%s equality failed (z=%s, -z=%s). Expected: %s but was: %s (Unspecified sign = %s)",
373 type, z, z.negate(), c1, c2, sign));
374 new Exception().printStackTrace();
375 }
376 }
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392 private static void assertComplex(Complex z,
393 UnaryOperator<Complex> operation, Complex expected) {
394 assertComplex(z, operation, expected, FunctionType.NONE, UnspecifiedSign.NONE);
395 }
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412 private static void assertComplex(Complex z,
413 UnaryOperator<Complex> operation, Complex expected, UnspecifiedSign sign) {
414 assertComplex(z, operation, expected, FunctionType.NONE, sign);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439 private static void assertComplex(Complex z,
440 UnaryOperator<Complex> operation, Complex expected,
441 FunctionType type) {
442 assertComplex(z, operation, expected, type, UnspecifiedSign.NONE);
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 private static void assertComplex(Complex z,
473 UnaryOperator<Complex> operation, Complex expected,
474 FunctionType type, UnspecifiedSign sign) {
475
476
477
478
479
480
481 final Complex c = operation.apply(z);
482 final Complex t1 = sign.removeSign(c);
483 final Complex t2 = sign.removeSign(expected);
484 if (!equals(t1.getReal(), t2.getReal()) ||
485 !equals(t1.getImaginary(), t2.getImaginary())) {
486 Assertions.fail(
487 String.format("Operation failed (z=%s). Expected: %s but was: %s (Unspecified sign = %s)",
488 z, expected, c, sign));
489 }
490
491 if (!Double.isNaN(z.getImaginary())) {
492 assertConjugateEquality(z, operation, sign);
493 }
494
495 if (type != FunctionType.NONE) {
496 assertFunctionType(z, operation, type, sign);
497
498
499
500
501
502
503
504
505 if (!Double.isNaN(z.getImaginary())) {
506 assertConjugateEquality(z.negate(), operation, sign);
507 }
508 }
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 private static void assertAbs(Complex z, int ulps) {
536 double x = z.getReal();
537 double y = z.getImaginary();
538
539 final double expected = Math.hypot(x, y);
540 final double observed = z.abs();
541 if (expected == observed) {
542
543 return;
544 }
545
546
547
548
549 int scale = 0;
550 x = Math.abs(x);
551 y = Math.abs(y);
552 if (Math.max(x, y) > 0x1.0p+500) {
553 scale = Math.getExponent(Math.max(x, y));
554 } else if (Math.min(x, y) < 0x1.0p-500) {
555 scale = Math.getExponent(Math.min(x, y));
556 }
557 if (scale != 0) {
558 x = Math.scalb(x, -scale);
559 y = Math.scalb(y, -scale);
560 }
561
562
563 final double result = Math.sqrt(new BigDecimal(x).pow(2).add(new BigDecimal(y).pow(2)).doubleValue());
564 final double exact = scale != 0 ? Math.scalb(result, scale) : result;
565 if (exact == observed) {
566
567 return;
568 }
569
570 final long obsBits = Double.doubleToLongBits(observed);
571 final long exactBits = Double.doubleToLongBits(exact);
572 final long obsUlp = Math.abs(exactBits - obsBits);
573 Assertions.assertTrue(obsUlp <= ulps, () -> {
574
575 final long expBits = Double.doubleToLongBits(expected);
576 final long expUlp = Math.abs(exactBits - expBits);
577 return String.format("%s.abs(). Expected %s, was %s (%d ulps). hypot %s (%d ulps)",
578 z, exact, observed, obsUlp, expected, expUlp);
579 });
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593 private static void assertAbs(UniformRandomProvider rng,
594 ToDoubleFunction<UniformRandomProvider> fx,
595 ToDoubleFunction<UniformRandomProvider> fy,
596 int samples) {
597 for (int i = 0; i < samples; i++) {
598 double x = fx.applyAsDouble(rng);
599 double y = fy.applyAsDouble(rng);
600 assertAbs(Complex.ofCartesian(x, y), 1);
601 }
602 }
603
604
605
606
607
608
609
610
611
612 private static double createSubNormalNumber(UniformRandomProvider rng, int drop) {
613 return Double.longBitsToDouble(rng.nextLong() >>> (12 + drop));
614 }
615
616
617
618
619
620
621
622
623
624 private static double createFixedExponentNumber(UniformRandomProvider rng, int exponent) {
625 return Double.longBitsToDouble((rng.nextLong() >>> 12) | ((1023L + exponent) << 52));
626 }
627
628
629
630
631
632
633
634
635
636 private static boolean equals(double x, double y) {
637 return Double.doubleToLongBits(x) == Double.doubleToLongBits(y);
638 }
639
640
641
642
643
644
645
646
647 private static Complex complex(double real, double imaginary) {
648 return Complex.ofCartesian(real, imaginary);
649 }
650
651
652
653
654
655
656 private static ArrayList<Complex> createInfinites() {
657 final double[] values = {0, 1, inf, negInf, nan};
658 return createCombinations(values, Complex::isInfinite);
659 }
660
661
662
663
664
665
666 private static ArrayList<Complex> createNonZeroFinites() {
667 final double[] values = {-1, -0, 0, 1, Double.MAX_VALUE};
668 return createCombinations(values, c -> !CStandardTest.isZero(c));
669 }
670
671
672
673
674
675
676 private static ArrayList<Complex> createZeroFinites() {
677 final double[] values = {-0, 0};
678 return createCombinations(values, c -> true);
679 }
680
681
682
683
684
685
686 private static ArrayList<Complex> createNaNs() {
687 final double[] values = {0, 1, nan};
688 return createCombinations(values, Complex::isNaN);
689 }
690
691
692
693
694
695
696
697
698
699 private static ArrayList<Complex> createCombinations(final double[] values, Predicate<Complex> condition) {
700 final ArrayList<Complex> list = new ArrayList<>();
701 for (final double re : values) {
702 for (final double im : values) {
703 final Complex z = complex(re, im);
704 if (condition.test(z)) {
705 list.add(z);
706 }
707 }
708 }
709 return list;
710 }
711
712
713
714
715
716
717
718
719 private static boolean isZero(Complex c) {
720 return c.getReal() == 0 && c.getImaginary() == 0;
721 }
722
723
724
725
726 @Test
727 void testMultiply() {
728 final ArrayList<Complex> infinites = createInfinites();
729 final ArrayList<Complex> nonZeroFinites = createNonZeroFinites();
730 final ArrayList<Complex> zeroFinites = createZeroFinites();
731
732
733
734 Assertions.assertEquals(nan, 0.0 * inf, "0 * inf");
735 Assertions.assertEquals(nan, 0.0 * negInf, "0 * -inf");
736 Assertions.assertEquals(nan, -0.0 * inf, "-0 * inf");
737 Assertions.assertEquals(nan, -0.0 * negInf, "-0 * -inf");
738
739
740
741 for (final Complex z : infinites) {
742 for (final Complex w : infinites) {
743 assertOperation(z, w, Complex::multiply, "*", Complex::isInfinite, "Inf");
744 assertOperation(w, z, Complex::multiply, "*", Complex::isInfinite, "Inf");
745 }
746 for (final Complex w : nonZeroFinites) {
747 assertOperation(z, w, Complex::multiply, "*", Complex::isInfinite, "Inf");
748 assertOperation(w, z, Complex::multiply, "*", Complex::isInfinite, "Inf");
749 }
750
751
752 for (final Complex w : zeroFinites) {
753 assertOperation(z, w, Complex::multiply, "*", Complex::isNaN, "NaN");
754 assertOperation(w, z, Complex::multiply, "*", Complex::isNaN, "NaN");
755 }
756 }
757
758
759
760
761
762
763
764
765
766
767
768 final double[] values = {0, 1, inf, negInf, nan};
769 for (final Complex z : createCombinations(values, c -> true)) {
770 assertOperation(z, NAN, Complex::multiply, "*", Complex::isNaN, "NaN");
771 assertOperation(NAN, z, Complex::multiply, "*", Complex::isNaN, "NaN");
772 }
773
774
775 assertOperation(maxMax, maxMax, Complex::multiply, "*", Complex::isInfinite, "Inf");
776 assertOperation(maxNan, maxNan, Complex::multiply, "*", Complex::isInfinite, "Inf");
777 assertOperation(nanMax, maxNan, Complex::multiply, "*", Complex::isInfinite, "Inf");
778 assertOperation(maxNan, nanMax, Complex::multiply, "*", Complex::isInfinite, "Inf");
779 assertOperation(nanMax, nanMax, Complex::multiply, "*", Complex::isInfinite, "Inf");
780 }
781
782
783
784
785 @Test
786 void testDivide() {
787 final ArrayList<Complex> infinites = createInfinites();
788 final ArrayList<Complex> nonZeroFinites = createNonZeroFinites();
789 final ArrayList<Complex> zeroFinites = createZeroFinites();
790 final ArrayList<Complex> nans = createNaNs();
791 final ArrayList<Complex> finites = new ArrayList<>(nonZeroFinites);
792 finites.addAll(zeroFinites);
793
794
795
796 for (final Complex z : infinites) {
797 for (final Complex w : nonZeroFinites) {
798 assertOperation(z, w, Complex::divide, "/", Complex::isInfinite, "Inf");
799 }
800 for (final Complex w : zeroFinites) {
801 assertOperation(z, w, Complex::divide, "/", Complex::isInfinite, "Inf");
802 }
803
804 for (final Complex w : infinites) {
805 assertOperation(z, w, Complex::divide, "/", Complex::isNaN, "NaN");
806 }
807 }
808
809
810
811 for (final Complex z : finites) {
812 for (final Complex w : infinites) {
813 assertOperation(z, w, Complex::divide, "/", CStandardTest::isZero, "Zero");
814 }
815 }
816
817
818
819 for (final Complex w : zeroFinites) {
820 for (final Complex z : nonZeroFinites) {
821 assertOperation(z, w, Complex::divide, "/", Complex::isInfinite, "Inf");
822 }
823 for (final Complex z : infinites) {
824 assertOperation(z, w, Complex::divide, "/", Complex::isInfinite, "Inf");
825 }
826 }
827
828
829
830
831 for (final Complex w : nans) {
832 for (final Complex z : finites) {
833 assertOperation(z, w, Complex::divide, "/", c -> NAN.equals(c), "(NaN,NaN)");
834 }
835 for (final Complex z : infinites) {
836 assertOperation(z, w, Complex::divide, "/", c -> NAN.equals(c), "(NaN,NaN)");
837 }
838 }
839
840
841 for (final Complex w : zeroFinites) {
842 assertOperation(NAN, w, Complex::divide, "/", Complex::isNaN, "NaN");
843 }
844 for (final Complex w : infinites) {
845 assertOperation(NAN, w, Complex::divide, "/", Complex::isNaN, "NaN");
846 }
847 }
848
849
850
851
852 @Test
853 void testSqrt1() {
854 assertComplex(complex(-2.0, 0.0).sqrt(), complex(0.0, Math.sqrt(2)));
855 assertComplex(complex(-2.0, -0.0).sqrt(), complex(0.0, -Math.sqrt(2)));
856 }
857
858
859
860
861 @Test
862 void testImplicitTrig() {
863 final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
864 for (int i = 0; i < 100; i++) {
865 final double re = next(rng);
866 final double im = next(rng);
867 final Complex z = complex(re, im);
868 final Complex iz = z.multiplyImaginary(1);
869 assertComplex(z.asin(), iz.asinh().multiplyImaginary(-1));
870 assertComplex(z.atan(), iz.atanh().multiplyImaginary(-1));
871 assertComplex(z.cos(), iz.cosh());
872 assertComplex(z.sin(), iz.sinh().multiplyImaginary(-1));
873 assertComplex(z.tan(), iz.tanh().multiplyImaginary(-1));
874 }
875 }
876
877
878
879
880
881
882
883 private static double next(UniformRandomProvider rng) {
884
885 return (rng.nextDouble() - rng.nextInt(1)) * 5;
886 }
887
888
889
890
891
892 @Test
893 void testAbs() {
894 Assertions.assertEquals(inf, complex(inf, nan).abs());
895 Assertions.assertEquals(inf, complex(negInf, nan).abs());
896 final UniformRandomProvider rng = RandomSource.XO_RO_SHI_RO_128_PP.create();
897 for (int i = 0; i < 10; i++) {
898 final double x = next(rng);
899 final double y = next(rng);
900 Assertions.assertEquals(complex(x, y).abs(), complex(y, x).abs());
901 Assertions.assertEquals(complex(x, y).abs(), complex(x, -y).abs());
902 Assertions.assertEquals(Math.abs(x), complex(x, 0.0).abs());
903 Assertions.assertEquals(Math.abs(x), complex(x, -0.0).abs());
904 Assertions.assertEquals(inf, complex(inf, y).abs());
905 Assertions.assertEquals(inf, complex(negInf, y).abs());
906 }
907
908
909
910 final double[] parts = {-0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL, -Double.MAX_VALUE,
911 Double.NEGATIVE_INFINITY, Double.NaN};
912 for (final double x : parts) {
913 for (final double y : parts) {
914 Assertions.assertEquals(Math.hypot(x, y), complex(x, y).abs());
915 }
916 }
917
918
919
920
921
922
923
924 for (final double[] pair : new double[][] {
925 {1.3122561682406755, 1.3122565442732959},
926 {1.40905821964671, 1.4090583434236112},
927 {1.912164268932753, 1.9121638616231227}}) {
928 final Complex z = complex(pair[0], pair[1]);
929 Assertions.assertEquals(z.abs(), z.multiplyImaginary(1).abs(), "Expected |z| == |iz|");
930 }
931
932
933
934
935
936
937
938
939
940
941
942
943
944 final int samples = 100;
945 assertAbs(rng, r -> createSubNormalNumber(r, 0), r -> createSubNormalNumber(r, 0), samples);
946 assertAbs(rng, r -> createSubNormalNumber(r, 0), r -> createSubNormalNumber(r, 1), samples);
947 assertAbs(rng, r -> createSubNormalNumber(r, 0), r -> createSubNormalNumber(r, 2), samples);
948
949 assertAbs(rng, r -> createFixedExponentNumber(r, 0), r -> createFixedExponentNumber(r, 0), samples);
950
951 assertAbs(rng, r -> createFixedExponentNumber(r, 0), r -> createFixedExponentNumber(r, 1), samples);
952 assertAbs(rng, r -> createFixedExponentNumber(r, 0), r -> createFixedExponentNumber(r, 2 + r.nextInt(10)), samples);
953
954 assertAbs(rng, r -> createFixedExponentNumber(r, 1022), r -> createFixedExponentNumber(r, 1022), samples);
955 assertAbs(rng, r -> createFixedExponentNumber(r, -1022), r -> createFixedExponentNumber(r, -1022), samples);
956
957 final ToDoubleFunction<UniformRandomProvider> cisGenerator = new ToDoubleFunction<UniformRandomProvider>() {
958 private double tmp = Double.NaN;
959 @Override
960 public double applyAsDouble(UniformRandomProvider rng) {
961 if (Double.isNaN(tmp)) {
962 double u = rng.nextDouble() * Math.PI;
963 tmp = Math.cos(u);
964 return Math.sin(u);
965 }
966 final double r = tmp;
967 tmp = Double.NaN;
968 return r;
969 }
970 };
971 assertAbs(rng, cisGenerator, cisGenerator, samples);
972 }
973
974
975
976
977 @Test
978 void testAcos() {
979 final UnaryOperator<Complex> operation = Complex::acos;
980 assertConjugateEquality(operation);
981 assertComplex(Complex.ZERO, operation, piTwoNegZero);
982 assertComplex(negZeroZero, operation, piTwoNegZero);
983 assertComplex(zeroNaN, operation, piTwoNaN);
984 assertComplex(negZeroNaN, operation, piTwoNaN);
985 for (double x : finite) {
986 assertComplex(complex(x, inf), operation, piTwoNegInf);
987 }
988 for (double x : nonZeroFinite) {
989 assertComplex(complex(x, nan), operation, NAN);
990 }
991 for (double y : positiveFinite) {
992 assertComplex(complex(-inf, y), operation, piNegInf);
993 }
994 for (double y : positiveFinite) {
995 assertComplex(complex(inf, y), operation, zeroNegInf);
996 }
997 assertComplex(negInfInf, operation, threePiFourNegInf);
998 assertComplex(infInf, operation, piFourNegInf);
999 assertComplex(infNaN, operation, nanInf, UnspecifiedSign.IMAGINARY);
1000 assertComplex(negInfNaN, operation, nanNegInf, UnspecifiedSign.IMAGINARY);
1001 for (double y : finite) {
1002 assertComplex(complex(nan, y), operation, NAN);
1003 }
1004 assertComplex(nanInf, operation, nanNegInf);
1005 assertComplex(NAN, operation, NAN);
1006 }
1007
1008
1009
1010
1011
1012
1013
1014 @Test
1015 void testAcosh() {
1016 final UnaryOperator<Complex> operation = Complex::acosh;
1017 assertConjugateEquality(operation);
1018 assertComplex(Complex.ZERO, operation, zeroPiTwo);
1019 assertComplex(negZeroZero, operation, zeroPiTwo);
1020 for (double x : finite) {
1021 assertComplex(complex(x, inf), operation, infPiTwo);
1022 }
1023 assertComplex(zeroNaN, operation, nanPiTwo);
1024 assertComplex(negZeroNaN, operation, nanPiTwo);
1025 for (double x : nonZeroFinite) {
1026 assertComplex(complex(x, nan), operation, NAN);
1027 }
1028 for (double y : positiveFinite) {
1029 assertComplex(complex(-inf, y), operation, infPi);
1030 }
1031 for (double y : positiveFinite) {
1032 assertComplex(complex(inf, y), operation, infZero);
1033 }
1034 assertComplex(negInfInf, operation, infThreePiFour);
1035 assertComplex(infInf, operation, infPiFour);
1036 assertComplex(infNaN, operation, infNaN);
1037 assertComplex(negInfNaN, operation, infNaN);
1038 for (double y : finite) {
1039 assertComplex(complex(nan, y), operation, NAN);
1040 }
1041 assertComplex(nanInf, operation, infNaN);
1042 assertComplex(NAN, operation, NAN);
1043 }
1044
1045
1046
1047
1048 @Test
1049 void testAsinh() {
1050 final UnaryOperator<Complex> operation = Complex::asinh;
1051 final FunctionType type = FunctionType.ODD;
1052 assertConjugateEquality(operation);
1053 assertFunctionType(operation, type);
1054 assertComplex(Complex.ZERO, operation, Complex.ZERO, type);
1055 for (double x : positiveFinite) {
1056 assertComplex(complex(x, inf), operation, infPiTwo, type);
1057 }
1058 for (double x : finite) {
1059 assertComplex(complex(x, nan), operation, NAN, type);
1060 }
1061 for (double y : positiveFinite) {
1062 assertComplex(complex(inf, y), operation, infZero, type);
1063 }
1064 assertComplex(infInf, operation, infPiFour, type);
1065 assertComplex(infNaN, operation, infNaN, type);
1066 assertComplex(nanZero, operation, nanZero, type);
1067 for (double y : nonZeroFinite) {
1068 assertComplex(complex(nan, y), operation, NAN, type);
1069 }
1070 assertComplex(nanInf, operation, infNaN, type, UnspecifiedSign.REAL);
1071 assertComplex(NAN, operation, NAN, type);
1072 }
1073
1074
1075
1076
1077 @Test
1078 void testAtanh() {
1079 final UnaryOperator<Complex> operation = Complex::atanh;
1080 final FunctionType type = FunctionType.ODD;
1081 assertConjugateEquality(operation);
1082 assertFunctionType(operation, type);
1083 assertComplex(Complex.ZERO, operation, Complex.ZERO, type);
1084 assertComplex(zeroNaN, operation, zeroNaN, type);
1085 assertComplex(oneZero, operation, infZero, type);
1086 for (double x : positiveFinite) {
1087 assertComplex(complex(x, inf), operation, zeroPiTwo, type);
1088 }
1089 for (double x : nonZeroFinite) {
1090 assertComplex(complex(x, nan), operation, NAN, type);
1091 }
1092 for (double y : positiveFinite) {
1093 assertComplex(complex(inf, y), operation, zeroPiTwo, type);
1094 }
1095 assertComplex(infInf, operation, zeroPiTwo, type);
1096 assertComplex(infNaN, operation, zeroNaN, type);
1097 assertComplex(nanZero, operation, NAN, type);
1098 for (double y : finite) {
1099 assertComplex(complex(nan, y), operation, NAN, type);
1100 }
1101 assertComplex(nanInf, operation, zeroPiTwo, type, UnspecifiedSign.REAL);
1102 assertComplex(NAN, operation, NAN, type);
1103 }
1104
1105
1106
1107
1108 @Test
1109 void testCosh() {
1110 final UnaryOperator<Complex> operation = Complex::cosh;
1111 final FunctionType type = FunctionType.EVEN;
1112 assertConjugateEquality(operation);
1113 assertFunctionType(operation, type);
1114 assertComplex(Complex.ZERO, operation, Complex.ONE, type);
1115 assertComplex(zeroInf, operation, nanZero, type, UnspecifiedSign.IMAGINARY);
1116 assertComplex(zeroNaN, operation, nanZero, type, UnspecifiedSign.IMAGINARY);
1117 for (double x : nonZeroFinite) {
1118 assertComplex(complex(x, inf), operation, NAN, type);
1119 }
1120 for (double x : nonZeroFinite) {
1121 assertComplex(complex(x, nan), operation, NAN, type);
1122 }
1123 assertComplex(infZero, operation, infZero, type);
1124 for (double y : nonZeroFinite) {
1125 assertComplex(complex(inf, y), operation, Complex.ofCis(y).multiply(inf), type);
1126 }
1127 assertComplex(infInf, operation, infNaN, type, UnspecifiedSign.REAL);
1128 assertComplex(infNaN, operation, infNaN, type);
1129 assertComplex(nanZero, operation, nanZero, type, UnspecifiedSign.IMAGINARY);
1130 for (double y : nonZero) {
1131 assertComplex(complex(nan, y), operation, NAN, type);
1132 }
1133 assertComplex(NAN, operation, NAN, type);
1134 }
1135
1136
1137
1138
1139 @Test
1140 void testSinh() {
1141 final UnaryOperator<Complex> operation = Complex::sinh;
1142 final FunctionType type = FunctionType.ODD;
1143 assertConjugateEquality(operation);
1144 assertFunctionType(operation, type);
1145 assertComplex(Complex.ZERO, operation, Complex.ZERO, type);
1146 assertComplex(zeroInf, operation, zeroNaN, type, UnspecifiedSign.REAL);
1147 assertComplex(zeroNaN, operation, zeroNaN, type, UnspecifiedSign.REAL);
1148 for (double x : nonZeroPositiveFinite) {
1149 assertComplex(complex(x, inf), operation, NAN, type);
1150 }
1151 for (double x : nonZeroFinite) {
1152 assertComplex(complex(x, nan), operation, NAN, type);
1153 }
1154 assertComplex(infZero, operation, infZero, type);
1155
1156 for (double y : nonZeroFinite) {
1157 assertComplex(complex(inf, y), operation, Complex.ofCis(y).multiply(inf), type);
1158 }
1159 assertComplex(infInf, operation, infNaN, type, UnspecifiedSign.REAL);
1160 assertComplex(infNaN, operation, infNaN, type, UnspecifiedSign.REAL);
1161 assertComplex(nanZero, operation, nanZero, type);
1162 for (double y : nonZero) {
1163 assertComplex(complex(nan, y), operation, NAN, type);
1164 }
1165 assertComplex(NAN, operation, NAN, type);
1166 }
1167
1168
1169
1170
1171
1172
1173
1174 @Test
1175 void testTanh() {
1176 final UnaryOperator<Complex> operation = Complex::tanh;
1177 final FunctionType type = FunctionType.ODD;
1178 assertConjugateEquality(operation);
1179 assertFunctionType(operation, type);
1180 assertComplex(Complex.ZERO, operation, Complex.ZERO, type);
1181 assertComplex(zeroInf, operation, zeroNaN, type);
1182 for (double x : nonZeroFinite) {
1183 assertComplex(complex(x, inf), operation, NAN, type);
1184 }
1185 assertComplex(zeroNaN, operation, zeroNaN, type);
1186 for (double x : nonZeroFinite) {
1187 assertComplex(complex(x, nan), operation, NAN, type);
1188 }
1189 for (double y : positiveFinite) {
1190 assertComplex(complex(inf, y), operation, complex(1.0, Math.copySign(0, Math.sin(2 * y))), type);
1191 }
1192 assertComplex(infInf, operation, oneZero, type, UnspecifiedSign.IMAGINARY);
1193 assertComplex(infNaN, operation, oneZero, type, UnspecifiedSign.IMAGINARY);
1194 assertComplex(nanZero, operation, nanZero, type);
1195 for (double y : nonZero) {
1196 assertComplex(complex(nan, y), operation, NAN, type);
1197 }
1198 assertComplex(NAN, operation, NAN, type);
1199 }
1200
1201
1202
1203
1204 @Test
1205 void testExp() {
1206 final UnaryOperator<Complex> operation = Complex::exp;
1207 assertConjugateEquality(operation);
1208 assertComplex(Complex.ZERO, operation, oneZero);
1209 assertComplex(negZeroZero, operation, oneZero);
1210 for (double x : finite) {
1211 assertComplex(complex(x, inf), operation, NAN);
1212 }
1213 for (double x : finite) {
1214 assertComplex(complex(x, nan), operation, NAN);
1215 }
1216 assertComplex(infZero, operation, infZero);
1217 for (double y : finite) {
1218 assertComplex(complex(-inf, y), operation, Complex.ofCis(y).multiply(0.0));
1219 }
1220 for (double y : nonZeroFinite) {
1221 assertComplex(complex(inf, y), operation, Complex.ofCis(y).multiply(inf));
1222 }
1223 assertComplex(negInfInf, operation, Complex.ZERO, UnspecifiedSign.REAL_IMAGINARY);
1224 assertComplex(infInf, operation, infNaN, UnspecifiedSign.REAL);
1225 assertComplex(negInfNaN, operation, Complex.ZERO, UnspecifiedSign.REAL_IMAGINARY);
1226 assertComplex(infNaN, operation, infNaN, UnspecifiedSign.REAL);
1227 assertComplex(nanZero, operation, nanZero);
1228 for (double y : nonZero) {
1229 assertComplex(complex(nan, y), operation, NAN);
1230 }
1231 assertComplex(NAN, operation, NAN);
1232 }
1233
1234
1235
1236
1237 @Test
1238 void testLog() {
1239 final UnaryOperator<Complex> operation = Complex::log;
1240 assertConjugateEquality(operation);
1241 assertComplex(negZeroZero, operation, negInfPi);
1242 assertComplex(Complex.ZERO, operation, negInfZero);
1243 for (double x : finite) {
1244 assertComplex(complex(x, inf), operation, infPiTwo);
1245 }
1246 for (double x : finite) {
1247 assertComplex(complex(x, nan), operation, NAN);
1248 }
1249 for (double y : positiveFinite) {
1250 assertComplex(complex(-inf, y), operation, infPi);
1251 }
1252 for (double y : positiveFinite) {
1253 assertComplex(complex(inf, y), operation, infZero);
1254 }
1255 assertComplex(negInfInf, operation, infThreePiFour);
1256 assertComplex(infInf, operation, infPiFour);
1257 assertComplex(negInfNaN, operation, infNaN);
1258 assertComplex(infNaN, operation, infNaN);
1259 for (double y : finite) {
1260 assertComplex(complex(nan, y), operation, NAN);
1261 }
1262 assertComplex(nanInf, operation, infNaN);
1263 assertComplex(NAN, operation, NAN);
1264 }
1265
1266
1267
1268
1269
1270 @Test
1271 void testLog10() {
1272 final UnaryOperator<Complex> operation = Complex::log10;
1273 assertConjugateEquality(operation);
1274 assertComplex(negZeroZero, operation, negInfPi);
1275 assertComplex(Complex.ZERO, operation, negInfZero);
1276 for (double x : finite) {
1277 assertComplex(complex(x, inf), operation, infPiTwo);
1278 }
1279 for (double x : finite) {
1280 assertComplex(complex(x, nan), operation, NAN);
1281 }
1282 for (double y : positiveFinite) {
1283 assertComplex(complex(-inf, y), operation, infPi);
1284 }
1285 for (double y : positiveFinite) {
1286 assertComplex(complex(inf, y), operation, infZero);
1287 }
1288 assertComplex(negInfInf, operation, infThreePiFour);
1289 assertComplex(infInf, operation, infPiFour);
1290 assertComplex(negInfNaN, operation, infNaN);
1291 assertComplex(infNaN, operation, infNaN);
1292 for (double y : finite) {
1293 assertComplex(complex(nan, y), operation, NAN);
1294 }
1295 assertComplex(nanInf, operation, infNaN);
1296 assertComplex(NAN, operation, NAN);
1297 }
1298
1299
1300
1301
1302 @Test
1303 void testSqrt() {
1304 final UnaryOperator<Complex> operation = Complex::sqrt;
1305 assertConjugateEquality(operation);
1306 assertComplex(negZeroZero, operation, Complex.ZERO);
1307 assertComplex(Complex.ZERO, operation, Complex.ZERO);
1308 for (double x : finite) {
1309 assertComplex(complex(x, inf), operation, infInf);
1310 }
1311
1312 assertComplex(infInf, operation, infInf);
1313 assertComplex(negInfInf, operation, infInf);
1314 assertComplex(nanInf, operation, infInf);
1315 for (double x : finite) {
1316 assertComplex(complex(x, nan), operation, NAN);
1317 }
1318 for (double y : positiveFinite) {
1319 assertComplex(complex(-inf, y), operation, zeroInf);
1320 }
1321 for (double y : positiveFinite) {
1322 assertComplex(complex(inf, y), operation, infZero);
1323 }
1324 assertComplex(negInfNaN, operation, nanInf, UnspecifiedSign.IMAGINARY);
1325 assertComplex(infNaN, operation, infNaN);
1326 for (double y : finite) {
1327 assertComplex(complex(nan, y), operation, NAN);
1328 }
1329 assertComplex(NAN, operation, NAN);
1330 }
1331 }