Program: 131511
Project: 131511
Buggy source:
/** 
 * Computes the expected feature counts for a factor graph, and adds them to the gradient after scaling them.
 * @param ex 
 * @param inferencer The inferencer for a clamped factor graph, which has already been run.
 * @param fts TODO
 * @param multiplier The value which the expected features will be multiplied by.
 * @param gradient The OUTPUT gradient vector to which the scaled expected features will be added.
 * @param factorId The id of the factor.
 * @param featCache The feature cache for the clamped factor graph, on which the inferencer was run.
 */
private void addExpectedFeatureCounts(FactorGraph fg,FgExample ex,FgInferencer inferencer,FeatureTemplateList fts,double multiplier,FgModel gradient){
  for (int factorId=0; factorId < fg.getNumFactors(); factorId++) {
    Factor f=fg.getFactor(factorId);
    if (f instanceof GlobalFactor) {
      continue;
    }
 else     if (f instanceof ExpFamFactor) {
      DenseFactor factorMarginal=inferencer.getMarginalsForFactorId(factorId);
      int numConfigs=factorMarginal.getVars().calcNumConfigs();
      if (numConfigs == 0) {
        FeatureVector fv=ex.getObservationFeatures(factorId);
        int config=ex.getGoldConfigIdxLatPred(factorId);
        for (        IntDoubleEntry entry : fv) {
          gradient.addIfParamExists(fts.getTemplateId(f),config,entry.index(),multiplier * entry.get());
        }
      }
 else {
        IntIter iter=null;
        if (fg == ex.getFgLat()) {
          VarConfig predVc=ex.getGoldConfigPred(factorId);
          iter=IndexForVc.getConfigIter(ex.getFgLatPred().getFactor(factorId).getVars(),predVc);
        }
        for (int c=0; c < numConfigs; c++) {
          double prob=factorMarginal.getValue(c);
          if (inferencer.isLogDomain()) {
            prob=Utilities.exp(prob);
          }
          FeatureVector fv=ex.getObservationFeatures(factorId);
          int config=(iter != null) ? iter.next() : c;
          for (          IntDoubleEntry entry : fv) {
            gradient.addIfParamExists(fts.getTemplateId(f),config,entry.index(),multiplier * prob * entry.get());
          }
        }
        assert(iter == null || !iter.hasNext());
      }
    }
 else {
      throw new UnsupportedFactorTypeException(f);
    }
  }
}

Fixed version (ground truth):
/** 
 * Computes the expected feature counts for a factor graph, and adds them to the gradient after scaling them.
 * @param ex 
 * @param inferencer The inferencer for a clamped factor graph, which has already been run.
 * @param fts TODO
 * @param multiplier The value which the expected features will be multiplied by.
 * @param gradient The OUTPUT gradient vector to which the scaled expected features will be added.
 * @param factorId The id of the factor.
 * @param featCache The feature cache for the clamped factor graph, on which the inferencer was run.
 */
private void addExpectedFeatureCounts(FactorGraph fg,FgExample ex,FgInferencer inferencer,FeatureTemplateList fts,double multiplier,FgModel gradient){
  for (int factorId=0; factorId < fg.getNumFactors(); factorId++) {
    Factor f=fg.getFactor(factorId);
    if (f instanceof GlobalFactor) {
      continue;
    }
 else     if (f instanceof ExpFamFactor) {
      DenseFactor factorMarginal=inferencer.getMarginalsForFactorId(factorId);
      int numConfigs=factorMarginal.getVars().calcNumConfigs();
      if (numConfigs == 0) {
        FeatureVector fv=ex.getObservationFeatures(factorId);
        int config=ex.getGoldConfigIdxPred(factorId);
        for (        IntDoubleEntry entry : fv) {
          gradient.addIfParamExists(fts.getTemplateId(f),config,entry.index(),multiplier * entry.get());
        }
      }
 else {
        IntIter iter=null;
        if (fg == ex.getFgLat()) {
          VarConfig predVc=ex.getGoldConfigPred(factorId);
          iter=IndexForVc.getConfigIter(ex.getFgLatPred().getFactor(factorId).getVars(),predVc);
        }
        for (int c=0; c < numConfigs; c++) {
          double prob=factorMarginal.getValue(c);
          if (inferencer.isLogDomain()) {
            prob=Utilities.exp(prob);
          }
          FeatureVector fv=ex.getObservationFeatures(factorId);
          int config=(iter != null) ? iter.next() : c;
          for (          IntDoubleEntry entry : fv) {
            gradient.addIfParamExists(fts.getTemplateId(f),config,entry.index(),multiplier * prob * entry.get());
          }
        }
        assert(iter == null || !iter.hasNext());
      }
    }
 else {
      throw new UnsupportedFactorTypeException(f);
    }
  }
}