Skip Navigation Links
Numerical Libraries
Linear Algebra
Differential Equations
Optimization
Samples
Skip Navigation Links
Linear Algebra
CSLapack
CSBlas
   1:  #region Translated by Jose Antonio De Santiago-Castillo.
   2:   
   3:  //Translated by Jose Antonio De Santiago-Castillo. 
   4:  //E-mail:JAntonioDeSantiago@gmail.com
   5:  //Web: www.DotNumerics.com
   6:  //
   7:  //Fortran to C# Translation.
   8:  //Translated by:
   9:  //F2CSharp Version 0.71 (November 10, 2009)
  10:  //Code Optimizations: None
  11:  //
  12:  #endregion
  13:   
  14:  using System;
  15:  using DotNumerics.FortranLibrary;
  16:   
  17:  namespace DotNumerics.CSLapack
  18:  {
  19:      /// <summary>
  20:      /// -- LAPACK auxiliary routine (version 3.1) --
  21:      /// Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  22:      /// November 2006
  23:      /// Purpose
  24:      /// =======
  25:      /// 
  26:      /// Using a divide and conquer approach, DLASDA computes the singular
  27:      /// value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
  28:      /// B with diagonal D and offdiagonal E, where M = N + SQRE. The
  29:      /// algorithm computes the singular values in the SVD B = U * S * VT.
  30:      /// The orthogonal matrices U and VT are optionally computed in
  31:      /// compact form.
  32:      /// 
  33:      /// A related subroutine, DLASD0, computes the singular values and
  34:      /// the singular vectors in explicit form.
  35:      /// 
  36:      ///</summary>
  37:      public class DLASDA
  38:      {
  39:      
  40:   
  41:          #region Dependencies
  42:          
  43:          DCOPY _dcopy; DLASD6 _dlasd6; DLASDQ _dlasdq; DLASDT _dlasdt; DLASET _dlaset; XERBLA _xerbla; 
  44:   
  45:          #endregion
  46:   
  47:   
  48:          #region Fields
  49:          
  50:          const double ZERO = 0.0E+0; const double ONE = 1.0E+0; int I = 0; int I1 = 0; int IC = 0; int IDXQ = 0; int IDXQI = 0; 
  51:          int IM1 = 0;int INODE = 0; int ITEMP = 0; int IWK = 0; int J = 0; int LF = 0; int LL = 0; int LVL = 0; int LVL2 = 0; 
  52:          int M = 0;int NCC = 0; int ND = 0; int NDB1 = 0; int NDIML = 0; int NDIMR = 0; int NL = 0; int NLF = 0; int NLP1 = 0; 
  53:          int NLVL = 0;int NR = 0; int NRF = 0; int NRP1 = 0; int NRU = 0; int NWORK1 = 0; int NWORK2 = 0; int SMLSZP = 0; 
  54:          int SQREI = 0;int VF = 0; int VFI = 0; int VL = 0; int VLI = 0; double ALPHA = 0; double BETA = 0; 
  55:   
  56:          #endregion
  57:   
  58:          public DLASDA(DCOPY dcopy, DLASD6 dlasd6, DLASDQ dlasdq, DLASDT dlasdt, DLASET dlaset, XERBLA xerbla)
  59:          {
  60:      
  61:   
  62:              #region Set Dependencies
  63:              
  64:              this._dcopy = dcopy; this._dlasd6 = dlasd6; this._dlasdq = dlasdq; this._dlasdt = dlasdt; this._dlaset = dlaset; 
  65:              this._xerbla = xerbla;
  66:   
  67:              #endregion
  68:   
  69:          }
  70:      
  71:          public DLASDA()
  72:          {
  73:      
  74:   
  75:              #region Dependencies (Initialization)
  76:              
  77:              DCOPY dcopy = new DCOPY();
  78:              DLAMRG dlamrg = new DLAMRG();
  79:              LSAME lsame = new LSAME();
  80:              DLAMC3 dlamc3 = new DLAMC3();
  81:              XERBLA xerbla = new XERBLA();
  82:              DROT drot = new DROT();
  83:              DLAPY2 dlapy2 = new DLAPY2();
  84:              DLASD5 dlasd5 = new DLASD5();
  85:              DDOT ddot = new DDOT();
  86:              DNRM2 dnrm2 = new DNRM2();
  87:              DLAS2 dlas2 = new DLAS2();
  88:              DLASQ5 dlasq5 = new DLASQ5();
  89:              DLAZQ4 dlazq4 = new DLAZQ4();
  90:              IEEECK ieeeck = new IEEECK();
  91:              IPARMQ iparmq = new IPARMQ();
  92:              DSCAL dscal = new DSCAL();
  93:              DSWAP dswap = new DSWAP();
  94:              DLASDT dlasdt = new DLASDT();
  95:              DLAMC1 dlamc1 = new DLAMC1(dlamc3);
  96:              DLAMC4 dlamc4 = new DLAMC4(dlamc3);
  97:              DLAMC5 dlamc5 = new DLAMC5(dlamc3);
  98:              DLAMC2 dlamc2 = new DLAMC2(dlamc3, dlamc1, dlamc4, dlamc5);
  99:              DLAMCH dlamch = new DLAMCH(lsame, dlamc2);
 100:              DLASCL dlascl = new DLASCL(lsame, dlamch, xerbla);
 101:              DLASD7 dlasd7 = new DLASD7(dcopy, dlamrg, drot, xerbla, dlamch, dlapy2);
 102:              DLAED6 dlaed6 = new DLAED6(dlamch);
 103:              DLASD4 dlasd4 = new DLASD4(dlaed6, dlasd5, dlamch);
 104:              DLASET dlaset = new DLASET(lsame);
 105:              DLASD8 dlasd8 = new DLASD8(dcopy, dlascl, dlasd4, dlaset, xerbla, ddot, dlamc3, dnrm2);
 106:              DLASD6 dlasd6 = new DLASD6(dcopy, dlamrg, dlascl, dlasd7, dlasd8, xerbla);
 107:              DLARTG dlartg = new DLARTG(dlamch);
 108:              DLASQ6 dlasq6 = new DLASQ6(dlamch);
 109:              DLAZQ3 dlazq3 = new DLAZQ3(dlasq5, dlasq6, dlazq4, dlamch);
 110:              DLASRT dlasrt = new DLASRT(lsame, xerbla);
 111:              ILAENV ilaenv = new ILAENV(ieeeck, iparmq);
 112:              DLASQ2 dlasq2 = new DLASQ2(dlazq3, dlasrt, xerbla, dlamch, ilaenv);
 113:              DLASQ1 dlasq1 = new DLASQ1(dcopy, dlas2, dlascl, dlasq2, dlasrt, xerbla, dlamch);
 114:              DLASR dlasr = new DLASR(lsame, xerbla);
 115:              DLASV2 dlasv2 = new DLASV2(dlamch);
 116:              DBDSQR dbdsqr = new DBDSQR(lsame, dlamch, dlartg, dlas2, dlasq1, dlasr, dlasv2, drot, dscal, dswap
 117:                                         , xerbla);
 118:              DLASDQ dlasdq = new DLASDQ(dbdsqr, dlartg, dlasr, dswap, xerbla, lsame);
 119:   
 120:              #endregion
 121:   
 122:   
 123:              #region Set Dependencies
 124:              
 125:              this._dcopy = dcopy; this._dlasd6 = dlasd6; this._dlasdq = dlasdq; this._dlasdt = dlasdt; this._dlaset = dlaset; 
 126:              this._xerbla = xerbla;
 127:   
 128:              #endregion
 129:   
 130:          }
 131:          /// <summary>
 132:          /// Purpose
 133:          /// =======
 134:          /// 
 135:          /// Using a divide and conquer approach, DLASDA computes the singular
 136:          /// value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
 137:          /// B with diagonal D and offdiagonal E, where M = N + SQRE. The
 138:          /// algorithm computes the singular values in the SVD B = U * S * VT.
 139:          /// The orthogonal matrices U and VT are optionally computed in
 140:          /// compact form.
 141:          /// 
 142:          /// A related subroutine, DLASD0, computes the singular values and
 143:          /// the singular vectors in explicit form.
 144:          /// 
 145:          ///</summary>
 146:          /// <param name="ICOMPQ">
 147:          /// (input) INTEGER
 148:          /// Specifies whether singular vectors are to be computed
 149:          /// in compact form, as follows
 150:          /// = 0: Compute singular values only.
 151:          /// = 1: Compute singular vectors of upper bidiagonal
 152:          /// matrix in compact form.
 153:          ///</param>
 154:          /// <param name="SMLSIZ">
 155:          /// (input) INTEGER
 156:          /// The maximum size of the subproblems at the bottom of the
 157:          /// computation tree.
 158:          ///</param>
 159:          /// <param name="N">
 160:          /// (input) INTEGER
 161:          /// The row dimension of the upper bidiagonal matrix. This is
 162:          /// also the dimension of the main diagonal array D.
 163:          ///</param>
 164:          /// <param name="SQRE">
 165:          /// (input) INTEGER
 166:          /// Specifies the column dimension of the bidiagonal matrix.
 167:          /// = 0: The bidiagonal matrix has column dimension M = N;
 168:          /// = 1: The bidiagonal matrix has column dimension M = N + 1.
 169:          ///</param>
 170:          /// <param name="D">
 171:          /// (input/output) DOUBLE PRECISION array, dimension ( N )
 172:          /// On entry D contains the main diagonal of the bidiagonal
 173:          /// matrix. On exit D, if INFO = 0, contains its singular values.
 174:          ///</param>
 175:          /// <param name="E">
 176:          /// (input) DOUBLE PRECISION array, dimension ( M-1 )
 177:          /// Contains the subdiagonal entries of the bidiagonal matrix.
 178:          /// On exit, E has been destroyed.
 179:          ///</param>
 180:          /// <param name="U">
 181:          /// (output) DOUBLE PRECISION array,
 182:          /// dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
 183:          /// if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
 184:          /// singular vector matrices of all subproblems at the bottom
 185:          /// level.
 186:          ///</param>
 187:          /// <param name="LDU">
 188:          /// (input) INTEGER, LDU = .GT. N.
 189:          /// The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
 190:          /// GIVNUM, and Z.
 191:          ///</param>
 192:          /// <param name="VT">
 193:          /// (output) DOUBLE PRECISION array,
 194:          /// dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
 195:          /// if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT' contains the right
 196:          /// singular vector matrices of all subproblems at the bottom
 197:          /// level.
 198:          ///</param>
 199:          /// <param name="K">
 200:          /// (output) INTEGER array,
 201:          /// dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
 202:          /// If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
 203:          /// secular equation on the computation tree.
 204:          ///</param>
 205:          /// <param name="DIFL">
 206:          /// (output) DOUBLE PRECISION array, dimension ( LDU, NLVL ),
 207:          /// where NLVL = floor(log_2 (N/SMLSIZ))).
 208:          ///</param>
 209:          /// <param name="DIFR">
 210:          /// (output) DOUBLE PRECISION array,
 211:          /// dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
 212:          /// dimension ( N ) if ICOMPQ = 0.
 213:          /// If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
 214:          /// record distances between singular values on the I-th
 215:          /// level and singular values on the (I -1)-th level, and
 216:          /// DIFR(1:N, 2 * I ) contains the normalizing factors for
 217:          /// the right singular vector matrix. See DLASD8 for details.
 218:          ///</param>
 219:          /// <param name="Z">
 220:          /// (output) DOUBLE PRECISION array,
 221:          /// dimension ( LDU, NLVL ) if ICOMPQ = 1 and
 222:          /// dimension ( N ) if ICOMPQ = 0.
 223:          /// The first K elements of Z(1, I) contain the components of
 224:          /// the deflation-adjusted updating row vector for subproblems
 225:          /// on the I-th level.
 226:          ///</param>
 227:          /// <param name="POLES">
 228:          /// (output) DOUBLE PRECISION array,
 229:          /// dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
 230:          /// if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
 231:          /// POLES(1, 2*I) contain  the new and old singular values
 232:          /// involved in the secular equations on the I-th level.
 233:          ///</param>
 234:          /// <param name="GIVPTR">
 235:          /// (output) INTEGER array,
 236:          /// dimension ( N ) if ICOMPQ = 1, and not referenced if
 237:          /// ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
 238:          /// the number of Givens rotations performed on the I-th
 239:          /// problem on the computation tree.
 240:          ///</param>
 241:          /// <param name="GIVCOL">
 242:          /// (output) INTEGER array,
 243:          /// dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
 244:          /// referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
 245:          /// GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
 246:          /// of Givens rotations performed on the I-th level on the
 247:          /// computation tree.
 248:          ///</param>
 249:          /// <param name="LDGCOL">
 250:          /// (input) INTEGER, LDGCOL = .GT. N.
 251:          /// The leading dimension of arrays GIVCOL and PERM.
 252:          ///</param>
 253:          /// <param name="PERM">
 254:          /// (output) INTEGER array,
 255:          /// dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced
 256:          /// if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
 257:          /// permutations done on the I-th level of the computation tree.
 258:          ///</param>
 259:          /// <param name="GIVNUM">
 260:          /// (output) DOUBLE PRECISION array,
 261:          /// dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
 262:          /// referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
 263:          /// GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
 264:          /// values of Givens rotations performed on the I-th level on
 265:          /// the computation tree.
 266:          ///</param>
 267:          /// <param name="C">
 268:          /// (output) DOUBLE PRECISION array,
 269:          /// dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
 270:          /// If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
 271:          /// C( I ) contains the C-value of a Givens rotation related to
 272:          /// the right null space of the I-th subproblem.
 273:          ///</param>
 274:          /// <param name="S">
 275:          /// (output) DOUBLE PRECISION array, dimension ( N ) if
 276:          /// ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
 277:          /// and the I-th subproblem is not square, on exit, S( I )
 278:          /// contains the S-value of a Givens rotation related to
 279:          /// the right null space of the I-th subproblem.
 280:          ///</param>
 281:          /// <param name="WORK">
 282:          /// (workspace) DOUBLE PRECISION array, dimension
 283:          /// (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
 284:          ///</param>
 285:          /// <param name="IWORK">
 286:          /// (workspace) INTEGER array.
 287:          /// Dimension must be at least (7 * N).
 288:          ///</param>
 289:          /// <param name="INFO">
 290:          /// (output) INTEGER
 291:          /// = 0:  successful exit.
 292:          /// .LT. 0:  if INFO = -i, the i-th argument had an illegal value.
 293:          /// .GT. 0:  if INFO = 1, an singular value did not converge
 294:          ///</param>
 295:          public void Run(int ICOMPQ, int SMLSIZ, int N, int SQRE, ref double[] D, int offset_d, ref double[] E, int offset_e
 296:                           , ref double[] U, int offset_u, int LDU, ref double[] VT, int offset_vt, ref int[] K, int offset_k, ref double[] DIFL, int offset_difl, ref double[] DIFR, int offset_difr
 297:                           , ref double[] Z, int offset_z, ref double[] POLES, int offset_poles, ref int[] GIVPTR, int offset_givptr, ref int[] GIVCOL, int offset_givcol, int LDGCOL, ref int[] PERM, int offset_perm
 298:                           , ref double[] GIVNUM, int offset_givnum, ref double[] C, int offset_c, ref double[] S, int offset_s, ref double[] WORK, int offset_work, ref int[] IWORK, int offset_iwork, ref int INFO)
 299:          {
 300:   
 301:              #region Array Index Correction
 302:              
 303:               int o_d = -1 + offset_d;  int o_e = -1 + offset_e;  int o_u = -1 - LDU + offset_u;  int o_vt = -1 - LDU + offset_vt; 
 304:               int o_k = -1 + offset_k; int o_difl = -1 - LDU + offset_difl;  int o_difr = -1 - LDU + offset_difr; 
 305:               int o_z = -1 - LDU + offset_z; int o_poles = -1 - LDU + offset_poles;  int o_givptr = -1 + offset_givptr; 
 306:               int o_givcol = -1 - LDGCOL + offset_givcol; int o_perm = -1 - LDGCOL + offset_perm; 
 307:               int o_givnum = -1 - LDU + offset_givnum; int o_c = -1 + offset_c;  int o_s = -1 + offset_s; 
 308:               int o_work = -1 + offset_work; int o_iwork = -1 + offset_iwork; 
 309:   
 310:              #endregion
 311:   
 312:   
 313:              #region Prolog
 314:              
 315:              // *
 316:              // *  -- LAPACK auxiliary routine (version 3.1) --
 317:              // *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
 318:              // *     November 2006
 319:              // *
 320:              // *     .. Scalar Arguments ..
 321:              // *     ..
 322:              // *     .. Array Arguments ..
 323:              // *     ..
 324:              // *
 325:              // *  Purpose
 326:              // *  =======
 327:              // *
 328:              // *  Using a divide and conquer approach, DLASDA computes the singular
 329:              // *  value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
 330:              // *  B with diagonal D and offdiagonal E, where M = N + SQRE. The
 331:              // *  algorithm computes the singular values in the SVD B = U * S * VT.
 332:              // *  The orthogonal matrices U and VT are optionally computed in
 333:              // *  compact form.
 334:              // *
 335:              // *  A related subroutine, DLASD0, computes the singular values and
 336:              // *  the singular vectors in explicit form.
 337:              // *
 338:              // *  Arguments
 339:              // *  =========
 340:              // *
 341:              // *  ICOMPQ (input) INTEGER
 342:              // *         Specifies whether singular vectors are to be computed
 343:              // *         in compact form, as follows
 344:              // *         = 0: Compute singular values only.
 345:              // *         = 1: Compute singular vectors of upper bidiagonal
 346:              // *              matrix in compact form.
 347:              // *
 348:              // *  SMLSIZ (input) INTEGER
 349:              // *         The maximum size of the subproblems at the bottom of the
 350:              // *         computation tree.
 351:              // *
 352:              // *  N      (input) INTEGER
 353:              // *         The row dimension of the upper bidiagonal matrix. This is
 354:              // *         also the dimension of the main diagonal array D.
 355:              // *
 356:              // *  SQRE   (input) INTEGER
 357:              // *         Specifies the column dimension of the bidiagonal matrix.
 358:              // *         = 0: The bidiagonal matrix has column dimension M = N;
 359:              // *         = 1: The bidiagonal matrix has column dimension M = N + 1.
 360:              // *
 361:              // *  D      (input/output) DOUBLE PRECISION array, dimension ( N )
 362:              // *         On entry D contains the main diagonal of the bidiagonal
 363:              // *         matrix. On exit D, if INFO = 0, contains its singular values.
 364:              // *
 365:              // *  E      (input) DOUBLE PRECISION array, dimension ( M-1 )
 366:              // *         Contains the subdiagonal entries of the bidiagonal matrix.
 367:              // *         On exit, E has been destroyed.
 368:              // *
 369:              // *  U      (output) DOUBLE PRECISION array,
 370:              // *         dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
 371:              // *         if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
 372:              // *         singular vector matrices of all subproblems at the bottom
 373:              // *         level.
 374:              // *
 375:              // *  LDU    (input) INTEGER, LDU = > N.
 376:              // *         The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
 377:              // *         GIVNUM, and Z.
 378:              // *
 379:              // *  VT     (output) DOUBLE PRECISION array,
 380:              // *         dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
 381:              // *         if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT' contains the right
 382:              // *         singular vector matrices of all subproblems at the bottom
 383:              // *         level.
 384:              // *
 385:              // *  K      (output) INTEGER array,
 386:              // *         dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
 387:              // *         If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
 388:              // *         secular equation on the computation tree.
 389:              // *
 390:              // *  DIFL   (output) DOUBLE PRECISION array, dimension ( LDU, NLVL ),
 391:              // *         where NLVL = floor(log_2 (N/SMLSIZ))).
 392:              // *
 393:              // *  DIFR   (output) DOUBLE PRECISION array,
 394:              // *                  dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
 395:              // *                  dimension ( N ) if ICOMPQ = 0.
 396:              // *         If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
 397:              // *         record distances between singular values on the I-th
 398:              // *         level and singular values on the (I -1)-th level, and
 399:              // *         DIFR(1:N, 2 * I ) contains the normalizing factors for
 400:              // *         the right singular vector matrix. See DLASD8 for details.
 401:              // *
 402:              // *  Z      (output) DOUBLE PRECISION array,
 403:              // *                  dimension ( LDU, NLVL ) if ICOMPQ = 1 and
 404:              // *                  dimension ( N ) if ICOMPQ = 0.
 405:              // *         The first K elements of Z(1, I) contain the components of
 406:              // *         the deflation-adjusted updating row vector for subproblems
 407:              // *         on the I-th level.
 408:              // *
 409:              // *  POLES  (output) DOUBLE PRECISION array,
 410:              // *         dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
 411:              // *         if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
 412:              // *         POLES(1, 2*I) contain  the new and old singular values
 413:              // *         involved in the secular equations on the I-th level.
 414:              // *
 415:              // *  GIVPTR (output) INTEGER array,
 416:              // *         dimension ( N ) if ICOMPQ = 1, and not referenced if
 417:              // *         ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
 418:              // *         the number of Givens rotations performed on the I-th
 419:              // *         problem on the computation tree.
 420:              // *
 421:              // *  GIVCOL (output) INTEGER array,
 422:              // *         dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
 423:              // *         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
 424:              // *         GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
 425:              // *         of Givens rotations performed on the I-th level on the
 426:              // *         computation tree.
 427:              // *
 428:              // *  LDGCOL (input) INTEGER, LDGCOL = > N.
 429:              // *         The leading dimension of arrays GIVCOL and PERM.
 430:              // *
 431:              // *  PERM   (output) INTEGER array,
 432:              // *         dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced
 433:              // *         if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
 434:              // *         permutations done on the I-th level of the computation tree.
 435:              // *
 436:              // *  GIVNUM (output) DOUBLE PRECISION array,
 437:              // *         dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
 438:              // *         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
 439:              // *         GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
 440:              // *         values of Givens rotations performed on the I-th level on
 441:              // *         the computation tree.
 442:              // *
 443:              // *  C      (output) DOUBLE PRECISION array,
 444:              // *         dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
 445:              // *         If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
 446:              // *         C( I ) contains the C-value of a Givens rotation related to
 447:              // *         the right null space of the I-th subproblem.
 448:              // *
 449:              // *  S      (output) DOUBLE PRECISION array, dimension ( N ) if
 450:              // *         ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
 451:              // *         and the I-th subproblem is not square, on exit, S( I )
 452:              // *         contains the S-value of a Givens rotation related to
 453:              // *         the right null space of the I-th subproblem.
 454:              // *
 455:              // *  WORK   (workspace) DOUBLE PRECISION array, dimension
 456:              // *         (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
 457:              // *
 458:              // *  IWORK  (workspace) INTEGER array.
 459:              // *         Dimension must be at least (7 * N).
 460:              // *
 461:              // *  INFO   (output) INTEGER
 462:              // *          = 0:  successful exit.
 463:              // *          < 0:  if INFO = -i, the i-th argument had an illegal value.
 464:              // *          > 0:  if INFO = 1, an singular value did not converge
 465:              // *
 466:              // *  Further Details
 467:              // *  ===============
 468:              // *
 469:              // *  Based on contributions by
 470:              // *     Ming Gu and Huan Ren, Computer Science Division, University of
 471:              // *     California at Berkeley, USA
 472:              // *
 473:              // *  =====================================================================
 474:              // *
 475:              // *     .. Parameters ..
 476:              // *     ..
 477:              // *     .. Local Scalars ..
 478:              // *     ..
 479:              // *     .. External Subroutines ..
 480:              // *     ..
 481:              // *     .. Executable Statements ..
 482:              // *
 483:              // *     Test the input parameters.
 484:              // *
 485:   
 486:              #endregion
 487:   
 488:   
 489:              #region Body
 490:              
 491:              INFO = 0;
 492:              // *
 493:              if ((ICOMPQ < 0) || (ICOMPQ > 1))
 494:              {
 495:                  INFO =  - 1;
 496:              }
 497:              else
 498:              {
 499:                  if (SMLSIZ < 3)
 500:                  {
 501:                      INFO =  - 2;
 502:                  }
 503:                  else
 504:                  {
 505:                      if (N < 0)
 506:                      {
 507:                          INFO =  - 3;
 508:                      }
 509:                      else
 510:                      {
 511:                          if ((SQRE < 0) || (SQRE > 1))
 512:                          {
 513:                              INFO =  - 4;
 514:                          }
 515:                          else
 516:                          {
 517:                              if (LDU < (N + SQRE))
 518:                              {
 519:                                  INFO =  - 8;
 520:                              }
 521:                              else
 522:                              {
 523:                                  if (LDGCOL < N)
 524:                                  {
 525:                                      INFO =  - 17;
 526:                                  }
 527:                              }
 528:                          }
 529:                      }
 530:                  }
 531:              }
 532:              if (INFO != 0)
 533:              {
 534:                  this._xerbla.Run("DLASDA",  - INFO);
 535:                  return;
 536:              }
 537:              // *
 538:              M = N + SQRE;
 539:              // *
 540:              // *     If the input matrix is too small, call DLASDQ to find the SVD.
 541:              // *
 542:              if (N <= SMLSIZ)
 543:              {
 544:                  if (ICOMPQ == 0)
 545:                  {
 546:                      this._dlasdq.Run("U", SQRE, N, 0, 0, 0
 547:                                       , ref D, offset_d, ref E, offset_e, ref VT, offset_vt, LDU, ref U, offset_u, LDU
 548:                                       , ref U, offset_u, LDU, ref WORK, offset_work, ref INFO);
 549:                  }
 550:                  else
 551:                  {
 552:                      this._dlasdq.Run("U", SQRE, N, M, N, 0
 553:                                       , ref D, offset_d, ref E, offset_e, ref VT, offset_vt, LDU, ref U, offset_u, LDU
 554:                                       , ref U, offset_u, LDU, ref WORK, offset_work, ref INFO);
 555:                  }
 556:                  return;
 557:              }
 558:              // *
 559:              // *     Book-keeping and  set up the computation tree.
 560:              // *
 561:              INODE = 1;
 562:              NDIML = INODE + N;
 563:              NDIMR = NDIML + N;
 564:              IDXQ = NDIMR + N;
 565:              IWK = IDXQ + N;
 566:              // *
 567:              NCC = 0;
 568:              NRU = 0;
 569:              // *
 570:              SMLSZP = SMLSIZ + 1;
 571:              VF = 1;
 572:              VL = VF + M;
 573:              NWORK1 = VL + M;
 574:              NWORK2 = NWORK1 + SMLSZP * SMLSZP;
 575:              // *
 576:              this._dlasdt.Run(N, ref NLVL, ref ND, ref IWORK, INODE + o_iwork, ref IWORK, NDIML + o_iwork, ref IWORK, NDIMR + o_iwork
 577:                               , SMLSIZ);
 578:              // *
 579:              // *     for the nodes on bottom level of the tree, solve
 580:              // *     their subproblems by DLASDQ.
 581:              // *
 582:              NDB1 = (ND + 1) / 2;
 583:              for (I = NDB1; I <= ND; I++)
 584:              {
 585:                  // *
 586:                  // *        IC : center row of each node
 587:                  // *        NL : number of rows of left  subproblem
 588:                  // *        NR : number of rows of right subproblem
 589:                  // *        NLF: starting row of the left   subproblem
 590:                  // *        NRF: starting row of the right  subproblem
 591:                  // *
 592:                  I1 = I - 1;
 593:                  IC = IWORK[INODE + I1 + o_iwork];
 594:                  NL = IWORK[NDIML + I1 + o_iwork];
 595:                  NLP1 = NL + 1;
 596:                  NR = IWORK[NDIMR + I1 + o_iwork];
 597:                  NLF = IC - NL;
 598:                  NRF = IC + 1;
 599:                  IDXQI = IDXQ + NLF - 2;
 600:                  VFI = VF + NLF - 1;
 601:                  VLI = VL + NLF - 1;
 602:                  SQREI = 1;
 603:                  if (ICOMPQ == 0)
 604:                  {
 605:                      this._dlaset.Run("A", NLP1, NLP1, ZERO, ONE, ref WORK, NWORK1 + o_work
 606:                                       , SMLSZP);
 607:                      this._dlasdq.Run("U", SQREI, NL, NLP1, NRU, NCC
 608:                                       , ref D, NLF + o_d, ref E, NLF + o_e, ref WORK, NWORK1 + o_work, SMLSZP, ref WORK, NWORK2 + o_work, NL
 609:                                       , ref WORK, NWORK2 + o_work, NL, ref WORK, NWORK2 + o_work, ref INFO);
 610:                      ITEMP = NWORK1 + NL * SMLSZP;
 611:                      this._dcopy.Run(NLP1, WORK, NWORK1 + o_work, 1, ref WORK, VFI + o_work, 1);
 612:                      this._dcopy.Run(NLP1, WORK, ITEMP + o_work, 1, ref WORK, VLI + o_work, 1);
 613:                  }
 614:                  else
 615:                  {
 616:                      this._dlaset.Run("A", NL, NL, ZERO, ONE, ref U, NLF+1 * LDU + o_u
 617:                                       , LDU);
 618:                      this._dlaset.Run("A", NLP1, NLP1, ZERO, ONE, ref VT, NLF+1 * LDU + o_vt
 619:                                       , LDU);
 620:                      this._dlasdq.Run("U", SQREI, NL, NLP1, NL, NCC
 621:                                       , ref D, NLF + o_d, ref E, NLF + o_e, ref VT, NLF+1 * LDU + o_vt, LDU, ref U, NLF+1 * LDU + o_u, LDU
 622:                                       , ref U, NLF+1 * LDU + o_u, LDU, ref WORK, NWORK1 + o_work, ref INFO);
 623:                      this._dcopy.Run(NLP1, VT, NLF+1 * LDU + o_vt, 1, ref WORK, VFI + o_work, 1);
 624:                      this._dcopy.Run(NLP1, VT, NLF+NLP1 * LDU + o_vt, 1, ref WORK, VLI + o_work, 1);
 625:                  }
 626:                  if (INFO != 0)
 627:                  {
 628:                      return;
 629:                  }
 630:                  for (J = 1; J <= NL; J++)
 631:                  {
 632:                      IWORK[IDXQI + J + o_iwork] = J;
 633:                  }
 634:                  if ((I == ND) && (SQRE == 0))
 635:                  {
 636:                      SQREI = 0;
 637:                  }
 638:                  else
 639:                  {
 640:                      SQREI = 1;
 641:                  }
 642:                  IDXQI = IDXQI + NLP1;
 643:                  VFI = VFI + NLP1;
 644:                  VLI = VLI + NLP1;
 645:                  NRP1 = NR + SQREI;
 646:                  if (ICOMPQ == 0)
 647:                  {
 648:                      this._dlaset.Run("A", NRP1, NRP1, ZERO, ONE, ref WORK, NWORK1 + o_work
 649:                                       , SMLSZP);
 650:                      this._dlasdq.Run("U", SQREI, NR, NRP1, NRU, NCC
 651:                                       , ref D, NRF + o_d, ref E, NRF + o_e, ref WORK, NWORK1 + o_work, SMLSZP, ref WORK, NWORK2 + o_work, NR
 652:                                       , ref WORK, NWORK2 + o_work, NR, ref WORK, NWORK2 + o_work, ref INFO);
 653:                      ITEMP = NWORK1 + (NRP1 - 1) * SMLSZP;
 654:                      this._dcopy.Run(NRP1, WORK, NWORK1 + o_work, 1, ref WORK, VFI + o_work, 1);
 655:                      this._dcopy.Run(NRP1, WORK, ITEMP + o_work, 1, ref WORK, VLI + o_work, 1);
 656:                  }
 657:                  else
 658:                  {
 659:                      this._dlaset.Run("A", NR, NR, ZERO, ONE, ref U, NRF+1 * LDU + o_u
 660:                                       , LDU);
 661:                      this._dlaset.Run("A", NRP1, NRP1, ZERO, ONE, ref VT, NRF+1 * LDU + o_vt
 662:                                       , LDU);
 663:                      this._dlasdq.Run("U", SQREI, NR, NRP1, NR, NCC
 664:                                       , ref D, NRF + o_d, ref E, NRF + o_e, ref VT, NRF+1 * LDU + o_vt, LDU, ref U, NRF+1 * LDU + o_u, LDU
 665:                                       , ref U, NRF+1 * LDU + o_u, LDU, ref WORK, NWORK1 + o_work, ref INFO);
 666:                      this._dcopy.Run(NRP1, VT, NRF+1 * LDU + o_vt, 1, ref WORK, VFI + o_work, 1);
 667:                      this._dcopy.Run(NRP1, VT, NRF+NRP1 * LDU + o_vt, 1, ref WORK, VLI + o_work, 1);
 668:                  }
 669:                  if (INFO != 0)
 670:                  {
 671:                      return;
 672:                  }
 673:                  for (J = 1; J <= NR; J++)
 674:                  {
 675:                      IWORK[IDXQI + J + o_iwork] = J;
 676:                  }
 677:              }
 678:              // *
 679:              // *     Now conquer each subproblem bottom-up.
 680:              // *
 681:              J = (int)Math.Pow(2, NLVL);
 682:              for (LVL = NLVL; LVL >= 1; LVL +=  - 1)
 683:              {
 684:                  LVL2 = LVL * 2 - 1;
 685:                  // *
 686:                  // *        Find the first node LF and last node LL on
 687:                  // *        the current level LVL.
 688:                  // *
 689:                  if (LVL == 1)
 690:                  {
 691:                      LF = 1;
 692:                      LL = 1;
 693:                  }
 694:                  else
 695:                  {
 696:                      LF = (int)Math.Pow(2, LVL - 1);
 697:                      LL = 2 * LF - 1;
 698:                  }
 699:                  for (I = LF; I <= LL; I++)
 700:                  {
 701:                      IM1 = I - 1;
 702:                      IC = IWORK[INODE + IM1 + o_iwork];
 703:                      NL = IWORK[NDIML + IM1 + o_iwork];
 704:                      NR = IWORK[NDIMR + IM1 + o_iwork];
 705:                      NLF = IC - NL;
 706:                      NRF = IC + 1;
 707:                      if (I == LL)
 708:                      {
 709:                          SQREI = SQRE;
 710:                      }
 711:                      else
 712:                      {
 713:                          SQREI = 1;
 714:                      }
 715:                      VFI = VF + NLF - 1;
 716:                      VLI = VL + NLF - 1;
 717:                      IDXQI = IDXQ + NLF - 1;
 718:                      ALPHA = D[IC + o_d];
 719:                      BETA = E[IC + o_e];
 720:                      if (ICOMPQ == 0)
 721:                      {
 722:                          this._dlasd6.Run(ICOMPQ, NL, NR, SQREI, ref D, NLF + o_d, ref WORK, VFI + o_work
 723:                                           , ref WORK, VLI + o_work, ref ALPHA, ref BETA, ref IWORK, IDXQI + o_iwork, ref PERM, offset_perm, ref GIVPTR[1 + o_givptr]
 724:                                           , ref GIVCOL, offset_givcol, LDGCOL, ref GIVNUM, offset_givnum, LDU, ref POLES, offset_poles, ref DIFL, offset_difl
 725:                                           , ref DIFR, offset_difr, ref Z, offset_z, ref K[1 + o_k], ref C[1 + o_c], ref S[1 + o_s], ref WORK, NWORK1 + o_work
 726:                                           , ref IWORK, IWK + o_iwork, ref INFO);
 727:                      }
 728:                      else
 729:                      {
 730:                          J = J - 1;
 731:                          this._dlasd6.Run(ICOMPQ, NL, NR, SQREI, ref D, NLF + o_d, ref WORK, VFI + o_work
 732:                                           , ref WORK, VLI + o_work, ref ALPHA, ref BETA, ref IWORK, IDXQI + o_iwork, ref PERM, NLF+LVL * LDGCOL + o_perm, ref GIVPTR[J + o_givptr]
 733:                                           , ref GIVCOL, NLF+LVL2 * LDGCOL + o_givcol, LDGCOL, ref GIVNUM, NLF+LVL2 * LDU + o_givnum, LDU, ref POLES, NLF+LVL2 * LDU + o_poles, ref DIFL, NLF+LVL * LDU + o_difl
 734:                                           , ref DIFR, NLF+LVL2 * LDU + o_difr, ref Z, NLF+LVL * LDU + o_z, ref K[J + o_k], ref C[J + o_c], ref S[J + o_s], ref WORK, NWORK1 + o_work
 735:                                           , ref IWORK, IWK + o_iwork, ref INFO);
 736:                      }
 737:                      if (INFO != 0)
 738:                      {
 739:                          return;
 740:                      }
 741:                  }
 742:              }
 743:              // *
 744:              return;
 745:              // *
 746:              // *     End of DLASDA
 747:              // *
 748:   
 749:              #endregion
 750:   
 751:          }
 752:      }
 753:  }