Program: 72935
Project: 72935
Buggy source:
public static final HashMap gaussianHMM(int startAt,double[] y,double[][] A,double[] mu,double[] sigma,double[] prior){
  int nStates=mu.length;
  double[][] alphas=new double[y.length][nStates];
  double[][] betas=new double[y.length][nStates];
  double[] Py=new double[y.length];
  double[][] gamma=new double[y.length][nStates];
  for (int t=0; t < y.length; t++) {
    for (int i=0; i < nStates; i++) {
      if (t == 0) {
        alphas[t][i]=prior[i] * gaussian(y[t],mu[i],sigma[i]);
      }
 else {
        alphas[t][i]=0;
        for (int qt=0; qt < nStates; qt++) {
          alphas[t][i]+=A[qt][i] * gaussian(y[t],mu[i],sigma[i]) * alphas[t - 1][qt];
        }
      }
    }
  }
  for (int t=y.length - 1; t >= 0; t--) {
    Py[t]=0;
    for (int i=0; i < nStates; i++) {
      gamma[t][i]=0.0;
      if (t == y.length - 1) {
        betas[t][i]=1;
      }
 else {
        betas[t][i]=0;
        for (int qtp=0; qtp < nStates; qtp++) {
          betas[t][i]+=A[i][qtp] * gaussian(y[t + 1],mu[qtp],sigma[qtp]) * betas[t + 1][qtp];
        }
      }
      Py[t]+=alphas[t][i] * betas[t][i];
    }
    for (int i=0; i < nStates; i++) {
      gamma[t][i]+=alphas[t][i] * betas[t][i] / Py[t];
    }
  }
  double[][][] psi=new double[y.length - 1][nStates][nStates];
  double[][] A_hat=new double[nStates][nStates];
  double[] mu_hat=new double[nStates];
  double[] s_hat=new double[nStates];
  for (int next=0; next < nStates; next++) {
    for (int now=0; now < nStates; now++) {
      for (int t=0; t < (y.length - 1); t++) {
        if (alphas[t + 1][next] == 0) {
          psi[t][now][next]=0;
        }
 else {
          psi[t][now][next]=alphas[t][now] * gaussian(y[t + 1],mu[next],sigma[next]) * gamma[t + 1][next]* A[now][next] / alphas[t + 1][next];
        }
        A_hat[now][next]+=psi[t][now][next];
      }
    }
    mu_hat[next]=0;
    s_hat[next]=0;
  }
  double[] rowsum=new double[nStates];
  double[] gammasum=new double[nStates];
  for (int i=0; i < nStates; i++) {
    rowsum[i]=0;
    for (int j=0; j < nStates; j++) {
      rowsum[i]+=A_hat[i][j];
    }
    for (int j=0; j < nStates; j++) {
      A_hat[i][j]/=rowsum[i];
    }
    gammasum[i]=0.0;
  }
  for (int j=0; j < nStates; j++) {
    gammasum[j]=0.0;
    for (int t=0; t < y.length; t++) {
      gammasum[j]+=gamma[t][j];
      mu_hat[j]+=gamma[t][j] * y[t];
    }
    mu_hat[j]=mu_hat[j] / gammasum[j];
    for (int t=0; t < y.length; t++) {
      s_hat[j]+=(gamma[t][j] * Math.pow((y[t] - mu_hat[j]),2));
    }
    s_hat[j]=Math.pow(s_hat[j] / gammasum[j],0.5);
  }
  HashMap estimates=new HashMap();
  estimates=sortEstimates(mu_hat,s_hat,A_hat);
  return estimates;
}

Fixed version (ground truth):
public static final HashMap gaussianHMM(int startAt,double[] y,double[][] A,double[] mu,double[] sigma,double[] prior){
  int nStates=mu.length;
  double[][] alphas=new double[y.length][nStates];
  double[][] betas=new double[y.length][nStates];
  double[] Py=new double[y.length];
  double[][] gamma=new double[y.length][nStates];
  for (int t=0; t < y.length; t++) {
    for (int i=0; i < nStates; i++) {
      if (t == 0) {
        alphas[t][i]=prior[i] * gaussian(y[t],mu[i],sigma[i]);
      }
 else {
        alphas[t][i]=0;
        for (int qt=0; qt < nStates; qt++) {
          alphas[t][i]+=A[qt][i] * gaussian(y[t],mu[i],sigma[i]) * alphas[t - 1][qt];
        }
      }
    }
  }
  for (int t=y.length - 1; t >= 0; t--) {
    Py[t]=0;
    for (int i=0; i < nStates; i++) {
      gamma[t][i]=0.0;
      if (t == y.length - 1) {
        betas[t][i]=1;
      }
 else {
        betas[t][i]=0;
        for (int qtp=0; qtp < nStates; qtp++) {
          betas[t][i]+=A[i][qtp] * gaussian(y[t + 1],mu[qtp],sigma[qtp]) * betas[t + 1][qtp];
        }
      }
      Py[t]+=alphas[t][i] * betas[t][i];
    }
    for (int i=0; i < nStates; i++) {
      gamma[t][i]+=alphas[t][i] * betas[t][i] / Py[t];
    }
  }
  double[][][] psi=new double[y.length - 1][nStates][nStates];
  double[][] A_hat=new double[nStates][nStates];
  double[] mu_hat=new double[nStates];
  double[] s_hat=new double[nStates];
  for (int next=0; next < nStates; next++) {
    for (int now=0; now < nStates; now++) {
      for (int t=0; t < (y.length - 1); t++) {
        if (alphas[t + 1][next] == 0) {
          psi[t][now][next]=0;
        }
 else {
          psi[t][now][next]=alphas[t][now] * gaussian(y[t + 1],mu[next],sigma[next]) * gamma[t + 1][next]* A[now][next] / alphas[t + 1][next];
        }
        A_hat[now][next]+=psi[t][now][next];
      }
    }
    mu_hat[next]=0;
    s_hat[next]=0;
  }
  double[] rowsum=new double[nStates];
  double[] gammasum=new double[nStates];
  for (int i=0; i < nStates; i++) {
    rowsum[i]=0;
    for (int j=0; j < nStates; j++) {
      rowsum[i]+=A_hat[i][j];
    }
    for (int j=0; j < nStates; j++) {
      A_hat[i][j]/=rowsum[i];
    }
    gammasum[i]=0.0;
  }
  for (int j=0; j < nStates; j++) {
    gammasum[j]=0.0;
    for (int t=0; t < y.length; t++) {
      gammasum[j]+=gamma[t][j];
      mu_hat[j]+=gamma[t][j] * y[t];
    }
    mu_hat[j]=mu_hat[j] / gammasum[j];
    for (int t=0; t < y.length; t++) {
      s_hat[j]+=(gamma[t][j] * Math.pow((y[t] - mu_hat[j]),2));
    }
    s_hat[j]=Math.sqrt(s_hat[j] / gammasum[j]);
  }
  HashMap estimates=new HashMap();
  estimates=sortEstimates(mu_hat,s_hat,A_hat);
  return estimates;
}