summaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/math3/util/MathUtils.java
diff options
context:
space:
mode:
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.java289
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&pi;:<br>
+ * {@code a = MathUtils.normalizeAngle(a, FastMath.PI);}
+ * <li>normalize an angle between -&pi; and +&pi;<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 &pi; 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&pi; interval for the result
+ * @return a-2k&pi; with integer k and center-&pi; &lt;= a-2k&pi; &lt;= center+&pi;
+ * @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();
+ }
+ }
+}