package aima.core.util; import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; /** * @author Ravi Mohan * */ public class Util { public static final String NO = "No"; public static final String YES = "Yes"; // private static Random _r = new Random(); /** * Get the first element from a list. * * @param l * the list the first element is to be extracted from. * @return the first element of the passed in list. */ public static <T> T first(List<T> l) { return l.get(0); } /** * Get a sublist of all of the elements in the list except for first. * * @param l * the list the rest of the elements are to be extracted from. * @return a list of all of the elements in the passed in list except for * the first element. */ public static <T> List<T> rest(List<T> l) { return l.subList(1, l.size()); } /** * Create a Map<K, V> with the passed in keys having their values * initialized to the passed in value. * * @param keys * the keys for the newly constructed map. * @param value * the value to be associated with each of the maps keys. * @return a map with the passed in keys initialized to value. */ public static <K, V> Map<K, V> create(Collection<K> keys, V value) { Map<K, V> map = new LinkedHashMap<K, V>(); for (K k : keys) { map.put(k, value); } return map; } /** * Randomly select an element from a list. * * @param <T> * the type of element to be returned from the list l. * @param l * a list of type T from which an element is to be selected * randomly. * @return a randomly selected element from l. */ public static <T> T selectRandomlyFromList(List<T> l) { return l.get(_r.nextInt(l.size())); } public static boolean randomBoolean() { int trueOrFalse = _r.nextInt(2); return (!(trueOrFalse == 0)); } public static double[] normalize(double[] probDist) { int len = probDist.length; double total = 0.0; for (double d : probDist) { total = total + d; } double[] normalized = new double[len]; if (total != 0) { for (int i = 0; i < len; i++) { normalized[i] = probDist[i] / total; } } return normalized; } public static List<Double> normalize(List<Double> values) { double[] valuesAsArray = new double[values.size()]; for (int i = 0; i < valuesAsArray.length; i++) { valuesAsArray[i] = values.get(i); } double[] normalized = normalize(valuesAsArray); List<Double> results = new ArrayList<Double>(); for (int i = 0; i < normalized.length; i++) { results.add(normalized[i]); } return results; } public static int min(int i, int j) { return (i > j ? j : i); } public static int max(int i, int j) { return (i < j ? j : i); } public static int max(int i, int j, int k) { return max(max(i, j), k); } public static int min(int i, int j, int k) { return min(min(i, j), k); } public static <T> T mode(List<T> l) { Hashtable<T, Integer> hash = new Hashtable<T, Integer>(); for (T obj : l) { if (hash.containsKey(obj)) { hash.put(obj, hash.get(obj).intValue() + 1); } else { hash.put(obj, 1); } } T maxkey = hash.keySet().iterator().next(); for (T key : hash.keySet()) { if (hash.get(key) > hash.get(maxkey)) { maxkey = key; } } return maxkey; } public static String[] yesno() { return new String[] { YES, NO }; } public static double log2(double d) { return Math.log(d) / Math.log(2); } public static double information(double[] probabilities) { double total = 0.0; for (double d : probabilities) { total += (-1.0 * log2(d) * d); } return total; } public static <T> List<T> removeFrom(List<T> list, T member) { List<T> newList = new ArrayList<T>(list); newList.remove(member); return newList; } public static <T extends Number> double sumOfSquares(List<T> list) { double accum = 0; for (T item : list) { accum = accum + (item.doubleValue() * item.doubleValue()); } return accum; } public static String ntimes(String s, int n) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < n; i++) { buf.append(s); } return buf.toString(); } public static void checkForNanOrInfinity(double d) { if (Double.isNaN(d)) { throw new RuntimeException("Not a Number"); } if (Double.isInfinite(d)) { throw new RuntimeException("Infinite Number"); } } public static int randomNumberBetween(int i, int j) { /* i,j bothinclusive */ return _r.nextInt(j - i + 1) + i; } public static double calculateMean(List<Double> lst) { Double sum = 0.0; for (Double d : lst) { sum = sum + d.doubleValue(); } return sum / lst.size(); } public static double calculateStDev(List<Double> values, double mean) { int listSize = values.size(); Double sumOfDiffSquared = 0.0; for (Double value : values) { double diffFromMean = value - mean; sumOfDiffSquared += ((diffFromMean * diffFromMean) / (listSize - 1)); // division moved here to avoid sum becoming too big if this // doesn't work use incremental formulation } double variance = sumOfDiffSquared; // (listSize - 1); // assumes at least 2 members in list. return Math.sqrt(variance); } public static List<Double> normalizeFromMeanAndStdev(List<Double> values, double mean, double stdev) { List<Double> normalized = new ArrayList<Double>(); for (Double d : values) { normalized.add((d - mean) / stdev); } return normalized; } public static double generateRandomDoubleBetween(double lowerLimit, double upperLimit) { return lowerLimit + ((upperLimit - lowerLimit) * _r.nextDouble()); } }