Program: 57114
Project: 57114
Buggy source:
/** 
 * In the original algorithm only the partial correlations of the regressors is returned to the user. In this implementation, we have <pre> corr = { corrxx - lower triangular corrxy - bottom row of the matrix } Replaces subroutines PCORR and COR of: ALGORITHM AS274  APPL. STATIST. (1992) VOL.41, NO. 2 </pre> <p>Calculate partial correlations after the variables in rows 1, 2, ..., IN have been forced into the regression. If IN = 1, and the first row of R represents a constant in the model, then the usual simple correlations are returned.</p> <p>If IN = 0, the value returned in array CORMAT for the correlation of variables Xi & Xj is: <pre> sum ( Xi.Xj ) / Sqrt ( sum (Xi^2) . sum (Xj^2) )</pre> <p>On return, array CORMAT contains the upper triangle of the matrix of partial correlations stored by rows, excluding the 1's on the diagonal. e.g. if IN = 2, the consecutive elements returned are: (3,4) (3,5) ... (3,ncol), (4,5) (4,6) ... (4,ncol), etc. Array YCORR stores the partial correlations with the Y-variable starting with YCORR(IN+1) = partial correlation with the variable in position (IN+1). </p>
 * @param in how many of the regressors to include (either in canonicalorder, or in the current reordered state)
 * @return an array with the partial correlations of the remainder ofregressors with each other and the regressand, in lower triangular form
 */
public double[] getPartialCorrelations(int in){
  final double[] output=new double[(nvars - in + 1) * (nvars - in) / 2];
  int pos;
  int pos1;
  int pos2;
  final int rms_off=-in;
  final int wrk_off=-(in + 1);
  final double[] rms=new double[nvars - in];
  final double[] work=new double[nvars - in - 1];
  double sumxx;
  double sumxy;
  double sumyy;
  final int offXX=(nvars - in) * (nvars - in - 1) / 2;
  if (in < -1 || in >= nvars) {
    return null;
  }
  final int nvm=nvars - 1;
  final int base_pos=r.length - (nvm - in) * (nvm - in + 1) / 2;
  if (d[in] > 0.0) {
    rms[in + rms_off]=1.0 / FastMath.sqrt(d[in]);
  }
  for (int col=in + 1; col < nvars; col++) {
    pos=base_pos + col - 1 - in;
    sumxx=d[col];
    for (int row=in; row < col; row++) {
      sumxx+=d[row] * r[pos] * r[pos];
      pos+=nvars - row - 2;
    }
    if (sumxx > 0.0) {
      rms[col + rms_off]=1.0 / FastMath.sqrt(sumxx);
    }
 else {
      rms[col + rms_off]=0.0;
    }
  }
  sumyy=sserr;
  for (int row=in; row < nvars; row++) {
    sumyy+=d[row] * rhs[row] * rhs[row];
  }
  if (sumyy > 0.0) {
    sumyy=1.0 / FastMath.sqrt(sumyy);
  }
  pos=0;
  for (int col1=in; col1 < nvars; col1++) {
    sumxy=0.0;
    Arrays.fill(work,0.0);
    pos1=base_pos + col1 - in - 1;
    for (int row=in; row < col1; row++) {
      pos2=pos1 + 1;
      for (int col2=col1 + 1; col2 < nvars; col2++) {
        work[col2 + wrk_off]+=d[row] * r[pos1] * r[pos2];
        pos2++;
      }
      sumxy+=d[row] * r[pos1] * rhs[row];
      pos1+=nvars - row - 2;
    }
    pos2=pos1 + 1;
    for (int col2=col1 + 1; col2 < nvars; col2++) {
      work[col2 + wrk_off]+=d[col1] * r[pos2];
      ++pos2;
      output[(col2 - 1 - in) * (col2 - in) / 2 + col1 - in]=work[col2 + wrk_off] * rms[col1 + rms_off] * rms[col2 + rms_off];
      ++pos;
    }
    sumxy+=d[col1] * rhs[col1];
    output[col1 + rms_off + offXX]=sumxy * rms[col1 + rms_off] * sumyy;
  }
  return output;
}

