001    /*
002     * Created on Aug 24, 2003 by Ravi Mohan
003     *  
004     */
005    package aima.util;
006    
007    import java.util.ArrayList;
008    import java.util.Hashtable;
009    import java.util.List;
010    import java.util.Random;
011    
012    public class Util {
013            public static final String NO = "No";
014    
015            public static final String YES = "Yes";
016    
017            private static Random r = new Random();
018    
019            public static <T> T first(List<T> l) {
020    
021                    List<T> newList = new ArrayList<T>();
022                    for (T element : l) {
023                            newList.add(element);
024                    }
025                    return newList.get(0);
026            }
027    
028            public static <T> List<T> rest(List<T> l) {
029                    List<T> newList = new ArrayList<T>();
030                    for (T element : l) {
031                            newList.add(element);
032                    }
033                    newList.remove(0);
034                    return newList;
035            }
036    
037            public static boolean randomBoolean() {
038                    int trueOrFalse = r.nextInt(2);
039                    return (!(trueOrFalse == 0));
040            }
041    
042            public static double[] normalize(double[] probDist) {
043                    int len = probDist.length;
044                    double total = 0.0;
045                    for (double d : probDist) {
046                            total = total + d;
047                    }
048    
049                    double[] normalized = new double[len];
050                    if (total != 0) {
051                            for (int i = 0; i < len; i++) {
052                                    normalized[i] = probDist[i] / total;
053                            }
054                    }
055                    double totalN = 0.0;
056                    for (double d : normalized) {
057                            totalN = totalN + d;
058                    }
059    
060                    return normalized;
061            }
062    
063            public static List<Double> normalize(List<Double> values) {
064                    double[] valuesAsArray = new double[values.size()];
065                    for (int i = 0; i < valuesAsArray.length; i++) {
066                            valuesAsArray[i] = values.get(i);
067                    }
068                    double[] normalized = normalize(valuesAsArray);
069                    List<Double> results = new ArrayList<Double>();
070                    for (int i = 0; i < normalized.length; i++) {
071                            results.add(normalized[i]);
072                    }
073                    return results;
074            }
075    
076            public static int min(int i, int j) {
077                    return (i > j ? j : i);
078            }
079    
080            public static int max(int i, int j) {
081                    return (i < j ? j : i);
082            }
083    
084            public static int max(int i, int j, int k) {
085                    return max(max(i, j), k);
086            }
087    
088            public static int min(int i, int j, int k) {
089                    return min(min(i, j), k);
090            }
091    
092            public static <T> T selectRandomlyFromList(List<T> l) {
093                    int index = r.nextInt(l.size());
094                    return l.get(index);
095            }
096    
097            public static <T> T mode(List<T> l) {
098                    Hashtable<T, Integer> hash = new Hashtable<T, Integer>();
099                    for (T obj : l) {
100                            if (hash.containsKey(obj)) {
101                                    hash.put(obj, hash.get(obj).intValue() + 1);
102                            } else {
103                                    hash.put(obj, 1);
104                            }
105                    }
106    
107                    T maxkey = hash.keySet().iterator().next();
108                    for (T key : hash.keySet()) {
109                            if (hash.get(key) > hash.get(maxkey)) {
110                                    maxkey = key;
111                            }
112                    }
113                    return maxkey;
114            }
115    
116            public static String[] yesno() {
117                    return new String[] { YES, NO };
118            }
119    
120            public static double log2(double d) {
121                    return Math.log(d) / Math.log(2);
122            }
123    
124            public static double information(double[] probabilities) {
125                    double total = 0.0;
126                    for (double d : probabilities) {
127                            total += (-1.0 * log2(d) * d);
128                    }
129                    return total;
130            }
131    
132            public static <T> List<T> removeFrom(List<T> list, T member) {
133                    List<T> newList = new ArrayList<T>();
134                    for (T s : list) {
135                            if (!(s.equals(member))) {
136                                    newList.add(s);
137                            }
138                    }
139                    return newList;
140            }
141    
142            public static <T extends Number> double sumOfSquares(List<T> list) {
143                    double accum = 0;
144                    for (T item : list) {
145                            accum = accum + (item.doubleValue() * item.doubleValue());
146                    }
147                    return accum;
148            }
149    
150            public static String ntimes(String s, int n) {
151                    StringBuffer buf = new StringBuffer();
152                    for (int i = 0; i < n; i++) {
153                            buf.append(s);
154                    }
155                    return buf.toString();
156            }
157    
158            public static void checkForNanOrInfinity(double d) {
159                    if (Double.isNaN(d)) {
160                            throw new RuntimeException("Not a Number");
161                    }
162                    if (Double.isInfinite(d)) {
163                            throw new RuntimeException("Infinite Number");
164                    }
165            }
166    
167            public static int randomNumberBetween(int i, int j) {
168                    /* i,j both **inclusive** */
169                    return r.nextInt(j - i + 1) + i;
170            }
171    
172            public static double calculateMean(List<Double> lst) {
173                    Double sum = 0.0;
174                    for (Double d : lst) {
175                            sum = sum + d.doubleValue();
176                    }
177                    return sum / lst.size();
178            }
179    
180            public static double calculateStDev(List<Double> values, double mean) {
181    
182                    int listSize = values.size();
183    
184                    Double sumOfDiffSquared = 0.0;
185                    for (Double value : values) {
186                            double diffFromMean = value - mean;
187                            sumOfDiffSquared += ((diffFromMean * diffFromMean) / (listSize - 1));// division
188                            // moved
189                            // here
190                            // to
191                            // avoid
192                            // sum
193                            // becoming
194                            // too
195                            // big
196                            // if
197                            // this
198                            // doesn't
199                            // work
200                            // use
201                            // incremental
202                            // formulation
203    
204                    }
205                    double variance = sumOfDiffSquared; // (listSize - 1); // assumes at
206                    // least 2
207                    // members in
208                    // list
209                    return Math.sqrt(variance);
210            }
211    
212            public static List<Double> normalizeFromMeanAndStdev(List<Double> values,
213                            double mean, double stdev) {
214                    List<Double> normalized = new ArrayList<Double>();
215                    for (Double d : values) {
216                            normalized.add((d - mean) / stdev);
217                    }
218                    return normalized;
219            }
220    
221            public static double generateRandomDoubleBetween(double lowerLimit,
222                            double upperLimit) {
223    
224                    return lowerLimit + ((upperLimit - lowerLimit) * r.nextDouble());
225            }
226    
227    }