KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > maths > ExtraMath


1 package JSci.maths;
2
3 /**
4  * The extra math library.
5  * Provides extra functions not in java.lang.Math class.
6  * This class cannot be subclassed or instantiated because all methods are static.
7  * @version 1.2
8  * @author Mark Hale
9  */

10 public final class ExtraMath extends AbstractMath {
11     private ExtraMath() {}
12     
13     /**
14      * Rounds a number to so many significant figures.
15      * @param x a number to be rounded.
16      * @param significant number of significant figures to round to.
17      */

18     public static double round(final double x, final int significant) {
19         if(x == 0.0)
20             return x;
21         else if(significant == 0)
22             return 0.0;
23         final double signedExp = log10(Math.abs(x)) - significant;
24         if(signedExp < 0.0) {
25             // keep the exponent positive so factor is representable
26
final double factor = Math.pow(10.0, Math.floor(-signedExp));
27             return Math.round(x*factor)/factor;
28         } else {
29             final double factor = Math.pow(10.0, Math.ceil(signedExp));
30             return Math.round(x/factor)*factor;
31         }
32     }
33     /**
34      * Returns a random number within a specified range.
35      */

36     public static double random(double min, double max) {
37         return (max-min)*Math.random()+min;
38     }
39     /**
40      * Returns the sign of a number.
41      * @return 1 if x>0.0, -1 if x<0.0, else 0.
42      */

43     public static int sign(double x) {
44         if(x > 0.0)
45             return 1;
46         else if(x < 0.0)
47             return -1;
48         else
49             return 0;
50     }
51     /**
52      * Returns sqrt(x<sup>2</sup>+y<sup>2</sup>).
53      */

54     public static double hypot(final double x,final double y) {
55         final double xAbs=Math.abs(x);
56         final double yAbs=Math.abs(y);
57         if(xAbs==0.0 && yAbs==0.0)
58             return 0.0;
59         else if(xAbs<yAbs)
60             return yAbs*Math.sqrt(1.0+(x/y)*(x/y));
61         else
62             return xAbs*Math.sqrt(1.0+(y/x)*(y/x));
63     }
64     /**
65      * Returns a<sup>b</sup>.
66      * @param a an integer.
67      * @param b a positive integer.
68      */

69     public static int pow(int a, int b) {
70         if(b < 0) {
71             throw new IllegalArgumentException JavaDoc(b+" must be a positive integer.");
72         } else if(b == 0) {
73             return 1;
74         } else {
75             if(a == 0) {
76                 return 0;
77             } else if(a == 1) {
78                 return 1;
79             } else if(a == 2) {
80                 return 1<<b;
81             } else {
82                 for(int i=1; i<b; i++)
83                     a *= a;
84                 return a;
85             }
86         }
87     }
88     /**
89      * Returns 2<sup>a</sup>.
90      * @param a a positive integer.
91      */

92     public static int pow2(int a) {
93         return 1<<a;
94     }
95     /**
96      * Returns the factorial.
97      * (Wrapper for the gamma function).
98      * @see SpecialMath#gamma
99      * @param x a double.
100      */

101     public static double factorial(double x) {
102         return SpecialMath.gamma(x+1.0);
103     }
104     /**
105      * Returns the natural logarithm of the factorial.
106      * (Wrapper for the log gamma function).
107      * @see SpecialMath#logGamma
108      * @param x a double.
109      */

110     public static double logFactorial(double x) {
111         return SpecialMath.logGamma(x+1.0);
112     }
113     /**
114      * Returns the binomial coefficient (n k).
115      * Uses Pascal's recursion formula.
116      * @jsci.planetmath PascalsRule
117      * @param n an integer.
118      * @param k an integer.
119      */

120     public static int binomial(int n,int k) {
121         if(k == n || k ==0)
122             return 1;
123         else if(n == 0)
124             return 1;
125         else
126             return binomial(n-1, k-1)+binomial(n-1, k);
127     }
128     /**
129      * Returns the binomial coefficient (n k).
130      * Uses gamma functions.
131      * @jsci.planetmath BinomialCoefficient
132      * @param n a double.
133      * @param k a double.
134      */

135     public static double binomial(double n,double k) {
136         return Math.exp(SpecialMath.logGamma(n+1.0)-SpecialMath.logGamma(k+1.0)-SpecialMath.logGamma(n-k+1.0));
137     }
138     /**
139      * Returns the base 10 logarithm of a double.
140      * @param x a double.
141      */

142     public static double log10(double x) {
143         return Math.log(x)/NumericalConstants.LOG10;
144     }
145     /**
146      * Returns the hyperbolic sine of a double.
147      * @param x a double.
148      */

149     public static double sinh(double x) {
150         return (Math.exp(x)-Math.exp(-x))/2.0;
151     }
152     /**
153      * Returns the hyperbolic cosine of a double.
154      * @param x a double.
155      */

156     public static double cosh(double x) {
157         return (Math.exp(x)+Math.exp(-x))/2.0;
158     }
159     /**
160      * Returns the hyperbolic tangent of a double.
161      * @param x a double.
162      */

163     public static double tanh(double x) {
164         return sinh(x)/cosh(x);
165     }
166     
167     /**
168      * Returns the hyperbolic cotangent of a <code>double</code> value.
169      * <p>The identity is:
170      * <p><i>coth(x)&nbsp;=&nbsp;(e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup>)/(e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup>)</i>,
171     
172      * in other words, {@linkplain Math#cosh cosh(<i>x</i>)}/{@linkplain Math#sinh sinh(<i>x</i>)}.
173      * <p>Special cases:
174      * <ul>
175      * <li>If the argument is NaN, then the result is NaN.
176      * <li>If the argument is zero, then the result is an infinity with the same sign as the argument.
177      * <li>If the argument is positive infinity, then the result is <code>+1.0</code>.
178      * <li>If the argument is negative infinity, then the result is <code>-1.0</code>.
179      * </ul>
180      * @param x The number whose hyperbolic cotangent is sought
181      * @return The hyperbolic cotangent of <code>x</code>
182      */

183     public static double
184             coth(double x) {
185         return 1.0D/tanh(x);
186     } //coth
187

188     /**
189      * Returns the hyperbolic cosecant of a <code>double</code> value.
190      * <p>The identity is:
191      * <p><i>csch(x)&nbsp;=&nbsp;(2/(e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup>)</i>,
192      * in other words, 1/{@linkplain Math#sinh sinh(<i>x</i>)}.
193      * <p>Special cases:
194      * <ul>
195      * <li>If the argument is NaN, then the result is NaN.
196      * <li>If the argument is zero, then the result is an infinity with the same sign as the argument.
197      * <li>If the argument is positive infinity, then the result is <code>+0.0</code>.
198      * <li>If the argument is negative infinity, then the result is <code>-0.0</code>.
199      * </ul>
200      * @param x The number whose hyperbolic cosecant is sought
201      * @return The hyperbolic cosecant of <code>x</code>
202      */

203     public static double
204             csch(double x) {
205         return 1.0D/sinh(x);
206     } //csch
207

208     /**
209      * Returns the hyperbolic secant of a <code>double</code> value.
210      * <p>The identity is:
211      * <p><i>sech(x)&nbsp;=&nbsp;(2/(e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup>)</i>,
212      * in other words, 1/{@linkplain Math#cosh cosh(<i>x</i>)}.
213      * <p>Special cases:
214      * <ul>
215      * <li>If the argument is NaN, then the result is NaN.
216      * <li>If the argument is an infinity (positive or negative), then the result is <code>+0.0</code>.
217      * </ul>
218      * @param x The number whose hyperbolic secant is sought
219      * @return The hyperbolic secant of <code>x</code>
220      */

221     public static double
222             sech(double x) {
223         return 1.0D/cosh(x);
224     } //sech
225

226     /**
227      * Returns the inverse hyperbolic sine of a <code>double</code> value.
228      * <p>The identity is:
229      * <p><i>asinh(x)&nbsp;=&nbsp;ln(x&nbsp;+&nbsp;sqrt(x<sup>2</sup>&nbsp;+&nbsp;1))</i>
230      * <p>Special cases:
231      * <ul>
232      * <li>If the argument is NaN, then the result is NaN.
233      * <li>If the argument is infinite, then the result is an infinity with the same sign as the argument.
234      * <li>If the argument is zero, then the result is a zero with the same sign as the argument.
235      * </ul>
236      * @param x The number whose inverse hyperbolic sine is sought
237      * @return The inverse hyperbolic sine of <code>x</code>
238      */

239     public static double
240             asinh(double x) {
241         //Math.hypot(Double.NEGATIVE_INFINITY, 1.0D) is Double.POSITIVE_INFINITY
242
//return Double.isInfinite(x) ? x : (x == 0.0) ? x : Math.log(x + Math.hypot(x, 1.0D));
243
return Double.isInfinite(x) ? x : (x == 0.0) ? x : Math.log(x+Math.sqrt(x*x+1.0));
244     } //asinh
245

246     /**
247      * Returns the inverse hyperbolic cosine of a <code>double</code> value.
248      * Note that <i>cosh(±acosh(x))&nbsp;=&nbsp;x</i>; this function arbitrarily returns the positive branch.
249      * <p>The identity is:
250      * <p><i>acosh(x)&nbsp;=&nbsp;ln(x&nbsp;±&nbsp;sqrt(x<sup>2</sup>&nbsp;-&nbsp;1))</i>
251      * <p>Special cases:
252      * <ul>
253      * <li>If the argument is NaN or less than one, then the result is NaN.
254      * <li>If the argument is a positive infinity, then the result is (positive) infinity.
255      * <li>If the argument is one, then the result is (positive) zero.
256      * </ul>
257      * @param x The number whose inverse hyperbolic cosine is sought
258      * @return The inverse hyperbolic cosine of <code>x</code>
259      */

260     public static double
261             acosh(double x) {
262         return Math.log(x + Math.sqrt(x*x - 1.0D));
263     } //acosh
264

265     /**
266      * Returns the inverse hyperbolic tangent of a <code>double</code> value.
267      * <p>The identity is:
268      * <p><i>atanh(x)&nbsp;=&nbsp;(1/2)*ln((1&nbsp;+&nbsp;x)/(1&nbsp;-&nbsp;x))</i>
269      * <p>Special cases:
270      * <ul>
271      * <li>If the argument is NaN, an infinity, or has a modulus of greater than one, then the result is NaN.
272      * <li>If the argument is plus or minus one, then the result is infinity with the same sign as the argument.
273      * <li>If the argument is zero, then the result is a zero with the same sign as the argument.
274      * </ul>
275      * @param x A double specifying the value whose inverse hyperbolic tangent is sought
276      * @return A double specifying the inverse hyperbolic tangent of x
277      */

278     public static double
279             atanh(double x) {
280         //return (Math.log1p(x) - Math.log1p(-x))/2.0D;
281
return (x != 0.0) ? (Math.log(1.0D + x)-Math.log(1.0D - x))/2.0D : x;
282     } //atanh
283

284     /**
285      * Returns the inverse hyperbolic cotangent of a <code>double</code> value.
286      * <p>The identity is:
287      * <p><i>acoth(x)&nbsp;=&nbsp;(1/2)*ln((x&nbsp;+&nbsp;1)/(x&nbsp;-&nbsp;1))</i>
288      * <p>Special cases:
289      * <ul>
290      * <li>If the argument is NaN or a modulus of less than one, then the result is NaN.
291      * <li>If the argument is an infinity, then the result is zero with the same sign as the argument.
292      * <li>If the argument is plus or minus one, then the result is infinity with the same sign as the argument.
293      * </ul>
294      * @param x The number whose inverse hyperbolic cotangent is sought
295      * @return The inverse hyperbolic cotangent of <code>x</code>
296      */

297     public static double
298             acoth(double x) {
299 // return (Math.log1p(x) - Math.log(x - 1.0D))/2.0D; // Difference of two same-sign infinities is NaN
300
if (Double.isInfinite(x)) return (x < 0.0) ? -0.0D : +0.0D;
301         //return (x == -1.0D) ? Double.NEGATIVE_INFINITY : (Math.log1p(x) - Math.log(x - 1.0D))/2.0D;
302
return (x == -1.0D) ? Double.NEGATIVE_INFINITY : (Math.log(x+1.0) - Math.log(x - 1.0D))/2.0D;
303     } //acoth
304

305     /**
306      * Returns the inverse hyperbolic cosecant of a <code>double</code> value.
307      * <p>The identity is:
308      * <p><i>acsch(x)&nbsp;=&nbsp;ln((1&nbsp;-&nbsp;sqrt(1&nbsp;+&nbsp;x<sup>2</sup>))/x)</i> for x &lt; 0;
309      * <p><i>acsch(x)&nbsp;=&nbsp;ln((1&nbsp;+&nbsp;sqrt(1&nbsp;+&nbsp;x<sup>2</sup>))/x)</i> for x &gt; 0.
310      * <p>Special cases:
311      * <ul>
312      * <li>If the argument is NaN, then the result is NaN.
313      * <li>If the argument is an infinity, then the result is zero with the same sign as the argument.
314      * <li>If the argument is zero, then the result is infinity with the same sign as the argument.
315      * </ul>
316      * @param x The number whose inverse hyperbolic cosecant is sought
317      * @return The inverse hyperbolic cosecant of <code>x</code>
318      */

319     public static double
320             acsch(double x) {
321 // return (x < 0) ? Math.log((1.0D - Math.sqrt(Math.hypot(1.0, x)))/x) : Math.log((1.0D + Math.sqrt(1.0, x))/x);
322

323         if (Double.isInfinite(x)) return (x < 0.0) ? -0.0D : +0.0D;
324         //log(+infinity) is +infinity, but log(-infinity) is NaN
325
return (x == 0.0D) ? 1.0/x : Math.log((1.0D + sign(x)*Math.sqrt(x*x+1.0))/x);
326     } //acsch
327

328     /**
329      * Returns the inverse hyperbolic secant of a <code>double</code> value.
330      * Note that <i>sech(±asech(x))&nbsp;=&nbsp;x</i>; this function arbitrarily returns the positive branch.
331      * <p>The identity is:
332      * <p><i>asech(x)&nbsp;=&nbsp;ln((1&nbsp;+&nbsp;sqrt(1&nbsp;-&nbsp;x<sup>2</sup>))/x)</i>.
333      * <p>Special cases:
334      * <ul>
335      * <li>If the argument is NaN, less than zero, or greater than one, then the result is NaN.
336      * <li>If the argument is zero, then the result is infinity with the same sign as the argument.
337      * </ul>
338      * @param x The number whose hyperbolic secant is sought
339      * @return The hyperbolic secant of <code>x</code>
340      */

341     public static double
342             asech(double x) {
343         //log(+infinity) is +infinity, but log(-infinity) is NaN
344
return (x == 0.0D) ? 1.0/x : Math.log((1.0D + Math.sqrt(1.0D - x*x))/x);
345     } //asech
346
}
347
Popular Tags