/* -- translated by f2c (version 20201020 (for_lapack)). -- */ #include "f2c.h" //> \brief \b IEEECK // // =========== DOCUMENTATION =========== // // Online html documentation available at // http://www.netlib.org/lapack/explore-html/ // //> \htmlonly //> Download IEEECK + dependencies //> //> [TGZ] //> //> [ZIP] //> //> [TXT] //> \endhtmlonly // // Definition: // =========== // // INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) // // .. Scalar Arguments .. // INTEGER ISPEC // REAL ONE, ZERO // .. // // //> \par Purpose: // ============= //> //> \verbatim //> //> IEEECK is called from the ILAENV to verify that Infinity and //> possibly NaN arithmetic is safe (i.e. will not trap). //> \endverbatim // // Arguments: // ========== // //> \param[in] ISPEC //> \verbatim //> ISPEC is INTEGER //> Specifies whether to test just for inifinity arithmetic //> or whether to test for infinity and NaN arithmetic. //> = 0: Verify infinity arithmetic only. //> = 1: Verify infinity and NaN arithmetic. //> \endverbatim //> //> \param[in] ZERO //> \verbatim //> ZERO is REAL //> Must contain the value 0.0 //> This is passed to prevent the compiler from optimizing //> away this code. //> \endverbatim //> //> \param[in] ONE //> \verbatim //> ONE is REAL //> Must contain the value 1.0 //> This is passed to prevent the compiler from optimizing //> away this code. //> //> RETURN VALUE: INTEGER //> = 0: Arithmetic failed to produce the correct answers //> = 1: Arithmetic produced the correct answers //> \endverbatim // // Authors: // ======== // //> \author Univ. of Tennessee //> \author Univ. of California Berkeley //> \author Univ. of Colorado Denver //> \author NAG Ltd. // //> \date December 2016 // //> \ingroup OTHERauxiliary // // ===================================================================== int ieeeck_(int *ispec, float *zero, float *one) { // System generated locals int ret_val; // Local variables float nan1, nan2, nan3, nan4, nan5, nan6, neginf, posinf, negzro, newzro; // // -- LAPACK auxiliary routine (version 3.7.0) -- // -- LAPACK is a software package provided by Univ. of Tennessee, -- // -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- // December 2016 // // .. Scalar Arguments .. // .. // // ===================================================================== // // .. Local Scalars .. // .. // .. Executable Statements .. ret_val = 1; posinf = *one / *zero; if (posinf <= *one) { ret_val = 0; return ret_val; } neginf = -(*one) / *zero; if (neginf >= *zero) { ret_val = 0; return ret_val; } negzro = *one / (neginf + *one); if (negzro != *zero) { ret_val = 0; return ret_val; } neginf = *one / negzro; if (neginf >= *zero) { ret_val = 0; return ret_val; } newzro = negzro + *zero; if (newzro != *zero) { ret_val = 0; return ret_val; } posinf = *one / newzro; if (posinf <= *one) { ret_val = 0; return ret_val; } neginf *= posinf; if (neginf >= *zero) { ret_val = 0; return ret_val; } posinf *= posinf; if (posinf <= *one) { ret_val = 0; return ret_val; } // // // // // Return if we were only asked to check infinity arithmetic // if (*ispec == 0) { return ret_val; } nan1 = posinf + neginf; nan2 = posinf / neginf; nan3 = posinf / posinf; nan4 = posinf * *zero; nan5 = neginf * negzro; nan6 = nan5 * *zero; if (nan1 == nan1) { ret_val = 0; return ret_val; } if (nan2 == nan2) { ret_val = 0; return ret_val; } if (nan3 == nan3) { ret_val = 0; return ret_val; } if (nan4 == nan4) { ret_val = 0; return ret_val; } if (nan5 == nan5) { ret_val = 0; return ret_val; } if (nan6 == nan6) { ret_val = 0; return ret_val; } return ret_val; } // ieeeck_ /* -- translated by f2c (version 20201020 (for_lapack)). -- */ //> \brief \b ILAENV // // =========== DOCUMENTATION =========== // // Online html documentation available at // http://www.netlib.org/lapack/explore-html/ // //> \htmlonly //> Download ILAENV + dependencies //> //> [TGZ] //> //> [ZIP] //> //> [TXT] //> \endhtmlonly // // Definition: // =========== // // INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) // // .. Scalar Arguments .. // CHARACTER*( * ) NAME, OPTS // INTEGER ISPEC, N1, N2, N3, N4 // .. // // //> \par Purpose: // ============= //> //> \verbatim //> //> ILAENV is called from the LAPACK routines to choose problem-dependent //> parameters for the local environment. See ISPEC for a description of //> the parameters. //> //> ILAENV returns an INTEGER //> if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC //> if ILAENV < 0: if ILAENV = -k, the k-th argument had an illegal value. //> //> This version provides a set of parameters which should give good, //> but not optimal, performance on many of the currently available //> computers. Users are encouraged to modify this subroutine to set //> the tuning parameters for their particular machine using the option //> and problem size information in the arguments. //> //> This routine will not function correctly if it is converted to all //> lower case. Converting it to all upper case is allowed. //> \endverbatim // // Arguments: // ========== // //> \param[in] ISPEC //> \verbatim //> ISPEC is INTEGER //> Specifies the parameter to be returned as the value of //> ILAENV. //> = 1: the optimal blocksize; if this value is 1, an unblocked //> algorithm will give the best performance. //> = 2: the minimum block size for which the block routine //> should be used; if the usable block size is less than //> this value, an unblocked routine should be used. //> = 3: the crossover point (in a block routine, for N less //> than this value, an unblocked routine should be used) //> = 4: the number of shifts, used in the nonsymmetric //> eigenvalue routines (DEPRECATED) //> = 5: the minimum column dimension for blocking to be used; //> rectangular blocks must have dimension at least k by m, //> where k is given by ILAENV(2,...) and m by ILAENV(5,...) //> = 6: the crossover point for the SVD (when reducing an m by n //> matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds //> this value, a QR factorization is used first to reduce //> the matrix to a triangular form.) //> = 7: the number of processors //> = 8: the crossover point for the multishift QR method //> for nonsymmetric eigenvalue problems (DEPRECATED) //> = 9: maximum size of the subproblems at the bottom of the //> computation tree in the divide-and-conquer algorithm //> (used by xGELSD and xGESDD) //> =10: ieee NaN arithmetic can be trusted not to trap //> =11: infinity arithmetic can be trusted not to trap //> 12 <= ISPEC <= 16: //> xHSEQR or related subroutines, //> see IPARMQ for detailed explanation //> \endverbatim //> //> \param[in] NAME //> \verbatim //> NAME is CHARACTER*(*) //> The name of the calling subroutine, in either upper case or //> lower case. //> \endverbatim //> //> \param[in] OPTS //> \verbatim //> OPTS is CHARACTER*(*) //> The character options to the subroutine NAME, concatenated //> into a single character string. For example, UPLO = 'U', //> TRANS = 'T', and DIAG = 'N' for a triangular routine would //> be specified as OPTS = 'UTN'. //> \endverbatim //> //> \param[in] N1 //> \verbatim //> N1 is INTEGER //> \endverbatim //> //> \param[in] N2 //> \verbatim //> N2 is INTEGER //> \endverbatim //> //> \param[in] N3 //> \verbatim //> N3 is INTEGER //> \endverbatim //> //> \param[in] N4 //> \verbatim //> N4 is INTEGER //> Problem dimensions for the subroutine NAME; these may not all //> be required. //> \endverbatim // // Authors: // ======== // //> \author Univ. of Tennessee //> \author Univ. of California Berkeley //> \author Univ. of Colorado Denver //> \author NAG Ltd. // //> \date November 2019 // //> \ingroup OTHERauxiliary // //> \par Further Details: // ===================== //> //> \verbatim //> //> The following conventions have been used when calling ILAENV from the //> LAPACK routines: //> 1) OPTS is a concatenation of all of the character options to //> subroutine NAME, in the same order that they appear in the //> argument list for NAME, even if they are not used in determining //> the value of the parameter specified by ISPEC. //> 2) The problem dimensions N1, N2, N3, N4 are specified in the order //> that they appear in the argument list for NAME. N1 is used //> first, N2 second, and so on, and unused problem dimensions are //> passed a value of -1. //> 3) The parameter value returned by ILAENV is checked for validity in //> the calling subroutine. For example, ILAENV is used to retrieve //> the optimal blocksize for STRTRI as follows: //> //> NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) //> IF( NB.LE.1 ) NB = MAX( 1, N ) //> \endverbatim //> // ===================================================================== int ilaenv_(int *ispec, char *name__, char *opts, int *n1, int *n2, int *n3, int *n4) { // Table of constant values int c__1 = 1; float c_b174 = 0.f; float c_b175 = 1.f; int c__0 = 0; // System generated locals int ret_val; // Local variables int twostage; int i__; char c1[1+1]={'\0'}, c2[2+1]={'\0'}, c3[3+1]={'\0'}, c4[2+1]={'\0'}; int ic, nb, iz, nx; int cname; int nbmin; int sname; extern int ieeeck_(int *, float *, float *); char subnam[16+1]={'\0'}; extern int iparmq_(int *, char *, char *, int *, int *, int *, int *); // // -- LAPACK auxiliary routine (version 3.9.0) -- // -- LAPACK is a software package provided by Univ. of Tennessee, -- // -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- // November 2019 // // .. Scalar Arguments .. // .. // // ===================================================================== // // .. Local Scalars .. // .. // .. Intrinsic Functions .. // .. // .. External Functions .. // .. // .. Executable Statements .. // switch (*ispec) { case 1: goto L10; case 2: goto L10; case 3: goto L10; case 4: goto L80; case 5: goto L90; case 6: goto L100; case 7: goto L110; case 8: goto L120; case 9: goto L130; case 10: goto L140; case 11: goto L150; case 12: goto L160; case 13: goto L160; case 14: goto L160; case 15: goto L160; case 16: goto L160; } // // Invalid value for ISPEC // ret_val = -1; return ret_val; L10: // // Convert NAME to upper case if the first character is lower case. // ret_val = 1; s_copy(subnam, name__, (int)16); ic = *(unsigned char *)subnam; iz = 'Z'; if (iz == 90 || iz == 122) { // // ASCII character set // if (ic >= 97 && ic <= 122) { *(unsigned char *)subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 97 && ic <= 122) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32); } // L20: } } } else if (iz == 233 || iz == 169) { // // EBCDIC character set // if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { *(unsigned char *)subnam = (char) (ic + 64); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic + 64); } // L30: } } } else if (iz == 218 || iz == 250) { // // Prime machines: ASCII+128 // if (ic >= 225 && ic <= 250) { *(unsigned char *)subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 225 && ic <= 250) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32); } // L40: } } } *(unsigned char *)c1 = *(unsigned char *)subnam; sname = *(unsigned char *)c1 == 'S' || *(unsigned char *)c1 == 'D'; cname = *(unsigned char *)c1 == 'C' || *(unsigned char *)c1 == 'Z'; if (! (cname || sname)) { return ret_val; } s_copy(c2, subnam + 1, (int)2); s_copy(c3, subnam + 3, (int)3); s_copy(c4, c3 + 1, (int)2); twostage = i_len(subnam) >= 11 && *(unsigned char *)&subnam[10] == '2'; switch (*ispec) { case 1: goto L50; case 2: goto L60; case 3: goto L70; } L50: // // ISPEC = 1: block size // // In these examples, separate code is provided for setting NB for // real and complex. We assume that NB will take the same value in // single or double precision. // nb = 1; if (s_cmp(subnam + 1, "LAORH") == 0) { // // This is for *LAORHR_GETRFNP routine // if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp(c2, "GE") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { nb = 64; } else { nb = 64; } } else if (s_cmp(c3, "QRF") == 0 || s_cmp(c3, "RQF") == 0 || s_cmp(c3, "LQF") == 0 || s_cmp(c3, "QLF") == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp(c3, "QR ") == 0) { if (*n3 == 1) { if (sname) { // M*N if (*n1 * *n2 <= 131072 || *n1 <= 8192) { nb = *n1; } else { nb = 32768 / *n2; } } else { if (*n1 * *n2 <= 131072 || *n1 <= 8192) { nb = *n1; } else { nb = 32768 / *n2; } } } else { if (sname) { nb = 1; } else { nb = 1; } } } else if (s_cmp(c3, "LQ ") == 0) { if (*n3 == 2) { if (sname) { // M*N if (*n1 * *n2 <= 131072 || *n1 <= 8192) { nb = *n1; } else { nb = 32768 / *n2; } } else { if (*n1 * *n2 <= 131072 || *n1 <= 8192) { nb = *n1; } else { nb = 32768 / *n2; } } } else { if (sname) { nb = 1; } else { nb = 1; } } } else if (s_cmp(c3, "HRD") == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp(c3, "BRD") == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp(c3, "TRI") == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp(c2, "PO") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp(c2, "SY") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { if (twostage) { nb = 192; } else { nb = 64; } } else { if (twostage) { nb = 192; } else { nb = 64; } } } else if (sname && s_cmp(c3, "TRD") == 0) { nb = 32; } else if (sname && s_cmp(c3, "GST") == 0) { nb = 64; } } else if (cname && s_cmp(c2, "HE") == 0) { if (s_cmp(c3, "TRF") == 0) { if (twostage) { nb = 192; } else { nb = 64; } } else if (s_cmp(c3, "TRD") == 0) { nb = 32; } else if (s_cmp(c3, "GST") == 0) { nb = 64; } } else if (sname && s_cmp(c2, "OR") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nb = 32; } } else if (*(unsigned char *)c3 == 'M') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nb = 32; } } } else if (cname && s_cmp(c2, "UN") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nb = 32; } } else if (*(unsigned char *)c3 == 'M') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nb = 32; } } } else if (s_cmp(c2, "GB") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { if (*n4 <= 64) { nb = 1; } else { nb = 32; } } else { if (*n4 <= 64) { nb = 1; } else { nb = 32; } } } } else if (s_cmp(c2, "PB") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { if (*n2 <= 64) { nb = 1; } else { nb = 32; } } else { if (*n2 <= 64) { nb = 1; } else { nb = 32; } } } } else if (s_cmp(c2, "TR") == 0) { if (s_cmp(c3, "TRI") == 0) { if (sname) { nb = 64; } else { nb = 64; } } else if (s_cmp(c3, "EVC") == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp(c2, "LA") == 0) { if (s_cmp(c3, "UUM") == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (sname && s_cmp(c2, "ST") == 0) { if (s_cmp(c3, "EBZ") == 0) { nb = 1; } } else if (s_cmp(c2, "GG") == 0) { nb = 32; if (s_cmp(c3, "HD3") == 0) { if (sname) { nb = 32; } else { nb = 32; } } } ret_val = nb; return ret_val; L60: // // ISPEC = 2: minimum block size // nbmin = 2; if (s_cmp(c2, "GE") == 0) { if (s_cmp(c3, "QRF") == 0 || s_cmp(c3, "RQF") == 0 || s_cmp(c3, "LQF") == 0 || s_cmp(c3, "QLF") == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp(c3, "HRD") == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp(c3, "BRD") == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp(c3, "TRI") == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } } else if (s_cmp(c2, "SY") == 0) { if (s_cmp(c3, "TRF") == 0) { if (sname) { nbmin = 8; } else { nbmin = 8; } } else if (sname && s_cmp(c3, "TRD") == 0) { nbmin = 2; } } else if (cname && s_cmp(c2, "HE") == 0) { if (s_cmp(c3, "TRD") == 0) { nbmin = 2; } } else if (sname && s_cmp(c2, "OR") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nbmin = 2; } } else if (*(unsigned char *)c3 == 'M') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nbmin = 2; } } } else if (cname && s_cmp(c2, "UN") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nbmin = 2; } } else if (*(unsigned char *)c3 == 'M') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nbmin = 2; } } } else if (s_cmp(c2, "GG") == 0) { nbmin = 2; if (s_cmp(c3, "HD3") == 0) { nbmin = 2; } } ret_val = nbmin; return ret_val; L70: // // ISPEC = 3: crossover point // nx = 0; if (s_cmp(c2, "GE") == 0) { if (s_cmp(c3, "QRF") == 0 || s_cmp(c3, "RQF") == 0 || s_cmp(c3, "LQF") == 0 || s_cmp(c3, "QLF") == 0) { if (sname) { nx = 128; } else { nx = 128; } } else if (s_cmp(c3, "HRD") == 0) { if (sname) { nx = 128; } else { nx = 128; } } else if (s_cmp(c3, "BRD") == 0) { if (sname) { nx = 128; } else { nx = 128; } } } else if (s_cmp(c2, "SY") == 0) { if (sname && s_cmp(c3, "TRD") == 0) { nx = 32; } } else if (cname && s_cmp(c2, "HE") == 0) { if (s_cmp(c3, "TRD") == 0) { nx = 32; } } else if (sname && s_cmp(c2, "OR") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nx = 128; } } } else if (cname && s_cmp(c2, "UN") == 0) { if (*(unsigned char *)c3 == 'G') { if (s_cmp(c4, "QR") == 0 || s_cmp(c4, "RQ") == 0 || s_cmp(c4, "LQ") == 0 || s_cmp(c4, "QL") == 0 || s_cmp(c4, "HR") == 0 || s_cmp(c4, "TR") == 0 || s_cmp(c4, "BR") == 0) { nx = 128; } } } else if (s_cmp(c2, "GG") == 0) { nx = 128; if (s_cmp(c3, "HD3") == 0) { nx = 128; } } ret_val = nx; return ret_val; L80: // // ISPEC = 4: number of shifts (used by xHSEQR) // ret_val = 6; return ret_val; L90: // // ISPEC = 5: minimum column dimension (not used) // ret_val = 2; return ret_val; L100: // // ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) // ret_val = (int) ((float) min(*n1,*n2) * 1.6f); return ret_val; L110: // // ISPEC = 7: number of processors (not used) // ret_val = 1; return ret_val; L120: // // ISPEC = 8: crossover point for multishift (used by xHSEQR) // ret_val = 50; return ret_val; L130: // // ISPEC = 9: maximum size of the subproblems at the bottom of the // computation tree in the divide-and-conquer algorithm // (used by xGELSD and xGESDD) // ret_val = 25; return ret_val; L140: // // ISPEC = 10: ieee NaN arithmetic can be trusted not to trap // // ILAENV = 0 ret_val = 1; if (ret_val == 1) { ret_val = ieeeck_(&c__1, &c_b174, &c_b175); } return ret_val; L150: // // ISPEC = 11: infinity arithmetic can be trusted not to trap // // ILAENV = 0 ret_val = 1; if (ret_val == 1) { ret_val = ieeeck_(&c__0, &c_b174, &c_b175); } return ret_val; L160: // // 12 <= ISPEC <= 16: xHSEQR or related subroutines. // ret_val = iparmq_(ispec, name__, opts, n1, n2, n3, n4); return ret_val; // // End of ILAENV // } // ilaenv_ /* -- translated by f2c (version 20201020 (for_lapack)). -- */ //> \brief \b IPARMQ // // =========== DOCUMENTATION =========== // // Online html documentation available at // http://www.netlib.org/lapack/explore-html/ // //> \htmlonly //> Download IPARMQ + dependencies //> //> [TGZ] //> //> [ZIP] //> //> [TXT] //> \endhtmlonly // // Definition: // =========== // // INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK ) // // .. Scalar Arguments .. // INTEGER IHI, ILO, ISPEC, LWORK, N // CHARACTER NAME*( * ), OPTS*( * ) // // //> \par Purpose: // ============= //> //> \verbatim //> //> This program sets problem and machine dependent parameters //> useful for xHSEQR and related subroutines for eigenvalue //> problems. It is called whenever //> IPARMQ is called with 12 <= ISPEC <= 16 //> \endverbatim // // Arguments: // ========== // //> \param[in] ISPEC //> \verbatim //> ISPEC is INTEGER //> ISPEC specifies which tunable parameter IPARMQ should //> return. //> //> ISPEC=12: (INMIN) Matrices of order nmin or less //> are sent directly to xLAHQR, the implicit //> double shift QR algorithm. NMIN must be //> at least 11. //> //> ISPEC=13: (INWIN) Size of the deflation window. //> This is best set greater than or equal to //> the number of simultaneous shifts NS. //> Larger matrices benefit from larger deflation //> windows. //> //> ISPEC=14: (INIBL) Determines when to stop nibbling and //> invest in an (expensive) multi-shift QR sweep. //> If the aggressive early deflation subroutine //> finds LD converged eigenvalues from an order //> NW deflation window and LD > (NW*NIBBLE)/100, //> then the next QR sweep is skipped and early //> deflation is applied immediately to the //> remaining active diagonal block. Setting //> IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a //> multi-shift QR sweep whenever early deflation //> finds a converged eigenvalue. Setting //> IPARMQ(ISPEC=14) greater than or equal to 100 //> prevents TTQRE from skipping a multi-shift //> QR sweep. //> //> ISPEC=15: (NSHFTS) The number of simultaneous shifts in //> a multi-shift QR iteration. //> //> ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the //> following meanings. //> 0: During the multi-shift QR/QZ sweep, //> blocked eigenvalue reordering, blocked //> Hessenberg-triangular reduction, //> reflections and/or rotations are not //> accumulated when updating the //> far-from-diagonal matrix entries. //> 1: During the multi-shift QR/QZ sweep, //> blocked eigenvalue reordering, blocked //> Hessenberg-triangular reduction, //> reflections and/or rotations are //> accumulated, and matrix-matrix //> multiplication is used to update the //> far-from-diagonal matrix entries. //> 2: During the multi-shift QR/QZ sweep, //> blocked eigenvalue reordering, blocked //> Hessenberg-triangular reduction, //> reflections and/or rotations are //> accumulated, and 2-by-2 block structure //> is exploited during matrix-matrix //> multiplies. //> (If xTRMM is slower than xGEMM, then //> IPARMQ(ISPEC=16)=1 may be more efficient than //> IPARMQ(ISPEC=16)=2 despite the greater level of //> arithmetic work implied by the latter choice.) //> \endverbatim //> //> \param[in] NAME //> \verbatim //> NAME is CHARACTER string //> Name of the calling subroutine //> \endverbatim //> //> \param[in] OPTS //> \verbatim //> OPTS is CHARACTER string //> This is a concatenation of the string arguments to //> TTQRE. //> \endverbatim //> //> \param[in] N //> \verbatim //> N is INTEGER //> N is the order of the Hessenberg matrix H. //> \endverbatim //> //> \param[in] ILO //> \verbatim //> ILO is INTEGER //> \endverbatim //> //> \param[in] IHI //> \verbatim //> IHI is INTEGER //> It is assumed that H is already upper triangular //> in rows and columns 1:ILO-1 and IHI+1:N. //> \endverbatim //> //> \param[in] LWORK //> \verbatim //> LWORK is INTEGER //> The amount of workspace available. //> \endverbatim // // Authors: // ======== // //> \author Univ. of Tennessee //> \author Univ. of California Berkeley //> \author Univ. of Colorado Denver //> \author NAG Ltd. // //> \date June 2017 // //> \ingroup OTHERauxiliary // //> \par Further Details: // ===================== //> //> \verbatim //> //> Little is known about how best to choose these parameters. //> It is possible to use different values of the parameters //> for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR. //> //> It is probably best to choose different parameters for //> different matrices and different parameters at different //> times during the iteration, but this has not been //> implemented --- yet. //> //> //> The best choices of most of the parameters depend //> in an ill-understood way on the relative execution //> rate of xLAQR3 and xLAQR5 and on the nature of each //> particular eigenvalue problem. Experiment may be the //> only practical way to determine which choices are most //> effective. //> //> Following is a list of default values supplied by IPARMQ. //> These defaults may be adjusted in order to attain better //> performance in any particular computational environment. //> //> IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point. //> Default: 75. (Must be at least 11.) //> //> IPARMQ(ISPEC=13) Recommended deflation window size. //> This depends on ILO, IHI and NS, the //> number of simultaneous shifts returned //> by IPARMQ(ISPEC=15). The default for //> (IHI-ILO+1) <= 500 is NS. The default //> for (IHI-ILO+1) > 500 is 3*NS/2. //> //> IPARMQ(ISPEC=14) Nibble crossover point. Default: 14. //> //> IPARMQ(ISPEC=15) Number of simultaneous shifts, NS. //> a multi-shift QR iteration. //> //> If IHI-ILO+1 is ... //> //> greater than ...but less ... the //> or equal to ... than default is //> //> 0 30 NS = 2+ //> 30 60 NS = 4+ //> 60 150 NS = 10 //> 150 590 NS = ** //> 590 3000 NS = 64 //> 3000 6000 NS = 128 //> 6000 infinity NS = 256 //> //> (+) By default matrices of this order are //> passed to the implicit double shift routine //> xLAHQR. See IPARMQ(ISPEC=12) above. These //> values of NS are used only in case of a rare //> xLAHQR failure. //> //> (**) The asterisks (**) indicate an ad-hoc //> function increasing from 10 to 64. //> //> IPARMQ(ISPEC=16) Select structured matrix multiply. //> (See ISPEC=16 above for details.) //> Default: 3. //> \endverbatim //> // ===================================================================== int iparmq_(int *ispec, char *name__, char *opts, int *n, int *ilo, int *ihi, int *lwork) { // System generated locals int ret_val, i__1, i__2; float r__1; // Local variables int i__, ic, nh, ns, iz; char subnam[6+1]={'\0'}; // // -- LAPACK auxiliary routine (version 3.7.1) -- // -- LAPACK is a software package provided by Univ. of Tennessee, -- // -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- // June 2017 // // .. Scalar Arguments .. // // ================================================================ // .. Parameters .. // .. // .. Local Scalars .. // .. // .. Intrinsic Functions .. // .. // .. Executable Statements .. if (*ispec == 15 || *ispec == 13 || *ispec == 16) { // // ==== Set the number simultaneous shifts ==== // nh = *ihi - *ilo + 1; ns = 2; if (nh >= 30) { ns = 4; } if (nh >= 60) { ns = 10; } if (nh >= 150) { // Computing MAX r__1 = log((float) nh) / log(2.f); i__1 = 10, i__2 = nh / i_nint(&r__1); ns = max(i__1,i__2); } if (nh >= 590) { ns = 64; } if (nh >= 3000) { ns = 128; } if (nh >= 6000) { ns = 256; } // Computing MAX i__1 = 2, i__2 = ns - ns % 2; ns = max(i__1,i__2); } if (*ispec == 12) { // // // ===== Matrices of order smaller than NMIN get sent // . to xLAHQR, the classic double shift algorithm. // . This must be at least 11. ==== // ret_val = 75; } else if (*ispec == 14) { // // ==== INIBL: skip a multi-shift qr iteration and // . whenever aggressive early deflation finds // . at least (NIBBLE*(window size)/100) deflations. ==== // ret_val = 14; } else if (*ispec == 15) { // // ==== NSHFTS: The number of simultaneous shifts ===== // ret_val = ns; } else if (*ispec == 13) { // // ==== NW: deflation window size. ==== // if (nh <= 500) { ret_val = ns; } else { ret_val = ns * 3 / 2; } } else if (*ispec == 16) { // // ==== IACC22: Whether to accumulate reflections // . before updating the far-from-diagonal elements // . and whether to use 2-by-2 block structure while // . doing it. A small amount of work could be saved // . by making this choice dependent also upon the // . NH=IHI-ILO+1. // // // Convert NAME to upper case if the first character is lower case. // ret_val = 0; s_copy(subnam, name__, (int)6); ic = *(unsigned char *)subnam; iz = 'Z'; if (iz == 90 || iz == 122) { // // ASCII character set // if (ic >= 97 && ic <= 122) { *(unsigned char *)subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 97 && ic <= 122) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32); } } } } else if (iz == 233 || iz == 169) { // // EBCDIC character set // if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { *(unsigned char *)subnam = (char) (ic + 64); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic + 64); } } } } else if (iz == 218 || iz == 250) { // // Prime machines: ASCII+128 // if (ic >= 225 && ic <= 250) { *(unsigned char *)subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = *(unsigned char *)&subnam[i__ - 1]; if (ic >= 225 && ic <= 250) { *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32); } } } } if (s_cmp(subnam + 1, "GGHRD") == 0 || s_cmp(subnam + 1, "GGHD3") == 0) { ret_val = 1; if (nh >= 14) { ret_val = 2; } } else if (s_cmp(subnam + 3, "EXC") == 0) { if (nh >= 14) { ret_val = 1; } if (nh >= 14) { ret_val = 2; } } else if (s_cmp(subnam + 1, "HSEQR") == 0 || s_cmp(subnam + 1, "LAQR" ) == 0) { if (ns >= 14) { ret_val = 1; } if (ns >= 14) { ret_val = 2; } } } else { // ===== invalid value of ispec ===== ret_val = -1; } // // ==== End of IPARMQ ==== // return ret_val; } // iparmq_