Program: 32076
Project: 32076
Buggy source:
@Override public GainInfo computeImpurity(double[] stats,ColumnConfig config){
  int numClasses=super.statsSize;
  double[] statsByClasses=new double[numClasses];
  for (int i=0; i < stats.length / numClasses; i++) {
    for (int j=0; j < numClasses; j++) {
      double oneStatValue=stats[i * super.statsSize + j];
      statsByClasses[j]+=oneStatValue;
    }
  }
  InternalEntropyInfo info=getEntropyInterInfo(statsByClasses);
  Predict predict=new Predict(info.indexOfLargestElement,statsByClasses[1] / info.sumAll);
  double[] leftStatByClasses=new double[numClasses];
  double[] rightStatByClasses=new double[numClasses];
  List<GainInfo> internalGainList=new ArrayList<GainInfo>();
  Set<String> leftCategories=config.isCategorical() ? new HashSet<String>() : null;
  for (int i=0; i < (stats.length / numClasses - 1); i++) {
    for (int j=0; j < leftStatByClasses.length; j++) {
      leftStatByClasses[j]+=stats[i * numClasses + j];
    }
    InternalEntropyInfo leftInfo=getEntropyInterInfo(leftStatByClasses);
    Predict leftPredict=new Predict(leftInfo.indexOfLargestElement,leftStatByClasses[1] / leftInfo.sumAll);
    for (int j=0; j < leftStatByClasses.length; j++) {
      rightStatByClasses[j]=statsByClasses[j] - leftStatByClasses[j];
    }
    InternalEntropyInfo rightInfo=getEntropyInterInfo(rightStatByClasses);
    Predict rightPredict=new Predict(rightInfo.indexOfLargestElement,rightStatByClasses[1] / rightInfo.sumAll);
    double gain=info.impurity - (leftInfo.sumAll / info.sumAll) * leftInfo.impurity - (rightInfo.sumAll / info.sumAll) * rightInfo.impurity;
    Split split=null;
    if (config.isCategorical()) {
      leftCategories.add(config.getBinCategory().get(i));
      split=new Split(config.getColumnNum(),FeatureType.CATEGORICAL,0d,leftCategories);
    }
 else {
      split=new Split(config.getColumnNum(),FeatureType.CONTINUOUS,config.getBinBoundary().get(i + 1),null);
    }
    internalGainList.add(new GainInfo(gain,info.impurity,predict,leftInfo.impurity,rightInfo.impurity,leftPredict,rightPredict,split));
  }
  return GainInfo.getGainInfoByMaxGain(internalGainList);
}

Fixed version (ground truth):
@Override public GainInfo computeImpurity(double[] stats,ColumnConfig config){
  int numClasses=super.statsSize;
  double[] statsByClasses=new double[numClasses];
  for (int i=0; i < stats.length / numClasses; i++) {
    for (int j=0; j < numClasses; j++) {
      double oneStatValue=stats[i * super.statsSize + j];
      statsByClasses[j]+=oneStatValue;
    }
  }
  InternalEntropyInfo info=getEntropyInterInfo(statsByClasses);
  Predict predict=new Predict(info.sumAll == 0d ? 0d : statsByClasses[1] / info.sumAll,info.indexOfLargestElement);
  double[] leftStatByClasses=new double[numClasses];
  double[] rightStatByClasses=new double[numClasses];
  List<GainInfo> internalGainList=new ArrayList<GainInfo>();
  Set<String> leftCategories=config.isCategorical() ? new HashSet<String>() : null;
  for (int i=0; i < (stats.length / numClasses - 1); i++) {
    for (int j=0; j < leftStatByClasses.length; j++) {
      leftStatByClasses[j]+=stats[i * numClasses + j];
    }
    InternalEntropyInfo leftInfo=getEntropyInterInfo(leftStatByClasses);
    Predict leftPredict=new Predict(leftInfo.sumAll == 0d ? 0d : leftStatByClasses[1] / leftInfo.sumAll,leftInfo.indexOfLargestElement);
    for (int j=0; j < leftStatByClasses.length; j++) {
      rightStatByClasses[j]=statsByClasses[j] - leftStatByClasses[j];
    }
    InternalEntropyInfo rightInfo=getEntropyInterInfo(rightStatByClasses);
    Predict rightPredict=new Predict(rightInfo.sumAll == 0d ? 0d : rightStatByClasses[1] / rightInfo.sumAll,rightInfo.indexOfLargestElement);
    double gain=info.impurity - (leftInfo.sumAll / info.sumAll) * leftInfo.impurity - (rightInfo.sumAll / info.sumAll) * rightInfo.impurity;
    Split split=null;
    if (config.isCategorical()) {
      leftCategories.add(config.getBinCategory().get(i));
      split=new Split(config.getColumnNum(),FeatureType.CATEGORICAL,0d,leftCategories);
    }
 else {
      split=new Split(config.getColumnNum(),FeatureType.CONTINUOUS,config.getBinBoundary().get(i + 1),null);
    }
    internalGainList.add(new GainInfo(gain,info.impurity,predict,leftInfo.impurity,rightInfo.impurity,leftPredict,rightPredict,split));
  }
  return GainInfo.getGainInfoByMaxGain(internalGainList);
}