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    *      http://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  package org.apache.commons.math.complex;
19  
20  import org.apache.commons.math.TestUtils;
21  
22  import java.util.List;
23  
24  import junit.framework.TestCase;
25  
26  /**
27   * @version $Revision: 791237 $ $Date: 2009-07-05 08:53:13 -0400 (Sun, 05 Jul 2009) $
28   */
29  public class ComplexTest extends TestCase {
30      
31  
32      private double inf = Double.POSITIVE_INFINITY;
33      private double neginf = Double.NEGATIVE_INFINITY;
34      private double nan = Double.NaN;
35      private double pi = Math.PI;
36      private Complex oneInf = new Complex(1, inf);
37      private Complex oneNegInf = new Complex(1, neginf);
38      private Complex infOne = new Complex(inf, 1);
39      private Complex infZero = new Complex(inf, 0);
40      private Complex infNaN = new Complex(inf, nan);
41      private Complex infNegInf = new Complex(inf, neginf);
42      private Complex infInf = new Complex(inf, inf);
43      private Complex negInfInf = new Complex(neginf, inf);
44      private Complex negInfZero = new Complex(neginf, 0);
45      private Complex negInfOne = new Complex(neginf, 1);
46      private Complex negInfNaN = new Complex(neginf, nan);
47      private Complex negInfNegInf = new Complex(neginf, neginf);
48      private Complex oneNaN = new Complex(1, nan);
49      private Complex zeroInf = new Complex(0, inf);
50      private Complex zeroNaN = new Complex(0, nan);
51      private Complex nanInf = new Complex(nan, inf);
52      private Complex nanNegInf = new Complex(nan, neginf);
53      private Complex nanZero = new Complex(nan, 0);
54      
55      public void testConstructor() {
56          Complex z = new Complex(3.0, 4.0);
57          assertEquals(3.0, z.getReal(), 1.0e-5);
58          assertEquals(4.0, z.getImaginary(), 1.0e-5);
59      }
60      
61      public void testConstructorNaN() {
62          Complex z = new Complex(3.0, Double.NaN);
63          assertTrue(z.isNaN());
64  
65          z = new Complex(nan, 4.0);
66          assertTrue(z.isNaN());
67  
68          z = new Complex(3.0, 4.0);
69          assertFalse(z.isNaN());
70      }
71      
72      public void testAbs() {
73          Complex z = new Complex(3.0, 4.0);
74          assertEquals(5.0, z.abs(), 1.0e-5);
75      }
76      
77      public void testAbsNaN() {
78          assertTrue(Double.isNaN(Complex.NaN.abs()));
79          Complex z = new Complex(inf, nan);
80          assertTrue(Double.isNaN(z.abs()));
81      }
82      
83      public void testAbsInfinite() {
84          Complex z = new Complex(inf, 0);
85          assertEquals(inf, z.abs(), 0);
86          z = new Complex(0, neginf);
87          assertEquals(inf, z.abs(), 0);
88          z = new Complex(inf, neginf);
89          assertEquals(inf, z.abs(), 0);     
90      }
91      
92      public void testAdd() {
93          Complex x = new Complex(3.0, 4.0);
94          Complex y = new Complex(5.0, 6.0);
95          Complex z = x.add(y);
96          assertEquals(8.0, z.getReal(), 1.0e-5);
97          assertEquals(10.0, z.getImaginary(), 1.0e-5);
98      }
99      
100     public void testAddNaN() {
101         Complex x = new Complex(3.0, 4.0);
102         Complex z = x.add(Complex.NaN);
103         assertTrue(z.isNaN());
104         z = new Complex(1, nan);
105         Complex w = x.add(z);
106         assertEquals(w.getReal(), 4.0, 0);
107         assertTrue(Double.isNaN(w.getImaginary()));
108     }
109     
110     public void testAddInfinite() {
111         Complex x = new Complex(1, 1);
112         Complex z = new Complex(inf, 0);
113         Complex w = x.add(z);
114         assertEquals(w.getImaginary(), 1, 0);
115         assertEquals(inf, w.getReal(), 0);
116         
117         x = new Complex(neginf, 0);
118         assertTrue(Double.isNaN(x.add(z).getReal()));
119     }
120     
121     public void testConjugate() {
122         Complex x = new Complex(3.0, 4.0);
123         Complex z = x.conjugate();
124         assertEquals(3.0, z.getReal(), 1.0e-5);
125         assertEquals(-4.0, z.getImaginary(), 1.0e-5);
126     }
127     
128     public void testConjugateNaN() {
129         Complex z = Complex.NaN.conjugate();
130         assertTrue(z.isNaN());
131     }
132     
133     public void testConjugateInfiinite() {
134         Complex z = new Complex(0, inf);
135         assertEquals(neginf, z.conjugate().getImaginary(), 0);
136         z = new Complex(0, neginf);
137         assertEquals(inf, z.conjugate().getImaginary(), 0);
138     }
139     
140     public void testDivide() {
141         Complex x = new Complex(3.0, 4.0);
142         Complex y = new Complex(5.0, 6.0);
143         Complex z = x.divide(y);
144         assertEquals(39.0 / 61.0, z.getReal(), 1.0e-5);
145         assertEquals(2.0 / 61.0, z.getImaginary(), 1.0e-5);
146     }
147     
148     public void testDivideInfinite() {
149         Complex x = new Complex(3, 4);
150         Complex w = new Complex(neginf, inf);
151         assertTrue(x.divide(w).equals(Complex.ZERO));
152         
153         Complex z = w.divide(x);
154         assertTrue(Double.isNaN(z.getReal()));
155         assertEquals(inf, z.getImaginary(), 0);
156         
157         w = new Complex(inf, inf);
158         z = w.divide(x);
159         assertTrue(Double.isNaN(z.getImaginary()));
160         assertEquals(inf, z.getReal(), 0);
161         
162         w = new Complex(1, inf);
163         z = w.divide(w);
164         assertTrue(Double.isNaN(z.getReal()));
165         assertTrue(Double.isNaN(z.getImaginary()));
166     }
167     
168     public void testDivideNaN() {
169         Complex x = new Complex(3.0, 4.0);
170         Complex z = x.divide(Complex.NaN);
171         assertTrue(z.isNaN());
172     }
173     
174     public void testDivideNaNInf() {  
175        Complex z = oneInf.divide(Complex.ONE);
176        assertTrue(Double.isNaN(z.getReal()));
177        assertEquals(inf, z.getImaginary(), 0);
178        
179        z = negInfNegInf.divide(oneNaN);
180        assertTrue(Double.isNaN(z.getReal()));
181        assertTrue(Double.isNaN(z.getImaginary()));
182        
183        z = negInfInf.divide(Complex.ONE);
184        assertTrue(Double.isNaN(z.getReal()));
185        assertTrue(Double.isNaN(z.getImaginary()));
186     }
187     
188     public void testMultiply() {
189         Complex x = new Complex(3.0, 4.0);
190         Complex y = new Complex(5.0, 6.0);
191         Complex z = x.multiply(y);
192         assertEquals(-9.0, z.getReal(), 1.0e-5);
193         assertEquals(38.0, z.getImaginary(), 1.0e-5);
194     }
195     
196     public void testMultiplyNaN() {
197         Complex x = new Complex(3.0, 4.0);
198         Complex z = x.multiply(Complex.NaN);
199         assertTrue(z.isNaN());
200     }
201     
202     public void testMultiplyNaNInf() {
203         Complex z = new Complex(1,1);
204         Complex w = z.multiply(infOne);
205         assertEquals(w.getReal(), inf, 0);
206         assertEquals(w.getImaginary(), inf, 0);
207 
208         // [MATH-164]
209         assertTrue(new Complex( 1,0).multiply(infInf).equals(Complex.INF));
210         assertTrue(new Complex(-1,0).multiply(infInf).equals(Complex.INF));
211         assertTrue(new Complex( 1,0).multiply(negInfZero).equals(Complex.INF));
212         
213         w = oneInf.multiply(oneNegInf);
214         assertEquals(w.getReal(), inf, 0);
215         assertEquals(w.getImaginary(), inf, 0);
216         
217         w = negInfNegInf.multiply(oneNaN);
218         assertTrue(Double.isNaN(w.getReal()));
219         assertTrue(Double.isNaN(w.getImaginary()));  
220     }
221     
222     public void testScalarMultiply() {
223         Complex x = new Complex(3.0, 4.0);
224         double y = 2.0;
225         Complex z = x.multiply(y);
226         assertEquals(6.0, z.getReal(), 1.0e-5);
227         assertEquals(8.0, z.getImaginary(), 1.0e-5);
228     }
229     
230     public void testScalarMultiplyNaN() {
231         Complex x = new Complex(3.0, 4.0);
232         Complex z = x.multiply(Double.NaN);
233         assertTrue(z.isNaN());
234     }
235     
236     public void testScalarMultiplyInf() {
237         Complex z = new Complex(1,1);
238         Complex w = z.multiply(Double.POSITIVE_INFINITY);
239         assertEquals(w.getReal(), inf, 0);
240         assertEquals(w.getImaginary(), inf, 0);
241 
242         w = z.multiply(Double.NEGATIVE_INFINITY);
243         assertEquals(w.getReal(), inf, 0);
244         assertEquals(w.getImaginary(), inf, 0);
245     }
246     
247     public void testNegate() {
248         Complex x = new Complex(3.0, 4.0);
249         Complex z = x.negate();
250         assertEquals(-3.0, z.getReal(), 1.0e-5);
251         assertEquals(-4.0, z.getImaginary(), 1.0e-5);
252     }
253     
254     public void testNegateNaN() {
255         Complex z = Complex.NaN.negate();
256         assertTrue(z.isNaN());
257     }
258     
259     public void testSubtract() {
260         Complex x = new Complex(3.0, 4.0);
261         Complex y = new Complex(5.0, 6.0);
262         Complex z = x.subtract(y);
263         assertEquals(-2.0, z.getReal(), 1.0e-5);
264         assertEquals(-2.0, z.getImaginary(), 1.0e-5);
265     }
266     
267     public void testSubtractNaN() {
268         Complex x = new Complex(3.0, 4.0);
269         Complex z = x.subtract(Complex.NaN);
270         assertTrue(z.isNaN());
271     }
272     
273     public void testEqualsNull() {
274         Complex x = new Complex(3.0, 4.0);
275         assertFalse(x.equals(null));
276     }
277     
278     public void testEqualsClass() {
279         Complex x = new Complex(3.0, 4.0);
280         assertFalse(x.equals(this));
281     }
282     
283     public void testEqualsSame() {
284         Complex x = new Complex(3.0, 4.0);
285         assertTrue(x.equals(x));
286     }
287     
288     public void testEqualsTrue() {
289         Complex x = new Complex(3.0, 4.0);
290         Complex y = new Complex(3.0, 4.0);
291         assertTrue(x.equals(y));
292     }
293     
294     public void testEqualsRealDifference() {
295         Complex x = new Complex(0.0, 0.0);
296         Complex y = new Complex(0.0 + Double.MIN_VALUE, 0.0);
297         assertFalse(x.equals(y));
298     }
299     
300     public void testEqualsImaginaryDifference() {
301         Complex x = new Complex(0.0, 0.0);
302         Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE);
303         assertFalse(x.equals(y));
304     }
305     
306     public void testEqualsNaN() {
307         Complex realNaN = new Complex(Double.NaN, 0.0);
308         Complex imaginaryNaN = new Complex(0.0, Double.NaN);
309         Complex complexNaN = Complex.NaN;
310         assertTrue(realNaN.equals(imaginaryNaN));
311         assertTrue(imaginaryNaN.equals(complexNaN));
312         assertTrue(realNaN.equals(complexNaN));
313     }
314     
315     public void testHashCode() {
316         Complex x = new Complex(0.0, 0.0);
317         Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE);
318         assertFalse(x.hashCode()==y.hashCode());
319         y = new Complex(0.0 + Double.MIN_VALUE, 0.0);
320         assertFalse(x.hashCode()==y.hashCode());
321         Complex realNaN = new Complex(Double.NaN, 0.0);
322         Complex imaginaryNaN = new Complex(0.0, Double.NaN);
323         assertEquals(realNaN.hashCode(), imaginaryNaN.hashCode());
324         assertEquals(imaginaryNaN.hashCode(), Complex.NaN.hashCode());
325     }
326     
327     public void testAcos() {
328         Complex z = new Complex(3, 4);
329         Complex expected = new Complex(0.936812, -2.30551);
330         TestUtils.assertEquals(expected, z.acos(), 1.0e-5);
331         TestUtils.assertEquals(new Complex(Math.acos(0), 0), 
332                 Complex.ZERO.acos(), 1.0e-12);
333     }
334     
335     public void testAcosInf() {
336         TestUtils.assertSame(Complex.NaN, oneInf.acos());
337         TestUtils.assertSame(Complex.NaN, oneNegInf.acos());
338         TestUtils.assertSame(Complex.NaN, infOne.acos());
339         TestUtils.assertSame(Complex.NaN, negInfOne.acos());
340         TestUtils.assertSame(Complex.NaN, infInf.acos());
341         TestUtils.assertSame(Complex.NaN, infNegInf.acos());
342         TestUtils.assertSame(Complex.NaN, negInfInf.acos());
343         TestUtils.assertSame(Complex.NaN, negInfNegInf.acos());
344     }
345     
346     public void testAcosNaN() {
347         assertTrue(Complex.NaN.acos().isNaN());
348     }
349     
350     public void testAsin() {
351         Complex z = new Complex(3, 4);
352         Complex expected = new Complex(0.633984, 2.30551);
353         TestUtils.assertEquals(expected, z.asin(), 1.0e-5);
354     }
355     
356     public void testAsinNaN() {
357         assertTrue(Complex.NaN.asin().isNaN());
358     }
359     
360     public void testAsinInf() {
361         TestUtils.assertSame(Complex.NaN, oneInf.asin());
362         TestUtils.assertSame(Complex.NaN, oneNegInf.asin());
363         TestUtils.assertSame(Complex.NaN, infOne.asin());
364         TestUtils.assertSame(Complex.NaN, negInfOne.asin());
365         TestUtils.assertSame(Complex.NaN, infInf.asin());
366         TestUtils.assertSame(Complex.NaN, infNegInf.asin());
367         TestUtils.assertSame(Complex.NaN, negInfInf.asin());
368         TestUtils.assertSame(Complex.NaN, negInfNegInf.asin());
369     }
370     
371    
372     public void testAtan() {
373         Complex z = new Complex(3, 4);
374         Complex expected = new Complex(1.44831, 0.158997);
375         TestUtils.assertEquals(expected, z.atan(), 1.0e-5);
376     }
377     
378     public void testAtanInf() {
379         TestUtils.assertSame(Complex.NaN, oneInf.atan());
380         TestUtils.assertSame(Complex.NaN, oneNegInf.atan());
381         TestUtils.assertSame(Complex.NaN, infOne.atan());
382         TestUtils.assertSame(Complex.NaN, negInfOne.atan());
383         TestUtils.assertSame(Complex.NaN, infInf.atan());
384         TestUtils.assertSame(Complex.NaN, infNegInf.atan());
385         TestUtils.assertSame(Complex.NaN, negInfInf.atan());
386         TestUtils.assertSame(Complex.NaN, negInfNegInf.atan());
387     } 
388     
389     public void testAtanNaN() {
390         assertTrue(Complex.NaN.atan().isNaN());
391         assertTrue(Complex.I.atan().isNaN());
392     }
393     
394     public void testCos() {
395         Complex z = new Complex(3, 4);
396         Complex expected = new Complex(-27.03495, -3.851153);
397         TestUtils.assertEquals(expected, z.cos(), 1.0e-5);
398     }
399     
400     public void testCosNaN() {
401         assertTrue(Complex.NaN.cos().isNaN());
402     }
403     
404     public void testCosInf() {
405         TestUtils.assertSame(infNegInf, oneInf.cos());
406         TestUtils.assertSame(infInf, oneNegInf.cos());
407         TestUtils.assertSame(Complex.NaN, infOne.cos());
408         TestUtils.assertSame(Complex.NaN, negInfOne.cos());
409         TestUtils.assertSame(Complex.NaN, infInf.cos());
410         TestUtils.assertSame(Complex.NaN, infNegInf.cos());
411         TestUtils.assertSame(Complex.NaN, negInfInf.cos());
412         TestUtils.assertSame(Complex.NaN, negInfNegInf.cos());
413     } 
414     
415     public void testCosh() {
416         Complex z = new Complex(3, 4);
417         Complex expected = new Complex(-6.58066, -7.58155);
418         TestUtils.assertEquals(expected, z.cosh(), 1.0e-5);
419     }
420     
421     public void testCoshNaN() {
422         assertTrue(Complex.NaN.cosh().isNaN());
423     }
424     
425     public void testCoshInf() {  
426         TestUtils.assertSame(Complex.NaN, oneInf.cosh());
427         TestUtils.assertSame(Complex.NaN, oneNegInf.cosh());
428         TestUtils.assertSame(infInf, infOne.cosh());
429         TestUtils.assertSame(infNegInf, negInfOne.cosh());
430         TestUtils.assertSame(Complex.NaN, infInf.cosh());
431         TestUtils.assertSame(Complex.NaN, infNegInf.cosh());
432         TestUtils.assertSame(Complex.NaN, negInfInf.cosh());
433         TestUtils.assertSame(Complex.NaN, negInfNegInf.cosh());
434     } 
435     
436     public void testExp() {
437         Complex z = new Complex(3, 4);
438         Complex expected = new Complex(-13.12878, -15.20078);
439         TestUtils.assertEquals(expected, z.exp(), 1.0e-5);
440         TestUtils.assertEquals(Complex.ONE, 
441                 Complex.ZERO.exp(), 10e-12);
442         Complex iPi = Complex.I.multiply(new Complex(pi,0));
443         TestUtils.assertEquals(Complex.ONE.negate(), 
444                 iPi.exp(), 10e-12);
445     }
446     
447     public void testExpNaN() {
448         assertTrue(Complex.NaN.exp().isNaN());
449     }
450     
451     public void testExpInf() {
452         TestUtils.assertSame(Complex.NaN, oneInf.exp());
453         TestUtils.assertSame(Complex.NaN, oneNegInf.exp());
454         TestUtils.assertSame(infInf, infOne.exp());
455         TestUtils.assertSame(Complex.ZERO, negInfOne.exp());
456         TestUtils.assertSame(Complex.NaN, infInf.exp());
457         TestUtils.assertSame(Complex.NaN, infNegInf.exp());
458         TestUtils.assertSame(Complex.NaN, negInfInf.exp());
459         TestUtils.assertSame(Complex.NaN, negInfNegInf.exp());
460     }
461     
462     public void testLog() {
463         Complex z = new Complex(3, 4);
464         Complex expected = new Complex(1.60944, 0.927295);
465         TestUtils.assertEquals(expected, z.log(), 1.0e-5);
466     }
467     
468     public void testLogNaN() {
469         assertTrue(Complex.NaN.log().isNaN());
470     }
471     
472     public void testLogInf() {
473         TestUtils.assertEquals(new Complex(inf, pi / 2),
474                 oneInf.log(), 10e-12);
475         TestUtils.assertEquals(new Complex(inf, -pi / 2),
476                 oneNegInf.log(), 10e-12);
477         TestUtils.assertEquals(infZero, infOne.log(), 10e-12);
478         TestUtils.assertEquals(new Complex(inf, pi),
479                 negInfOne.log(), 10e-12);
480         TestUtils.assertEquals(new Complex(inf, pi / 4),
481                 infInf.log(), 10e-12);
482         TestUtils.assertEquals(new Complex(inf, -pi / 4),
483                 infNegInf.log(), 10e-12);
484         TestUtils.assertEquals(new Complex(inf, 3d * pi / 4),
485                 negInfInf.log(), 10e-12);
486         TestUtils.assertEquals(new Complex(inf, - 3d * pi / 4),
487                 negInfNegInf.log(), 10e-12);
488     }
489     
490     public void testLogZero() {
491         TestUtils.assertSame(negInfZero, Complex.ZERO.log());
492     }
493     
494     public void testPow() {
495         Complex x = new Complex(3, 4);
496         Complex y = new Complex(5, 6);
497         Complex expected = new Complex(-1.860893, 11.83677);
498         TestUtils.assertEquals(expected, x.pow(y), 1.0e-5);
499     }
500     
501     public void testPowNaNBase() {
502         Complex x = new Complex(3, 4);
503         assertTrue(Complex.NaN.pow(x).isNaN());
504     }
505     
506     public void testPowNaNExponent() {
507         Complex x = new Complex(3, 4);
508         assertTrue(x.pow(Complex.NaN).isNaN());
509     }
510     
511    public void testPowInf() {
512        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneInf));
513        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneNegInf));
514        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infOne));
515        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infInf));
516        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infNegInf));
517        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfInf));
518        TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfNegInf));
519        TestUtils.assertSame(Complex.NaN,infOne.pow(Complex.ONE));
520        TestUtils.assertSame(Complex.NaN,negInfOne.pow(Complex.ONE));
521        TestUtils.assertSame(Complex.NaN,infInf.pow(Complex.ONE));
522        TestUtils.assertSame(Complex.NaN,infNegInf.pow(Complex.ONE));
523        TestUtils.assertSame(Complex.NaN,negInfInf.pow(Complex.ONE));
524        TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Complex.ONE));
525        TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infNegInf));
526        TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(negInfNegInf));
527        TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infInf));
528        TestUtils.assertSame(Complex.NaN,infInf.pow(infNegInf));
529        TestUtils.assertSame(Complex.NaN,infInf.pow(negInfNegInf));
530        TestUtils.assertSame(Complex.NaN,infInf.pow(infInf));
531        TestUtils.assertSame(Complex.NaN,infNegInf.pow(infNegInf));
532        TestUtils.assertSame(Complex.NaN,infNegInf.pow(negInfNegInf));
533        TestUtils.assertSame(Complex.NaN,infNegInf.pow(infInf));   
534    }
535    
536    public void testPowZero() {
537        TestUtils.assertSame(Complex.NaN, 
538                Complex.ZERO.pow(Complex.ONE));
539        TestUtils.assertSame(Complex.NaN, 
540                Complex.ZERO.pow(Complex.ZERO));
541        TestUtils.assertSame(Complex.NaN, 
542                Complex.ZERO.pow(Complex.I));
543        TestUtils.assertEquals(Complex.ONE,
544                Complex.ONE.pow(Complex.ZERO), 10e-12);
545        TestUtils.assertEquals(Complex.ONE,
546                Complex.I.pow(Complex.ZERO), 10e-12);
547        TestUtils.assertEquals(Complex.ONE,
548                new Complex(-1, 3).pow(Complex.ZERO), 10e-12);
549    }
550     
551     public void testpowNull() {
552         try {
553             Complex.ONE.pow(null); 
554             fail("Expecting NullPointerException");
555         } catch (NullPointerException ex) {
556             // expected
557         }
558     }
559     
560     public void testSin() {
561         Complex z = new Complex(3, 4);
562         Complex expected = new Complex(3.853738, -27.01681);
563         TestUtils.assertEquals(expected, z.sin(), 1.0e-5);
564     }
565     
566     public void testSinInf() {
567         TestUtils.assertSame(infInf, oneInf.sin());
568         TestUtils.assertSame(infNegInf, oneNegInf.sin());
569         TestUtils.assertSame(Complex.NaN, infOne.sin());
570         TestUtils.assertSame(Complex.NaN, negInfOne.sin());
571         TestUtils.assertSame(Complex.NaN, infInf.sin());
572         TestUtils.assertSame(Complex.NaN, infNegInf.sin());
573         TestUtils.assertSame(Complex.NaN, negInfInf.sin());
574         TestUtils.assertSame(Complex.NaN, negInfNegInf.sin());
575     }
576     
577     public void testSinNaN() {
578         assertTrue(Complex.NaN.sin().isNaN());
579     }
580     
581     public void testSinh() {
582         Complex z = new Complex(3, 4);
583         Complex expected = new Complex(-6.54812, -7.61923);
584         TestUtils.assertEquals(expected, z.sinh(), 1.0e-5);
585     }
586     
587     public void testSinhNaN() {
588         assertTrue(Complex.NaN.sinh().isNaN());
589     }
590     
591     public void testSinhInf() {
592         TestUtils.assertSame(Complex.NaN, oneInf.sinh());
593         TestUtils.assertSame(Complex.NaN, oneNegInf.sinh());
594         TestUtils.assertSame(infInf, infOne.sinh());
595         TestUtils.assertSame(negInfInf, negInfOne.sinh());
596         TestUtils.assertSame(Complex.NaN, infInf.sinh());
597         TestUtils.assertSame(Complex.NaN, infNegInf.sinh());
598         TestUtils.assertSame(Complex.NaN, negInfInf.sinh());
599         TestUtils.assertSame(Complex.NaN, negInfNegInf.sinh());
600     }
601     
602     public void testSqrtRealPositive() {
603         Complex z = new Complex(3, 4);
604         Complex expected = new Complex(2, 1);
605         TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
606     }
607     
608     public void testSqrtRealZero() {
609         Complex z = new Complex(0.0, 4);
610         Complex expected = new Complex(1.41421, 1.41421);
611         TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
612     }
613     
614     public void testSqrtRealNegative() {
615         Complex z = new Complex(-3.0, 4);
616         Complex expected = new Complex(1, 2);
617         TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
618     }
619     
620     public void testSqrtImaginaryZero() {
621         Complex z = new Complex(-3.0, 0.0);
622         Complex expected = new Complex(0.0, 1.73205);
623         TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
624     }
625     
626     public void testSqrtImaginaryNegative() {
627         Complex z = new Complex(-3.0, -4.0);
628         Complex expected = new Complex(1.0, -2.0);
629         TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5);
630     }
631     
632     public void testSqrtPolar() {
633         double r = 1;
634         for (int i = 0; i < 5; i++) {
635             r += i;
636             double theta = 0;
637             for (int j =0; j < 11; j++) {
638                 theta += pi /12;
639                 Complex z = ComplexUtils.polar2Complex(r, theta);
640                 Complex sqrtz = ComplexUtils.polar2Complex(Math.sqrt(r), theta / 2);
641                 TestUtils.assertEquals(sqrtz, z.sqrt(), 10e-12);
642             }
643         }       
644     }
645     
646     public void testSqrtNaN() {
647         assertTrue(Complex.NaN.sqrt().isNaN());
648     }
649       
650     public void testSqrtInf() {
651         TestUtils.assertSame(infNaN, oneInf.sqrt());
652         TestUtils.assertSame(infNaN, oneNegInf.sqrt());
653         TestUtils.assertSame(infZero, infOne.sqrt());
654         TestUtils.assertSame(zeroInf, negInfOne.sqrt());
655         TestUtils.assertSame(infNaN, infInf.sqrt());
656         TestUtils.assertSame(infNaN, infNegInf.sqrt());
657         TestUtils.assertSame(nanInf, negInfInf.sqrt());
658         TestUtils.assertSame(nanNegInf, negInfNegInf.sqrt());
659     }
660     
661     public void testSqrt1z() {
662         Complex z = new Complex(3, 4);
663         Complex expected = new Complex(4.08033, -2.94094);
664         TestUtils.assertEquals(expected, z.sqrt1z(), 1.0e-5);
665     }
666     
667     public void testSqrt1zNaN() {
668         assertTrue(Complex.NaN.sqrt1z().isNaN());
669     }
670     
671     public void testTan() {
672         Complex z = new Complex(3, 4);
673         Complex expected = new Complex(-0.000187346, 0.999356);
674         TestUtils.assertEquals(expected, z.tan(), 1.0e-5);
675     }
676     
677     public void testTanNaN() {
678         assertTrue(Complex.NaN.tan().isNaN());
679     }
680     
681     public void testTanInf() {
682         TestUtils.assertSame(zeroNaN, oneInf.tan());
683         TestUtils.assertSame(zeroNaN, oneNegInf.tan());
684         TestUtils.assertSame(Complex.NaN, infOne.tan());
685         TestUtils.assertSame(Complex.NaN, negInfOne.tan());
686         TestUtils.assertSame(Complex.NaN, infInf.tan());
687         TestUtils.assertSame(Complex.NaN, infNegInf.tan());
688         TestUtils.assertSame(Complex.NaN, negInfInf.tan());
689         TestUtils.assertSame(Complex.NaN, negInfNegInf.tan());
690     }
691     
692    public void testTanCritical() {
693         TestUtils.assertSame(infNaN, new Complex(pi/2, 0).tan());
694         TestUtils.assertSame(negInfNaN, new Complex(-pi/2, 0).tan());
695     }
696     
697     public void testTanh() {
698         Complex z = new Complex(3, 4);
699         Complex expected = new Complex(1.00071, 0.00490826);
700         TestUtils.assertEquals(expected, z.tanh(), 1.0e-5);
701     }
702     
703     public void testTanhNaN() {
704         assertTrue(Complex.NaN.tanh().isNaN());
705     }
706     
707     public void testTanhInf() {
708         TestUtils.assertSame(Complex.NaN, oneInf.tanh());
709         TestUtils.assertSame(Complex.NaN, oneNegInf.tanh());
710         TestUtils.assertSame(nanZero, infOne.tanh());
711         TestUtils.assertSame(nanZero, negInfOne.tanh());
712         TestUtils.assertSame(Complex.NaN, infInf.tanh());
713         TestUtils.assertSame(Complex.NaN, infNegInf.tanh());
714         TestUtils.assertSame(Complex.NaN, negInfInf.tanh());
715         TestUtils.assertSame(Complex.NaN, negInfNegInf.tanh());
716     }
717     
718     public void testTanhCritical() {
719         TestUtils.assertSame(nanInf, new Complex(0, pi/2).tanh());
720     }
721 
722     /** test issue MATH-221 */
723     public void testMath221() {
724         assertEquals(new Complex(0,-1), new Complex(0,1).multiply(new Complex(-1,0)));
725     }
726     
727     /** 
728      * Test: computing <b>third roots</b> of z.
729      * <pre>
730      * <code>
731      * <b>z = -2 + 2 * i</b>
732      *   => z_0 =  1      +          i
733      *   => z_1 = -1.3660 + 0.3660 * i
734      *   => z_2 =  0.3660 - 1.3660 * i
735      * </code>
736      * </pre>
737      */
738     public void testNthRoot_normal_thirdRoot() {
739         // The complex number we want to compute all third-roots for.
740         Complex z = new Complex(-2,2);
741         // The List holding all third roots
742         Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
743         // Returned Collection must not be empty!
744         assertEquals(3, thirdRootsOfZ.length);
745         // test z_0
746         assertEquals(1.0,                  thirdRootsOfZ[0].getReal(),      1.0e-5); 
747         assertEquals(1.0,                  thirdRootsOfZ[0].getImaginary(), 1.0e-5);
748         // test z_1
749         assertEquals(-1.3660254037844386,  thirdRootsOfZ[1].getReal(),      1.0e-5);
750         assertEquals(0.36602540378443843,  thirdRootsOfZ[1].getImaginary(), 1.0e-5);
751         // test z_2
752         assertEquals(0.366025403784439,    thirdRootsOfZ[2].getReal(),      1.0e-5);
753         assertEquals(-1.3660254037844384,  thirdRootsOfZ[2].getImaginary(), 1.0e-5);
754     }
755 
756 
757     /** 
758      * Test: computing <b>fourth roots</b> of z.
759      * <pre>
760      * <code>
761      * <b>z = 5 - 2 * i</b>
762      *   => z_0 =  1.5164 - 0.1446 * i
763      *   => z_1 =  0.1446 + 1.5164 * i
764      *   => z_2 = -1.5164 + 0.1446 * i
765      *   => z_3 = -1.5164 - 0.1446 * i
766      * </code>
767      * </pre>
768      */
769     public void testNthRoot_normal_fourthRoot() {
770         // The complex number we want to compute all third-roots for.
771         Complex z = new Complex(5,-2);
772         // The List holding all fourth roots
773         Complex[] fourthRootsOfZ = z.nthRoot(4).toArray(new Complex[0]);
774         // Returned Collection must not be empty!
775         assertEquals(4, fourthRootsOfZ.length);
776         // test z_0
777         assertEquals(1.5164629308487783,     fourthRootsOfZ[0].getReal(),      1.0e-5); 
778         assertEquals(-0.14469266210702247,   fourthRootsOfZ[0].getImaginary(), 1.0e-5);
779         // test z_1
780         assertEquals(0.14469266210702256,    fourthRootsOfZ[1].getReal(),      1.0e-5);
781         assertEquals(1.5164629308487783,     fourthRootsOfZ[1].getImaginary(), 1.0e-5);
782         // test z_2
783         assertEquals(-1.5164629308487783,    fourthRootsOfZ[2].getReal(),      1.0e-5);
784         assertEquals(0.14469266210702267,    fourthRootsOfZ[2].getImaginary(), 1.0e-5);
785         // test z_3
786         assertEquals(-0.14469266210702275,   fourthRootsOfZ[3].getReal(),      1.0e-5);
787         assertEquals(-1.5164629308487783,    fourthRootsOfZ[3].getImaginary(), 1.0e-5);
788     }
789 
790     /** 
791      * Test: computing <b>third roots</b> of z.
792      * <pre>
793      * <code>
794      * <b>z = 8</b>
795      *   => z_0 =  2
796      *   => z_1 = -1 + 1.73205 * i
797      *   => z_2 = -1 - 1.73205 * i
798      * </code>
799      * </pre>
800      */
801     public void testNthRoot_cornercase_thirdRoot_imaginaryPartEmpty() {
802         // The number 8 has three third roots. One we all already know is the number 2.
803         // But there are two more complex roots.
804         Complex z = new Complex(8,0);
805         // The List holding all third roots
806         Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
807         // Returned Collection must not be empty!
808         assertEquals(3, thirdRootsOfZ.length);
809         // test z_0
810         assertEquals(2.0,                thirdRootsOfZ[0].getReal(),      1.0e-5); 
811         assertEquals(0.0,                thirdRootsOfZ[0].getImaginary(), 1.0e-5);
812         // test z_1
813         assertEquals(-1.0,               thirdRootsOfZ[1].getReal(),      1.0e-5);
814         assertEquals(1.7320508075688774, thirdRootsOfZ[1].getImaginary(), 1.0e-5);
815         // test z_2
816         assertEquals(-1.0,               thirdRootsOfZ[2].getReal(),      1.0e-5);
817         assertEquals(-1.732050807568877, thirdRootsOfZ[2].getImaginary(), 1.0e-5);
818     }
819 
820 
821     /** 
822      * Test: computing <b>third roots</b> of z with real part 0.
823      * <pre>
824      * <code>
825      * <b>z = 2 * i</b>
826      *   => z_0 =  1.0911 + 0.6299 * i
827      *   => z_1 = -1.0911 + 0.6299 * i
828      *   => z_2 = -2.3144 - 1.2599 * i
829      * </code>
830      * </pre>
831      */
832     public void testNthRoot_cornercase_thirdRoot_realPartZero() {
833         // complex number with only imaginary part
834         Complex z = new Complex(0,2);
835         // The List holding all third roots
836         Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
837         // Returned Collection must not be empty!
838         assertEquals(3, thirdRootsOfZ.length);
839         // test z_0
840         assertEquals(1.0911236359717216,      thirdRootsOfZ[0].getReal(),      1.0e-5); 
841         assertEquals(0.6299605249474365,      thirdRootsOfZ[0].getImaginary(), 1.0e-5);
842         // test z_1
843         assertEquals(-1.0911236359717216,     thirdRootsOfZ[1].getReal(),      1.0e-5);
844         assertEquals(0.6299605249474365,      thirdRootsOfZ[1].getImaginary(), 1.0e-5);
845         // test z_2
846         assertEquals(-2.3144374213981936E-16, thirdRootsOfZ[2].getReal(),      1.0e-5);
847         assertEquals(-1.2599210498948732,     thirdRootsOfZ[2].getImaginary(), 1.0e-5);
848     }
849 
850     /**
851      * Test cornercases with NaN and Infinity.
852      */
853     public void testNthRoot_cornercase_NAN_Inf() {
854         // NaN + finite -> NaN
855         List<Complex> roots = oneNaN.nthRoot(3);
856         assertEquals(1,roots.size());
857         assertEquals(Complex.NaN, roots.get(0));
858         
859         roots = nanZero.nthRoot(3);
860         assertEquals(1,roots.size());
861         assertEquals(Complex.NaN, roots.get(0));
862         
863         // NaN + infinite -> NaN
864         roots = nanInf.nthRoot(3);
865         assertEquals(1,roots.size());
866         assertEquals(Complex.NaN, roots.get(0));
867         
868         // finite + infinite -> Inf
869         roots = oneInf.nthRoot(3);
870         assertEquals(1,roots.size());
871         assertEquals(Complex.INF, roots.get(0));
872         
873         // infinite + infinite -> Inf
874         roots = negInfInf.nthRoot(3);
875         assertEquals(1,roots.size());
876         assertEquals(Complex.INF, roots.get(0));
877     }
878     
879     /**
880      * Test standard values
881      */
882     public void testGetArgument() {
883         Complex z = new Complex(1, 0);
884         assertEquals(0.0, z.getArgument(), 1.0e-12);
885         
886         z = new Complex(1, 1);
887         assertEquals(Math.PI/4, z.getArgument(), 1.0e-12);
888         
889         z = new Complex(0, 1);
890         assertEquals(Math.PI/2, z.getArgument(), 1.0e-12);
891         
892         z = new Complex(-1, 1);
893         assertEquals(3 * Math.PI/4, z.getArgument(), 1.0e-12);
894         
895         z = new Complex(-1, 0);
896         assertEquals(Math.PI, z.getArgument(), 1.0e-12);
897         
898         z = new Complex(-1, -1);
899         assertEquals(-3 * Math.PI/4, z.getArgument(), 1.0e-12);
900         
901         z = new Complex(0, -1);
902         assertEquals(-Math.PI/2, z.getArgument(), 1.0e-12);
903         
904         z = new Complex(1, -1);
905         assertEquals(-Math.PI/4, z.getArgument(), 1.0e-12);
906         
907     }
908     
909     /**
910      * Verify atan2-style handling of infinite parts
911      */
912     public void testGetArgumentInf() {
913         assertEquals(Math.PI/4, infInf.getArgument(), 1.0e-12);
914         assertEquals(Math.PI/2, oneInf.getArgument(), 1.0e-12);
915         assertEquals(0.0, infOne.getArgument(), 1.0e-12);
916         assertEquals(Math.PI/2, zeroInf.getArgument(), 1.0e-12);
917         assertEquals(0.0, infZero.getArgument(), 1.0e-12);
918         assertEquals(Math.PI, negInfOne.getArgument(), 1.0e-12);
919         assertEquals(-3.0*Math.PI/4, negInfNegInf.getArgument(), 1.0e-12);  
920         assertEquals(-Math.PI/2, oneNegInf.getArgument(), 1.0e-12);        
921     }
922     
923     /**
924      * Verify that either part NaN results in NaN
925      */
926     public void testGetArgumentNaN() {
927         assertEquals(nan, nanZero.getArgument());
928         assertEquals(nan, zeroNaN.getArgument());
929         assertEquals(nan, Complex.NaN.getArgument());  
930     }
931     
932     public void testSerial() {
933         Complex z = new Complex(3.0, 4.0);
934         assertEquals(z, TestUtils.serializeAndRecover(z));
935         Complex ncmplx = (Complex)TestUtils.serializeAndRecover(oneNaN);
936         assertEquals(nanZero, ncmplx);
937         assertTrue(ncmplx.isNaN());
938         Complex infcmplx = (Complex)TestUtils.serializeAndRecover(infInf);
939         assertEquals(infInf, infcmplx);
940         assertTrue(infcmplx.isInfinite());
941         TestComplex tz = new TestComplex(3.0, 4.0);
942         assertEquals(tz, TestUtils.serializeAndRecover(tz));
943         TestComplex ntcmplx = (TestComplex)TestUtils.serializeAndRecover(new TestComplex(oneNaN));
944         assertEquals(nanZero, ntcmplx);
945         assertTrue(ntcmplx.isNaN());
946         TestComplex inftcmplx = (TestComplex)TestUtils.serializeAndRecover(new TestComplex(infInf));
947         assertEquals(infInf, inftcmplx);
948         assertTrue(inftcmplx.isInfinite());
949     }
950     
951     /**
952      * Class to test extending Complex
953      */
954     public static class TestComplex extends Complex {
955 
956         /**
957          * Serialization identifier.
958          */
959         private static final long serialVersionUID = 3268726724160389237L;
960 
961         public TestComplex(double real, double imaginary) {
962             super(real, imaginary);
963         }
964         
965         public TestComplex(Complex other){
966             this(other.getReal(), other.getImaginary());
967         }
968 
969         @Override
970         protected TestComplex createComplex(double real, double imaginary){
971             return new TestComplex(real, imaginary);
972         }
973 
974     }
975 
976 }