Fixed version (ground truth):
/** 
 * In the original algorithm only the partial correlations of the regressors is returned to the user. In this implementation, we have <pre> corr = { corrxx - lower triangular corrxy - bottom row of the matrix } Replaces subroutines PCORR and COR of: ALGORITHM AS274  APPL. STATIST. (1992) VOL.41, NO. 2 </pre> <p>Calculate partial correlations after the variables in rows 1, 2, ..., IN have been forced into the regression. If IN = 1, and the first row of R represents a constant in the model, then the usual simple correlations are returned.</p> <p>If IN = 0, the value returned in array CORMAT for the correlation of variables Xi &amp; Xj is: <pre> sum ( Xi.Xj ) / Sqrt ( sum (Xi^2) . sum (Xj^2) )</pre> <p>On return, array CORMAT contains the upper triangle of the matrix of partial correlations stored by rows, excluding the 1's on the diagonal. e.g. if IN = 2, the consecutive elements returned are: (3,4) (3,5) ... (3,ncol), (4,5) (4,6) ... (4,ncol), etc. Array YCORR stores the partial correlations with the Y-variable starting with YCORR(IN+1) = partial correlation with the variable in position (IN+1). </p>
 * @param in how many of the regressors to include (either in canonicalorder, or in the current reordered state)
 * @return an array with the partial correlations of the remainder ofregressors with each other and the regressand, in lower triangular form
 */
public double[] getPartialCorrelations(int in){
  final double[] output=new double[(nvars - in + 1) * (nvars - in) / 2];
  int pos;
  int pos1;
  int pos2;
  final int rms_off=-in;
  final int wrk_off=-(in + 1);
  final double[] rms=new double[nvars - in];
  final double[] work=new double[nvars - in - 1];
  double sumxx;
  double sumxy;
  double sumyy;
  final int offXX=(nvars - in) * (nvars - in - 1) / 2;
  if (in < -1 || in >= nvars) {
    return null;
  }
  final int nvm=nvars - 1;
  final int base_pos=r.length - (nvm - in) * (nvm - in + 1) / 2;
  if (d[in] > 0.0) {
    rms[in + rms_off]=1.0 / FastMath.sqrt(d[in]);
  }
  for (int col=in + 1; col < nvars; col++) {
    pos=base_pos + col - 1 - in;
    sumxx=d[col];
    for (int row=in; row < col; row++) {
      sumxx+=d[row] * r[pos] * r[pos];
      pos+=nvars - row - 2;
    }
    if (sumxx > 0.0) {
      rms[col + rms_off]=1.0 / FastMath.sqrt(sumxx);
    }
 else {
      rms[col + rms_off]=0.0;
    }
  }
  sumyy=sserr;
  for (int row=in; row < nvars; row++) {
    sumyy+=d[row] * rhs[row] * rhs[row];
  }
  if (sumyy > 0.0) {
    sumyy=1.0 / FastMath.sqrt(sumyy);
  }
  pos=0;
  for (int col1=in; col1 < nvars; col1++) {
    sumxy=0.0;
    Arrays.fill(work,0.0);
    pos1=base_pos + col1 - in - 1;
    for (int row=in; row < col1; row++) {
      pos2=pos1 + 1;
      for (int col2=col1 + 1; col2 < nvars; col2++) {
        work[col2 + wrk_off]+=d[row] * r[pos1] * r[pos2];
        pos2++;
      }
      sumxy+=d[row] * r[pos1] * rhs[row];
      pos1+=nvars - row - 2;
    }
    pos2=pos1 + 1;
    for (int col2=col1 + 1; col2 < nvars; col2++) {
      work[col2 + wrk_off]+=d[col1] * r[pos2];
      ++pos2;
      output[(col2 - 1 - in) * (col2 - in) / 2 + col1 - in]=work[col2 + wrk_off] * rms[col1 + rms_off] * rms[col2 + rms_off];
      ++pos;
    }
    sumxy+=d[col1] * rhs[col1];
    output[col1 + rms_off + offXX]=sumxy * rms[col1 + rms_off] * sumyy;
  }
  return output;
}