View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.complex;
24  
25  import org.hipparchus.CalculusFieldElementAbstractTest;
26  import org.hipparchus.UnitTestUtils;
27  import org.hipparchus.exception.LocalizedCoreFormats;
28  import org.hipparchus.exception.MathIllegalArgumentException;
29  import org.hipparchus.exception.NullArgumentException;
30  import org.hipparchus.util.Binary64;
31  import org.hipparchus.util.FastMath;
32  import org.hipparchus.util.MathUtils;
33  import org.hipparchus.util.Precision;
34  import org.junit.jupiter.api.Assertions;
35  import org.junit.jupiter.api.Test;
36  
37  import java.util.Arrays;
38  import java.util.List;
39  
40  import static org.junit.jupiter.api.Assertions.assertEquals;
41  import static org.junit.jupiter.api.Assertions.assertFalse;
42  import static org.junit.jupiter.api.Assertions.assertNotEquals;
43  import static org.junit.jupiter.api.Assertions.assertSame;
44  import static org.junit.jupiter.api.Assertions.assertThrows;
45  import static org.junit.jupiter.api.Assertions.assertTrue;
46  import static org.junit.jupiter.api.Assertions.fail;
47  
48  
49  /**
50   */
51  class ComplexTest extends CalculusFieldElementAbstractTest<Complex> {
52  
53  
54      private double inf = Double.POSITIVE_INFINITY;
55      private double neginf = Double.NEGATIVE_INFINITY;
56      private double nan = Double.NaN;
57      private double pi = FastMath.PI;
58      private Complex oneInf = new Complex(1, inf);
59      private Complex oneNegInf = new Complex(1, neginf);
60      private Complex infOne = new Complex(inf, 1);
61      private Complex infZero = new Complex(inf, 0);
62      private Complex infNaN = new Complex(inf, nan);
63      private Complex infNegInf = new Complex(inf, neginf);
64      private Complex infInf = new Complex(inf, inf);
65      private Complex negInfInf = new Complex(neginf, inf);
66      private Complex negInfZero = new Complex(neginf, 0);
67      private Complex negInfOne = new Complex(neginf, 1);
68      private Complex negInfNaN = new Complex(neginf, nan);
69      private Complex negInfNegInf = new Complex(neginf, neginf);
70      private Complex oneNaN = new Complex(1, nan);
71      private Complex zeroInf = new Complex(0, inf);
72      private Complex zeroNaN = new Complex(0, nan);
73      private Complex nanInf = new Complex(nan, inf);
74      private Complex nanNegInf = new Complex(nan, neginf);
75      private Complex nanZero = new Complex(nan, 0);
76  
77      @Override
78      protected Complex build(final double x) {
79          return new Complex(x, 0.0);
80      }
81  
82      @Test
83      void testConstructor() {
84          Complex z = new Complex(3.0, 4.0);
85          assertEquals(3.0, z.getReal(), 1.0e-5);
86          assertEquals(4.0, z.getImaginary(), 1.0e-5);
87          assertEquals(3.0, z.getRealPart(), 1.0e-5);
88          assertEquals(4.0, z.getImaginaryPart(), 1.0e-5);
89      }
90  
91      @Test
92      void testConstructorNaN() {
93          Complex z = new Complex(3.0, Double.NaN);
94          assertTrue(z.isNaN());
95  
96          z = new Complex(nan, 4.0);
97          assertTrue(z.isNaN());
98  
99          z = new Complex(3.0, 4.0);
100         assertFalse(z.isNaN());
101     }
102 
103     @Test
104     void testNorm() {
105         Complex z = new Complex(3.0, 4.0);
106         assertEquals(5.0, z.norm(), 1.0e-5);
107     }
108 
109     @Test
110     void testNormNaN() {
111         assertTrue(Double.isNaN(Complex.NaN.norm()));
112         Complex z = new Complex(inf, nan);
113         assertTrue(Double.isNaN(z.norm()));
114     }
115 
116     @Test
117     void testNormInfinite() {
118         Complex z = Complex.NaN.newInstance(inf);
119         assertEquals(inf, z.norm(), 0);
120         z = new Complex(0, neginf);
121         assertEquals(inf, z.norm(), 0);
122         z = new Complex(inf, neginf);
123         assertEquals(inf, z.norm(), 0);
124     }
125 
126     @Test
127     void testAdd() {
128         Complex x = new Complex(3.0, 4.0);
129         Complex y = new Complex(5.0, 6.0);
130         Complex z = x.add(y);
131         assertEquals(8.0, z.getReal(), 1.0e-5);
132         assertEquals(10.0, z.getImaginary(), 1.0e-5);
133     }
134 
135     @Test
136     void testAddNaN() {
137         Complex x = new Complex(3.0, 4.0);
138         Complex z = x.add(Complex.NaN);
139         assertSame(Complex.NaN, z);
140         z = new Complex(1, nan);
141         Complex w = x.add(z);
142         assertSame(Complex.NaN, w);
143         assertSame(Complex.NaN, Complex.NaN.add(Double.NaN));
144     }
145 
146     @Test
147     void testAddInf() {
148         Complex x = new Complex(1, 1);
149         Complex z = new Complex(inf, 0);
150         Complex w = x.add(z);
151         assertEquals(1, w.getImaginary(), 0);
152         assertEquals(inf, w.getReal(), 0);
153 
154         x = new Complex(neginf, 0);
155         assertTrue(Double.isNaN(x.add(z).getReal()));
156     }
157 
158     @Test
159     void testScalarAdd() {
160         Complex x = new Complex(3.0, 4.0);
161         double yDouble = 2.0;
162         Complex yComplex = new Complex(yDouble);
163         assertEquals(x.add(yComplex), x.add(yDouble));
164     }
165 
166     @Test
167     void testScalarAddNaN() {
168         Complex x = new Complex(3.0, 4.0);
169         double yDouble = Double.NaN;
170         Complex yComplex = new Complex(yDouble);
171         assertEquals(x.add(yComplex), x.add(yDouble));
172     }
173 
174     @Test
175     void testScalarAddInf() {
176         Complex x = new Complex(1, 1);
177         double yDouble = Double.POSITIVE_INFINITY;
178 
179         Complex yComplex = new Complex(yDouble);
180         assertEquals(x.add(yComplex), x.add(yDouble));
181 
182         x = new Complex(neginf, 0);
183         assertEquals(x.add(yComplex), x.add(yDouble));
184     }
185 
186     @Test
187     void testConjugate() {
188         Complex x = new Complex(3.0, 4.0);
189         Complex z = x.conjugate();
190         assertEquals(3.0, z.getReal(), 1.0e-5);
191         assertEquals(-4.0, z.getImaginary(), 1.0e-5);
192     }
193 
194     @Test
195     void testConjugateNaN() {
196         Complex z = Complex.NaN.conjugate();
197         assertTrue(z.isNaN());
198     }
199 
200     @Test
201     void testConjugateInfiinite() {
202         Complex z = new Complex(0, inf);
203         assertEquals(neginf, z.conjugate().getImaginary(), 0);
204         z = new Complex(0, neginf);
205         assertEquals(inf, z.conjugate().getImaginary(), 0);
206     }
207 
208     @Test
209     void testDivide() {
210         Complex x = new Complex(3.0, 4.0);
211         Complex y = new Complex(5.0, 6.0);
212         Complex z = x.divide(y);
213         assertEquals(39.0 / 61.0, z.getReal(), 1.0e-5);
214         assertEquals(2.0 / 61.0, z.getImaginary(), 1.0e-5);
215     }
216 
217     @Test
218     void testDivideReal() {
219         Complex x = new Complex(2d, 3d);
220         Complex y = new Complex(2d, 0d);
221         assertEquals(new Complex(1d, 1.5), x.divide(y));
222 
223     }
224 
225     @Test
226     void testDivideImaginary() {
227         Complex x = new Complex(2d, 3d);
228         Complex y = new Complex(0d, 2d);
229         assertEquals(new Complex(1.5d, -1d), x.divide(y));
230     }
231 
232     @Test
233     void testDivideInf() {
234         Complex x = new Complex(3, 4);
235         Complex w = new Complex(neginf, inf);
236         assertEquals(Complex.ZERO, x.divide(w));
237 
238         Complex z = w.divide(x);
239         assertTrue(Double.isNaN(z.getReal()));
240         assertEquals(inf, z.getImaginary(), 0);
241 
242         w = new Complex(inf, inf);
243         z = w.divide(x);
244         assertTrue(Double.isNaN(z.getImaginary()));
245         assertEquals(inf, z.getReal(), 0);
246 
247         w = new Complex(1, inf);
248         z = w.divide(w);
249         assertTrue(Double.isNaN(z.getReal()));
250         assertTrue(Double.isNaN(z.getImaginary()));
251     }
252 
253     @Test
254     void testDivideZero() {
255         Complex x = new Complex(3.0, 4.0);
256         Complex z = x.divide(Complex.ZERO);
257         // Assertions.assertEquals(z, Complex.INF); // See MATH-657
258         assertEquals(Complex.NaN, z);
259     }
260 
261     @Test
262     void testDivideZeroZero() {
263         Complex x = new Complex(0.0, 0.0);
264         Complex z = x.divide(Complex.ZERO);
265         assertEquals(Complex.NaN, z);
266     }
267 
268     @Test
269     void testDivideNaN() {
270         Complex x = new Complex(3.0, 4.0);
271         Complex z = x.divide(Complex.NaN);
272         assertTrue(z.isNaN());
273         assertTrue(Complex.NaN.divide(Complex.NaN).isNaN());
274     }
275 
276     @Test
277     void testDivideNaNInf() {
278        Complex z = oneInf.divide(Complex.ONE);
279        assertTrue(Double.isNaN(z.getReal()));
280        assertEquals(inf, z.getImaginary(), 0);
281 
282        z = negInfNegInf.divide(oneNaN);
283        assertTrue(Double.isNaN(z.getReal()));
284        assertTrue(Double.isNaN(z.getImaginary()));
285 
286        z = negInfInf.divide(Complex.ONE);
287        assertTrue(Double.isNaN(z.getReal()));
288        assertTrue(Double.isNaN(z.getImaginary()));
289     }
290 
291     @Test
292     void testScalarDivide() {
293         Complex x = new Complex(3.0, 4.0);
294         double yDouble = 2.0;
295         Complex yComplex = new Complex(yDouble);
296         assertEquals(x.divide(yComplex), x.divide(yDouble));
297     }
298 
299     @Test
300     void testScalarDivideNaN() {
301         Complex x = new Complex(3.0, 4.0);
302         double yDouble = Double.NaN;
303         Complex yComplex = new Complex(yDouble);
304         assertEquals(x.divide(yComplex), x.divide(yDouble));
305         assertTrue(Complex.NaN.divide(Double.NaN).isNaN());
306     }
307 
308     @Test
309     void testScalarDivideInf() {
310         Complex x = new Complex(1,1);
311         double yDouble = Double.POSITIVE_INFINITY;
312         Complex yComplex = new Complex(yDouble);
313         UnitTestUtils.customAssertEquals(x.divide(yComplex), x.divide(yDouble), 0);
314 
315         yDouble = Double.NEGATIVE_INFINITY;
316         yComplex = new Complex(yDouble);
317         UnitTestUtils.customAssertEquals(x.divide(yComplex), x.divide(yDouble), 0);
318 
319         x = new Complex(1, Double.NEGATIVE_INFINITY);
320         UnitTestUtils.customAssertEquals(x.divide(yComplex), x.divide(yDouble), 0);
321     }
322 
323     @Test
324     void testScalarDivideZero() {
325         Complex x = new Complex(1,1);
326         UnitTestUtils.customAssertEquals(x.divide(Complex.ZERO), x.divide(0), 0);
327     }
328 
329     @Test
330     void testReciprocal() {
331         Complex z = new Complex(5.0, 6.0);
332         Complex act = z.reciprocal();
333         double expRe = 5.0 / 61.0;
334         double expIm = -6.0 / 61.0;
335         assertEquals(expRe, act.getReal(), FastMath.ulp(expRe));
336         assertEquals(expIm, act.getImaginary(), FastMath.ulp(expIm));
337     }
338 
339     @Test
340     void testReciprocalReal() {
341         Complex z = new Complex(-2.0, 0.0);
342         assertTrue(Complex.equals(new Complex(-0.5, 0.0), z.reciprocal()));
343     }
344 
345     @Test
346     void testReciprocalImaginary() {
347         Complex z = new Complex(0.0, -2.0);
348         assertEquals(new Complex(0.0, 0.5), z.reciprocal());
349     }
350 
351     @Test
352     void testReciprocalInf() {
353         Complex z = new Complex(neginf, inf);
354         assertEquals(Complex.ZERO, z.reciprocal());
355 
356         z = new Complex(1, inf).reciprocal();
357         assertEquals(Complex.ZERO, z);
358     }
359 
360     @Test
361     void testReciprocalZero() {
362         assertEquals(Complex.INF, Complex.ZERO.reciprocal());
363     }
364 
365     @Test
366     void testReciprocalNaN() {
367         assertTrue(Complex.NaN.reciprocal().isNaN());
368     }
369 
370     @Test
371     void testMultiply() {
372         Complex x = new Complex(3.0, 4.0);
373         Complex y = new Complex(5.0, 6.0);
374         Complex z = x.multiply(y);
375         assertEquals(-9.0, z.getReal(), 1.0e-5);
376         assertEquals(38.0, z.getImaginary(), 1.0e-5);
377     }
378 
379     @Test
380     void testMultiplyNaN() {
381         Complex x = new Complex(3.0, 4.0);
382         Complex z = x.multiply(Complex.NaN);
383         assertSame(Complex.NaN, z);
384         z = Complex.NaN.multiply(5);
385         assertSame(Complex.NaN, z);
386     }
387 
388     @Test
389     void testMultiplyInfInf() {
390         // Assertions.assertTrue(infInf.multiply(infInf).isNaN()); // MATH-620
391         assertTrue(infInf.multiply(infInf).isInfinite());
392     }
393 
394     @Test
395     void testMultiplyNaNInf() {
396         Complex z = new Complex(1,1);
397         Complex w = z.multiply(infOne);
398         assertEquals(w.getReal(), inf, 0);
399         assertEquals(w.getImaginary(), inf, 0);
400 
401         // [MATH-164]
402         assertEquals(Complex.INF, new Complex( 1, 0).multiply(infInf));
403         assertEquals(Complex.INF, new Complex(-1, 0).multiply(infInf));
404         assertEquals(Complex.INF, new Complex( 1, 0).multiply(negInfZero));
405 
406         w = oneInf.multiply(oneNegInf);
407         assertEquals(w.getReal(), inf, 0);
408         assertEquals(w.getImaginary(), inf, 0);
409 
410         w = negInfNegInf.multiply(oneNaN);
411         assertTrue(Double.isNaN(w.getReal()));
412         assertTrue(Double.isNaN(w.getImaginary()));
413 
414         z = new Complex(1, neginf);
415         assertSame(Complex.INF, z.square());
416     }
417 
418     @Test
419     void testScalarMultiply() {
420         Complex x = new Complex(3.0, 4.0);
421         double yDouble = 2.0;
422         Complex yComplex = new Complex(yDouble);
423         assertEquals(x.multiply(yComplex), x.multiply(yDouble));
424         int zInt = -5;
425         Complex zComplex = new Complex(zInt);
426         assertEquals(x.multiply(zComplex), x.multiply(zInt));
427     }
428 
429     @Test
430     void testScalarMultiplyNaN() {
431         Complex x = new Complex(3.0, 4.0);
432         double yDouble = Double.NaN;
433         Complex yComplex = new Complex(yDouble);
434         assertEquals(x.multiply(yComplex), x.multiply(yDouble));
435         assertTrue(new Complex(Double.NaN, 0).multiply(5).isNaN());
436         assertTrue(new Complex(0, Double.NaN).multiply(5).isNaN());
437         assertTrue(Complex.NaN.multiply(5).isNaN());
438         assertTrue(new Complex(Double.NaN, 0).multiply(5.0).isNaN());
439         assertTrue(new Complex(0, Double.NaN).multiply(5.0).isNaN());
440         assertTrue(Complex.NaN.multiply(5.0).isNaN());
441         assertTrue(Complex.ONE.multiply(Double.NaN).isNaN());
442     }
443 
444     @Test
445     void testScalarMultiplyInf() {
446         Complex x = new Complex(1, 1);
447         double yDouble = Double.POSITIVE_INFINITY;
448         Complex yComplex = new Complex(yDouble);
449         assertEquals(x.multiply(yComplex), x.multiply(yDouble));
450 
451         yDouble = Double.NEGATIVE_INFINITY;
452         yComplex = new Complex(yDouble);
453         assertEquals(x.multiply(yComplex), x.multiply(yDouble));
454 
455         assertTrue(new Complex(Double.POSITIVE_INFINITY, 0).multiply(5).isInfinite());
456         assertTrue(new Complex(0, Double.POSITIVE_INFINITY).multiply(5).isInfinite());
457         assertTrue(Complex.INF.multiply(5).isInfinite());
458         assertTrue(new Complex(Double.POSITIVE_INFINITY, 0).multiply(5.0).isInfinite());
459         assertTrue(new Complex(0, Double.POSITIVE_INFINITY).multiply(5.0).isInfinite());
460         assertTrue(Complex.INF.multiply(5.0).isInfinite());
461         assertTrue(Complex.ONE.multiply(Double.POSITIVE_INFINITY).isInfinite());
462     }
463 
464     @Test
465     void testNegate() {
466         Complex x = new Complex(3.0, 4.0);
467         Complex z = x.negate();
468         assertEquals(-3.0, z.getReal(), 1.0e-5);
469         assertEquals(-4.0, z.getImaginary(), 1.0e-5);
470     }
471 
472     @Test
473     void testNegateNaN() {
474         Complex z = Complex.NaN.negate();
475         assertTrue(z.isNaN());
476     }
477 
478     @Test
479     void testSubtract() {
480         Complex x = new Complex(3.0, 4.0);
481         Complex y = new Complex(5.0, 6.0);
482         Complex z = x.subtract(y);
483         assertEquals(-2.0, z.getReal(), 1.0e-5);
484         assertEquals(-2.0, z.getImaginary(), 1.0e-5);
485     }
486 
487     @Test
488     void testSubtractNaN() {
489         Complex x = new Complex(3.0, 4.0);
490         Complex z = x.subtract(Complex.NaN);
491         assertSame(Complex.NaN, z);
492         z = new Complex(1, nan);
493         Complex w = x.subtract(z);
494         assertSame(Complex.NaN, w);
495         assertSame(Complex.NaN, Complex.NaN.subtract(Complex.NaN));
496         assertSame(Complex.NaN, Complex.NaN.subtract(Double.NaN));
497     }
498 
499     @Test
500     void testSubtractInf() {
501         Complex x = new Complex(1, 1);
502         Complex z = new Complex(neginf, 0);
503         Complex w = x.subtract(z);
504         assertEquals(1, w.getImaginary(), 0);
505         assertEquals(inf, w.getReal(), 0);
506 
507         x = new Complex(neginf, 0);
508         assertTrue(Double.isNaN(x.subtract(z).getReal()));
509     }
510 
511     @Test
512     void testScalarSubtract() {
513         Complex x = new Complex(3.0, 4.0);
514         double yDouble = 2.0;
515         Complex yComplex = new Complex(yDouble);
516         assertEquals(x.subtract(yComplex), x.subtract(yDouble));
517     }
518 
519     @Test
520     void testScalarSubtractNaN() {
521         Complex x = new Complex(3.0, 4.0);
522         double yDouble = Double.NaN;
523         Complex yComplex = new Complex(yDouble);
524         assertEquals(x.subtract(yComplex), x.subtract(yDouble));
525     }
526 
527     @Test
528     void testScalarSubtractInf() {
529         Complex x = new Complex(1, 1);
530         double yDouble = Double.POSITIVE_INFINITY;
531         Complex yComplex = new Complex(yDouble);
532         assertEquals(x.subtract(yComplex), x.subtract(yDouble));
533 
534         x = new Complex(neginf, 0);
535         assertEquals(x.subtract(yComplex), x.subtract(yDouble));
536     }
537 
538     @Test
539     void testEqualsNull() {
540         Complex x = new Complex(3.0, 4.0);
541         assertNotEquals(null, x);
542     }
543 
544     @Test
545     void testFloatingPointEqualsPrecondition1() {
546         assertThrows(NullPointerException.class, () -> {
547             Complex.equals(new Complex(3.0, 4.0), null, 3);
548         });
549     }
550 
551     @Test
552     void testFloatingPointEqualsPrecondition2() {
553         assertThrows(NullPointerException.class, () -> {
554             Complex.equals(null, new Complex(3.0, 4.0), 3);
555         });
556     }
557 
558     @SuppressWarnings("unlikely-arg-type")
559     @Test
560     void testEqualsClass() {
561         Complex x = new Complex(3.0, 4.0);
562         assertNotEquals(x, this);
563     }
564 
565     @Test
566     void testEqualsSame() {
567         Complex x = new Complex(3.0, 4.0);
568         assertEquals(x, x);
569     }
570 
571     @Test
572     void testFloatingPointEquals() {
573         double re = -3.21;
574         double im = 456789e10;
575 
576         final Complex x = new Complex(re, im);
577         Complex y = new Complex(re, im);
578 
579         assertEquals(x, y);
580         assertTrue(Complex.equals(x, y));
581 
582         final int maxUlps = 5;
583         for (int i = 0; i < maxUlps; i++) {
584             re = FastMath.nextUp(re);
585             im = FastMath.nextUp(im);
586         }
587         y = new Complex(re, im);
588         assertTrue(Complex.equals(x, y, maxUlps));
589 
590         re = FastMath.nextUp(re);
591         im = FastMath.nextUp(im);
592         y = new Complex(re, im);
593         assertFalse(Complex.equals(x, y, maxUlps));
594     }
595 
596     @Test
597     void testFloatingPointEqualsNaN() {
598         Complex c = new Complex(Double.NaN, 1);
599         assertFalse(Complex.equals(c, c));
600 
601         c = new Complex(1, Double.NaN);
602         assertFalse(Complex.equals(c, c));
603     }
604 
605     @Test
606     void testFloatingPointEqualsWithAllowedDelta() {
607         final double re = 153.0000;
608         final double im = 152.9375;
609         final double tol1 = 0.0625;
610         final Complex x = new Complex(re, im);
611         final Complex y = new Complex(re + tol1, im + tol1);
612         assertTrue(Complex.equals(x, y, tol1));
613 
614         final double tol2 = 0.0624;
615         assertFalse(Complex.equals(x, y, tol2));
616     }
617 
618     @Test
619     void testFloatingPointEqualsWithAllowedDeltaNaN() {
620         final Complex x = new Complex(0, Double.NaN);
621         final Complex y = new Complex(Double.NaN, 0);
622         assertFalse(Complex.equals(x, Complex.ZERO, 0.1));
623         assertFalse(Complex.equals(x, x, 0.1));
624         assertFalse(Complex.equals(x, y, 0.1));
625     }
626 
627     @Test
628     void testFloatingPointEqualsWithRelativeTolerance() {
629         final double tol = 1e-4;
630         final double re = 1;
631         final double im = 1e10;
632 
633         final double f = 1 + tol;
634         final Complex x = new Complex(re, im);
635         final Complex y = new Complex(re * f, im * f);
636         assertTrue(Complex.equalsWithRelativeTolerance(x, y, tol));
637     }
638 
639     @Test
640     void testFloatingPointEqualsWithRelativeToleranceNaN() {
641         final Complex x = new Complex(0, Double.NaN);
642         final Complex y = new Complex(Double.NaN, 0);
643         assertFalse(Complex.equalsWithRelativeTolerance(x, Complex.ZERO, 0.1));
644         assertFalse(Complex.equalsWithRelativeTolerance(x, x, 0.1));
645         assertFalse(Complex.equalsWithRelativeTolerance(x, y, 0.1));
646     }
647 
648     @Test
649     void testEqualsTrue() {
650         Complex x = new Complex(3.0, 4.0);
651         Complex y = new Complex(3.0, 4.0);
652         assertEquals(x, y);
653     }
654 
655     @Test
656     void testEqualsRealDifference() {
657         Complex x = new Complex(0.0, 0.0);
658         Complex y = new Complex(0.0 + Double.MIN_VALUE, 0.0);
659         assertNotEquals(x, y);
660     }
661 
662     @Test
663     void testEqualsImaginaryDifference() {
664         Complex x = new Complex(0.0, 0.0);
665         Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE);
666         assertNotEquals(x, y);
667     }
668 
669     @Test
670     void testEqualsNaN() {
671         Complex realNaN = new Complex(Double.NaN, 0.0);
672         Complex imaginaryNaN = new Complex(0.0, Double.NaN);
673         Complex complexNaN = Complex.NaN;
674         assertEquals(realNaN, imaginaryNaN);
675         assertEquals(imaginaryNaN, complexNaN);
676         assertEquals(realNaN, complexNaN);
677     }
678 
679     @Test
680     void testHashCode() {
681         Complex x = new Complex(0.0, 0.0);
682         Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE);
683         assertFalse(x.hashCode()==y.hashCode());
684         y = new Complex(0.0 + Double.MIN_VALUE, 0.0);
685         assertFalse(x.hashCode()==y.hashCode());
686         Complex realNaN = new Complex(Double.NaN, 0.0);
687         Complex imaginaryNaN = new Complex(0.0, Double.NaN);
688         assertEquals(realNaN.hashCode(), imaginaryNaN.hashCode());
689         assertEquals(imaginaryNaN.hashCode(), Complex.NaN.hashCode());
690 
691         // MATH-1118
692         // "equals" and "hashCode" must be compatible: if two objects have
693         // different hash codes, "equals" must return false.
694         final String msg = "'equals' not compatible with 'hashCode'";
695 
696         x = new Complex(0.0, 0.0);
697         y = new Complex(0.0, -0.0);
698         assertTrue(x.hashCode() != y.hashCode());
699         assertNotEquals(x, y, msg);
700 
701         x = new Complex(0.0, 0.0);
702         y = new Complex(-0.0, 0.0);
703         assertTrue(x.hashCode() != y.hashCode());
704         assertNotEquals(x, y, msg);
705     }
706 
707     @Test
708     void testToDegreesComplex() {
709         Complex z = new Complex(3, 4);
710         Complex expected = new Complex(FastMath.toDegrees(z.getReal()), FastMath.toDegrees(z.getImaginary()));
711         UnitTestUtils.customAssertEquals(expected, z.toDegrees(), 1.0e-15);
712     }
713 
714     @Test
715     void testToRadiansComplex() {
716         Complex z = new Complex(3, 4);
717         Complex expected = new Complex(FastMath.toRadians(z.getReal()), FastMath.toRadians(z.getImaginary()));
718         UnitTestUtils.customAssertEquals(expected, z.toRadians(), 1.0e-15);
719     }
720 
721     @Test
722     void testAcosComplex() {
723         Complex z = new Complex(3, 4);
724         Complex expected = new Complex(0.936812, -2.30551);
725         UnitTestUtils.customAssertEquals(expected, z.acos(), 1.0e-5);
726         UnitTestUtils.customAssertEquals(new Complex(FastMath.acos(0), 0),
727                                          Complex.ZERO.acos(), 1.0e-12);
728     }
729 
730     @Test
731     void testAcosNaN() {
732         assertTrue(Complex.NaN.acos().isNaN());
733     }
734 
735     @Test
736     void testAcosInf() {
737         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.acos());
738         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.acos());
739         UnitTestUtils.customAssertSame(Complex.NaN, infOne.acos());
740         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.acos());
741         UnitTestUtils.customAssertSame(Complex.NaN, infInf.acos());
742         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.acos());
743         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.acos());
744         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.acos());
745     }
746 
747     @Test
748     void testAcosBranchCuts() {
749         UnitTestUtils.customAssertEquals(new Complex(3.141592653589793238462, -0.76103968373182660633),
750                                          FastMath.acos(new Complex(-1.3038404810405297, +0.0)),
751                                          1.0e-14);
752         UnitTestUtils.customAssertEquals(new Complex(3.141592653589793238462, +0.76103968373182660633),
753                                          FastMath.acos(new Complex(-1.3038404810405297, -0.0)),
754                                          1.0e-14);
755         UnitTestUtils.customAssertEquals(new Complex(0.0, -0.76103968373182660633),
756                                          FastMath.acos(new Complex(1.3038404810405297, +0.0)),
757                                          1.0e-14);
758         UnitTestUtils.customAssertEquals(new Complex(0.0, +0.76103968373182660633),
759                                          FastMath.acos(new Complex(1.3038404810405297, -0.0)),
760                                          1.0e-14);
761     }
762 
763     @Test
764     void testAsinComplex() {
765         Complex z = new Complex(3, 4);
766         Complex expected = new Complex(0.633984, 2.30551);
767         UnitTestUtils.customAssertEquals(expected, z.asin(), 1.0e-5);
768     }
769 
770     @Test
771     void testAsinNaN() {
772         assertTrue(Complex.NaN.asin().isNaN());
773     }
774 
775     @Test
776     void testAsinInf() {
777         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.asin());
778         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.asin());
779         UnitTestUtils.customAssertSame(Complex.NaN, infOne.asin());
780         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.asin());
781         UnitTestUtils.customAssertSame(Complex.NaN, infInf.asin());
782         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.asin());
783         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.asin());
784         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.asin());
785     }
786 
787     @Test
788     void testAsinBranchCuts() {
789         UnitTestUtils.customAssertEquals(new Complex(-1.57079632679489661923, +0.76103968373182660633),
790                                          FastMath.asin(new Complex(-1.3038404810405297, +0.0)),
791                                          1.0e-14);
792         UnitTestUtils.customAssertEquals(new Complex(-1.57079632679489661923, -0.76103968373182660633),
793                                          FastMath.asin(new Complex(-1.3038404810405297, -0.0)),
794                                          1.0e-14);
795         UnitTestUtils.customAssertEquals(new Complex(1.57079632679489661923, +0.76103968373182660633),
796                                          FastMath.asin(new Complex(1.3038404810405297, +0.0)),
797                                          1.0e-14);
798         UnitTestUtils.customAssertEquals(new Complex(1.57079632679489661923, -0.76103968373182660633),
799                                          FastMath.asin(new Complex(1.3038404810405297, -0.0)),
800                                          1.0e-14);
801     }
802 
803     @Test
804     void testAtanComplex() {
805         Complex z = new Complex(3, 4);
806         Complex expected = new Complex(1.44831, 0.158997);
807         UnitTestUtils.customAssertEquals(expected, z.atan(), 1.0e-5);
808     }
809 
810     @Test
811     void testAtanInf() {
812         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.atan());
813         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.atan());
814         UnitTestUtils.customAssertSame(Complex.NaN, infOne.atan());
815         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.atan());
816         UnitTestUtils.customAssertSame(Complex.NaN, infInf.atan());
817         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.atan());
818         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.atan());
819         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.atan());
820     }
821 
822     @Test
823     void testAtanI() {
824         assertTrue(Complex.I.atan().isNaN());
825     }
826 
827     @Test
828     void testAtanNaN() {
829         assertTrue(Complex.NaN.atan().isNaN());
830     }
831 
832     @Test
833     void testAtanBranchCuts() {
834         UnitTestUtils.customAssertEquals(new Complex(+1.5707963267948966192, +1.0986122886681096913),
835                                          FastMath.atan(new Complex(+0.0, 1.25)),
836                                          1.0e-14);
837         UnitTestUtils.customAssertEquals(new Complex(-1.5707963267948966192, +1.0986122886681096913),
838                                          FastMath.atan(new Complex(-0.0, 1.25)),
839                                          1.0e-14);
840         UnitTestUtils.customAssertEquals(new Complex(+1.5707963267948966192, -1.0986122886681096913),
841                                          FastMath.atan(new Complex(+0.0, -1.25)),
842                                          1.0e-14);
843         UnitTestUtils.customAssertEquals(new Complex(-1.5707963267948966192, -1.0986122886681096913),
844                                          FastMath.atan(new Complex(-0.0, -1.25)),
845                                          1.0e-14);
846         UnitTestUtils.customAssertEquals(new Complex(0.0, +0.25541281188299534160),
847                                          FastMath.atan(new Complex(+0.0, 0.25)),
848                                          1.0e-14);
849         assertTrue(FastMath.copySign(1.0, FastMath.atan(new Complex(+0.0, 0.25)).getReal()) > 0.0);
850         UnitTestUtils.customAssertEquals(new Complex(0.0, +0.25541281188299534160),
851                                          FastMath.atan(new Complex(-0.0, 0.25)),
852                                          1.0e-14);
853         assertTrue(FastMath.copySign(1.0, FastMath.atan(new Complex(-0.0, 0.25)).getReal()) < 0.0);
854         UnitTestUtils.customAssertEquals(new Complex(0.0, -0.25541281188299534160),
855                                          FastMath.atan(new Complex(+0.0, -0.25)),
856                                          1.0e-14);
857         assertTrue(FastMath.copySign(1.0, FastMath.atan(new Complex(+0.0, -0.25)).getReal()) > 0.0);
858         UnitTestUtils.customAssertEquals(new Complex(0.0, -0.25541281188299534160),
859                                          FastMath.atan(new Complex(-0.0, -0.25)),
860                                          1.0e-14);
861         assertTrue(FastMath.copySign(1.0, FastMath.atan(new Complex(-0.0, -0.25)).getReal()) < 0.0);
862     }
863 
864     @Test
865     public void testAtanReal() {
866         final Complex zP = new Complex(0.8734729023516287, 0.0);
867         final Complex aP = new Complex(0.717964439926383,  0.0);
868         Assertions.assertEquals(aP, zP.atan());
869         Assertions.assertEquals(1.0, FastMath.copySign(1.0, zP.atan().getImaginary()), 1.0e-15);
870         final Complex zM = new Complex(0.8734729023516287, -0.0);
871         final Complex aM = new Complex(0.717964439926383,  -0.0);
872         Assertions.assertEquals(aM, zM.atan());
873         Assertions.assertEquals(-1.0, FastMath.copySign(1.0, zM.atan().getImaginary()), 1.0e-15);
874     }
875 
876     @Test
877     @Override
878     public void testAtan2() {
879         for (double x = -3; x < 3; x += 0.2) {
880             for (double y = -3; y < 3; y += 0.2) {
881                 final Complex z = build(x).atan2(build(y));
882                 final double  r = FastMath.atan2(x, y);
883                 checkRelative(r, new Complex(MathUtils.normalizeAngle(z.getReal(), r), z.getImaginary()));
884             }
885         }
886     }
887 
888     @Test
889     void testAtan2Complex() {
890         for (double r1 : Arrays.asList(-3, 3)) {
891             for (double i1 : Arrays.asList(-2, 0, 2)) {
892                 final Complex c1 = new Complex(r1, i1);
893                 for (double r2 : Arrays.asList(-1, 1)) {
894                     for (double i2 : Arrays.asList(-5, 0, 5)) {
895                         final Complex c2 = new Complex(r2, i2);
896                         UnitTestUtils.customAssertEquals(c1.divide(c2), c1.atan2(c2).tan(), 1.0e-14);
897                         final Complex atan   = c1.divide(c2).atan();
898                         final Complex atan2  = c1.atan2(c2);
899                         final double  deltaR = FastMath.abs(atan.getReal() - atan2.getReal()) / FastMath.PI;
900                         assertTrue(FastMath.abs(deltaR - FastMath.rint(deltaR)) < 1.0e-14);
901                         assertEquals(atan.getImaginary(), atan2.getImaginary(), 1.0e-14);
902                     }
903                 }
904             }
905         }
906     }
907 
908     @Test
909     void testAtan2Real() {
910         for (double r1 : Arrays.asList(-3, 3)) {
911             final Complex c1 = new Complex(r1, 0);
912             for (double r2 : Arrays.asList(-1, 1)) {
913                 final Complex c2 = new Complex(r2, 0);
914                 assertEquals(FastMath.atan2(r1, r2),
915                                     MathUtils.normalizeAngle(c1.atan2(c2).getReal(), 0.0),
916                                     1.0e-14);
917             }
918         }
919     }
920 
921     @Override
922     @Test
923     public void testAtan2SpecialCases() {
924         assertTrue(build(+0.0).atan2(build(+0.0)).isNaN());
925         assertTrue(build(-0.0).atan2(build(+0.0)).isNaN());
926         assertTrue(build(+0.0).atan2(build(-0.0)).isNaN());
927         assertTrue(build(-0.0).atan2(build(-0.0)).isNaN());
928     }
929 
930     @Test
931     void testCosComplex() {
932         Complex z = new Complex(3, 4);
933         Complex expected = new Complex(-27.03495, -3.851153);
934         UnitTestUtils.customAssertEquals(expected, z.cos(), 1.0e-5);
935     }
936 
937     @Test
938     void testCosNaN() {
939         assertTrue(Complex.NaN.cos().isNaN());
940     }
941 
942     @Test
943     void testCosInf() {
944         UnitTestUtils.customAssertSame(infNegInf, oneInf.cos());
945         UnitTestUtils.customAssertSame(infInf, oneNegInf.cos());
946         UnitTestUtils.customAssertSame(Complex.NaN, infOne.cos());
947         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.cos());
948         UnitTestUtils.customAssertSame(Complex.NaN, infInf.cos());
949         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.cos());
950         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.cos());
951         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.cos());
952     }
953 
954     @Test
955     void testCoshComplex() {
956         Complex z = new Complex(3, 4);
957         Complex expected = new Complex(-6.58066, -7.58155);
958         UnitTestUtils.customAssertEquals(expected, z.cosh(), 1.0e-5);
959     }
960 
961     @Test
962     void testCoshNaN() {
963         assertTrue(Complex.NaN.cosh().isNaN());
964     }
965 
966     @Test
967     void testCoshInf() {
968         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.cosh());
969         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.cosh());
970         UnitTestUtils.customAssertSame(infInf, infOne.cosh());
971         UnitTestUtils.customAssertSame(infNegInf, negInfOne.cosh());
972         UnitTestUtils.customAssertSame(Complex.NaN, infInf.cosh());
973         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.cosh());
974         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.cosh());
975         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.cosh());
976     }
977 
978     @Test
979     void testExpComplex() {
980         Complex z = new Complex(3, 4);
981         Complex expected = new Complex(-13.12878, -15.20078);
982         UnitTestUtils.customAssertEquals(expected, z.exp(), 1.0e-5);
983         UnitTestUtils.customAssertEquals(Complex.ONE,
984                                          Complex.ZERO.exp(), 10e-12);
985         Complex iPi = Complex.I.multiply(new Complex(pi,0));
986         UnitTestUtils.customAssertEquals(Complex.ONE.negate(),
987                                          iPi.exp(), 10e-12);
988     }
989 
990     @Test
991     void testExpNaN() {
992         assertTrue(Complex.NaN.exp().isNaN());
993     }
994 
995     @Test
996     void testExpInf1() {
997         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.exp());
998     }
999 
1000     @Test
1001     void testExpInf2() {
1002         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.exp());
1003     }
1004 
1005     @Test
1006     void testExpInf3() {
1007         UnitTestUtils.customAssertSame(infInf, infOne.exp());
1008     }
1009 
1010     @Test
1011     void testExpInf4() {
1012         final Complex exp = negInfOne.exp();
1013         UnitTestUtils.customAssertSame(Complex.ZERO, exp);
1014     }
1015 
1016     @Test
1017     void testExpInf5() {
1018         UnitTestUtils.customAssertSame(Complex.NaN, infInf.exp());
1019     }
1020 
1021     @Test
1022     void testExpInf6() {
1023         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.exp());
1024     }
1025 
1026     @Test
1027     void testExpInf7() {
1028         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.exp());
1029     }
1030 
1031     @Test
1032     void testExpInf8() {
1033         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.exp());
1034     }
1035 
1036     @Test
1037     void testExpM1() {
1038         UnitTestUtils.customAssertSame(Complex.NaN, Complex.NaN.expm1());
1039         final double testValue = FastMath.scalb(1.0, -30);
1040         assertEquals(FastMath.expm1(testValue), new Complex(testValue, 0).expm1().getReal(), 1.0e-30);
1041         assertTrue(FastMath.expm1(testValue) - new Complex(testValue).exp().subtract(1.0).getReal() > 4.0e-19);
1042         assertEquals(0.0, new Complex(0, testValue).expm1().getReal(), 1.0e-30);
1043         assertEquals(0.0, new Complex(0, testValue).expm1().getImaginary(), 1.0e-30);
1044     }
1045 
1046     @Test
1047     void testLogComplex() {
1048         Complex z = new Complex(3, 4);
1049         Complex expected = new Complex(1.60944, 0.927295);
1050         UnitTestUtils.customAssertEquals(expected, z.log(), 1.0e-5);
1051     }
1052 
1053     @Test
1054     void testLogNaN() {
1055         assertTrue(Complex.NaN.log().isNaN());
1056     }
1057 
1058     @Test
1059     void testLogInf() {
1060         UnitTestUtils.customAssertEquals(new Complex(inf, pi / 2),
1061                                          oneInf.log(), 10e-12);
1062         UnitTestUtils.customAssertEquals(new Complex(inf, -pi / 2),
1063                                          oneNegInf.log(), 10e-12);
1064         UnitTestUtils.customAssertEquals(infZero, infOne.log(), 10e-12);
1065         UnitTestUtils.customAssertEquals(new Complex(inf, pi),
1066                                          negInfOne.log(), 10e-12);
1067         UnitTestUtils.customAssertEquals(new Complex(inf, pi / 4),
1068                                          infInf.log(), 10e-12);
1069         UnitTestUtils.customAssertEquals(new Complex(inf, -pi / 4),
1070                                          infNegInf.log(), 10e-12);
1071         UnitTestUtils.customAssertEquals(new Complex(inf, 3d * pi / 4),
1072                                          negInfInf.log(), 10e-12);
1073         UnitTestUtils.customAssertEquals(new Complex(inf, - 3d * pi / 4),
1074                                          negInfNegInf.log(), 10e-12);
1075     }
1076 
1077     @Test
1078     void testLogBranchCut() {
1079         UnitTestUtils.customAssertEquals(new Complex(0.6931471805599453094, +3.1415926535897932384),
1080                                          FastMath.log(new Complex(-2.0, +0.0)),
1081                                          10e-12);
1082         UnitTestUtils.customAssertEquals(new Complex(0.6931471805599453094, -3.1415926535897932384),
1083                                          FastMath.log(new Complex(-2.0, -0.0)),
1084                                          10e-12);
1085     }
1086 
1087     @Test
1088     void testLogZero() {
1089         UnitTestUtils.customAssertSame(negInfZero, Complex.ZERO.log());
1090     }
1091 
1092     @Test
1093     void testLog1P() {
1094         Complex z = new Complex(2, 4);
1095         Complex expected = new Complex(1.60944, 0.927295);
1096         UnitTestUtils.customAssertEquals(expected, z.log1p(), 1.0e-5);
1097     }
1098 
1099     @Test
1100     void testLog10Complex() {
1101         UnitTestUtils.customAssertEquals(new Complex(2.0, 0.0), new Complex(100, 0).log10(), 1.0e-15);
1102         UnitTestUtils.customAssertEquals(new Complex(2.0, 0.5 * FastMath.PI / FastMath.log(10)), new Complex(0, 100).log10(), 1.0e-15);
1103     }
1104 
1105     @Test
1106     @Override
1107     public void testLog10() {
1108         for (double x = -0.9; x < 0.9; x += 0.05) {
1109             if (x < 0) {
1110                 // special case for Complex
1111                 assertTrue(Double.isNaN(FastMath.log10(x)));
1112                 assertFalse(build(x).log10().isNaN());
1113             } else {
1114                 checkRelative(FastMath.log10(x), build(x).log10());
1115             }
1116         }
1117     }
1118 
1119     @Test
1120     @Override
1121     public void testPowField() {
1122         for (double x = -0.9; x < 0.9; x += 0.05) {
1123             for (double y = 0.1; y < 4; y += 0.2) {
1124                 if ( x < 0) {
1125                     // special case for Complex
1126                     assertTrue(Double.isNaN(FastMath.pow(x, y)));
1127                     assertFalse(build(x).pow(build(y)).isNaN());
1128                 } else {
1129                     checkRelative(FastMath.pow(x, y), build(x).pow(build(y)));
1130                 }
1131             }
1132         }
1133     }
1134 
1135     @Test
1136     @Override
1137     public void testPowDouble() {
1138         for (double x = -0.9; x < 0.9; x += 0.05) {
1139             for (double y = 0.1; y < 4; y += 0.2) {
1140                 if ( x < 0) {
1141                     // special case for Complex
1142                     assertTrue(Double.isNaN(FastMath.pow(x, y)));
1143                     assertFalse(build(x).pow(y).isNaN());
1144                 } else {
1145                     checkRelative(FastMath.pow(x, y), build(x).pow(y));
1146                 }
1147             }
1148         }
1149     }
1150 
1151     @Test
1152     void testPow() {
1153         Complex x = new Complex(3, 4);
1154         Complex y = new Complex(5, 6);
1155         Complex expected = new Complex(-1.860893, 11.83677);
1156         UnitTestUtils.customAssertEquals(expected, x.pow(y), 1.0e-5);
1157         UnitTestUtils.customAssertEquals(new Complex(-46, 9).divide(2197), new Complex(2, -3).pow(new Complex(-3, 0)), 1.0e-15);
1158         UnitTestUtils.customAssertEquals(new Complex(-1, 0).divide(8), new Complex(-2, 0).pow(new Complex(-3, 0)), 1.0e-15);
1159         UnitTestUtils.customAssertEquals(new Complex(0, 2),
1160                                          new Complex(-4, 0).pow(new Complex(0.5, 0)),
1161                                          1.0e-15);
1162     }
1163 
1164     @Test
1165     void testPowNaNBase() {
1166         Complex x = new Complex(3, 4);
1167         assertTrue(Complex.NaN.pow(x).isNaN());
1168     }
1169 
1170     @Test
1171     void testPowNaNExponent() {
1172         Complex x = new Complex(3, 4);
1173         assertTrue(x.pow(Complex.NaN).isNaN());
1174     }
1175 
1176     @Test
1177     void testPowInf() {
1178         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(oneInf));
1179         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(oneNegInf));
1180         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(infOne));
1181         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(infInf));
1182         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(infNegInf));
1183         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(negInfInf));
1184         UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(negInfNegInf));
1185         UnitTestUtils.customAssertSame(Complex.INF, infOne.pow(Complex.ONE));
1186         UnitTestUtils.customAssertSame(Complex.INF, negInfOne.pow(Complex.ONE));
1187         UnitTestUtils.customAssertSame(Complex.INF, infInf.pow(Complex.ONE));
1188         UnitTestUtils.customAssertSame(Complex.INF, infNegInf.pow(Complex.ONE));
1189         UnitTestUtils.customAssertSame(Complex.INF, negInfInf.pow(Complex.ONE));
1190         UnitTestUtils.customAssertSame(Complex.INF, negInfNegInf.pow(Complex.ONE));
1191         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.pow(infNegInf));
1192         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.pow(negInfNegInf));
1193         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.pow(infInf));
1194         UnitTestUtils.customAssertSame(Complex.NaN, infInf.pow(infNegInf));
1195         UnitTestUtils.customAssertSame(Complex.NaN, infInf.pow(negInfNegInf));
1196         UnitTestUtils.customAssertSame(Complex.NaN, infInf.pow(infInf));
1197         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.pow(infNegInf));
1198         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.pow(negInfNegInf));
1199         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.pow(infInf));
1200     }
1201 
1202     @Test
1203     void testPowZero() {
1204         UnitTestUtils.customAssertEquals(Complex.ZERO,
1205                                          Complex.ZERO.pow(Complex.ONE), 1.0e-12);
1206         UnitTestUtils.customAssertSame(Complex.ONE,
1207                                        Complex.ZERO.pow(Complex.ZERO));
1208         UnitTestUtils.customAssertSame(Complex.NaN,
1209                                        Complex.ZERO.pow(Complex.I));
1210         UnitTestUtils.customAssertEquals(Complex.ONE,
1211                                          Complex.ONE.pow(Complex.ZERO), 10e-12);
1212         UnitTestUtils.customAssertEquals(Complex.ONE,
1213                                          Complex.I.pow(Complex.ZERO), 10e-12);
1214         UnitTestUtils.customAssertEquals(Complex.ONE,
1215                                          new Complex(-1, 3).pow(Complex.ZERO), 10e-12);
1216     }
1217 
1218     @Test
1219     void testZeroPow() {
1220         UnitTestUtils.customAssertEquals(Complex.ZERO, Complex.ZERO.pow(2.0), 1.0e-5);
1221     }
1222 
1223     @Test
1224     void testScalarPow() {
1225         Complex x = new Complex(3, 4);
1226         double yDouble = 5.0;
1227         Complex yComplex = new Complex(yDouble);
1228         assertEquals(x.pow(yComplex), x.pow(yDouble));
1229         UnitTestUtils.customAssertEquals(Complex.ONE.negate(), Complex.ONE.negate().pow(0.5).pow(2), 1.0e-15);
1230         UnitTestUtils.customAssertEquals(new Complex(2, 0), new Complex(4, 0).pow(0.5), 1.0e-15);
1231         UnitTestUtils.customAssertEquals(new Complex(2, 0), new Complex(4, 0).pow(new Complex(0.5, 0)), 1.0e-15);
1232     }
1233 
1234     @Test
1235     void testScalarPowNaNBase() {
1236         Complex x = Complex.NaN;
1237         double yDouble = 5.0;
1238         Complex yComplex = new Complex(yDouble);
1239         assertEquals(x.pow(yComplex), x.pow(yDouble));
1240     }
1241 
1242     @Test
1243     void testScalarPowNaNExponent() {
1244         Complex x = new Complex(3, 4);
1245         double yDouble = Double.NaN;
1246         Complex yComplex = new Complex(yDouble);
1247         assertEquals(x.pow(yComplex), x.pow(yDouble));
1248     }
1249 
1250     @Test
1251     void testScalarPowInf() {
1252        UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(Double.POSITIVE_INFINITY));
1253        UnitTestUtils.customAssertSame(Complex.NaN, Complex.ONE.pow(Double.NEGATIVE_INFINITY));
1254        UnitTestUtils.customAssertSame(Complex.INF, infOne.pow(1.0));
1255        UnitTestUtils.customAssertSame(Complex.INF, negInfOne.pow(1.0));
1256        UnitTestUtils.customAssertSame(Complex.INF, infInf.pow(1.0));
1257        UnitTestUtils.customAssertSame(Complex.INF, infNegInf.pow(1.0));
1258        UnitTestUtils.customAssertSame(Complex.INF, negInfInf.pow(10));
1259        UnitTestUtils.customAssertSame(Complex.INF, negInfNegInf.pow(1.0));
1260        UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.pow(Double.POSITIVE_INFINITY));
1261        UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.pow(Double.POSITIVE_INFINITY));
1262        UnitTestUtils.customAssertSame(Complex.NaN, infInf.pow(Double.POSITIVE_INFINITY));
1263        UnitTestUtils.customAssertSame(Complex.NaN, infInf.pow(Double.NEGATIVE_INFINITY));
1264        UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.pow(Double.NEGATIVE_INFINITY));
1265        UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.pow(Double.POSITIVE_INFINITY));
1266    }
1267 
1268     @Test
1269     void testScalarPowZero() {
1270        UnitTestUtils.customAssertEquals(Complex.ZERO, Complex.ZERO.pow(1.0), 1.0e-12);
1271        UnitTestUtils.customAssertSame(Complex.ONE, Complex.ZERO.pow(0.0));
1272        UnitTestUtils.customAssertEquals(Complex.ONE, Complex.ONE.pow(0.0), 10e-12);
1273        UnitTestUtils.customAssertEquals(Complex.ONE, Complex.I.pow(0.0), 10e-12);
1274        UnitTestUtils.customAssertEquals(Complex.ONE, new Complex(-1, 3).pow(0.0), 10e-12);
1275    }
1276 
1277     @Test
1278     void testpowNull() {
1279         assertThrows(NullArgumentException.class, () -> {
1280             Complex.ONE.pow(null);
1281         });
1282     }
1283 
1284     @Test
1285     void testSinComplex() {
1286         Complex z = new Complex(3, 4);
1287         Complex expected = new Complex(3.853738, -27.01681);
1288         UnitTestUtils.customAssertEquals(expected, z.sin(), 1.0e-5);
1289     }
1290 
1291     @Test
1292     void testSinInf() {
1293         UnitTestUtils.customAssertSame(infInf, oneInf.sin());
1294         UnitTestUtils.customAssertSame(infNegInf, oneNegInf.sin());
1295         UnitTestUtils.customAssertSame(Complex.NaN, infOne.sin());
1296         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.sin());
1297         UnitTestUtils.customAssertSame(Complex.NaN, infInf.sin());
1298         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.sin());
1299         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.sin());
1300         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.sin());
1301     }
1302 
1303     @Test
1304     void testSinNaN() {
1305         assertTrue(Complex.NaN.sin().isNaN());
1306     }
1307 
1308     @Test
1309     void testSinhComplex() {
1310         Complex z = new Complex(3, 4);
1311         Complex expected = new Complex(-6.54812, -7.61923);
1312         UnitTestUtils.customAssertEquals(expected, z.sinh(), 1.0e-5);
1313     }
1314 
1315     @Test
1316     void testSinhNaN() {
1317         assertTrue(Complex.NaN.sinh().isNaN());
1318     }
1319 
1320     @Test
1321     void testSinhInf() {
1322         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.sinh());
1323         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.sinh());
1324         UnitTestUtils.customAssertSame(infInf, infOne.sinh());
1325         UnitTestUtils.customAssertSame(negInfInf, negInfOne.sinh());
1326         UnitTestUtils.customAssertSame(Complex.NaN, infInf.sinh());
1327         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.sinh());
1328         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.sinh());
1329         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.sinh());
1330     }
1331 
1332     @Test
1333     void testAsinhComplex() {
1334         for (double x = -2; x <= 2; x += 0.125) {
1335             for (double y = -2; y <= 2; y += 0.125) {
1336                 final Complex z = new Complex(x, y);
1337                 UnitTestUtils.customAssertEquals(z, z.asinh().sinh(), 1.0e-14);
1338             }
1339         }
1340     }
1341 
1342     @Test
1343     void testAsinhBranchCuts() {
1344         UnitTestUtils.customAssertEquals(new Complex(FastMath.log(2 + FastMath.sqrt(3)), 0.5 * FastMath.PI),
1345                                          new Complex(+0.0, 2.0).asinh(),
1346                                          1.0e-14);
1347         UnitTestUtils.customAssertEquals(new Complex(-FastMath.log(2 + FastMath.sqrt(3)), 0.5 * FastMath.PI),
1348                                          new Complex(-0.0, 2.0).asinh(),
1349                                          1.0e-14);
1350     }
1351 
1352     @Test
1353     void testAcoshComplex() {
1354         for (double x = -2; x <= 2; x += 0.125) {
1355             for (double y = -2; y <= 2; y += 0.125) {
1356                 final Complex z = new Complex(x, y);
1357                 UnitTestUtils.customAssertEquals(z, z.acosh().cosh(), 1.0e-14);
1358             }
1359         }
1360     }
1361 
1362     @Test
1363     void testAcoshBranchCuts() {
1364         UnitTestUtils.customAssertEquals(new Complex(FastMath.log(2 + FastMath.sqrt(3)), +FastMath.PI),
1365                                          new Complex(-2.0, +0.0).acosh(),
1366                                          1.0e-14);
1367         UnitTestUtils.customAssertEquals(new Complex(FastMath.log(2 + FastMath.sqrt(3)), -FastMath.PI),
1368                                          new Complex(-2.0, -0.0).acosh(),
1369                                          1.0e-14);
1370     }
1371 
1372     @Test
1373     void testAtanhComplex() {
1374         for (double x = -2; x <= 2; x += 0.125) {
1375             for (double y = -2; y <= 2; y += 0.125) {
1376                 final Complex z = new Complex(x, y);
1377                 if (FastMath.abs(x) == 1.0 && y == 0.0) {
1378                     assertTrue(z.atanh().isInfinite());
1379                 } else {
1380                     UnitTestUtils.customAssertEquals(z, z.atanh().tanh(), 1.0e-14);
1381                 }
1382             }
1383         }
1384     }
1385 
1386     @Test
1387     void testAtanhBranchCuts() {
1388         UnitTestUtils.customAssertEquals(new Complex(-0.5 * FastMath.log(3), +0.5 * FastMath.PI),
1389                                          new Complex(-2.0, +0.0).atanh(),
1390                                          1.0e-14);
1391         UnitTestUtils.customAssertEquals(new Complex(-0.5 * FastMath.log(3), -0.5 * FastMath.PI),
1392                                          new Complex(-2.0, -0.0).atanh(),
1393                                          1.0e-14);
1394     }
1395 
1396     @Test
1397     void testSqrtRealPositive() {
1398         Complex z = new Complex(3, 4);
1399         Complex expected = new Complex(2, 1);
1400         UnitTestUtils.customAssertEquals(expected, z.sqrt(), 1.0e-5);
1401     }
1402 
1403     @Test
1404     void testSqrtRealZero() {
1405         Complex z = new Complex(0.0, 4);
1406         Complex expected = new Complex(1.41421, 1.41421);
1407         UnitTestUtils.customAssertEquals(expected, z.sqrt(), 1.0e-5);
1408     }
1409 
1410     @Test
1411     void testSqrtZero() {
1412         UnitTestUtils.customAssertEquals(Complex.ZERO, Complex.ZERO.sqrt(), 1.0e-15);
1413     }
1414 
1415     @Test
1416     void testSqrtRealNegative() {
1417         Complex z = new Complex(-3.0, 4);
1418         Complex expected = new Complex(1, 2);
1419         UnitTestUtils.customAssertEquals(expected, z.sqrt(), 1.0e-5);
1420     }
1421 
1422     @Test
1423     void testSqrtImaginaryZero() {
1424         Complex z = new Complex(-3.0, 0.0);
1425         Complex expected = new Complex(0.0, 1.73205);
1426         UnitTestUtils.customAssertEquals(expected, z.sqrt(), 1.0e-5);
1427     }
1428 
1429     @Test
1430     void testSqrtImaginaryNegative() {
1431         Complex z = new Complex(-3.0, -4.0);
1432         Complex expected = new Complex(1.0, -2.0);
1433         UnitTestUtils.customAssertEquals(expected, z.sqrt(), 1.0e-5);
1434     }
1435 
1436     @Test
1437     void testSqrtPolar() {
1438         double r = 1;
1439         for (int i = 0; i < 5; i++) {
1440             r += i;
1441             double theta = 0;
1442             for (int j =0; j < 11; j++) {
1443                 theta += pi /12;
1444                 Complex z = ComplexUtils.polar2Complex(r, theta);
1445                 Complex sqrtz = ComplexUtils.polar2Complex(FastMath.sqrt(r), theta / 2);
1446                 UnitTestUtils.customAssertEquals(sqrtz, z.sqrt(), 10e-12);
1447             }
1448         }
1449     }
1450 
1451     @Test
1452     void testSqrtNaN() {
1453         assertTrue(Complex.NaN.sqrt().isNaN());
1454     }
1455 
1456     @Test
1457     void testSqrtInf() {
1458         UnitTestUtils.customAssertSame(infNaN, oneInf.sqrt());
1459         UnitTestUtils.customAssertSame(infNaN, oneNegInf.sqrt());
1460         UnitTestUtils.customAssertSame(infZero, infOne.sqrt());
1461         UnitTestUtils.customAssertSame(zeroInf, negInfOne.sqrt());
1462         UnitTestUtils.customAssertSame(infNaN, infInf.sqrt());
1463         UnitTestUtils.customAssertSame(infNaN, infNegInf.sqrt());
1464         UnitTestUtils.customAssertSame(nanInf, negInfInf.sqrt());
1465         UnitTestUtils.customAssertSame(nanNegInf, negInfNegInf.sqrt());
1466     }
1467 
1468     @Test
1469     void testSqrt1z() {
1470         Complex z = new Complex(3, 4);
1471         Complex expected = new Complex(4.08033, -2.94094);
1472         UnitTestUtils.customAssertEquals(expected, z.sqrt1z(), 1.0e-5);
1473     }
1474 
1475     @Test
1476     void testSqrt1zNaN() {
1477         assertTrue(Complex.NaN.sqrt1z().isNaN());
1478     }
1479 
1480     @Test
1481     @Override
1482     public void testCbrt() {
1483         for (double x = -0.9; x < 0.9; x += 0.05) {
1484             if ( x < 0) {
1485                 // special case for Complex
1486                 assertTrue(FastMath.cbrt(x) < 0);
1487                 assertEquals(FastMath.PI / 3, build(x).cbrt().getArgument(), 1.0e-15);
1488             } else {
1489                 checkRelative(FastMath.cbrt(x), build(x).cbrt());
1490             }
1491         }
1492     }
1493 
1494     @Test
1495     void testCbrtComplex() {
1496         Complex z = new Complex(15, 2);
1497         UnitTestUtils.customAssertEquals(z, z.square().multiply(z).cbrt(), 1.0e-14);
1498         Complex branchCutPlus = new Complex(-8.0, +0.0);
1499         Complex cbrtPlus = branchCutPlus.cbrt();
1500         UnitTestUtils.customAssertEquals(branchCutPlus, cbrtPlus.multiply(cbrtPlus).multiply(cbrtPlus), 1.0e-14);
1501         assertEquals(1.0, cbrtPlus.getReal(), 1.0e-15);
1502         assertEquals(FastMath.sqrt(3.0), cbrtPlus.getImaginary(), 1.0e-15);
1503         Complex branchCutMinus = new Complex(-8.0, -0.0);
1504         Complex cbrtMinus = branchCutMinus.cbrt();
1505         UnitTestUtils.customAssertEquals(branchCutMinus, cbrtMinus.multiply(cbrtMinus).multiply(cbrtMinus), 1.0e-14);
1506         assertEquals(1.0, cbrtMinus.getReal(), 1.0e-15);
1507         assertEquals(-FastMath.sqrt(3.0), cbrtMinus.getImaginary(), 1.0e-15);
1508     }
1509 
1510     @Test
1511     @Override
1512     public void testRootN() {
1513         for (double x = -0.9; x < 0.9; x += 0.05) {
1514             for (int n = 1; n < 5; ++n) {
1515                 if (x < 0) {
1516                     // special case for Complex
1517                     final double doubleRoot = new Binary64(x).rootN(n).getReal();
1518                     if (n % 2 == 0) {
1519                         assertTrue(Double.isNaN(doubleRoot));
1520                     } else {
1521                         assertTrue(doubleRoot < 0);
1522                     }
1523                     assertEquals(FastMath.PI / n, build(x).rootN(n).getArgument(), 1.0e-15);
1524                 } else {
1525                     checkRelative(FastMath.pow(x, 1.0 / n), build(x).rootN(n));
1526                 }
1527             }
1528         }
1529     }
1530 
1531     @Test
1532     void testRootNComplex() {
1533         Complex z = new Complex(15, 2);
1534         UnitTestUtils.customAssertEquals(z, z.square().multiply(z).rootN(3), 1.0e-14);
1535         Complex branchCutPlus = new Complex(-8.0, +0.0);
1536         Complex cbrtPlus = branchCutPlus.rootN(3);
1537         UnitTestUtils.customAssertEquals(branchCutPlus, cbrtPlus.multiply(cbrtPlus).multiply(cbrtPlus), 1.0e-14);
1538         assertEquals(1.0, cbrtPlus.getReal(), 1.0e-15);
1539         assertEquals(FastMath.sqrt(3.0), cbrtPlus.getImaginary(), 1.0e-15);
1540         Complex branchCutMinus = new Complex(-8.0, -0.0);
1541         Complex cbrtMinus = branchCutMinus.rootN(3);
1542         UnitTestUtils.customAssertEquals(branchCutMinus, cbrtMinus.multiply(cbrtMinus).multiply(cbrtMinus), 1.0e-14);
1543         assertEquals(1.0, cbrtMinus.getReal(), 1.0e-15);
1544         assertEquals(-FastMath.sqrt(3.0), cbrtMinus.getImaginary(), 1.0e-15);
1545     }
1546 
1547     @Test
1548     void testTanComplex() {
1549         Complex z = new Complex(3, 4);
1550         Complex expected = new Complex(-0.000187346, 0.999356);
1551         UnitTestUtils.customAssertEquals(expected, z.tan(), 1.0e-5);
1552         /* Check that no overflow occurs (MATH-722) */
1553         Complex actual = new Complex(3.0, 1E10).tan();
1554         expected = new Complex(0, 1);
1555         UnitTestUtils.customAssertEquals(expected, actual, 1.0e-5);
1556         actual = new Complex(3.0, -1E10).tan();
1557         expected = new Complex(0, -1);
1558         UnitTestUtils.customAssertEquals(expected, actual, 1.0e-5);
1559     }
1560 
1561     @Test
1562     void testTanNaN() {
1563         assertTrue(Complex.NaN.tan().isNaN());
1564     }
1565 
1566     @Test
1567     void testTanInf() {
1568         UnitTestUtils.customAssertSame(Complex.valueOf(0.0, 1.0), oneInf.tan());
1569         UnitTestUtils.customAssertSame(Complex.valueOf(0.0, -1.0), oneNegInf.tan());
1570         UnitTestUtils.customAssertSame(Complex.NaN, infOne.tan());
1571         UnitTestUtils.customAssertSame(Complex.NaN, negInfOne.tan());
1572         UnitTestUtils.customAssertSame(Complex.NaN, infInf.tan());
1573         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.tan());
1574         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.tan());
1575         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.tan());
1576     }
1577 
1578     @Test
1579     void testTanCritical() {
1580         UnitTestUtils.customAssertSame(infNaN, new Complex(pi/2, 0).tan());
1581         UnitTestUtils.customAssertSame(negInfNaN, new Complex(-pi/2, 0).tan());
1582     }
1583 
1584     @Test
1585     void testTanhComplex() {
1586         Complex z = new Complex(3, 4);
1587         Complex expected = new Complex(1.00071, 0.00490826);
1588         UnitTestUtils.customAssertEquals(expected, z.tanh(), 1.0e-5);
1589         /* Check that no overflow occurs (MATH-722) */
1590         Complex actual = new Complex(1E10, 3.0).tanh();
1591         expected = new Complex(1, 0);
1592         UnitTestUtils.customAssertEquals(expected, actual, 1.0e-5);
1593         actual = new Complex(-1E10, 3.0).tanh();
1594         expected = new Complex(-1, 0);
1595         UnitTestUtils.customAssertEquals(expected, actual, 1.0e-5);
1596     }
1597 
1598     @Test
1599     void testTanhNaN() {
1600         assertTrue(Complex.NaN.tanh().isNaN());
1601     }
1602 
1603     @Test
1604     void testTanhInf() {
1605         UnitTestUtils.customAssertSame(Complex.NaN, oneInf.tanh());
1606         UnitTestUtils.customAssertSame(Complex.NaN, oneNegInf.tanh());
1607         UnitTestUtils.customAssertSame(Complex.valueOf(1.0, 0.0), infOne.tanh());
1608         UnitTestUtils.customAssertSame(Complex.valueOf(-1.0, 0.0), negInfOne.tanh());
1609         UnitTestUtils.customAssertSame(Complex.NaN, infInf.tanh());
1610         UnitTestUtils.customAssertSame(Complex.NaN, infNegInf.tanh());
1611         UnitTestUtils.customAssertSame(Complex.NaN, negInfInf.tanh());
1612         UnitTestUtils.customAssertSame(Complex.NaN, negInfNegInf.tanh());
1613     }
1614 
1615     @Test
1616     void testTanhCritical() {
1617         UnitTestUtils.customAssertSame(nanInf, new Complex(0, pi/2).tanh());
1618     }
1619 
1620     /** test issue MATH-221 */
1621     @Test
1622     void testMath221() {
1623         assertTrue(Complex.equals(new Complex(0,-1),
1624                                          new Complex(0,1).multiply(new Complex(-1,0))));
1625     }
1626 
1627     /**
1628      * Test: computing <b>third roots</b> of z.
1629      * <pre>
1630      * <code>
1631      * <b>z = -2 + 2 * i</b>
1632      *   ⇒ z_0 =  1      +          i
1633      *   ⇒ z_1 = -1.3660 + 0.3660 * i
1634      *   ⇒ z_2 =  0.3660 - 1.3660 * i
1635      * </code>
1636      * </pre>
1637      */
1638     @Test
1639     void testNthRoot_normal_thirdRoot() {
1640         // The complex number we want to compute all third-roots for.
1641         Complex z = new Complex(-2,2);
1642         // The List holding all third roots
1643         List<Complex> thirdRootsOfZ = z.nthRoot(3);
1644         // Returned Collection must not be empty!
1645         assertEquals(3, thirdRootsOfZ.size());
1646         // test z_0
1647         assertEquals(1.0,                  thirdRootsOfZ.get(0).getReal(),      1.0e-5);
1648         assertEquals(1.0,                  thirdRootsOfZ.get(0).getImaginary(), 1.0e-5);
1649         // test z_1
1650         assertEquals(-1.3660254037844386,  thirdRootsOfZ.get(1).getReal(),      1.0e-5);
1651         assertEquals(0.36602540378443843,  thirdRootsOfZ.get(1).getImaginary(), 1.0e-5);
1652         // test z_2
1653         assertEquals(0.366025403784439,    thirdRootsOfZ.get(2).getReal(),      1.0e-5);
1654         assertEquals(-1.3660254037844384,  thirdRootsOfZ.get(2).getImaginary(), 1.0e-5);
1655     }
1656 
1657 
1658     /**
1659      * Test: computing <b>fourth roots</b> of z.
1660      * <pre>
1661      * <code>
1662      * <b>z = 5 - 2 * i</b>
1663      *   ⇒ z_0 =  1.5164 - 0.1446 * i
1664      *   ⇒ z_1 =  0.1446 + 1.5164 * i
1665      *   ⇒ z_2 = -1.5164 + 0.1446 * i
1666      *   ⇒ z_3 = -1.5164 - 0.1446 * i
1667      * </code>
1668      * </pre>
1669      */
1670     @Test
1671     void testNthRoot_normal_fourthRoot() {
1672         // The complex number we want to compute all third-roots for.
1673         Complex z = new Complex(5,-2);
1674         // The List holding all fourth roots
1675         List<Complex> fourthRootsOfZ = z.nthRoot(4);
1676         // Returned Collection must not be empty!
1677         assertEquals(4, fourthRootsOfZ.size());
1678         // test z_0
1679         assertEquals(1.5164629308487783,     fourthRootsOfZ.get(0).getReal(),      1.0e-5);
1680         assertEquals(-0.14469266210702247,   fourthRootsOfZ.get(0).getImaginary(), 1.0e-5);
1681         // test z_1
1682         assertEquals(0.14469266210702256,    fourthRootsOfZ.get(1).getReal(),      1.0e-5);
1683         assertEquals(1.5164629308487783,     fourthRootsOfZ.get(1).getImaginary(), 1.0e-5);
1684         // test z_2
1685         assertEquals(-1.5164629308487783,    fourthRootsOfZ.get(2).getReal(),      1.0e-5);
1686         assertEquals(0.14469266210702267,    fourthRootsOfZ.get(2).getImaginary(), 1.0e-5);
1687         // test z_3
1688         assertEquals(-0.14469266210702275,   fourthRootsOfZ.get(3).getReal(),      1.0e-5);
1689         assertEquals(-1.5164629308487783,    fourthRootsOfZ.get(3).getImaginary(), 1.0e-5);
1690     }
1691 
1692     /**
1693      * Test: computing <b>third roots</b> of z.
1694      * <pre>
1695      * <code>
1696      * <b>z = 8</b>
1697      *   ⇒ z_0 =  2
1698      *   ⇒ z_1 = -1 + 1.73205 * i
1699      *   ⇒ z_2 = -1 - 1.73205 * i
1700      * </code>
1701      * </pre>
1702      */
1703     @Test
1704     void testNthRoot_cornercase_thirdRoot_imaginaryPartEmpty() {
1705         // The number 8 has three third roots. One we all already know is the number 2.
1706         // But there are two more complex roots.
1707         Complex z = new Complex(8,0);
1708         // The List holding all third roots
1709         List<Complex> thirdRootsOfZ = z.nthRoot(3);
1710         // Returned Collection must not be empty!
1711         assertEquals(3, thirdRootsOfZ.size());
1712         // test z_0
1713         assertEquals(2.0,                thirdRootsOfZ.get(0).getReal(),      1.0e-5);
1714         assertEquals(0.0,                thirdRootsOfZ.get(0).getImaginary(), 1.0e-5);
1715         // test z_1
1716         assertEquals(-1.0,               thirdRootsOfZ.get(1).getReal(),      1.0e-5);
1717         assertEquals(1.7320508075688774, thirdRootsOfZ.get(1).getImaginary(), 1.0e-5);
1718         // test z_2
1719         assertEquals(-1.0,               thirdRootsOfZ.get(2).getReal(),      1.0e-5);
1720         assertEquals(-1.732050807568877, thirdRootsOfZ.get(2).getImaginary(), 1.0e-5);
1721     }
1722 
1723 
1724     /**
1725      * Test: computing <b>third roots</b> of z with real part 0.
1726      * <pre>
1727      * <code>
1728      * <b>z = 2 * i</b>
1729      *   ⇒ z_0 =  1.0911 + 0.6299 * i
1730      *   ⇒ z_1 = -1.0911 + 0.6299 * i
1731      *   ⇒ z_2 = -2.3144 - 1.2599 * i
1732      * </code>
1733      * </pre>
1734      */
1735     @Test
1736     void testNthRoot_cornercase_thirdRoot_realPartZero() {
1737         // complex number with only imaginary part
1738         Complex z = new Complex(0,2);
1739         // The List holding all third roots
1740         List<Complex> thirdRootsOfZ = z.nthRoot(3);
1741         // Returned Collection must not be empty!
1742         assertEquals(3, thirdRootsOfZ.size());
1743         // test z_0
1744         assertEquals(1.0911236359717216,      thirdRootsOfZ.get(0).getReal(),      1.0e-5);
1745         assertEquals(0.6299605249474365,      thirdRootsOfZ.get(0).getImaginary(), 1.0e-5);
1746         // test z_1
1747         assertEquals(-1.0911236359717216,     thirdRootsOfZ.get(1).getReal(),      1.0e-5);
1748         assertEquals(0.6299605249474365,      thirdRootsOfZ.get(1).getImaginary(), 1.0e-5);
1749         // test z_2
1750         assertEquals(-2.3144374213981936E-16, thirdRootsOfZ.get(2).getReal(),      1.0e-5);
1751         assertEquals(-1.2599210498948732,     thirdRootsOfZ.get(2).getImaginary(), 1.0e-5);
1752     }
1753 
1754     /**
1755      * Test cornercases with NaN and Infinity.
1756      */
1757     @Test
1758     void testNthRoot_cornercase_NAN_Inf() {
1759         // NaN + finite -> NaN
1760         List<Complex> roots = oneNaN.nthRoot(3);
1761         assertEquals(1,roots.size());
1762         assertEquals(Complex.NaN, roots.get(0));
1763 
1764         roots = nanZero.nthRoot(3);
1765         assertEquals(1,roots.size());
1766         assertEquals(Complex.NaN, roots.get(0));
1767 
1768         // NaN + infinite -> NaN
1769         roots = nanInf.nthRoot(3);
1770         assertEquals(1,roots.size());
1771         assertEquals(Complex.NaN, roots.get(0));
1772 
1773         // finite + infinite -> Inf
1774         roots = oneInf.nthRoot(3);
1775         assertEquals(1,roots.size());
1776         assertEquals(Complex.INF, roots.get(0));
1777 
1778         // infinite + infinite -> Inf
1779         roots = negInfInf.nthRoot(3);
1780         assertEquals(1,roots.size());
1781         assertEquals(Complex.INF, roots.get(0));
1782     }
1783 
1784     @Test
1785     void testNthRootError() {
1786         try {
1787             Complex.ONE.nthRoot(-1);
1788             fail("an exception should have been thrown");
1789         } catch (MathIllegalArgumentException miae) {
1790             assertEquals(LocalizedCoreFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
1791                                 miae.getSpecifier());
1792         }
1793     }
1794 
1795     @Test
1796     void testIsMathematicalInteger() {
1797         doTestIsMathmeaticalInteger(-0.0, true);
1798         doTestIsMathmeaticalInteger(+0.0, true);
1799         doTestIsMathmeaticalInteger(-0.5, false);
1800         doTestIsMathmeaticalInteger(+0.5, false);
1801         doTestIsMathmeaticalInteger(Double.NaN, false);
1802         doTestIsMathmeaticalInteger(Double.POSITIVE_INFINITY, false);
1803         doTestIsMathmeaticalInteger(Double.NEGATIVE_INFINITY, false);
1804         doTestIsMathmeaticalInteger(Double.MIN_NORMAL, false);
1805         doTestIsMathmeaticalInteger(Double.MIN_VALUE, false);
1806     }
1807 
1808     private void doTestIsMathmeaticalInteger(double imaginary, boolean expectedForInteger) {
1809         assertFalse(new Complex(Double.NaN, imaginary).isMathematicalInteger());
1810         assertFalse(new Complex(Double.POSITIVE_INFINITY, imaginary).isMathematicalInteger());
1811         assertFalse(new Complex(Double.NEGATIVE_INFINITY, imaginary).isMathematicalInteger());
1812         assertFalse(new Complex(Double.MIN_NORMAL, imaginary).isMathematicalInteger());
1813         assertFalse(new Complex(Double.MIN_VALUE, imaginary).isMathematicalInteger());
1814 
1815         assertEquals(expectedForInteger, new Complex(-0.0, imaginary).isMathematicalInteger());
1816         assertEquals(expectedForInteger, new Complex(+0.0, imaginary).isMathematicalInteger());
1817 
1818         for (int i = -1000; i < 1000; ++i) {
1819             final double d = i;
1820             assertEquals(expectedForInteger, new Complex(d, imaginary).isMathematicalInteger());
1821             assertFalse(new Complex(FastMath.nextAfter(d, Double.POSITIVE_INFINITY), imaginary).isMathematicalInteger());
1822             assertFalse(new Complex(FastMath.nextAfter(d, Double.NEGATIVE_INFINITY), imaginary).isMathematicalInteger());
1823         }
1824 
1825         double minNoFractional = 0x1l << 52;
1826         assertEquals(expectedForInteger, new Complex(minNoFractional, imaginary).isMathematicalInteger());
1827         assertFalse(new Complex(minNoFractional - 0.5, imaginary).isMathematicalInteger());
1828         assertEquals(expectedForInteger, new Complex(minNoFractional + 0.5, imaginary).isMathematicalInteger());
1829 
1830     }
1831 
1832     /**
1833      * Test standard values
1834      */
1835     @Test
1836     void testGetArgument() {
1837         Complex z = new Complex(1, 0);
1838         assertEquals(0.0, z.getArgument(), 1.0e-12);
1839 
1840         z = new Complex(1, 1);
1841         assertEquals(FastMath.PI/4, z.getArgument(), 1.0e-12);
1842 
1843         z = new Complex(0, 1);
1844         assertEquals(FastMath.PI/2, z.getArgument(), 1.0e-12);
1845 
1846         z = new Complex(-1, 1);
1847         assertEquals(3 * FastMath.PI/4, z.getArgument(), 1.0e-12);
1848 
1849         z = new Complex(-1, 0);
1850         assertEquals(FastMath.PI, z.getArgument(), 1.0e-12);
1851 
1852         z = new Complex(-1, -1);
1853         assertEquals(-3 * FastMath.PI/4, z.getArgument(), 1.0e-12);
1854 
1855         z = new Complex(0, -1);
1856         assertEquals(-FastMath.PI/2, z.getArgument(), 1.0e-12);
1857 
1858         z = new Complex(1, -1);
1859         assertEquals(-FastMath.PI/4, z.getArgument(), 1.0e-12);
1860 
1861     }
1862 
1863     /**
1864      * Verify atan2-style handling of infinite parts
1865      */
1866     @Test
1867     void testGetArgumentInf() {
1868         assertEquals(FastMath.PI/4, infInf.getArgument(), 1.0e-12);
1869         assertEquals(FastMath.PI/2, oneInf.getArgument(), 1.0e-12);
1870         assertEquals(0.0, infOne.getArgument(), 1.0e-12);
1871         assertEquals(FastMath.PI/2, zeroInf.getArgument(), 1.0e-12);
1872         assertEquals(0.0, infZero.getArgument(), 1.0e-12);
1873         assertEquals(FastMath.PI, negInfOne.getArgument(), 1.0e-12);
1874         assertEquals(-3.0*FastMath.PI/4, negInfNegInf.getArgument(), 1.0e-12);
1875         assertEquals(-FastMath.PI/2, oneNegInf.getArgument(), 1.0e-12);
1876     }
1877 
1878     /**
1879      * Verify that either part NaN results in NaN
1880      */
1881     @Test
1882     void testGetArgumentNaN() {
1883         assertTrue(Double.isNaN(nanZero.getArgument()));
1884         assertTrue(Double.isNaN(zeroNaN.getArgument()));
1885         assertTrue(Double.isNaN(Complex.NaN.getArgument()));
1886     }
1887 
1888     @Test
1889     void testValueOf() {
1890         assertEquals(2.0, Complex.valueOf(2.0).getReal(), 1.0e-15);
1891         assertEquals(0.0, Complex.valueOf(2.0).getImaginary(), 1.0e-15);
1892         assertTrue(Complex.valueOf(Double.NaN).isNaN());
1893         assertTrue(Complex.valueOf(Double.POSITIVE_INFINITY).isInfinite());
1894         assertEquals( 2.0, Complex.valueOf(2.0, -1.0).getReal(), 1.0e-15);
1895         assertEquals(-1.0, Complex.valueOf(2.0, -1.0).getImaginary(), 1.0e-15);
1896         assertTrue(Complex.valueOf(Double.NaN, 0.0).isNaN());
1897         assertTrue(Complex.valueOf(Double.POSITIVE_INFINITY, 0.0).isInfinite());
1898         assertTrue(Complex.valueOf(Double.NaN, -1.0).isNaN());
1899         assertTrue(Complex.valueOf(Double.POSITIVE_INFINITY, -1.0).isInfinite());
1900         assertTrue(Complex.valueOf(0.0, Double.NaN).isNaN());
1901         assertTrue(Complex.valueOf(0.0, Double.POSITIVE_INFINITY).isInfinite());
1902         assertTrue(Complex.valueOf(-1.0, Double.NaN).isNaN());
1903         assertTrue(Complex.valueOf(-1.0, Double.POSITIVE_INFINITY).isInfinite());
1904     }
1905 
1906     @Test
1907     void testField() {
1908         assertEquals(ComplexField.getInstance(), Complex.ZERO.getField());
1909     }
1910 
1911     @Test
1912     void testToString() {
1913         assertEquals("(1.0, -2.0)", new Complex(1, -2).toString());
1914     }
1915 
1916     @Test
1917     void testScalbComplex() {
1918         assertEquals(0.125,  new Complex(2.0, 1.0).scalb(-4).getReal(), 1.0e-15);
1919         assertEquals(0.0625, new Complex(2.0, 1.0).scalb(-4).getImaginary(), 1.0e-15);
1920     }
1921 
1922     @Test
1923     void testHypotComplex() {
1924         assertEquals(5.8269600298808519855, new Complex(3, 4).hypot(new Complex(5, 6)).getReal(), 1.0e-15);
1925         assertEquals(7.2078750814528590485, new Complex(3, 4).hypot(new Complex(5, 6)).getImaginary(), 1.0e-15);
1926     }
1927 
1928     @Test
1929     void testCeilComplex() {
1930         for (double x = -3.9; x < 3.9; x += 0.05) {
1931             for (double y = -3.9; y < 3.9; y += 0.05) {
1932                 final Complex z = new Complex(x, y);
1933                 assertEquals(FastMath.ceil(x), z.ceil().getReal(), 1.0e-15);
1934                 assertEquals(FastMath.ceil(y), z.ceil().getImaginary(), 1.0e-15);
1935             }
1936         }
1937     }
1938 
1939     @Test
1940     void testFloorComplex() {
1941         for (double x = -3.9; x < 3.9; x += 0.05) {
1942             for (double y = -3.9; y < 3.9; y += 0.05) {
1943                 final Complex z = new Complex(x, y);
1944                 assertEquals(FastMath.floor(x), z.floor().getReal(), 1.0e-15);
1945                 assertEquals(FastMath.floor(y), z.floor().getImaginary(), 1.0e-15);
1946             }
1947         }
1948     }
1949 
1950     @Test
1951     void testRintComplex() {
1952         for (double x = -3.9; x < 3.9; x += 0.05) {
1953             for (double y = -3.9; y < 3.9; y += 0.05) {
1954                 final Complex z = new Complex(x, y);
1955                 assertEquals(FastMath.rint(x), z.rint().getReal(), 1.0e-15);
1956                 assertEquals(FastMath.rint(y), z.rint().getImaginary(), 1.0e-15);
1957             }
1958         }
1959     }
1960 
1961     @Test
1962     void testRemainderComplexComplex() {
1963         for (double x1 = -3.9; x1 < 3.9; x1 += 0.125) {
1964             for (double y1 = -3.9; y1 < 3.9; y1 += 0.125) {
1965                 final Complex z1 = new Complex(x1, y1);
1966                 for (double x2 = -3.92; x2 < 3.9; x2 += 0.125) {
1967                     for (double y2 = -3.92; y2 < 3.9; y2 += 0.125) {
1968                         final Complex z2 = new Complex(x2, y2);
1969                         final Complex r  = z1.remainder(z2);
1970                         final Complex q  = z1.subtract(r).divide(z2);
1971                         assertTrue(r.norm() <= z2.norm());
1972                         assertEquals(FastMath.rint(q.getReal()), q.getReal(), 2.0e-14);
1973                         assertEquals(FastMath.rint(q.getImaginary()), q.getImaginary(), 2.0e-14);
1974                     }
1975                 }
1976             }
1977         }
1978     }
1979 
1980     @Test
1981     void testRemainderComplexDouble() {
1982         for (double x1 = -3.9; x1 < 3.9; x1 += 0.125) {
1983             for (double y1 = -3.9; y1 < 3.9; y1 += 0.125) {
1984                 final Complex z1 = new Complex(x1, y1);
1985                 for (double a = -3.92; a < 3.9; a += 0.125) {
1986                         final Complex r  = z1.remainder(a);
1987                         final Complex q  = z1.subtract(r).divide(a);
1988                         assertTrue(r.norm() <= FastMath.abs(a));
1989                         assertEquals(FastMath.rint(q.getReal()), q.getReal(), 2.0e-14);
1990                         assertEquals(FastMath.rint(q.getImaginary()), q.getImaginary(), 2.0e-14);
1991                 }
1992             }
1993         }
1994     }
1995 
1996     @Test
1997     void testRemainderAxKr() {
1998         checkRemainder(new Complex(14, -5), new Complex(3, 4), new Complex(-1.0,  0.0));
1999         checkRemainder(new Complex(26, 120), new Complex(37, 226), new Complex(-11.0, -106.0));
2000         checkRemainder(new Complex(9.4, 6), new Complex(1.0, 1.0), new Complex(-0.6, 0.0));
2001         checkRemainder(new Complex(-5.89, 0.33), new Complex(2.4, -0.123), new Complex(-1.09, 0.084));
2002     }
2003 
2004     private void checkRemainder(final Complex c1, final Complex c2, final Complex expectedRemainder) {
2005 
2006         final Complex remainder = c1.remainder(c2);
2007         assertEquals(expectedRemainder.getReal(),      remainder.getReal(),      1.0e-15);
2008         assertEquals(expectedRemainder.getImaginary(), remainder.getImaginary(), 1.0e-15);
2009 
2010         final Complex crossCheck = c1.subtract(remainder).divide(c2);
2011         assertTrue(Precision.isMathematicalInteger(crossCheck.getReal()));
2012         assertTrue(Precision.isMathematicalInteger(crossCheck.getImaginary()));
2013 
2014     }
2015 
2016     @Test
2017     void testCopySignFieldComplex() {
2018         for (double x1 = -3.9; x1 < 3.9; x1 += 0.08) {
2019             for (double y1 = -3.9; y1 < 3.9; y1 += 0.08) {
2020                 final Complex z1 = new Complex(x1, y1);
2021                 for (double x2 = -3.9; x2 < 3.9; x2 += 0.08) {
2022                     for (double y2 = -3.9; y2 < 3.9; y2 += 0.08) {
2023                         final Complex z2 = new Complex(x2, y2);
2024                         assertEquals(FastMath.copySign(x1, x2), z1.copySign(z2).getReal(), 1.0e-15);
2025                         assertEquals(FastMath.copySign(y1, y2), z1.copySign(z2).getImaginary(), 1.0e-15);
2026                     }
2027                 }
2028             }
2029         }
2030     }
2031 
2032     @Test
2033     void testCopySignDoubleComplex() {
2034         for (double x1 = -3.9; x1 < 3.9; x1 += 0.05) {
2035             for (double y1 = -3.9; y1 < 3.9; y1 += 0.05) {
2036                 final Complex z1 = new Complex(x1, y1);
2037                 for (double r = -3.9; r < 3.9; r += 0.05) {
2038                     assertEquals(FastMath.copySign(x1, r), z1.copySign(r).getReal(), 1.0e-15);
2039                     assertEquals(FastMath.copySign(y1, r), z1.copySign(r).getImaginary(), 1.0e-15);
2040                 }
2041             }
2042         }
2043     }
2044 
2045     @Test
2046     void testSignComplex() {
2047         for (double x = -3.9; x < 3.9; x += 0.05) {
2048             for (double y = -3.9; y < 3.9; y += 0.05) {
2049                 final Complex z = new Complex(x, y);
2050                 assertEquals(1.0, z.sign().norm(), 1.0e-15);
2051                 assertEquals(FastMath.copySign(1, FastMath.signum(x)), FastMath.copySign(1, z.sign().getRealPart()), 1.0e-15);
2052                 assertEquals(FastMath.copySign(1, FastMath.signum(y)), FastMath.copySign(1, z.sign().getImaginaryPart()), 1.0e-15);
2053             }
2054         }
2055         assertTrue(Complex.NaN.sign().isNaN());
2056         for (int sR : Arrays.asList(-1, +1)) {
2057             for (int sI : Arrays.asList(-1, +1)) {
2058                 Complex z = new Complex(FastMath.copySign(0, sR), FastMath.copySign(0, sI));
2059                 assertTrue(z.isZero());
2060                 Complex zSign = z.sign();
2061                 assertTrue(zSign.isZero());
2062                 assertEquals(sR, FastMath.copySign(1, zSign.getRealPart()), 1.0e-15);
2063                 assertEquals(sI, FastMath.copySign(1, zSign.getImaginaryPart()), 1.0e-15);
2064             }
2065         }
2066     }
2067 
2068     @Test
2069     void testLinearCombination1() {
2070         final Complex[] a = new Complex[] {
2071             new Complex(-1321008684645961.0 / 268435456.0,
2072                         +5774608829631843.0 / 268435456.0),
2073             new Complex(-7645843051051357.0 / 8589934592.0,
2074                         0.0)
2075         };
2076         final Complex[] b = new Complex[] {
2077             new Complex(-5712344449280879.0 / 2097152.0,
2078                         -4550117129121957.0 / 2097152.0),
2079             new Complex(8846951984510141.0 / 131072.0,
2080                         0.0)
2081         };
2082 
2083         final Complex abSumInline = Complex.ZERO.linearCombination(a[0], b[0],
2084                                                                   a[1], b[1]);
2085         final Complex abSumArray = Complex.ZERO.linearCombination(a, b);
2086 
2087         UnitTestUtils.customAssertEquals(abSumInline, abSumArray, 0);
2088         UnitTestUtils.customAssertEquals(-1.8551294182586248737720779899, abSumInline.getReal(), 1.0e-15);
2089 
2090         final Complex naive = a[0].multiply(b[0]).add(a[1].multiply(b[1]));
2091         assertTrue(naive.subtract(abSumInline).norm() > 1.5);
2092 
2093     }
2094 
2095     @Test
2096     void testSignedZeroEquality() {
2097 
2098         assertFalse(new Complex(-0.0, 1.0).isZero());
2099         assertFalse(new Complex(+0.0, 1.0).isZero());
2100         assertFalse(new Complex( 1.0, -0.0).isZero());
2101         assertFalse(new Complex( 1.0, +0.0).isZero());
2102 
2103         assertTrue(new Complex(-0.0, -0.0).isZero());
2104         assertTrue(new Complex(-0.0, +0.0).isZero());
2105         assertTrue(new Complex(+0.0, -0.0).isZero());
2106         assertTrue(new Complex(+0.0, +0.0).isZero());
2107 
2108         assertNotEquals(Complex.ZERO, new Complex(-0.0, -0.0));
2109         assertNotEquals(Complex.ZERO, new Complex(-0.0, +0.0));
2110         assertNotEquals(Complex.ZERO, new Complex(+0.0, -0.0));
2111         assertEquals(Complex.ZERO, new Complex(+0.0, +0.0));
2112 
2113     }
2114 
2115     @Test
2116     void testSerial() {
2117         Complex z = new Complex(3.0, 4.0);
2118         assertEquals(z, UnitTestUtils.serializeAndRecover(z));
2119         Complex ncmplx = (Complex)UnitTestUtils.serializeAndRecover(oneNaN);
2120         assertEquals(nanZero, ncmplx);
2121         assertTrue(ncmplx.isNaN());
2122         Complex infcmplx = (Complex)UnitTestUtils.serializeAndRecover(infInf);
2123         assertEquals(infInf, infcmplx);
2124         assertTrue(infcmplx.isInfinite());
2125         TestComplex tz = new TestComplex(3.0, 4.0);
2126         assertEquals(tz, UnitTestUtils.serializeAndRecover(tz));
2127         TestComplex ntcmplx = (TestComplex)UnitTestUtils.serializeAndRecover(new TestComplex(oneNaN));
2128         assertEquals(nanZero, ntcmplx);
2129         assertTrue(ntcmplx.isNaN());
2130         TestComplex inftcmplx = (TestComplex)UnitTestUtils.serializeAndRecover(new TestComplex(infInf));
2131         assertEquals(infInf, inftcmplx);
2132         assertTrue(inftcmplx.isInfinite());
2133     }
2134 
2135     /**
2136      * Class to test extending Complex
2137      */
2138     public static class TestComplex extends Complex {
2139 
2140         /**
2141          * Serialization identifier.
2142          */
2143         private static final long serialVersionUID = 3268726724160389237L;
2144 
2145         public TestComplex(double real, double imaginary) {
2146             super(real, imaginary);
2147         }
2148 
2149         public TestComplex(Complex other) {
2150             this(other.getReal(), other.getImaginary());
2151         }
2152 
2153         @Override
2154         protected TestComplex createComplex(double real, double imaginary) {
2155             return new TestComplex(real, imaginary);
2156         }
2157 
2158     }
2159 }