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:      /// This program sets problem and machine dependent parameters
  27:      /// useful for xHSEQR and its subroutines. It is called whenever 
  28:      /// ILAENV is called with 12 .LE. ISPEC .LE. 16
  29:      /// 
  30:      ///</summary>
  31:      public class IPARMQ
  32:      {
  33:      
  34:   
  35:          #region Fields
  36:          
  37:          const int INMIN = 12; const int INWIN = 13; const int INIBL = 14; const int ISHFTS = 15; const int IACC22 = 16; 
  38:          const int NMIN = 75;const int K22MIN = 14; const int KACMIN = 14; const int NIBBLE = 14; const int KNWSWP = 500; 
  39:          const double TWO = 2.0;int NH = 0; int NS = 0; 
  40:   
  41:          #endregion
  42:   
  43:          public IPARMQ()
  44:          {
  45:      
  46:          }
  47:      
  48:          /// <summary>
  49:          /// Purpose
  50:          /// =======
  51:          /// 
  52:          /// This program sets problem and machine dependent parameters
  53:          /// useful for xHSEQR and its subroutines. It is called whenever 
  54:          /// ILAENV is called with 12 .LE. ISPEC .LE. 16
  55:          /// 
  56:          ///</summary>
  57:          /// <param name="ISPEC">
  58:          /// (input) integer scalar
  59:          /// ISPEC specifies which tunable parameter IPARMQ should
  60:          /// return.
  61:          /// 
  62:          /// ISPEC=12: (INMIN)  Matrices of order nmin or less
  63:          /// are sent directly to xLAHQR, the implicit
  64:          /// double shift QR algorithm.  NMIN must be
  65:          /// at least 11.
  66:          /// 
  67:          /// ISPEC=13: (INWIN)  Size of the deflation window.
  68:          /// This is best set greater than or equal to
  69:          /// the number of simultaneous shifts NS.
  70:          /// Larger matrices benefit from larger deflation
  71:          /// windows.
  72:          /// 
  73:          /// ISPEC=14: (INIBL) Determines when to stop nibbling and
  74:          /// invest in an (expensive) multi-shift QR sweep.
  75:          /// If the aggressive early deflation subroutine
  76:          /// finds LD converged eigenvalues from an order
  77:          /// NW deflation window and LD.GT.(NW*NIBBLE)/100,
  78:          /// then the next QR sweep is skipped and early
  79:          /// deflation is applied immediately to the
  80:          /// remaining active diagonal block.  Setting
  81:          /// IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a
  82:          /// multi-shift QR sweep whenever early deflation
  83:          /// finds a converged eigenvalue.  Setting
  84:          /// IPARMQ(ISPEC=14) greater than or equal to 100
  85:          /// prevents TTQRE from skipping a multi-shift
  86:          /// QR sweep.
  87:          /// 
  88:          /// ISPEC=15: (NSHFTS) The number of simultaneous shifts in
  89:          /// a multi-shift QR iteration.
  90:          /// 
  91:          /// ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the
  92:          /// following meanings.
  93:          /// 0:  During the multi-shift QR sweep,
  94:          /// xLAQR5 does not accumulate reflections and
  95:          /// does not use matrix-matrix multiply to
  96:          /// update the far-from-diagonal matrix
  97:          /// entries.
  98:          /// 1:  During the multi-shift QR sweep,
  99:          /// xLAQR5 and/or xLAQRaccumulates reflections and uses
 100:          /// matrix-matrix multiply to update the
 101:          /// far-from-diagonal matrix entries.
 102:          /// 2:  During the multi-shift QR sweep.
 103:          /// xLAQR5 accumulates reflections and takes
 104:          /// advantage of 2-by-2 block structure during
 105:          /// matrix-matrix multiplies.
 106:          /// (If xTRMM is slower than xGEMM, then
 107:          /// IPARMQ(ISPEC=16)=1 may be more efficient than
 108:          /// IPARMQ(ISPEC=16)=2 despite the greater level of
 109:          /// arithmetic work implied by the latter choice.)
 110:          ///</param>
 111:          /// <param name="NAME">
 112:          /// (input) character string
 113:          /// Name of the calling subroutine
 114:          ///</param>
 115:          /// <param name="OPTS">
 116:          /// (input) character string
 117:          /// This is a concatenation of the string arguments to
 118:          /// TTQRE.
 119:          ///</param>
 120:          /// <param name="N">
 121:          /// (input) integer scalar
 122:          /// N is the order of the Hessenberg matrix H.
 123:          ///</param>
 124:          /// <param name="ILO">
 125:          /// (input) INTEGER
 126:          ///</param>
 127:          /// <param name="IHI">
 128:          /// (input) INTEGER
 129:          /// It is assumed that H is already upper triangular
 130:          /// in rows and columns 1:ILO-1 and IHI+1:N.
 131:          ///</param>
 132:          /// <param name="LWORK">
 133:          /// (input) integer scalar
 134:          /// The amount of workspace available.
 135:          ///</param>
 136:          public int Run(int ISPEC, string NAME, string OPTS, int N, int ILO, int IHI
 137:                          , int LWORK)
 138:          {
 139:          int iparmq = 0;
 140:   
 141:              #region Strings
 142:              
 143:                
 144:   
 145:              #endregion
 146:   
 147:   
 148:              #region Prolog
 149:              
 150:              // *
 151:              // *  -- LAPACK auxiliary routine (version 3.1) --
 152:              // *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
 153:              // *     November 2006
 154:              // *     
 155:              // *     .. Scalar Arguments ..
 156:              // *
 157:              // *  Purpose
 158:              // *  =======
 159:              // *
 160:              // *       This program sets problem and machine dependent parameters
 161:              // *       useful for xHSEQR and its subroutines. It is called whenever 
 162:              // *       ILAENV is called with 12 <= ISPEC <= 16
 163:              // *
 164:              // *  Arguments
 165:              // *  =========
 166:              // *
 167:              // *       ISPEC  (input) integer scalar
 168:              // *              ISPEC specifies which tunable parameter IPARMQ should
 169:              // *              return.
 170:              // *
 171:              // *              ISPEC=12: (INMIN)  Matrices of order nmin or less
 172:              // *                        are sent directly to xLAHQR, the implicit
 173:              // *                        double shift QR algorithm.  NMIN must be
 174:              // *                        at least 11.
 175:              // *
 176:              // *              ISPEC=13: (INWIN)  Size of the deflation window.
 177:              // *                        This is best set greater than or equal to
 178:              // *                        the number of simultaneous shifts NS.
 179:              // *                        Larger matrices benefit from larger deflation
 180:              // *                        windows.
 181:              // *
 182:              // *              ISPEC=14: (INIBL) Determines when to stop nibbling and
 183:              // *                        invest in an (expensive) multi-shift QR sweep.
 184:              // *                        If the aggressive early deflation subroutine
 185:              // *                        finds LD converged eigenvalues from an order
 186:              // *                        NW deflation window and LD.GT.(NW*NIBBLE)/100,
 187:              // *                        then the next QR sweep is skipped and early
 188:              // *                        deflation is applied immediately to the
 189:              // *                        remaining active diagonal block.  Setting
 190:              // *                        IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a
 191:              // *                        multi-shift QR sweep whenever early deflation
 192:              // *                        finds a converged eigenvalue.  Setting
 193:              // *                        IPARMQ(ISPEC=14) greater than or equal to 100
 194:              // *                        prevents TTQRE from skipping a multi-shift
 195:              // *                        QR sweep.
 196:              // *
 197:              // *              ISPEC=15: (NSHFTS) The number of simultaneous shifts in
 198:              // *                        a multi-shift QR iteration.
 199:              // *
 200:              // *              ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the
 201:              // *                        following meanings.
 202:              // *                        0:  During the multi-shift QR sweep,
 203:              // *                            xLAQR5 does not accumulate reflections and
 204:              // *                            does not use matrix-matrix multiply to
 205:              // *                            update the far-from-diagonal matrix
 206:              // *                            entries.
 207:              // *                        1:  During the multi-shift QR sweep,
 208:              // *                            xLAQR5 and/or xLAQRaccumulates reflections and uses
 209:              // *                            matrix-matrix multiply to update the
 210:              // *                            far-from-diagonal matrix entries.
 211:              // *                        2:  During the multi-shift QR sweep.
 212:              // *                            xLAQR5 accumulates reflections and takes
 213:              // *                            advantage of 2-by-2 block structure during
 214:              // *                            matrix-matrix multiplies.
 215:              // *                        (If xTRMM is slower than xGEMM, then
 216:              // *                        IPARMQ(ISPEC=16)=1 may be more efficient than
 217:              // *                        IPARMQ(ISPEC=16)=2 despite the greater level of
 218:              // *                        arithmetic work implied by the latter choice.)
 219:              // *
 220:              // *       NAME    (input) character string
 221:              // *               Name of the calling subroutine
 222:              // *
 223:              // *       OPTS    (input) character string
 224:              // *               This is a concatenation of the string arguments to
 225:              // *               TTQRE.
 226:              // *
 227:              // *       N       (input) integer scalar
 228:              // *               N is the order of the Hessenberg matrix H.
 229:              // *
 230:              // *       ILO     (input) INTEGER
 231:              // *       IHI     (input) INTEGER
 232:              // *               It is assumed that H is already upper triangular
 233:              // *               in rows and columns 1:ILO-1 and IHI+1:N.
 234:              // *
 235:              // *       LWORK   (input) integer scalar
 236:              // *               The amount of workspace available.
 237:              // *
 238:              // *  Further Details
 239:              // *  ===============
 240:              // *
 241:              // *       Little is known about how best to choose these parameters.
 242:              // *       It is possible to use different values of the parameters
 243:              // *       for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR.
 244:              // *
 245:              // *       It is probably best to choose different parameters for
 246:              // *       different matrices and different parameters at different
 247:              // *       times during the iteration, but this has not been
 248:              // *       implemented --- yet.
 249:              // *
 250:              // *
 251:              // *       The best choices of most of the parameters depend
 252:              // *       in an ill-understood way on the relative execution
 253:              // *       rate of xLAQR3 and xLAQR5 and on the nature of each
 254:              // *       particular eigenvalue problem.  Experiment may be the
 255:              // *       only practical way to determine which choices are most
 256:              // *       effective.
 257:              // *
 258:              // *       Following is a list of default values supplied by IPARMQ.
 259:              // *       These defaults may be adjusted in order to attain better
 260:              // *       performance in any particular computational environment.
 261:              // *
 262:              // *       IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point.
 263:              // *                        Default: 75. (Must be at least 11.)
 264:              // *
 265:              // *       IPARMQ(ISPEC=13) Recommended deflation window size.
 266:              // *                        This depends on ILO, IHI and NS, the
 267:              // *                        number of simultaneous shifts returned
 268:              // *                        by IPARMQ(ISPEC=15).  The default for
 269:              // *                        (IHI-ILO+1).LE.500 is NS.  The default
 270:              // *                        for (IHI-ILO+1).GT.500 is 3*NS/2.
 271:              // *
 272:              // *       IPARMQ(ISPEC=14) Nibble crossover point.  Default: 14.
 273:              // *
 274:              // *       IPARMQ(ISPEC=15) Number of simultaneous shifts, NS.
 275:              // *                        a multi-shift QR iteration.
 276:              // *
 277:              // *                        If IHI-ILO+1 is ...
 278:              // *
 279:              // *                        greater than      ...but less    ... the
 280:              // *                        or equal to ...      than        default is
 281:              // *
 282:              // *                                0               30       NS =   2+
 283:              // *                               30               60       NS =   4+
 284:              // *                               60              150       NS =  10
 285:              // *                              150              590       NS =  **
 286:              // *                              590             3000       NS =  64
 287:              // *                             3000             6000       NS = 128
 288:              // *                             6000             infinity   NS = 256
 289:              // *
 290:              // *                    (+)  By default matrices of this order are
 291:              // *                         passed to the implicit double shift routine
 292:              // *                         xLAHQR.  See IPARMQ(ISPEC=12) above.   These
 293:              // *                         values of NS are used only in case of a rare
 294:              // *                         xLAHQR failure.
 295:              // *
 296:              // *                    (**) The asterisks (**) indicate an ad-hoc
 297:              // *                         function increasing from 10 to 64.
 298:              // *
 299:              // *       IPARMQ(ISPEC=16) Select structured matrix multiply.
 300:              // *                        (See ISPEC=16 above for details.)
 301:              // *                        Default: 3.
 302:              // *
 303:              // *     ================================================================
 304:              // *     .. Parameters ..
 305:              // *     ..
 306:              // *     .. Local Scalars ..
 307:              // *     ..
 308:              // *     .. Intrinsic Functions ..
 309:              //      INTRINSIC          LOG, MAX, MOD, NINT, REAL;
 310:              // *     ..
 311:              // *     .. Executable Statements ..
 312:   
 313:              #endregion
 314:   
 315:   
 316:              #region Body
 317:              
 318:              if ((ISPEC == ISHFTS) || (ISPEC == INWIN) || (ISPEC == IACC22))
 319:              {
 320:                  // *
 321:                  // *        ==== Set the number simultaneous shifts ====
 322:                  // *
 323:                  NH = IHI - ILO + 1;
 324:                  NS = 2;
 325:                  if (NH >= 30) NS = 4;
 326:                  if (NH >= 60) NS = 10;
 327:                  if (NH >= 150) NS = (int)Math.Max(10, NH / Math.Round(Math.Log(Convert.ToSingle(NH)) / Math.Log(TWO)));
 328:                  if (NH >= 590) NS = 64;
 329:                  if (NH >= 3000) NS = 128;
 330:                  if (NH >= 6000) NS = 256;
 331:                  NS = Math.Max(2, NS - FortranLib.Mod(NS,2));
 332:              }
 333:              // *
 334:              if (ISPEC == INMIN)
 335:              {
 336:                  // *
 337:                  // *
 338:                  // *        ===== Matrices of order smaller than NMIN get sent
 339:                  // *        .     to xLAHQR, the classic double shift algorithm.
 340:                  // *        .     This must be at least 11. ====
 341:                  // *
 342:                  iparmq = NMIN;
 343:                  // *
 344:              }
 345:              else
 346:              {
 347:                  if (ISPEC == INIBL)
 348:                  {
 349:                      // *
 350:                      // *        ==== INIBL: skip a multi-shift qr iteration and
 351:                      // *        .    whenever aggressive early deflation finds
 352:                      // *        .    at least (NIBBLE*(window size)/100) deflations. ====
 353:                      // *
 354:                      iparmq = NIBBLE;
 355:                      // *
 356:                  }
 357:                  else
 358:                  {
 359:                      if (ISPEC == ISHFTS)
 360:                      {
 361:                          // *
 362:                          // *        ==== NSHFTS: The number of simultaneous shifts =====
 363:                          // *
 364:                          iparmq = NS;
 365:                          // *
 366:                      }
 367:                      else
 368:                      {
 369:                          if (ISPEC == INWIN)
 370:                          {
 371:                              // *
 372:                              // *        ==== NW: deflation window size.  ====
 373:                              // *
 374:                              if (NH <= KNWSWP)
 375:                              {
 376:                                  iparmq = NS;
 377:                              }
 378:                              else
 379:                              {
 380:                                  iparmq = 3 * NS / 2;
 381:                              }
 382:                              // *
 383:                          }
 384:                          else
 385:                          {
 386:                              if (ISPEC == IACC22)
 387:                              {
 388:                                  // *
 389:                                  // *        ==== IACC22: Whether to accumulate reflections
 390:                                  // *        .     before updating the far-from-diagonal elements
 391:                                  // *        .     and whether to use 2-by-2 block structure while
 392:                                  // *        .     doing it.  A small amount of work could be saved
 393:                                  // *        .     by making this choice dependent also upon the
 394:                                  // *        .     NH=IHI-ILO+1.
 395:                                  // *
 396:                                  iparmq = 0;
 397:                                  if (NS >= KACMIN) iparmq = 1;
 398:                                  if (NS >= K22MIN) iparmq = 2;
 399:                                  // *
 400:                              }
 401:                              else
 402:                              {
 403:                                  // *        ===== invalid value of ispec =====
 404:                                  iparmq =  - 1;
 405:                                  // *
 406:                              }
 407:                          }
 408:                      }
 409:                  }
 410:              }
 411:              // *
 412:              // *     ==== End of IPARMQ ====
 413:              // *
 414:          return iparmq;
 415:   
 416:              #endregion
 417:   
 418:          }
 419:      }
 420:  }