iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree.NumberArithmetic.java Source code

Java tutorial

Introduction

Here is the source code for iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree.NumberArithmetic.java

Source

/* Copyright 2009-2015 David Hadka
 *
 * This file is part of the MOEA Framework.
 *
 * The MOEA Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * The MOEA Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the MOEA Framework.  If not, see <http://www.gnu.org/licenses/>.
 */
package iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree;

import org.apache.commons.math3.util.FastMath;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.Settings;

/**
 * Provides many arithmetic and trigonometric functions that operate on
 * {@link Number}s, performing any necessary implicit casting.  An integer
 * number remains an integer unless the specific function requires
 * floating-point values.  These methods favor {@link Long} and {@link Double}
 * representations for integer and floating-point values, respectively.
 * <p>
 * The arithmetic functions provided herein support optional function
 * protection, which is enabled by default.  Function protection prevents
 * values like {@code Inf} and {@code NaN} from appearing due to invalid
 * inputs.  For example, this protects against division-by-zero.  To disable
 * function protection, set the property
 * {@code iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.tree.protected_functions = false} in the file
 * {@code global.properties}.  {@code Inf} and {@code NaN} values can still
 * occur with function protection enabled, so outputs should still be
 * validated.
 */
public class NumberArithmetic {

    /**
     * Private constructor to prevent instantiation.
     */
    private NumberArithmetic() {
        super();
    }

