001 package com.croftsoft.core.math; 002 003 import java.awt.geom.Point2D; 004 import java.util.*; 005 006 /********************************************************************* 007 * A collection of static methods to supplement java.lang.Math. 008 * 009 * @version 010 * $Id: MathLib.java,v 1.5 2008/08/09 02:10:33 croft Exp $ 011 * @since 012 * 1998-12-27 013 * @author 014 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 015 *********************************************************************/ 016 017 public final class MathLib 018 ////////////////////////////////////////////////////////////////////// 019 ////////////////////////////////////////////////////////////////////// 020 { 021 022 public static void main ( String [ ] args ) 023 ////////////////////////////////////////////////////////////////////// 024 { 025 System.out.println ( test ( ) ); 026 } 027 028 public static boolean test ( ) 029 ////////////////////////////////////////////////////////////////////// 030 { 031 return ( greatestCommonFactor ( 6, 15 ) == 3 ) 032 && ( log ( 1.0, 10.0 ) == 0.0 ) 033 && ( log ( 10.0, 10.0 ) == 1.0 ) 034 && ( log ( 100.0, 10.0 ) == 2.0 ) 035 && ( log ( 0.5, 2.0 ) == -1.0 ) 036 && ( log ( 1.0, 2.0 ) == 0.0 ) 037 && ( log ( 2.0, 2.0 ) == 1.0 ) 038 && ( log ( 4.0, 2.0 ) == 2.0 ) 039 && ( wrap ( -190, -180, 360 ) == 170 ) 040 && ( wrap ( -180, -180, 360 ) == -180 ) 041 && ( wrap ( 180, -180, 360 ) == -180 ) 042 && ( wrap ( 190, -180, 360 ) == -170 ) 043 && ( wrap ( 370, -180, 360 ) == 10 ) 044 && ( wrap ( -10, 0, 360 ) == 350 ) 045 && ( wrap ( 0, 0, 360 ) == 0 ) 046 && ( wrap ( 10, 0, 360 ) == 10 ) 047 && ( wrap ( 360, 0, 360 ) == 0 ) 048 && ( wrap ( 370, 0, 360 ) == 10 ); 049 } 050 051 ////////////////////////////////////////////////////////////////////// 052 ////////////////////////////////////////////////////////////////////// 053 054 public static double clip ( 055 final double value, 056 final double minimum, 057 final double maximum ) 058 ////////////////////////////////////////////////////////////////////// 059 { 060 if ( minimum > maximum ) 061 { 062 throw new IllegalArgumentException ( 063 "minimum > maximum: " + minimum + ", " + maximum ); 064 } 065 066 return 067 value < minimum ? minimum : value > maximum ? maximum : value; 068 } 069 070 /********************************************************************* 071 * Cumulative Distribution Function (CDF). 072 * 073 * @see 074 * http://en.wikipedia.org/wiki/Exponential_distribution 075 * #Cumulative_distribution_function 076 *********************************************************************/ 077 public static double cumulative ( 078 double x, 079 double lambda ) 080 ////////////////////////////////////////////////////////////////////// 081 { 082 if ( x <= 0.0 ) 083 { 084 return 0.0; 085 } 086 087 return 1.0 - Math.exp ( -lambda * x ); 088 } 089 090 /********************************************************************* 091 * return cumulative ( x, 1 ); 092 *********************************************************************/ 093 public static double cumulative ( double x ) 094 ////////////////////////////////////////////////////////////////////// 095 { 096 return cumulative ( x, 1 ); 097 } 098 099 @SuppressWarnings ( "all" ) // TODO: fix argument assignment warning 100 public static List<Integer> factor ( int n ) 101 ////////////////////////////////////////////////////////////////////// 102 { 103 if ( n < 0 ) 104 { 105 throw new IllegalArgumentException ( "n < 0" ); 106 } 107 108 List<Integer> primeList = new ArrayList<Integer> ( ); 109 110 if ( n == 0 ) 111 { 112 primeList.add ( new Integer ( 0 ) ); 113 114 return primeList; 115 } 116 117 if ( n == 1 ) 118 { 119 primeList.add ( new Integer ( 1 ) ); 120 121 return primeList; 122 } 123 124 for ( int i = 2; i <= n; i++ ) 125 { 126 if ( n % i == 0 ) 127 { 128 primeList.add ( new Integer ( i ) ); 129 130 n = n / i; 131 132 i = 1; 133 } 134 } 135 136 return primeList; 137 } 138 139 public static int greatestCommonFactor ( 140 int n0, 141 int n1 ) 142 ////////////////////////////////////////////////////////////////////// 143 { 144 int gcf = 1; 145 146 List<Integer> primeList0 = factor ( n0 ); 147 148 List<Integer> primeList1 = factor ( n1 ); 149 150 Integer [ ] primeArray0 151 = primeList0.toArray ( new Integer [ 0 ] ); 152 153 for ( int i = 0; i < primeArray0.length; i++ ) 154 { 155 Integer j = primeArray0 [ i ]; 156 157 if ( primeList1.contains ( j ) ) 158 { 159 gcf = gcf * j.intValue ( ); 160 161 primeList1.remove ( j ); 162 } 163 } 164 165 return gcf; 166 } 167 168 /********************************************************************* 169 * Calculates the logarithm in the given base. 170 * 171 * <code><pre>return Math.log ( a ) / Math.log ( base );</pre></code> 172 *********************************************************************/ 173 public static double log ( 174 double a, 175 double base ) 176 ////////////////////////////////////////////////////////////////////// 177 { 178 return Math.log ( a ) / Math.log ( base ); 179 } 180 181 /********************************************************************* 182 * Also known as the "logistic function". 183 *********************************************************************/ 184 public static double sigmoid ( double a ) 185 ////////////////////////////////////////////////////////////////////// 186 { 187 return 1.0 / ( 1.0 + Math.exp ( -a ) ); 188 } 189 190 /********************************************************************* 191 * The derivative with respect to the argument. 192 *********************************************************************/ 193 public static double sigmoidDerivative ( double a ) 194 ////////////////////////////////////////////////////////////////////// 195 { 196 double y = sigmoid ( a ); 197 return y * ( 1.0 - y ); 198 } 199 200 /********************************************************************* 201 * Returns +1 if positive, -1 if negative, otherwise 0. 202 *********************************************************************/ 203 public static byte signum ( long l ) 204 ////////////////////////////////////////////////////////////////////// 205 { 206 return ( byte ) ( l > 0 ? 1 : ( l < 0 ? -1 : 0 ) ); 207 } 208 209 /********************************************************************* 210 * hyperbolic tangent = 2 * sigmoid ( 2 * a ) - 1 211 *********************************************************************/ 212 public static double tanh ( double a ) 213 ////////////////////////////////////////////////////////////////////// 214 { 215 return 2.0 * sigmoid ( 2.0 * a ) - 1.0; 216 } 217 218 /********************************************************************* 219 * Converts from polar to rectangular coordinates. 220 *********************************************************************/ 221 public static void toRectangular ( 222 double radius, 223 double angle, 224 Point2D point2D ) 225 ////////////////////////////////////////////////////////////////////// 226 { 227 point2D.setLocation ( 228 radius * Math.cos ( angle ), 229 radius * Math.sin ( angle ) ); 230 } 231 232 /********************************************************************* 233 * Converts from polar to rectangular coordinates. 234 *********************************************************************/ 235 public static Point2D toRectangular ( 236 double radius, 237 double angle ) 238 ////////////////////////////////////////////////////////////////////// 239 { 240 Point2D point2D = new Point2D.Double ( ); 241 242 toRectangular ( radius, angle, point2D ); 243 244 return point2D; 245 } 246 247 /********************************************************************* 248 * Wraps the value to [minimum, minimum + range). 249 * 250 * Example: wrap ( -190, -180, 360 ) ==> 170 251 * Example: wrap ( 190, -180, 360 ) ==> -10 252 * Example: wrap ( 360, -180, 360 ) ==> -180 253 *********************************************************************/ 254 public static double wrap ( 255 final double value, 256 final double minimum, 257 final double range ) 258 ////////////////////////////////////////////////////////////////////// 259 { 260 if ( range <= 0 ) 261 { 262 throw new IllegalArgumentException ( "range <= 0: " + range ); 263 } 264 265 final double maximum = minimum + range; 266 267 if ( ( value >= minimum ) 268 && ( value < maximum ) ) 269 { 270 return value; 271 } 272 273 if ( value < minimum ) 274 { 275 return value + Math.ceil ( ( minimum - value ) / range ) * range; 276 } 277 278 return value 279 - ( 1 + Math.floor ( ( value - maximum ) / range ) ) * range; 280 } 281 282 ////////////////////////////////////////////////////////////////////// 283 ////////////////////////////////////////////////////////////////////// 284 285 private MathLib ( ) 286 ////////////////////////////////////////////////////////////////////// 287 { 288 // empty 289 } 290 291 ////////////////////////////////////////////////////////////////////// 292 ////////////////////////////////////////////////////////////////////// 293 }