ztgsna function

void ztgsna(
  1. String JOB,
  2. String HOWMNY,
  3. Array<bool> SELECT_,
  4. int N,
  5. Matrix<Complex> A_,
  6. int LDA,
  7. Matrix<Complex> B_,
  8. int LDB,
  9. Matrix<Complex> VL_,
  10. int LDVL,
  11. Matrix<Complex> VR_,
  12. int LDVR,
  13. Array<double> S_,
  14. Array<double> DIF_,
  15. int MM,
  16. Box<int> M,
  17. Array<Complex> WORK_,
  18. int LWORK,
  19. Array<int> IWORK_,
  20. Box<int> INFO,
)

Implementation

void ztgsna(
  final String JOB,
  final String HOWMNY,
  final Array<bool> SELECT_,
  final int N,
  final Matrix<Complex> A_,
  final int LDA,
  final Matrix<Complex> B_,
  final int LDB,
  final Matrix<Complex> VL_,
  final int LDVL,
  final Matrix<Complex> VR_,
  final int LDVR,
  final Array<double> S_,
  final Array<double> DIF_,
  final int MM,
  final Box<int> M,
  final Array<Complex> WORK_,
  final int LWORK,
  final Array<int> IWORK_,
  final Box<int> INFO,
) {
  final A = A_.having(ld: LDA);
  final B = B_.having(ld: LDB);
  final VL = VL_.having(ld: LDVL);
  final VR = VR_.having(ld: LDVR);
  final WORK = WORK_.having();
  final IWORK = IWORK_.having();
  final SELECT = SELECT_.having();
  final S = S_.having();
  final DIF = DIF_.having();
  const ZERO = 0.0, ONE = 1.0, IDIFJB = 3;
  bool LQUERY, SOMCON, WANTBH, WANTDF, WANTS;
  int I, IFST, K, KS, LWMIN = 0, N1, N2;
  double COND, LNRM, RNRM;
  Complex YHAX, YHBX;
  final DUMMY = Array<Complex>(1), DUMMY1 = Array<Complex>(1);
  final IERR = Box(0), ILST = Box(0);
  final SCALE = Box(0.0);

  // Decode and test the input parameters

  WANTBH = lsame(JOB, 'B');
  WANTS = lsame(JOB, 'E') || WANTBH;
  WANTDF = lsame(JOB, 'V') || WANTBH;

  SOMCON = lsame(HOWMNY, 'S');

  INFO.value = 0;
  LQUERY = (LWORK == -1);

  if (!WANTS && !WANTDF) {
    INFO.value = -1;
  } else if (!lsame(HOWMNY, 'A') && !SOMCON) {
    INFO.value = -2;
  } else if (N < 0) {
    INFO.value = -4;
  } else if (LDA < max(1, N)) {
    INFO.value = -6;
  } else if (LDB < max(1, N)) {
    INFO.value = -8;
  } else if (WANTS && LDVL < N) {
    INFO.value = -10;
  } else if (WANTS && LDVR < N) {
    INFO.value = -12;
  } else {
    // Set M to the number of eigenpairs for which condition numbers
    // are required, and test MM.

    if (SOMCON) {
      M.value = 0;
      for (K = 1; K <= N; K++) {
        if (SELECT[K]) M.value++;
      }
    } else {
      M.value = N;
    }

    if (N == 0) {
      LWMIN = 1;
    } else if (lsame(JOB, 'V') || lsame(JOB, 'B')) {
      LWMIN = 2 * N * N;
    } else {
      LWMIN = N;
    }
    WORK[1] = LWMIN.toComplex();

    if (MM < M.value) {
      INFO.value = -15;
    } else if (LWORK < LWMIN && !LQUERY) {
      INFO.value = -18;
    }
  }

  if (INFO.value != 0) {
    xerbla('ZTGSNA', -INFO.value);
    return;
  } else if (LQUERY) {
    return;
  }

  // Quick return if possible

  if (N == 0) return;

  KS = 0;
  for (K = 1; K <= N; K++) {
    // Determine whether condition numbers are required for the k-th
    // eigenpair.

    if (SOMCON) {
      if (!SELECT[K]) continue;
    }

    KS++;

    if (WANTS) {
      // Compute the reciprocal condition number of the k-th
      // eigenvalue.

      RNRM = dznrm2(N, VR(1, KS).asArray(), 1);
      LNRM = dznrm2(N, VL(1, KS).asArray(), 1);
      zgemv('N', N, N, Complex.one, A, LDA, VR(1, KS).asArray(), 1,
          Complex.zero, WORK, 1);
      YHAX = zdotc(N, WORK, 1, VL(1, KS).asArray(), 1);
      zgemv('N', N, N, Complex.one, B, LDB, VR(1, KS).asArray(), 1,
          Complex.zero, WORK, 1);
      YHBX = zdotc(N, WORK, 1, VL(1, KS).asArray(), 1);
      COND = dlapy2(YHAX.abs(), YHBX.abs());
      if (COND == ZERO) {
        S[KS] = -ONE;
      } else {
        S[KS] = COND / (RNRM * LNRM);
      }
    }

    if (WANTDF) {
      if (N == 1) {
        DIF[KS] = dlapy2(A[1][1].abs(), B[1][1].abs());
      } else {
        // Estimate the reciprocal condition number of the k-th
        // eigenvectors.

        // Copy the matrix (A, B) to the array WORK and move the
        // (k,k)th pair to the (1,1) position.

        zlacpy('Full', N, N, A, LDA, WORK.asMatrix(N), N);
        zlacpy('Full', N, N, B, LDB, WORK(N * N + 1).asMatrix(N), N);
        IFST = K;
        ILST.value = 1;

        ztgexc(
            false,
            false,
            N,
            WORK.asMatrix(N),
            N,
            WORK(N * N + 1).asMatrix(N),
            N,
            DUMMY.asMatrix(1),
            1,
            DUMMY1.asMatrix(1),
            1,
            IFST,
            ILST,
            IERR);

        if (IERR.value > 0) {
          // Ill-conditioned problem - swap rejected.

          DIF[KS] = ZERO;
        } else {
          // Reordering successful, solve generalized Sylvester
          // equation for R and L,
          //            A22 * R - L * A11 = A12
          //            B22 * R - L * B11 = B12,
          // and compute estimate of Difl[(A11,B11), (A22, B22)].

          N1 = 1;
          N2 = N - N1;
          I = N * N + 1;
          ztgsyl(
              'N',
              IDIFJB,
              N2,
              N1,
              WORK(N * N1 + N1 + 1).asMatrix(N),
              N,
              WORK.asMatrix(N),
              N,
              WORK(N1 + 1).asMatrix(N),
              N,
              WORK(N * N1 + N1 + I).asMatrix(N),
              N,
              WORK(I).asMatrix(N),
              N,
              WORK(N1 + I).asMatrix(N),
              N,
              SCALE,
              DIF(KS),
              DUMMY,
              1,
              IWORK,
              IERR);
        }
      }
    }
  }
  WORK[1] = LWMIN.toComplex();
}