• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package org.apache.commons.math3.util;
19 
20 import org.apache.commons.math3.RealFieldElement;
21 import org.apache.commons.math3.exception.MathArithmeticException;
22 import org.apache.commons.math3.exception.NotFiniteNumberException;
23 import org.apache.commons.math3.exception.NullArgumentException;
24 import org.apache.commons.math3.exception.util.Localizable;
25 import org.apache.commons.math3.exception.util.LocalizedFormats;
26 
27 import java.util.Arrays;
28 
29 /**
30  * Miscellaneous utility functions.
31  *
32  * @see ArithmeticUtils
33  * @see Precision
34  * @see MathArrays
35  */
36 public final class MathUtils {
37     /**
38      * \(2\pi\)
39      *
40      * @since 2.1
41      */
42     public static final double TWO_PI = 2 * FastMath.PI;
43 
44     /**
45      * \(\pi^2\)
46      *
47      * @since 3.4
48      */
49     public static final double PI_SQUARED = FastMath.PI * FastMath.PI;
50 
51     /** Class contains only static methods. */
MathUtils()52     private MathUtils() {}
53 
54     /**
55      * Returns an integer hash code representing the given double value.
56      *
57      * @param value the value to be hashed
58      * @return the hash code
59      */
hash(double value)60     public static int hash(double value) {
61         return new Double(value).hashCode();
62     }
63 
64     /**
65      * Returns {@code true} if the values are equal according to semantics of {@link
66      * Double#equals(Object)}.
67      *
68      * @param x Value
69      * @param y Value
70      * @return {@code new Double(x).equals(new Double(y))}
71      */
equals(double x, double y)72     public static boolean equals(double x, double y) {
73         return new Double(x).equals(new Double(y));
74     }
75 
76     /**
77      * Returns an integer hash code representing the given double array.
78      *
79      * @param value the value to be hashed (may be null)
80      * @return the hash code
81      * @since 1.2
82      */
hash(double[] value)83     public static int hash(double[] value) {
84         return Arrays.hashCode(value);
85     }
86 
87     /**
88      * Normalize an angle in a 2π wide interval around a center value.
89      *
90      * <p>This method has three main uses:
91      *
92      * <ul>
93      *   <li>normalize an angle between 0 and 2&pi;:<br>
94      *       {@code a = MathUtils.normalizeAngle(a, FastMath.PI);}
95      *   <li>normalize an angle between -&pi; and +&pi;<br>
96      *       {@code a = MathUtils.normalizeAngle(a, 0.0);}
97      *   <li>compute the angle between two defining angular positions:<br>
98      *       {@code angle = MathUtils.normalizeAngle(end, start) - start;}
99      * </ul>
100      *
101      * <p>Note that due to numerical accuracy and since &pi; cannot be represented exactly, the
102      * result interval is <em>closed</em>, it cannot be half-closed as would be more satisfactory in
103      * a purely mathematical view.
104      *
105      * @param a angle to normalize
106      * @param center center of the desired 2&pi; interval for the result
107      * @return a-2k&pi; with integer k and center-&pi; &lt;= a-2k&pi; &lt;= center+&pi;
108      * @since 1.2
109      */
normalizeAngle(double a, double center)110     public static double normalizeAngle(double a, double center) {
111         return a - TWO_PI * FastMath.floor((a + FastMath.PI - center) / TWO_PI);
112     }
113 
114     /**
115      * Find the maximum of two field elements.
116      *
117      * @param <T> the type of the field elements
118      * @param e1 first element
119      * @param e2 second element
120      * @return max(a1, e2)
121      * @since 3.6
122      */
max(final T e1, final T e2)123     public static <T extends RealFieldElement<T>> T max(final T e1, final T e2) {
124         return e1.subtract(e2).getReal() >= 0 ? e1 : e2;
125     }
126 
127     /**
128      * Find the minimum of two field elements.
129      *
130      * @param <T> the type of the field elements
131      * @param e1 first element
132      * @param e2 second element
133      * @return min(a1, e2)
134      * @since 3.6
135      */
min(final T e1, final T e2)136     public static <T extends RealFieldElement<T>> T min(final T e1, final T e2) {
137         return e1.subtract(e2).getReal() >= 0 ? e2 : e1;
138     }
139 
140     /**
141      * Reduce {@code |a - offset|} to the primary interval {@code [0, |period|)}.
142      *
143      * <p>Specifically, the value returned is <br>
144      * {@code a - |period| * floor((a - offset) / |period|) - offset}.
145      *
146      * <p>If any of the parameters are {@code NaN} or infinite, the result is {@code NaN}.
147      *
148      * @param a Value to reduce.
149      * @param period Period.
150      * @param offset Value that will be mapped to {@code 0}.
151      * @return the value, within the interval {@code [0 |period|)}, that corresponds to {@code a}.
152      */
reduce(double a, double period, double offset)153     public static double reduce(double a, double period, double offset) {
154         final double p = FastMath.abs(period);
155         return a - p * FastMath.floor((a - offset) / p) - offset;
156     }
157 
158     /**
159      * Returns the first argument with the sign of the second argument.
160      *
161      * @param magnitude Magnitude of the returned value.
162      * @param sign Sign of the returned value.
163      * @return a value with magnitude equal to {@code magnitude} and with the same sign as the
164      *     {@code sign} argument.
165      * @throws MathArithmeticException if {@code magnitude == Byte.MIN_VALUE} and {@code sign >= 0}.
166      */
copySign(byte magnitude, byte sign)167     public static byte copySign(byte magnitude, byte sign) throws MathArithmeticException {
168         if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK.
169             return magnitude;
170         } else if (sign >= 0 && magnitude == Byte.MIN_VALUE) {
171             throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
172         } else {
173             return (byte) -magnitude; // Flip sign.
174         }
175     }
176 
177     /**
178      * Returns the first argument with the sign of the second argument.
179      *
180      * @param magnitude Magnitude of the returned value.
181      * @param sign Sign of the returned value.
182      * @return a value with magnitude equal to {@code magnitude} and with the same sign as the
183      *     {@code sign} argument.
184      * @throws MathArithmeticException if {@code magnitude == Short.MIN_VALUE} and {@code sign >=
185      *     0}.
186      */
copySign(short magnitude, short sign)187     public static short copySign(short magnitude, short sign) throws MathArithmeticException {
188         if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK.
189             return magnitude;
190         } else if (sign >= 0 && magnitude == Short.MIN_VALUE) {
191             throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
192         } else {
193             return (short) -magnitude; // Flip sign.
194         }
195     }
196 
197     /**
198      * Returns the first argument with the sign of the second argument.
199      *
200      * @param magnitude Magnitude of the returned value.
201      * @param sign Sign of the returned value.
202      * @return a value with magnitude equal to {@code magnitude} and with the same sign as the
203      *     {@code sign} argument.
204      * @throws MathArithmeticException if {@code magnitude == Integer.MIN_VALUE} and {@code sign >=
205      *     0}.
206      */
copySign(int magnitude, int sign)207     public static int copySign(int magnitude, int sign) throws MathArithmeticException {
208         if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK.
209             return magnitude;
210         } else if (sign >= 0 && magnitude == Integer.MIN_VALUE) {
211             throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
212         } else {
213             return -magnitude; // Flip sign.
214         }
215     }
216 
217     /**
218      * Returns the first argument with the sign of the second argument.
219      *
220      * @param magnitude Magnitude of the returned value.
221      * @param sign Sign of the returned value.
222      * @return a value with magnitude equal to {@code magnitude} and with the same sign as the
223      *     {@code sign} argument.
224      * @throws MathArithmeticException if {@code magnitude == Long.MIN_VALUE} and {@code sign >= 0}.
225      */
copySign(long magnitude, long sign)226     public static long copySign(long magnitude, long sign) throws MathArithmeticException {
227         if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK.
228             return magnitude;
229         } else if (sign >= 0 && magnitude == Long.MIN_VALUE) {
230             throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
231         } else {
232             return -magnitude; // Flip sign.
233         }
234     }
235 
236     /**
237      * Check that the argument is a real number.
238      *
239      * @param x Argument.
240      * @throws NotFiniteNumberException if {@code x} is not a finite real number.
241      */
checkFinite(final double x)242     public static void checkFinite(final double x) throws NotFiniteNumberException {
243         if (Double.isInfinite(x) || Double.isNaN(x)) {
244             throw new NotFiniteNumberException(x);
245         }
246     }
247 
248     /**
249      * Check that all the elements are real numbers.
250      *
251      * @param val Arguments.
252      * @throws NotFiniteNumberException if any values of the array is not a finite real number.
253      */
checkFinite(final double[] val)254     public static void checkFinite(final double[] val) throws NotFiniteNumberException {
255         for (int i = 0; i < val.length; i++) {
256             final double x = val[i];
257             if (Double.isInfinite(x) || Double.isNaN(x)) {
258                 throw new NotFiniteNumberException(LocalizedFormats.ARRAY_ELEMENT, x, i);
259             }
260         }
261     }
262 
263     /**
264      * Checks that an object is not null.
265      *
266      * @param o Object to be checked.
267      * @param pattern Message pattern.
268      * @param args Arguments to replace the placeholders in {@code pattern}.
269      * @throws NullArgumentException if {@code o} is {@code null}.
270      */
checkNotNull(Object o, Localizable pattern, Object... args)271     public static void checkNotNull(Object o, Localizable pattern, Object... args)
272             throws NullArgumentException {
273         if (o == null) {
274             throw new NullArgumentException(pattern, args);
275         }
276     }
277 
278     /**
279      * Checks that an object is not null.
280      *
281      * @param o Object to be checked.
282      * @throws NullArgumentException if {@code o} is {@code null}.
283      */
checkNotNull(Object o)284     public static void checkNotNull(Object o) throws NullArgumentException {
285         if (o == null) {
286             throw new NullArgumentException();
287         }
288     }
289 }
290