dlarfg function

void dlarfg(
  1. int N,
  2. Box<double> ALPHA,
  3. Array<double> X_,
  4. int INCX,
  5. Box<double> TAU,
)

Implementation

void dlarfg(
  final int N,
  final Box<double> ALPHA,
  final Array<double> X_,
  final int INCX,
  final Box<double> TAU,
) {
  final X = X_.having();
  const ONE = 1.0, ZERO = 0.0;
  int J, KNT = 0;
  double BETA = 0, RSAFMN = 0, SAFMIN = 0, XNORM;

  if (N <= 1) {
    TAU.value = ZERO;
    return;
  }

  XNORM = dnrm2(N - 1, X, INCX);

  if (XNORM == ZERO) {
    // H  =  I
    TAU.value = ZERO;
    return;
  }

  // general case

  BETA = -sign(dlapy2(ALPHA.value, XNORM), ALPHA.value);
  SAFMIN = dlamch('S') / dlamch('E');
  KNT = 0;
  if (BETA.abs() < SAFMIN) {
    // XNORM, BETA may be inaccurate; scale X and recompute them

    RSAFMN = ONE / SAFMIN;
    do {
      KNT++;
      dscal(N - 1, RSAFMN, X, INCX);
      BETA *= RSAFMN;
      ALPHA.value *= RSAFMN;
    } while ((BETA.abs() < SAFMIN) && (KNT < 20));

    // New BETA is at most 1, at least SAFMIN

    XNORM = dnrm2(N - 1, X, INCX);
    BETA = -sign(dlapy2(ALPHA.value, XNORM), ALPHA.value);
  }
  TAU.value = (BETA - ALPHA.value) / BETA;
  dscal(N - 1, ONE / (ALPHA.value - BETA), X, INCX);

  // If ALPHA is subnormal, it may lose relative accuracy

  for (J = 1; J <= KNT; J++) {
    BETA *= SAFMIN;
  }
  ALPHA.value = BETA;
}