diff options
Diffstat (limited to 'src/main/java/org/apache/commons/math3/util/MathUtils.java')
-rw-r--r-- | src/main/java/org/apache/commons/math3/util/MathUtils.java | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math3/util/MathUtils.java b/src/main/java/org/apache/commons/math3/util/MathUtils.java new file mode 100644 index 0000000..2f376d7 --- /dev/null +++ b/src/main/java/org/apache/commons/math3/util/MathUtils.java @@ -0,0 +1,289 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math3.util; + +import org.apache.commons.math3.RealFieldElement; +import org.apache.commons.math3.exception.MathArithmeticException; +import org.apache.commons.math3.exception.NotFiniteNumberException; +import org.apache.commons.math3.exception.NullArgumentException; +import org.apache.commons.math3.exception.util.Localizable; +import org.apache.commons.math3.exception.util.LocalizedFormats; + +import java.util.Arrays; + +/** + * Miscellaneous utility functions. + * + * @see ArithmeticUtils + * @see Precision + * @see MathArrays + */ +public final class MathUtils { + /** + * \(2\pi\) + * + * @since 2.1 + */ + public static final double TWO_PI = 2 * FastMath.PI; + + /** + * \(\pi^2\) + * + * @since 3.4 + */ + public static final double PI_SQUARED = FastMath.PI * FastMath.PI; + + /** Class contains only static methods. */ + private MathUtils() {} + + /** + * Returns an integer hash code representing the given double value. + * + * @param value the value to be hashed + * @return the hash code + */ + public static int hash(double value) { + return new Double(value).hashCode(); + } + + /** + * Returns {@code true} if the values are equal according to semantics of {@link + * Double#equals(Object)}. + * + * @param x Value + * @param y Value + * @return {@code new Double(x).equals(new Double(y))} + */ + public static boolean equals(double x, double y) { + return new Double(x).equals(new Double(y)); + } + + /** + * Returns an integer hash code representing the given double array. + * + * @param value the value to be hashed (may be null) + * @return the hash code + * @since 1.2 + */ + public static int hash(double[] value) { + return Arrays.hashCode(value); + } + + /** + * Normalize an angle in a 2π wide interval around a center value. + * + * <p>This method has three main uses: + * + * <ul> + * <li>normalize an angle between 0 and 2π:<br> + * {@code a = MathUtils.normalizeAngle(a, FastMath.PI);} + * <li>normalize an angle between -π and +π<br> + * {@code a = MathUtils.normalizeAngle(a, 0.0);} + * <li>compute the angle between two defining angular positions:<br> + * {@code angle = MathUtils.normalizeAngle(end, start) - start;} + * </ul> + * + * <p>Note that due to numerical accuracy and since π cannot be represented exactly, the + * result interval is <em>closed</em>, it cannot be half-closed as would be more satisfactory in + * a purely mathematical view. + * + * @param a angle to normalize + * @param center center of the desired 2π interval for the result + * @return a-2kπ with integer k and center-π <= a-2kπ <= center+π + * @since 1.2 + */ + public static double normalizeAngle(double a, double center) { + return a - TWO_PI * FastMath.floor((a + FastMath.PI - center) / TWO_PI); + } + + /** + * Find the maximum of two field elements. + * + * @param <T> the type of the field elements + * @param e1 first element + * @param e2 second element + * @return max(a1, e2) + * @since 3.6 + */ + public static <T extends RealFieldElement<T>> T max(final T e1, final T e2) { + return e1.subtract(e2).getReal() >= 0 ? e1 : e2; + } + + /** + * Find the minimum of two field elements. + * + * @param <T> the type of the field elements + * @param e1 first element + * @param e2 second element + * @return min(a1, e2) + * @since 3.6 + */ + public static <T extends RealFieldElement<T>> T min(final T e1, final T e2) { + return e1.subtract(e2).getReal() >= 0 ? e2 : e1; + } + + /** + * Reduce {@code |a - offset|} to the primary interval {@code [0, |period|)}. + * + * <p>Specifically, the value returned is <br> + * {@code a - |period| * floor((a - offset) / |period|) - offset}. + * + * <p>If any of the parameters are {@code NaN} or infinite, the result is {@code NaN}. + * + * @param a Value to reduce. + * @param period Period. + * @param offset Value that will be mapped to {@code 0}. + * @return the value, within the interval {@code [0 |period|)}, that corresponds to {@code a}. + */ + public static double reduce(double a, double period, double offset) { + final double p = FastMath.abs(period); + return a - p * FastMath.floor((a - offset) / p) - offset; + } + + /** + * Returns the first argument with the sign of the second argument. + * + * @param magnitude Magnitude of the returned value. + * @param sign Sign of the returned value. + * @return a value with magnitude equal to {@code magnitude} and with the same sign as the + * {@code sign} argument. + * @throws MathArithmeticException if {@code magnitude == Byte.MIN_VALUE} and {@code sign >= 0}. + */ + public static byte copySign(byte magnitude, byte sign) throws MathArithmeticException { + if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK. + return magnitude; + } else if (sign >= 0 && magnitude == Byte.MIN_VALUE) { + throw new MathArithmeticException(LocalizedFormats.OVERFLOW); + } else { + return (byte) -magnitude; // Flip sign. + } + } + + /** + * Returns the first argument with the sign of the second argument. + * + * @param magnitude Magnitude of the returned value. + * @param sign Sign of the returned value. + * @return a value with magnitude equal to {@code magnitude} and with the same sign as the + * {@code sign} argument. + * @throws MathArithmeticException if {@code magnitude == Short.MIN_VALUE} and {@code sign >= + * 0}. + */ + public static short copySign(short magnitude, short sign) throws MathArithmeticException { + if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK. + return magnitude; + } else if (sign >= 0 && magnitude == Short.MIN_VALUE) { + throw new MathArithmeticException(LocalizedFormats.OVERFLOW); + } else { + return (short) -magnitude; // Flip sign. + } + } + + /** + * Returns the first argument with the sign of the second argument. + * + * @param magnitude Magnitude of the returned value. + * @param sign Sign of the returned value. + * @return a value with magnitude equal to {@code magnitude} and with the same sign as the + * {@code sign} argument. + * @throws MathArithmeticException if {@code magnitude == Integer.MIN_VALUE} and {@code sign >= + * 0}. + */ + public static int copySign(int magnitude, int sign) throws MathArithmeticException { + if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK. + return magnitude; + } else if (sign >= 0 && magnitude == Integer.MIN_VALUE) { + throw new MathArithmeticException(LocalizedFormats.OVERFLOW); + } else { + return -magnitude; // Flip sign. + } + } + + /** + * Returns the first argument with the sign of the second argument. + * + * @param magnitude Magnitude of the returned value. + * @param sign Sign of the returned value. + * @return a value with magnitude equal to {@code magnitude} and with the same sign as the + * {@code sign} argument. + * @throws MathArithmeticException if {@code magnitude == Long.MIN_VALUE} and {@code sign >= 0}. + */ + public static long copySign(long magnitude, long sign) throws MathArithmeticException { + if ((magnitude >= 0 && sign >= 0) || (magnitude < 0 && sign < 0)) { // Sign is OK. + return magnitude; + } else if (sign >= 0 && magnitude == Long.MIN_VALUE) { + throw new MathArithmeticException(LocalizedFormats.OVERFLOW); + } else { + return -magnitude; // Flip sign. + } + } + + /** + * Check that the argument is a real number. + * + * @param x Argument. + * @throws NotFiniteNumberException if {@code x} is not a finite real number. + */ + public static void checkFinite(final double x) throws NotFiniteNumberException { + if (Double.isInfinite(x) || Double.isNaN(x)) { + throw new NotFiniteNumberException(x); + } + } + + /** + * Check that all the elements are real numbers. + * + * @param val Arguments. + * @throws NotFiniteNumberException if any values of the array is not a finite real number. + */ + public static void checkFinite(final double[] val) throws NotFiniteNumberException { + for (int i = 0; i < val.length; i++) { + final double x = val[i]; + if (Double.isInfinite(x) || Double.isNaN(x)) { + throw new NotFiniteNumberException(LocalizedFormats.ARRAY_ELEMENT, x, i); + } + } + } + + /** + * Checks that an object is not null. + * + * @param o Object to be checked. + * @param pattern Message pattern. + * @param args Arguments to replace the placeholders in {@code pattern}. + * @throws NullArgumentException if {@code o} is {@code null}. + */ + public static void checkNotNull(Object o, Localizable pattern, Object... args) + throws NullArgumentException { + if (o == null) { + throw new NullArgumentException(pattern, args); + } + } + + /** + * Checks that an object is not null. + * + * @param o Object to be checked. + * @throws NullArgumentException if {@code o} is {@code null}. + */ + public static void checkNotNull(Object o) throws NullArgumentException { + if (o == null) { + throw new NullArgumentException(); + } + } +} |