dlasdq function

void dlasdq(
  1. String UPLO,
  2. int SQRE,
  3. int N,
  4. int NCVT,
  5. int NRU,
  6. int NCC,
  7. Array<double> D_,
  8. Array<double> E_,
  9. Matrix<double> VT_,
  10. int LDVT,
  11. Matrix<double> U_,
  12. int LDU,
  13. Matrix<double> C_,
  14. int LDC,
  15. Array<double> WORK_,
  16. Box<int> INFO,
)

Implementation

void dlasdq(
  final String UPLO,
  final int SQRE,
  final int N,
  final int NCVT,
  final int NRU,
  final int NCC,
  final Array<double> D_,
  final Array<double> E_,
  final Matrix<double> VT_,
  final int LDVT,
  final Matrix<double> U_,
  final int LDU,
  final Matrix<double> C_,
  final int LDC,
  final Array<double> WORK_,
  final Box<int> INFO,
) {
  final D = D_.having();
  final E = E_.having();
  final VT = VT_.having(ld: LDVT);
  final U = U_.having(ld: LDU);
  final C = C_.having(ld: LDC);
  final WORK = WORK_.having();
  const ZERO = 0.0;
  bool ROTATE;
  int I, ISUB, IUPLO, J, NP1, SQRE1;
  double SMIN;
  final CS = Box(0.0), R = Box(0.0), SN = Box(0.0);

  // Test the input parameters.

  INFO.value = 0;
  IUPLO = 0;
  if (lsame(UPLO, 'U')) IUPLO = 1;
  if (lsame(UPLO, 'L')) IUPLO = 2;
  if (IUPLO == 0) {
    INFO.value = -1;
  } else if ((SQRE < 0) || (SQRE > 1)) {
    INFO.value = -2;
  } else if (N < 0) {
    INFO.value = -3;
  } else if (NCVT < 0) {
    INFO.value = -4;
  } else if (NRU < 0) {
    INFO.value = -5;
  } else if (NCC < 0) {
    INFO.value = -6;
  } else if ((NCVT == 0 && LDVT < 1) || (NCVT > 0 && LDVT < max(1, N))) {
    INFO.value = -10;
  } else if (LDU < max(1, NRU)) {
    INFO.value = -12;
  } else if ((NCC == 0 && LDC < 1) || (NCC > 0 && LDC < max(1, N))) {
    INFO.value = -14;
  }
  if (INFO.value != 0) {
    xerbla('DLASDQ', -INFO.value);
    return;
  }
  if (N == 0) return;

  // ROTATE is true if any singular vectors desired, false otherwise

  ROTATE = (NCVT > 0) || (NRU > 0) || (NCC > 0);
  NP1 = N + 1;
  SQRE1 = SQRE;

  // If matrix non-square upper bidiagonal, rotate to be lower
  // bidiagonal.  The rotations are on the right.

  if ((IUPLO == 1) && (SQRE1 == 1)) {
    for (I = 1; I <= N - 1; I++) {
      dlartg(D[I], E[I], CS, SN, R);
      D[I] = R.value;
      E[I] = SN.value * D[I + 1];
      D[I + 1] = CS.value * D[I + 1];
      if (ROTATE) {
        WORK[I] = CS.value;
        WORK[N + I] = SN.value;
      }
    }
    dlartg(D[N], E[N], CS, SN, R);
    D[N] = R.value;
    E[N] = ZERO;
    if (ROTATE) {
      WORK[N] = CS.value;
      WORK[N + N] = SN.value;
    }
    IUPLO = 2;
    SQRE1 = 0;

    // Update singular vectors if desired.

    if (NCVT > 0) dlasr('L', 'V', 'F', NP1, NCVT, WORK(1), WORK(NP1), VT, LDVT);
  }

  // If matrix lower bidiagonal, rotate to be upper bidiagonal
  // by applying Givens rotations on the left.

  if (IUPLO == 2) {
    for (I = 1; I <= N - 1; I++) {
      dlartg(D[I], E[I], CS, SN, R);
      D[I] = R.value;
      E[I] = SN.value * D[I + 1];
      D[I + 1] = CS.value * D[I + 1];
      if (ROTATE) {
        WORK[I] = CS.value;
        WORK[N + I] = SN.value;
      }
    }

    // If matrix (N+1)-by-N lower bidiagonal, one additional
    // rotation is needed.

    if (SQRE1 == 1) {
      dlartg(D[N], E[N], CS, SN, R);
      D[N] = R.value;
      if (ROTATE) {
        WORK[N] = CS.value;
        WORK[N + N] = SN.value;
      }
    }

    // Update singular vectors if desired.

    if (NRU > 0) {
      if (SQRE1 == 0) {
        dlasr('R', 'V', 'F', NRU, N, WORK(1), WORK(NP1), U, LDU);
      } else {
        dlasr('R', 'V', 'F', NRU, NP1, WORK(1), WORK(NP1), U, LDU);
      }
    }
    if (NCC > 0) {
      if (SQRE1 == 0) {
        dlasr('L', 'V', 'F', N, NCC, WORK(1), WORK(NP1), C, LDC);
      } else {
        dlasr('L', 'V', 'F', NP1, NCC, WORK(1), WORK(NP1), C, LDC);
      }
    }
  }

  // Call DBDSQR to compute the SVD of the reduced real
  // N-by-N upper bidiagonal matrix.

  dbdsqr('U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C, LDC, WORK, INFO);

  // Sort the singular values into ascending order (insertion sort on
  // singular values, but only one transposition per singular vector)

  for (I = 1; I <= N; I++) {
    // Scan for smallest D(I).

    ISUB = I;
    SMIN = D[I];
    for (J = I + 1; J <= N; J++) {
      if (D[J] < SMIN) {
        ISUB = J;
        SMIN = D[J];
      }
    }
    if (ISUB != I) {
      // Swap singular values and vectors.

      D[ISUB] = D[I];
      D[I] = SMIN;
      if (NCVT > 0) {
        dswap(NCVT, VT(ISUB, 1).asArray(), LDVT, VT(I, 1).asArray(), LDVT);
      }
      if (NRU > 0) dswap(NRU, U(1, ISUB).asArray(), 1, U(1, I).asArray(), 1);
      if (NCC > 0) {
        dswap(NCC, C(ISUB, 1).asArray(), LDC, C(I, 1).asArray(), LDC);
      }
    }
  }
}