dlagv2 function

void dlagv2(
  1. Matrix<double> A_,
  2. int LDA,
  3. Matrix<double> B_,
  4. int LDB,
  5. Array<double> ALPHAR_,
  6. Array<double> ALPHAI_,
  7. Array<double> BETA_,
  8. Box<double> CSL,
  9. Box<double> SNL,
  10. Box<double> CSR,
  11. Box<double> SNR,
)

Implementation

void dlagv2(
  final Matrix<double> A_,
  final int LDA,
  final Matrix<double> B_,
  final int LDB,
  final Array<double> ALPHAR_,
  final Array<double> ALPHAI_,
  final Array<double> BETA_,
  final Box<double> CSL,
  final Box<double> SNL,
  final Box<double> CSR,
  final Box<double> SNR,
) {
  final A = A_.having(ld: LDA);
  final B = B_.having(ld: LDB);
  final ALPHAR = ALPHAR_.having();
  final ALPHAI = ALPHAI_.having();
  final BETA = BETA_.having();
  const ZERO = 0.0, ONE = 1.0;
  double ANORM, ASCALE, BNORM, BSCALE, H1, H2, H3, QQ, RR, SAFMIN = 0, ULP;
  final R = Box(0.0),
      T = Box(0.0),
      SCALE1 = Box(0.0),
      SCALE2 = Box(0.0),
      WI = Box(0.0),
      WR1 = Box(0.0),
      WR2 = Box(0.0);

  SAFMIN = dlamch('S');
  ULP = dlamch('P');

  // Scale A

  ANORM = max(max(A[1][1].abs() + A[2][1].abs(), A[1][2].abs() + A[2][2].abs()),
      SAFMIN);
  ASCALE = ONE / ANORM;
  A[1][1] = ASCALE * A[1][1];
  A[1][2] = ASCALE * A[1][2];
  A[2][1] = ASCALE * A[2][1];
  A[2][2] = ASCALE * A[2][2];

  // Scale B

  BNORM = max(max(B[1][1].abs(), B[1][2].abs() + B[2][2].abs()), SAFMIN);
  BSCALE = ONE / BNORM;
  B[1][1] = BSCALE * B[1][1];
  B[1][2] = BSCALE * B[1][2];
  B[2][2] = BSCALE * B[2][2];

  // Check if A can be deflated

  if (A[2][1].abs() <= ULP) {
    CSL.value = ONE;
    SNL.value = ZERO;
    CSR.value = ONE;
    SNR.value = ZERO;
    A[2][1] = ZERO;
    B[2][1] = ZERO;
    WI.value = ZERO;

    // Check if B is singular
  } else if (B[1][1].abs() <= ULP) {
    dlartg(A[1][1], A[2][1], CSL, SNL, R);
    CSR.value = ONE;
    SNR.value = ZERO;
    drot(2, A(1, 1).asArray(), LDA, A(2, 1).asArray(), LDA, CSL.value,
        SNL.value);
    drot(2, B(1, 1).asArray(), LDB, B(2, 1).asArray(), LDB, CSL.value,
        SNL.value);
    A[2][1] = ZERO;
    B[1][1] = ZERO;
    B[2][1] = ZERO;
    WI.value = ZERO;
  } else if (B[2][2].abs() <= ULP) {
    dlartg(A[2][2], A[2][1], CSR, SNR, T);
    SNR.value = -SNR.value;
    drot(2, A(1, 1).asArray(), 1, A(1, 2).asArray(), 1, CSR.value, SNR.value);
    drot(2, B(1, 1).asArray(), 1, B(1, 2).asArray(), 1, CSR.value, SNR.value);
    CSL.value = ONE;
    SNL.value = ZERO;
    A[2][1] = ZERO;
    B[2][1] = ZERO;
    B[2][2] = ZERO;
    WI.value = ZERO;
  } else {
    // B is nonsingular, first compute the eigenvalues of (A,B)

    dlag2(A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1, WR2, WI);

    if (WI.value == ZERO) {
      // two real eigenvalues, compute s*A-w*B

      H1 = SCALE1.value * A[1][1] - WR1.value * B[1][1];
      H2 = SCALE1.value * A[1][2] - WR1.value * B[1][2];
      H3 = SCALE1.value * A[2][2] - WR1.value * B[2][2];

      RR = dlapy2(H1, H2);
      QQ = dlapy2(SCALE1.value * A[2][1], H3);

      if (RR > QQ) {
        // find right rotation matrix to zero 1,1 element of
        // (sA - wB)

        dlartg(H2, H1, CSR, SNR, T);
      } else {
        // find right rotation matrix to zero 2,1 element of
        // (sA - wB)

        dlartg(H3, SCALE1.value * A[2][1], CSR, SNR, T);
      }

      SNR.value = -SNR.value;
      drot(2, A(1, 1).asArray(), 1, A(1, 2).asArray(), 1, CSR.value, SNR.value);
      drot(2, B(1, 1).asArray(), 1, B(1, 2).asArray(), 1, CSR.value, SNR.value);

      // compute inf norms of A and B

      H1 = max(A[1][1].abs() + A[1][2].abs(), A[2][1].abs() + A[2][2].abs());

      H2 = max(B[1][1].abs() + B[1][2].abs(), B[2][1].abs() + B[2][2].abs());

      if ((SCALE1.value * H1) >= WR1.value.abs() * H2) {
        // find left rotation matrix Q to zero out B(2,1)

        dlartg(B[1][1], B[2][1], CSL, SNL, R);
      } else {
        // find left rotation matrix Q to zero out A(2,1)

        dlartg(A[1][1], A[2][1], CSL, SNL, R);
      }

      drot(2, A(1, 1).asArray(), LDA, A(2, 1).asArray(), LDA, CSL.value,
          SNL.value);
      drot(2, B(1, 1).asArray(), LDB, B(2, 1).asArray(), LDB, CSL.value,
          SNL.value);

      A[2][1] = ZERO;
      B[2][1] = ZERO;
    } else {
      // a pair of complex conjugate eigenvalues
      // first compute the SVD of the matrix B

      dlasv2(B[1][1], B[1][2], B[2][2], R, T, SNR, CSR, SNL, CSL);

      // Form (A,B) := Q(A,B)Z**T where Q is left rotation matrix and
      // Z is right rotation matrix computed from DLASV2

      drot(2, A(1, 1).asArray(), LDA, A(2, 1).asArray(), LDA, CSL.value,
          SNL.value);
      drot(2, B(1, 1).asArray(), LDB, B(2, 1).asArray(), LDB, CSL.value,
          SNL.value);
      drot(2, A(1, 1).asArray(), 1, A(1, 2).asArray(), 1, CSR.value, SNR.value);
      drot(2, B(1, 1).asArray(), 1, B(1, 2).asArray(), 1, CSR.value, SNR.value);

      B[2][1] = ZERO;
      B[1][2] = ZERO;
    }
  }

  // Unscaling

  A[1][1] = ANORM * A[1][1];
  A[2][1] = ANORM * A[2][1];
  A[1][2] = ANORM * A[1][2];
  A[2][2] = ANORM * A[2][2];
  B[1][1] = BNORM * B[1][1];
  B[2][1] = BNORM * B[2][1];
  B[1][2] = BNORM * B[1][2];
  B[2][2] = BNORM * B[2][2];

  if (WI.value == ZERO) {
    ALPHAR[1] = A[1][1];
    ALPHAR[2] = A[2][2];
    ALPHAI[1] = ZERO;
    ALPHAI[2] = ZERO;
    BETA[1] = B[1][1];
    BETA[2] = B[2][2];
  } else {
    ALPHAR[1] = ANORM * WR1.value / SCALE1.value / BNORM;
    ALPHAI[1] = ANORM * WI.value / SCALE1.value / BNORM;
    ALPHAR[2] = ALPHAR[1];
    ALPHAI[2] = -ALPHAI[1];
    BETA[1] = ONE;
    BETA[2] = ONE;
  }
}