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