/* A library of additional mathematical operations beyond those provided by the Java Math class. Copyright (c) 1998-2013 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY */ package ptolemy.math; /////////////////////////////////////////////////////////////////// //// ExtendedMath /** ExtendedMath is a library of additional mathematical operations beyond those provided by the Java Math class. @author Albert Chen, William Wu, Edward A. Lee, Jeff Tsay @version $Id: ExtendedMath.java 65768 2013-03-07 03:33:00Z cxh $ @since Ptolemy II 0.2 @Pt.ProposedRating Yellow (ctsay) @Pt.AcceptedRating Red (cxh) */ public class ExtendedMath { /////////////////////////////////////////////////////////////////// //// public methods //// /** Return the inverse hyperbolic cosine of the argument. * The argument is required to be greater than one, or an * IllegalArgumentException is thrown (this is a runtime * exception, so it need not be declared). * The returned value is positive. */ public static final double acosh(final double x) { // FIXME: Is the range of the argument correct? if (x < 1) { throw new IllegalArgumentException("ExtendedMath.acosh: Argument " + "is required to be greater than 1. Got " + x); } return Math.log(x + Math.sqrt(x * x - 1)); } /** Return the inverse hyperbolic sine of the argument. */ public static final double asinh(final double x) { double result; if (x < 0) { result = -Math.log(-x + Math.sqrt(x * x + 1)); } else { result = Math.log(x + Math.sqrt(x * x + 1)); } return result; } /** Return the hyperbolic cosine of the argument. */ public static final double cosh(final double x) { return (Math.exp(x) + Math.exp(-x)) / 2; } /** Implement Euclid's method for finding the Greatest Common Divisor * (GCD) of * two numbers. If the numbers are negative, then we compute the * GCD of their absolute values. */ public static int gcd(int u, int v) { int t; if (u < 0) { u = -u; } if (v < 0) { v = -v; } while (u > 0) { if (u < v) { t = u; u = v; v = t; } else { u = u % v; } } return v; } /** Return the base-10 logarithm of the argument. */ public static final double log10(final double x) { return Math.log(x) * _ONEOVERLN10; } /** Return the base-2 logarithm of the argument. */ public static final double log2(final double x) { return Math.log(x) * _ONEOVERLN2; } /** Compute the remainder after dividing the first argument by the * second argument as prescribed by the IEEE 754 standard. This * is implemented by the java.lang.Math class method IEEERemainder. * The documentation for that class says: * *

"The remainder value is mathematically equal to f1 - f2 * × n, where n is the mathematical integer * closest to the exact mathematical value of the quotient f1/f2, * and if two mathematical integers are equally close to f1/f2, * then n is the integer that is even. If the remainder is * zero, its sign is the same as the sign of the first * argument. Special cases: * *

*/ public static double remainder(double f1, double f2) { return Math.IEEEremainder(f1, f2); } /** Round to the nearest integer. If the argument is NaN, then * the return value is 0. If the argument is out of range, then * the return value is Integer.MAX_VALUE or Integer.MIN_VALUE, * depending on the sign of the argument. * @param x The number to round. * @return The nearest integer. */ public static final int roundToInt(final double x) { long returnValue = Math.round(x); if (returnValue >= Integer.MAX_VALUE) { return Integer.MAX_VALUE; } if (returnValue <= Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) returnValue; } /** If the argument is less than zero, return -1, otherwise * return 1. */ public static final int sgn(final double x) { if (x < 0) { return -1; } else { return 1; } } /** Return the hyperbolic sine of the argument. */ public static final double sinh(final double x) { return (Math.exp(x) - Math.exp(-x)) / 2; } /** Return the hyperbolic tangent of the argument. */ public static final double tanh(final double x) { return sinh(x) / cosh(x); } /////////////////////////////////////////////////////////////////// //// public variables //// /** sqrt(2). */ public static final double SQRT_2 = Math.sqrt(2.0); /** 1 / sqrt(2). */ public static final double ONE_OVER_SQRT_2 = 1.0 / SQRT_2; /** PI / 2. */ public static final double PI_OVER_2 = Math.PI * 0.5; /** PI / 4. */ public static final double PI_OVER_4 = Math.PI * 0.25; /** The smallest, normalized, positive double value with a single precision. */ public static final double SINGLE_PRECISION_SMALLEST_NORMALIZED_POSITIVE_DOUBLE = Math .pow(2.0, -126); /** The smallest, normalized, positive double value with a double precision. */ public static final double DOUBLE_PRECISION_SMALLEST_NORMALIZED_POSITIVE_DOUBLE = Math .pow(2.0, -1022); /** The constant value of a double representation that has all bits as * 1 except the sign bit, where only the significand contributes to the * value. This value is equal to 1 + 1/2 + 1/2^2 + 1/2^3 + ... + 1/2^m, * where m is the number of bits for the significand. M is 52 for * a double precision floating point number. */ public static final double DOUBLE_PRECISION_SIGNIFICAND_ONLY = 2.0 - Math .pow(2.0, -52); /** The constant value of a double representation that has all bits as * 1 except the sign bit, where only the significand contributes to the * value. This value is equal to 1 + 1/2 + 1/2^2 + 1/2^3 + ... + 1/2^m, * where m is the number of bits for the significand. M is 23 for * a single precision floating point number. */ public static final double SINGLE_PRECISION_SIGNIFICAND_ONLY = 2.0 - Math .pow(2.0, -23); /////////////////////////////////////////////////////////////////// //// private variables //// private static final double _ONEOVERLN2 = 1.0 / Math.log(2.0); private static final double _ONEOVERLN10 = 1.0 / Math.log(10.0); }