    /**
     * Returns {@code true} if the two numbers are equal; {@code false}
     * otherwise.
     * 
     * @param a the first number
     * @param b the second number
     * @return {@code true} if the two numbers are equal; {@code false}
     *         otherwise
     */
    public static boolean equals(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() == b.doubleValue();
        } else {
            return a.longValue() == b.longValue();
        }
    }

    /**
     * Returns {@code true} if the first number is less than the second;
     * {@code false} otherwise.
     * 
     * @param a the first number
     * @param b the second number
     * @return {@code true} if the first number is less than the second;
     *         {@code false} otherwise
     */
    public static boolean lessThan(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() < b.doubleValue();
        } else {
            return a.longValue() < b.longValue();
        }
    }

    /**
     * Returns {@code true} if the first number is less than or equal to the
     * second; {@code false} otherwise.
     * 
     * @param a the first number
     * @param b the second number
     * @return {@code true} if the first number is less than or equal to the
     *         second; {@code false} otherwise
     */
    public static boolean lessThanOrEqual(Number a, Number b) {
        return lessThan(a, b) || equals(a, b);
    }

    /**
     * Returns {@code true} if the first number is greater than the second;
     * {@code false} otherwise.
     * 
     * @param a the first number
     * @param b the second number
     * @return {@code true} if the first number is greater than the second;
     *         {@code false} otherwise
     */
    public static boolean greaterThan(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() > b.doubleValue();
        } else {
            return a.longValue() > b.longValue();
        }
    }

    /**
     * Returns {@code true} if the first number is greater than or equal to the
     * second; {@code false} otherwise.
     * 
     * @param a the first number
     * @param b the second number
     * @return {@code true} if the first number is greater than or equal to the
     *         second; {@code false} otherwise
     */
    public static boolean greaterThanOrEqual(Number a, Number b) {
        return greaterThan(a, b) || equals(a, b);
    }

    /**
     * Returns the value of adding the two numbers
     * 
     * @param a the first number
     * @param b the second number
     * @return the value of adding the two numbers
     */
    public static Number add(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() + b.doubleValue();
        } else {
            return a.longValue() + b.longValue();
        }
    }

    /**
     * Returns the square root of the number.  If the number is less than zero
     * and function protection is enabled, this functions the square root of
     * the absolute value of the number.
     * 
     * @param a the number
     * @return the square root of the number
     * @see Math#sqrt(double)
     */
    public static Number sqrt(Number a) {
        if ((a.doubleValue() < 0.0) && Settings.isProtectedFunctions()) {
            return Math.sqrt(Math.abs(a.doubleValue()));
        } else {
            return Math.sqrt(a.doubleValue());
        }
    }

    /**
     * Returns the value of the first number to the power of the second.
     * 
     * @param a the first number
     * @param b the second number
     * @return the value of the first number to the power of the second
     * @see Math#pow(double, double)
     */
    public static Number pow(Number a, Number b) {
        return Math.pow(a.doubleValue(), b.doubleValue());
    }

    /**
     * Returns the value of subtracting the first from the second number.
     * 
     * @param a the first number
     * @param b the second number
     * @return the value of subtracting the first from the second number
     */
    public static Number sub(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() - b.doubleValue();
        } else {
            return a.longValue() - b.longValue();
        }
    }

    /**
     * Returns the value of multiplying the two numbers.
     * 
     * @param a the first number
     * @param b the second number
     * @return the value of multiplying the two numbers
     */
    public static Number mul(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return a.doubleValue() * b.doubleValue();
        } else {
            return a.longValue() * b.longValue();
        }
    }

    /**
     * Returns the value of dividing the first number by the second.  If the
     * second argument is {@code 0} and function protection is enabled, this
     * function returns {@code 1} regardless of the first argument's value.
     * 
     * @param a the first number
     * @param b the second number
     * @return the value of dividing the first number by the second
     */
    public static Number div(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            if ((Math.abs(b.doubleValue()) < Settings.EPS) && Settings.isProtectedFunctions()) {
                return 1.0;
            } else {
                return a.doubleValue() / b.doubleValue();
            }
        } else {
            if ((b.longValue() == 0) && Settings.isProtectedFunctions()) {
                return 1L;
            } else {
                return a.longValue() / b.longValue();
            }
        }
    }

    /**
     * Returns the remainder from dividing the first number by the second.  If
     * the second argument is {@code 0} and function protection is enabled, 
     * this function returns {@code 0} regardless of the first argument's
     * value.
     * 
     * @param a the first number
     * @param b the second number
     * @return the remainder from dividing the first number by the second
     */
    public static Number mod(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            if ((Math.abs(b.doubleValue()) < Settings.EPS) && Settings.isProtectedFunctions()) {
                return 0.0;
            } else {
                return a.doubleValue() % b.doubleValue();
            }
        } else {
            if ((b.longValue() == 0) && Settings.isProtectedFunctions()) {
                return 0L;
            } else {
                return a.longValue() % b.longValue();
            }
        }
    }

    /**
     * Returns the largest integer value less than or equal to the given
     * number.
     * 
     * @param a the number
     * @return the largest integer value less than or equal to the given
     *         number
     * @see Math#floor(double)
     */
    public static Number floor(Number a) {
        if (isFloatingPoint(a)) {
            return Math.floor(a.doubleValue());
        } else {
            return a.longValue();
        }
    }

    /**
     * Returns the smallest integer value greater than or equal to the given
     * number.
     * 
     * @param a the number
     * @return the smallest integer value greater than or equal to the given
     *         number
     * @see Math#ceil(double)
     */
    public static Number ceil(Number a) {
        if (isFloatingPoint(a)) {
            return Math.ceil(a.doubleValue());
        } else {
            return a.longValue();
        }
    }

    /**
     * Returns the value of the number rounded to the nearest integer.
     * 
     * @param a the number
     * @return the value of the number rounded to the nearest integer
     * @see Math#round(double)
     */
    public static Number round(Number a) {
        if (isFloatingPoint(a)) {
            return Math.round(a.doubleValue());
        } else {
            return a.longValue();
        }
    }

    /**
     * Returns the absolute value of the number.
     * 
     * @param a the number
     * @return the absolute value of the number
     * @see Math#abs(long)
     * @see Math#abs(double)
     */
    public static Number abs(Number a) {
        if (isFloatingPoint(a)) {
            return Math.abs(a.doubleValue());
        } else {
            return Math.abs(a.longValue());
        }
    }

    /**
     * Returns the natural logarithm of the number.  If the numbers is
     * negative and function protection is enabled, then this function returns
     * the natural logarithm of the absolute value of the number.  If the
     * number is near zero and function protection is enabled, this function
     * returns {@code 0.0}.
     * 
     * @param a the number
     * @return the natural logarithm of the number
     * @see Math#log(double)
     */
    public static Number log(Number a) {
        if ((a.doubleValue() < Settings.EPS) && Settings.isProtectedFunctions()) {
            double value = Math.abs(a.doubleValue());

            if (value < Settings.EPS) {
                return 0.0;
            } else {
                return Math.log(value);
            }
        } else {
            return Math.log(a.doubleValue());
        }
    }

    /**
     * Returns the base-10 logarithm of the number.  If the numbers is
     * negative and function protection is enabled, then this function returns
     * the base-10 logarithm of the absolute value of the number.  If the
     * number is near zero and function protection is enabled, this function
     * returns {@code 0.0}.
     * 
     * @param a the number
     * @return the base-10 logarithm of the number
     * @see Math#log10(double)
     */
    public static Number log10(Number a) {
        if ((a.doubleValue() < Settings.EPS) && Settings.isProtectedFunctions()) {
            double value = Math.abs(a.doubleValue());

            if (value < Settings.EPS) {
                return 0.0;
            } else {
                return Math.log10(value);
            }
        } else {
            return Math.log10(a.doubleValue());
        }
    }

    /**
     * Returns the value from taking Euler's number <i>e</i> to the power of
     * the given number.
     * 
     * @param a the number
     * @return  the value from taking Euler's number <i>e</i> to the power of
     *          the given number
     * @see Math#exp(double)
     */
    public static Number exp(Number a) {
        return Math.exp(a.doubleValue());
    }

    /**
     * Returns the trigonometric sine of the number.
     * 
     * @param a the number
     * @return the trigonometric sine of the number
     * @see Math#sin(double)
     */
    public static Number sin(Number a) {
        return Math.sin(a.doubleValue());
    }

    /**
     * Returns the trigonometric cosine of the number.
     * 
     * @param a the number
     * @return the trigonometric cosine of the number
     * @see Math#cos(double)
     */
    public static Number cos(Number a) {
        return Math.cos(a.doubleValue());
    }

    /**
     * Returns the trigonometric tangent of the number.
     * 
     * @param a the number
     * @return the trigonometric tangent of the number
     * @see Math#tan(double)
     */
    public static Number tan(Number a) {
        return Math.tan(a.doubleValue());
    }

    /**
     * Returns the arc sine of the number.
     * 
     * @param a the number
     * @return the arc sine of the number
     * @see Math#asin(double)
     */
    public static Number asin(Number a) {
        return Math.asin(a.doubleValue());
    }

    /**
     * Returns the arc cosine of the number.
     * 
     * @param a the number
     * @return the arc cosine of the number
     * @see Math#acos(double)
     */
    public static Number acos(Number a) {
        return Math.acos(a.doubleValue());
    }

    /**
     * Returns the arc tangent of the number.
     * 
     * @param a the number
     * @return the arc tangent of the number
     * @see Math#atan(double)
     */
    public static Number atan(Number a) {
        return Math.atan(a.doubleValue());
    }

    /**
     * Returns the hyperbolic sine of the number.
     * 
     * @param a the number
     * @return the hyperbolic sine of the number
     * @see Math#sinh(double)
     */
    public static Number sinh(Number a) {
        return Math.sinh(a.doubleValue());
    }

    /**
     * Returns the hyperbolic cosine of the number.
     * 
     * @param a the number
     * @return the hyperbolic cosine of the number
     * @see Math#cosh(double)
     */
    public static Number cosh(Number a) {
        return Math.cosh(a.doubleValue());
    }

    /**
     * Returns the hyperbolic tangent of the number.
     * 
     * @param a the number
     * @return the hyperbolic tangent of the number
     * @see Math#tanh(double)
     */
    public static Number tanh(Number a) {
        return Math.tanh(a.doubleValue());
    }

    /**
     * Returns the hyperbolic arc sine of the number.
     * 
     * @param a the number
     * @return the hyperbolic arc sine of the number
     * @see FastMath#asinh(double)
     */
    public static Number asinh(Number a) {
        return FastMath.asinh(a.doubleValue());
    }

    /**
     * Returns the hyperbolic arc cosine of the number.
     * 
     * @param a the number
     * @return the hyperbolic arc cosine of the number
     * @see FastMath#acosh(double)
     */
    public static Number acosh(Number a) {
        return FastMath.acosh(a.doubleValue());
    }

    /**
     * Returns the hyperbolic arc tangent of the number.
     * 
     * @param a the number
     * @return the hyperbolic arc tangent of the number
     * @see FastMath#atanh(double)
     */
    public static Number atanh(Number a) {
        return FastMath.atanh(a.doubleValue());
    }

    /**
     * Returns the maximum value of two numbers.
     * 
     * @param a the first number
     * @param b the second number
     * @return the maximum value of two numbers
     * @see Math#min(long, long)
     * @see Math#min(double, double)
     */
    public static Number max(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return Math.max(a.doubleValue(), b.doubleValue());
        } else {
            return Math.max(a.longValue(), b.longValue());
        }
    }

    /**
     * Returns the minimum value of two numbers.
     * 
     * @param a the first number
     * @param b the second number
     * @return the minimum value of two numbers
     * @see Math#max(long, long)
     * @see Math#max(double, double)
     */
    public static Number min(Number a, Number b) {
        if (isFloatingPoint(a) || isFloatingPoint(b)) {
            return Math.min(a.doubleValue(), b.doubleValue());
        } else {
            return Math.min(a.longValue(), b.longValue());
        }
    }

    /**
     * Returns the sign of the number.
     * 
     * @param a the number
     * @return the sign of the number
     * @see Long#signum(long)
     * @see Math#signum(double)
     */
    public static Number sign(Number a) {
        if (isFloatingPoint(a)) {
            return Math.signum(a.doubleValue());
        } else {
            return Long.signum(a.longValue());
        }
    }

    /**
     * Returns {@code true} if the number is a floating-point value;
     * {@code false} otherwise.
     * 
     * @param a the number
     * @return {@code true} if the number is a floating-point value;
     *         {@code false} otherwise
     */
    public static boolean isFloatingPoint(Number a) {
        return (a instanceof Float) || (a instanceof Double);
    }

}