KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > util > MathLib


1 package prefuse.util;
2
3 import java.util.Arrays JavaDoc;
4
5 import prefuse.Constants;
6
7 /**
8  * Library of mathematical constants and methods not included in the
9  * {@link java.lang.Math} class.
10  *
11  * @author <a HREF="http://jheer.org">jeffrey heer</a>
12  */

13 public class MathLib {
14
15     /** The value 2 * PI */
16     public static final double TWO_PI = 2*Math.PI;
17     /** The natural logarithm of 10 */
18     public static final double LOG10 = Math.log(10);
19     /** The natural logarithm of 2 */
20     public static final double LOG2 = Math.log(2);
21     
22     private MathLib() {
23         // prevent instantiation
24
}
25     
26     /**
27      * The base 2 logarithm of the input value
28      * @param x the input value
29      * @return the base 2 logarithm
30      */

31     public static double log2(double x) {
32         return Math.log(x)/LOG2;
33     }
34
35     /**
36      * The base 10 logarithm of the input value
37      * @param x the input value
38      * @return the base 10 logarithm
39      */

40     public static double log10(double x) {
41         return Math.log(x)/LOG10;
42     }
43     
44     /**
45      * The "safe" base 10 logarithm of the input value, handling
46      * negative values by simply making them positive and then
47      * negating the return value.
48      * @param x the input value
49      * @return the "negative-safe" base 10 logarithm
50      */

51     public static double safeLog10(double x) {
52         boolean neg = (x < 0.0);
53         if ( neg ) { x = -x; }
54         if ( x < 10.0 ) { x += (10.0-x) / 10; }
55         x = Math.log(x) / LOG10;
56         
57         return neg ? -x : x;
58     }
59     
60     /**
61      * The "safe" square root of the input value, handling
62      * negative values by simply making them positive and then
63      * negating the return value.
64      * @param x the input value
65      * @return the "negative-safe" square root
66      */

67     public static double safeSqrt(double x) {
68         return ( x<0 ? -Math.sqrt(-x) : Math.sqrt(x) );
69     }
70     
71     /**
72      * Interpolates a value within a range using a specified scale,
73      * returning the fractional position of the value within that scale.
74      * @param scale The scale on which to perform the interpolation, one of
75      * {@link prefuse.Constants#LINEAR_SCALE},
76      * {@link prefuse.Constants#LOG_SCALE},
77      * {@link prefuse.Constants#SQRT_SCALE}, or
78      * {@link prefuse.Constants#QUANTILE_SCALE}.
79      * @param val the interpolation value, a fraction between 0 and 1.0.
80      * @param dist a double array describing the distribution of the data.
81      * For the {@link prefuse.Constants#QUANTILE_SCALE} option, this should
82      * be a collection of quantile boundaries, as determined by the
83      * {@link #quantiles(int, double[])} method. For any other scale type,
84      * the first value of the array must contain the minimum value of the
85      * distribution and the last value of the array must contain the
86      * maximum value of the distribution; all values in between will be
87      * ignored.
88      * @return the fractional position of the value within the scale,
89      * a double between 0 and 1.
90      */

91     public static double interp(int scale, double val, double dist[]) {
92         switch ( scale ) {
93         case Constants.LINEAR_SCALE:
94             return linearInterp(val, dist[0], dist[dist.length-1]);
95         case Constants.LOG_SCALE:
96             return logInterp(val, dist[0], dist[dist.length-1]);
97         case Constants.SQRT_SCALE:
98             return sqrtInterp(val, dist[0], dist[dist.length-1]);
99         case Constants.QUANTILE_SCALE:
100             return quantile(val, dist);
101         }
102         throw new IllegalArgumentException JavaDoc("Unrecognized scale value: "+scale);
103     }
104     
105     /**
106      * Interpolates a value between a given minimum and maximum value using
107      * a linear scale.
108      * @param val the interpolation value, a fraction between 0 and 1.0.
109      * @param min the minimum value of the interpolation range
110      * @param max the maximum value of the interpolation range
111      * @return the resulting interpolated value
112      */

113     public static double linearInterp(double val, double min, double max) {
114         double denominator = (max-min);
115         if ( denominator == 0 )
116             return 0;
117         return (val-min)/denominator;
118     }
119     
120     /**
121      * Interpolates a value between a given minimum and maximum value using
122      * a base-10 logarithmic scale.
123      * @param val the interpolation value, a fraction between 0 and 1.0.
124      * @param min the minimum value of the interpolation range
125      * @param max the maximum value of the interpolation range
126      * @return the resulting interpolated value
127      */

128     public static double logInterp(double val, double min, double max) {
129         double logMin = safeLog10(min);
130         double denominator = (safeLog10(max)-logMin);
131         if ( denominator == 0 )
132             return 0;
133         return (safeLog10(val)-logMin) / denominator;
134     }
135     
136     /**
137      * Interpolates a value between a given minimum and maximum value using
138      * a square root scale.
139      * @param val the interpolation value, a fraction between 0 and 1.0.
140      * @param min the minimum value of the interpolation range
141      * @param max the maximum value of the interpolation range
142      * @return the resulting interpolated value
143      */

144     public static double sqrtInterp(double val, double min, double max) {
145         double sqrtMin = safeSqrt(min);
146         double denominator = (safeSqrt(max)-sqrtMin);
147         if ( denominator == 0 )
148             return 0;
149         return (safeSqrt(val)-sqrtMin) / denominator;
150     }
151     
152     /**
153      * Compute the n-quantile boundaries for a set of values. The result is
154      * an n+1 size array holding the minimum value in the first entry and
155      * then n quantile boundaries in the subsequent entries.
156      * @param n the number of quantile boundaries. For example, a value of 4
157      * will break up the values into quartiles, while a value of 100 will break
158      * up the values into percentiles.
159      * @param values the array of double values to divide into quantiles
160      * @return an n+1 array of doubles containing the minimum value and
161      * the quantile boundary values, in that order
162      */

163     public static double[] quantiles(int n, double[] values) {
164         values = (double[])values.clone();
165         Arrays.sort(values);
166         double[] qtls = new double[n+1];
167         for ( int i=0; i<=n; ++i ) {
168             qtls[i] = values[((values.length-1)*i)/n];
169         }
170         return qtls;
171     }
172     
173     /**
174      * Get the quantile measure, as a value between 0 and 1, for a given
175      * value and set of quantile boundaries. For example, if the input value
176      * is the median of the distribution described by the quantile boundaries,
177      * this method will return 0.5. As another example, if the quantile
178      * boundaries represent percentiles, this value will return the percentile
179      * ranking of the input value according to the given boundaries.
180      * @param val the value for which to return the quantile ranking
181      * @param quantiles an array of quantile boundaries of a distribution
182      * @return the quantile ranking, a value between 0 and 1
183      * @see #quantiles(int, double[])
184      */

185     public static double quantile(double val, double[] quantiles) {
186         int x1 = 1;
187         int x2 = quantiles.length;
188         int i = x2 / 2;
189         while (x1 < x2) {
190             if (quantiles[i] == val) {
191                 break;
192             } else if (quantiles[i] < val) {
193                 x1 = i + 1;
194             } else {
195                 x2 = i;
196             }
197             i = x1 + (x2 - x1) / 2;
198         }
199         return ((double)i)/(quantiles.length-1);
200     }
201     
202 } // end of class MathLib
203
Popular Tags