001/* A library of additional mathematical operations beyond those provided 002 by the Java Math class. 003 004 Copyright (c) 1998-2013 The Regents of the University of California. 005 All rights reserved. 006 007 Permission is hereby granted, without written agreement and without 008 license or royalty fees, to use, copy, modify, and distribute this 009 software and its documentation for any purpose, provided that the above 010 copyright notice and the following two paragraphs appear in all copies 011 of this software. 012 013 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 014 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 015 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 016 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 017 SUCH DAMAGE. 018 019 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 020 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 022 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 023 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 024 ENHANCEMENTS, OR MODIFICATIONS. 025 026 PT_COPYRIGHT_VERSION_2 027 COPYRIGHTENDKEY 028 029 */ 030package ptolemy.math; 031 032/////////////////////////////////////////////////////////////////// 033//// ExtendedMath 034 035/** 036 ExtendedMath is a library of additional mathematical operations 037 beyond those provided by the Java Math class. 038 039 @author Albert Chen, William Wu, Edward A. Lee, Jeff Tsay 040 @version $Id$ 041 @since Ptolemy II 0.2 042 @Pt.ProposedRating Yellow (ctsay) 043 @Pt.AcceptedRating Red (cxh) 044 */ 045public class ExtendedMath { 046 /////////////////////////////////////////////////////////////////// 047 //// public methods //// 048 049 /** Return the inverse hyperbolic cosine of the argument. 050 * The argument is required to be greater than one, or an 051 * IllegalArgumentException is thrown (this is a runtime 052 * exception, so it need not be declared). 053 * The returned value is positive. 054 */ 055 public static final double acosh(final double x) { 056 // FIXME: Is the range of the argument correct? 057 if (x < 1) { 058 throw new IllegalArgumentException("ExtendedMath.acosh: Argument " 059 + "is required to be greater than 1. Got " + x); 060 } 061 062 return Math.log(x + Math.sqrt(x * x - 1)); 063 } 064 065 /** Return the inverse hyperbolic sine of the argument. 066 */ 067 public static final double asinh(final double x) { 068 double result; 069 070 if (x < 0) { 071 result = -Math.log(-x + Math.sqrt(x * x + 1)); 072 } else { 073 result = Math.log(x + Math.sqrt(x * x + 1)); 074 } 075 076 return result; 077 } 078 079 /** Return the hyperbolic cosine of the argument. 080 */ 081 public static final double cosh(final double x) { 082 return (Math.exp(x) + Math.exp(-x)) / 2; 083 } 084 085 /** Implement Euclid's method for finding the Greatest Common Divisor 086 * (GCD) of 087 * two numbers. If the numbers are negative, then we compute the 088 * GCD of their absolute values. 089 */ 090 public static int gcd(int u, int v) { 091 int t; 092 093 if (u < 0) { 094 u = -u; 095 } 096 097 if (v < 0) { 098 v = -v; 099 } 100 101 while (u > 0) { 102 if (u < v) { 103 t = u; 104 u = v; 105 v = t; 106 } else { 107 u = u % v; 108 } 109 } 110 111 return v; 112 } 113 114 /** Return the base-10 logarithm of the argument. */ 115 public static final double log10(final double x) { 116 return Math.log(x) * _ONEOVERLN10; 117 } 118 119 /** Return the base-2 logarithm of the argument. */ 120 public static final double log2(final double x) { 121 return Math.log(x) * _ONEOVERLN2; 122 } 123 124 /** Compute the remainder after dividing the first argument by the 125 * second argument as prescribed by the IEEE 754 standard. This 126 * is implemented by the java.lang.Math class method IEEERemainder. 127 * The documentation for that class says: 128 * 129 * <p> "The remainder value is mathematically equal to f1 - f2 130 * × <i>n</i>, where <i>n</i> is the mathematical integer 131 * closest to the exact mathematical value of the quotient f1/f2, 132 * and if two mathematical integers are equally close to f1/f2, 133 * then <i>n</i> is the integer that is even. If the remainder is 134 * zero, its sign is the same as the sign of the first 135 * argument. Special cases: 136 * 137 * <ul> 138 * <li> If either argument is NaN, or the first argument is 139 * infinite, or the second argument is positive zero or negative 140 * zero, then the result is NaN. 141 * <li> If the first argument is finite 142 * and the second argument is infinite, then the result is the 143 * same as the first argument. 144 * </ul> 145 */ 146 public static double remainder(double f1, double f2) { 147 return Math.IEEEremainder(f1, f2); 148 } 149 150 /** Round to the nearest integer. If the argument is NaN, then 151 * the return value is 0. If the argument is out of range, then 152 * the return value is Integer.MAX_VALUE or Integer.MIN_VALUE, 153 * depending on the sign of the argument. 154 * @param x The number to round. 155 * @return The nearest integer. 156 */ 157 public static final int roundToInt(final double x) { 158 long returnValue = Math.round(x); 159 160 if (returnValue >= Integer.MAX_VALUE) { 161 return Integer.MAX_VALUE; 162 } 163 164 if (returnValue <= Integer.MIN_VALUE) { 165 return Integer.MIN_VALUE; 166 } 167 168 return (int) returnValue; 169 } 170 171 /** If the argument is less than zero, return -1, otherwise 172 * return 1. 173 */ 174 public static final int sgn(final double x) { 175 if (x < 0) { 176 return -1; 177 } else { 178 return 1; 179 } 180 } 181 182 /** Return the hyperbolic sine of the argument. 183 */ 184 public static final double sinh(final double x) { 185 return (Math.exp(x) - Math.exp(-x)) / 2; 186 } 187 188 /** Return the hyperbolic tangent of the argument. 189 */ 190 public static final double tanh(final double x) { 191 return sinh(x) / cosh(x); 192 } 193 194 /////////////////////////////////////////////////////////////////// 195 //// public variables //// 196 197 /** sqrt(2). */ 198 public static final double SQRT_2 = Math.sqrt(2.0); 199 200 /** 1 / sqrt(2). */ 201 public static final double ONE_OVER_SQRT_2 = 1.0 / SQRT_2; 202 203 /** PI / 2. */ 204 public static final double PI_OVER_2 = Math.PI * 0.5; 205 206 /** PI / 4. */ 207 public static final double PI_OVER_4 = Math.PI * 0.25; 208 209 /** The smallest, normalized, positive double value with a single precision. 210 */ 211 public static final double SINGLE_PRECISION_SMALLEST_NORMALIZED_POSITIVE_DOUBLE = Math 212 .pow(2.0, -126); 213 214 /** The smallest, normalized, positive double value with a double precision. 215 */ 216 public static final double DOUBLE_PRECISION_SMALLEST_NORMALIZED_POSITIVE_DOUBLE = Math 217 .pow(2.0, -1022); 218 219 /** The constant value of a double representation that has all bits as 220 * 1 except the sign bit, where only the significand contributes to the 221 * value. This value is equal to 1 + 1/2 + 1/2^2 + 1/2^3 + ... + 1/2^m, 222 * where m is the number of bits for the significand. M is 52 for 223 * a double precision floating point number. 224 */ 225 public static final double DOUBLE_PRECISION_SIGNIFICAND_ONLY = 2.0 226 - Math.pow(2.0, -52); 227 228 /** The constant value of a double representation that has all bits as 229 * 1 except the sign bit, where only the significand contributes to the 230 * value. This value is equal to 1 + 1/2 + 1/2^2 + 1/2^3 + ... + 1/2^m, 231 * where m is the number of bits for the significand. M is 23 for 232 * a single precision floating point number. 233 */ 234 public static final double SINGLE_PRECISION_SIGNIFICAND_ONLY = 2.0 235 - Math.pow(2.0, -23); 236 237 /////////////////////////////////////////////////////////////////// 238 //// private variables //// 239 private static final double _ONEOVERLN2 = 1.0 / Math.log(2.0); 240 241 private static final double _ONEOVERLN10 = 1.0 / Math.log(10.0); 242}