Program: 20190
Project: 20190
Buggy source:
/** 
 * Use Gibbs sampling to infer a topic distribution. Topics are initialized to the (or a) most probable topic for each token. Using zero iterations returns exactly this initial topic distribution.<p/> This code does not adjust type-topic counts: P(w|t) is clamped.
 */
public double[] getSampledDistribution(Instance instance,int numIterations,int thinning,int burnIn){
  FeatureSequence tokens=(FeatureSequence)instance.getData();
  int docLength=tokens.size();
  int[] topics=new int[docLength];
  int[] localTopicCounts=new int[numTopics];
  int[] localTopicIndex=new int[numTopics];
  int type;
  int[] currentTypeTopicCounts;
  for (int position=0; position < docLength; position++) {
    type=tokens.getIndexAtPosition(position);
    if (type < numTypes) {
      currentTypeTopicCounts=typeTopicCounts[type];
      topics[position]=currentTypeTopicCounts[0] & topicMask;
      localTopicCounts[topics[position]]++;
    }
  }
  int denseIndex=0;
  for (int topic=0; topic < numTopics; topic++) {
    if (localTopicCounts[topic] != 0) {
      localTopicIndex[denseIndex]=topic;
      denseIndex++;
    }
  }
  int nonZeroTopics=denseIndex;
  double topicBetaMass=0.0;
  for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
    int topic=localTopicIndex[denseIndex];
    int n=localTopicCounts[topic];
    topicBetaMass+=beta * n / (tokensPerTopic[topic] + betaSum);
    cachedCoefficients[topic]=(alpha[topic] + n) / (tokensPerTopic[topic] + betaSum);
  }
  double topicTermMass=0.0;
  double[] topicTermScores=new double[numTopics];
  int[] topicTermIndices;
  int[] topicTermValues;
  int i;
  double score;
  int oldTopic, newTopic;
  double[] result=new double[numTopics];
  double sum=0.0;
  for (int iteration=1; iteration <= numIterations; iteration++) {
    for (int position=0; position < docLength; position++) {
      type=tokens.getIndexAtPosition(position);
      if (type >= numTypes) {
        continue;
      }
      oldTopic=topics[position];
      currentTypeTopicCounts=typeTopicCounts[type];
      topicBetaMass-=beta * localTopicCounts[oldTopic] / (tokensPerTopic[oldTopic] + betaSum);
      localTopicCounts[oldTopic]--;
      if (localTopicCounts[oldTopic] == 0) {
        denseIndex=0;
        while (localTopicIndex[denseIndex] != oldTopic) {
          denseIndex++;
        }
        while (denseIndex < nonZeroTopics) {
          if (denseIndex < localTopicIndex.length - 1) {
            localTopicIndex[denseIndex]=localTopicIndex[denseIndex + 1];
          }
          denseIndex++;
        }
        nonZeroTopics--;
      }
      topicBetaMass+=beta * localTopicCounts[oldTopic] / (tokensPerTopic[oldTopic] + betaSum);
      cachedCoefficients[oldTopic]=(alpha[oldTopic] + localTopicCounts[oldTopic]) / (tokensPerTopic[oldTopic] + betaSum);
      if (cachedCoefficients[oldTopic] <= 0) {
        System.out.println("String_Node_Str" + oldTopic + "String_Node_Str"+ alpha[oldTopic]+ "String_Node_Str"+ localTopicCounts[oldTopic]+ "String_Node_Str"+ tokensPerTopic[oldTopic]+ "String_Node_Str"+ betaSum+ "String_Node_Str");
      }
      int index=0;
      int currentTopic, currentValue;
      boolean alreadyDecremented=false;
      topicTermMass=0.0;
      while (index < currentTypeTopicCounts.length && currentTypeTopicCounts[index] > 0) {
        currentTopic=currentTypeTopicCounts[index] & topicMask;
        currentValue=currentTypeTopicCounts[index] >> topicBits;
        score=cachedCoefficients[currentTopic] * currentValue;
        topicTermMass+=score;
        topicTermScores[index]=score;
        index++;
      }
      double sample=random.nextUniform() * (smoothingOnlyMass + topicBetaMass + topicTermMass);
      double origSample=sample;
      newTopic=-1;
      if (sample < topicTermMass) {
        i=-1;
        while (sample > 0) {
          i++;
          sample-=topicTermScores[i];
        }
        newTopic=currentTypeTopicCounts[i] & topicMask;
      }
 else {
        sample-=topicTermMass;
        if (sample < topicBetaMass) {
          sample/=beta;
          for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
            int topic=localTopicIndex[denseIndex];
            sample-=localTopicCounts[topic] / (tokensPerTopic[topic] + betaSum);
            if (sample <= 0.0) {
              newTopic=topic;
              break;
            }
          }
        }
 else {
          sample-=topicBetaMass;
          sample/=beta;
          newTopic=0;
          sample-=alpha[newTopic] / (tokensPerTopic[newTopic] + betaSum);
          while (sample > 0.0) {
            newTopic++;
            if (newTopic >= numTopics) {
              index=0;
              while (index < currentTypeTopicCounts.length && currentTypeTopicCounts[index] > 0) {
                currentTopic=currentTypeTopicCounts[index] & topicMask;
                currentValue=currentTypeTopicCounts[index] >> topicBits;
                System.out.println(currentTopic + "String_Node_Str" + currentValue+ "String_Node_Str"+ topicTermScores[index]+ "String_Node_Str"+ cachedCoefficients[currentTopic]);
                index++;
              }
            }
            sample-=alpha[newTopic] / (tokensPerTopic[newTopic] + betaSum);
          }
        }
      }
      topics[position]=newTopic;
      topicBetaMass-=beta * localTopicCounts[newTopic] / (tokensPerTopic[newTopic] + betaSum);
      localTopicCounts[newTopic]++;
      if (localTopicCounts[newTopic] == 1) {
        denseIndex=nonZeroTopics;
        while (denseIndex > 0 && localTopicIndex[denseIndex - 1] > newTopic) {
          localTopicIndex[denseIndex]=localTopicIndex[denseIndex - 1];
          denseIndex--;
        }
        localTopicIndex[denseIndex]=newTopic;
        nonZeroTopics++;
      }
      cachedCoefficients[newTopic]=(alpha[newTopic] + localTopicCounts[newTopic]) / (tokensPerTopic[newTopic] + betaSum);
      topicBetaMass+=beta * localTopicCounts[newTopic] / (tokensPerTopic[newTopic] + betaSum);
    }
    if (iteration > burnIn && (iteration - burnIn) % thinning == 0) {
      for (int topic=0; topic < numTopics; topic++) {
        result[topic]+=alpha[topic] + localTopicCounts[topic];
        sum+=alpha[topic] + localTopicCounts[topic];
      }
    }
  }
  for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
    int topic=localTopicIndex[denseIndex];
    cachedCoefficients[topic]=alpha[topic] / (tokensPerTopic[topic] + betaSum);
  }
  if (sum == 0.0) {
    for (int topic=0; topic < numTopics; topic++) {
      result[topic]=alpha[topic] + localTopicCounts[topic];
      sum+=result[topic];
    }
  }
  for (int topic=0; topic < numTopics; topic++) {
    result[topic]/=sum;
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Use Gibbs sampling to infer a topic distribution. Topics are initialized to the (or a) most probable topic for each token. Using zero iterations returns exactly this initial topic distribution.<p/> This code does not adjust type-topic counts: P(w|t) is clamped.
 */
public double[] getSampledDistribution(Instance instance,int numIterations,int thinning,int burnIn){
  FeatureSequence tokens=(FeatureSequence)instance.getData();
  int docLength=tokens.size();
  int[] topics=new int[docLength];
  int[] localTopicCounts=new int[numTopics];
  int[] localTopicIndex=new int[numTopics];
  int type;
  int[] currentTypeTopicCounts;
  for (int position=0; position < docLength; position++) {
    type=tokens.getIndexAtPosition(position);
    if (type < numTypes && typeTopicCounts[type].length != 0) {
      currentTypeTopicCounts=typeTopicCounts[type];
      topics[position]=currentTypeTopicCounts[0] & topicMask;
      localTopicCounts[topics[position]]++;
    }
  }
  int denseIndex=0;
  for (int topic=0; topic < numTopics; topic++) {
    if (localTopicCounts[topic] != 0) {
      localTopicIndex[denseIndex]=topic;
      denseIndex++;
    }
  }
  int nonZeroTopics=denseIndex;
  double topicBetaMass=0.0;
  for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
    int topic=localTopicIndex[denseIndex];
    int n=localTopicCounts[topic];
    topicBetaMass+=beta * n / (tokensPerTopic[topic] + betaSum);
    cachedCoefficients[topic]=(alpha[topic] + n) / (tokensPerTopic[topic] + betaSum);
  }
  double topicTermMass=0.0;
  double[] topicTermScores=new double[numTopics];
  int[] topicTermIndices;
  int[] topicTermValues;
  int i;
  double score;
  int oldTopic, newTopic;
  double[] result=new double[numTopics];
  double sum=0.0;
  for (int iteration=1; iteration <= numIterations; iteration++) {
    for (int position=0; position < docLength; position++) {
      type=tokens.getIndexAtPosition(position);
      if (type >= numTypes || typeTopicCounts[type].length == 0) {
        continue;
      }
      oldTopic=topics[position];
      currentTypeTopicCounts=typeTopicCounts[type];
      topicBetaMass-=beta * localTopicCounts[oldTopic] / (tokensPerTopic[oldTopic] + betaSum);
      localTopicCounts[oldTopic]--;
      if (localTopicCounts[oldTopic] == 0) {
        denseIndex=0;
        while (localTopicIndex[denseIndex] != oldTopic) {
          denseIndex++;
        }
        while (denseIndex < nonZeroTopics) {
          if (denseIndex < localTopicIndex.length - 1) {
            localTopicIndex[denseIndex]=localTopicIndex[denseIndex + 1];
          }
          denseIndex++;
        }
        nonZeroTopics--;
      }
      topicBetaMass+=beta * localTopicCounts[oldTopic] / (tokensPerTopic[oldTopic] + betaSum);
      cachedCoefficients[oldTopic]=(alpha[oldTopic] + localTopicCounts[oldTopic]) / (tokensPerTopic[oldTopic] + betaSum);
      if (cachedCoefficients[oldTopic] <= 0) {
        System.out.println("String_Node_Str" + oldTopic + "String_Node_Str"+ alpha[oldTopic]+ "String_Node_Str"+ localTopicCounts[oldTopic]+ "String_Node_Str"+ tokensPerTopic[oldTopic]+ "String_Node_Str"+ betaSum+ "String_Node_Str");
      }
      int index=0;
      int currentTopic, currentValue;
      boolean alreadyDecremented=false;
      topicTermMass=0.0;
      while (index < currentTypeTopicCounts.length && currentTypeTopicCounts[index] > 0) {
        currentTopic=currentTypeTopicCounts[index] & topicMask;
        currentValue=currentTypeTopicCounts[index] >> topicBits;
        score=cachedCoefficients[currentTopic] * currentValue;
        topicTermMass+=score;
        topicTermScores[index]=score;
        index++;
      }
      double sample=random.nextUniform() * (smoothingOnlyMass + topicBetaMass + topicTermMass);
      double origSample=sample;
      newTopic=-1;
      if (sample < topicTermMass) {
        i=-1;
        while (sample > 0) {
          i++;
          sample-=topicTermScores[i];
        }
        newTopic=currentTypeTopicCounts[i] & topicMask;
      }
 else {
        sample-=topicTermMass;
        if (sample < topicBetaMass) {
          sample/=beta;
          for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
            int topic=localTopicIndex[denseIndex];
            sample-=localTopicCounts[topic] / (tokensPerTopic[topic] + betaSum);
            if (sample <= 0.0) {
              newTopic=topic;
              break;
            }
          }
        }
 else {
          sample-=topicBetaMass;
          sample/=beta;
          newTopic=0;
          sample-=alpha[newTopic] / (tokensPerTopic[newTopic] + betaSum);
          while (sample > 0.0) {
            newTopic++;
            if (newTopic >= numTopics) {
              index=0;
              while (index < currentTypeTopicCounts.length && currentTypeTopicCounts[index] > 0) {
                currentTopic=currentTypeTopicCounts[index] & topicMask;
                currentValue=currentTypeTopicCounts[index] >> topicBits;
                System.out.println(currentTopic + "String_Node_Str" + currentValue+ "String_Node_Str"+ topicTermScores[index]+ "String_Node_Str"+ cachedCoefficients[currentTopic]);
                index++;
              }
            }
            sample-=alpha[newTopic] / (tokensPerTopic[newTopic] + betaSum);
          }
        }
      }
      topics[position]=newTopic;
      topicBetaMass-=beta * localTopicCounts[newTopic] / (tokensPerTopic[newTopic] + betaSum);
      localTopicCounts[newTopic]++;
      if (localTopicCounts[newTopic] == 1) {
        denseIndex=nonZeroTopics;
        while (denseIndex > 0 && localTopicIndex[denseIndex - 1] > newTopic) {
          localTopicIndex[denseIndex]=localTopicIndex[denseIndex - 1];
          denseIndex--;
        }
        localTopicIndex[denseIndex]=newTopic;
        nonZeroTopics++;
      }
      cachedCoefficients[newTopic]=(alpha[newTopic] + localTopicCounts[newTopic]) / (tokensPerTopic[newTopic] + betaSum);
      topicBetaMass+=beta * localTopicCounts[newTopic] / (tokensPerTopic[newTopic] + betaSum);
    }
    if (iteration > burnIn && (iteration - burnIn) % thinning == 0) {
      for (int topic=0; topic < numTopics; topic++) {
        result[topic]+=alpha[topic] + localTopicCounts[topic];
        sum+=alpha[topic] + localTopicCounts[topic];
      }
    }
  }
  for (denseIndex=0; denseIndex < nonZeroTopics; denseIndex++) {
    int topic=localTopicIndex[denseIndex];
    cachedCoefficients[topic]=alpha[topic] / (tokensPerTopic[topic] + betaSum);
  }
  if (sum == 0.0) {
    for (int topic=0; topic < numTopics; topic++) {
      result[topic]=alpha[topic] + localTopicCounts[topic];
      sum+=result[topic];
    }
  }
  for (int topic=0; topic < numTopics; topic++) {
    result[topic]/=sum;
  }
  return result;
}