static double[] recenter(double[] x) { double[] r = new double[x.length]; // double logTotal = Double.NEGATIVE_INFINITY; // for (int i = 0; i < x.length; i++) // logTotal = SloppyMath.logAdd(logTotal, x[i]); double logTotal = ArrayMath.logSum(x); for (int i = 0; i < x.length; i++) { r[i] = x[i] - logTotal; } return r; }
/** * Returns the log of the sum of an array of numbers, which are * themselves input in log form. This is all natural logarithms. * Reasonable care is taken to do this as efficiently as possible * (under the assumption that the numbers might differ greatly in * magnitude), with high accuracy, and without numerical overflow. * * @param logInputs An array of numbers [log(x1), ..., log(xn)] * @return {@literal log(x1 + ... + xn)} */ public static double logSum(double... logInputs) { return logSum(logInputs,0,logInputs.length); }
public double totalMass() { return ArrayMath.logSum(table); }
public float totalMass() { return ArrayMath.logSum(table); }
public static double logSum(List<Double> logInputs) { return logSum(logInputs, 0, logInputs.size()); }
public float unnormalizedLogProbFront(int[] label) { label = indicesFront(label); float[] masses = new float[label.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[label[i]]; } return ArrayMath.logSum(masses); }
public float unnormalizedLogProbEnd(int[] label) { label = indicesEnd(label); float[] masses = new float[label.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[label[i]]; } return ArrayMath.logSum(masses); }
public double unnormalizedLogProbEnd(int[] labels) { labels = indicesEnd(labels); double[] masses = new double[labels.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[labels[i]]; } return ArrayMath.logSum(masses); }
public float unnormalizedLogProbEnd(int label) { int[] l = {label}; l = indicesEnd(l); float[] masses = new float[l.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[l[i]]; } return ArrayMath.logSum(masses); }
public static double[] calculateSums(double[][] weights, int[] featureIndices, double[] featureValues) { int numClasses = weights.length + 1; double[] result = new double[numClasses]; result[0] = 0.0; for (int c = 1; c < numClasses; c++) { result[c] = -dotProduct(weights[c - 1], featureIndices, featureValues); } double total = ArrayMath.logSum(result); for (int c = 0; c < numClasses; c++) { result[c] -= total; } return result; }
public static double[] calculateSums(double[][] weights, int[] featureIndices, double[] featureValues, double[] intercepts) { int numClasses = weights.length + 1; double[] result = new double[numClasses]; result[0] = 0.0; for (int c = 1; c < numClasses; c++) { result[c] = -dotProduct(weights[c - 1], featureIndices, featureValues) - intercepts[c - 1]; } double total = ArrayMath.logSum(result); for (int c = 0; c < numClasses; c++) { result[c] -= total; } return result; }
/** * Makes the values in this array sum to 1.0. Does it in place. * If the total is 0.0, throws a RuntimeException. * If the total is Double.NEGATIVE_INFINITY, then it replaces the * array with a normalized uniform distribution. CDM: This last bit is * weird! Do we really want that? */ public static void logNormalize(double[] a) { double logTotal = logSum(a); if (logTotal == Double.NEGATIVE_INFINITY) { // to avoid NaN values double v = -Math.log(a.length); for (int i = 0; i < a.length; i++) { a[i] = v; } return; } addInPlace(a, -logTotal); // subtract log total from each value }
/** * Computes the probability of the tag OF being at the end of the table given * that the previous tag sequence in table is GIVEN. given is at the beginning, * of is at the end. * * @return the probability of the tag OF being at the end of the table */ public double conditionalLogProbGivenPrevious(int[] given, int of) { if (given.length != windowSize - 1) { throw new IllegalArgumentException("conditionalLogProbGivenPrevious requires given one less than clique size (" + windowSize + ") but was " + Arrays.toString(given)); } // Note: other similar methods could be optimized like this one, but this is the one the CRF uses.... /* int startIndex = indicesFront(given); int numCellsToSum = SloppyMath.intPow(numClasses, windowSize - given.length); double z = ArrayMath.logSum(table, startIndex, startIndex + numCellsToSum); int i = indexOf(given, of); System.err.printf("startIndex is %d, numCellsToSum is %d, i is %d (of is %d)%n", startIndex, numCellsToSum, i, of); */ int startIndex = indicesFront(given); double z = ArrayMath.logSum(table, startIndex, startIndex + numClasses); int i = startIndex + of; // System.err.printf("startIndex is %d, numCellsToSum is %d, i is %d (of is %d)%n", startIndex, numClasses, i, of); return table[i] - z; }
/** * Returns ArrayMath.logSum of the values in this counter. * * @param c Argument counter (which is not modified) * @return ArrayMath.logSum of the values in this counter. */ public static <E> double logSum(Counter<E> c) { return ArrayMath.logSum(ArrayMath.unbox(c.values())); }
public FactorTable sumOutEnd() { FactorTable ft = new FactorTable(numClasses, windowSize - 1); for (int i = 0, sz = ft.size(); i < sz; i++) { ft.table[i] = ArrayMath.logSum(table, i * numClasses, (i+1) * numClasses); } /* for (int i = 0; i < table.length; i++) { ft.logIncrementValue(i / numClasses, table[i]); } */ return ft; }
public double unnormalizedLogProbFront(int[] labels) { int startIndex = indicesFront(labels); int numCellsToSum = SloppyMath.intPow(numClasses, windowSize - labels.length); // double[] masses = new double[labels.length]; // for (int i = 0; i < masses.length; i++) { // masses[i] = table[labels[i]]; // } return ArrayMath.logSum(table, startIndex, startIndex + numCellsToSum); }
/** * Computes the probability of the tag OF being at the beginning of the table * given that the tag sequence GIVEN is at the end of the table. given is at * the end, of is at the beginning * * @return the probability of the tag of being at the beginning of the table */ public double conditionalLogProbGivenNext(int[] given, int of) { if (given.length != windowSize - 1) { throw new IllegalArgumentException("conditionalLogProbGivenNext requires given one less than clique size (" + windowSize + ") but was " + Arrays.toString(given)); } int[] label = indicesEnd(given); double[] masses = new double[label.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[label[i]]; } double z = ArrayMath.logSum(masses); return table[indexOf(of, given)] - z; }
public float conditionalLogProb(int[] given, int of) { if (given.length != windowSize - 1) { log.info("error computing conditional log prob"); System.exit(0); } int[] label = indicesFront(given); float[] masses = new float[label.length]; for (int i = 0; i < masses.length; i++) { masses[i] = table[label[i]]; } float z = ArrayMath.logSum(masses); return table[indexOf(given, of)] - z; }
public FactorTable sumOutFront() { FactorTable ft = new FactorTable(numClasses, windowSize - 1); int stride = ft.size(); for (int i = 0; i < stride; i++) { ft.setValue(i, ArrayMath.logSum(table, i, table.length, stride)); } return ft; }
private double[] getApproximateScores(History h) { String[] tags = stringTagsAt(h.current - h.start + leftWindow()); double[] scores = getHistories(tags, h); // log score for each active tag, unnormalized // Number of tags that get assigned a default score: int nDefault = maxentTagger.ySize - tags.length; double logScore = ArrayMath.logSum(scores); double logScoreInactiveTags = maxentTagger.getInactiveTagDefaultScore(nDefault); double logTotal = SloppyMath.logAdd(logScore, logScoreInactiveTags); ArrayMath.addInPlace(scores, -logTotal); return scores; }