001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.complex;
019    
020    import org.apache.commons.math.TestUtils;
021    
022    import java.util.List;
023    
024    import junit.framework.TestCase;
025    
026    /**
027     * @version $Revision: 791237 $ $Date: 2009-07-05 08:53:13 -0400 (Sun, 05 Jul 2009) $
028     */
029    public class ComplexTest extends TestCase {
030        
031    
032        private double inf = Double.POSITIVE_INFINITY;
033        private double neginf = Double.NEGATIVE_INFINITY;
034        private double nan = Double.NaN;
035        private double pi = Math.PI;
036        private Complex oneInf = new Complex(1, inf);
037        private Complex oneNegInf = new Complex(1, neginf);
038        private Complex infOne = new Complex(inf, 1);
039        private Complex infZero = new Complex(inf, 0);
040        private Complex infNaN = new Complex(inf, nan);
041        private Complex infNegInf = new Complex(inf, neginf);
042        private Complex infInf = new Complex(inf, inf);
043        private Complex negInfInf = new Complex(neginf, inf);
044        private Complex negInfZero = new Complex(neginf, 0);
045        private Complex negInfOne = new Complex(neginf, 1);
046        private Complex negInfNaN = new Complex(neginf, nan);
047        private Complex negInfNegInf = new Complex(neginf, neginf);
048        private Complex oneNaN = new Complex(1, nan);
049        private Complex zeroInf = new Complex(0, inf);
050        private Complex zeroNaN = new Complex(0, nan);
051        private Complex nanInf = new Complex(nan, inf);
052        private Complex nanNegInf = new Complex(nan, neginf);
053        private Complex nanZero = new Complex(nan, 0);
054        
055        public void testConstructor() {
056            Complex z = new Complex(3.0, 4.0);
057            assertEquals(3.0, z.getReal(), 1.0e-5);
058            assertEquals(4.0, z.getImaginary(), 1.0e-5);
059        }
060        
061        public void testConstructorNaN() {
062            Complex z = new Complex(3.0, Double.NaN);
063            assertTrue(z.isNaN());
064    
065            z = new Complex(nan, 4.0);
066            assertTrue(z.isNaN());
067    
068            z = new Complex(3.0, 4.0);
069            assertFalse(z.isNaN());
070        }
071        
072        public void testAbs() {
073            Complex z = new Complex(3.0, 4.0);
074            assertEquals(5.0, z.abs(), 1.0e-5);
075        }
076        
077        public void testAbsNaN() {
078            assertTrue(Double.isNaN(Complex.NaN.abs()));
079            Complex z = new Complex(inf, nan);
080            assertTrue(Double.isNaN(z.abs()));
081        }
082        
083        public void testAbsInfinite() {
084            Complex z = new Complex(inf, 0);
085            assertEquals(inf, z.abs(), 0);
086            z = new Complex(0, neginf);
087            assertEquals(inf, z.abs(), 0);
088            z = new Complex(inf, neginf);
089            assertEquals(inf, z.abs(), 0);     
090        }
091        
092        public void testAdd() {
093            Complex x = new Complex(3.0, 4.0);
094            Complex y = new Complex(5.0, 6.0);
095            Complex z = x.add(y);
096            assertEquals(8.0, z.getReal(), 1.0e-5);
097            assertEquals(10.0, z.getImaginary(), 1.0e-5);
098        }
099        
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    }