dlasd0 function

void dlasd0(
  1. int N,
  2. int SQRE,
  3. Array<double> D_,
  4. Array<double> E_,
  5. Matrix<double> U_,
  6. int LDU,
  7. Matrix<double> VT_,
  8. int LDVT,
  9. int SMLSIZ,
  10. Array<int> IWORK_,
  11. Array<double> WORK_,
  12. Box<int> INFO,
)

Implementation

void dlasd0(
  final int N,
  final int SQRE,
  final Array<double> D_,
  final Array<double> E_,
  final Matrix<double> U_,
  final int LDU,
  final Matrix<double> VT_,
  final int LDVT,
  final int SMLSIZ,
  final Array<int> IWORK_,
  final Array<double> WORK_,
  final Box<int> INFO,
) {
  final D = D_.having();
  final E = E_.having();
  final U = U_.having(ld: LDU);
  final VT = VT_.having(ld: LDVT);
  final IWORK = IWORK_.having();
  final WORK = WORK_.having();
  int I,
      I1,
      IC,
      IDXQ,
      IDXQC,
      IM1,
      INODE,
      ITEMP,
      IWK,
      J,
      LF,
      LL,
      LVL,
      M,
      NCC,
      NDB1,
      NDIML,
      NDIMR,
      NL,
      NLF,
      NLP1,
      NR,
      NRF,
      NRP1,
      SQREI;
  final ALPHA = Box(0.0), BETA = Box(0.0);
  final ND = Box(0), NLVL = Box(0);

  // Test the input parameters.

  INFO.value = 0;

  if (N < 0) {
    INFO.value = -1;
  } else if ((SQRE < 0) || (SQRE > 1)) {
    INFO.value = -2;
  }

  M = N + SQRE;

  if (LDU < N) {
    INFO.value = -6;
  } else if (LDVT < M) {
    INFO.value = -8;
  } else if (SMLSIZ < 3) {
    INFO.value = -9;
  }
  if (INFO.value != 0) {
    xerbla('DLASD0', -INFO.value);
    return;
  }

  // If the input matrix is too small, call DLASDQ to find the SVD.

  if (N <= SMLSIZ) {
    dlasdq('U', SQRE, N, M, N, 0, D, E, VT, LDVT, U, LDU, U, LDU, WORK, INFO);
    return;
  }

  // Set up the computation tree.

  INODE = 1;
  NDIML = INODE + N;
  NDIMR = NDIML + N;
  IDXQ = NDIMR + N;
  IWK = IDXQ + N;
  dlasdt(N, NLVL, ND, IWORK(INODE), IWORK(NDIML), IWORK(NDIMR), SMLSIZ);

  // For the nodes on bottom level of the tree, solve
  // their subproblems by DLASDQ.

  NDB1 = (ND.value + 1) ~/ 2;
  NCC = 0;
  for (I = NDB1; I <= ND.value; I++) {
    // IC : center row of each node
    // NL : number of rows of left  subproblem
    // NR : number of rows of right subproblem
    // NLF: starting row of the left   subproblem
    // NRF: starting row of the right  subproblem

    I1 = I - 1;
    IC = IWORK[INODE + I1];
    NL = IWORK[NDIML + I1];
    NLP1 = NL + 1;
    NR = IWORK[NDIMR + I1];
    NRP1 = NR + 1;
    NLF = IC - NL;
    NRF = IC + 1;
    SQREI = 1;
    dlasdq('U', SQREI, NL, NLP1, NL, NCC, D(NLF), E(NLF), VT(NLF, NLF), LDVT,
        U(NLF, NLF), LDU, U(NLF, NLF), LDU, WORK, INFO);
    if (INFO.value != 0) {
      return;
    }
    ITEMP = IDXQ + NLF - 2;
    for (J = 1; J <= NL; J++) {
      IWORK[ITEMP + J] = J;
    }
    if (I == ND.value) {
      SQREI = SQRE;
    } else {
      SQREI = 1;
    }
    NRP1 = NR + SQREI;
    dlasdq('U', SQREI, NR, NRP1, NR, NCC, D(NRF), E(NRF), VT(NRF, NRF), LDVT,
        U(NRF, NRF), LDU, U(NRF, NRF), LDU, WORK, INFO);
    if (INFO.value != 0) {
      return;
    }
    ITEMP = IDXQ + IC;
    for (J = 1; J <= NR; J++) {
      IWORK[ITEMP + J - 1] = J;
    }
  }

  // Now conquer each subproblem bottom-up.

  for (LVL = NLVL.value; LVL >= 1; LVL--) {
    // Find the first node LF and last node LL on the
    // current level LVL.

    if (LVL == 1) {
      LF = 1;
      LL = 1;
    } else {
      LF = pow(2, LVL - 1).toInt();
      LL = 2 * LF - 1;
    }
    for (I = LF; I <= LL; I++) {
      IM1 = I - 1;
      IC = IWORK[INODE + IM1];
      NL = IWORK[NDIML + IM1];
      NR = IWORK[NDIMR + IM1];
      NLF = IC - NL;
      if ((SQRE == 0) && (I == LL)) {
        SQREI = SQRE;
      } else {
        SQREI = 1;
      }
      IDXQC = IDXQ + NLF - 1;
      ALPHA.value = D[IC];
      BETA.value = E[IC];
      dlasd1(NL, NR, SQREI, D(NLF), ALPHA, BETA, U(NLF, NLF), LDU, VT(NLF, NLF),
          LDVT, IWORK(IDXQC), IWORK(IWK), WORK, INFO);

      // Report the possible convergence failure.

      if (INFO.value != 0) {
        return;
      }
    }
  }
}