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: }