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