View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.ode.nonstiff;
18  
19  import org.apache.commons.numbers.core.Sum;
20  import org.apache.commons.math4.core.jdkmath.JdkMath;
21  import org.apache.commons.math4.legacy.core.Field;
22  import org.apache.commons.math4.legacy.core.RealFieldElement;
23  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
24  
25  /**
26   * This class wraps a {@code double} value in an object. It is similar to the
27   * standard class {@link Double}, while also implementing the
28   * {@link RealFieldElement} interface.
29   *
30   * @since 3.1
31   */
32  public class Decimal64 extends Number
33                         implements RealFieldElement<Decimal64>, Comparable<Decimal64> {
34  
35      /** The constant value of {@code 0d} as a {@code Decimal64}. */
36      public static final Decimal64 ZERO;
37  
38      /** The constant value of {@code 1d} as a {@code Decimal64}. */
39      public static final Decimal64 ONE;
40  
41      /**
42       * The constant value of {@link Double#NEGATIVE_INFINITY} as a
43       * {@code Decimal64}.
44       */
45      public static final Decimal64 NEGATIVE_INFINITY;
46  
47      /**
48       * The constant value of {@link Double#POSITIVE_INFINITY} as a
49       * {@code Decimal64}.
50       */
51      public static final Decimal64 POSITIVE_INFINITY;
52  
53      /** The constant value of {@link Double#NaN} as a {@code Decimal64}. */
54      public static final Decimal64 NAN;
55  
56      /** */
57      private static final long serialVersionUID = 20120227L;
58  
59      static {
60          ZERO = new Decimal64(0d);
61          ONE = new Decimal64(1d);
62          NEGATIVE_INFINITY = new Decimal64(Double.NEGATIVE_INFINITY);
63          POSITIVE_INFINITY = new Decimal64(Double.POSITIVE_INFINITY);
64          NAN = new Decimal64(Double.NaN);
65      }
66  
67      /** The primitive {@code double} value of this object. */
68      private final double value;
69  
70      /**
71       * Creates a new instance of this class.
72       *
73       * @param x the primitive {@code double} value of the object to be created
74       */
75      public Decimal64(final double x) {
76          this.value = x;
77      }
78  
79      /*
80       * Methods from the FieldElement interface.
81       */
82  
83      /** {@inheritDoc} */
84      @Override
85      public Field<Decimal64> getField() {
86          return Decimal64Field.getInstance();
87      }
88  
89      /**
90       * {@inheritDoc}
91       *
92       * The current implementation strictly enforces
93       * {@code this.add(a).equals(new Decimal64(this.doubleValue()
94       * + a.doubleValue()))}.
95       */
96      @Override
97      public Decimal64 add(final Decimal64 a) {
98          return new Decimal64(this.value + a.value);
99      }
100 
101     /**
102      * {@inheritDoc}
103      *
104      * The current implementation strictly enforces
105      * {@code this.subtract(a).equals(new Decimal64(this.doubleValue()
106      * - a.doubleValue()))}.
107      */
108     @Override
109     public Decimal64 subtract(final Decimal64 a) {
110         return new Decimal64(this.value - a.value);
111     }
112 
113     /**
114      * {@inheritDoc}
115      *
116      * The current implementation strictly enforces
117      * {@code this.negate().equals(new Decimal64(-this.doubleValue()))}.
118      */
119     @Override
120     public Decimal64 negate() {
121         return new Decimal64(-this.value);
122     }
123 
124     /**
125      * {@inheritDoc}
126      *
127      * The current implementation strictly enforces
128      * {@code this.multiply(a).equals(new Decimal64(this.doubleValue()
129      * * a.doubleValue()))}.
130      */
131     @Override
132     public Decimal64 multiply(final Decimal64 a) {
133         return new Decimal64(this.value * a.value);
134     }
135 
136     /**
137      * {@inheritDoc}
138      *
139      * The current implementation strictly enforces
140      * {@code this.multiply(n).equals(new Decimal64(n * this.doubleValue()))}.
141      */
142     @Override
143     public Decimal64 multiply(final int n) {
144         return new Decimal64(n * this.value);
145     }
146 
147     /**
148      * {@inheritDoc}
149      *
150      * The current implementation strictly enforces
151      * {@code this.divide(a).equals(new Decimal64(this.doubleValue()
152      * / a.doubleValue()))}.
153      *
154      */
155     @Override
156     public Decimal64 divide(final Decimal64 a) {
157         return new Decimal64(this.value / a.value);
158     }
159 
160     /**
161      * {@inheritDoc}
162      *
163      * The current implementation strictly enforces
164      * {@code this.reciprocal().equals(new Decimal64(1.0
165      * / this.doubleValue()))}.
166      */
167     @Override
168     public Decimal64 reciprocal() {
169         return new Decimal64(1.0 / this.value);
170     }
171 
172     /*
173      * Methods from the Number abstract class
174      */
175 
176     /**
177      * {@inheritDoc}
178      *
179      * The current implementation performs casting to a {@code byte}.
180      */
181     @Override
182     public byte byteValue() {
183         return (byte) value;
184     }
185 
186     /**
187      * {@inheritDoc}
188      *
189      * The current implementation performs casting to a {@code short}.
190      */
191     @Override
192     public short shortValue() {
193         return (short) value;
194     }
195 
196     /**
197      * {@inheritDoc}
198      *
199      * The current implementation performs casting to a {@code int}.
200      */
201     @Override
202     public int intValue() {
203         return (int) value;
204     }
205 
206     /**
207      * {@inheritDoc}
208      *
209      * The current implementation performs casting to a {@code long}.
210      */
211     @Override
212     public long longValue() {
213         return (long) value;
214     }
215 
216     /**
217      * {@inheritDoc}
218      *
219      * The current implementation performs casting to a {@code float}.
220      */
221     @Override
222     public float floatValue() {
223         return (float) value;
224     }
225 
226     /** {@inheritDoc} */
227     @Override
228     public double doubleValue() {
229         return value;
230     }
231 
232     /*
233      * Methods from the Comparable interface.
234      */
235 
236     /**
237      * {@inheritDoc}
238      *
239      * The current implementation returns the same value as
240      * <center> {@code Double.valueOf(this.doubleValue()).compareTo(
241      * Double.valueOf(o.doubleValue()))} </center>
242      *
243      * @see Double#compareTo(Double)
244      */
245     @Override
246     public int compareTo(final Decimal64 o) {
247         return Double.compare(this.value, o.value);
248     }
249 
250     /*
251      * Methods from the Object abstract class.
252      */
253 
254     /** {@inheritDoc} */
255     @Override
256     public boolean equals(final Object obj) {
257         if (obj instanceof Decimal64) {
258             final Decimal64 that = (Decimal64) obj;
259             return Double.doubleToLongBits(this.value) == Double
260                     .doubleToLongBits(that.value);
261         }
262         return false;
263     }
264 
265     /**
266      * {@inheritDoc}
267      *
268      * The current implementation returns the same value as
269      * {@code new Double(this.doubleValue()).hashCode()}
270      *
271      * @see Double#hashCode()
272      */
273     @Override
274     public int hashCode() {
275         long v = Double.doubleToLongBits(value);
276         return (int) (v ^ (v >>> 32));
277     }
278 
279     /**
280      * {@inheritDoc}
281      *
282      * The returned {@code String} is equal to
283      * {@code Double.toString(this.doubleValue())}
284      *
285      * @see Double#toString(double)
286      */
287     @Override
288     public String toString() {
289         return Double.toString(value);
290     }
291 
292     /*
293      * Methods inspired by the Double class.
294      */
295 
296     /**
297      * Returns {@code true} if {@code this} double precision number is infinite
298      * ({@link Double#POSITIVE_INFINITY} or {@link Double#NEGATIVE_INFINITY}).
299      *
300      * @return {@code true} if {@code this} number is infinite
301      */
302     public boolean isInfinite() {
303         return Double.isInfinite(value);
304     }
305 
306     /**
307      * Returns {@code true} if {@code this} double precision number is
308      * Not-a-Number ({@code NaN}), false otherwise.
309      *
310      * @return {@code true} if {@code this} is {@code NaN}
311      */
312     public boolean isNaN() {
313         return Double.isNaN(value);
314     }
315 
316     /** {@inheritDoc}
317      * @since 3.2
318      */
319     @Override
320     public double getReal() {
321         return value;
322     }
323 
324     /** {@inheritDoc}
325      * @since 3.2
326      */
327     @Override
328     public Decimal64 add(final double a) {
329         return new Decimal64(value + a);
330     }
331 
332     /** {@inheritDoc}
333      * @since 3.2
334      */
335     @Override
336     public Decimal64 subtract(final double a) {
337         return new Decimal64(value - a);
338     }
339 
340     /** {@inheritDoc}
341      * @since 3.2
342      */
343     @Override
344     public Decimal64 multiply(final double a) {
345         return new Decimal64(value * a);
346     }
347 
348     /** {@inheritDoc}
349      * @since 3.2
350      */
351     @Override
352     public Decimal64 divide(final double a) {
353         return new Decimal64(value / a);
354     }
355 
356     /** {@inheritDoc}
357      * @since 3.2
358      */
359     @Override
360     public Decimal64 remainder(final double a) {
361         return new Decimal64(JdkMath.IEEEremainder(value, a));
362     }
363 
364     /** {@inheritDoc}
365      * @since 3.2
366      */
367     @Override
368     public Decimal64 remainder(final Decimal64 a) {
369         return new Decimal64(JdkMath.IEEEremainder(value, a.value));
370     }
371 
372     /** {@inheritDoc}
373      * @since 3.2
374      */
375     @Override
376     public Decimal64 abs() {
377         return new Decimal64(JdkMath.abs(value));
378     }
379 
380     /** {@inheritDoc}
381      * @since 3.2
382      */
383     @Override
384     public Decimal64 ceil() {
385         return new Decimal64(JdkMath.ceil(value));
386     }
387 
388     /** {@inheritDoc}
389      * @since 3.2
390      */
391     @Override
392     public Decimal64 floor() {
393         return new Decimal64(JdkMath.floor(value));
394     }
395 
396     /** {@inheritDoc}
397      * @since 3.2
398      */
399     @Override
400     public Decimal64 rint() {
401         return new Decimal64(JdkMath.rint(value));
402     }
403 
404     /** {@inheritDoc}
405      * @since 3.2
406      */
407     @Override
408     public long round() {
409         return JdkMath.round(value);
410     }
411 
412     /** {@inheritDoc}
413      * @since 3.2
414      */
415     @Override
416     public Decimal64 signum() {
417         return new Decimal64(JdkMath.signum(value));
418     }
419 
420     /** {@inheritDoc}
421      * @since 3.2
422      */
423     @Override
424     public Decimal64 copySign(final Decimal64 sign) {
425         return new Decimal64(JdkMath.copySign(value, sign.value));
426     }
427 
428     /** {@inheritDoc}
429      * @since 3.2
430      */
431     @Override
432     public Decimal64 copySign(final double sign) {
433         return new Decimal64(JdkMath.copySign(value, sign));
434     }
435 
436     /** {@inheritDoc}
437      * @since 3.2
438      */
439     @Override
440     public Decimal64 scalb(final int n) {
441         return new Decimal64(JdkMath.scalb(value, n));
442     }
443 
444     /** {@inheritDoc}
445      * @since 3.2
446      */
447     @Override
448     public Decimal64 hypot(final Decimal64 y) {
449         return new Decimal64(JdkMath.hypot(value, y.value));
450     }
451 
452     /** {@inheritDoc}
453      * @since 3.2
454      */
455     @Override
456     public Decimal64 sqrt() {
457         return new Decimal64(JdkMath.sqrt(value));
458     }
459 
460     /** {@inheritDoc}
461      * @since 3.2
462      */
463     @Override
464     public Decimal64 cbrt() {
465         return new Decimal64(JdkMath.cbrt(value));
466     }
467 
468     /** {@inheritDoc}
469      * @since 3.2
470      */
471     @Override
472     public Decimal64 rootN(final int n) {
473         if (value < 0) {
474             return new Decimal64(-JdkMath.pow(-value, 1.0 / n));
475         } else {
476             return new Decimal64(JdkMath.pow(value, 1.0 / n));
477         }
478     }
479 
480     /** {@inheritDoc}
481      * @since 3.2
482      */
483     @Override
484     public Decimal64 pow(final double p) {
485         return new Decimal64(JdkMath.pow(value, p));
486     }
487 
488     /** {@inheritDoc}
489      * @since 3.2
490      */
491     @Override
492     public Decimal64 pow(final int n) {
493         return new Decimal64(JdkMath.pow(value, n));
494     }
495 
496     /** {@inheritDoc}
497      * @since 3.2
498      */
499     @Override
500     public Decimal64 pow(final Decimal64 e) {
501         return new Decimal64(JdkMath.pow(value, e.value));
502     }
503 
504     /** {@inheritDoc}
505      * @since 3.2
506      */
507     @Override
508     public Decimal64 exp() {
509         return new Decimal64(JdkMath.exp(value));
510     }
511 
512     /** {@inheritDoc}
513      * @since 3.2
514      */
515     @Override
516     public Decimal64 expm1() {
517         return new Decimal64(JdkMath.expm1(value));
518     }
519 
520     /** {@inheritDoc}
521      * @since 3.2
522      */
523     @Override
524     public Decimal64 log() {
525         return new Decimal64(JdkMath.log(value));
526     }
527 
528     /** {@inheritDoc}
529      * @since 3.2
530      */
531     @Override
532     public Decimal64 log1p() {
533         return new Decimal64(JdkMath.log1p(value));
534     }
535 
536     /** Base 10 logarithm.
537      * @return base 10 logarithm of the instance
538      * @since 3.2
539      */
540     @Override
541     public Decimal64 log10() {
542         return new Decimal64(JdkMath.log10(value));
543     }
544 
545     /** {@inheritDoc}
546      * @since 3.2
547      */
548     @Override
549     public Decimal64 cos() {
550         return new Decimal64(JdkMath.cos(value));
551     }
552 
553     /** {@inheritDoc}
554      * @since 3.2
555      */
556     @Override
557     public Decimal64 sin() {
558         return new Decimal64(JdkMath.sin(value));
559     }
560 
561     /** {@inheritDoc}
562      * @since 3.2
563      */
564     @Override
565     public Decimal64 tan() {
566         return new Decimal64(JdkMath.tan(value));
567     }
568 
569     /** {@inheritDoc}
570      * @since 3.2
571      */
572     @Override
573     public Decimal64 acos() {
574         return new Decimal64(JdkMath.acos(value));
575     }
576 
577     /** {@inheritDoc}
578      * @since 3.2
579      */
580     @Override
581     public Decimal64 asin() {
582         return new Decimal64(JdkMath.asin(value));
583     }
584 
585     /** {@inheritDoc}
586      * @since 3.2
587      */
588     @Override
589     public Decimal64 atan() {
590         return new Decimal64(JdkMath.atan(value));
591     }
592 
593     /** {@inheritDoc}
594      * @since 3.2
595      */
596     @Override
597     public Decimal64 atan2(final Decimal64 x) {
598         return new Decimal64(JdkMath.atan2(value, x.value));
599     }
600 
601     /** {@inheritDoc}
602      * @since 3.2
603      */
604     @Override
605     public Decimal64 cosh() {
606         return new Decimal64(JdkMath.cosh(value));
607     }
608 
609     /** {@inheritDoc}
610      * @since 3.2
611      */
612     @Override
613     public Decimal64 sinh() {
614         return new Decimal64(JdkMath.sinh(value));
615     }
616 
617     /** {@inheritDoc}
618      * @since 3.2
619      */
620     @Override
621     public Decimal64 tanh() {
622         return new Decimal64(JdkMath.tanh(value));
623     }
624 
625     /** {@inheritDoc}
626      * @since 3.2
627      */
628     @Override
629     public Decimal64 acosh() {
630         return new Decimal64(JdkMath.acosh(value));
631     }
632 
633     /** {@inheritDoc}
634      * @since 3.2
635      */
636     @Override
637     public Decimal64 asinh() {
638         return new Decimal64(JdkMath.asinh(value));
639     }
640 
641     /** {@inheritDoc}
642      * @since 3.2
643      */
644     @Override
645     public Decimal64 atanh() {
646         return new Decimal64(JdkMath.atanh(value));
647     }
648 
649     /** {@inheritDoc}
650      * @since 3.2
651      */
652     @Override
653     public Decimal64 linearCombination(final Decimal64[] a, final Decimal64[] b)
654         throws DimensionMismatchException {
655         if (a.length != b.length) {
656             throw new DimensionMismatchException(a.length, b.length);
657         }
658         final double[] aDouble = new double[a.length];
659         final double[] bDouble = new double[b.length];
660         for (int i = 0; i < a.length; ++i) {
661             aDouble[i] = a[i].value;
662             bDouble[i] = b[i].value;
663         }
664         return new Decimal64(Sum.ofProducts(aDouble, bDouble).getAsDouble());
665     }
666 
667     /** {@inheritDoc}
668      * @since 3.2
669      */
670     @Override
671     public Decimal64 linearCombination(final double[] a, final Decimal64[] b)
672         throws DimensionMismatchException {
673         if (a.length != b.length) {
674             throw new DimensionMismatchException(a.length, b.length);
675         }
676         final double[] bDouble = new double[b.length];
677         for (int i = 0; i < a.length; ++i) {
678             bDouble[i] = b[i].value;
679         }
680         return new Decimal64(Sum.ofProducts(a, bDouble).getAsDouble());
681     }
682 
683     /** {@inheritDoc}
684      * @since 3.2
685      */
686     @Override
687     public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
688                                        final Decimal64 a2, final Decimal64 b2) {
689         return new Decimal64(Sum.create()
690                              .addProduct(a1.value, b1.value)
691                              .addProduct(a2.value, b2.value).getAsDouble());
692     }
693 
694     /** {@inheritDoc}
695      * @since 3.2
696      */
697     @Override
698     public Decimal64 linearCombination(final double a1, final Decimal64 b1,
699                                        final double a2, final Decimal64 b2) {
700         return new Decimal64(Sum.create()
701                              .addProduct(a1, b1.value)
702                              .addProduct(a2, b2.value).getAsDouble());
703     }
704 
705     /** {@inheritDoc}
706      * @since 3.2
707      */
708     @Override
709     public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
710                                        final Decimal64 a2, final Decimal64 b2,
711                                        final Decimal64 a3, final Decimal64 b3) {
712         return new Decimal64(Sum.create()
713                              .addProduct(a1.value, b1.value)
714                              .addProduct(a2.value, b2.value)
715                              .addProduct(a3.value, b3.value).getAsDouble());
716     }
717 
718     /** {@inheritDoc}
719      * @since 3.2
720      */
721     @Override
722     public Decimal64 linearCombination(final double a1, final Decimal64 b1,
723                                        final double a2, final Decimal64 b2,
724                                        final double a3, final Decimal64 b3) {
725         return new Decimal64(Sum.create()
726                              .addProduct(a1, b1.value)
727                              .addProduct(a2, b2.value)
728                              .addProduct(a3, b3.value).getAsDouble());
729     }
730 
731     /** {@inheritDoc}
732      * @since 3.2
733      */
734     @Override
735     public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
736                                        final Decimal64 a2, final Decimal64 b2,
737                                        final Decimal64 a3, final Decimal64 b3,
738                                        final Decimal64 a4, final Decimal64 b4) {
739         return new Decimal64(Sum.create()
740                              .addProduct(a1.value, b1.value)
741                              .addProduct(a2.value, b2.value)
742                              .addProduct(a3.value, b3.value)
743                              .addProduct(a4.value, b4.value).getAsDouble());
744     }
745 
746     /** {@inheritDoc}
747      * @since 3.2
748      */
749     @Override
750     public Decimal64 linearCombination(final double a1, final Decimal64 b1,
751                                        final double a2, final Decimal64 b2,
752                                        final double a3, final Decimal64 b3,
753                                        final double a4, final Decimal64 b4) {
754         return new Decimal64(Sum.create()
755                              .addProduct(a1, b1.value)
756                              .addProduct(a2, b2.value)
757                              .addProduct(a3, b3.value)
758                              .addProduct(a4, b4.value).getAsDouble());
759     }
760 }