/* Subroutine */ int sdrvgg_(integer *nsizes, integer *nn, integer *ntypes, logical *dotype, integer *iseed, real *thresh, real *thrshn, integer * nounit, real *a, integer *lda, real *b, real *s, real *t, real *s2, real *t2, real *q, integer *ldq, real *z__, real *alphr1, real * alphi1, real *beta1, real *alphr2, real *alphi2, real *beta2, real * vl, real *vr, real *work, integer *lwork, real *result, integer *info) { /* Initialized data */ static integer kclass[26] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2, 2,2,2,3 }; static integer kbmagn[26] = { 1,1,1,1,1,1,1,1,3,2,3,2,2,3,1,1,1,1,1,1,1,3, 2,3,2,1 }; static integer ktrian[26] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,1,1,1 }; static integer iasign[26] = { 0,0,0,0,0,0,2,0,2,2,0,0,2,2,2,0,2,0,0,0,2,2, 2,2,2,0 }; static integer ibsign[26] = { 0,0,0,0,0,0,0,2,0,0,2,2,0,0,2,0,2,0,0,0,0,0, 0,0,0,0 }; static integer kz1[6] = { 0,1,2,1,3,3 }; static integer kz2[6] = { 0,0,1,2,1,1 }; static integer kadd[6] = { 0,0,0,0,3,2 }; static integer katype[26] = { 0,1,0,1,2,3,4,1,4,4,1,1,4,4,4,2,4,5,8,7,9,4, 4,4,4,0 }; static integer kbtype[26] = { 0,0,1,1,2,-3,1,4,1,1,4,4,1,1,-4,2,-4,8,8,8, 8,8,8,8,8,0 }; static integer kazero[26] = { 1,1,1,1,1,1,2,1,2,2,1,1,2,2,3,1,3,5,5,5,5,3, 3,3,3,1 }; static integer kbzero[26] = { 1,1,1,1,1,1,1,2,1,1,2,2,1,1,4,1,4,6,6,6,6,4, 4,4,4,1 }; static integer kamagn[26] = { 1,1,1,1,1,1,1,1,2,3,2,3,2,3,1,1,1,1,1,1,1,2, 3,3,2,1 }; /* Format strings */ static char fmt_9999[] = "(\002 SDRVGG: \002,a,\002 returned INFO=\002,i" "6,\002.\002,/9x,\002N=\002,i6,\002, JTYPE=\002,i6,\002, ISEED=" "(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9997[] = "(\002 SDRVGG: SGET53 returned INFO=\002,i1," "\002 for eigenvalue \002,i6,\002.\002,/9x,\002N=\002,i6,\002, JT" "YPE=\002,i6,\002, ISEED=(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9996[] = "(\002 SDRVGG: S not in Schur form at eigenvalu" "e \002,i6,\002.\002,/9x,\002N=\002,i6,\002, JTYPE=\002,i6,\002, " "ISEED=(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9998[] = "(\002 SDRVGG: \002,a,\002 Eigenvectors from" " \002,a,\002 incorrectly \002,\002normalized.\002,/\002 Bits of " "error=\002,0p,g10.3,\002,\002,9x,\002N=\002,i6,\002, JTYPE=\002," "i6,\002, ISEED=(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9995[] = "(/1x,a3,\002 -- Real Generalized eigenvalue pr" "oblem driver\002)"; static char fmt_9994[] = "(\002 Matrix types (see SDRVGG for details):" " \002)"; static char fmt_9993[] = "(\002 Special Matrices:\002,23x,\002(J'=transp" "osed Jordan block)\002,/\002 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I" ") 5=(J',J') \002,\0026=(diag(J',I), diag(I,J'))\002,/\002 Diag" "onal Matrices: ( \002,\002D=diag(0,1,2,...) )\002,/\002 7=(D," "I) 9=(large*D, small*I\002,\002) 11=(large*I, small*D) 13=(l" "arge*D, large*I)\002,/\002 8=(I,D) 10=(small*D, large*I) 12=" "(small*I, large*D) \002,\002 14=(small*D, small*I)\002,/\002 15" "=(D, reversed D)\002)"; static char fmt_9992[] = "(\002 Matrices Rotated by Random \002,a,\002 M" "atrices U, V:\002,/\002 16=Transposed Jordan Blocks " " 19=geometric \002,\002alpha, beta=0,1\002,/\002 17=arithm. alp" "ha&beta \002,\002 20=arithmetic alpha, beta=0," "1\002,/\002 18=clustered \002,\002alpha, beta=0,1 21" "=random alpha, beta=0,1\002,/\002 Large & Small Matrices:\002," "/\002 22=(large, small) \002,\00223=(small,large) 24=(smal" "l,small) 25=(large,large)\002,/\002 26=random O(1) matrices" ".\002)"; static char fmt_9991[] = "(/\002 Tests performed: (S is Schur, T is tri" "angular, \002,\002Q and Z are \002,a,\002,\002,/20x,\002l and r " "are the appropriate left and right\002,/19x,\002eigenvectors, re" "sp., a is alpha, b is beta, and\002,/19x,a,\002 means \002,a," "\002.)\002,/\002 1 = | A - Q S Z\002,a,\002 | / ( |A| n ulp ) " " 2 = | B - Q T Z\002,a,\002 | / ( |B| n ulp )\002,/\002 3 = | " "I - QQ\002,a,\002 | / ( n ulp ) 4 = | I - ZZ\002,a" ",\002 | / ( n ulp )\002,/\002 5 = difference between (alpha,beta" ") and diagonals of\002,\002 (S,T)\002,/\002 6 = max | ( b A - a " "B )\002,a,\002 l | / const. 7 = max | ( b A - a B ) r | / cons" "t.\002,/1x)"; static char fmt_9990[] = "(\002 Matrix order=\002,i5,\002, type=\002,i2" ",\002, seed=\002,4(i4,\002,\002),\002 result \002,i3,\002 is\002" ",0p,f8.2)"; static char fmt_9989[] = "(\002 Matrix order=\002,i5,\002, type=\002,i2" ",\002, seed=\002,4(i4,\002,\002),\002 result \002,i3,\002 is\002" ",1p,e10.3)"; /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, s_dim1, s_offset, s2_dim1, s2_offset, t_dim1, t_offset, t2_dim1, t2_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4; real r__1, r__2, r__3, r__4, r__5, r__6, r__7, r__8, r__9, r__10; /* Builtin functions */ double r_sign(real *, real *); integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); /* Local variables */ integer j, n, i1, n1, jc, nb, in, jr, ns, nbz; real ulp; integer iadd, nmax; real temp1, temp2; logical badnn; real dumma[4]; integer iinfo; real rmagn[4]; extern /* Subroutine */ int sgegs_(char *, char *, integer *, real *, integer *, real *, integer *, real *, real *, real *, real *, integer *, real *, integer *, real *, integer *, integer *), sget51_(integer *, integer *, real *, integer *, real *, integer *, real *, integer *, real *, integer *, real *, real *), sget52_(logical *, integer *, real *, integer *, real *, integer *, real *, integer *, real *, real *, real *, real *, real *), sgegv_(char *, char *, integer *, real *, integer *, real *, integer *, real *, real *, real *, real *, integer *, real *, integer *, real *, integer *, integer *), sget53_(real *, integer *, real *, integer *, real *, real *, real *, real *, integer *); integer nmats, jsize, nerrs, jtype, ntest; extern /* Subroutine */ int slatm4_(integer *, integer *, integer *, integer *, integer *, real *, real *, real *, integer *, integer * , real *, integer *); logical ilabad; extern /* Subroutine */ int sorm2r_(char *, char *, integer *, integer *, integer *, real *, integer *, real *, real *, integer *, real *, integer *), slabad_(real *, real *); extern doublereal slamch_(char *); real safmin; integer ioldsd[4]; real safmax; extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *); extern /* Subroutine */ int slarfg_(integer *, real *, real *, integer *, real *); extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int alasvm_(char *, integer *, integer *, integer *, integer *), xerbla_(char *, integer *), slacpy_(char *, integer *, integer *, real *, integer *, real *, integer *), slaset_(char *, integer *, integer *, real *, real *, real *, integer *); real ulpinv; integer lwkopt, mtypes, ntestt; /* Fortran I/O blocks */ static cilist io___42 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___43 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___47 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___48 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___49 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___51 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___52 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___53 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___54 = { 0, 0, 0, fmt_9995, 0 }; static cilist io___55 = { 0, 0, 0, fmt_9994, 0 }; static cilist io___56 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___57 = { 0, 0, 0, fmt_9992, 0 }; static cilist io___58 = { 0, 0, 0, fmt_9991, 0 }; static cilist io___59 = { 0, 0, 0, fmt_9990, 0 }; static cilist io___60 = { 0, 0, 0, fmt_9989, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SDRVGG checks the nonsymmetric generalized eigenvalue driver */ /* routines. */ /* T T T */ /* SGEGS factors A and B as Q S Z and Q T Z , where means */ /* transpose, T is upper triangular, S is in generalized Schur form */ /* (block upper triangular, with 1x1 and 2x2 blocks on the diagonal, */ /* the 2x2 blocks corresponding to complex conjugate pairs of */ /* generalized eigenvalues), and Q and Z are orthogonal. It also */ /* computes the generalized eigenvalues (alpha(1),beta(1)), ..., */ /* (alpha(n),beta(n)), where alpha(j)=S(j,j) and beta(j)=P(j,j) -- */ /* thus, w(j) = alpha(j)/beta(j) is a root of the generalized */ /* eigenvalue problem */ /* det( A - w(j) B ) = 0 */ /* and m(j) = beta(j)/alpha(j) is a root of the essentially equivalent */ /* problem */ /* det( m(j) A - B ) = 0 */ /* SGEGV computes the generalized eigenvalues (alpha(1),beta(1)), ..., */ /* (alpha(n),beta(n)), the matrix L whose columns contain the */ /* generalized left eigenvectors l, and the matrix R whose columns */ /* contain the generalized right eigenvectors r for the pair (A,B). */ /* When SDRVGG is called, a number of matrix "sizes" ("n's") and a */ /* number of matrix "types" are specified. For each size ("n") */ /* and each type of matrix, one matrix will be generated and used */ /* to test the nonsymmetric eigenroutines. For each matrix, 7 */ /* tests will be performed and compared with the threshhold THRESH: */ /* Results from SGEGS: */ /* T */ /* (1) | A - Q S Z | / ( |A| n ulp ) */ /* T */ /* (2) | B - Q T Z | / ( |B| n ulp ) */ /* T */ /* (3) | I - QQ | / ( n ulp ) */ /* T */ /* (4) | I - ZZ | / ( n ulp ) */ /* (5) maximum over j of D(j) where: */ /* if alpha(j) is real: */ /* |alpha(j) - S(j,j)| |beta(j) - T(j,j)| */ /* D(j) = ------------------------ + ----------------------- */ /* max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|) */ /* if alpha(j) is complex: */ /* | det( s S - w T ) | */ /* D(j) = --------------------------------------------------- */ /* ulp max( s norm(S), |w| norm(T) )*norm( s S - w T ) */ /* and S and T are here the 2 x 2 diagonal blocks of S and T */ /* corresponding to the j-th eigenvalue. */ /* Results from SGEGV: */ /* (6) max over all left eigenvalue/-vector pairs (beta/alpha,l) of */ /* | l**H * (beta A - alpha B) | / ( ulp max( |beta A|, |alpha B| ) ) */ /* where l**H is the conjugate tranpose of l. */ /* (7) max over all right eigenvalue/-vector pairs (beta/alpha,r) of */ /* | (beta A - alpha B) r | / ( ulp max( |beta A|, |alpha B| ) ) */ /* Test Matrices */ /* ---- -------- */ /* The sizes of the test matrices are specified by an array */ /* NN(1:NSIZES); the value of each element NN(j) specifies one size. */ /* The "types" are specified by a logical array DOTYPE( 1:NTYPES ); if */ /* DOTYPE(j) is .TRUE., then matrix type "j" will be generated. */ /* Currently, the list of possible types is: */ /* (1) ( 0, 0 ) (a pair of zero matrices) */ /* (2) ( I, 0 ) (an identity and a zero matrix) */ /* (3) ( 0, I ) (an identity and a zero matrix) */ /* (4) ( I, I ) (a pair of identity matrices) */ /* t t */ /* (5) ( J , J ) (a pair of transposed Jordan blocks) */ /* t ( I 0 ) */ /* (6) ( X, Y ) where X = ( J 0 ) and Y = ( t ) */ /* ( 0 I ) ( 0 J ) */ /* and I is a k x k identity and J a (k+1)x(k+1) */ /* Jordan block; k=(N-1)/2 */ /* (7) ( D, I ) where D is diag( 0, 1,..., N-1 ) (a diagonal */ /* matrix with those diagonal entries.) */ /* (8) ( I, D ) */ /* (9) ( big*D, small*I ) where "big" is near overflow and small=1/big */ /* (10) ( small*D, big*I ) */ /* (11) ( big*I, small*D ) */ /* (12) ( small*I, big*D ) */ /* (13) ( big*D, big*I ) */ /* (14) ( small*D, small*I ) */ /* (15) ( D1, D2 ) where D1 is diag( 0, 0, 1, ..., N-3, 0 ) and */ /* D2 is diag( 0, N-3, N-4,..., 1, 0, 0 ) */ /* t t */ /* (16) Q ( J , J ) Z where Q and Z are random orthogonal matrices. */ /* (17) Q ( T1, T2 ) Z where T1 and T2 are upper triangular matrices */ /* with random O(1) entries above the diagonal */ /* and diagonal entries diag(T1) = */ /* ( 0, 0, 1, ..., N-3, 0 ) and diag(T2) = */ /* ( 0, N-3, N-4,..., 1, 0, 0 ) */ /* (18) Q ( T1, T2 ) Z diag(T1) = ( 0, 0, 1, 1, s, ..., s, 0 ) */ /* diag(T2) = ( 0, 1, 0, 1,..., 1, 0 ) */ /* s = machine precision. */ /* (19) Q ( T1, T2 ) Z diag(T1)=( 0,0,1,1, 1-d, ..., 1-(N-5)*d=s, 0 ) */ /* diag(T2) = ( 0, 1, 0, 1, ..., 1, 0 ) */ /* N-5 */ /* (20) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, 1, a, ..., a =s, 0 ) */ /* diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 ) */ /* (21) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, r1, r2, ..., r(N-4), 0 ) */ /* diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 ) */ /* where r1,..., r(N-4) are random. */ /* (22) Q ( big*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) */ /* diag(T2) = ( 0, 1, ..., 1, 0, 0 ) */ /* (23) Q ( small*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) */ /* diag(T2) = ( 0, 1, ..., 1, 0, 0 ) */ /* (24) Q ( small*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) */ /* diag(T2) = ( 0, 1, ..., 1, 0, 0 ) */ /* (25) Q ( big*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) */ /* diag(T2) = ( 0, 1, ..., 1, 0, 0 ) */ /* (26) Q ( T1, T2 ) Z where T1 and T2 are random upper-triangular */ /* matrices. */ /* Arguments */ /* ========= */ /* NSIZES (input) INTEGER */ /* The number of sizes of matrices to use. If it is zero, */ /* SDRVGG does nothing. It must be at least zero. */ /* NN (input) INTEGER array, dimension (NSIZES) */ /* An array containing the sizes to be used for the matrices. */ /* Zero values will be skipped. The values must be at least */ /* zero. */ /* NTYPES (input) INTEGER */ /* The number of elements in DOTYPE. If it is zero, SDRVGG */ /* does nothing. It must be at least zero. If it is MAXTYP+1 */ /* and NSIZES is 1, then an additional type, MAXTYP+1 is */ /* defined, which is to use whatever matrix is in A. This */ /* is only useful if DOTYPE(1:MAXTYP) is .FALSE. and */ /* DOTYPE(MAXTYP+1) is .TRUE. . */ /* DOTYPE (input) LOGICAL array, dimension (NTYPES) */ /* If DOTYPE(j) is .TRUE., then for each size in NN a */ /* matrix of that size and of type j will be generated. */ /* If NTYPES is smaller than the maximum number of types */ /* defined (PARAMETER MAXTYP), then types NTYPES+1 through */ /* MAXTYP will not be generated. If NTYPES is larger */ /* than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES) */ /* will be ignored. */ /* ISEED (input/output) INTEGER array, dimension (4) */ /* On entry ISEED specifies the seed of the random number */ /* generator. The array elements should be between 0 and 4095; */ /* if not they will be reduced mod 4096. Also, ISEED(4) must */ /* be odd. The random number generator uses a linear */ /* congruential sequence limited to small integers, and so */ /* should produce machine independent random numbers. The */ /* values of ISEED are changed on exit, and can be used in the */ /* next call to SDRVGG to continue the same random number */ /* sequence. */ /* THRESH (input) REAL */ /* A test will count as "failed" if the "error", computed as */ /* described above, exceeds THRESH. Note that the error is */ /* scaled to be O(1), so THRESH should be a reasonably small */ /* multiple of 1, e.g., 10 or 100. In particular, it should */ /* not depend on the precision (single vs. double) or the size */ /* of the matrix. It must be at least zero. */ /* THRSHN (input) REAL */ /* Threshhold for reporting eigenvector normalization error. */ /* If the normalization of any eigenvector differs from 1 by */ /* more than THRSHN*ulp, then a special error message will be */ /* printed. (This is handled separately from the other tests, */ /* since only a compiler or programming error should cause an */ /* error message, at least if THRSHN is at least 5--10.) */ /* NOUNIT (input) INTEGER */ /* The FORTRAN unit number for printing out error messages */ /* (e.g., if a routine returns IINFO not equal to 0.) */ /* A (input/workspace) REAL array, dimension */ /* (LDA, max(NN)) */ /* Used to hold the original A matrix. Used as input only */ /* if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and */ /* DOTYPE(MAXTYP+1)=.TRUE. */ /* LDA (input) INTEGER */ /* The leading dimension of A, B, S, T, S2, and T2. */ /* It must be at least 1 and at least max( NN ). */ /* B (input/workspace) REAL array, dimension */ /* (LDA, max(NN)) */ /* Used to hold the original B matrix. Used as input only */ /* if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and */ /* DOTYPE(MAXTYP+1)=.TRUE. */ /* S (workspace) REAL array, dimension (LDA, max(NN)) */ /* The Schur form matrix computed from A by SGEGS. On exit, S */ /* contains the Schur form matrix corresponding to the matrix */ /* in A. */ /* T (workspace) REAL array, dimension (LDA, max(NN)) */ /* The upper triangular matrix computed from B by SGEGS. */ /* S2 (workspace) REAL array, dimension (LDA, max(NN)) */ /* The matrix computed from A by SGEGV. This will be the */ /* Schur form of some matrix related to A, but will not, in */ /* general, be the same as S. */ /* T2 (workspace) REAL array, dimension (LDA, max(NN)) */ /* The matrix computed from B by SGEGV. This will be the */ /* Schur form of some matrix related to B, but will not, in */ /* general, be the same as T. */ /* Q (workspace) REAL array, dimension (LDQ, max(NN)) */ /* The (left) orthogonal matrix computed by SGEGS. */ /* LDQ (input) INTEGER */ /* The leading dimension of Q, Z, VL, and VR. It must */ /* be at least 1 and at least max( NN ). */ /* Z (workspace) REAL array of */ /* dimension( LDQ, max(NN) ) */ /* The (right) orthogonal matrix computed by SGEGS. */ /* ALPHR1 (workspace) REAL array, dimension (max(NN)) */ /* ALPHI1 (workspace) REAL array, dimension (max(NN)) */ /* BETA1 (workspace) REAL array, dimension (max(NN)) */ /* The generalized eigenvalues of (A,B) computed by SGEGS. */ /* ( ALPHR1(k)+ALPHI1(k)*i ) / BETA1(k) is the k-th */ /* generalized eigenvalue of the matrices in A and B. */ /* ALPHR2 (workspace) REAL array, dimension (max(NN)) */ /* ALPHI2 (workspace) REAL array, dimension (max(NN)) */ /* BETA2 (workspace) REAL array, dimension (max(NN)) */ /* The generalized eigenvalues of (A,B) computed by SGEGV. */ /* ( ALPHR2(k)+ALPHI2(k)*i ) / BETA2(k) is the k-th */ /* generalized eigenvalue of the matrices in A and B. */ /* VL (workspace) REAL array, dimension (LDQ, max(NN)) */ /* The (block lower triangular) left eigenvector matrix for */ /* the matrices in A and B. (See STGEVC for the format.) */ /* VR (workspace) REAL array, dimension (LDQ, max(NN)) */ /* The (block upper triangular) right eigenvector matrix for */ /* the matrices in A and B. (See STGEVC for the format.) */ /* WORK (workspace) REAL array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* The number of entries in WORK. This must be at least */ /* 2*N + MAX( 6*N, N*(NB+1), (k+1)*(2*k+N+1) ), where */ /* "k" is the sum of the blocksize and number-of-shifts for */ /* SHGEQZ, and NB is the greatest of the blocksizes for */ /* SGEQRF, SORMQR, and SORGQR. (The blocksizes and the */ /* number-of-shifts are retrieved through calls to ILAENV.) */ /* RESULT (output) REAL array, dimension (15) */ /* The values computed by the tests described above. */ /* The values are currently limited to 1/ulp, to avoid */ /* overflow. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value. */ /* > 0: A routine returned an error code. INFO is the */ /* absolute value of the INFO value returned. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nn; --dotype; --iseed; t2_dim1 = *lda; t2_offset = 1 + t2_dim1; t2 -= t2_offset; s2_dim1 = *lda; s2_offset = 1 + s2_dim1; s2 -= s2_offset; t_dim1 = *lda; t_offset = 1 + t_dim1; t -= t_offset; s_dim1 = *lda; s_offset = 1 + s_dim1; s -= s_offset; b_dim1 = *lda; b_offset = 1 + b_dim1; b -= b_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; vr_dim1 = *ldq; vr_offset = 1 + vr_dim1; vr -= vr_offset; vl_dim1 = *ldq; vl_offset = 1 + vl_dim1; vl -= vl_offset; z_dim1 = *ldq; z_offset = 1 + z_dim1; z__ -= z_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; --alphr1; --alphi1; --beta1; --alphr2; --alphi2; --beta2; --work; --result; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Check for errors */ *info = 0; badnn = FALSE_; nmax = 1; i__1 = *nsizes; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = nmax, i__3 = nn[j]; nmax = max(i__2,i__3); if (nn[j] < 0) { badnn = TRUE_; } /* L10: */ } /* Maximum blocksize and shift -- we assume that blocksize and number */ /* of shifts are monotone increasing functions of N. */ /* Computing MAX */ i__1 = 1, i__2 = ilaenv_(&c__1, "SGEQRF", " ", &nmax, &nmax, &c_n1, &c_n1), i__1 = max(i__1,i__2), i__2 = ilaenv_(& c__1, "SORMQR", "LT", &nmax, &nmax, &nmax, &c_n1), i__1 = max(i__1,i__2), i__2 = ilaenv_(&c__1, "SORGQR", " ", &nmax, &nmax, &nmax, &c_n1); nb = max(i__1,i__2); nbz = ilaenv_(&c__1, "SHGEQZ", "SII", &nmax, &c__1, &nmax, &c__0); ns = ilaenv_(&c__4, "SHGEQZ", "SII", &nmax, &c__1, &nmax, &c__0); i1 = nbz + ns; /* Computing MAX */ i__1 = nmax * 6, i__2 = nmax * (nb + 1), i__1 = max(i__1,i__2), i__2 = (( i1 << 1) + nmax + 1) * (i1 + 1); lwkopt = (nmax << 1) + max(i__1,i__2); /* Check for errors */ if (*nsizes < 0) { *info = -1; } else if (badnn) { *info = -2; } else if (*ntypes < 0) { *info = -3; } else if (*thresh < 0.f) { *info = -6; } else if (*lda <= 1 || *lda < nmax) { *info = -10; } else if (*ldq <= 1 || *ldq < nmax) { *info = -19; } else if (lwkopt > *lwork) { *info = -30; } if (*info != 0) { i__1 = -(*info); xerbla_("SDRVGG", &i__1); return 0; } /* Quick return if possible */ if (*nsizes == 0 || *ntypes == 0) { return 0; } safmin = slamch_("Safe minimum"); ulp = slamch_("Epsilon") * slamch_("Base"); safmin /= ulp; safmax = 1.f / safmin; slabad_(&safmin, &safmax); ulpinv = 1.f / ulp; /* The values RMAGN(2:3) depend on N, see below. */ rmagn[0] = 0.f; rmagn[1] = 1.f; /* Loop over sizes, types */ ntestt = 0; nerrs = 0; nmats = 0; i__1 = *nsizes; for (jsize = 1; jsize <= i__1; ++jsize) { n = nn[jsize]; n1 = max(1,n); rmagn[2] = safmax * ulp / (real) n1; rmagn[3] = safmin * ulpinv * n1; if (*nsizes != 1) { mtypes = min(26,*ntypes); } else { mtypes = min(27,*ntypes); } i__2 = mtypes; for (jtype = 1; jtype <= i__2; ++jtype) { if (! dotype[jtype]) { goto L160; } ++nmats; ntest = 0; /* Save ISEED in case of an error. */ for (j = 1; j <= 4; ++j) { ioldsd[j - 1] = iseed[j]; /* L20: */ } /* Initialize RESULT */ for (j = 1; j <= 15; ++j) { result[j] = 0.f; /* L30: */ } /* Compute A and B */ /* Description of control parameters: */ /* KCLASS: =1 means w/o rotation, =2 means w/ rotation, */ /* =3 means random. */ /* KATYPE: the "type" to be passed to SLATM4 for computing A. */ /* KAZERO: the pattern of zeros on the diagonal for A: */ /* =1: ( xxx ), =2: (0, xxx ) =3: ( 0, 0, xxx, 0 ), */ /* =4: ( 0, xxx, 0, 0 ), =5: ( 0, 0, 1, xxx, 0 ), */ /* =6: ( 0, 1, 0, xxx, 0 ). (xxx means a string of */ /* non-zero entries.) */ /* KAMAGN: the magnitude of the matrix: =0: zero, =1: O(1), */ /* =2: large, =3: small. */ /* IASIGN: 1 if the diagonal elements of A are to be */ /* multiplied by a random magnitude 1 number, =2 if */ /* randomly chosen diagonal blocks are to be rotated */ /* to form 2x2 blocks. */ /* KBTYPE, KBZERO, KBMAGN, IBSIGN: the same, but for B. */ /* KTRIAN: =0: don't fill in the upper triangle, =1: do. */ /* KZ1, KZ2, KADD: used to implement KAZERO and KBZERO. */ /* RMAGN: used to implement KAMAGN and KBMAGN. */ if (mtypes > 26) { goto L110; } iinfo = 0; if (kclass[jtype - 1] < 3) { /* Generate A (w/o rotation) */ if ((i__3 = katype[jtype - 1], abs(i__3)) == 3) { in = ((n - 1) / 2 << 1) + 1; if (in != n) { slaset_("Full", &n, &n, &c_b36, &c_b36, &a[a_offset], lda); } } else { in = n; } slatm4_(&katype[jtype - 1], &in, &kz1[kazero[jtype - 1] - 1], &kz2[kazero[jtype - 1] - 1], &iasign[jtype - 1], & rmagn[kamagn[jtype - 1]], &ulp, &rmagn[ktrian[jtype - 1] * kamagn[jtype - 1]], &c__2, &iseed[1], &a[ a_offset], lda); iadd = kadd[kazero[jtype - 1] - 1]; if (iadd > 0 && iadd <= n) { a[iadd + iadd * a_dim1] = 1.f; } /* Generate B (w/o rotation) */ if ((i__3 = kbtype[jtype - 1], abs(i__3)) == 3) { in = ((n - 1) / 2 << 1) + 1; if (in != n) { slaset_("Full", &n, &n, &c_b36, &c_b36, &b[b_offset], lda); } } else { in = n; } slatm4_(&kbtype[jtype - 1], &in, &kz1[kbzero[jtype - 1] - 1], &kz2[kbzero[jtype - 1] - 1], &ibsign[jtype - 1], & rmagn[kbmagn[jtype - 1]], &c_b42, &rmagn[ktrian[jtype - 1] * kbmagn[jtype - 1]], &c__2, &iseed[1], &b[ b_offset], lda); iadd = kadd[kbzero[jtype - 1] - 1]; if (iadd != 0 && iadd <= n) { b[iadd + iadd * b_dim1] = 1.f; } if (kclass[jtype - 1] == 2 && n > 0) { /* Include rotations */ /* Generate Q, Z as Householder transformations times */ /* a diagonal matrix. */ i__3 = n - 1; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = jc; jr <= i__4; ++jr) { q[jr + jc * q_dim1] = slarnd_(&c__3, &iseed[1]); z__[jr + jc * z_dim1] = slarnd_(&c__3, &iseed[1]); /* L40: */ } i__4 = n + 1 - jc; slarfg_(&i__4, &q[jc + jc * q_dim1], &q[jc + 1 + jc * q_dim1], &c__1, &work[jc]); work[(n << 1) + jc] = r_sign(&c_b42, &q[jc + jc * q_dim1]); q[jc + jc * q_dim1] = 1.f; i__4 = n + 1 - jc; slarfg_(&i__4, &z__[jc + jc * z_dim1], &z__[jc + 1 + jc * z_dim1], &c__1, &work[n + jc]); work[n * 3 + jc] = r_sign(&c_b42, &z__[jc + jc * z_dim1]); z__[jc + jc * z_dim1] = 1.f; /* L50: */ } q[n + n * q_dim1] = 1.f; work[n] = 0.f; r__1 = slarnd_(&c__2, &iseed[1]); work[n * 3] = r_sign(&c_b42, &r__1); z__[n + n * z_dim1] = 1.f; work[n * 2] = 0.f; r__1 = slarnd_(&c__2, &iseed[1]); work[n * 4] = r_sign(&c_b42, &r__1); /* Apply the diagonal matrices */ i__3 = n; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = 1; jr <= i__4; ++jr) { a[jr + jc * a_dim1] = work[(n << 1) + jr] * work[ n * 3 + jc] * a[jr + jc * a_dim1]; b[jr + jc * b_dim1] = work[(n << 1) + jr] * work[ n * 3 + jc] * b[jr + jc * b_dim1]; /* L60: */ } /* L70: */ } i__3 = n - 1; sorm2r_("L", "N", &n, &n, &i__3, &q[q_offset], ldq, &work[ 1], &a[a_offset], lda, &work[(n << 1) + 1], & iinfo); if (iinfo != 0) { goto L100; } i__3 = n - 1; sorm2r_("R", "T", &n, &n, &i__3, &z__[z_offset], ldq, & work[n + 1], &a[a_offset], lda, &work[(n << 1) + 1], &iinfo); if (iinfo != 0) { goto L100; } i__3 = n - 1; sorm2r_("L", "N", &n, &n, &i__3, &q[q_offset], ldq, &work[ 1], &b[b_offset], lda, &work[(n << 1) + 1], & iinfo); if (iinfo != 0) { goto L100; } i__3 = n - 1; sorm2r_("R", "T", &n, &n, &i__3, &z__[z_offset], ldq, & work[n + 1], &b[b_offset], lda, &work[(n << 1) + 1], &iinfo); if (iinfo != 0) { goto L100; } } } else { /* Random matrices */ i__3 = n; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = 1; jr <= i__4; ++jr) { a[jr + jc * a_dim1] = rmagn[kamagn[jtype - 1]] * slarnd_(&c__2, &iseed[1]); b[jr + jc * b_dim1] = rmagn[kbmagn[jtype - 1]] * slarnd_(&c__2, &iseed[1]); /* L80: */ } /* L90: */ } } L100: if (iinfo != 0) { io___42.ciunit = *nounit; s_wsfe(&io___42); do_fio(&c__1, "Generator", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); return 0; } L110: /* Call SGEGS to compute H, T, Q, Z, alpha, and beta. */ slacpy_(" ", &n, &n, &a[a_offset], lda, &s[s_offset], lda); slacpy_(" ", &n, &n, &b[b_offset], lda, &t[t_offset], lda); ntest = 1; result[1] = ulpinv; sgegs_("V", "V", &n, &s[s_offset], lda, &t[t_offset], lda, & alphr1[1], &alphi1[1], &beta1[1], &q[q_offset], ldq, &z__[ z_offset], ldq, &work[1], lwork, &iinfo); if (iinfo != 0) { io___43.ciunit = *nounit; s_wsfe(&io___43); do_fio(&c__1, "SGEGS", (ftnlen)5); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); goto L140; } ntest = 4; /* Do tests 1--4 */ sget51_(&c__1, &n, &a[a_offset], lda, &s[s_offset], lda, &q[ q_offset], ldq, &z__[z_offset], ldq, &work[1], &result[1]) ; sget51_(&c__1, &n, &b[b_offset], lda, &t[t_offset], lda, &q[ q_offset], ldq, &z__[z_offset], ldq, &work[1], &result[2]) ; sget51_(&c__3, &n, &b[b_offset], lda, &t[t_offset], lda, &q[ q_offset], ldq, &q[q_offset], ldq, &work[1], &result[3]); sget51_(&c__3, &n, &b[b_offset], lda, &t[t_offset], lda, &z__[ z_offset], ldq, &z__[z_offset], ldq, &work[1], &result[4]) ; /* Do test 5: compare eigenvalues with diagonals. */ /* Also check Schur form of A. */ temp1 = 0.f; i__3 = n; for (j = 1; j <= i__3; ++j) { ilabad = FALSE_; if (alphi1[j] == 0.f) { /* Computing MAX */ r__7 = safmin, r__8 = (r__2 = alphr1[j], dabs(r__2)), r__7 = max(r__7,r__8), r__8 = (r__3 = s[j + j * s_dim1], dabs(r__3)); /* Computing MAX */ r__9 = safmin, r__10 = (r__5 = beta1[j], dabs(r__5)), r__9 = max(r__9,r__10), r__10 = (r__6 = t[j + j * t_dim1], dabs(r__6)); temp2 = ((r__1 = alphr1[j] - s[j + j * s_dim1], dabs(r__1) ) / dmax(r__7,r__8) + (r__4 = beta1[j] - t[j + j * t_dim1], dabs(r__4)) / dmax(r__9,r__10)) / ulp; if (j < n) { if (s[j + 1 + j * s_dim1] != 0.f) { ilabad = TRUE_; } } if (j > 1) { if (s[j + (j - 1) * s_dim1] != 0.f) { ilabad = TRUE_; } } } else { if (alphi1[j] > 0.f) { i1 = j; } else { i1 = j - 1; } if (i1 <= 0 || i1 >= n) { ilabad = TRUE_; } else if (i1 < n - 1) { if (s[i1 + 2 + (i1 + 1) * s_dim1] != 0.f) { ilabad = TRUE_; } } else if (i1 > 1) { if (s[i1 + (i1 - 1) * s_dim1] != 0.f) { ilabad = TRUE_; } } if (! ilabad) { sget53_(&s[i1 + i1 * s_dim1], lda, &t[i1 + i1 * t_dim1], lda, &beta1[j], &alphr1[j], &alphi1[ j], &temp2, &iinfo); if (iinfo >= 3) { io___47.ciunit = *nounit; s_wsfe(&io___47); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof( integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); e_wsfe(); *info = abs(iinfo); } } else { temp2 = ulpinv; } } temp1 = dmax(temp1,temp2); if (ilabad) { io___48.ciunit = *nounit; s_wsfe(&io___48); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); } /* L120: */ } result[5] = temp1; /* Call SGEGV to compute S2, T2, VL, and VR, do tests. */ /* Eigenvalues and Eigenvectors */ slacpy_(" ", &n, &n, &a[a_offset], lda, &s2[s2_offset], lda); slacpy_(" ", &n, &n, &b[b_offset], lda, &t2[t2_offset], lda); ntest = 6; result[6] = ulpinv; sgegv_("V", "V", &n, &s2[s2_offset], lda, &t2[t2_offset], lda, & alphr2[1], &alphi2[1], &beta2[1], &vl[vl_offset], ldq, & vr[vr_offset], ldq, &work[1], lwork, &iinfo); if (iinfo != 0) { io___49.ciunit = *nounit; s_wsfe(&io___49); do_fio(&c__1, "SGEGV", (ftnlen)5); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); goto L140; } ntest = 7; /* Do Tests 6 and 7 */ sget52_(&c_true, &n, &a[a_offset], lda, &b[b_offset], lda, &vl[ vl_offset], ldq, &alphr2[1], &alphi2[1], &beta2[1], &work[ 1], dumma); result[6] = dumma[0]; if (dumma[1] > *thrshn) { io___51.ciunit = *nounit; s_wsfe(&io___51); do_fio(&c__1, "Left", (ftnlen)4); do_fio(&c__1, "SGEGV", (ftnlen)5); do_fio(&c__1, (char *)&dumma[1], (ftnlen)sizeof(real)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); } sget52_(&c_false, &n, &a[a_offset], lda, &b[b_offset], lda, &vr[ vr_offset], ldq, &alphr2[1], &alphi2[1], &beta2[1], &work[ 1], dumma); result[7] = dumma[0]; if (dumma[1] > *thresh) { io___52.ciunit = *nounit; s_wsfe(&io___52); do_fio(&c__1, "Right", (ftnlen)5); do_fio(&c__1, "SGEGV", (ftnlen)5); do_fio(&c__1, (char *)&dumma[1], (ftnlen)sizeof(real)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); } /* Check form of Complex eigenvalues. */ i__3 = n; for (j = 1; j <= i__3; ++j) { ilabad = FALSE_; if (alphi2[j] > 0.f) { if (j == n) { ilabad = TRUE_; } else if (alphi2[j + 1] >= 0.f) { ilabad = TRUE_; } } else if (alphi2[j] < 0.f) { if (j == 1) { ilabad = TRUE_; } else if (alphi2[j - 1] <= 0.f) { ilabad = TRUE_; } } if (ilabad) { io___53.ciunit = *nounit; s_wsfe(&io___53); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); } /* L130: */ } /* End of Loop -- Check for RESULT(j) > THRESH */ L140: ntestt += ntest; /* Print out tests which fail. */ i__3 = ntest; for (jr = 1; jr <= i__3; ++jr) { if (result[jr] >= *thresh) { /* If this is the first test to fail, */ /* print a header to the data file. */ if (nerrs == 0) { io___54.ciunit = *nounit; s_wsfe(&io___54); do_fio(&c__1, "SGG", (ftnlen)3); e_wsfe(); /* Matrix types */ io___55.ciunit = *nounit; s_wsfe(&io___55); e_wsfe(); io___56.ciunit = *nounit; s_wsfe(&io___56); e_wsfe(); io___57.ciunit = *nounit; s_wsfe(&io___57); do_fio(&c__1, "Orthogonal", (ftnlen)10); e_wsfe(); /* Tests performed */ io___58.ciunit = *nounit; s_wsfe(&io___58); do_fio(&c__1, "orthogonal", (ftnlen)10); do_fio(&c__1, "'", (ftnlen)1); do_fio(&c__1, "transpose", (ftnlen)9); for (j = 1; j <= 5; ++j) { do_fio(&c__1, "'", (ftnlen)1); } e_wsfe(); } ++nerrs; if (result[jr] < 1e4f) { io___59.ciunit = *nounit; s_wsfe(&io___59); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)) ; do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&jr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[jr], (ftnlen)sizeof( real)); e_wsfe(); } else { io___60.ciunit = *nounit; s_wsfe(&io___60); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)) ; do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&jr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[jr], (ftnlen)sizeof( real)); e_wsfe(); } } /* L150: */ } L160: ; } /* L170: */ } /* Summary */ alasvm_("SGG", nounit, &nerrs, &ntestt, &c__0); return 0; /* End of SDRVGG */ } /* sdrvgg_ */
/* Subroutine */ int slatm4_(integer *itype, integer *n, integer *nz1, integer *nz2, integer *isign, real *amagn, real *rcond, real *triang, integer *idist, integer *iseed, real *a, integer *lda) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4; real r__1, r__2, r__3, r__4; doublereal d__1, d__2; /* Builtin functions */ double pow_dd(doublereal *, doublereal *), pow_ri(real *, integer *), log( doublereal), exp(doublereal), sqrt(doublereal); /* Local variables */ static integer kbeg, isdb, kend, ioff, isde, klen; static real temp; static integer i__, k; static real alpha; static integer jc, jd; static real cl, cr; static integer jr; static real sl, sr; extern doublereal slamch_(char *); static real safmin; extern doublereal slaran_(integer *), slarnd_(integer *, integer *); extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *, real *, real *, integer *); static real sv1, sv2; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] /* -- LAPACK auxiliary test routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= SLATM4 generates basic square matrices, which may later be multiplied by others in order to produce test matrices. It is intended mainly to be used to test the generalized eigenvalue routines. It first generates the diagonal and (possibly) subdiagonal, according to the value of ITYPE, NZ1, NZ2, ISIGN, AMAGN, and RCOND. It then fills in the upper triangle with random numbers, if TRIANG is non-zero. Arguments ========= ITYPE (input) INTEGER The "type" of matrix on the diagonal and sub-diagonal. If ITYPE < 0, then type abs(ITYPE) is generated and then swapped end for end (A(I,J) := A'(N-J,N-I).) See also the description of AMAGN and ISIGN. Special types: = 0: the zero matrix. = 1: the identity. = 2: a transposed Jordan block. = 3: If N is odd, then a k+1 x k+1 transposed Jordan block followed by a k x k identity block, where k=(N-1)/2. If N is even, then k=(N-2)/2, and a zero diagonal entry is tacked onto the end. Diagonal types. The diagonal consists of NZ1 zeros, then k=N-NZ1-NZ2 nonzeros. The subdiagonal is zero. ITYPE specifies the nonzero diagonal entries as follows: = 4: 1, ..., k = 5: 1, RCOND, ..., RCOND = 6: 1, ..., 1, RCOND = 7: 1, a, a^2, ..., a^(k-1)=RCOND = 8: 1, 1-d, 1-2*d, ..., 1-(k-1)*d=RCOND = 9: random numbers chosen from (RCOND,1) = 10: random numbers with distribution IDIST (see SLARND.) N (input) INTEGER The order of the matrix. NZ1 (input) INTEGER If abs(ITYPE) > 3, then the first NZ1 diagonal entries will be zero. NZ2 (input) INTEGER If abs(ITYPE) > 3, then the last NZ2 diagonal entries will be zero. ISIGN (input) INTEGER = 0: The sign of the diagonal and subdiagonal entries will be left unchanged. = 1: The diagonal and subdiagonal entries will have their sign changed at random. = 2: If ITYPE is 2 or 3, then the same as ISIGN=1. Otherwise, with probability 0.5, odd-even pairs of diagonal entries A(2*j-1,2*j-1), A(2*j,2*j) will be converted to a 2x2 block by pre- and post-multiplying by distinct random orthogonal rotations. The remaining diagonal entries will have their sign changed at random. AMAGN (input) REAL The diagonal and subdiagonal entries will be multiplied by AMAGN. RCOND (input) REAL If abs(ITYPE) > 4, then the smallest diagonal entry will be entry will be RCOND. RCOND must be between 0 and 1. TRIANG (input) REAL The entries above the diagonal will be random numbers with magnitude bounded by TRIANG (i.e., random numbers multiplied by TRIANG.) IDIST (input) INTEGER Specifies the type of distribution to be used to generate a random matrix. = 1: UNIFORM( 0, 1 ) = 2: UNIFORM( -1, 1 ) = 3: NORMAL ( 0, 1 ) ISEED (input/output) INTEGER array, dimension (4) On entry ISEED specifies the seed of the random number generator. The values of ISEED are changed on exit, and can be used in the next call to SLATM4 to continue the same random number sequence. Note: ISEED(4) should be odd, for the random number generator used at present. A (output) REAL array, dimension (LDA, N) Array to be computed. LDA (input) INTEGER Leading dimension of A. Must be at least 1 and at least N. ===================================================================== Parameter adjustments */ --iseed; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ if (*n <= 0) { return 0; } slaset_("Full", n, n, &c_b3, &c_b3, &a[a_offset], lda); /* Insure a correct ISEED */ if (iseed[4] % 2 != 1) { ++iseed[4]; } /* Compute diagonal and subdiagonal according to ITYPE, NZ1, NZ2, and RCOND */ if (*itype != 0) { if (abs(*itype) >= 4) { /* Computing MAX Computing MIN */ i__3 = *n, i__4 = *nz1 + 1; i__1 = 1, i__2 = min(i__3,i__4); kbeg = max(i__1,i__2); /* Computing MAX Computing MIN */ i__3 = *n, i__4 = *n - *nz2; i__1 = kbeg, i__2 = min(i__3,i__4); kend = max(i__1,i__2); klen = kend + 1 - kbeg; } else { kbeg = 1; kend = *n; klen = *n; } isdb = 1; isde = 0; switch (abs(*itype)) { case 1: goto L10; case 2: goto L30; case 3: goto L50; case 4: goto L80; case 5: goto L100; case 6: goto L120; case 7: goto L140; case 8: goto L160; case 9: goto L180; case 10: goto L200; } /* |ITYPE| = 1: Identity */ L10: i__1 = *n; for (jd = 1; jd <= i__1; ++jd) { a_ref(jd, jd) = 1.f; /* L20: */ } goto L220; /* |ITYPE| = 2: Transposed Jordan block */ L30: i__1 = *n - 1; for (jd = 1; jd <= i__1; ++jd) { a_ref(jd + 1, jd) = 1.f; /* L40: */ } isdb = 1; isde = *n - 1; goto L220; /* |ITYPE| = 3: Transposed Jordan block, followed by the identity. */ L50: k = (*n - 1) / 2; i__1 = k; for (jd = 1; jd <= i__1; ++jd) { a_ref(jd + 1, jd) = 1.f; /* L60: */ } isdb = 1; isde = k; i__1 = (k << 1) + 1; for (jd = k + 2; jd <= i__1; ++jd) { a_ref(jd, jd) = 1.f; /* L70: */ } goto L220; /* |ITYPE| = 4: 1,...,k */ L80: i__1 = kend; for (jd = kbeg; jd <= i__1; ++jd) { a_ref(jd, jd) = (real) (jd - *nz1); /* L90: */ } goto L220; /* |ITYPE| = 5: One large D value: */ L100: i__1 = kend; for (jd = kbeg + 1; jd <= i__1; ++jd) { a_ref(jd, jd) = *rcond; /* L110: */ } a_ref(kbeg, kbeg) = 1.f; goto L220; /* |ITYPE| = 6: One small D value: */ L120: i__1 = kend - 1; for (jd = kbeg; jd <= i__1; ++jd) { a_ref(jd, jd) = 1.f; /* L130: */ } a_ref(kend, kend) = *rcond; goto L220; /* |ITYPE| = 7: Exponentially distributed D values: */ L140: a_ref(kbeg, kbeg) = 1.f; if (klen > 1) { d__1 = (doublereal) (*rcond); d__2 = (doublereal) (1.f / (real) (klen - 1)); alpha = pow_dd(&d__1, &d__2); i__1 = klen; for (i__ = 2; i__ <= i__1; ++i__) { i__2 = i__ - 1; a_ref(*nz1 + i__, *nz1 + i__) = pow_ri(&alpha, &i__2); /* L150: */ } } goto L220; /* |ITYPE| = 8: Arithmetically distributed D values: */ L160: a_ref(kbeg, kbeg) = 1.f; if (klen > 1) { alpha = (1.f - *rcond) / (real) (klen - 1); i__1 = klen; for (i__ = 2; i__ <= i__1; ++i__) { a_ref(*nz1 + i__, *nz1 + i__) = (real) (klen - i__) * alpha + *rcond; /* L170: */ } } goto L220; /* |ITYPE| = 9: Randomly distributed D values on ( RCOND, 1): */ L180: alpha = log(*rcond); i__1 = kend; for (jd = kbeg; jd <= i__1; ++jd) { a_ref(jd, jd) = exp(alpha * slaran_(&iseed[1])); /* L190: */ } goto L220; /* |ITYPE| = 10: Randomly distributed D values from DIST */ L200: i__1 = kend; for (jd = kbeg; jd <= i__1; ++jd) { a_ref(jd, jd) = slarnd_(idist, &iseed[1]); /* L210: */ } L220: /* Scale by AMAGN */ i__1 = kend; for (jd = kbeg; jd <= i__1; ++jd) { a_ref(jd, jd) = *amagn * a_ref(jd, jd); /* L230: */ } i__1 = isde; for (jd = isdb; jd <= i__1; ++jd) { a_ref(jd + 1, jd) = *amagn * a_ref(jd + 1, jd); /* L240: */ } /* If ISIGN = 1 or 2, assign random signs to diagonal and subdiagonal */ if (*isign > 0) { i__1 = kend; for (jd = kbeg; jd <= i__1; ++jd) { if (a_ref(jd, jd) != 0.f) { if (slaran_(&iseed[1]) > .5f) { a_ref(jd, jd) = -a_ref(jd, jd); } } /* L250: */ } i__1 = isde; for (jd = isdb; jd <= i__1; ++jd) { if (a_ref(jd + 1, jd) != 0.f) { if (slaran_(&iseed[1]) > .5f) { a_ref(jd + 1, jd) = -a_ref(jd + 1, jd); } } /* L260: */ } } /* Reverse if ITYPE < 0 */ if (*itype < 0) { i__1 = (kbeg + kend - 1) / 2; for (jd = kbeg; jd <= i__1; ++jd) { temp = a_ref(jd, jd); a_ref(jd, jd) = a_ref(kbeg + kend - jd, kbeg + kend - jd); a_ref(kbeg + kend - jd, kbeg + kend - jd) = temp; /* L270: */ } i__1 = (*n - 1) / 2; for (jd = 1; jd <= i__1; ++jd) { temp = a_ref(jd + 1, jd); a_ref(jd + 1, jd) = a_ref(*n + 1 - jd, *n - jd); a_ref(*n + 1 - jd, *n - jd) = temp; /* L280: */ } } /* If ISIGN = 2, and no subdiagonals already, then apply random rotations to make 2x2 blocks. */ if (*isign == 2 && *itype != 2 && *itype != 3) { safmin = slamch_("S"); i__1 = kend - 1; for (jd = kbeg; jd <= i__1; jd += 2) { if (slaran_(&iseed[1]) > .5f) { /* Rotation on left. */ cl = slaran_(&iseed[1]) * 2.f - 1.f; sl = slaran_(&iseed[1]) * 2.f - 1.f; /* Computing MAX Computing 2nd power */ r__3 = cl; /* Computing 2nd power */ r__4 = sl; r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4); temp = 1.f / dmax(r__1,r__2); cl *= temp; sl *= temp; /* Rotation on right. */ cr = slaran_(&iseed[1]) * 2.f - 1.f; sr = slaran_(&iseed[1]) * 2.f - 1.f; /* Computing MAX Computing 2nd power */ r__3 = cr; /* Computing 2nd power */ r__4 = sr; r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4); temp = 1.f / dmax(r__1,r__2); cr *= temp; sr *= temp; /* Apply */ sv1 = a_ref(jd, jd); sv2 = a_ref(jd + 1, jd + 1); a_ref(jd, jd) = cl * cr * sv1 + sl * sr * sv2; a_ref(jd + 1, jd) = -sl * cr * sv1 + cl * sr * sv2; a_ref(jd, jd + 1) = -cl * sr * sv1 + sl * cr * sv2; a_ref(jd + 1, jd + 1) = sl * sr * sv1 + cl * cr * sv2; } /* L290: */ } } } /* Fill in upper triangle (except for 2x2 blocks) */ if (*triang != 0.f) { if (*isign != 2 || *itype == 2 || *itype == 3) { ioff = 1; } else { ioff = 2; i__1 = *n - 1; for (jr = 1; jr <= i__1; ++jr) { if (a_ref(jr + 1, jr) == 0.f) { a_ref(jr, jr + 1) = *triang * slarnd_(idist, &iseed[1]); } /* L300: */ } } i__1 = *n; for (jc = 2; jc <= i__1; ++jc) { i__2 = jc - ioff; for (jr = 1; jr <= i__2; ++jr) { a_ref(jr, jc) = *triang * slarnd_(idist, &iseed[1]); /* L310: */ } /* L320: */ } } return 0; /* End of SLATM4 */ } /* slatm4_ */
/* Subroutine */ int cchkbd_(integer *nsizes, integer *mval, integer *nval, integer *ntypes, logical *dotype, integer *nrhs, integer *iseed, real *thresh, complex *a, integer *lda, real *bd, real *be, real *s1, real *s2, complex *x, integer *ldx, complex *y, complex *z__, complex *q, integer *ldq, complex *pt, integer *ldpt, complex *u, complex *vt, complex *work, integer *lwork, real *rwork, integer *nout, integer * info) { /* Initialized data */ static integer ktype[16] = { 1,2,4,4,4,4,4,6,6,6,6,6,9,9,9,10 }; static integer kmagn[16] = { 1,1,1,1,1,2,3,1,1,1,2,3,1,2,3,0 }; static integer kmode[16] = { 0,0,4,3,1,4,4,4,3,1,4,4,0,0,0,0 }; /* Format strings */ static char fmt_9998[] = "(\002 CCHKBD: \002,a,\002 returned INFO=\002,i" "6,\002.\002,/9x,\002M=\002,i6,\002, N=\002,i6,\002, JTYPE=\002,i" "6,\002, ISEED=(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9999[] = "(\002 M=\002,i5,\002, N=\002,i5,\002, type " "\002,i2,\002, seed=\002,4(i4,\002,\002),\002 test(\002,i2,\002)" "=\002,g11.4)"; /* System generated locals */ integer a_dim1, a_offset, pt_dim1, pt_offset, q_dim1, q_offset, u_dim1, u_offset, vt_dim1, vt_offset, x_dim1, x_offset, y_dim1, y_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1, r__2, r__3, r__4, r__5, r__6, r__7; /* Builtin functions Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); double log(doublereal), sqrt(doublereal), exp(doublereal); integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); /* Local variables */ static real cond; static integer jcol; static char path[3]; static integer mmax, nmax; static real unfl, ovfl; static char uplo[1]; static real temp1, temp2; static integer i__, j, m, n; extern /* Subroutine */ int cbdt01_(integer *, integer *, integer *, complex *, integer *, complex *, integer *, real *, real *, complex *, integer *, complex *, real *, real *); static logical badmm, badnn; extern /* Subroutine */ int cbdt02_(integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, real *, real *), cbdt03_(char *, integer *, integer *, real *, real *, complex *, integer *, real *, complex *, integer *, complex *, real *); static integer nfail, imode; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *); static real dumma[1]; static integer iinfo; extern /* Subroutine */ int cunt01_(char *, integer *, integer *, complex *, integer *, complex *, integer *, real *, real *); static real anorm; static integer mnmin, mnmax, jsize, itype, jtype, iwork[1], ntest; extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, integer *), slahd2_(integer *, char *); static integer log2ui; static logical bidiag; extern /* Subroutine */ int cgebrd_(integer *, integer *, complex *, integer *, real *, real *, complex *, complex *, complex *, integer *, integer *), slabad_(real *, real *); static integer mq; extern doublereal slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), xerbla_(char *, integer *); static integer ioldsd[4]; extern /* Subroutine */ int cbdsqr_(char *, integer *, integer *, integer *, integer *, real *, real *, complex *, integer *, complex *, integer *, complex *, integer *, real *, integer *), cungbr_(char *, integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *), alasum_(char *, integer *, integer *, integer *, integer *); extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int clatmr_(integer *, integer *, char *, integer *, char *, complex *, integer *, real *, complex *, char *, char * , complex *, integer *, real *, complex *, integer *, real *, char *, integer *, integer *, integer *, real *, real *, char *, complex *, integer *, integer *, integer *), clatms_(integer *, integer *, char *, integer *, char *, real *, integer *, real *, real *, integer *, integer *, char *, complex *, integer *, complex *, integer *); static real amninv; extern /* Subroutine */ int ssvdch_(integer *, real *, real *, real *, real *, integer *); static integer minwrk; static real rtunfl, rtovfl, ulpinv, result[14]; static integer mtypes; static real ulp; /* Fortran I/O blocks */ static cilist io___40 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___41 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___43 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___44 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___45 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___46 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___50 = { 0, 0, 0, fmt_9999, 0 }; #define a_subscr(a_1,a_2) (a_2)*a_dim1 + a_1 #define a_ref(a_1,a_2) a[a_subscr(a_1,a_2)] /* -- LAPACK test routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= CCHKBD checks the singular value decomposition (SVD) routines. CGEBRD reduces a complex general m by n matrix A to real upper or lower bidiagonal form by an orthogonal transformation: Q' * A * P = B (or A = Q * B * P'). The matrix B is upper bidiagonal if m >= n and lower bidiagonal if m < n. CUNGBR generates the orthogonal matrices Q and P' from CGEBRD. Note that Q and P are not necessarily square. CBDSQR computes the singular value decomposition of the bidiagonal matrix B as B = U S V'. It is called three times to compute 1) B = U S1 V', where S1 is the diagonal matrix of singular values and the columns of the matrices U and V are the left and right singular vectors, respectively, of B. 2) Same as 1), but the singular values are stored in S2 and the singular vectors are not computed. 3) A = (UQ) S (P'V'), the SVD of the original matrix A. In addition, CBDSQR has an option to apply the left orthogonal matrix U to a matrix X, useful in least squares applications. For each pair of matrix dimensions (M,N) and each selected matrix type, an M by N matrix A and an M by NRHS matrix X are generated. The problem dimensions are as follows A: M x N Q: M x min(M,N) (but M x M if NRHS > 0) P: min(M,N) x N B: min(M,N) x min(M,N) U, V: min(M,N) x min(M,N) S1, S2 diagonal, order min(M,N) X: M x NRHS For each generated matrix, 14 tests are performed: Test CGEBRD and CUNGBR (1) | A - Q B PT | / ( |A| max(M,N) ulp ), PT = P' (2) | I - Q' Q | / ( M ulp ) (3) | I - PT PT' | / ( N ulp ) Test CBDSQR on bidiagonal matrix B (4) | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V' (5) | Y - U Z | / ( |Y| max(min(M,N),k) ulp ), where Y = Q' X and Z = U' Y. (6) | I - U' U | / ( min(M,N) ulp ) (7) | I - VT VT' | / ( min(M,N) ulp ) (8) S1 contains min(M,N) nonnegative values in decreasing order. (Return 0 if true, 1/ULP if false.) (9) 0 if the true singular values of B are within THRESH of those in S1. 2*THRESH if they are not. (Tested using SSVDCH) (10) | S1 - S2 | / ( |S1| ulp ), where S2 is computed without computing U and V. Test CBDSQR on matrix A (11) | A - (QU) S (VT PT) | / ( |A| max(M,N) ulp ) (12) | X - (QU) Z | / ( |X| max(M,k) ulp ) (13) | I - (QU)'(QU) | / ( M ulp ) (14) | I - (VT PT) (PT'VT') | / ( N ulp ) The possible matrix types are (1) The zero matrix. (2) The identity matrix. (3) A diagonal matrix with evenly spaced entries 1, ..., ULP and random signs. (ULP = (first number larger than 1) - 1 ) (4) A diagonal matrix with geometrically spaced entries 1, ..., ULP and random signs. (5) A diagonal matrix with "clustered" entries 1, ULP, ..., ULP and random signs. (6) Same as (3), but multiplied by SQRT( overflow threshold ) (7) Same as (3), but multiplied by SQRT( underflow threshold ) (8) A matrix of the form U D V, where U and V are orthogonal and D has evenly spaced entries 1, ..., ULP with random signs on the diagonal. (9) A matrix of the form U D V, where U and V are orthogonal and D has geometrically spaced entries 1, ..., ULP with random signs on the diagonal. (10) A matrix of the form U D V, where U and V are orthogonal and D has "clustered" entries 1, ULP,..., ULP with random signs on the diagonal. (11) Same as (8), but multiplied by SQRT( overflow threshold ) (12) Same as (8), but multiplied by SQRT( underflow threshold ) (13) Rectangular matrix with random entries chosen from (-1,1). (14) Same as (13), but multiplied by SQRT( overflow threshold ) (15) Same as (13), but multiplied by SQRT( underflow threshold ) Special case: (16) A bidiagonal matrix with random entries chosen from a logarithmic distribution on [ulp^2,ulp^(-2)] (I.e., each entry is e^x, where x is chosen uniformly on [ 2 log(ulp), -2 log(ulp) ] .) For *this* type: (a) CGEBRD is not called to reduce it to bidiagonal form. (b) the bidiagonal is min(M,N) x min(M,N); if M<N, the matrix will be lower bidiagonal, otherwise upper. (c) only tests 5--8 and 14 are performed. A subset of the full set of matrix types may be selected through the logical array DOTYPE. Arguments ========== NSIZES (input) INTEGER The number of values of M and N contained in the vectors MVAL and NVAL. The matrix sizes are used in pairs (M,N). MVAL (input) INTEGER array, dimension (NM) The values of the matrix row dimension M. NVAL (input) INTEGER array, dimension (NM) The values of the matrix column dimension N. NTYPES (input) INTEGER The number of elements in DOTYPE. If it is zero, CCHKBD does nothing. It must be at least zero. If it is MAXTYP+1 and NSIZES is 1, then an additional type, MAXTYP+1 is defined, which is to use whatever matrices are in A and B. This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and DOTYPE(MAXTYP+1) is .TRUE. . DOTYPE (input) LOGICAL array, dimension (NTYPES) If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix of type j will be generated. If NTYPES is smaller than the maximum number of types defined (PARAMETER MAXTYP), then types NTYPES+1 through MAXTYP will not be generated. If NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES) will be ignored. NRHS (input) INTEGER The number of columns in the "right-hand side" matrices X, Y, and Z, used in testing CBDSQR. If NRHS = 0, then the operations on the right-hand side will not be tested. NRHS must be at least 0. ISEED (input/output) INTEGER array, dimension (4) On entry ISEED specifies the seed of the random number generator. The array elements should be between 0 and 4095; if not they will be reduced mod 4096. Also, ISEED(4) must be odd. The values of ISEED are changed on exit, and can be used in the next call to CCHKBD to continue the same random number sequence. THRESH (input) REAL The threshold value for the test ratios. A result is included in the output file if RESULT >= THRESH. To have every test ratio printed, use THRESH = 0. Note that the expected value of the test ratios is O(1), so THRESH should be a reasonably small multiple of 1, e.g., 10 or 100. A (workspace) COMPLEX array, dimension (LDA,NMAX) where NMAX is the maximum value of N in NVAL. LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,MMAX), where MMAX is the maximum value of M in MVAL. BD (workspace) REAL array, dimension (max(min(MVAL(j),NVAL(j)))) BE (workspace) REAL array, dimension (max(min(MVAL(j),NVAL(j)))) S1 (workspace) REAL array, dimension (max(min(MVAL(j),NVAL(j)))) S2 (workspace) REAL array, dimension (max(min(MVAL(j),NVAL(j)))) X (workspace) COMPLEX array, dimension (LDX,NRHS) LDX (input) INTEGER The leading dimension of the arrays X, Y, and Z. LDX >= max(1,MMAX). Y (workspace) COMPLEX array, dimension (LDX,NRHS) Z (workspace) COMPLEX array, dimension (LDX,NRHS) Q (workspace) COMPLEX array, dimension (LDQ,MMAX) LDQ (input) INTEGER The leading dimension of the array Q. LDQ >= max(1,MMAX). PT (workspace) COMPLEX array, dimension (LDPT,NMAX) LDPT (input) INTEGER The leading dimension of the arrays PT, U, and V. LDPT >= max(1, max(min(MVAL(j),NVAL(j)))). U (workspace) COMPLEX array, dimension (LDPT,max(min(MVAL(j),NVAL(j)))) V (workspace) COMPLEX array, dimension (LDPT,max(min(MVAL(j),NVAL(j)))) WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The number of entries in WORK. This must be at least 3(M+N) and M(M + max(M,N,k) + 1) + N*min(M,N) for all pairs (M,N)=(MM(j),NN(j)) RWORK (workspace) REAL array, dimension (5*max(min(M,N))) NOUT (input) INTEGER The FORTRAN unit number for printing out error messages (e.g., if a routine returns IINFO not equal to 0.) INFO (output) INTEGER If 0, then everything ran OK. -1: NSIZES < 0 -2: Some MM(j) < 0 -3: Some NN(j) < 0 -4: NTYPES < 0 -6: NRHS < 0 -8: THRESH < 0 -11: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ). -17: LDB < 1 or LDB < MMAX. -21: LDQ < 1 or LDQ < MMAX. -23: LDP < 1 or LDP < MNMAX. -27: LWORK too small. If CLATMR, CLATMS, CGEBRD, CUNGBR, or CBDSQR, returns an error code, the absolute value of it is returned. ----------------------------------------------------------------------- Some Local Variables and Parameters: ---- ----- --------- --- ---------- ZERO, ONE Real 0 and 1. MAXTYP The number of types defined. NTEST The number of tests performed, or which can be performed so far, for the current matrix. MMAX Largest value in NN. NMAX Largest value in NN. MNMIN min(MM(j), NN(j)) (the dimension of the bidiagonal matrix.) MNMAX The maximum value of MNMIN for j=1,...,NSIZES. NFAIL The number of tests which have exceeded THRESH COND, IMODE Values to be passed to the matrix generators. ANORM Norm of A; passed to matrix generators. OVFL, UNFL Overflow and underflow thresholds. RTOVFL, RTUNFL Square roots of the previous 2 values. ULP, ULPINV Finest relative precision and its inverse. The following four arrays decode JTYPE: KTYPE(j) The general type (1-10) for type "j". KMODE(j) The MODE value to be passed to the matrix generator for type "j". KMAGN(j) The order of magnitude ( O(1), O(overflow^(1/2) ), O(underflow^(1/2) ) ====================================================================== Parameter adjustments */ --mval; --nval; --dotype; --iseed; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --bd; --be; --s1; --s2; z_dim1 = *ldx; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; y_dim1 = *ldx; y_offset = 1 + y_dim1 * 1; y -= y_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1 * 1; x -= x_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; vt_dim1 = *ldpt; vt_offset = 1 + vt_dim1 * 1; vt -= vt_offset; u_dim1 = *ldpt; u_offset = 1 + u_dim1 * 1; u -= u_offset; pt_dim1 = *ldpt; pt_offset = 1 + pt_dim1 * 1; pt -= pt_offset; --work; --rwork; /* Function Body Check for errors */ *info = 0; badmm = FALSE_; badnn = FALSE_; mmax = 1; nmax = 1; mnmax = 1; minwrk = 1; i__1 = *nsizes; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = mmax, i__3 = mval[j]; mmax = max(i__2,i__3); if (mval[j] < 0) { badmm = TRUE_; } /* Computing MAX */ i__2 = nmax, i__3 = nval[j]; nmax = max(i__2,i__3); if (nval[j] < 0) { badnn = TRUE_; } /* Computing MAX Computing MIN */ i__4 = mval[j], i__5 = nval[j]; i__2 = mnmax, i__3 = min(i__4,i__5); mnmax = max(i__2,i__3); /* Computing MAX Computing MAX */ i__4 = mval[j], i__5 = nval[j], i__4 = max(i__4,i__5); /* Computing MIN */ i__6 = nval[j], i__7 = mval[j]; i__2 = minwrk, i__3 = (mval[j] + nval[j]) * 3, i__2 = max(i__2,i__3), i__3 = mval[j] * (mval[j] + max(i__4,*nrhs) + 1) + nval[j] * min(i__6,i__7); minwrk = max(i__2,i__3); /* L10: */ } /* Check for errors */ if (*nsizes < 0) { *info = -1; } else if (badmm) { *info = -2; } else if (badnn) { *info = -3; } else if (*ntypes < 0) { *info = -4; } else if (*nrhs < 0) { *info = -6; } else if (*lda < mmax) { *info = -11; } else if (*ldx < mmax) { *info = -17; } else if (*ldq < mmax) { *info = -21; } else if (*ldpt < mnmax) { *info = -23; } else if (minwrk > *lwork) { *info = -27; } if (*info != 0) { i__1 = -(*info); xerbla_("CCHKBD", &i__1); return 0; } /* Initialize constants */ s_copy(path, "Complex precision", (ftnlen)1, (ftnlen)17); s_copy(path + 1, "BD", (ftnlen)2, (ftnlen)2); nfail = 0; ntest = 0; unfl = slamch_("Safe minimum"); ovfl = slamch_("Overflow"); slabad_(&unfl, &ovfl); ulp = slamch_("Precision"); ulpinv = 1.f / ulp; log2ui = (integer) (log(ulpinv) / log(2.f)); rtunfl = sqrt(unfl); rtovfl = sqrt(ovfl); infoc_1.infot = 0; /* Loop over sizes, types */ i__1 = *nsizes; for (jsize = 1; jsize <= i__1; ++jsize) { m = mval[jsize]; n = nval[jsize]; mnmin = min(m,n); /* Computing MAX */ i__2 = max(m,n); amninv = 1.f / max(i__2,1); if (*nsizes != 1) { mtypes = min(16,*ntypes); } else { mtypes = min(17,*ntypes); } i__2 = mtypes; for (jtype = 1; jtype <= i__2; ++jtype) { if (! dotype[jtype]) { goto L170; } for (j = 1; j <= 4; ++j) { ioldsd[j - 1] = iseed[j]; /* L20: */ } for (j = 1; j <= 14; ++j) { result[j - 1] = -1.f; /* L30: */ } *(unsigned char *)uplo = ' '; /* Compute "A" Control parameters: KMAGN KMODE KTYPE =1 O(1) clustered 1 zero =2 large clustered 2 identity =3 small exponential (none) =4 arithmetic diagonal, (w/ eigenvalues) =5 random symmetric, w/ eigenvalues =6 nonsymmetric, w/ singular values =7 random diagonal =8 random symmetric =9 random nonsymmetric =10 random bidiagonal (log. distrib.) */ if (mtypes > 16) { goto L100; } itype = ktype[jtype - 1]; imode = kmode[jtype - 1]; /* Compute norm */ switch (kmagn[jtype - 1]) { case 1: goto L40; case 2: goto L50; case 3: goto L60; } L40: anorm = 1.f; goto L70; L50: anorm = rtovfl * ulp * amninv; goto L70; L60: anorm = rtunfl * max(m,n) * ulpinv; goto L70; L70: claset_("Full", lda, &n, &c_b1, &c_b1, &a[a_offset], lda); iinfo = 0; cond = ulpinv; bidiag = FALSE_; if (itype == 1) { /* Zero matrix */ iinfo = 0; } else if (itype == 2) { /* Identity */ i__3 = mnmin; for (jcol = 1; jcol <= i__3; ++jcol) { i__4 = a_subscr(jcol, jcol); a[i__4].r = anorm, a[i__4].i = 0.f; /* L80: */ } } else if (itype == 4) { /* Diagonal Matrix, [Eigen]values Specified */ clatms_(&mnmin, &mnmin, "S", &iseed[1], "N", &rwork[1], & imode, &cond, &anorm, &c__0, &c__0, "N", &a[a_offset], lda, &work[1], &iinfo); } else if (itype == 5) { /* Symmetric, eigenvalues specified */ clatms_(&mnmin, &mnmin, "S", &iseed[1], "S", &rwork[1], & imode, &cond, &anorm, &m, &n, "N", &a[a_offset], lda, &work[1], &iinfo); } else if (itype == 6) { /* Nonsymmetric, singular values specified */ clatms_(&m, &n, "S", &iseed[1], "N", &rwork[1], &imode, &cond, &anorm, &m, &n, "N", &a[a_offset], lda, &work[1], & iinfo); } else if (itype == 7) { /* Diagonal, random entries */ clatmr_(&mnmin, &mnmin, "S", &iseed[1], "N", &work[1], &c__6, &c_b37, &c_b2, "T", "N", &work[mnmin + 1], &c__1, & c_b37, &work[(mnmin << 1) + 1], &c__1, &c_b37, "N", iwork, &c__0, &c__0, &c_b47, &anorm, "NO", &a[ a_offset], lda, iwork, &iinfo); } else if (itype == 8) { /* Symmetric, random entries */ clatmr_(&mnmin, &mnmin, "S", &iseed[1], "S", &work[1], &c__6, &c_b37, &c_b2, "T", "N", &work[mnmin + 1], &c__1, & c_b37, &work[m + mnmin + 1], &c__1, &c_b37, "N", iwork, &m, &n, &c_b47, &anorm, "NO", &a[a_offset], lda, iwork, &iinfo); } else if (itype == 9) { /* Nonsymmetric, random entries */ clatmr_(&m, &n, "S", &iseed[1], "N", &work[1], &c__6, &c_b37, &c_b2, "T", "N", &work[mnmin + 1], &c__1, &c_b37, & work[m + mnmin + 1], &c__1, &c_b37, "N", iwork, &m, & n, &c_b47, &anorm, "NO", &a[a_offset], lda, iwork, & iinfo); } else if (itype == 10) { /* Bidiagonal, random entries */ temp1 = log(ulp) * -2.f; i__3 = mnmin; for (j = 1; j <= i__3; ++j) { bd[j] = exp(temp1 * slarnd_(&c__2, &iseed[1])); if (j < mnmin) { be[j] = exp(temp1 * slarnd_(&c__2, &iseed[1])); } /* L90: */ } iinfo = 0; bidiag = TRUE_; if (m >= n) { *(unsigned char *)uplo = 'U'; } else { *(unsigned char *)uplo = 'L'; } } else { iinfo = 1; } if (iinfo == 0) { /* Generate Right-Hand Side */ if (bidiag) { clatmr_(&mnmin, nrhs, "S", &iseed[1], "N", &work[1], & c__6, &c_b37, &c_b2, "T", "N", &work[mnmin + 1], & c__1, &c_b37, &work[(mnmin << 1) + 1], &c__1, & c_b37, "N", iwork, &mnmin, nrhs, &c_b47, &c_b37, "NO", &y[y_offset], ldx, iwork, &iinfo); } else { clatmr_(&m, nrhs, "S", &iseed[1], "N", &work[1], &c__6, & c_b37, &c_b2, "T", "N", &work[m + 1], &c__1, & c_b37, &work[(m << 1) + 1], &c__1, &c_b37, "N", iwork, &m, nrhs, &c_b47, &c_b37, "NO", &x[ x_offset], ldx, iwork, &iinfo); } } /* Error Exit */ if (iinfo != 0) { io___40.ciunit = *nout; s_wsfe(&io___40); do_fio(&c__1, "Generator", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); return 0; } L100: /* Call CGEBRD and CUNGBR to compute B, Q, and P, do tests. */ if (! bidiag) { /* Compute transformations to reduce A to bidiagonal form: B := Q' * A * P. */ clacpy_(" ", &m, &n, &a[a_offset], lda, &q[q_offset], ldq); i__3 = *lwork - (mnmin << 1); cgebrd_(&m, &n, &q[q_offset], ldq, &bd[1], &be[1], &work[1], & work[mnmin + 1], &work[(mnmin << 1) + 1], &i__3, & iinfo); /* Check error code from CGEBRD. */ if (iinfo != 0) { io___41.ciunit = *nout; s_wsfe(&io___41); do_fio(&c__1, "CGEBRD", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } clacpy_(" ", &m, &n, &q[q_offset], ldq, &pt[pt_offset], ldpt); if (m >= n) { *(unsigned char *)uplo = 'U'; } else { *(unsigned char *)uplo = 'L'; } /* Generate Q */ mq = m; if (*nrhs <= 0) { mq = mnmin; } i__3 = *lwork - (mnmin << 1); cungbr_("Q", &m, &mq, &n, &q[q_offset], ldq, &work[1], &work[( mnmin << 1) + 1], &i__3, &iinfo); /* Check error code from CUNGBR. */ if (iinfo != 0) { io___43.ciunit = *nout; s_wsfe(&io___43); do_fio(&c__1, "CUNGBR(Q)", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } /* Generate P' */ i__3 = *lwork - (mnmin << 1); cungbr_("P", &mnmin, &n, &m, &pt[pt_offset], ldpt, &work[ mnmin + 1], &work[(mnmin << 1) + 1], &i__3, &iinfo); /* Check error code from CUNGBR. */ if (iinfo != 0) { io___44.ciunit = *nout; s_wsfe(&io___44); do_fio(&c__1, "CUNGBR(P)", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } /* Apply Q' to an M by NRHS matrix X: Y := Q' * X. */ cgemm_("Conjugate transpose", "No transpose", &m, nrhs, &m, & c_b2, &q[q_offset], ldq, &x[x_offset], ldx, &c_b1, &y[ y_offset], ldx); /* Test 1: Check the decomposition A := Q * B * PT 2: Check the orthogonality of Q 3: Check the orthogonality of PT */ cbdt01_(&m, &n, &c__1, &a[a_offset], lda, &q[q_offset], ldq, & bd[1], &be[1], &pt[pt_offset], ldpt, &work[1], &rwork[ 1], result); cunt01_("Columns", &m, &mq, &q[q_offset], ldq, &work[1], lwork, &rwork[1], &result[1]); cunt01_("Rows", &mnmin, &n, &pt[pt_offset], ldpt, &work[1], lwork, &rwork[1], &result[2]); } /* Use CBDSQR to form the SVD of the bidiagonal matrix B: B := U * S1 * VT, and compute Z = U' * Y. */ scopy_(&mnmin, &bd[1], &c__1, &s1[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &rwork[1], &c__1); } clacpy_(" ", &m, nrhs, &y[y_offset], ldx, &z__[z_offset], ldx); claset_("Full", &mnmin, &mnmin, &c_b1, &c_b2, &u[u_offset], ldpt); claset_("Full", &mnmin, &mnmin, &c_b1, &c_b2, &vt[vt_offset], ldpt); cbdsqr_(uplo, &mnmin, &mnmin, &mnmin, nrhs, &s1[1], &rwork[1], & vt[vt_offset], ldpt, &u[u_offset], ldpt, &z__[z_offset], ldx, &rwork[mnmin + 1], &iinfo); /* Check error code from CBDSQR. */ if (iinfo != 0) { io___45.ciunit = *nout; s_wsfe(&io___45); do_fio(&c__1, "CBDSQR(vects)", (ftnlen)13); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[3] = ulpinv; goto L150; } } /* Use CBDSQR to compute only the singular values of the bidiagonal matrix B; U, VT, and Z should not be modified. */ scopy_(&mnmin, &bd[1], &c__1, &s2[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &rwork[1], &c__1); } cbdsqr_(uplo, &mnmin, &c__0, &c__0, &c__0, &s2[1], &rwork[1], &vt[ vt_offset], ldpt, &u[u_offset], ldpt, &z__[z_offset], ldx, &rwork[mnmin + 1], &iinfo); /* Check error code from CBDSQR. */ if (iinfo != 0) { io___46.ciunit = *nout; s_wsfe(&io___46); do_fio(&c__1, "CBDSQR(values)", (ftnlen)14); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[8] = ulpinv; goto L150; } } /* Test 4: Check the decomposition B := U * S1 * VT 5: Check the computation Z := U' * Y 6: Check the orthogonality of U 7: Check the orthogonality of VT */ cbdt03_(uplo, &mnmin, &c__1, &bd[1], &be[1], &u[u_offset], ldpt, & s1[1], &vt[vt_offset], ldpt, &work[1], &result[3]); cbdt02_(&mnmin, nrhs, &y[y_offset], ldx, &z__[z_offset], ldx, &u[ u_offset], ldpt, &work[1], &rwork[1], &result[4]); cunt01_("Columns", &mnmin, &mnmin, &u[u_offset], ldpt, &work[1], lwork, &rwork[1], &result[5]); cunt01_("Rows", &mnmin, &mnmin, &vt[vt_offset], ldpt, &work[1], lwork, &rwork[1], &result[6]); /* Test 8: Check that the singular values are sorted in non-increasing order and are non-negative */ result[7] = 0.f; i__3 = mnmin - 1; for (i__ = 1; i__ <= i__3; ++i__) { if (s1[i__] < s1[i__ + 1]) { result[7] = ulpinv; } if (s1[i__] < 0.f) { result[7] = ulpinv; } /* L110: */ } if (mnmin >= 1) { if (s1[mnmin] < 0.f) { result[7] = ulpinv; } } /* Test 9: Compare CBDSQR with and without singular vectors */ temp2 = 0.f; i__3 = mnmin; for (j = 1; j <= i__3; ++j) { /* Computing MAX Computing MAX */ r__6 = (r__1 = s1[j], dabs(r__1)), r__7 = (r__2 = s2[j], dabs( r__2)); r__4 = sqrt(unfl) * dmax(s1[1],1.f), r__5 = ulp * dmax(r__6, r__7); temp1 = (r__3 = s1[j] - s2[j], dabs(r__3)) / dmax(r__4,r__5); temp2 = dmax(temp1,temp2); /* L120: */ } result[8] = temp2; /* Test 10: Sturm sequence test of singular values Go up by factors of two until it succeeds */ temp1 = *thresh * (.5f - ulp); i__3 = log2ui; for (j = 0; j <= i__3; ++j) { ssvdch_(&mnmin, &bd[1], &be[1], &s1[1], &temp1, &iinfo); if (iinfo == 0) { goto L140; } temp1 *= 2.f; /* L130: */ } L140: result[9] = temp1; /* Use CBDSQR to form the decomposition A := (QU) S (VT PT) from the bidiagonal form A := Q B PT. */ if (! bidiag) { scopy_(&mnmin, &bd[1], &c__1, &s2[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &rwork[1], &c__1); } cbdsqr_(uplo, &mnmin, &n, &m, nrhs, &s2[1], &rwork[1], &pt[ pt_offset], ldpt, &q[q_offset], ldq, &y[y_offset], ldx, &rwork[mnmin + 1], &iinfo); /* Test 11: Check the decomposition A := Q*U * S2 * VT*PT 12: Check the computation Z := U' * Q' * X 13: Check the orthogonality of Q*U 14: Check the orthogonality of VT*PT */ cbdt01_(&m, &n, &c__0, &a[a_offset], lda, &q[q_offset], ldq, & s2[1], dumma, &pt[pt_offset], ldpt, &work[1], &rwork[ 1], &result[10]); cbdt02_(&m, nrhs, &x[x_offset], ldx, &y[y_offset], ldx, &q[ q_offset], ldq, &work[1], &rwork[1], &result[11]); cunt01_("Columns", &m, &mq, &q[q_offset], ldq, &work[1], lwork, &rwork[1], &result[12]); cunt01_("Rows", &mnmin, &n, &pt[pt_offset], ldpt, &work[1], lwork, &rwork[1], &result[13]); } /* End of Loop -- Check for RESULT(j) > THRESH */ L150: for (j = 1; j <= 14; ++j) { if (result[j - 1] >= *thresh) { if (nfail == 0) { slahd2_(nout, path); } io___50.ciunit = *nout; s_wsfe(&io___50); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[j - 1], (ftnlen)sizeof(real) ); e_wsfe(); ++nfail; } /* L160: */ } if (! bidiag) { ntest += 14; } else { ntest += 5; } L170: ; } /* L180: */ } /* Summary */ alasum_(path, nout, &nfail, &ntest, &c__0); return 0; /* End of CCHKBD */ } /* cchkbd_ */
/* Subroutine */ int sqrt15_(integer *scale, integer *rksel, integer *m, integer *n, integer *nrhs, real *a, integer *lda, real *b, integer * ldb, real *s, integer *rank, real *norma, real *normb, integer *iseed, real *work, integer *lwork) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2; real r__1; /* Local variables */ static integer info; static real temp; extern doublereal snrm2_(integer *, real *, integer *); static integer j; extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *), slarf_(char *, integer *, integer *, real *, integer *, real *, real *, integer *, real *), sgemm_(char *, char *, integer *, integer *, integer *, real *, real *, integer *, real * , integer *, real *, real *, integer *); extern doublereal sasum_(integer *, real *, integer *); static real dummy[1]; static integer mn; extern doublereal slamch_(char *), slange_(char *, integer *, integer *, real *, integer *, real *); extern /* Subroutine */ int xerbla_(char *, integer *); static real bignum; extern /* Subroutine */ int slascl_(char *, integer *, integer *, real *, real *, integer *, integer *, real *, integer *, integer *); extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int slaord_(char *, integer *, real *, integer *), slaset_(char *, integer *, integer *, real *, real *, real *, integer *), slaror_(char *, char *, integer *, integer *, real *, integer *, integer *, real *, integer *), slarnv_(integer *, integer *, integer *, real *); static real smlnum, eps; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] /* -- LAPACK test routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= SQRT15 generates a matrix with full or deficient rank and of various norms. Arguments ========= SCALE (input) INTEGER SCALE = 1: normally scaled matrix SCALE = 2: matrix scaled up SCALE = 3: matrix scaled down RKSEL (input) INTEGER RKSEL = 1: full rank matrix RKSEL = 2: rank-deficient matrix M (input) INTEGER The number of rows of the matrix A. N (input) INTEGER The number of columns of A. NRHS (input) INTEGER The number of columns of B. A (output) REAL array, dimension (LDA,N) The M-by-N matrix A. LDA (input) INTEGER The leading dimension of the array A. B (output) REAL array, dimension (LDB, NRHS) A matrix that is in the range space of matrix A. LDB (input) INTEGER The leading dimension of the array B. S (output) REAL array, dimension MIN(M,N) Singular values of A. RANK (output) INTEGER number of nonzero singular values of A. NORMA (output) REAL one-norm of A. NORMB (output) REAL one-norm of B. ISEED (input/output) integer array, dimension (4) seed for random number generator. WORK (workspace) REAL array, dimension (LWORK) LWORK (input) INTEGER length of work space required. LWORK >= MAX(M+MIN(M,N),NRHS*MIN(M,N),2*N+M) ===================================================================== Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --s; --iseed; --work; /* Function Body */ mn = min(*m,*n); /* Computing MAX */ i__1 = *m + mn, i__2 = mn * *nrhs, i__1 = max(i__1,i__2), i__2 = (*n << 1) + *m; if (*lwork < max(i__1,i__2)) { xerbla_("SQRT15", &c__16); return 0; } smlnum = slamch_("Safe minimum"); bignum = 1.f / smlnum; eps = slamch_("Epsilon"); smlnum = smlnum / eps / eps; bignum = 1.f / smlnum; /* Determine rank and (unscaled) singular values */ if (*rksel == 1) { *rank = mn; } else if (*rksel == 2) { *rank = mn * 3 / 4; i__1 = mn; for (j = *rank + 1; j <= i__1; ++j) { s[j] = 0.f; /* L10: */ } } else { xerbla_("SQRT15", &c__2); } if (*rank > 0) { /* Nontrivial case */ s[1] = 1.f; i__1 = *rank; for (j = 2; j <= i__1; ++j) { L20: temp = slarnd_(&c__1, &iseed[1]); if (temp > .1f) { s[j] = dabs(temp); } else { goto L20; } /* L30: */ } slaord_("Decreasing", rank, &s[1], &c__1); /* Generate 'rank' columns of a random orthogonal matrix in A */ slarnv_(&c__2, &iseed[1], m, &work[1]); r__1 = 1.f / snrm2_(m, &work[1], &c__1); sscal_(m, &r__1, &work[1], &c__1); slaset_("Full", m, rank, &c_b18, &c_b19, &a[a_offset], lda) ; slarf_("Left", m, rank, &work[1], &c__1, &c_b22, &a[a_offset], lda, & work[*m + 1]); /* workspace used: m+mn Generate consistent rhs in the range space of A */ i__1 = *rank * *nrhs; slarnv_(&c__2, &iseed[1], &i__1, &work[1]); sgemm_("No transpose", "No transpose", m, nrhs, rank, &c_b19, &a[ a_offset], lda, &work[1], rank, &c_b18, &b[b_offset], ldb); /* work space used: <= mn *nrhs generate (unscaled) matrix A */ i__1 = *rank; for (j = 1; j <= i__1; ++j) { sscal_(m, &s[j], &a_ref(1, j), &c__1); /* L40: */ } if (*rank < *n) { i__1 = *n - *rank; slaset_("Full", m, &i__1, &c_b18, &c_b18, &a_ref(1, *rank + 1), lda); } slaror_("Right", "No initialization", m, n, &a[a_offset], lda, &iseed[ 1], &work[1], &info); } else { /* work space used 2*n+m Generate null matrix and rhs */ i__1 = mn; for (j = 1; j <= i__1; ++j) { s[j] = 0.f; /* L50: */ } slaset_("Full", m, n, &c_b18, &c_b18, &a[a_offset], lda); slaset_("Full", m, nrhs, &c_b18, &c_b18, &b[b_offset], ldb) ; } /* Scale the matrix */ if (*scale != 1) { *norma = slange_("Max", m, n, &a[a_offset], lda, dummy); if (*norma != 0.f) { if (*scale == 2) { /* matrix scaled up */ slascl_("General", &c__0, &c__0, norma, &bignum, m, n, &a[ a_offset], lda, &info); slascl_("General", &c__0, &c__0, norma, &bignum, &mn, &c__1, & s[1], &mn, &info); slascl_("General", &c__0, &c__0, norma, &bignum, m, nrhs, &b[ b_offset], ldb, &info); } else if (*scale == 3) { /* matrix scaled down */ slascl_("General", &c__0, &c__0, norma, &smlnum, m, n, &a[ a_offset], lda, &info); slascl_("General", &c__0, &c__0, norma, &smlnum, &mn, &c__1, & s[1], &mn, &info); slascl_("General", &c__0, &c__0, norma, &smlnum, m, nrhs, &b[ b_offset], ldb, &info); } else { xerbla_("SQRT15", &c__1); return 0; } } } *norma = sasum_(&mn, &s[1], &c__1); *normb = slange_("One-norm", m, nrhs, &b[b_offset], ldb, dummy) ; return 0; /* End of SQRT15 */ } /* sqrt15_ */
/* Subroutine */ int sdrvrf1_(integer *nout, integer *nn, integer *nval, real *thresh, real *a, integer *lda, real *arf, real *work) { /* Initialized data */ static integer iseedy[4] = { 1988,1989,1990,1991 }; static char uplos[1*2] = "U" "L"; static char forms[1*2] = "N" "T"; static char norms[1*4] = "M" "1" "I" "F"; /* Format strings */ static char fmt_9999[] = "(1x,\002 *** Error(s) or Failure(s) while test" "ing SLANSF ***\002)"; static char fmt_9998[] = "(1x,\002 Error in \002,a6,\002 with UPLO=" "'\002,a1,\002', FORM='\002,a1,\002', N=\002,i5)"; static char fmt_9997[] = "(1x,\002 Failure in \002,a6,\002 N=\002," "i5,\002 TYPE=\002,i5,\002 UPLO='\002,a1,\002', FORM ='\002,a1" ",\002', NORM='\002,a1,\002', test=\002,g12.5)"; static char fmt_9996[] = "(1x,\002All tests for \002,a6,\002 auxiliary r" "outine passed the \002,\002threshold (\002,i5,\002 tests run)" "\002)"; static char fmt_9995[] = "(1x,a6,\002 auxiliary routine:\002,i5,\002 out" " of \002,i5,\002 tests failed to pass the threshold\002)"; static char fmt_9994[] = "(26x,i5,\002 error message recorded (\002,a6" ",\002)\002)"; /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); integer s_wsle(cilist *), e_wsle(void), s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen); /* Local variables */ integer i__, j, n, iin, iit; real eps; integer info; char norm[1], uplo[1]; integer nrun, nfail; real large; integer iseed[4]; char cform[1]; real small; integer iform; real norma; integer inorm, iuplo, nerrs; extern doublereal slamch_(char *), slarnd_(integer *, integer *), slansf_(char *, char *, char *, integer *, real *, real *), slansy_(char *, char *, integer *, real *, integer *, real *); real result[1]; extern /* Subroutine */ int strttf_(char *, char *, integer *, real *, integer *, real *, integer *); real normarf; /* Fortran I/O blocks */ static cilist io___22 = { 0, 0, 0, 0, 0 }; static cilist io___23 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___24 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___30 = { 0, 0, 0, 0, 0 }; static cilist io___31 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___32 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___33 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___34 = { 0, 0, 0, fmt_9995, 0 }; static cilist io___35 = { 0, 0, 0, fmt_9994, 0 }; /* -- LAPACK test routine (version 3.2.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2008 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SDRVRF1 tests the LAPACK RFP routines: */ /* SLANSF */ /* Arguments */ /* ========= */ /* NOUT (input) INTEGER */ /* The unit number for output. */ /* NN (input) INTEGER */ /* The number of values of N contained in the vector NVAL. */ /* NVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix dimension N. */ /* THRESH (input) REAL */ /* The threshold value for the test ratios. A result is */ /* included in the output file if RESULT >= THRESH. To have */ /* every test ratio printed, use THRESH = 0. */ /* A (workspace) REAL array, dimension (LDA,NMAX) */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* ARF (workspace) REAL array, dimension ((NMAX*(NMAX+1))/2). */ /* WORK (workspace) REAL array, dimension ( NMAX ) */ /* ===================================================================== */ /* .. */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nval; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --arf; --work; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Initialize constants and the random number seed. */ nrun = 0; nfail = 0; nerrs = 0; info = 0; for (i__ = 1; i__ <= 4; ++i__) { iseed[i__ - 1] = iseedy[i__ - 1]; /* L10: */ } eps = slamch_("Precision"); small = slamch_("Safe minimum"); large = 1.f / small; small = small * *lda * *lda; large = large / *lda / *lda; i__1 = *nn; for (iin = 1; iin <= i__1; ++iin) { n = nval[iin]; for (iit = 1; iit <= 3; ++iit) { /* IIT = 1 : random matrix */ /* IIT = 2 : random matrix scaled near underflow */ /* IIT = 3 : random matrix scaled near overflow */ i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = 1; i__ <= i__3; ++i__) { a[i__ + j * a_dim1] = slarnd_(&c__2, iseed); } } if (iit == 2) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = 1; i__ <= i__3; ++i__) { a[i__ + j * a_dim1] *= large; } } } if (iit == 3) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = 1; i__ <= i__3; ++i__) { a[i__ + j * a_dim1] *= small; } } } /* Do first for UPLO = 'U', then for UPLO = 'L' */ for (iuplo = 1; iuplo <= 2; ++iuplo) { *(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1]; /* Do first for CFORM = 'N', then for CFORM = 'C' */ for (iform = 1; iform <= 2; ++iform) { *(unsigned char *)cform = *(unsigned char *)&forms[iform - 1]; s_copy(srnamc_1.srnamt, "STRTTF", (ftnlen)32, (ftnlen)6); strttf_(cform, uplo, &n, &a[a_offset], lda, &arf[1], & info); /* Check error code from STRTTF */ if (info != 0) { if (nfail == 0 && nerrs == 0) { io___22.ciunit = *nout; s_wsle(&io___22); e_wsle(); io___23.ciunit = *nout; s_wsfe(&io___23); e_wsfe(); } io___24.ciunit = *nout; s_wsfe(&io___24); do_fio(&c__1, srnamc_1.srnamt, (ftnlen)32); do_fio(&c__1, uplo, (ftnlen)1); do_fio(&c__1, cform, (ftnlen)1); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); e_wsfe(); ++nerrs; goto L100; } for (inorm = 1; inorm <= 4; ++inorm) { /* Check all four norms: 'M', '1', 'I', 'F' */ *(unsigned char *)norm = *(unsigned char *)&norms[ inorm - 1]; normarf = slansf_(norm, cform, uplo, &n, &arf[1], & work[1]); norma = slansy_(norm, uplo, &n, &a[a_offset], lda, & work[1]); result[0] = (norma - normarf) / norma / eps; ++nrun; if (result[0] >= *thresh) { if (nfail == 0 && nerrs == 0) { io___30.ciunit = *nout; s_wsle(&io___30); e_wsle(); io___31.ciunit = *nout; s_wsfe(&io___31); e_wsfe(); } io___32.ciunit = *nout; s_wsfe(&io___32); do_fio(&c__1, "SLANSF", (ftnlen)6); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&iit, (ftnlen)sizeof( integer)); do_fio(&c__1, uplo, (ftnlen)1); do_fio(&c__1, cform, (ftnlen)1); do_fio(&c__1, norm, (ftnlen)1); do_fio(&c__1, (char *)&result[0], (ftnlen)sizeof( real)); e_wsfe(); ++nfail; } /* L90: */ } L100: ; } /* L110: */ } /* L120: */ } /* L130: */ } /* Print a summary of the results. */ if (nfail == 0) { io___33.ciunit = *nout; s_wsfe(&io___33); do_fio(&c__1, "SLANSF", (ftnlen)6); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___34.ciunit = *nout; s_wsfe(&io___34); do_fio(&c__1, "SLANSF", (ftnlen)6); do_fio(&c__1, (char *)&nfail, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } if (nerrs != 0) { io___35.ciunit = *nout; s_wsfe(&io___35); do_fio(&c__1, (char *)&nerrs, (ftnlen)sizeof(integer)); do_fio(&c__1, "SLANSF", (ftnlen)6); e_wsfe(); } return 0; /* End of SDRVRF1 */ } /* sdrvrf1_ */
/* Subroutine */ int cqrt15_(integer *scale, integer *rksel, integer *m, integer *n, integer *nrhs, complex *a, integer *lda, complex *b, integer *ldb, real *s, integer *rank, real *norma, real *normb, integer *iseed, complex *work, integer *lwork) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2; real r__1; /* Local variables */ integer j, mn; real eps; integer info; real temp; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), clarf_(char *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, complex *); extern doublereal sasum_(integer *, real *, integer *); real dummy[1]; extern doublereal scnrm2_(integer *, complex *, integer *); extern /* Subroutine */ int slabad_(real *, real *); extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); extern /* Subroutine */ int clascl_(char *, integer *, integer *, real *, real *, integer *, integer *, complex *, integer *, integer *); extern doublereal slamch_(char *); extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), xerbla_(char *, integer *); real bignum; extern /* Subroutine */ int claror_(char *, char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *); extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int slaord_(char *, integer *, real *, integer *), clarnv_(integer *, integer *, integer *, complex *), slascl_(char *, integer *, integer *, real *, real *, integer *, integer *, real *, integer *, integer *); real smlnum; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CQRT15 generates a matrix with full or deficient rank and of various */ /* norms. */ /* Arguments */ /* ========= */ /* SCALE (input) INTEGER */ /* SCALE = 1: normally scaled matrix */ /* SCALE = 2: matrix scaled up */ /* SCALE = 3: matrix scaled down */ /* RKSEL (input) INTEGER */ /* RKSEL = 1: full rank matrix */ /* RKSEL = 2: rank-deficient matrix */ /* M (input) INTEGER */ /* The number of rows of the matrix A. */ /* N (input) INTEGER */ /* The number of columns of A. */ /* NRHS (input) INTEGER */ /* The number of columns of B. */ /* A (output) COMPLEX array, dimension (LDA,N) */ /* The M-by-N matrix A. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. */ /* B (output) COMPLEX array, dimension (LDB, NRHS) */ /* A matrix that is in the range space of matrix A. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. */ /* S (output) REAL array, dimension MIN(M,N) */ /* Singular values of A. */ /* RANK (output) INTEGER */ /* number of nonzero singular values of A. */ /* NORMA (output) REAL */ /* one-norm norm of A. */ /* NORMB (output) REAL */ /* one-norm norm of B. */ /* ISEED (input/output) integer array, dimension (4) */ /* seed for random number generator. */ /* WORK (workspace) COMPLEX array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* length of work space required. */ /* LWORK >= MAX(M+MIN(M,N),NRHS*MIN(M,N),2*N+M) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; --s; --iseed; --work; /* Function Body */ mn = min(*m,*n); /* Computing MAX */ i__1 = *m + mn, i__2 = mn * *nrhs, i__1 = max(i__1,i__2), i__2 = (*n << 1) + *m; if (*lwork < max(i__1,i__2)) { xerbla_("CQRT15", &c__16); return 0; } smlnum = slamch_("Safe minimum"); bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); eps = slamch_("Epsilon"); smlnum = smlnum / eps / eps; bignum = 1.f / smlnum; /* Determine rank and (unscaled) singular values */ if (*rksel == 1) { *rank = mn; } else if (*rksel == 2) { *rank = mn * 3 / 4; i__1 = mn; for (j = *rank + 1; j <= i__1; ++j) { s[j] = 0.f; /* L10: */ } } else { xerbla_("CQRT15", &c__2); } if (*rank > 0) { /* Nontrivial case */ s[1] = 1.f; i__1 = *rank; for (j = 2; j <= i__1; ++j) { L20: temp = slarnd_(&c__1, &iseed[1]); if (temp > .1f) { s[j] = dabs(temp); } else { goto L20; } /* L30: */ } slaord_("Decreasing", rank, &s[1], &c__1); /* Generate 'rank' columns of a random orthogonal matrix in A */ clarnv_(&c__2, &iseed[1], m, &work[1]); r__1 = 1.f / scnrm2_(m, &work[1], &c__1); csscal_(m, &r__1, &work[1], &c__1); claset_("Full", m, rank, &c_b1, &c_b2, &a[a_offset], lda); clarf_("Left", m, rank, &work[1], &c__1, &c_b22, &a[a_offset], lda, & work[*m + 1]); /* workspace used: m+mn */ /* Generate consistent rhs in the range space of A */ i__1 = *rank * *nrhs; clarnv_(&c__2, &iseed[1], &i__1, &work[1]); cgemm_("No transpose", "No transpose", m, nrhs, rank, &c_b2, &a[ a_offset], lda, &work[1], rank, &c_b1, &b[b_offset], ldb); /* work space used: <= mn *nrhs */ /* generate (unscaled) matrix A */ i__1 = *rank; for (j = 1; j <= i__1; ++j) { csscal_(m, &s[j], &a[j * a_dim1 + 1], &c__1); /* L40: */ } if (*rank < *n) { i__1 = *n - *rank; claset_("Full", m, &i__1, &c_b1, &c_b1, &a[(*rank + 1) * a_dim1 + 1], lda); } claror_("Right", "No initialization", m, n, &a[a_offset], lda, &iseed[ 1], &work[1], &info); } else { /* work space used 2*n+m */ /* Generate null matrix and rhs */ i__1 = mn; for (j = 1; j <= i__1; ++j) { s[j] = 0.f; /* L50: */ } claset_("Full", m, n, &c_b1, &c_b1, &a[a_offset], lda); claset_("Full", m, nrhs, &c_b1, &c_b1, &b[b_offset], ldb); } /* Scale the matrix */ if (*scale != 1) { *norma = clange_("Max", m, n, &a[a_offset], lda, dummy); if (*norma != 0.f) { if (*scale == 2) { /* matrix scaled up */ clascl_("General", &c__0, &c__0, norma, &bignum, m, n, &a[ a_offset], lda, &info); slascl_("General", &c__0, &c__0, norma, &bignum, &mn, &c__1, & s[1], &mn, &info); clascl_("General", &c__0, &c__0, norma, &bignum, m, nrhs, &b[ b_offset], ldb, &info); } else if (*scale == 3) { /* matrix scaled down */ clascl_("General", &c__0, &c__0, norma, &smlnum, m, n, &a[ a_offset], lda, &info); slascl_("General", &c__0, &c__0, norma, &smlnum, &mn, &c__1, & s[1], &mn, &info); clascl_("General", &c__0, &c__0, norma, &smlnum, m, nrhs, &b[ b_offset], ldb, &info); } else { xerbla_("CQRT15", &c__1); return 0; } } } *norma = sasum_(&mn, &s[1], &c__1); *normb = clange_("One-norm", m, nrhs, &b[b_offset], ldb, dummy) ; return 0; /* End of CQRT15 */ } /* cqrt15_ */
/* Subroutine */ int slaror_(char *side, char *init, integer *m, integer *n, real *a, integer *lda, integer *iseed, real *x, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2; real r__1; /* Builtin functions */ double r_sign(real *, real *); /* Local variables */ static integer kbeg, jcol; extern /* Subroutine */ int sger_(integer *, integer *, real *, real *, integer *, real *, integer *, real *, integer *); static integer irow; extern real snrm2_(integer *, real *, integer *); static integer j; extern logical lsame_(char *, char *); extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *), sgemv_(char *, integer *, integer *, real *, real *, integer *, real *, integer *, real *, real *, integer *); static integer ixfrm, itype, nxfrm; static real xnorm; extern /* Subroutine */ int xerbla_(char *, integer *); static real factor; extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *, real *, real *, integer *); static real xnorms; /* -- LAPACK auxiliary test routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= SLAROR pre- or post-multiplies an M by N matrix A by a random orthogonal matrix U, overwriting A. A may optionally be initialized to the identity matrix before multiplying by U. U is generated using the method of G.W. Stewart (SIAM J. Numer. Anal. 17, 1980, 403-409). Arguments ========= SIDE (input) CHARACTER*1 Specifies whether A is multiplied on the left or right by U. = 'L': Multiply A on the left (premultiply) by U = 'R': Multiply A on the right (postmultiply) by U' = 'C' or 'T': Multiply A on the left by U and the right by U' (Here, U' means U-transpose.) INIT (input) CHARACTER*1 Specifies whether or not A should be initialized to the identity matrix. = 'I': Initialize A to (a section of) the identity matrix before applying U. = 'N': No initialization. Apply U to the input matrix A. INIT = 'I' may be used to generate square or rectangular orthogonal matrices: For M = N and SIDE = 'L' or 'R', the rows will be orthogonal to each other, as will the columns. If M < N, SIDE = 'R' produces a dense matrix whose rows are orthogonal and whose columns are not, while SIDE = 'L' produces a matrix whose rows are orthogonal, and whose first M columns are orthogonal, and whose remaining columns are zero. If M > N, SIDE = 'L' produces a dense matrix whose columns are orthogonal and whose rows are not, while SIDE = 'R' produces a matrix whose columns are orthogonal, and whose first M rows are orthogonal, and whose remaining rows are zero. M (input) INTEGER The number of rows of A. N (input) INTEGER The number of columns of A. A (input/output) REAL array, dimension (LDA, N) On entry, the array A. On exit, overwritten by U A ( if SIDE = 'L' ), or by A U ( if SIDE = 'R' ), or by U A U' ( if SIDE = 'C' or 'T'). LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,M). ISEED (input/output) INTEGER array, dimension (4) On entry ISEED specifies the seed of the random number generator. The array elements should be between 0 and 4095; if not they will be reduced mod 4096. Also, ISEED(4) must be odd. The random number generator uses a linear congruential sequence limited to small integers, and so should produce machine independent random numbers. The values of ISEED are changed on exit, and can be used in the next call to SLAROR to continue the same random number sequence. X (workspace) REAL array, dimension (3*MAX( M, N )) Workspace of length 2*M + N if SIDE = 'L', 2*N + M if SIDE = 'R', 3*N if SIDE = 'C' or 'T'. INFO (output) INTEGER An error flag. It is set to: = 0: normal return < 0: if INFO = -k, the k-th argument had an illegal value = 1: if the random numbers generated by SLARND are bad. ===================================================================== Parameter adjustments */ a_dim1 = *lda; a_offset = a_dim1 + 1; a -= a_offset; --iseed; --x; /* Function Body */ if (*n == 0 || *m == 0) { return 0; } itype = 0; if (lsame_(side, "L")) { itype = 1; } else if (lsame_(side, "R")) { itype = 2; } else if (lsame_(side, "C") || lsame_(side, "T")) { itype = 3; } /* Check for argument errors. */ *info = 0; if (itype == 0) { *info = -1; } else if (*m < 0) { *info = -3; } else if (*n < 0 || itype == 3 && *n != *m) { *info = -4; } else if (*lda < *m) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("SLAROR", &i__1); return 0; } if (itype == 1) { nxfrm = *m; } else { nxfrm = *n; } /* Initialize A to the identity matrix if desired */ if (lsame_(init, "I")) { slaset_("Full", m, n, &c_b9, &c_b10, &a[a_offset], lda); } /* If no rotation possible, multiply by random +/-1 Compute rotation by computing Householder transformations H(2), H(3), ..., H(nhouse) */ i__1 = nxfrm; for (j = 1; j <= i__1; ++j) { x[j] = 0.f; /* L10: */ } i__1 = nxfrm; for (ixfrm = 2; ixfrm <= i__1; ++ixfrm) { kbeg = nxfrm - ixfrm + 1; /* Generate independent normal( 0, 1 ) random numbers */ i__2 = nxfrm; for (j = kbeg; j <= i__2; ++j) { x[j] = slarnd_(&c__3, &iseed[1]); /* L20: */ } /* Generate a Householder transformation from the random vector X */ xnorm = snrm2_(&ixfrm, &x[kbeg], &c__1); xnorms = r_sign(&xnorm, &x[kbeg]); r__1 = -(doublereal)x[kbeg]; x[kbeg + nxfrm] = r_sign(&c_b10, &r__1); factor = xnorms * (xnorms + x[kbeg]); if (dabs(factor) < 1e-20f) { *info = 1; xerbla_("SLAROR", info); return 0; } else { factor = 1.f / factor; } x[kbeg] += xnorms; /* Apply Householder transformation to A */ if (itype == 1 || itype == 3) { /* Apply H(k) from the left. */ sgemv_("T", &ixfrm, n, &c_b10, &a[kbeg + a_dim1], lda, &x[kbeg], & c__1, &c_b9, &x[(nxfrm << 1) + 1], &c__1); r__1 = -(doublereal)factor; sger_(&ixfrm, n, &r__1, &x[kbeg], &c__1, &x[(nxfrm << 1) + 1], & c__1, &a[kbeg + a_dim1], lda); } if (itype == 2 || itype == 3) { /* Apply H(k) from the right. */ sgemv_("N", m, &ixfrm, &c_b10, &a[kbeg * a_dim1 + 1], lda, &x[ kbeg], &c__1, &c_b9, &x[(nxfrm << 1) + 1], &c__1); r__1 = -(doublereal)factor; sger_(m, &ixfrm, &r__1, &x[(nxfrm << 1) + 1], &c__1, &x[kbeg], & c__1, &a[kbeg * a_dim1 + 1], lda); } /* L30: */ } r__1 = slarnd_(&c__3, &iseed[1]); x[nxfrm * 2] = r_sign(&c_b10, &r__1); /* Scale the matrix A by D. */ if (itype == 1 || itype == 3) { i__1 = *m; for (irow = 1; irow <= i__1; ++irow) { sscal_(n, &x[nxfrm + irow], &a[irow + a_dim1], lda); /* L40: */ } } if (itype == 2 || itype == 3) { i__1 = *n; for (jcol = 1; jcol <= i__1; ++jcol) { sscal_(m, &x[nxfrm + jcol], &a[jcol * a_dim1 + 1], &c__1); /* L50: */ } } return 0; /* End of SLAROR */ } /* slaror_ */
doublereal slatm3_(integer *m, integer *n, integer *i__, integer *j, integer * isub, integer *jsub, integer *kl, integer *ku, integer *idist, integer *iseed, real *d__, integer *igrade, real *dl, real *dr, integer *ipvtng, integer *iwork, real *sparse) { /* System generated locals */ real ret_val; /* Local variables */ real temp; extern doublereal slaran_(integer *), slarnd_(integer *, integer *); /* -- LAPACK auxiliary test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SLATM3 returns the (ISUB,JSUB) entry of a random matrix of */ /* dimension (M, N) described by the other paramters. (ISUB,JSUB) */ /* is the final position of the (I,J) entry after pivoting */ /* according to IPVTNG and IWORK. SLATM3 is called by the */ /* SLATMR routine in order to build random test matrices. No error */ /* checking on parameters is done, because this routine is called in */ /* a tight loop by SLATMR which has already checked the parameters. */ /* Use of SLATM3 differs from SLATM2 in the order in which the random */ /* number generator is called to fill in random matrix entries. */ /* With SLATM2, the generator is called to fill in the pivoted matrix */ /* columnwise. With SLATM3, the generator is called to fill in the */ /* matrix columnwise, after which it is pivoted. Thus, SLATM3 can */ /* be used to construct random matrices which differ only in their */ /* order of rows and/or columns. SLATM2 is used to construct band */ /* matrices while avoiding calling the random number generator for */ /* entries outside the band (and therefore generating random numbers */ /* in different orders for different pivot orders). */ /* The matrix whose (ISUB,JSUB) entry is returned is constructed as */ /* follows (this routine only computes one entry): */ /* If ISUB is outside (1..M) or JSUB is outside (1..N), return zero */ /* (this is convenient for generating matrices in band format). */ /* Generate a matrix A with random entries of distribution IDIST. */ /* Set the diagonal to D. */ /* Grade the matrix, if desired, from the left (by DL) and/or */ /* from the right (by DR or DL) as specified by IGRADE. */ /* Permute, if desired, the rows and/or columns as specified by */ /* IPVTNG and IWORK. */ /* Band the matrix to have lower bandwidth KL and upper */ /* bandwidth KU. */ /* Set random entries to zero as specified by SPARSE. */ /* Arguments */ /* ========= */ /* M - INTEGER */ /* Number of rows of matrix. Not modified. */ /* N - INTEGER */ /* Number of columns of matrix. Not modified. */ /* I - INTEGER */ /* Row of unpivoted entry to be returned. Not modified. */ /* J - INTEGER */ /* Column of unpivoted entry to be returned. Not modified. */ /* ISUB - INTEGER */ /* Row of pivoted entry to be returned. Changed on exit. */ /* JSUB - INTEGER */ /* Column of pivoted entry to be returned. Changed on exit. */ /* KL - INTEGER */ /* Lower bandwidth. Not modified. */ /* KU - INTEGER */ /* Upper bandwidth. Not modified. */ /* IDIST - INTEGER */ /* On entry, IDIST specifies the type of distribution to be */ /* used to generate a random matrix . */ /* 1 => UNIFORM( 0, 1 ) */ /* 2 => UNIFORM( -1, 1 ) */ /* 3 => NORMAL( 0, 1 ) */ /* Not modified. */ /* ISEED - INTEGER array of dimension ( 4 ) */ /* Seed for random number generator. */ /* Changed on exit. */ /* D - REAL array of dimension ( MIN( I , J ) ) */ /* Diagonal entries of matrix. Not modified. */ /* IGRADE - INTEGER */ /* Specifies grading of matrix as follows: */ /* 0 => no grading */ /* 1 => matrix premultiplied by diag( DL ) */ /* 2 => matrix postmultiplied by diag( DR ) */ /* 3 => matrix premultiplied by diag( DL ) and */ /* postmultiplied by diag( DR ) */ /* 4 => matrix premultiplied by diag( DL ) and */ /* postmultiplied by inv( diag( DL ) ) */ /* 5 => matrix premultiplied by diag( DL ) and */ /* postmultiplied by diag( DL ) */ /* Not modified. */ /* DL - REAL array ( I or J, as appropriate ) */ /* Left scale factors for grading matrix. Not modified. */ /* DR - REAL array ( I or J, as appropriate ) */ /* Right scale factors for grading matrix. Not modified. */ /* IPVTNG - INTEGER */ /* On entry specifies pivoting permutations as follows: */ /* 0 => none. */ /* 1 => row pivoting. */ /* 2 => column pivoting. */ /* 3 => full pivoting, i.e., on both sides. */ /* Not modified. */ /* IWORK - INTEGER array ( I or J, as appropriate ) */ /* This array specifies the permutation used. The */ /* row (or column) originally in position K is in */ /* position IWORK( K ) after pivoting. */ /* This differs from IWORK for SLATM2. Not modified. */ /* SPARSE - REAL between 0. and 1. */ /* On entry specifies the sparsity of the matrix */ /* if sparse matix is to be generated. */ /* SPARSE should lie between 0 and 1. */ /* A uniform ( 0, 1 ) random number x is generated and */ /* compared to SPARSE; if x is larger the matrix entry */ /* is unchanged and if x is smaller the entry is set */ /* to zero. Thus on the average a fraction SPARSE of the */ /* entries will be set to zero. */ /* Not modified. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* ----------------------------------------------------------------------- */ /* .. Executable Statements .. */ /* Check for I and J in range */ /* Parameter adjustments */ --iwork; --dr; --dl; --d__; --iseed; /* Function Body */ if (*i__ < 1 || *i__ > *m || *j < 1 || *j > *n) { *isub = *i__; *jsub = *j; ret_val = 0.f; return ret_val; } /* Compute subscripts depending on IPVTNG */ if (*ipvtng == 0) { *isub = *i__; *jsub = *j; } else if (*ipvtng == 1) { *isub = iwork[*i__]; *jsub = *j; } else if (*ipvtng == 2) { *isub = *i__; *jsub = iwork[*j]; } else if (*ipvtng == 3) { *isub = iwork[*i__]; *jsub = iwork[*j]; } /* Check for banding */ if (*jsub > *isub + *ku || *jsub < *isub - *kl) { ret_val = 0.f; return ret_val; } /* Check for sparsity */ if (*sparse > 0.f) { if (slaran_(&iseed[1]) < *sparse) { ret_val = 0.f; return ret_val; } } /* Compute entry and grade it according to IGRADE */ if (*i__ == *j) { temp = d__[*i__]; } else { temp = slarnd_(idist, &iseed[1]); } if (*igrade == 1) { temp *= dl[*i__]; } else if (*igrade == 2) { temp *= dr[*j]; } else if (*igrade == 3) { temp = temp * dl[*i__] * dr[*j]; } else if (*igrade == 4 && *i__ != *j) { temp = temp * dl[*i__] / dl[*j]; } else if (*igrade == 5) { temp = temp * dl[*i__] * dl[*j]; } ret_val = temp; return ret_val; /* End of SLATM3 */ } /* slatm3_ */
/* Subroutine */ int cdrvrf4_(integer *nout, integer *nn, integer *nval, real *thresh, complex *c1, complex *c2, integer *ldc, complex *crf, complex *a, integer *lda, real *s_work_clange__) { /* Initialized data */ static integer iseedy[4] = { 1988,1989,1990,1991 }; static char uplos[1*2] = "U" "L"; static char forms[1*2] = "N" "C"; static char transs[1*2] = "N" "C"; /* Format strings */ static char fmt_9999[] = "(1x,\002 *** Error(s) or Failure(s) while test" "ing CHFRK ***\002)"; static char fmt_9997[] = "(1x,\002 Failure in \002,a5,\002, CFORM=" "'\002,a1,\002',\002,\002 UPLO='\002,a1,\002',\002,\002 TRANS=" "'\002,a1,\002',\002,\002 N=\002,i3,\002, K =\002,i3,\002, test" "=\002,g12.5)"; static char fmt_9996[] = "(1x,\002All tests for \002,a5,\002 auxiliary r" "outine passed the \002,\002threshold (\002,i5,\002 tests run)" "\002)"; static char fmt_9995[] = "(1x,a6,\002 auxiliary routine:\002,i5,\002 out" " of \002,i5,\002 tests failed to pass the threshold\002)"; /* System generated locals */ integer a_dim1, a_offset, c1_dim1, c1_offset, c2_dim1, c2_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1; complex q__1; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); integer s_wsle(cilist *), e_wsle(void), s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen); /* Local variables */ integer i__, j, k, n, iik, iin; real eps, beta; integer info; char uplo[1]; integer nrun; real alpha; integer nfail, iseed[4]; extern /* Subroutine */ int cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *, integer *), chfrk_(char *, char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *); char cform[1]; integer iform; real norma, normc; char trans[1]; integer iuplo; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); integer ialpha; extern /* Complex */ VOID clarnd_(complex *, integer *, integer *); extern doublereal slamch_(char *), slarnd_(integer *, integer *); integer itrans; extern /* Subroutine */ int ctfttr_(char *, char *, integer *, complex *, complex *, integer *, integer *), ctrttf_(char *, char *, integer *, complex *, integer *, complex *, integer *); real result[1]; /* Fortran I/O blocks */ static cilist io___28 = { 0, 0, 0, 0, 0 }; static cilist io___29 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___30 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___31 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___32 = { 0, 0, 0, fmt_9995, 0 }; /* -- LAPACK test routine (version 3.2.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2008 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CDRVRF4 tests the LAPACK RFP routines: */ /* CHFRK */ /* Arguments */ /* ========= */ /* NOUT (input) INTEGER */ /* The unit number for output. */ /* NN (input) INTEGER */ /* The number of values of N contained in the vector NVAL. */ /* NVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix dimension N. */ /* THRESH (input) REAL */ /* The threshold value for the test ratios. A result is */ /* included in the output file if RESULT >= THRESH. To have */ /* every test ratio printed, use THRESH = 0. */ /* C1 (workspace) COMPLEX array, dimension (LDC,NMAX) */ /* C2 (workspace) COMPLEX array, dimension (LDC,NMAX) */ /* LDC (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* CRF (workspace) COMPLEX array, dimension ((NMAX*(NMAX+1))/2). */ /* A (workspace) COMPLEX array, dimension (LDA,NMAX) */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* S_WORK_CLANGE (workspace) REAL array, dimension (NMAX) */ /* ===================================================================== */ /* .. */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nval; c2_dim1 = *ldc; c2_offset = 1 + c2_dim1; c2 -= c2_offset; c1_dim1 = *ldc; c1_offset = 1 + c1_dim1; c1 -= c1_offset; --crf; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --s_work_clange__; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Initialize constants and the random number seed. */ nrun = 0; nfail = 0; info = 0; for (i__ = 1; i__ <= 4; ++i__) { iseed[i__ - 1] = iseedy[i__ - 1]; /* L10: */ } eps = slamch_("Precision"); i__1 = *nn; for (iin = 1; iin <= i__1; ++iin) { n = nval[iin]; i__2 = *nn; for (iik = 1; iik <= i__2; ++iik) { k = nval[iin]; for (iform = 1; iform <= 2; ++iform) { *(unsigned char *)cform = *(unsigned char *)&forms[iform - 1]; for (iuplo = 1; iuplo <= 2; ++iuplo) { *(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1]; for (itrans = 1; itrans <= 2; ++itrans) { *(unsigned char *)trans = *(unsigned char *)&transs[ itrans - 1]; for (ialpha = 1; ialpha <= 4; ++ialpha) { if (ialpha == 1) { alpha = 0.f; beta = 0.f; } else if (ialpha == 1) { alpha = 1.f; beta = 0.f; } else if (ialpha == 1) { alpha = 0.f; beta = 1.f; } else { alpha = slarnd_(&c__2, iseed); beta = slarnd_(&c__2, iseed); } /* All the parameters are set: */ /* CFORM, UPLO, TRANS, M, N, */ /* ALPHA, and BETA */ /* READY TO TEST! */ ++nrun; if (itrans == 1) { /* In this case we are NOTRANS, so A is N-by-K */ i__3 = k; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * a_dim1; clarnd_(&q__1, &c__4, iseed); a[i__5].r = q__1.r, a[i__5].i = q__1.i; } } norma = clange_("I", &n, &k, &a[a_offset], lda, &s_work_clange__[1]); } else { /* In this case we are TRANS, so A is K-by-N */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = k; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * a_dim1; clarnd_(&q__1, &c__4, iseed); a[i__5].r = q__1.r, a[i__5].i = q__1.i; } } norma = clange_("I", &k, &n, &a[a_offset], lda, &s_work_clange__[1]); } /* Generate C1 our N--by--N Hermitian matrix. */ /* Make sure C2 has the same upper/lower part, */ /* (the one that we do not touch), so */ /* copy the initial C1 in C2 in it. */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * c1_dim1; clarnd_(&q__1, &c__4, iseed); c1[i__5].r = q__1.r, c1[i__5].i = q__1.i; i__5 = i__ + j * c2_dim1; i__6 = i__ + j * c1_dim1; c2[i__5].r = c1[i__6].r, c2[i__5].i = c1[ i__6].i; } } /* (See comment later on for why we use CLANGE and */ /* not CLANHE for C1.) */ normc = clange_("I", &n, &n, &c1[c1_offset], ldc, &s_work_clange__[1]); s_copy(srnamc_1.srnamt, "CTRTTF", (ftnlen)32, ( ftnlen)6); ctrttf_(cform, uplo, &n, &c1[c1_offset], ldc, & crf[1], &info); /* call zherk the BLAS routine -> gives C1 */ s_copy(srnamc_1.srnamt, "CHERK ", (ftnlen)32, ( ftnlen)6); cherk_(uplo, trans, &n, &k, &alpha, &a[a_offset], lda, &beta, &c1[c1_offset], ldc); /* call zhfrk the RFP routine -> gives CRF */ s_copy(srnamc_1.srnamt, "CHFRK ", (ftnlen)32, ( ftnlen)6); chfrk_(cform, uplo, trans, &n, &k, &alpha, &a[ a_offset], lda, &beta, &crf[1]); /* convert CRF in full format -> gives C2 */ s_copy(srnamc_1.srnamt, "CTFTTR", (ftnlen)32, ( ftnlen)6); ctfttr_(cform, uplo, &n, &crf[1], &c2[c2_offset], ldc, &info); /* compare C1 and C2 */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * c1_dim1; i__6 = i__ + j * c1_dim1; i__7 = i__ + j * c2_dim1; q__1.r = c1[i__6].r - c2[i__7].r, q__1.i = c1[i__6].i - c2[i__7].i; c1[i__5].r = q__1.r, c1[i__5].i = q__1.i; } } /* Yes, C1 is Hermitian so we could call CLANHE, */ /* but we want to check the upper part that is */ /* supposed to be unchanged and the diagonal that */ /* is supposed to be real -> CLANGE */ result[0] = clange_("I", &n, &n, &c1[c1_offset], ldc, &s_work_clange__[1]); /* Computing MAX */ r__1 = dabs(alpha) * norma * norma + dabs(beta) * normc; result[0] = result[0] / dmax(r__1,1.f) / max(n,1) / eps; if (result[0] >= *thresh) { if (nfail == 0) { io___28.ciunit = *nout; s_wsle(&io___28); e_wsle(); io___29.ciunit = *nout; s_wsfe(&io___29); e_wsfe(); } io___30.ciunit = *nout; s_wsfe(&io___30); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, cform, (ftnlen)1); do_fio(&c__1, uplo, (ftnlen)1); do_fio(&c__1, trans, (ftnlen)1); do_fio(&c__1, (char *)&n, (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&k, (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&result[0], (ftnlen) sizeof(real)); e_wsfe(); ++nfail; } /* L100: */ } /* L110: */ } /* L120: */ } /* L130: */ } /* L140: */ } /* L150: */ } /* Print a summary of the results. */ if (nfail == 0) { io___31.ciunit = *nout; s_wsfe(&io___31); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___32.ciunit = *nout; s_wsfe(&io___32); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, (char *)&nfail, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } return 0; /* End of CDRVRF4 */ } /* cdrvrf4_ */
/* Subroutine */ int sdrvrf2_(integer *nout, integer *nn, integer *nval, real *a, integer *lda, real *arf, real *ap, real *asav) { /* Initialized data */ static integer iseedy[4] = { 1988,1989,1990,1991 }; static char uplos[1*2] = "U" "L"; static char forms[1*2] = "N" "T"; /* Format strings */ static char fmt_9999[] = "(1x,\002 *** Error(s) while testing the RFP co" "nvertion\002,\002 routines ***\002)"; static char fmt_9998[] = "(1x,\002 Error in RFP,convertion routines " "N=\002,i5,\002 UPLO='\002,a1,\002', FORM ='\002,a1,\002'\002)"; static char fmt_9997[] = "(1x,\002All tests for the RFP convertion routi" "nes passed (\002,i5,\002 tests run)\002)"; static char fmt_9996[] = "(1x,\002RFP convertion routines:\002,i5,\002 o" "ut of \002,i5,\002 error message recorded\002)"; /* System generated locals */ integer a_dim1, a_offset, asav_dim1, asav_offset, i__1, i__2, i__3; /* Local variables */ integer i__, j, n; logical ok1, ok2; integer iin, info; char uplo[1]; integer nrun, iseed[4]; char cform[1]; integer iform; logical lower; integer iuplo, nerrs; /* Fortran I/O blocks */ static cilist io___19 = { 0, 0, 0, 0, 0 }; static cilist io___20 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___21 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___22 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___23 = { 0, 0, 0, fmt_9996, 0 }; /* -- LAPACK test routine (version 3.2.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2008 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SDRVRF2 tests the LAPACK RFP convertion routines. */ /* Arguments */ /* ========= */ /* NOUT (input) INTEGER */ /* The unit number for output. */ /* NN (input) INTEGER */ /* The number of values of N contained in the vector NVAL. */ /* NVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix dimension N. */ /* A (workspace) REAL array, dimension (LDA,NMAX) */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* ARF (workspace) REAL array, dimension ((NMAX*(NMAX+1))/2). */ /* AP (workspace) REAL array, dimension ((NMAX*(NMAX+1))/2). */ /* A2 (workspace) REAL array, dimension (LDA,NMAX) */ /* ===================================================================== */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nval; asav_dim1 = *lda; asav_offset = 1 + asav_dim1; asav -= asav_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --arf; --ap; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Initialize constants and the random number seed. */ nrun = 0; nerrs = 0; info = 0; for (i__ = 1; i__ <= 4; ++i__) { iseed[i__ - 1] = iseedy[i__ - 1]; /* L10: */ } i__1 = *nn; for (iin = 1; iin <= i__1; ++iin) { n = nval[iin]; /* Do first for UPLO = 'U', then for UPLO = 'L' */ for (iuplo = 1; iuplo <= 2; ++iuplo) { *(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1]; lower = TRUE_; if (iuplo == 1) { lower = FALSE_; } /* Do first for CFORM = 'N', then for CFORM = 'T' */ for (iform = 1; iform <= 2; ++iform) { *(unsigned char *)cform = *(unsigned char *)&forms[iform - 1]; ++nrun; i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = 1; i__ <= i__3; ++i__) { a[i__ + j * a_dim1] = slarnd_(&c__2, iseed); } } s_copy(srnamc_1.srnamt, "DTRTTF", (ftnlen)32, (ftnlen)6); strttf_(cform, uplo, &n, &a[a_offset], lda, &arf[1], &info); s_copy(srnamc_1.srnamt, "DTFTTP", (ftnlen)32, (ftnlen)6); stfttp_(cform, uplo, &n, &arf[1], &ap[1], &info); s_copy(srnamc_1.srnamt, "DTPTTR", (ftnlen)32, (ftnlen)6); stpttr_(uplo, &n, &ap[1], &asav[asav_offset], lda, &info); ok1 = TRUE_; if (lower) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = j; i__ <= i__3; ++i__) { if (a[i__ + j * a_dim1] != asav[i__ + j * asav_dim1]) { ok1 = FALSE_; } } } } else { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = j; for (i__ = 1; i__ <= i__3; ++i__) { if (a[i__ + j * a_dim1] != asav[i__ + j * asav_dim1]) { ok1 = FALSE_; } } } } ++nrun; s_copy(srnamc_1.srnamt, "DTRTTP", (ftnlen)32, (ftnlen)6); strttp_(uplo, &n, &a[a_offset], lda, &ap[1], &info) ; s_copy(srnamc_1.srnamt, "DTPTTF", (ftnlen)32, (ftnlen)6); stpttf_(cform, uplo, &n, &ap[1], &arf[1], &info); s_copy(srnamc_1.srnamt, "DTFTTR", (ftnlen)32, (ftnlen)6); stfttr_(cform, uplo, &n, &arf[1], &asav[asav_offset], lda, & info); ok2 = TRUE_; if (lower) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = n; for (i__ = j; i__ <= i__3; ++i__) { if (a[i__ + j * a_dim1] != asav[i__ + j * asav_dim1]) { ok2 = FALSE_; } } } } else { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = j; for (i__ = 1; i__ <= i__3; ++i__) { if (a[i__ + j * a_dim1] != asav[i__ + j * asav_dim1]) { ok2 = FALSE_; } } } } if (! ok1 || ! ok2) { if (nerrs == 0) { io___19.ciunit = *nout; s_wsle(&io___19); e_wsle(); io___20.ciunit = *nout; s_wsfe(&io___20); e_wsfe(); } io___21.ciunit = *nout; s_wsfe(&io___21); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, uplo, (ftnlen)1); do_fio(&c__1, cform, (ftnlen)1); e_wsfe(); ++nerrs; } /* L100: */ } /* L110: */ } /* L120: */ } /* Print a summary of the results. */ if (nerrs == 0) { io___22.ciunit = *nout; s_wsfe(&io___22); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___23.ciunit = *nout; s_wsfe(&io___23); do_fio(&c__1, (char *)&nerrs, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } return 0; /* End of SDRVRF2 */ } /* sdrvrf2_ */
doublereal slatm2_(integer *m, integer *n, integer *i__, integer *j, integer * kl, integer *ku, integer *idist, integer *iseed, real *d__, integer * igrade, real *dl, real *dr, integer *ipvtng, integer *iwork, real * sparse) { /* System generated locals */ real ret_val; /* Local variables */ static integer isub, jsub; static real temp; extern doublereal slaran_(integer *), slarnd_(integer *, integer *); /* -- LAPACK auxiliary test routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University February 29, 1992 Purpose ======= SLATM2 returns the (I,J) entry of a random matrix of dimension (M, N) described by the other paramters. It is called by the SLATMR routine in order to build random test matrices. No error checking on parameters is done, because this routine is called in a tight loop by SLATMR which has already checked the parameters. Use of SLATM2 differs from SLATM3 in the order in which the random number generator is called to fill in random matrix entries. With SLATM2, the generator is called to fill in the pivoted matrix columnwise. With SLATM3, the generator is called to fill in the matrix columnwise, after which it is pivoted. Thus, SLATM3 can be used to construct random matrices which differ only in their order of rows and/or columns. SLATM2 is used to construct band matrices while avoiding calling the random number generator for entries outside the band (and therefore generating random numbers The matrix whose (I,J) entry is returned is constructed as follows (this routine only computes one entry): If I is outside (1..M) or J is outside (1..N), return zero (this is convenient for generating matrices in band format). Generate a matrix A with random entries of distribution IDIST. Set the diagonal to D. Grade the matrix, if desired, from the left (by DL) and/or from the right (by DR or DL) as specified by IGRADE. Permute, if desired, the rows and/or columns as specified by IPVTNG and IWORK. Band the matrix to have lower bandwidth KL and upper bandwidth KU. Set random entries to zero as specified by SPARSE. Arguments ========= M - INTEGER Number of rows of matrix. Not modified. N - INTEGER Number of columns of matrix. Not modified. I - INTEGER Row of entry to be returned. Not modified. J - INTEGER Column of entry to be returned. Not modified. KL - INTEGER Lower bandwidth. Not modified. KU - INTEGER Upper bandwidth. Not modified. IDIST - INTEGER On entry, IDIST specifies the type of distribution to be used to generate a random matrix . 1 => UNIFORM( 0, 1 ) 2 => UNIFORM( -1, 1 ) 3 => NORMAL( 0, 1 ) Not modified. ISEED - INTEGER array of dimension ( 4 ) Seed for random number generator. Changed on exit. D - REAL array of dimension ( MIN( I , J ) ) Diagonal entries of matrix. Not modified. IGRADE - INTEGER Specifies grading of matrix as follows: 0 => no grading 1 => matrix premultiplied by diag( DL ) 2 => matrix postmultiplied by diag( DR ) 3 => matrix premultiplied by diag( DL ) and postmultiplied by diag( DR ) 4 => matrix premultiplied by diag( DL ) and postmultiplied by inv( diag( DL ) ) 5 => matrix premultiplied by diag( DL ) and postmultiplied by diag( DL ) Not modified. DL - REAL array ( I or J, as appropriate ) Left scale factors for grading matrix. Not modified. DR - REAL array ( I or J, as appropriate ) Right scale factors for grading matrix. Not modified. IPVTNG - INTEGER On entry specifies pivoting permutations as follows: 0 => none. 1 => row pivoting. 2 => column pivoting. 3 => full pivoting, i.e., on both sides. Not modified. IWORK - INTEGER array ( I or J, as appropriate ) This array specifies the permutation used. The row (or column) in position K was originally in position IWORK( K ). This differs from IWORK for SLATM3. Not modified. SPARSE - REAL between 0. and 1. On entry specifies the sparsity of the matrix if sparse matix is to be generated. SPARSE should lie between 0 and 1. A uniform ( 0, 1 ) random number x is generated and compared to SPARSE; if x is larger the matrix entry is unchanged and if x is smaller the entry is set to zero. Thus on the average a fraction SPARSE of the entries will be set to zero. Not modified. ===================================================================== ----------------------------------------------------------------------- Check for I and J in range Parameter adjustments */ --iwork; --dr; --dl; --d__; --iseed; /* Function Body */ if (*i__ < 1 || *i__ > *m || *j < 1 || *j > *n) { ret_val = 0.f; return ret_val; } /* Check for banding */ if (*j > *i__ + *ku || *j < *i__ - *kl) { ret_val = 0.f; return ret_val; } /* Check for sparsity */ if (*sparse > 0.f) { if (slaran_(&iseed[1]) < *sparse) { ret_val = 0.f; return ret_val; } } /* Compute subscripts depending on IPVTNG */ if (*ipvtng == 0) { isub = *i__; jsub = *j; } else if (*ipvtng == 1) { isub = iwork[*i__]; jsub = *j; } else if (*ipvtng == 2) { isub = *i__; jsub = iwork[*j]; } else if (*ipvtng == 3) { isub = iwork[*i__]; jsub = iwork[*j]; } /* Compute entry and grade it according to IGRADE */ if (isub == jsub) { temp = d__[isub]; } else { temp = slarnd_(idist, &iseed[1]); } if (*igrade == 1) { temp *= dl[isub]; } else if (*igrade == 2) { temp *= dr[jsub]; } else if (*igrade == 3) { temp = temp * dl[isub] * dr[jsub]; } else if (*igrade == 4 && isub != jsub) { temp = temp * dl[isub] / dl[jsub]; } else if (*igrade == 5) { temp = temp * dl[isub] * dl[jsub]; } ret_val = temp; return ret_val; /* End of SLATM2 */ } /* slatm2_ */
/* Subroutine */ int schkbd_(integer *nsizes, integer *mval, integer *nval, integer *ntypes, logical *dotype, integer *nrhs, integer *iseed, real *thresh, real *a, integer *lda, real *bd, real *be, real *s1, real * s2, real *x, integer *ldx, real *y, real *z__, real *q, integer *ldq, real *pt, integer *ldpt, real *u, real *vt, real *work, integer * lwork, integer *iwork, integer *nout, integer *info) { /* Initialized data */ static integer ktype[16] = { 1,2,4,4,4,4,4,6,6,6,6,6,9,9,9,10 }; static integer kmagn[16] = { 1,1,1,1,1,2,3,1,1,1,2,3,1,2,3,0 }; static integer kmode[16] = { 0,0,4,3,1,4,4,4,3,1,4,4,0,0,0,0 }; /* Format strings */ static char fmt_9998[] = "(\002 SCHKBD: \002,a,\002 returned INFO=\002,i" "6,\002.\002,/9x,\002M=\002,i6,\002, N=\002,i6,\002, JTYPE=\002,i" "6,\002, ISEED=(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9999[] = "(\002 M=\002,i5,\002, N=\002,i5,\002, type " "\002,i2,\002, seed=\002,4(i4,\002,\002),\002 test(\002,i2,\002)" "=\002,g11.4)"; /* System generated locals */ integer a_dim1, a_offset, pt_dim1, pt_offset, q_dim1, q_offset, u_dim1, u_offset, vt_dim1, vt_offset, x_dim1, x_offset, y_dim1, y_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1, r__2, r__3, r__4, r__5, r__6, r__7; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); double log(doublereal), sqrt(doublereal), exp(doublereal); integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); /* Local variables */ integer i__, j, m, n, mq; real dum[1], ulp, cond; integer jcol; char path[3]; integer idum[1], mmax, nmax; real unfl, ovfl; char uplo[1]; real temp1, temp2; logical badmm, badnn; integer nfail, imode; extern /* Subroutine */ int sbdt01_(integer *, integer *, integer *, real *, integer *, real *, integer *, real *, real *, real *, integer * , real *, real *), sbdt02_(integer *, integer *, real *, integer * , real *, integer *, real *, integer *, real *, real *), sbdt03_( char *, integer *, integer *, real *, real *, real *, integer *, real *, real *, integer *, real *, real *); real dumma[1]; integer iinfo; extern /* Subroutine */ int sgemm_(char *, char *, integer *, integer *, integer *, real *, real *, integer *, real *, integer *, real *, real *, integer *); real anorm; integer mnmin, mnmax, jsize; extern /* Subroutine */ int sort01_(char *, integer *, integer *, real *, integer *, real *, integer *, real *); integer itype, jtype, ntest; extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, integer *), slahd2_(integer *, char *); integer log2ui; logical bidiag; extern /* Subroutine */ int slabad_(real *, real *), sbdsdc_(char *, char *, integer *, real *, real *, real *, integer *, real *, integer * , real *, integer *, real *, integer *, integer *) , sgebrd_(integer *, integer *, real *, integer *, real *, real *, real *, real *, real *, integer *, integer *); extern doublereal slamch_(char *); extern /* Subroutine */ int xerbla_(char *, integer *); integer ioldsd[4]; extern /* Subroutine */ int alasum_(char *, integer *, integer *, integer *, integer *); extern doublereal slarnd_(integer *, integer *); real amninv; extern /* Subroutine */ int slacpy_(char *, integer *, integer *, real *, integer *, real *, integer *), slaset_(char *, integer *, integer *, real *, real *, real *, integer *), sbdsqr_( char *, integer *, integer *, integer *, integer *, real *, real * , real *, integer *, real *, integer *, real *, integer *, real *, integer *), sorgbr_(char *, integer *, integer *, integer *, real *, integer *, real *, real *, integer *, integer * ), slatmr_(integer *, integer *, char *, integer *, char * , real *, integer *, real *, real *, char *, char *, real *, integer *, real *, real *, integer *, real *, char *, integer *, integer *, integer *, real *, real *, char *, real *, integer *, integer *, integer *), slatms_(integer *, integer *, char *, integer *, char *, real *, integer *, real *, real *, integer *, integer *, char *, real *, integer *, real *, integer *); integer minwrk; real rtunfl, rtovfl, ulpinv, result[19]; integer mtypes; /* Fortran I/O blocks */ static cilist io___39 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___40 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___42 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___43 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___44 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___45 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___51 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___52 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___53 = { 0, 0, 0, fmt_9999, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SCHKBD checks the singular value decomposition (SVD) routines. */ /* SGEBRD reduces a real general m by n matrix A to upper or lower */ /* bidiagonal form B by an orthogonal transformation: Q' * A * P = B */ /* (or A = Q * B * P'). The matrix B is upper bidiagonal if m >= n */ /* and lower bidiagonal if m < n. */ /* SORGBR generates the orthogonal matrices Q and P' from SGEBRD. */ /* Note that Q and P are not necessarily square. */ /* SBDSQR computes the singular value decomposition of the bidiagonal */ /* matrix B as B = U S V'. It is called three times to compute */ /* 1) B = U S1 V', where S1 is the diagonal matrix of singular */ /* values and the columns of the matrices U and V are the left */ /* and right singular vectors, respectively, of B. */ /* 2) Same as 1), but the singular values are stored in S2 and the */ /* singular vectors are not computed. */ /* 3) A = (UQ) S (P'V'), the SVD of the original matrix A. */ /* In addition, SBDSQR has an option to apply the left orthogonal matrix */ /* U to a matrix X, useful in least squares applications. */ /* SBDSDC computes the singular value decomposition of the bidiagonal */ /* matrix B as B = U S V' using divide-and-conquer. It is called twice */ /* to compute */ /* 1) B = U S1 V', where S1 is the diagonal matrix of singular */ /* values and the columns of the matrices U and V are the left */ /* and right singular vectors, respectively, of B. */ /* 2) Same as 1), but the singular values are stored in S2 and the */ /* singular vectors are not computed. */ /* For each pair of matrix dimensions (M,N) and each selected matrix */ /* type, an M by N matrix A and an M by NRHS matrix X are generated. */ /* The problem dimensions are as follows */ /* A: M x N */ /* Q: M x min(M,N) (but M x M if NRHS > 0) */ /* P: min(M,N) x N */ /* B: min(M,N) x min(M,N) */ /* U, V: min(M,N) x min(M,N) */ /* S1, S2 diagonal, order min(M,N) */ /* X: M x NRHS */ /* For each generated matrix, 14 tests are performed: */ /* Test SGEBRD and SORGBR */ /* (1) | A - Q B PT | / ( |A| max(M,N) ulp ), PT = P' */ /* (2) | I - Q' Q | / ( M ulp ) */ /* (3) | I - PT PT' | / ( N ulp ) */ /* Test SBDSQR on bidiagonal matrix B */ /* (4) | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V' */ /* (5) | Y - U Z | / ( |Y| max(min(M,N),k) ulp ), where Y = Q' X */ /* and Z = U' Y. */ /* (6) | I - U' U | / ( min(M,N) ulp ) */ /* (7) | I - VT VT' | / ( min(M,N) ulp ) */ /* (8) S1 contains min(M,N) nonnegative values in decreasing order. */ /* (Return 0 if true, 1/ULP if false.) */ /* (9) | S1 - S2 | / ( |S1| ulp ), where S2 is computed without */ /* computing U and V. */ /* (10) 0 if the true singular values of B are within THRESH of */ /* those in S1. 2*THRESH if they are not. (Tested using */ /* SSVDCH) */ /* Test SBDSQR on matrix A */ /* (11) | A - (QU) S (VT PT) | / ( |A| max(M,N) ulp ) */ /* (12) | X - (QU) Z | / ( |X| max(M,k) ulp ) */ /* (13) | I - (QU)'(QU) | / ( M ulp ) */ /* (14) | I - (VT PT) (PT'VT') | / ( N ulp ) */ /* Test SBDSDC on bidiagonal matrix B */ /* (15) | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V' */ /* (16) | I - U' U | / ( min(M,N) ulp ) */ /* (17) | I - VT VT' | / ( min(M,N) ulp ) */ /* (18) S1 contains min(M,N) nonnegative values in decreasing order. */ /* (Return 0 if true, 1/ULP if false.) */ /* (19) | S1 - S2 | / ( |S1| ulp ), where S2 is computed without */ /* computing U and V. */ /* The possible matrix types are */ /* (1) The zero matrix. */ /* (2) The identity matrix. */ /* (3) A diagonal matrix with evenly spaced entries */ /* 1, ..., ULP and random signs. */ /* (ULP = (first number larger than 1) - 1 ) */ /* (4) A diagonal matrix with geometrically spaced entries */ /* 1, ..., ULP and random signs. */ /* (5) A diagonal matrix with "clustered" entries 1, ULP, ..., ULP */ /* and random signs. */ /* (6) Same as (3), but multiplied by SQRT( overflow threshold ) */ /* (7) Same as (3), but multiplied by SQRT( underflow threshold ) */ /* (8) A matrix of the form U D V, where U and V are orthogonal and */ /* D has evenly spaced entries 1, ..., ULP with random signs */ /* on the diagonal. */ /* (9) A matrix of the form U D V, where U and V are orthogonal and */ /* D has geometrically spaced entries 1, ..., ULP with random */ /* signs on the diagonal. */ /* (10) A matrix of the form U D V, where U and V are orthogonal and */ /* D has "clustered" entries 1, ULP,..., ULP with random */ /* signs on the diagonal. */ /* (11) Same as (8), but multiplied by SQRT( overflow threshold ) */ /* (12) Same as (8), but multiplied by SQRT( underflow threshold ) */ /* (13) Rectangular matrix with random entries chosen from (-1,1). */ /* (14) Same as (13), but multiplied by SQRT( overflow threshold ) */ /* (15) Same as (13), but multiplied by SQRT( underflow threshold ) */ /* Special case: */ /* (16) A bidiagonal matrix with random entries chosen from a */ /* logarithmic distribution on [ulp^2,ulp^(-2)] (I.e., each */ /* entry is e^x, where x is chosen uniformly on */ /* [ 2 log(ulp), -2 log(ulp) ] .) For *this* type: */ /* (a) SGEBRD is not called to reduce it to bidiagonal form. */ /* (b) the bidiagonal is min(M,N) x min(M,N); if M<N, the */ /* matrix will be lower bidiagonal, otherwise upper. */ /* (c) only tests 5--8 and 14 are performed. */ /* A subset of the full set of matrix types may be selected through */ /* the logical array DOTYPE. */ /* Arguments */ /* ========== */ /* NSIZES (input) INTEGER */ /* The number of values of M and N contained in the vectors */ /* MVAL and NVAL. The matrix sizes are used in pairs (M,N). */ /* MVAL (input) INTEGER array, dimension (NM) */ /* The values of the matrix row dimension M. */ /* NVAL (input) INTEGER array, dimension (NM) */ /* The values of the matrix column dimension N. */ /* NTYPES (input) INTEGER */ /* The number of elements in DOTYPE. If it is zero, SCHKBD */ /* does nothing. It must be at least zero. If it is MAXTYP+1 */ /* and NSIZES is 1, then an additional type, MAXTYP+1 is */ /* defined, which is to use whatever matrices are in A and B. */ /* This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and */ /* DOTYPE(MAXTYP+1) is .TRUE. . */ /* DOTYPE (input) LOGICAL array, dimension (NTYPES) */ /* If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix */ /* of type j will be generated. If NTYPES is smaller than the */ /* maximum number of types defined (PARAMETER MAXTYP), then */ /* types NTYPES+1 through MAXTYP will not be generated. If */ /* NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through */ /* DOTYPE(NTYPES) will be ignored. */ /* NRHS (input) INTEGER */ /* The number of columns in the "right-hand side" matrices X, Y, */ /* and Z, used in testing SBDSQR. If NRHS = 0, then the */ /* operations on the right-hand side will not be tested. */ /* NRHS must be at least 0. */ /* ISEED (input/output) INTEGER array, dimension (4) */ /* On entry ISEED specifies the seed of the random number */ /* generator. The array elements should be between 0 and 4095; */ /* if not they will be reduced mod 4096. Also, ISEED(4) must */ /* be odd. The values of ISEED are changed on exit, and can be */ /* used in the next call to SCHKBD to continue the same random */ /* number sequence. */ /* THRESH (input) REAL */ /* The threshold value for the test ratios. A result is */ /* included in the output file if RESULT >= THRESH. To have */ /* every test ratio printed, use THRESH = 0. Note that the */ /* expected value of the test ratios is O(1), so THRESH should */ /* be a reasonably small multiple of 1, e.g., 10 or 100. */ /* A (workspace) REAL array, dimension (LDA,NMAX) */ /* where NMAX is the maximum value of N in NVAL. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,MMAX), */ /* where MMAX is the maximum value of M in MVAL. */ /* BD (workspace) REAL array, dimension */ /* (max(min(MVAL(j),NVAL(j)))) */ /* BE (workspace) REAL array, dimension */ /* (max(min(MVAL(j),NVAL(j)))) */ /* S1 (workspace) REAL array, dimension */ /* (max(min(MVAL(j),NVAL(j)))) */ /* S2 (workspace) REAL array, dimension */ /* (max(min(MVAL(j),NVAL(j)))) */ /* X (workspace) REAL array, dimension (LDX,NRHS) */ /* LDX (input) INTEGER */ /* The leading dimension of the arrays X, Y, and Z. */ /* LDX >= max(1,MMAX) */ /* Y (workspace) REAL array, dimension (LDX,NRHS) */ /* Z (workspace) REAL array, dimension (LDX,NRHS) */ /* Q (workspace) REAL array, dimension (LDQ,MMAX) */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. LDQ >= max(1,MMAX). */ /* PT (workspace) REAL array, dimension (LDPT,NMAX) */ /* LDPT (input) INTEGER */ /* The leading dimension of the arrays PT, U, and V. */ /* LDPT >= max(1, max(min(MVAL(j),NVAL(j)))). */ /* U (workspace) REAL array, dimension */ /* (LDPT,max(min(MVAL(j),NVAL(j)))) */ /* V (workspace) REAL array, dimension */ /* (LDPT,max(min(MVAL(j),NVAL(j)))) */ /* WORK (workspace) REAL array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* The number of entries in WORK. This must be at least */ /* 3(M+N) and M(M + max(M,N,k) + 1) + N*min(M,N) for all */ /* pairs (M,N)=(MM(j),NN(j)) */ /* IWORK (workspace) INTEGER array, dimension at least 8*min(M,N) */ /* NOUT (input) INTEGER */ /* The FORTRAN unit number for printing out error messages */ /* (e.g., if a routine returns IINFO not equal to 0.) */ /* INFO (output) INTEGER */ /* If 0, then everything ran OK. */ /* -1: NSIZES < 0 */ /* -2: Some MM(j) < 0 */ /* -3: Some NN(j) < 0 */ /* -4: NTYPES < 0 */ /* -6: NRHS < 0 */ /* -8: THRESH < 0 */ /* -11: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ). */ /* -17: LDB < 1 or LDB < MMAX. */ /* -21: LDQ < 1 or LDQ < MMAX. */ /* -23: LDPT< 1 or LDPT< MNMAX. */ /* -27: LWORK too small. */ /* If SLATMR, SLATMS, SGEBRD, SORGBR, or SBDSQR, */ /* returns an error code, the */ /* absolute value of it is returned. */ /* ----------------------------------------------------------------------- */ /* Some Local Variables and Parameters: */ /* ---- ----- --------- --- ---------- */ /* ZERO, ONE Real 0 and 1. */ /* MAXTYP The number of types defined. */ /* NTEST The number of tests performed, or which can */ /* be performed so far, for the current matrix. */ /* MMAX Largest value in NN. */ /* NMAX Largest value in NN. */ /* MNMIN min(MM(j), NN(j)) (the dimension of the bidiagonal */ /* matrix.) */ /* MNMAX The maximum value of MNMIN for j=1,...,NSIZES. */ /* NFAIL The number of tests which have exceeded THRESH */ /* COND, IMODE Values to be passed to the matrix generators. */ /* ANORM Norm of A; passed to matrix generators. */ /* OVFL, UNFL Overflow and underflow thresholds. */ /* RTOVFL, RTUNFL Square roots of the previous 2 values. */ /* ULP, ULPINV Finest relative precision and its inverse. */ /* The following four arrays decode JTYPE: */ /* KTYPE(j) The general type (1-10) for type "j". */ /* KMODE(j) The MODE value to be passed to the matrix */ /* generator for type "j". */ /* KMAGN(j) The order of magnitude ( O(1), */ /* O(overflow^(1/2) ), O(underflow^(1/2) ) */ /* ====================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --mval; --nval; --dotype; --iseed; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --bd; --be; --s1; --s2; z_dim1 = *ldx; z_offset = 1 + z_dim1; z__ -= z_offset; y_dim1 = *ldx; y_offset = 1 + y_dim1; y -= y_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; vt_dim1 = *ldpt; vt_offset = 1 + vt_dim1; vt -= vt_offset; u_dim1 = *ldpt; u_offset = 1 + u_dim1; u -= u_offset; pt_dim1 = *ldpt; pt_offset = 1 + pt_dim1; pt -= pt_offset; --work; --iwork; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Check for errors */ *info = 0; badmm = FALSE_; badnn = FALSE_; mmax = 1; nmax = 1; mnmax = 1; minwrk = 1; i__1 = *nsizes; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = mmax, i__3 = mval[j]; mmax = max(i__2,i__3); if (mval[j] < 0) { badmm = TRUE_; } /* Computing MAX */ i__2 = nmax, i__3 = nval[j]; nmax = max(i__2,i__3); if (nval[j] < 0) { badnn = TRUE_; } /* Computing MAX */ /* Computing MIN */ i__4 = mval[j], i__5 = nval[j]; i__2 = mnmax, i__3 = min(i__4,i__5); mnmax = max(i__2,i__3); /* Computing MAX */ /* Computing MAX */ i__4 = mval[j], i__5 = nval[j], i__4 = max(i__4,i__5); /* Computing MIN */ i__6 = nval[j], i__7 = mval[j]; i__2 = minwrk, i__3 = (mval[j] + nval[j]) * 3, i__2 = max(i__2,i__3), i__3 = mval[j] * (mval[j] + max(i__4,*nrhs) + 1) + nval[j] * min(i__6,i__7); minwrk = max(i__2,i__3); /* L10: */ } /* Check for errors */ if (*nsizes < 0) { *info = -1; } else if (badmm) { *info = -2; } else if (badnn) { *info = -3; } else if (*ntypes < 0) { *info = -4; } else if (*nrhs < 0) { *info = -6; } else if (*lda < mmax) { *info = -11; } else if (*ldx < mmax) { *info = -17; } else if (*ldq < mmax) { *info = -21; } else if (*ldpt < mnmax) { *info = -23; } else if (minwrk > *lwork) { *info = -27; } if (*info != 0) { i__1 = -(*info); xerbla_("SCHKBD", &i__1); return 0; } /* Initialize constants */ s_copy(path, "Single precision", (ftnlen)1, (ftnlen)16); s_copy(path + 1, "BD", (ftnlen)2, (ftnlen)2); nfail = 0; ntest = 0; unfl = slamch_("Safe minimum"); ovfl = slamch_("Overflow"); slabad_(&unfl, &ovfl); ulp = slamch_("Precision"); ulpinv = 1.f / ulp; log2ui = (integer) (log(ulpinv) / log(2.f)); rtunfl = sqrt(unfl); rtovfl = sqrt(ovfl); infoc_1.infot = 0; /* Loop over sizes, types */ i__1 = *nsizes; for (jsize = 1; jsize <= i__1; ++jsize) { m = mval[jsize]; n = nval[jsize]; mnmin = min(m,n); /* Computing MAX */ i__2 = max(m,n); amninv = 1.f / max(i__2,1); if (*nsizes != 1) { mtypes = min(16,*ntypes); } else { mtypes = min(17,*ntypes); } i__2 = mtypes; for (jtype = 1; jtype <= i__2; ++jtype) { if (! dotype[jtype]) { goto L190; } for (j = 1; j <= 4; ++j) { ioldsd[j - 1] = iseed[j]; /* L20: */ } for (j = 1; j <= 14; ++j) { result[j - 1] = -1.f; /* L30: */ } *(unsigned char *)uplo = ' '; /* Compute "A" */ /* Control parameters: */ /* KMAGN KMODE KTYPE */ /* =1 O(1) clustered 1 zero */ /* =2 large clustered 2 identity */ /* =3 small exponential (none) */ /* =4 arithmetic diagonal, (w/ eigenvalues) */ /* =5 random symmetric, w/ eigenvalues */ /* =6 nonsymmetric, w/ singular values */ /* =7 random diagonal */ /* =8 random symmetric */ /* =9 random nonsymmetric */ /* =10 random bidiagonal (log. distrib.) */ if (mtypes > 16) { goto L100; } itype = ktype[jtype - 1]; imode = kmode[jtype - 1]; /* Compute norm */ switch (kmagn[jtype - 1]) { case 1: goto L40; case 2: goto L50; case 3: goto L60; } L40: anorm = 1.f; goto L70; L50: anorm = rtovfl * ulp * amninv; goto L70; L60: anorm = rtunfl * max(m,n) * ulpinv; goto L70; L70: slaset_("Full", lda, &n, &c_b20, &c_b20, &a[a_offset], lda); iinfo = 0; cond = ulpinv; bidiag = FALSE_; if (itype == 1) { /* Zero matrix */ iinfo = 0; } else if (itype == 2) { /* Identity */ i__3 = mnmin; for (jcol = 1; jcol <= i__3; ++jcol) { a[jcol + jcol * a_dim1] = anorm; /* L80: */ } } else if (itype == 4) { /* Diagonal Matrix, [Eigen]values Specified */ slatms_(&mnmin, &mnmin, "S", &iseed[1], "N", &work[1], &imode, &cond, &anorm, &c__0, &c__0, "N", &a[a_offset], lda, &work[mnmin + 1], &iinfo); } else if (itype == 5) { /* Symmetric, eigenvalues specified */ slatms_(&mnmin, &mnmin, "S", &iseed[1], "S", &work[1], &imode, &cond, &anorm, &m, &n, "N", &a[a_offset], lda, &work[ mnmin + 1], &iinfo); } else if (itype == 6) { /* Nonsymmetric, singular values specified */ slatms_(&m, &n, "S", &iseed[1], "N", &work[1], &imode, &cond, &anorm, &m, &n, "N", &a[a_offset], lda, &work[mnmin + 1], &iinfo); } else if (itype == 7) { /* Diagonal, random entries */ slatmr_(&mnmin, &mnmin, "S", &iseed[1], "N", &work[1], &c__6, &c_b37, &c_b37, "T", "N", &work[mnmin + 1], &c__1, & c_b37, &work[(mnmin << 1) + 1], &c__1, &c_b37, "N", & iwork[1], &c__0, &c__0, &c_b20, &anorm, "NO", &a[ a_offset], lda, &iwork[1], &iinfo); } else if (itype == 8) { /* Symmetric, random entries */ slatmr_(&mnmin, &mnmin, "S", &iseed[1], "S", &work[1], &c__6, &c_b37, &c_b37, "T", "N", &work[mnmin + 1], &c__1, & c_b37, &work[m + mnmin + 1], &c__1, &c_b37, "N", & iwork[1], &m, &n, &c_b20, &anorm, "NO", &a[a_offset], lda, &iwork[1], &iinfo); } else if (itype == 9) { /* Nonsymmetric, random entries */ slatmr_(&m, &n, "S", &iseed[1], "N", &work[1], &c__6, &c_b37, &c_b37, "T", "N", &work[mnmin + 1], &c__1, &c_b37, & work[m + mnmin + 1], &c__1, &c_b37, "N", &iwork[1], & m, &n, &c_b20, &anorm, "NO", &a[a_offset], lda, & iwork[1], &iinfo); } else if (itype == 10) { /* Bidiagonal, random entries */ temp1 = log(ulp) * -2.f; i__3 = mnmin; for (j = 1; j <= i__3; ++j) { bd[j] = exp(temp1 * slarnd_(&c__2, &iseed[1])); if (j < mnmin) { be[j] = exp(temp1 * slarnd_(&c__2, &iseed[1])); } /* L90: */ } iinfo = 0; bidiag = TRUE_; if (m >= n) { *(unsigned char *)uplo = 'U'; } else { *(unsigned char *)uplo = 'L'; } } else { iinfo = 1; } if (iinfo == 0) { /* Generate Right-Hand Side */ if (bidiag) { slatmr_(&mnmin, nrhs, "S", &iseed[1], "N", &work[1], & c__6, &c_b37, &c_b37, "T", "N", &work[mnmin + 1], &c__1, &c_b37, &work[(mnmin << 1) + 1], &c__1, & c_b37, "N", &iwork[1], &mnmin, nrhs, &c_b20, & c_b37, "NO", &y[y_offset], ldx, &iwork[1], &iinfo); } else { slatmr_(&m, nrhs, "S", &iseed[1], "N", &work[1], &c__6, & c_b37, &c_b37, "T", "N", &work[m + 1], &c__1, & c_b37, &work[(m << 1) + 1], &c__1, &c_b37, "N", & iwork[1], &m, nrhs, &c_b20, &c_b37, "NO", &x[ x_offset], ldx, &iwork[1], &iinfo); } } /* Error Exit */ if (iinfo != 0) { io___39.ciunit = *nout; s_wsfe(&io___39); do_fio(&c__1, "Generator", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); return 0; } L100: /* Call SGEBRD and SORGBR to compute B, Q, and P, do tests. */ if (! bidiag) { /* Compute transformations to reduce A to bidiagonal form: */ /* B := Q' * A * P. */ slacpy_(" ", &m, &n, &a[a_offset], lda, &q[q_offset], ldq); i__3 = *lwork - (mnmin << 1); sgebrd_(&m, &n, &q[q_offset], ldq, &bd[1], &be[1], &work[1], & work[mnmin + 1], &work[(mnmin << 1) + 1], &i__3, & iinfo); /* Check error code from SGEBRD. */ if (iinfo != 0) { io___40.ciunit = *nout; s_wsfe(&io___40); do_fio(&c__1, "SGEBRD", (ftnlen)6); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } slacpy_(" ", &m, &n, &q[q_offset], ldq, &pt[pt_offset], ldpt); if (m >= n) { *(unsigned char *)uplo = 'U'; } else { *(unsigned char *)uplo = 'L'; } /* Generate Q */ mq = m; if (*nrhs <= 0) { mq = mnmin; } i__3 = *lwork - (mnmin << 1); sorgbr_("Q", &m, &mq, &n, &q[q_offset], ldq, &work[1], &work[( mnmin << 1) + 1], &i__3, &iinfo); /* Check error code from SORGBR. */ if (iinfo != 0) { io___42.ciunit = *nout; s_wsfe(&io___42); do_fio(&c__1, "SORGBR(Q)", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } /* Generate P' */ i__3 = *lwork - (mnmin << 1); sorgbr_("P", &mnmin, &n, &m, &pt[pt_offset], ldpt, &work[ mnmin + 1], &work[(mnmin << 1) + 1], &i__3, &iinfo); /* Check error code from SORGBR. */ if (iinfo != 0) { io___43.ciunit = *nout; s_wsfe(&io___43); do_fio(&c__1, "SORGBR(P)", (ftnlen)9); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; e_wsfe(); *info = abs(iinfo); return 0; } /* Apply Q' to an M by NRHS matrix X: Y := Q' * X. */ sgemm_("Transpose", "No transpose", &m, nrhs, &m, &c_b37, &q[ q_offset], ldq, &x[x_offset], ldx, &c_b20, &y[ y_offset], ldx); /* Test 1: Check the decomposition A := Q * B * PT */ /* 2: Check the orthogonality of Q */ /* 3: Check the orthogonality of PT */ sbdt01_(&m, &n, &c__1, &a[a_offset], lda, &q[q_offset], ldq, & bd[1], &be[1], &pt[pt_offset], ldpt, &work[1], result) ; sort01_("Columns", &m, &mq, &q[q_offset], ldq, &work[1], lwork, &result[1]); sort01_("Rows", &mnmin, &n, &pt[pt_offset], ldpt, &work[1], lwork, &result[2]); } /* Use SBDSQR to form the SVD of the bidiagonal matrix B: */ /* B := U * S1 * VT, and compute Z = U' * Y. */ scopy_(&mnmin, &bd[1], &c__1, &s1[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &work[1], &c__1); } slacpy_(" ", &m, nrhs, &y[y_offset], ldx, &z__[z_offset], ldx); slaset_("Full", &mnmin, &mnmin, &c_b20, &c_b37, &u[u_offset], ldpt); slaset_("Full", &mnmin, &mnmin, &c_b20, &c_b37, &vt[vt_offset], ldpt); sbdsqr_(uplo, &mnmin, &mnmin, &mnmin, nrhs, &s1[1], &work[1], &vt[ vt_offset], ldpt, &u[u_offset], ldpt, &z__[z_offset], ldx, &work[mnmin + 1], &iinfo); /* Check error code from SBDSQR. */ if (iinfo != 0) { io___44.ciunit = *nout; s_wsfe(&io___44); do_fio(&c__1, "SBDSQR(vects)", (ftnlen)13); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[3] = ulpinv; goto L170; } } /* Use SBDSQR to compute only the singular values of the */ /* bidiagonal matrix B; U, VT, and Z should not be modified. */ scopy_(&mnmin, &bd[1], &c__1, &s2[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &work[1], &c__1); } sbdsqr_(uplo, &mnmin, &c__0, &c__0, &c__0, &s2[1], &work[1], &vt[ vt_offset], ldpt, &u[u_offset], ldpt, &z__[z_offset], ldx, &work[mnmin + 1], &iinfo); /* Check error code from SBDSQR. */ if (iinfo != 0) { io___45.ciunit = *nout; s_wsfe(&io___45); do_fio(&c__1, "SBDSQR(values)", (ftnlen)14); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[8] = ulpinv; goto L170; } } /* Test 4: Check the decomposition B := U * S1 * VT */ /* 5: Check the computation Z := U' * Y */ /* 6: Check the orthogonality of U */ /* 7: Check the orthogonality of VT */ sbdt03_(uplo, &mnmin, &c__1, &bd[1], &be[1], &u[u_offset], ldpt, & s1[1], &vt[vt_offset], ldpt, &work[1], &result[3]); sbdt02_(&mnmin, nrhs, &y[y_offset], ldx, &z__[z_offset], ldx, &u[ u_offset], ldpt, &work[1], &result[4]); sort01_("Columns", &mnmin, &mnmin, &u[u_offset], ldpt, &work[1], lwork, &result[5]); sort01_("Rows", &mnmin, &mnmin, &vt[vt_offset], ldpt, &work[1], lwork, &result[6]); /* Test 8: Check that the singular values are sorted in */ /* non-increasing order and are non-negative */ result[7] = 0.f; i__3 = mnmin - 1; for (i__ = 1; i__ <= i__3; ++i__) { if (s1[i__] < s1[i__ + 1]) { result[7] = ulpinv; } if (s1[i__] < 0.f) { result[7] = ulpinv; } /* L110: */ } if (mnmin >= 1) { if (s1[mnmin] < 0.f) { result[7] = ulpinv; } } /* Test 9: Compare SBDSQR with and without singular vectors */ temp2 = 0.f; i__3 = mnmin; for (j = 1; j <= i__3; ++j) { /* Computing MAX */ /* Computing MAX */ r__6 = (r__1 = s1[j], dabs(r__1)), r__7 = (r__2 = s2[j], dabs( r__2)); r__4 = sqrt(unfl) * dmax(s1[1],1.f), r__5 = ulp * dmax(r__6, r__7); temp1 = (r__3 = s1[j] - s2[j], dabs(r__3)) / dmax(r__4,r__5); temp2 = dmax(temp1,temp2); /* L120: */ } result[8] = temp2; /* Test 10: Sturm sequence test of singular values */ /* Go up by factors of two until it succeeds */ temp1 = *thresh * (.5f - ulp); i__3 = log2ui; for (j = 0; j <= i__3; ++j) { /* CALL SSVDCH( MNMIN, BD, BE, S1, TEMP1, IINFO ) */ if (iinfo == 0) { goto L140; } temp1 *= 2.f; /* L130: */ } L140: result[9] = temp1; /* Use SBDSQR to form the decomposition A := (QU) S (VT PT) */ /* from the bidiagonal form A := Q B PT. */ if (! bidiag) { scopy_(&mnmin, &bd[1], &c__1, &s2[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &work[1], &c__1); } sbdsqr_(uplo, &mnmin, &n, &m, nrhs, &s2[1], &work[1], &pt[ pt_offset], ldpt, &q[q_offset], ldq, &y[y_offset], ldx, &work[mnmin + 1], &iinfo); /* Test 11: Check the decomposition A := Q*U * S2 * VT*PT */ /* 12: Check the computation Z := U' * Q' * X */ /* 13: Check the orthogonality of Q*U */ /* 14: Check the orthogonality of VT*PT */ sbdt01_(&m, &n, &c__0, &a[a_offset], lda, &q[q_offset], ldq, & s2[1], dumma, &pt[pt_offset], ldpt, &work[1], &result[ 10]); sbdt02_(&m, nrhs, &x[x_offset], ldx, &y[y_offset], ldx, &q[ q_offset], ldq, &work[1], &result[11]); sort01_("Columns", &m, &mq, &q[q_offset], ldq, &work[1], lwork, &result[12]); sort01_("Rows", &mnmin, &n, &pt[pt_offset], ldpt, &work[1], lwork, &result[13]); } /* Use SBDSDC to form the SVD of the bidiagonal matrix B: */ /* B := U * S1 * VT */ scopy_(&mnmin, &bd[1], &c__1, &s1[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &work[1], &c__1); } slaset_("Full", &mnmin, &mnmin, &c_b20, &c_b37, &u[u_offset], ldpt); slaset_("Full", &mnmin, &mnmin, &c_b20, &c_b37, &vt[vt_offset], ldpt); sbdsdc_(uplo, "I", &mnmin, &s1[1], &work[1], &u[u_offset], ldpt, & vt[vt_offset], ldpt, dum, idum, &work[mnmin + 1], &iwork[ 1], &iinfo); /* Check error code from SBDSDC. */ if (iinfo != 0) { io___51.ciunit = *nout; s_wsfe(&io___51); do_fio(&c__1, "SBDSDC(vects)", (ftnlen)13); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[14] = ulpinv; goto L170; } } /* Use SBDSDC to compute only the singular values of the */ /* bidiagonal matrix B; U and VT should not be modified. */ scopy_(&mnmin, &bd[1], &c__1, &s2[1], &c__1); if (mnmin > 0) { i__3 = mnmin - 1; scopy_(&i__3, &be[1], &c__1, &work[1], &c__1); } sbdsdc_(uplo, "N", &mnmin, &s2[1], &work[1], dum, &c__1, dum, & c__1, dum, idum, &work[mnmin + 1], &iwork[1], &iinfo); /* Check error code from SBDSDC. */ if (iinfo != 0) { io___52.ciunit = *nout; s_wsfe(&io___52); do_fio(&c__1, "SBDSDC(values)", (ftnlen)14); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); if (iinfo < 0) { return 0; } else { result[17] = ulpinv; goto L170; } } /* Test 15: Check the decomposition B := U * S1 * VT */ /* 16: Check the orthogonality of U */ /* 17: Check the orthogonality of VT */ sbdt03_(uplo, &mnmin, &c__1, &bd[1], &be[1], &u[u_offset], ldpt, & s1[1], &vt[vt_offset], ldpt, &work[1], &result[14]); sort01_("Columns", &mnmin, &mnmin, &u[u_offset], ldpt, &work[1], lwork, &result[15]); sort01_("Rows", &mnmin, &mnmin, &vt[vt_offset], ldpt, &work[1], lwork, &result[16]); /* Test 18: Check that the singular values are sorted in */ /* non-increasing order and are non-negative */ result[17] = 0.f; i__3 = mnmin - 1; for (i__ = 1; i__ <= i__3; ++i__) { if (s1[i__] < s1[i__ + 1]) { result[17] = ulpinv; } if (s1[i__] < 0.f) { result[17] = ulpinv; } /* L150: */ } if (mnmin >= 1) { if (s1[mnmin] < 0.f) { result[17] = ulpinv; } } /* Test 19: Compare SBDSQR with and without singular vectors */ temp2 = 0.f; i__3 = mnmin; for (j = 1; j <= i__3; ++j) { /* Computing MAX */ /* Computing MAX */ r__4 = dabs(s1[1]), r__5 = dabs(s2[1]); r__2 = sqrt(unfl) * dmax(s1[1],1.f), r__3 = ulp * dmax(r__4, r__5); temp1 = (r__1 = s1[j] - s2[j], dabs(r__1)) / dmax(r__2,r__3); temp2 = dmax(temp1,temp2); /* L160: */ } result[18] = temp2; /* End of Loop -- Check for RESULT(j) > THRESH */ L170: for (j = 1; j <= 19; ++j) { if (result[j - 1] >= *thresh) { if (nfail == 0) { slahd2_(nout, path); } io___53.ciunit = *nout; s_wsfe(&io___53); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)) ; do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[j - 1], (ftnlen)sizeof(real) ); e_wsfe(); ++nfail; } /* L180: */ } if (! bidiag) { ntest += 19; } else { ntest += 5; } L190: ; } /* L200: */ } /* Summary */ alasum_(path, nout, &nfail, &ntest, &c__0); return 0; /* End of SCHKBD */ } /* schkbd_ */
/* Subroutine */ int sckglm_(integer *nn, integer *mval, integer *pval, integer *nval, integer *nmats, integer *iseed, real *thresh, integer * nmax, real *a, real *af, real *b, real *bf, real *x, real *work, real *rwork, integer *nin, integer *nout, integer *info) { /* Format strings */ static char fmt_9997[] = "(\002 *** Invalid input for GLM: M = \002," "i6,\002, P = \002,i6,\002, N = \002,i6,\002;\002,/\002 must " "satisfy M <= N <= M+P \002,\002(this set of values will be skip" "ped)\002)"; static char fmt_9999[] = "(\002 SLATMS in SCKGLM INFO = \002,i5)"; static char fmt_9998[] = "(\002 N=\002,i4,\002 M=\002,i4,\002, P=\002," "i4,\002, type \002,i2,\002, test \002,i2,\002, ratio=\002,g13.6)"; /* System generated locals */ integer i__1, i__2; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); integer s_wsle(cilist *), e_wsle(void), s_wsfe(cilist *), do_fio(integer * , char *, ftnlen), e_wsfe(void); /* Local variables */ integer i__, m, n, p, ik, lda, ldb, kla, klb, kua, kub, imat; char path[3], type__[1]; integer nrun, modea, modeb, nfail; char dista[1], distb[1]; integer iinfo; real resid, anorm, bnorm; integer lwork; extern /* Subroutine */ int slatb9_(char *, integer *, integer *, integer *, integer *, char *, integer *, integer *, integer *, integer *, real *, real *, integer *, integer *, real *, real *, char *, char *), alahdg_(integer *, char * ); real cndnma, cndnmb; extern /* Subroutine */ int alareq_(char *, integer *, logical *, integer *, integer *, integer *), alasum_(char *, integer *, integer *, integer *, integer *); extern doublereal slarnd_(integer *, integer *); extern /* Subroutine */ int slatms_(integer *, integer *, char *, integer *, char *, real *, integer *, real *, real *, integer *, integer * , char *, real *, integer *, real *, integer *); logical dotype[8]; extern /* Subroutine */ int sglmts_(integer *, integer *, integer *, real *, real *, integer *, real *, real *, integer *, real *, real *, real *, real *, real *, integer *, real *, real *); logical firstt; /* Fortran I/O blocks */ static cilist io___13 = { 0, 0, 0, 0, 0 }; static cilist io___14 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___30 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___31 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___34 = { 0, 0, 0, fmt_9998, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SCKGLM tests SGGGLM - subroutine for solving generalized linear */ /* model problem. */ /* Arguments */ /* ========= */ /* NN (input) INTEGER */ /* The number of values of N, M and P contained in the vectors */ /* NVAL, MVAL and PVAL. */ /* MVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix column dimension M. */ /* PVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix column dimension P. */ /* NVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix row dimension N. */ /* NMATS (input) INTEGER */ /* The number of matrix types to be tested for each combination */ /* of matrix dimensions. If NMATS >= NTYPES (the maximum */ /* number of matrix types), then all the different types are */ /* generated for testing. If NMATS < NTYPES, another input line */ /* is read to get the numbers of the matrix types to be used. */ /* ISEED (input/output) INTEGER array, dimension (4) */ /* On entry, the seed of the random number generator. The array */ /* elements should be between 0 and 4095, otherwise they will be */ /* reduced mod 4096, and ISEED(4) must be odd. */ /* On exit, the next seed in the random number sequence after */ /* all the test matrices have been generated. */ /* THRESH (input) REAL */ /* The threshold value for the test ratios. A result is */ /* included in the output file if RESID >= THRESH. To have */ /* every test ratio printed, use THRESH = 0. */ /* NMAX (input) INTEGER */ /* The maximum value permitted for M or N, used in dimensioning */ /* the work arrays. */ /* A (workspace) REAL array, dimension (NMAX*NMAX) */ /* AF (workspace) REAL array, dimension (NMAX*NMAX) */ /* B (workspace) REAL array, dimension (NMAX*NMAX) */ /* BF (workspace) REAL array, dimension (NMAX*NMAX) */ /* X (workspace) REAL array, dimension (4*NMAX) */ /* RWORK (workspace) REAL array, dimension (NMAX) */ /* WORK (workspace) REAL array, dimension (NMAX*NMAX) */ /* NIN (input) INTEGER */ /* The unit number for input. */ /* NOUT (input) INTEGER */ /* The unit number for output. */ /* INFO (output) INTEGER */ /* = 0 : successful exit */ /* > 0 : If SLATMS returns an error code, the absolute value */ /* of it is returned. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Initialize constants. */ /* Parameter adjustments */ --rwork; --work; --x; --bf; --b; --af; --a; --iseed; --nval; --pval; --mval; /* Function Body */ s_copy(path, "GLM", (ftnlen)3, (ftnlen)3); *info = 0; nrun = 0; nfail = 0; firstt = TRUE_; alareq_(path, nmats, dotype, &c__8, nin, nout); lda = *nmax; ldb = *nmax; lwork = *nmax * *nmax; /* Check for valid input values. */ i__1 = *nn; for (ik = 1; ik <= i__1; ++ik) { m = mval[ik]; p = pval[ik]; n = nval[ik]; if (m > n || n > m + p) { if (firstt) { io___13.ciunit = *nout; s_wsle(&io___13); e_wsle(); firstt = FALSE_; } io___14.ciunit = *nout; s_wsfe(&io___14); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&p, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); e_wsfe(); } /* L10: */ } firstt = TRUE_; /* Do for each value of M in MVAL. */ i__1 = *nn; for (ik = 1; ik <= i__1; ++ik) { m = mval[ik]; p = pval[ik]; n = nval[ik]; if (m > n || n > m + p) { goto L40; } for (imat = 1; imat <= 8; ++imat) { /* Do the tests only if DOTYPE( IMAT ) is true. */ if (! dotype[imat - 1]) { goto L30; } /* Set up parameters with SLATB9 and generate test */ /* matrices A and B with SLATMS. */ slatb9_(path, &imat, &m, &p, &n, type__, &kla, &kua, &klb, &kub, & anorm, &bnorm, &modea, &modeb, &cndnma, &cndnmb, dista, distb); slatms_(&n, &m, dista, &iseed[1], type__, &rwork[1], &modea, & cndnma, &anorm, &kla, &kua, "No packing", &a[1], &lda, & work[1], &iinfo); if (iinfo != 0) { io___30.ciunit = *nout; s_wsfe(&io___30); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); goto L30; } slatms_(&n, &p, distb, &iseed[1], type__, &rwork[1], &modeb, & cndnmb, &bnorm, &klb, &kub, "No packing", &b[1], &ldb, & work[1], &iinfo); if (iinfo != 0) { io___31.ciunit = *nout; s_wsfe(&io___31); do_fio(&c__1, (char *)&iinfo, (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(iinfo); goto L30; } /* Generate random left hand side vector of GLM */ i__2 = n; for (i__ = 1; i__ <= i__2; ++i__) { x[i__] = slarnd_(&c__2, &iseed[1]); /* L20: */ } sglmts_(&n, &m, &p, &a[1], &af[1], &lda, &b[1], &bf[1], &ldb, &x[ 1], &x[*nmax + 1], &x[(*nmax << 1) + 1], &x[*nmax * 3 + 1] , &work[1], &lwork, &rwork[1], &resid); /* Print information about the tests that did not */ /* pass the threshold. */ if (resid >= *thresh) { if (nfail == 0 && firstt) { firstt = FALSE_; alahdg_(nout, path); } io___34.ciunit = *nout; s_wsfe(&io___34); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&m, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&p, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&imat, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&c__1, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&resid, (ftnlen)sizeof(real)); e_wsfe(); ++nfail; } ++nrun; L30: ; } L40: ; } /* Print a summary of the results. */ alasum_(path, nout, &nfail, &nrun, &c__0); return 0; /* End of SCKGLM */ } /* sckglm_ */
/* Subroutine */ int slattp_(integer *imat, char *uplo, char *trans, char * diag, integer *iseed, integer *n, real *a, real *b, real *work, integer *info) { /* System generated locals */ integer i__1, i__2; real r__1, r__2; doublereal d__1, d__2; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); double pow_dd(doublereal *, doublereal *), sqrt(doublereal), r_sign(real * , real *); /* Local variables */ real c__; integer i__, j; real s, t, x, y, z__; integer jc; real ra; integer jj; real rb; integer jl, kl, jr, ku, iy, jx; real ulp, sfac; integer mode; char path[3], dist[1]; real unfl, rexp; char type__[1]; real texp; extern /* Subroutine */ int srot_(integer *, real *, integer *, real *, integer *, real *, real *); real star1, plus1, plus2, bscal; extern logical lsame_(char *, char *); extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *); real tscal, anorm, bnorm, tleft, stemp; logical upper; extern /* Subroutine */ int srotg_(real *, real *, real *, real *), slatb4_(char *, integer *, integer *, integer *, char *, integer * , integer *, real *, integer *, real *, char *), slabad_(real *, real *); extern doublereal slamch_(char *); char packit[1]; real bignum; extern integer isamax_(integer *, real *, integer *); extern doublereal slarnd_(integer *, integer *); real cndnum; integer jcnext, jcount; extern /* Subroutine */ int slatms_(integer *, integer *, char *, integer *, char *, real *, integer *, real *, real *, integer *, integer * , char *, real *, integer *, real *, integer *), slarnv_(integer *, integer *, integer *, real *); real smlnum; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* SLATTP generates a triangular test matrix in packed storage. */ /* IMAT and UPLO uniquely specify the properties of the test */ /* matrix, which is returned in the array AP. */ /* Arguments */ /* ========= */ /* IMAT (input) INTEGER */ /* An integer key describing which matrix to generate for this */ /* path. */ /* UPLO (input) CHARACTER*1 */ /* Specifies whether the matrix A will be upper or lower */ /* triangular. */ /* = 'U': Upper triangular */ /* = 'L': Lower triangular */ /* TRANS (input) CHARACTER*1 */ /* Specifies whether the matrix or its transpose will be used. */ /* = 'N': No transpose */ /* = 'T': Transpose */ /* = 'C': Conjugate transpose (= Transpose) */ /* DIAG (output) CHARACTER*1 */ /* Specifies whether or not the matrix A is unit triangular. */ /* = 'N': Non-unit triangular */ /* = 'U': Unit triangular */ /* ISEED (input/output) INTEGER array, dimension (4) */ /* The seed vector for the random number generator (used in */ /* SLATMS). Modified on exit. */ /* N (input) INTEGER */ /* The order of the matrix to be generated. */ /* A (output) REAL array, dimension (N*(N+1)/2) */ /* The upper or lower triangular matrix A, packed columnwise in */ /* a linear array. The j-th column of A is stored in the array */ /* AP as follows: */ /* if UPLO = 'U', AP((j-1)*j/2 + i) = A(i,j) for 1<=i<=j; */ /* if UPLO = 'L', */ /* AP((j-1)*(n-j) + j*(j+1)/2 + i-j) = A(i,j) for j<=i<=n. */ /* B (output) REAL array, dimension (N) */ /* The right hand side vector, if IMAT > 10. */ /* WORK (workspace) REAL array, dimension (3*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -k, the k-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ --work; --b; --a; --iseed; /* Function Body */ s_copy(path, "Single precision", (ftnlen)1, (ftnlen)16); s_copy(path + 1, "TP", (ftnlen)2, (ftnlen)2); unfl = slamch_("Safe minimum"); ulp = slamch_("Epsilon") * slamch_("Base"); smlnum = unfl; bignum = (1.f - ulp) / smlnum; slabad_(&smlnum, &bignum); if (*imat >= 7 && *imat <= 10 || *imat == 18) { *(unsigned char *)diag = 'U'; } else { *(unsigned char *)diag = 'N'; } *info = 0; /* Quick return if N.LE.0. */ if (*n <= 0) { return 0; } /* Call SLATB4 to set parameters for SLATMS. */ upper = lsame_(uplo, "U"); if (upper) { slatb4_(path, imat, n, n, type__, &kl, &ku, &anorm, &mode, &cndnum, dist); *(unsigned char *)packit = 'C'; } else { i__1 = -(*imat); slatb4_(path, &i__1, n, n, type__, &kl, &ku, &anorm, &mode, &cndnum, dist); *(unsigned char *)packit = 'R'; } /* IMAT <= 6: Non-unit triangular matrix */ if (*imat <= 6) { slatms_(n, n, dist, &iseed[1], type__, &b[1], &mode, &cndnum, &anorm, &kl, &ku, packit, &a[1], n, &work[1], info); /* IMAT > 6: Unit triangular matrix */ /* The diagonal is deliberately set to something other than 1. */ /* IMAT = 7: Matrix is the identity */ } else if (*imat == 7) { if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { a[jc + i__ - 1] = 0.f; /* L10: */ } a[jc + j - 1] = (real) j; jc += j; /* L20: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { a[jc] = (real) j; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { a[jc + i__ - j] = 0.f; /* L30: */ } jc = jc + *n - j + 1; /* L40: */ } } /* IMAT > 7: Non-trivial unit triangular matrix */ /* Generate a unit triangular matrix T with condition CNDNUM by */ /* forming a triangular matrix with known singular values and */ /* filling in the zero entries with Givens rotations. */ } else if (*imat <= 10) { if (upper) { jc = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { a[jc + i__] = 0.f; /* L50: */ } a[jc + j] = (real) j; jc += j; /* L60: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { a[jc] = (real) j; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { a[jc + i__ - j] = 0.f; /* L70: */ } jc = jc + *n - j + 1; /* L80: */ } } /* Since the trace of a unit triangular matrix is 1, the product */ /* of its singular values must be 1. Let s = sqrt(CNDNUM), */ /* x = sqrt(s) - 1/sqrt(s), y = sqrt(2/(n-2))*x, and z = x**2. */ /* The following triangular matrix has singular values s, 1, 1, */ /* ..., 1, 1/s: */ /* 1 y y y ... y y z */ /* 1 0 0 ... 0 0 y */ /* 1 0 ... 0 0 y */ /* . ... . . . */ /* . . . . */ /* 1 0 y */ /* 1 y */ /* 1 */ /* To fill in the zeros, we first multiply by a matrix with small */ /* condition number of the form */ /* 1 0 0 0 0 ... */ /* 1 + * 0 0 ... */ /* 1 + 0 0 0 */ /* 1 + * 0 0 */ /* 1 + 0 0 */ /* ... */ /* 1 + 0 */ /* 1 0 */ /* 1 */ /* Each element marked with a '*' is formed by taking the product */ /* of the adjacent elements marked with '+'. The '*'s can be */ /* chosen freely, and the '+'s are chosen so that the inverse of */ /* T will have elements of the same magnitude as T. If the *'s in */ /* both T and inv(T) have small magnitude, T is well conditioned. */ /* The two offdiagonals of T are stored in WORK. */ /* The product of these two matrices has the form */ /* 1 y y y y y . y y z */ /* 1 + * 0 0 . 0 0 y */ /* 1 + 0 0 . 0 0 y */ /* 1 + * . . . . */ /* 1 + . . . . */ /* . . . . . */ /* . . . . */ /* 1 + y */ /* 1 y */ /* 1 */ /* Now we multiply by Givens rotations, using the fact that */ /* [ c s ] [ 1 w ] [ -c -s ] = [ 1 -w ] */ /* [ -s c ] [ 0 1 ] [ s -c ] [ 0 1 ] */ /* and */ /* [ -c -s ] [ 1 0 ] [ c s ] = [ 1 0 ] */ /* [ s -c ] [ w 1 ] [ -s c ] [ -w 1 ] */ /* where c = w / sqrt(w**2+4) and s = 2 / sqrt(w**2+4). */ star1 = .25f; sfac = .5f; plus1 = sfac; i__1 = *n; for (j = 1; j <= i__1; j += 2) { plus2 = star1 / plus1; work[j] = plus1; work[*n + j] = star1; if (j + 1 <= *n) { work[j + 1] = plus2; work[*n + j + 1] = 0.f; plus1 = star1 / plus2; rexp = slarnd_(&c__2, &iseed[1]); d__1 = (doublereal) sfac; d__2 = (doublereal) rexp; star1 *= pow_dd(&d__1, &d__2); if (rexp < 0.f) { d__1 = (doublereal) sfac; d__2 = (doublereal) (1.f - rexp); star1 = -pow_dd(&d__1, &d__2); } else { d__1 = (doublereal) sfac; d__2 = (doublereal) (rexp + 1.f); star1 = pow_dd(&d__1, &d__2); } } /* L90: */ } x = sqrt(cndnum) - 1.f / sqrt(cndnum); if (*n > 2) { y = sqrt(2.f / (real) (*n - 2)) * x; } else { y = 0.f; } z__ = x * x; if (upper) { /* Set the upper triangle of A with a unit triangular matrix */ /* of known condition number. */ jc = 1; i__1 = *n; for (j = 2; j <= i__1; ++j) { a[jc + 1] = y; if (j > 2) { a[jc + j - 1] = work[j - 2]; } if (j > 3) { a[jc + j - 2] = work[*n + j - 3]; } jc += j; /* L100: */ } jc -= *n; a[jc + 1] = z__; i__1 = *n - 1; for (j = 2; j <= i__1; ++j) { a[jc + j] = y; /* L110: */ } } else { /* Set the lower triangle of A with a unit triangular matrix */ /* of known condition number. */ i__1 = *n - 1; for (i__ = 2; i__ <= i__1; ++i__) { a[i__] = y; /* L120: */ } a[*n] = z__; jc = *n + 1; i__1 = *n - 1; for (j = 2; j <= i__1; ++j) { a[jc + 1] = work[j - 1]; if (j < *n - 1) { a[jc + 2] = work[*n + j - 1]; } a[jc + *n - j] = y; jc = jc + *n - j + 1; /* L130: */ } } /* Fill in the zeros using Givens rotations */ if (upper) { jc = 1; i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { jcnext = jc + j; ra = a[jcnext + j - 1]; rb = 2.f; srotg_(&ra, &rb, &c__, &s); /* Multiply by [ c s; -s c] on the left. */ if (*n > j + 1) { jx = jcnext + j; i__2 = *n; for (i__ = j + 2; i__ <= i__2; ++i__) { stemp = c__ * a[jx + j] + s * a[jx + j + 1]; a[jx + j + 1] = -s * a[jx + j] + c__ * a[jx + j + 1]; a[jx + j] = stemp; jx += i__; /* L140: */ } } /* Multiply by [-c -s; s -c] on the right. */ if (j > 1) { i__2 = j - 1; r__1 = -c__; r__2 = -s; srot_(&i__2, &a[jcnext], &c__1, &a[jc], &c__1, &r__1, & r__2); } /* Negate A(J,J+1). */ a[jcnext + j - 1] = -a[jcnext + j - 1]; jc = jcnext; /* L150: */ } } else { jc = 1; i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { jcnext = jc + *n - j + 1; ra = a[jc + 1]; rb = 2.f; srotg_(&ra, &rb, &c__, &s); /* Multiply by [ c -s; s c] on the right. */ if (*n > j + 1) { i__2 = *n - j - 1; r__1 = -s; srot_(&i__2, &a[jcnext + 1], &c__1, &a[jc + 2], &c__1, & c__, &r__1); } /* Multiply by [-c s; -s -c] on the left. */ if (j > 1) { jx = 1; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { stemp = -c__ * a[jx + j - i__] + s * a[jx + j - i__ + 1]; a[jx + j - i__ + 1] = -s * a[jx + j - i__] - c__ * a[ jx + j - i__ + 1]; a[jx + j - i__] = stemp; jx = jx + *n - i__ + 1; /* L160: */ } } /* Negate A(J+1,J). */ a[jc + 1] = -a[jc + 1]; jc = jcnext; /* L170: */ } } /* IMAT > 10: Pathological test cases. These triangular matrices */ /* are badly scaled or badly conditioned, so when used in solving a */ /* triangular system they may cause overflow in the solution vector. */ } else if (*imat == 11) { /* Type 11: Generate a triangular matrix with elements between */ /* -1 and 1. Give the diagonal norm 2 to make it well-conditioned. */ /* Make the right hand side large so that it requires scaling. */ if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { slarnv_(&c__2, &iseed[1], &j, &a[jc]); a[jc + j - 1] = r_sign(&c_b36, &a[jc + j - 1]); jc += j; /* L180: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n - j + 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); a[jc] = r_sign(&c_b36, &a[jc]); jc = jc + *n - j + 1; /* L190: */ } } /* Set the right hand side so that the largest value is BIGNUM. */ slarnv_(&c__2, &iseed[1], n, &b[1]); iy = isamax_(n, &b[1], &c__1); bnorm = (r__1 = b[iy], dabs(r__1)); bscal = bignum / dmax(1.f,bnorm); sscal_(n, &bscal, &b[1], &c__1); } else if (*imat == 12) { /* Type 12: Make the first diagonal element in the solve small to */ /* cause immediate overflow when dividing by T(j,j). */ /* In type 12, the offdiagonal elements are small (CNORM(j) < 1). */ slarnv_(&c__2, &iseed[1], n, &b[1]); /* Computing MAX */ r__1 = 1.f, r__2 = (real) (*n - 1); tscal = 1.f / dmax(r__1,r__2); if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); i__2 = j - 1; sscal_(&i__2, &tscal, &a[jc], &c__1); r__1 = slarnd_(&c__2, &iseed[1]); a[jc + j - 1] = r_sign(&c_b48, &r__1); jc += j; /* L200: */ } a[*n * (*n + 1) / 2] = smlnum; } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n - j; slarnv_(&c__2, &iseed[1], &i__2, &a[jc + 1]); i__2 = *n - j; sscal_(&i__2, &tscal, &a[jc + 1], &c__1); r__1 = slarnd_(&c__2, &iseed[1]); a[jc] = r_sign(&c_b48, &r__1); jc = jc + *n - j + 1; /* L210: */ } a[1] = smlnum; } } else if (*imat == 13) { /* Type 13: Make the first diagonal element in the solve small to */ /* cause immediate overflow when dividing by T(j,j). */ /* In type 13, the offdiagonal elements are O(1) (CNORM(j) > 1). */ slarnv_(&c__2, &iseed[1], n, &b[1]); if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); r__1 = slarnd_(&c__2, &iseed[1]); a[jc + j - 1] = r_sign(&c_b48, &r__1); jc += j; /* L220: */ } a[*n * (*n + 1) / 2] = smlnum; } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n - j; slarnv_(&c__2, &iseed[1], &i__2, &a[jc + 1]); r__1 = slarnd_(&c__2, &iseed[1]); a[jc] = r_sign(&c_b48, &r__1); jc = jc + *n - j + 1; /* L230: */ } a[1] = smlnum; } } else if (*imat == 14) { /* Type 14: T is diagonal with small numbers on the diagonal to */ /* make the growth factor underflow, but a small right hand side */ /* chosen so that the solution does not overflow. */ if (upper) { jcount = 1; jc = (*n - 1) * *n / 2 + 1; for (j = *n; j >= 1; --j) { i__1 = j - 1; for (i__ = 1; i__ <= i__1; ++i__) { a[jc + i__ - 1] = 0.f; /* L240: */ } if (jcount <= 2) { a[jc + j - 1] = smlnum; } else { a[jc + j - 1] = 1.f; } ++jcount; if (jcount > 4) { jcount = 1; } jc = jc - j + 1; /* L250: */ } } else { jcount = 1; jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { a[jc + i__ - j] = 0.f; /* L260: */ } if (jcount <= 2) { a[jc] = smlnum; } else { a[jc] = 1.f; } ++jcount; if (jcount > 4) { jcount = 1; } jc = jc + *n - j + 1; /* L270: */ } } /* Set the right hand side alternately zero and small. */ if (upper) { b[1] = 0.f; for (i__ = *n; i__ >= 2; i__ += -2) { b[i__] = 0.f; b[i__ - 1] = smlnum; /* L280: */ } } else { b[*n] = 0.f; i__1 = *n - 1; for (i__ = 1; i__ <= i__1; i__ += 2) { b[i__] = 0.f; b[i__ + 1] = smlnum; /* L290: */ } } } else if (*imat == 15) { /* Type 15: Make the diagonal elements small to cause gradual */ /* overflow when dividing by T(j,j). To control the amount of */ /* scaling needed, the matrix is bidiagonal. */ /* Computing MAX */ r__1 = 1.f, r__2 = (real) (*n - 1); texp = 1.f / dmax(r__1,r__2); d__1 = (doublereal) smlnum; d__2 = (doublereal) texp; tscal = pow_dd(&d__1, &d__2); slarnv_(&c__2, &iseed[1], n, &b[1]); if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 2; for (i__ = 1; i__ <= i__2; ++i__) { a[jc + i__ - 1] = 0.f; /* L300: */ } if (j > 1) { a[jc + j - 2] = -1.f; } a[jc + j - 1] = tscal; jc += j; /* L310: */ } b[*n] = 1.f; } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j + 2; i__ <= i__2; ++i__) { a[jc + i__ - j] = 0.f; /* L320: */ } if (j < *n) { a[jc + 1] = -1.f; } a[jc] = tscal; jc = jc + *n - j + 1; /* L330: */ } b[1] = 1.f; } } else if (*imat == 16) { /* Type 16: One zero diagonal element. */ iy = *n / 2 + 1; if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { slarnv_(&c__2, &iseed[1], &j, &a[jc]); if (j != iy) { a[jc + j - 1] = r_sign(&c_b36, &a[jc + j - 1]); } else { a[jc + j - 1] = 0.f; } jc += j; /* L340: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n - j + 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); if (j != iy) { a[jc] = r_sign(&c_b36, &a[jc]); } else { a[jc] = 0.f; } jc = jc + *n - j + 1; /* L350: */ } } slarnv_(&c__2, &iseed[1], n, &b[1]); sscal_(n, &c_b36, &b[1], &c__1); } else if (*imat == 17) { /* Type 17: Make the offdiagonal elements large to cause overflow */ /* when adding a column of T. In the non-transposed case, the */ /* matrix is constructed to cause overflow when adding a column in */ /* every other step. */ tscal = unfl / ulp; tscal = (1.f - ulp) / tscal; i__1 = *n * (*n + 1) / 2; for (j = 1; j <= i__1; ++j) { a[j] = 0.f; /* L360: */ } texp = 1.f; if (upper) { jc = (*n - 1) * *n / 2 + 1; for (j = *n; j >= 2; j += -2) { a[jc] = -tscal / (real) (*n + 1); a[jc + j - 1] = 1.f; b[j] = texp * (1.f - ulp); jc = jc - j + 1; a[jc] = -(tscal / (real) (*n + 1)) / (real) (*n + 2); a[jc + j - 2] = 1.f; b[j - 1] = texp * (real) (*n * *n + *n - 1); texp *= 2.f; jc = jc - j + 2; /* L370: */ } b[1] = (real) (*n + 1) / (real) (*n + 2) * tscal; } else { jc = 1; i__1 = *n - 1; for (j = 1; j <= i__1; j += 2) { a[jc + *n - j] = -tscal / (real) (*n + 1); a[jc] = 1.f; b[j] = texp * (1.f - ulp); jc = jc + *n - j + 1; a[jc + *n - j - 1] = -(tscal / (real) (*n + 1)) / (real) (*n + 2); a[jc] = 1.f; b[j + 1] = texp * (real) (*n * *n + *n - 1); texp *= 2.f; jc = jc + *n - j; /* L380: */ } b[*n] = (real) (*n + 1) / (real) (*n + 2) * tscal; } } else if (*imat == 18) { /* Type 18: Generate a unit triangular matrix with elements */ /* between -1 and 1, and make the right hand side large so that it */ /* requires scaling. */ if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); a[jc + j - 1] = 0.f; jc += j; /* L390: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (j < *n) { i__2 = *n - j; slarnv_(&c__2, &iseed[1], &i__2, &a[jc + 1]); } a[jc] = 0.f; jc = jc + *n - j + 1; /* L400: */ } } /* Set the right hand side so that the largest value is BIGNUM. */ slarnv_(&c__2, &iseed[1], n, &b[1]); iy = isamax_(n, &b[1], &c__1); bnorm = (r__1 = b[iy], dabs(r__1)); bscal = bignum / dmax(1.f,bnorm); sscal_(n, &bscal, &b[1], &c__1); } else if (*imat == 19) { /* Type 19: Generate a triangular matrix with elements between */ /* BIGNUM/(n-1) and BIGNUM so that at least one of the column */ /* norms will exceed BIGNUM. */ /* Computing MAX */ r__1 = 1.f, r__2 = (real) (*n - 1); tleft = bignum / dmax(r__1,r__2); /* Computing MAX */ r__1 = 1.f, r__2 = (real) (*n); tscal = bignum * ((real) (*n - 1) / dmax(r__1,r__2)); if (upper) { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { slarnv_(&c__2, &iseed[1], &j, &a[jc]); i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { a[jc + i__ - 1] = r_sign(&tleft, &a[jc + i__ - 1]) + tscal * a[jc + i__ - 1]; /* L410: */ } jc += j; /* L420: */ } } else { jc = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n - j + 1; slarnv_(&c__2, &iseed[1], &i__2, &a[jc]); i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { a[jc + i__ - j] = r_sign(&tleft, &a[jc + i__ - j]) + tscal * a[jc + i__ - j]; /* L430: */ } jc = jc + *n - j + 1; /* L440: */ } } slarnv_(&c__2, &iseed[1], n, &b[1]); sscal_(n, &c_b36, &b[1], &c__1); } /* Flip the matrix across its counter-diagonal if the transpose will */ /* be used. */ if (! lsame_(trans, "N")) { if (upper) { jj = 1; jr = *n * (*n + 1) / 2; i__1 = *n / 2; for (j = 1; j <= i__1; ++j) { jl = jj; i__2 = *n - j; for (i__ = j; i__ <= i__2; ++i__) { t = a[jr - i__ + j]; a[jr - i__ + j] = a[jl]; a[jl] = t; jl += i__; /* L450: */ } jj = jj + j + 1; jr -= *n - j + 1; /* L460: */ } } else { jl = 1; jj = *n * (*n + 1) / 2; i__1 = *n / 2; for (j = 1; j <= i__1; ++j) { jr = jj; i__2 = *n - j; for (i__ = j; i__ <= i__2; ++i__) { t = a[jl + i__ - j]; a[jl + i__ - j] = a[jr]; a[jr] = t; jr -= i__; /* L470: */ } jl = jl + *n - j + 1; jj = jj - j - 1; /* L480: */ } } } return 0; /* End of SLATTP */ } /* slattp_ */