diff options
author | philippe.theveny <philippe.theveny@8a072113-8704-0410-8d35-dd094bca7971> | 2015-02-24 23:50:54 +0000 |
---|---|---|
committer | philippe.theveny <philippe.theveny@8a072113-8704-0410-8d35-dd094bca7971> | 2015-02-24 23:50:54 +0000 |
commit | 6273f536d15680513e8cddfc4d8baa88ad2c64df (patch) | |
tree | a7f3303149eda2542ad7cf05fb470b60872e0161 /TESTING | |
parent | c95be035b79cca2ba9e68c961d537344c5390765 (diff) |
Add xGGHD3: blocked Hessenberg reduction, code from Daniel Kressner.
Add xGGES3 and xGGEV3: computation of the Schur form, the Schur vectors, and
the generalized eigenvalues using the blocked Hessenberg reduction.
Diffstat (limited to 'TESTING')
-rw-r--r-- | TESTING/EIG/CMakeLists.txt | 80 | ||||
-rw-r--r-- | TESTING/EIG/Makefile | 8 | ||||
-rw-r--r-- | TESTING/EIG/cchkee.f | 57 | ||||
-rw-r--r-- | TESTING/EIG/cdrges3.f | 940 | ||||
-rw-r--r-- | TESTING/EIG/cdrgev3.f | 943 | ||||
-rw-r--r-- | TESTING/EIG/cerrgg.f | 174 | ||||
-rw-r--r-- | TESTING/EIG/dchkee.f | 74 | ||||
-rw-r--r-- | TESTING/EIG/ddrges3.f | 997 | ||||
-rw-r--r-- | TESTING/EIG/ddrgev3.f | 940 | ||||
-rw-r--r-- | TESTING/EIG/derrgg.f | 142 | ||||
-rw-r--r-- | TESTING/EIG/schkee.f | 56 | ||||
-rw-r--r-- | TESTING/EIG/sdrges3.f | 997 | ||||
-rw-r--r-- | TESTING/EIG/sdrgev3.f | 941 | ||||
-rw-r--r-- | TESTING/EIG/serrgg.f | 174 | ||||
-rw-r--r-- | TESTING/EIG/zchkee.f | 58 | ||||
-rw-r--r-- | TESTING/EIG/zdrges3.f | 940 | ||||
-rw-r--r-- | TESTING/EIG/zdrgev3.f | 939 | ||||
-rw-r--r-- | TESTING/EIG/zerrgg.f | 176 | ||||
-rw-r--r-- | TESTING/cgg.in | 15 | ||||
-rw-r--r-- | TESTING/dgg.in | 1 | ||||
-rw-r--r-- | TESTING/sgg.in | 1 | ||||
-rw-r--r-- | TESTING/zgg.in | 1 |
22 files changed, 8475 insertions, 179 deletions
diff --git a/TESTING/EIG/CMakeLists.txt b/TESTING/EIG/CMakeLists.txt index 05b11fb6..cbf56220 100644 --- a/TESTING/EIG/CMakeLists.txt +++ b/TESTING/EIG/CMakeLists.txt @@ -51,16 +51,16 @@ set(SEIGTST schkee.f schkbb.f schkbd.f schkbk.f schkbl.f schkec.f schkgg.f schkgk.f schkgl.f schkhs.f schksb.f schkst.f sckcsd.f sckglm.f sckgqr.f sckgsv.f scklse.f scsdts.f - sdrges.f sdrgev.f sdrgsx.f sdrgvx.f - sdrvbd.f sdrves.f sdrvev.f sdrvgg.f sdrvsg.f - sdrvst.f sdrvsx.f sdrvvx.f - serrbd.f serrec.f serred.f serrgg.f serrhs.f serrst.f - sget02.f sget10.f sget22.f sget23.f sget24.f sget31.f - sget32.f sget33.f sget34.f sget35.f sget36.f - sget37.f sget38.f sget39.f sget51.f sget52.f sget53.f - sget54.f sglmts.f sgqrts.f sgrqts.f sgsvts.f - shst01.f slarfy.f slarhs.f slatm4.f slctes.f slctsx.f slsets.f sort01.f - sort03.f ssbt21.f ssgt01.f sslect.f sspt21.f sstt21.f + sdrges.f sdrgev.f sdrges3.f sdrgev3.f sdrgsx.f sdrgvx.f + sdrvbd.f sdrves.f sdrvev.f sdrvgg.f sdrvsg.f + sdrvst.f sdrvsx.f sdrvvx.f + serrbd.f serrec.f serred.f serrgg.f serrhs.f serrst.f + sget02.f sget10.f sget22.f sget23.f sget24.f sget31.f + sget32.f sget33.f sget34.f sget35.f sget36.f + sget37.f sget38.f sget39.f sget51.f sget52.f sget53.f + sget54.f sglmts.f sgqrts.f sgrqts.f sgsvts.f + shst01.f slarfy.f slarhs.f slatm4.f slctes.f slctsx.f slsets.f sort01.f + sort03.f ssbt21.f ssgt01.f sslect.f sspt21.f sstt21.f sstt22.f ssyt21.f ssyt22.f) set(CEIGTST cchkee.f @@ -68,16 +68,16 @@ set(CEIGTST cchkee.f cchkbb.f cchkbd.f cchkbk.f cchkbl.f cchkec.f cchkgg.f cchkgk.f cchkgl.f cchkhb.f cchkhs.f cchkst.f cckcsd.f cckglm.f cckgqr.f cckgsv.f ccklse.f ccsdts.f - cdrges.f cdrgev.f cdrgsx.f cdrgvx.f - cdrvbd.f cdrves.f cdrvev.f cdrvgg.f cdrvsg.f - cdrvst.f cdrvsx.f cdrvvx.f - cerrbd.f cerrec.f cerred.f cerrgg.f cerrhs.f cerrst.f - cget02.f cget10.f cget22.f cget23.f cget24.f - cget35.f cget36.f cget37.f cget38.f cget51.f cget52.f - cget54.f cglmts.f cgqrts.f cgrqts.f cgsvts.f - chbt21.f chet21.f chet22.f chpt21.f chst01.f - clarfy.f clarhs.f clatm4.f clctes.f clctsx.f clsets.f csbmv.f - csgt01.f cslect.f + cdrges.f cdrgev.f cdrges3.f cdrgev3.f cdrgsx.f cdrgvx.f + cdrvbd.f cdrves.f cdrvev.f cdrvgg.f cdrvsg.f + cdrvst.f cdrvsx.f cdrvvx.f + cerrbd.f cerrec.f cerred.f cerrgg.f cerrhs.f cerrst.f + cget02.f cget10.f cget22.f cget23.f cget24.f + cget35.f cget36.f cget37.f cget38.f cget51.f cget52.f + cget54.f cglmts.f cgqrts.f cgrqts.f cgsvts.f + chbt21.f chet21.f chet22.f chpt21.f chst01.f + clarfy.f clarhs.f clatm4.f clctes.f clctsx.f clsets.f csbmv.f + csgt01.f cslect.f cstt21.f cstt22.f cunt01.f cunt03.f) set(DZIGTST dlafts.f dlahd2.f dlasum.f dlatb9.f dstech.f dstect.f @@ -88,16 +88,16 @@ set(DEIGTST dchkee.f dchkbb.f dchkbd.f dchkbk.f dchkbl.f dchkec.f dchkgg.f dchkgk.f dchkgl.f dchkhs.f dchksb.f dchkst.f dckcsd.f dckglm.f dckgqr.f dckgsv.f dcklse.f dcsdts.f - ddrges.f ddrgev.f ddrgsx.f ddrgvx.f - ddrvbd.f ddrves.f ddrvev.f ddrvgg.f ddrvsg.f - ddrvst.f ddrvsx.f ddrvvx.f - derrbd.f derrec.f derred.f derrgg.f derrhs.f derrst.f - dget02.f dget10.f dget22.f dget23.f dget24.f dget31.f - dget32.f dget33.f dget34.f dget35.f dget36.f - dget37.f dget38.f dget39.f dget51.f dget52.f dget53.f - dget54.f dglmts.f dgqrts.f dgrqts.f dgsvts.f - dhst01.f dlarfy.f dlarhs.f dlatm4.f dlctes.f dlctsx.f dlsets.f dort01.f - dort03.f dsbt21.f dsgt01.f dslect.f dspt21.f dstt21.f + ddrges.f ddrgev.f ddrges3.f ddrgev3.f ddrgsx.f ddrgvx.f + ddrvbd.f ddrves.f ddrvev.f ddrvgg.f ddrvsg.f + ddrvst.f ddrvsx.f ddrvvx.f + derrbd.f derrec.f derred.f derrgg.f derrhs.f derrst.f + dget02.f dget10.f dget22.f dget23.f dget24.f dget31.f + dget32.f dget33.f dget34.f dget35.f dget36.f + dget37.f dget38.f dget39.f dget51.f dget52.f dget53.f + dget54.f dglmts.f dgqrts.f dgrqts.f dgsvts.f + dhst01.f dlarfy.f dlarhs.f dlatm4.f dlctes.f dlctsx.f dlsets.f dort01.f + dort03.f dsbt21.f dsgt01.f dslect.f dspt21.f dstt21.f dstt22.f dsyt21.f dsyt22.f) set(ZEIGTST zchkee.f @@ -105,16 +105,16 @@ set(ZEIGTST zchkee.f zchkbb.f zchkbd.f zchkbk.f zchkbl.f zchkec.f zchkgg.f zchkgk.f zchkgl.f zchkhb.f zchkhs.f zchkst.f zckcsd.f zckglm.f zckgqr.f zckgsv.f zcklse.f zcsdts.f - zdrges.f zdrgev.f zdrgsx.f zdrgvx.f - zdrvbd.f zdrves.f zdrvev.f zdrvgg.f zdrvsg.f - zdrvst.f zdrvsx.f zdrvvx.f - zerrbd.f zerrec.f zerred.f zerrgg.f zerrhs.f zerrst.f - zget02.f zget10.f zget22.f zget23.f zget24.f - zget35.f zget36.f zget37.f zget38.f zget51.f zget52.f - zget54.f zglmts.f zgqrts.f zgrqts.f zgsvts.f - zhbt21.f zhet21.f zhet22.f zhpt21.f zhst01.f - zlarfy.f zlarhs.f zlatm4.f zlctes.f zlctsx.f zlsets.f zsbmv.f - zsgt01.f zslect.f + zdrges.f zdrgev.f zdrges3.f zdrgev3.f zdrgsx.f zdrgvx.f + zdrvbd.f zdrves.f zdrvev.f zdrvgg.f zdrvsg.f + zdrvst.f zdrvsx.f zdrvvx.f + zerrbd.f zerrec.f zerred.f zerrgg.f zerrhs.f zerrst.f + zget02.f zget10.f zget22.f zget23.f zget24.f + zget35.f zget36.f zget37.f zget38.f zget51.f zget52.f + zget54.f zglmts.f zgqrts.f zgrqts.f zgsvts.f + zhbt21.f zhet21.f zhet22.f zhpt21.f zhst01.f + zlarfy.f zlarhs.f zlatm4.f zlctes.f zlctsx.f zlsets.f zsbmv.f + zsgt01.f zslect.f zstt21.f zstt22.f zunt01.f zunt03.f) macro(add_eig_executable name ) diff --git a/TESTING/EIG/Makefile b/TESTING/EIG/Makefile index 48e43c9f..63d14572 100644 --- a/TESTING/EIG/Makefile +++ b/TESTING/EIG/Makefile @@ -53,7 +53,7 @@ SEIGTST = schkee.o \ schkbb.o schkbd.o schkbk.o schkbl.o schkec.o \ schkgg.o schkgk.o schkgl.o schkhs.o schksb.o schkst.o \ sckcsd.o sckglm.o sckgqr.o sckgsv.o scklse.o scsdts.o \ - sdrges.o sdrgev.o sdrgsx.o sdrgvx.o \ + sdrges.o sdrgev.o sdrges3.o sdrgev3.o sdrgsx.o sdrgvx.o \ sdrvbd.o sdrves.o sdrvev.o sdrvgg.o sdrvsg.o \ sdrvst.o sdrvsx.o sdrvvx.o \ serrbd.o serrec.o serred.o serrgg.o serrhs.o serrst.o \ @@ -70,7 +70,7 @@ CEIGTST = cchkee.o \ cchkbb.o cchkbd.o cchkbk.o cchkbl.o cchkec.o \ cchkgg.o cchkgk.o cchkgl.o cchkhb.o cchkhs.o cchkst.o \ cckcsd.o cckglm.o cckgqr.o cckgsv.o ccklse.o ccsdts.o \ - cdrges.o cdrgev.o cdrgsx.o cdrgvx.o \ + cdrges.o cdrgev.o cdrges3.o cdrgev3.o cdrgsx.o cdrgvx.o \ cdrvbd.o cdrves.o cdrvev.o cdrvgg.o cdrvsg.o \ cdrvst.o cdrvsx.o cdrvvx.o \ cerrbd.o cerrec.o cerred.o cerrgg.o cerrhs.o cerrst.o \ @@ -90,7 +90,7 @@ DEIGTST = dchkee.o \ dchkbb.o dchkbd.o dchkbk.o dchkbl.o dchkec.o \ dchkgg.o dchkgk.o dchkgl.o dchkhs.o dchksb.o dchkst.o \ dckcsd.o dckglm.o dckgqr.o dckgsv.o dcklse.o dcsdts.o \ - ddrges.o ddrgev.o ddrgsx.o ddrgvx.o \ + ddrges.o ddrgev.o ddrges3.o ddrgev3.o ddrgsx.o ddrgvx.o \ ddrvbd.o ddrves.o ddrvev.o ddrvgg.o ddrvsg.o \ ddrvst.o ddrvsx.o ddrvvx.o \ derrbd.o derrec.o derred.o derrgg.o derrhs.o derrst.o \ @@ -107,7 +107,7 @@ ZEIGTST = zchkee.o \ zchkbb.o zchkbd.o zchkbk.o zchkbl.o zchkec.o \ zchkgg.o zchkgk.o zchkgl.o zchkhb.o zchkhs.o zchkst.o \ zckcsd.o zckglm.o zckgqr.o zckgsv.o zcklse.o zcsdts.o \ - zdrges.o zdrgev.o zdrgsx.o zdrgvx.o \ + zdrges.o zdrgev.o zdrges3.o zdrgev3.o zdrgsx.o zdrgvx.o \ zdrvbd.o zdrves.o zdrvev.o zdrvgg.o zdrvsg.o \ zdrvst.o zdrvsx.o zdrvvx.o \ zerrbd.o zerrec.o zerred.o zerrgg.o zerrhs.o zerrst.o \ diff --git a/TESTING/EIG/cchkee.f b/TESTING/EIG/cchkee.f index 31715d56..e485acc7 100644 --- a/TESTING/EIG/cchkee.f +++ b/TESTING/EIG/cchkee.f @@ -44,7 +44,7 @@ *> Test CGEESX *> *> CGG (Generalized Nonsymmetric Eigenvalue Problem): -*> Test CGGHRD, CGGBAL, CGGBAK, CHGEQZ, and CTGEVC +*> Test CGGHD3, CGGBAL, CGGBAK, CHGEQZ, and CTGEVC *> and the driver routines CGEGS and CGEGV *> *> CGS (Generalized Nonsymmetric Schur form Driver): @@ -489,38 +489,41 @@ *> line 8: MXBVAL, INTEGER array, dimension (NPARMS) *> The values for MAXB, used in determining minimum blocksize. *> -*> line 9: NBCOL, INTEGER array, dimension (NPARMS) +*> line 9: IACC22, INTEGER array, dimension (NPARMS) +*> select structured matrix multiply: 1 or 2) +*> +*> line 10: NBCOL, INTEGER array, dimension (NPARMS) *> The values for NBCOL, the minimum column dimension for *> blocks. *> -*> line 10: THRESH +*> line 11: THRESH *> Threshold value for the test ratios. Information will be *> printed about each test for which the test ratio is greater *> than or equal to the threshold. *> -*> line 11: TSTCHK, LOGICAL +*> line 12: TSTCHK, LOGICAL *> Flag indicating whether or not to test the LAPACK routines. *> -*> line 12: TSTDRV, LOGICAL +*> line 13: TSTDRV, LOGICAL *> Flag indicating whether or not to test the driver routines. *> -*> line 13: TSTERR, LOGICAL +*> line 14: TSTERR, LOGICAL *> Flag indicating whether or not to test the error exits for *> the LAPACK routines and driver routines. *> -*> line 14: NEWSD, INTEGER +*> line 15: NEWSD, INTEGER *> A code indicating how to set the random number seed. *> = 0: Set the seed to a default value before each run *> = 1: Initialize the seed to a default value only before the *> first run *> = 2: Like 1, but use the seed values on the next line *> -*> If line 14 was 2: +*> If line 15 was 2: *> -*> line 15: INTEGER array, dimension (4) +*> line 16: INTEGER array, dimension (4) *> Four integer values for the random number seed. *> -*> lines 16-EOF: Lines specifying matrix types, as for NEP. +*> lines 17-EOF: Lines specifying matrix types, as for NEP. *> The 3-character path name is 'CGG' for the generalized *> eigenvalue problem routines and driver routines. *> @@ -1100,7 +1103,8 @@ $ CCKCSD, CCKGLM, CCKGQR, CCKGSV, CCKLSE, CDRGES, $ CDRGEV, CDRGSX, CDRGVX, CDRVBD, CDRVES, CDRVEV, $ CDRVGG, CDRVSG, CDRVST, CDRVSX, CDRVVX, CERRBD, - $ CERRED, CERRGG, CERRHS, CERRST, ILAVER, XLAENV + $ CERRED, CERRGG, CERRHS, CERRST, ILAVER, XLAENV, + $ CDRGES3, CDRGEV3 * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN @@ -1621,7 +1625,7 @@ * * Read the values for IACC22. * - IF( NEP ) THEN + IF( NEP .OR. CGG ) THEN READ( NIN, FMT = * )( IACC22( I ), I = 1, NPARMS ) DO 620 I = 1, NPARMS IF( IACC22( I ).LT.0 ) THEN @@ -2090,6 +2094,7 @@ * NBMIN = minimum block size * NS = number of shifts * MAXB = minimum submatrix size +* IACC22: structured matrix multiply * NBCOL = minimum column dimension for blocks * MAXTYP = 26 @@ -2102,6 +2107,7 @@ CALL XLAENV( 2, NBMIN( I ) ) CALL XLAENV( 4, NSVAL( I ) ) CALL XLAENV( 8, MXBVAL( I ) ) + CALL XLAENV( 16, IACC22( I ) ) CALL XLAENV( 5, NBCOL( I ) ) * IF( NEWSD.EQ.0 ) THEN @@ -2110,7 +2116,7 @@ 340 CONTINUE END IF WRITE( NOUT, FMT = 9996 )C3, NBVAL( I ), NBMIN( I ), - $ NSVAL( I ), MXBVAL( I ), NBCOL( I ) + $ NSVAL( I ), MXBVAL( I ), IACC22( I ), NBCOL( I ) TSTDIF = .FALSE. THRSHN = 10. IF( TSTCHK ) THEN @@ -2162,8 +2168,20 @@ * IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'CDRGES', INFO +* +* Blocked version +* + CALL CDRGES3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ DC( 1, 1 ), DC( 1, 2 ), WORK, LWORK, RWORK, + $ RESULT, LOGWRK, INFO ) +* + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'CDRGES3', INFO END IF WRITE( NOUT, FMT = 9973 ) + GO TO 10 * ELSE IF( CGX ) THEN @@ -2216,6 +2234,17 @@ $ RESULT, INFO ) IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'CDRGEV', INFO +* +* Blocked version +* + CALL CDRGEV3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ A( 1, 9 ), NMAX, DC( 1, 1 ), DC( 1, 2 ), + $ DC( 1, 3 ), DC( 1, 4 ), WORK, LWORK, RWORK, + $ RESULT, INFO ) + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'CDRGEV3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2388,7 +2417,7 @@ 9999 FORMAT( / ' Execution not attempted due to input errors' ) 9997 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4 ) 9996 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NS =', I4, - $ ', MAXB =', I4, ', NBCOL =', I4 ) + $ ', MAXB =', I4, ', IACC22 =', I4, ', NBCOL =', I4 ) 9995 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4, $ ', NRHS =', I4 ) 9994 FORMAT( / / ' End of tests' ) diff --git a/TESTING/EIG/cdrges3.f b/TESTING/EIG/cdrges3.f new file mode 100644 index 00000000..0ef33dfd --- /dev/null +++ b/TESTING/EIG/cdrges3.f @@ -0,0 +1,940 @@ +*> \brief \b CDRGES3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE CDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHA, +* BETA, WORK, LWORK, RWORK, RESULT, BWORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES +* REAL THRESH +* .. +* .. Array Arguments .. +* LOGICAL BWORK( * ), DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* REAL RESULT( 13 ), RWORK( * ) +* COMPLEX A( LDA, * ), ALPHA( * ), B( LDA, * ), +* $ BETA( * ), Q( LDQ, * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> CDRGES3 checks the nonsymmetric generalized eigenvalue (Schur form) +*> problem driver CGGES3. +*> +*> CGGES3 factors A and B as Q*S*Z' and Q*T*Z' , where ' means conjugate +*> transpose, S and T are upper triangular (i.e., in generalized Schur +*> form), and Q and Z are unitary. It also computes the generalized +*> eigenvalues (alpha(j),beta(j)), j=1,...,n. Thus, +*> w(j) = alpha(j)/beta(j) is a root of the characteristic equation +*> +*> det( A - w(j) B ) = 0 +*> +*> Optionally it also reorder the eigenvalues so that a selected +*> cluster of eigenvalues appears in the leading diagonal block of the +*> Schur forms. +*> +*> When CDRGES3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following 13 tests +*> will be performed and compared with the threshhold THRESH except +*> the tests (5), (11) and (13). +*> +*> +*> (1) | A - Q S Z' | / ( |A| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (2) | B - Q T Z' | / ( |B| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (3) | I - QQ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> +*> (4) | I - ZZ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> (5) if A is in Schur form (i.e. triangular form) (no sorting of +*> eigenvalues) +*> +*> (6) if eigenvalues = diagonal elements of the Schur form (S, T), +*> i.e., test the maximum over j of D(j) where: +*> +*> |alpha(j) - S(j,j)| |beta(j) - T(j,j)| +*> D(j) = ------------------------ + ----------------------- +*> max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|) +*> +*> (no sorting of eigenvalues) +*> +*> (7) | (A,B) - Q (S,T) Z' | / ( |(A,B)| n ulp ) +*> (with sorting of eigenvalues). +*> +*> (8) | I - QQ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (9) | I - ZZ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (10) if A is in Schur form (i.e. quasi-triangular form) +*> (with sorting of eigenvalues). +*> +*> (11) if eigenvalues = diagonal elements of the Schur form (S, T), +*> i.e. test the maximum over j of D(j) where: +*> +*> |alpha(j) - S(j,j)| |beta(j) - T(j,j)| +*> D(j) = ------------------------ + ----------------------- +*> max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|) +*> +*> (with sorting of eigenvalues). +*> +*> (12) if sorting worked and SDIM is the number of eigenvalues +*> which were CELECTed. +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> SDRGES3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, SDRGES3 +*> 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 on input. +*> This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and +*> DOTYPE(MAXTYP+1) is .TRUE. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 SDRGES3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is 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. THRESH >= 0. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IINFO not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is COMPLEX 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is COMPLEX 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is COMPLEX array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by CGGES3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is COMPLEX array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by CGGES3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is COMPLEX array, dimension (LDQ, max(NN)) +*> The (left) orthogonal matrix computed by CGGES3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is COMPLEX array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by CGGES3. +*> \endverbatim +*> +*> \param[out] ALPHA +*> \verbatim +*> ALPHA is COMPLEX array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is COMPLEX array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by CGGES3. +*> ALPHA(k) / BETA(k) is the k-th generalized eigenvalue of A +*> and B. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is COMPLEX array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. LWORK >= 3*N*N. +*> \endverbatim +*> +*> \param[out] RWORK +*> \verbatim +*> RWORK is REAL array, dimension ( 8*N ) +*> Real workspace. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is REAL array, dimension (15) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] BWORK +*> \verbatim +*> BWORK is LOGICAL array, dimension (N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup complex_eig +* +* ===================================================================== + SUBROUTINE CDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHA, + $ BETA, WORK, LWORK, RWORK, RESULT, BWORK, + $ INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES + REAL THRESH +* .. +* .. Array Arguments .. + LOGICAL BWORK( * ), DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + REAL RESULT( 13 ), RWORK( * ) + COMPLEX A( LDA, * ), ALPHA( * ), B( LDA, * ), + $ BETA( * ), Q( LDQ, * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + REAL ZERO, ONE + PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) + COMPLEX CZERO, CONE + PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ), + $ CONE = ( 1.0E+0, 0.0E+0 ) ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN, ILABAD + CHARACTER SORT + INTEGER I, IADD, IINFO, IN, ISORT, J, JC, JR, JSIZE, + $ JTYPE, KNTEIG, MAXWRK, MINWRK, MTYPES, N, N1, + $ NB, NERRS, NMATS, NMAX, NTEST, NTESTT, RSUB, + $ SDIM + REAL SAFMAX, SAFMIN, TEMP1, TEMP2, ULP, ULPINV + COMPLEX CTEMP, X +* .. +* .. Local Arrays .. + LOGICAL LASIGN( MAXTYP ), LBSIGN( MAXTYP ) + INTEGER IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + REAL RMAGN( 0: 3 ) +* .. +* .. External Functions .. + LOGICAL CLCTES + INTEGER ILAENV + REAL SLAMCH + COMPLEX CLARND + EXTERNAL CLCTES, ILAENV, SLAMCH, CLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, CGET51, CGET54, CGGES3, CLACPY, CLARFG, + $ CLASET, CLATM4, CUNM2R, SLABAD, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, AIMAG, CONJG, MAX, MIN, REAL, SIGN +* .. +* .. Statement Functions .. + REAL ABS1 +* .. +* .. Statement Function definitions .. + ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) ) +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA LASIGN / 6*.FALSE., .TRUE., .FALSE., 2*.TRUE., + $ 2*.FALSE., 3*.TRUE., .FALSE., .TRUE., + $ 3*.FALSE., 5*.TRUE., .FALSE. / + DATA LBSIGN / 7*.FALSE., .TRUE., 2*.FALSE., + $ 2*.TRUE., 2*.FALSE., .TRUE., .FALSE., .TRUE., + $ 9*.FALSE. / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = 3*NMAX*NMAX + NB = MAX( 1, ILAENV( 1, 'CGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'CUNMQR', 'LC', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'CUNGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( NMAX+NMAX*NB, 3*NMAX*NMAX) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -19 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'CDRGES3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + ULP = SLAMCH( 'Precision' ) + SAFMIN = SLAMCH( 'Safe minimum' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL SLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over matrix sizes +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 190 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / REAL( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*REAL( N1 ) +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* +* Loop over matrix types +* + DO 180 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 180 + NMATS = NMATS + 1 + NTEST = 0 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Initialize RESULT +* + DO 30 J = 1, 13 + RESULT( J ) = ZERO + 30 CONTINUE +* +* Generate test matrices 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 CLATM4 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. +* LASIGN: .TRUE. if the diagonal elements of A are to be +* multiplied by a random magnitude 1 number. +* KBTYPE, KBZERO, KBMAGN, LBSIGN: 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.GT.MAXTYP ) + $ GO TO 110 + IINFO = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL CLASET( 'Full', N, N, CZERO, CZERO, A, LDA ) + ELSE + IN = N + END IF + CALL CLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), LASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = RMAGN( KAMAGN( JTYPE ) ) +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL CLASET( 'Full', N, N, CZERO, CZERO, B, LDA ) + ELSE + IN = N + END IF + CALL CLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), LBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = RMAGN( KBMAGN( JTYPE ) ) +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 50 JC = 1, N - 1 + DO 40 JR = JC, N + Q( JR, JC ) = CLARND( 3, ISEED ) + Z( JR, JC ) = CLARND( 3, ISEED ) + 40 CONTINUE + CALL CLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, REAL( Q( JC, JC ) ) ) + Q( JC, JC ) = CONE + CALL CLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, REAL( Z( JC, JC ) ) ) + Z( JC, JC ) = CONE + 50 CONTINUE + CTEMP = CLARND( 3, ISEED ) + Q( N, N ) = CONE + WORK( N ) = CZERO + WORK( 3*N ) = CTEMP / ABS( CTEMP ) + CTEMP = CLARND( 3, ISEED ) + Z( N, N ) = CONE + WORK( 2*N ) = CZERO + WORK( 4*N ) = CTEMP / ABS( CTEMP ) +* +* Apply the diagonal matrices +* + DO 70 JC = 1, N + DO 60 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )* + $ CONJG( WORK( 3*N+JC ) )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )* + $ CONJG( WORK( 3*N+JC ) )* + $ B( JR, JC ) + 60 CONTINUE + 70 CONTINUE + CALL CUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL CUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL CUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL CUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + END IF + ELSE +* +* Random matrices +* + DO 90 JC = 1, N + DO 80 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ CLARND( 4, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ CLARND( 4, ISEED ) + 80 CONTINUE + 90 CONTINUE + END IF +* + 100 CONTINUE +* + IF( IINFO.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + RETURN + END IF +* + 110 CONTINUE +* + DO 120 I = 1, 13 + RESULT( I ) = -ONE + 120 CONTINUE +* +* Test with and without sorting of eigenvalues +* + DO 150 ISORT = 0, 1 + IF( ISORT.EQ.0 ) THEN + SORT = 'N' + RSUB = 0 + ELSE + SORT = 'S' + RSUB = 5 + END IF +* +* Call CGGES3 to compute H, T, Q, Z, alpha, and beta. +* + CALL CLACPY( 'Full', N, N, A, LDA, S, LDA ) + CALL CLACPY( 'Full', N, N, B, LDA, T, LDA ) + NTEST = 1 + RSUB + ISORT + RESULT( 1+RSUB+ISORT ) = ULPINV + CALL CGGES3( 'V', 'V', SORT, CLCTES, N, S, LDA, T, LDA, + $ SDIM, ALPHA, BETA, Q, LDQ, Z, LDQ, WORK, + $ LWORK, RWORK, BWORK, IINFO ) + IF( IINFO.NE.0 .AND. IINFO.NE.N+2 ) THEN + RESULT( 1+RSUB+ISORT ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'CGGES3', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + GO TO 160 + END IF +* + NTEST = 4 + RSUB +* +* Do tests 1--4 (or tests 7--9 when reordering ) +* + IF( ISORT.EQ.0 ) THEN + CALL CGET51( 1, N, A, LDA, S, LDA, Q, LDQ, Z, LDQ, + $ WORK, RWORK, RESULT( 1 ) ) + CALL CGET51( 1, N, B, LDA, T, LDA, Q, LDQ, Z, LDQ, + $ WORK, RWORK, RESULT( 2 ) ) + ELSE + CALL CGET54( N, A, LDA, B, LDA, S, LDA, T, LDA, Q, + $ LDQ, Z, LDQ, WORK, RESULT( 2+RSUB ) ) + END IF +* + CALL CGET51( 3, N, B, LDA, T, LDA, Q, LDQ, Q, LDQ, WORK, + $ RWORK, RESULT( 3+RSUB ) ) + CALL CGET51( 3, N, B, LDA, T, LDA, Z, LDQ, Z, LDQ, WORK, + $ RWORK, RESULT( 4+RSUB ) ) +* +* Do test 5 and 6 (or Tests 10 and 11 when reordering): +* check Schur form of A and compare eigenvalues with +* diagonals. +* + NTEST = 6 + RSUB + TEMP1 = ZERO +* + DO 130 J = 1, N + ILABAD = .FALSE. + TEMP2 = ( ABS1( ALPHA( J )-S( J, J ) ) / + $ MAX( SAFMIN, ABS1( ALPHA( J ) ), ABS1( S( J, + $ J ) ) )+ABS1( BETA( J )-T( J, J ) ) / + $ MAX( SAFMIN, ABS1( BETA( J ) ), ABS1( T( J, + $ J ) ) ) ) / ULP +* + IF( J.LT.N ) THEN + IF( S( J+1, J ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( J.GT.1 ) THEN + IF( S( J, J-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + TEMP1 = MAX( TEMP1, TEMP2 ) + IF( ILABAD ) THEN + WRITE( NOUNIT, FMT = 9998 )J, N, JTYPE, IOLDSD + END IF + 130 CONTINUE + RESULT( 6+RSUB ) = TEMP1 +* + IF( ISORT.GE.1 ) THEN +* +* Do test 12 +* + NTEST = 12 + RESULT( 12 ) = ZERO + KNTEIG = 0 + DO 140 I = 1, N + IF( CLCTES( ALPHA( I ), BETA( I ) ) ) + $ KNTEIG = KNTEIG + 1 + 140 CONTINUE + IF( SDIM.NE.KNTEIG ) + $ RESULT( 13 ) = ULPINV + END IF +* + 150 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 160 CONTINUE +* + NTESTT = NTESTT + NTEST +* +* Print out tests which fail. +* + DO 170 JR = 1, NTEST + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'CGS' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Unitary' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 )'unitary', '''', + $ 'transpose', ( '''', J = 1, 8 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 170 CONTINUE +* + 180 CONTINUE + 190 CONTINUE +* +* Summary +* + CALL ALASVM( 'CGS', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' CDRGES3: ', A, ' returned INFO=', I6, '.', / 9X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' CDRGES3: S not in Schur form at eigenvalue ', I6, '.', + $ / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), + $ I5, ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Complex Generalized Schur from problem ', + $ 'driver' ) +* + 9996 FORMAT( ' Matrix types (see CDRGES3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: (S is Schur, T is triangular, ', + $ 'Q and Z are ', A, ',', / 19X, + $ 'l and r are the appropriate left and right', / 19X, + $ 'eigenvectors, resp., a is alpha, b is beta, and', / 19X, A, + $ ' means ', A, '.)', / ' Without ordering: ', + $ / ' 1 = | A - Q S Z', A, + $ ' | / ( |A| n ulp ) 2 = | B - Q T Z', A, + $ ' | / ( |B| n ulp )', / ' 3 = | I - QQ', A, + $ ' | / ( n ulp ) 4 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 5 = A is in Schur form S', + $ / ' 6 = difference between (alpha,beta)', + $ ' and diagonals of (S,T)', / ' With ordering: ', + $ / ' 7 = | (A,B) - Q (S,T) Z', A, ' | / ( |(A,B)| n ulp )', + $ / ' 8 = | I - QQ', A, + $ ' | / ( n ulp ) 9 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 10 = A is in Schur form S', + $ / ' 11 = difference between (alpha,beta) and diagonals', + $ ' of (S,T)', / ' 12 = SDIM is the correct number of ', + $ 'selected eigenvalues', / ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, E10.3 ) +* +* End of CDRGES3 +* + END diff --git a/TESTING/EIG/cdrgev3.f b/TESTING/EIG/cdrgev3.f new file mode 100644 index 00000000..a38882fc --- /dev/null +++ b/TESTING/EIG/cdrgev3.f @@ -0,0 +1,943 @@ +*> \brief \b CDRGEV3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE CDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, +* ALPHA, BETA, ALPHA1, BETA1, WORK, LWORK, RWORK, +* RESULT, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, +* $ NTYPES +* REAL THRESH +* .. +* .. Array Arguments .. +* LOGICAL DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* REAL RESULT( * ), RWORK( * ) +* COMPLEX A( LDA, * ), ALPHA( * ), ALPHA1( * ), +* $ B( LDA, * ), BETA( * ), BETA1( * ), +* $ Q( LDQ, * ), QE( LDQE, * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> CDRGEV3 checks the nonsymmetric generalized eigenvalue problem driver +*> routine CGGEV3. +*> +*> CGGEV3 computes for a pair of n-by-n nonsymmetric matrices (A,B) the +*> generalized eigenvalues and, optionally, the left and right +*> eigenvectors. +*> +*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w +*> or a ratio alpha/beta = w, such that A - w*B is singular. It is +*> usually represented as the pair (alpha,beta), as there is reasonable +*> interpretation for beta=0, and even for both being zero. +*> +*> A right generalized eigenvector corresponding to a generalized +*> eigenvalue w for a pair of matrices (A,B) is a vector r such that +*> (A - wB) * r = 0. A left generalized eigenvector is a vector l such +*> that l**H * (A - wB) = 0, where l**H is the conjugate-transpose of l. +*> +*> When CDRGEV3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following tests +*> will be performed and compared with the threshhold THRESH. +*> +*> Results from CGGEV3: +*> +*> (1) max over all left eigenvalue/-vector pairs (alpha/beta,l) of +*> +*> | VL**H * (beta A - alpha B) |/( ulp max(|beta A|, |alpha B|) ) +*> +*> where VL**H is the conjugate-transpose of VL. +*> +*> (2) | |VL(i)| - 1 | / ulp and whether largest component real +*> +*> VL(i) denotes the i-th column of VL. +*> +*> (3) max over all left eigenvalue/-vector pairs (alpha/beta,r) of +*> +*> | (beta A - alpha B) * VR | / ( ulp max(|beta A|, |alpha B|) ) +*> +*> (4) | |VR(i)| - 1 | / ulp and whether largest component real +*> +*> VR(i) denotes the i-th column of VR. +*> +*> (5) W(full) = W(partial) +*> W(full) denotes the eigenvalues computed when both l and r +*> are also computed, and W(partial) denotes the eigenvalues +*> computed when only W, only W and r, or only W and l are +*> computed. +*> +*> (6) VL(full) = VL(partial) +*> VL(full) denotes the left eigenvectors computed when both l +*> and r are computed, and VL(partial) denotes the result +*> when only l is computed. +*> +*> (7) VR(full) = VR(partial) +*> VR(full) denotes the right eigenvectors computed when both l +*> and r are also computed, and VR(partial) denotes the result +*> when only l is computed. +*> +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> CDRGEV3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, CDRGEV3 +*> 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. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 CDRGEV3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is 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. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IERR not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is COMPLEX 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is COMPLEX 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is COMPLEX array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by CGGEV3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is COMPLEX array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by CGGEV3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is COMPLEX array, dimension (LDQ, max(NN)) +*> The (left) eigenvectors matrix computed by CGGEV3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is COMPLEX array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by CGGEV3. +*> \endverbatim +*> +*> \param[out] QE +*> \verbatim +*> QE is COMPLEX array, dimension( LDQ, max(NN) ) +*> QE holds the computed right or left eigenvectors. +*> \endverbatim +*> +*> \param[in] LDQE +*> \verbatim +*> LDQE is INTEGER +*> The leading dimension of QE. LDQE >= max(1,max(NN)). +*> \endverbatim +*> +*> \param[out] ALPHA +*> \verbatim +*> ALPHA is COMPLEX array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is COMPLEX array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by CGGEV3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] ALPHA1 +*> \verbatim +*> ALPHA1 is COMPLEX array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA1 +*> \verbatim +*> BETA1 is COMPLEX array, dimension (max(NN)) +*> +*> Like ALPHAR, ALPHAI, BETA, these arrays contain the +*> eigenvalues of A and B, but those computed when CGGEV3 only +*> computes a partial eigendecomposition, i.e. not the +*> eigenvalues and left and right eigenvectors. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is COMPLEX array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The number of entries in WORK. LWORK >= N*(N+1) +*> \endverbatim +*> +*> \param[out] RWORK +*> \verbatim +*> RWORK is REAL array, dimension (8*N) +*> Real workspace. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is REAL array, dimension (2) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date January 2015 +* +*> \ingroup complex_eig +* +* ===================================================================== + SUBROUTINE CDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, + $ ALPHA, BETA, ALPHA1, BETA1, WORK, LWORK, + $ RWORK, RESULT, INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* January 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, + $ NTYPES + REAL THRESH +* .. +* .. Array Arguments .. + LOGICAL DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + REAL RESULT( * ), RWORK( * ) + COMPLEX A( LDA, * ), ALPHA( * ), ALPHA1( * ), + $ B( LDA, * ), BETA( * ), BETA1( * ), + $ Q( LDQ, * ), QE( LDQE, * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + REAL ZERO, ONE + PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) + COMPLEX CZERO, CONE + PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ), + $ CONE = ( 1.0E+0, 0.0E+0 ) ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN + INTEGER I, IADD, IERR, IN, J, JC, JR, JSIZE, JTYPE, + $ MAXWRK, MINWRK, MTYPES, N, N1, NB, NERRS, + $ NMATS, NMAX, NTESTT + REAL SAFMAX, SAFMIN, ULP, ULPINV + COMPLEX CTEMP +* .. +* .. Local Arrays .. + LOGICAL LASIGN( MAXTYP ), LBSIGN( MAXTYP ) + INTEGER IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + REAL RMAGN( 0: 3 ) +* .. +* .. External Functions .. + INTEGER ILAENV + REAL SLAMCH + COMPLEX CLARND + EXTERNAL ILAENV, SLAMCH, CLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, CGET52, CGGEV3, CLACPY, CLARFG, CLASET, + $ CLATM4, CUNM2R, SLABAD, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, CONJG, MAX, MIN, REAL, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA LASIGN / 6*.FALSE., .TRUE., .FALSE., 2*.TRUE., + $ 2*.FALSE., 3*.TRUE., .FALSE., .TRUE., + $ 3*.FALSE., 5*.TRUE., .FALSE. / + DATA LBSIGN / 7*.FALSE., .TRUE., 2*.FALSE., + $ 2*.TRUE., 2*.FALSE., .TRUE., .FALSE., .TRUE., + $ 9*.FALSE. / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + ELSE IF( LDQE.LE.1 .OR. LDQE.LT.NMAX ) THEN + INFO = -17 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = NMAX*( NMAX+1 ) + NB = MAX( 1, ILAENV( 1, 'CGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'CUNMQR', 'LC', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'CUNGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( 2*NMAX, NMAX*( NB+1 ), NMAX*( NMAX+1 ) ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -23 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'CDRGEV3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + ULP = SLAMCH( 'Precision' ) + SAFMIN = SLAMCH( 'Safe minimum' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL SLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over sizes, types +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 220 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / REAL( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*N1 +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* + DO 210 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 210 + NMATS = NMATS + 1 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Generate test matrices 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 CLATM4 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. +* LASIGN: .TRUE. if the diagonal elements of A are to be +* multiplied by a random magnitude 1 number. +* KBTYPE, KBZERO, KBMAGN, LBSIGN: 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.GT.MAXTYP ) + $ GO TO 100 + IERR = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL CLASET( 'Full', N, N, CZERO, CZERO, A, LDA ) + ELSE + IN = N + END IF + CALL CLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), LASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = RMAGN( KAMAGN( JTYPE ) ) +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL CLASET( 'Full', N, N, CZERO, CZERO, B, LDA ) + ELSE + IN = N + END IF + CALL CLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), LBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = RMAGN( KBMAGN( JTYPE ) ) +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 40 JC = 1, N - 1 + DO 30 JR = JC, N + Q( JR, JC ) = CLARND( 3, ISEED ) + Z( JR, JC ) = CLARND( 3, ISEED ) + 30 CONTINUE + CALL CLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, REAL( Q( JC, JC ) ) ) + Q( JC, JC ) = CONE + CALL CLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, REAL( Z( JC, JC ) ) ) + Z( JC, JC ) = CONE + 40 CONTINUE + CTEMP = CLARND( 3, ISEED ) + Q( N, N ) = CONE + WORK( N ) = CZERO + WORK( 3*N ) = CTEMP / ABS( CTEMP ) + CTEMP = CLARND( 3, ISEED ) + Z( N, N ) = CONE + WORK( 2*N ) = CZERO + WORK( 4*N ) = CTEMP / ABS( CTEMP ) +* +* Apply the diagonal matrices +* + DO 60 JC = 1, N + DO 50 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )* + $ CONJG( WORK( 3*N+JC ) )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )* + $ CONJG( WORK( 3*N+JC ) )* + $ B( JR, JC ) + 50 CONTINUE + 60 CONTINUE + CALL CUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL CUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL CUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL CUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + END IF + ELSE +* +* Random matrices +* + DO 80 JC = 1, N + DO 70 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ CLARND( 4, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ CLARND( 4, ISEED ) + 70 CONTINUE + 80 CONTINUE + END IF +* + 90 CONTINUE +* + IF( IERR.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + RETURN + END IF +* + 100 CONTINUE +* + DO 110 I = 1, 7 + RESULT( I ) = -ONE + 110 CONTINUE +* +* Call CGGEV3 to compute eigenvalues and eigenvectors. +* + CALL CLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL CLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL CGGEV3( 'V', 'V', N, S, LDA, T, LDA, ALPHA, BETA, Q, + $ LDQ, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'CGGEV31', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* +* Do the tests (1) and (2) +* + CALL CGET52( .TRUE., N, A, LDA, B, LDA, Q, LDQ, ALPHA, BETA, + $ WORK, RWORK, RESULT( 1 ) ) + IF( RESULT( 2 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Left', 'CGGEV31', + $ RESULT( 2 ), N, JTYPE, IOLDSD + END IF +* +* Do the tests (3) and (4) +* + CALL CGET52( .FALSE., N, A, LDA, B, LDA, Z, LDQ, ALPHA, + $ BETA, WORK, RWORK, RESULT( 3 ) ) + IF( RESULT( 4 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Right', 'CGGEV31', + $ RESULT( 4 ), N, JTYPE, IOLDSD + END IF +* +* Do test (5) +* + CALL CLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL CLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL CGGEV3( 'N', 'N', N, S, LDA, T, LDA, ALPHA1, BETA1, Q, + $ LDQ, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'CGGEV32', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 120 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. BETA( J ).NE. + $ BETA1( J ) ) RESULT( 5 ) = ULPINV + 120 CONTINUE +* +* Do the test (6): Compute eigenvalues and left eigenvectors, +* and test them +* + CALL CLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL CLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL CGGEV3( 'V', 'N', N, S, LDA, T, LDA, ALPHA1, BETA1, QE, + $ LDQE, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'CGGEV33', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF + +* + DO 130 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. + $ BETA( J ).NE.BETA1( J ) ) THEN + RESULT( 6 ) = ULPINV + ENDIF + 130 CONTINUE +* + DO 150 J = 1, N + DO 140 JC = 1, N + IF( Q( J, JC ).NE.QE( J, JC ) ) THEN + RESULT( 6 ) = ULPINV + END IF + 140 CONTINUE + 150 CONTINUE +* +* DO the test (7): Compute eigenvalues and right eigenvectors, +* and test them +* + CALL CLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL CLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL CGGEV3( 'N', 'V', N, S, LDA, T, LDA, ALPHA1, BETA1, Q, + $ LDQ, QE, LDQE, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'CGGEV34', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 160 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. BETA( J ).NE. + $ BETA1( J ) )RESULT( 7 ) = ULPINV + 160 CONTINUE +* + DO 180 J = 1, N + DO 170 JC = 1, N + IF( Z( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 7 ) = ULPINV + 170 CONTINUE + 180 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 190 CONTINUE +* + NTESTT = NTESTT + 7 +* +* Print out tests which fail. +* + DO 200 JR = 1, 7 + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'CGV' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 200 CONTINUE +* + 210 CONTINUE + 220 CONTINUE +* +* Summary +* + CALL ALASVM( 'CGV3', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' CDRGEV3: ', A, ' returned INFO=', I6, '.', / 3X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), I5, ')' ) +* + 9998 FORMAT( ' CDRGEV3: ', A, ' Eigenvectors from ', A, ' incorrectly ', + $ 'normalized.', / ' Bits of error=', 0P, G10.3, ',', 3X, + $ 'N=', I4, ', JTYPE=', I3, ', ISEED=(', 3( I4, ',' ), I5, + $ ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Complex Generalized eigenvalue problem ', + $ 'driver' ) +* + 9996 FORMAT( ' Matrix types (see CDRGEV3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: ', + $ / ' 1 = max | ( b A - a B )''*l | / const.,', + $ / ' 2 = | |VR(i)| - 1 | / ulp,', + $ / ' 3 = max | ( b A - a B )*r | / const.', + $ / ' 4 = | |VL(i)| - 1 | / ulp,', + $ / ' 5 = 0 if W same no matter if r or l computed,', + $ / ' 6 = 0 if l same no matter if l computed,', + $ / ' 7 = 0 if r same no matter if r computed,', / 1X ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, E10.3 ) +* +* End of CDRGEV3 +* + END diff --git a/TESTING/EIG/cerrgg.f b/TESTING/EIG/cerrgg.f index a768fe11..6f7e0508 100644 --- a/TESTING/EIG/cerrgg.f +++ b/TESTING/EIG/cerrgg.f @@ -2,19 +2,19 @@ * * =========== DOCUMENTATION =========== * -* Online html documentation available at -* http://www.netlib.org/lapack/explore-html/ +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE CERRGG( PATH, NUNIT ) -* +* * .. Scalar Arguments .. * CHARACTER*3 PATH * INTEGER NUNIT * .. -* +* * *> \par Purpose: * ============= @@ -22,8 +22,9 @@ *> \verbatim *> *> CERRGG tests the error exits for CGGES, CGGESX, CGGEV, CGGEVX, -*> CGGGLM, CGGHRD, CGGLSE, CGGQRF, CGGRQF, CGGSVD, CGGSVP, CHGEQZ, -*> CTGEVC, CTGEXC, CTGSEN, CTGSJA, CTGSNA, CTGSYL and CUNCSD. +*> CGGES3, CGGEV3, CGGGLM, CGGHRD, CGGLSE, CGGQRF, CGGRQF, CGGSVD, +*> CGGSVP, CHGEQZ, CTGEVC, CTGEXC, CTGSEN, CTGSJA, CTGSNA, CTGSYL, +*> and CUNCSD. *> \endverbatim * * Arguments: @@ -44,10 +45,10 @@ * Authors: * ======== * -*> \author Univ. of Tennessee -*> \author Univ. of California Berkeley -*> \author Univ. of Colorado Denver -*> \author NAG Ltd. +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. * *> \date November 2011 * @@ -98,7 +99,7 @@ EXTERNAL CGGES, CGGESX, CGGEV, CGGEVX, CGGGLM, CGGHRD, $ CGGLSE, CGGQRF, CGGRQF, CGGSVD, CGGSVP, CHGEQZ, $ CHKXER, CTGEVC, CTGEXC, CTGSEN, CTGSJA, CTGSNA, - $ CTGSYL, CUNCSD + $ CTGSYL, CUNCSD, CGGES3, CGGEV3, CGGHD3 * .. * .. Scalars in Common .. LOGICAL LERR, OK @@ -171,6 +172,47 @@ CALL CHKXER( 'CGGHRD', INFOT, NOUT, LERR, OK ) NT = NT + 9 * +* CGGHD3 +* + SRNAMT = 'CGGHD3' + INFOT = 1 + CALL CGGHD3( '/', 'N', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL CGGHD3( 'N', '/', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL CGGHD3( 'N', 'N', -1, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 4 + CALL CGGHD3( 'N', 'N', 0, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL CGGHD3( 'N', 'N', 0, 1, 1, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL CGGHD3( 'N', 'N', 2, 1, 1, A, 1, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL CGGHD3( 'N', 'N', 2, 1, 1, A, 2, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL CGGHD3( 'V', 'N', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL CGGHD3( 'N', 'V', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'CGGHD3', INFOT, NOUT, LERR, OK ) + NT = NT + 9 +* * CHGEQZ * SRNAMT = 'CHGEQZ' @@ -520,56 +562,56 @@ $ -1, 0, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 8 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, -1, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 9 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, -1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 11 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, -1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 20 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, -1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 22 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, -1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 24 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, -1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 26 CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ -1, W, LW, RW, LW, IW, INFO ) + $ -1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'CUNCSD', INFOT, NOUT, LERR, OK ) NT = NT + 8 * @@ -679,6 +721,55 @@ CALL CHKXER( 'CGGES ', INFOT, NOUT, LERR, OK ) NT = NT + 11 * +* CGGES3 +* + SRNAMT = 'CGGES3' + INFOT = 1 + CALL CGGES3( '/', 'N', 'S', CLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL CGGES3( 'N', '/', 'S', CLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL CGGES3( 'N', 'V', '/', CLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL CGGES3( 'N', 'V', 'S', CLCTES, -1, A, 1, B, 1, SDIM, + $ ALPHA, BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL CGGES3( 'N', 'V', 'S', CLCTES, 1, A, 0, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL CGGES3( 'N', 'V', 'S', CLCTES, 1, A, 1, B, 0, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL CGGES3( 'N', 'V', 'S', CLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 0, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL CGGES3( 'V', 'V', 'S', CLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 1, U, 2, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL CGGES3( 'N', 'V', 'S', CLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 0, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL CGGES3( 'V', 'V', 'S', CLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 2, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 18 + CALL CGGES3( 'V', 'V', 'S', CLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 2, U, 2, W, 1, RW, BW, INFO ) + CALL CHKXER( 'CGGES3', INFOT, NOUT, LERR, OK ) + NT = NT + 11 +* * CGGESX * SRNAMT = 'CGGESX' @@ -794,6 +885,51 @@ CALL CHKXER( 'CGGEV ', INFOT, NOUT, LERR, OK ) NT = NT + 10 * +* CGGEV3 +* + SRNAMT = 'CGGEV3' + INFOT = 1 + CALL CGGEV3( '/', 'N', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL CGGEV3( 'N', '/', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL CGGEV3( 'V', 'V', -1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL CGGEV3( 'V', 'V', 1, A, 0, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL CGGEV3( 'V', 'V', 1, A, 1, B, 0, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL CGGEV3( 'N', 'V', 1, A, 1, B, 1, ALPHA, BETA, Q, 0, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL CGGEV3( 'V', 'V', 2, A, 2, B, 2, ALPHA, BETA, Q, 1, U, 2, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL CGGEV3( 'V', 'N', 2, A, 2, B, 2, ALPHA, BETA, Q, 2, U, 0, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL CGGEV3( 'V', 'V', 2, A, 2, B, 2, ALPHA, BETA, Q, 2, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL CGGEV3( 'V', 'V', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'CGGEV3', INFOT, NOUT, LERR, OK ) + NT = NT + 10 +* * CGGEVX * SRNAMT = 'CGGEVX' diff --git a/TESTING/EIG/dchkee.f b/TESTING/EIG/dchkee.f index 2123aa76..8a29cc1a 100644 --- a/TESTING/EIG/dchkee.f +++ b/TESTING/EIG/dchkee.f @@ -2,14 +2,14 @@ * * =========== DOCUMENTATION =========== * -* Online html documentation available at -* http://www.netlib.org/lapack/explore-html/ +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * PROGRAM DCHKEE -* +* * *> \par Purpose: * ============= @@ -44,7 +44,7 @@ *> Test DGEESX *> *> DGG (Generalized Nonsymmetric Eigenvalue Problem): -*> Test DGGHRD, DGGBAL, DGGBAK, DHGEQZ, and DTGEVC +*> Test DGGHD3, DGGBAL, DGGBAK, DHGEQZ, and DTGEVC *> and the driver routines DGEGS and DGEGV *> *> DGS (Generalized Nonsymmetric Schur form Driver): @@ -493,38 +493,41 @@ *> line 8: MXBVAL, INTEGER array, dimension (NPARMS) *> The values for MAXB, used in determining minimum blocksize. *> -*> line 9: NBCOL, INTEGER array, dimension (NPARMS) +*> line 9: IACC22, INTEGER array, dimension (NPARMS) +*> select structured matrix multiply: 1 or 2) +*> +*> line 10: NBCOL, INTEGER array, dimension (NPARMS) *> The values for NBCOL, the minimum column dimension for *> blocks. *> -*> line 10: THRESH +*> line 11: THRESH *> Threshold value for the test ratios. Information will be *> printed about each test for which the test ratio is greater *> than or equal to the threshold. *> -*> line 11: TSTCHK, LOGICAL +*> line 12: TSTCHK, LOGICAL *> Flag indicating whether or not to test the LAPACK routines. *> -*> line 12: TSTDRV, LOGICAL +*> line 13: TSTDRV, LOGICAL *> Flag indicating whether or not to test the driver routines. *> -*> line 13: TSTERR, LOGICAL +*> line 14: TSTERR, LOGICAL *> Flag indicating whether or not to test the error exits for *> the LAPACK routines and driver routines. *> -*> line 14: NEWSD, INTEGER +*> line 15: NEWSD, INTEGER *> A code indicating how to set the random number seed. *> = 0: Set the seed to a default value before each run *> = 1: Initialize the seed to a default value only before the *> first run *> = 2: Like 1, but use the seed values on the next line *> -*> If line 14 was 2: +*> If line 15 was 2: *> -*> line 15: INTEGER array, dimension (4) +*> line 16: INTEGER array, dimension (4) *> Four integer values for the random number seed. *> -*> lines 15-EOF: Lines specifying matrix types, as for NEP. +*> lines 17-EOF: Lines specifying matrix types, as for NEP. *> The 3-character path name is 'DGG' for the generalized *> eigenvalue problem routines and driver routines. *> @@ -1027,10 +1030,10 @@ * Authors: * ======== * -*> \author Univ. of Tennessee -*> \author Univ. of California Berkeley -*> \author Univ. of Colorado Denver -*> \author NAG Ltd. +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. * *> \date November 2013 * @@ -1076,7 +1079,7 @@ CHARACTER*80 LINE INTEGER I, I1, IC, INFO, ITMP, K, LENP, MAXTYP, NEWSD, $ NK, NN, NPARMS, NRHS, NTYPES, - $ VERS_MAJOR, VERS_MINOR, VERS_PATCH + $ VERS_MAJOR, VERS_MINOR, VERS_PATCH DOUBLE PRECISION EPS, S1, S2, THRESH, THRSHN * .. * .. Local Arrays .. @@ -1104,7 +1107,8 @@ $ DCKCSD, DCKGLM, DCKGQR, DCKGSV, DCKLSE, DDRGES, $ DDRGEV, DDRGSX, DDRGVX, DDRVBD, DDRVES, DDRVEV, $ DDRVGG, DDRVSG, DDRVST, DDRVSX, DDRVVX, DERRBD, - $ DERRED, DERRGG, DERRHS, DERRST, ILAVER, XLAENV + $ DERRED, DERRGG, DERRHS, DERRST, ILAVER, XLAENV, + $ DDRGES3, DDRGEV3 * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN @@ -1630,7 +1634,7 @@ * * Read the values for IACC22. * - IF( NEP ) THEN + IF( NEP .OR. DGG ) THEN READ( NIN, FMT = * )( IACC22( I ), I = 1, NPARMS ) DO 620 I = 1, NPARMS IF( IACC22( I ).LT.0 ) THEN @@ -2097,6 +2101,7 @@ * NBMIN = minimum block size * NS = number of shifts * MAXB = minimum submatrix size +* IACC22: structured matrix multiply * NBCOL = minimum column dimension for blocks * MAXTYP = 26 @@ -2109,6 +2114,7 @@ CALL XLAENV( 2, NBMIN( I ) ) CALL XLAENV( 4, NSVAL( I ) ) CALL XLAENV( 8, MXBVAL( I ) ) + CALL XLAENV( 16, IACC22( I ) ) CALL XLAENV( 5, NBCOL( I ) ) * IF( NEWSD.EQ.0 ) THEN @@ -2117,7 +2123,7 @@ 340 CONTINUE END IF WRITE( NOUT, FMT = 9996 )C3, NBVAL( I ), NBMIN( I ), - $ NSVAL( I ), MXBVAL( I ), NBCOL( I ) + $ NSVAL( I ), MXBVAL( I ), IACC22( I ), NBCOL( I ) TSTDIF = .FALSE. THRSHN = 10.D0 IF( TSTCHK ) THEN @@ -2167,9 +2173,18 @@ $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), $ D( 1, 1 ), D( 1, 2 ), D( 1, 3 ), WORK, LWORK, $ RESULT, LOGWRK, INFO ) + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'DDRGES', INFO * +* Blocked version +* + CALL DDRGES3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ D( 1, 1 ), D( 1, 2 ), D( 1, 3 ), WORK, LWORK, + $ RESULT, LOGWRK, INFO ) IF( INFO.NE.0 ) - $ WRITE( NOUT, FMT = 9980 )'DDRGES', INFO + $ WRITE( NOUT, FMT = 9980 )'DDRGES3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2224,6 +2239,17 @@ $ WORK, LWORK, RESULT, INFO ) IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'DDRGEV', INFO +* +* Blocked version +* + CALL DDRGEV3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ A( 1, 9 ), NMAX, D( 1, 1 ), D( 1, 2 ), + $ D( 1, 3 ), D( 1, 4 ), D( 1, 5 ), D( 1, 6 ), + $ WORK, LWORK, RESULT, INFO ) + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'DDRGEV3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2395,7 +2421,7 @@ 9999 FORMAT( / ' Execution not attempted due to input errors' ) 9997 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4 ) 9996 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NS =', I4, - $ ', MAXB =', I4, ', NBCOL =', I4 ) + $ ', MAXB =', I4, ', IACC22 =', I4, ', NBCOL =', I4 ) 9995 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4, $ ', NRHS =', I4 ) 9994 FORMAT( / / ' End of tests' ) @@ -2451,7 +2477,7 @@ 9962 FORMAT( / ' Tests of the Generalized Nonsymmetric Eigenvalue ', $ 'Problem Expert Driver DGGEVX' ) 9961 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4, - $ ', INMIN=', I4, + $ ', INMIN=', I4, $ ', INWIN =', I4, ', INIBL =', I4, ', ISHFTS =', I4, $ ', IACC22 =', I4) 9960 FORMAT( / ' Tests of the CS Decomposition routines' ) diff --git a/TESTING/EIG/ddrges3.f b/TESTING/EIG/ddrges3.f new file mode 100644 index 00000000..77363019 --- /dev/null +++ b/TESTING/EIG/ddrges3.f @@ -0,0 +1,997 @@ +*> \brief \b DDRGES3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHAR, +* ALPHAI, BETA, WORK, LWORK, RESULT, BWORK, +* INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES +* DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. +* LOGICAL BWORK( * ), DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ), +* $ B( LDA, * ), BETA( * ), Q( LDQ, * ), +* $ RESULT( 13 ), S( LDA, * ), T( LDA, * ), +* $ WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DDRGES3 checks the nonsymmetric generalized eigenvalue (Schur form) +*> problem driver DGGES3. +*> +*> DGGES3 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(j),beta(j)), j=1,...,n, +*> Thus, w(j) = alpha(j)/beta(j) is a root of the characteristic +*> equation +*> det( A - w(j) B ) = 0 +*> Optionally it also reorder the eigenvalues so that a selected +*> cluster of eigenvalues appears in the leading diagonal block of the +*> Schur forms. +*> +*> When DDRGES3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following 13 tests +*> will be performed and compared with the threshhold THRESH except +*> the tests (5), (11) and (13). +*> +*> +*> (1) | A - Q S Z' | / ( |A| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (2) | B - Q T Z' | / ( |B| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (3) | I - QQ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> +*> (4) | I - ZZ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> (5) if A is in Schur form (i.e. quasi-triangular form) +*> (no sorting of eigenvalues) +*> +*> (6) if eigenvalues = diagonal blocks of the Schur form (S, T), +*> i.e., test the 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 and j+1-th eigenvalues. +*> (no sorting of eigenvalues) +*> +*> (7) | (A,B) - Q (S,T) Z' | / ( | (A,B) | n ulp ) +*> (with sorting of eigenvalues). +*> +*> (8) | I - QQ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (9) | I - ZZ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (10) if A is in Schur form (i.e. quasi-triangular form) +*> (with sorting of eigenvalues). +*> +*> (11) if eigenvalues = diagonal blocks of the Schur form (S, T), +*> i.e. test the 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 and j+1-th eigenvalues. +*> (with sorting of eigenvalues). +*> +*> (12) if sorting worked and SDIM is the number of eigenvalues +*> which were SELECTed. +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> DDRGES3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, DDRGES3 +*> 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 on input. +*> This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and +*> DOTYPE(MAXTYP+1) is .TRUE. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 DDRGES3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is DOUBLE PRECISION +*> 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. THRESH >= 0. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IINFO not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is DOUBLE PRECISION array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by DGGES3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is DOUBLE PRECISION array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by DGGES3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is DOUBLE PRECISION array, dimension (LDQ, max(NN)) +*> The (left) orthogonal matrix computed by DGGES3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by DGGES3. +*> \endverbatim +*> +*> \param[out] ALPHAR +*> \verbatim +*> ALPHAR is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHAI +*> \verbatim +*> ALPHAI is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by DGGES3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. +*> LWORK >= MAX( 10*(N+1), 3*N*N ), where N is the largest +*> matrix dimension. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is DOUBLE PRECISION array, dimension (15) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] BWORK +*> \verbatim +*> BWORK is LOGICAL array, dimension (N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup double_eig +* +* ===================================================================== + SUBROUTINE DDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHAR, + $ ALPHAI, BETA, WORK, LWORK, RESULT, BWORK, + $ INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES + DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. + LOGICAL BWORK( * ), DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ), + $ B( LDA, * ), BETA( * ), Q( LDQ, * ), + $ RESULT( 13 ), S( LDA, * ), T( LDA, * ), + $ WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN, ILABAD + CHARACTER SORT + INTEGER I, I1, IADD, IERR, IINFO, IN, ISORT, J, JC, JR, + $ JSIZE, JTYPE, KNTEIG, MAXWRK, MINWRK, MTYPES, + $ N, N1, NB, NERRS, NMATS, NMAX, NTEST, NTESTT, + $ RSUB, SDIM + DOUBLE PRECISION SAFMAX, SAFMIN, TEMP1, TEMP2, ULP, ULPINV +* .. +* .. Local Arrays .. + INTEGER IASIGN( MAXTYP ), IBSIGN( MAXTYP ), + $ IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + DOUBLE PRECISION RMAGN( 0: 3 ) +* .. +* .. External Functions .. + LOGICAL DLCTES + INTEGER ILAENV + DOUBLE PRECISION DLAMCH, DLARND + EXTERNAL DLCTES, ILAENV, DLAMCH, DLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, DGET51, DGET53, DGET54, DGGES3, DLABAD, + $ DLACPY, DLARFG, DLASET, DLATM4, DORM2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, MAX, MIN, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA IASIGN / 6*0, 2, 0, 2*2, 2*0, 3*2, 0, 2, 3*0, + $ 5*2, 0 / + DATA IBSIGN / 7*0, 2, 2*0, 2*2, 2*0, 2, 0, 2, 9*0 / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = MAX( 10*( NMAX+1 ), 3*NMAX*NMAX ) + NB = MAX( 1, ILAENV( 1, 'DGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'DORMQR', 'LT', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'DORGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( 10*( NMAX+1 ), 2*NMAX+NMAX*NB, 3*NMAX*NMAX ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -20 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DDRGES3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + SAFMIN = DLAMCH( 'Safe minimum' ) + ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL DLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over matrix sizes +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 190 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / DBLE( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*DBLE( N1 ) +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* +* Loop over matrix types +* + DO 180 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 180 + NMATS = NMATS + 1 + NTEST = 0 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Initialize RESULT +* + DO 30 J = 1, 13 + RESULT( J ) = ZERO + 30 CONTINUE +* +* Generate test matrices A and B +* +* Description of control parameters: +* +* KZLASS: =1 means w/o rotation, =2 means w/ rotation, +* =3 means random. +* KATYPE: the "type" to be passed to DLATM4 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.GT.MAXTYP ) + $ GO TO 110 + IINFO = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL DLASET( 'Full', N, N, ZERO, ZERO, A, LDA ) + ELSE + IN = N + END IF + CALL DLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), IASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = ONE +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL DLASET( 'Full', N, N, ZERO, ZERO, B, LDA ) + ELSE + IN = N + END IF + CALL DLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), IBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = ONE +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 50 JC = 1, N - 1 + DO 40 JR = JC, N + Q( JR, JC ) = DLARND( 3, ISEED ) + Z( JR, JC ) = DLARND( 3, ISEED ) + 40 CONTINUE + CALL DLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, Q( JC, JC ) ) + Q( JC, JC ) = ONE + CALL DLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, Z( JC, JC ) ) + Z( JC, JC ) = ONE + 50 CONTINUE + Q( N, N ) = ONE + WORK( N ) = ZERO + WORK( 3*N ) = SIGN( ONE, DLARND( 2, ISEED ) ) + Z( N, N ) = ONE + WORK( 2*N ) = ZERO + WORK( 4*N ) = SIGN( ONE, DLARND( 2, ISEED ) ) +* +* Apply the diagonal matrices +* + DO 70 JC = 1, N + DO 60 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ B( JR, JC ) + 60 CONTINUE + 70 CONTINUE + CALL DORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL DORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL DORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL DORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + END IF + ELSE +* +* Random matrices +* + DO 90 JC = 1, N + DO 80 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ DLARND( 2, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ DLARND( 2, ISEED ) + 80 CONTINUE + 90 CONTINUE + END IF +* + 100 CONTINUE +* + IF( IINFO.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + RETURN + END IF +* + 110 CONTINUE +* + DO 120 I = 1, 13 + RESULT( I ) = -ONE + 120 CONTINUE +* +* Test with and without sorting of eigenvalues +* + DO 150 ISORT = 0, 1 + IF( ISORT.EQ.0 ) THEN + SORT = 'N' + RSUB = 0 + ELSE + SORT = 'S' + RSUB = 5 + END IF +* +* Call DGGES3 to compute H, T, Q, Z, alpha, and beta. +* + CALL DLACPY( 'Full', N, N, A, LDA, S, LDA ) + CALL DLACPY( 'Full', N, N, B, LDA, T, LDA ) + NTEST = 1 + RSUB + ISORT + RESULT( 1+RSUB+ISORT ) = ULPINV + CALL DGGES3( 'V', 'V', SORT, DLCTES, N, S, LDA, T, LDA, + $ SDIM, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDQ, + $ WORK, LWORK, BWORK, IINFO ) + IF( IINFO.NE.0 .AND. IINFO.NE.N+2 ) THEN + RESULT( 1+RSUB+ISORT ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'DGGES3', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + GO TO 160 + END IF +* + NTEST = 4 + RSUB +* +* Do tests 1--4 (or tests 7--9 when reordering ) +* + IF( ISORT.EQ.0 ) THEN + CALL DGET51( 1, N, A, LDA, S, LDA, Q, LDQ, Z, LDQ, + $ WORK, RESULT( 1 ) ) + CALL DGET51( 1, N, B, LDA, T, LDA, Q, LDQ, Z, LDQ, + $ WORK, RESULT( 2 ) ) + ELSE + CALL DGET54( N, A, LDA, B, LDA, S, LDA, T, LDA, Q, + $ LDQ, Z, LDQ, WORK, RESULT( 7 ) ) + END IF + CALL DGET51( 3, N, A, LDA, T, LDA, Q, LDQ, Q, LDQ, WORK, + $ RESULT( 3+RSUB ) ) + CALL DGET51( 3, N, B, LDA, T, LDA, Z, LDQ, Z, LDQ, WORK, + $ RESULT( 4+RSUB ) ) +* +* Do test 5 and 6 (or Tests 10 and 11 when reordering): +* check Schur form of A and compare eigenvalues with +* diagonals. +* + NTEST = 6 + RSUB + TEMP1 = ZERO +* + DO 130 J = 1, N + ILABAD = .FALSE. + IF( ALPHAI( J ).EQ.ZERO ) THEN + TEMP2 = ( ABS( ALPHAR( J )-S( J, J ) ) / + $ MAX( SAFMIN, ABS( ALPHAR( J ) ), ABS( S( J, + $ J ) ) )+ABS( BETA( J )-T( J, J ) ) / + $ MAX( SAFMIN, ABS( BETA( J ) ), ABS( T( J, + $ J ) ) ) ) / ULP +* + IF( J.LT.N ) THEN + IF( S( J+1, J ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( J.GT.1 ) THEN + IF( S( J, J-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF +* + ELSE + IF( ALPHAI( J ).GT.ZERO ) THEN + I1 = J + ELSE + I1 = J - 1 + END IF + IF( I1.LE.0 .OR. I1.GE.N ) THEN + ILABAD = .TRUE. + ELSE IF( I1.LT.N-1 ) THEN + IF( S( I1+2, I1+1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + ELSE IF( I1.GT.1 ) THEN + IF( S( I1, I1-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( .NOT.ILABAD ) THEN + CALL DGET53( S( I1, I1 ), LDA, T( I1, I1 ), LDA, + $ BETA( J ), ALPHAR( J ), + $ ALPHAI( J ), TEMP2, IERR ) + IF( IERR.GE.3 ) THEN + WRITE( NOUNIT, FMT = 9998 )IERR, J, N, + $ JTYPE, IOLDSD + INFO = ABS( IERR ) + END IF + ELSE + TEMP2 = ULPINV + END IF +* + END IF + TEMP1 = MAX( TEMP1, TEMP2 ) + IF( ILABAD ) THEN + WRITE( NOUNIT, FMT = 9997 )J, N, JTYPE, IOLDSD + END IF + 130 CONTINUE + RESULT( 6+RSUB ) = TEMP1 +* + IF( ISORT.GE.1 ) THEN +* +* Do test 12 +* + NTEST = 12 + RESULT( 12 ) = ZERO + KNTEIG = 0 + DO 140 I = 1, N + IF( DLCTES( ALPHAR( I ), ALPHAI( I ), + $ BETA( I ) ) .OR. DLCTES( ALPHAR( I ), + $ -ALPHAI( I ), BETA( I ) ) ) THEN + KNTEIG = KNTEIG + 1 + END IF + IF( I.LT.N ) THEN + IF( ( DLCTES( ALPHAR( I+1 ), ALPHAI( I+1 ), + $ BETA( I+1 ) ) .OR. DLCTES( ALPHAR( I+1 ), + $ -ALPHAI( I+1 ), BETA( I+1 ) ) ) .AND. + $ ( .NOT.( DLCTES( ALPHAR( I ), ALPHAI( I ), + $ BETA( I ) ) .OR. DLCTES( ALPHAR( I ), + $ -ALPHAI( I ), BETA( I ) ) ) ) .AND. + $ IINFO.NE.N+2 ) THEN + RESULT( 12 ) = ULPINV + END IF + END IF + 140 CONTINUE + IF( SDIM.NE.KNTEIG ) THEN + RESULT( 12 ) = ULPINV + END IF + END IF +* + 150 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 160 CONTINUE +* + NTESTT = NTESTT + NTEST +* +* Print out tests which fail. +* + DO 170 JR = 1, NTEST + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9996 )'DGS' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 ) + WRITE( NOUNIT, FMT = 9993 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9992 )'orthogonal', '''', + $ 'transpose', ( '''', J = 1, 8 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0D0 ) THEN + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9990 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 170 CONTINUE +* + 180 CONTINUE + 190 CONTINUE +* +* Summary +* + CALL ALASVM( 'DGS', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' DDRGES3: ', A, ' returned INFO=', I6, '.', / 9X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' DDRGES3: DGET53 returned INFO=', I1, ' for eigenvalue ', + $ I6, '.', / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', + $ 4( I4, ',' ), I5, ')' ) +* + 9997 FORMAT( ' DDRGES3: S not in Schur form at eigenvalue ', I6, '.', + $ / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), + $ I5, ')' ) +* + 9996 FORMAT( / 1X, A3, ' -- Real Generalized Schur form driver' ) +* + 9995 FORMAT( ' Matrix types (see DDRGES3 for details): ' ) +* + 9994 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9993 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9992 FORMAT( / ' Tests performed: (S is Schur, T is triangular, ', + $ 'Q and Z are ', A, ',', / 19X, + $ 'l and r are the appropriate left and right', / 19X, + $ 'eigenvectors, resp., a is alpha, b is beta, and', / 19X, A, + $ ' means ', A, '.)', / ' Without ordering: ', + $ / ' 1 = | A - Q S Z', A, + $ ' | / ( |A| n ulp ) 2 = | B - Q T Z', A, + $ ' | / ( |B| n ulp )', / ' 3 = | I - QQ', A, + $ ' | / ( n ulp ) 4 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 5 = A is in Schur form S', + $ / ' 6 = difference between (alpha,beta)', + $ ' and diagonals of (S,T)', / ' With ordering: ', + $ / ' 7 = | (A,B) - Q (S,T) Z', A, + $ ' | / ( |(A,B)| n ulp ) ', / ' 8 = | I - QQ', A, + $ ' | / ( n ulp ) 9 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 10 = A is in Schur form S', + $ / ' 11 = difference between (alpha,beta) and diagonals', + $ ' of (S,T)', / ' 12 = SDIM is the correct number of ', + $ 'selected eigenvalues', / ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9990 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, D10.3 ) +* +* End of DDRGES3 +* + END diff --git a/TESTING/EIG/ddrgev3.f b/TESTING/EIG/ddrgev3.f new file mode 100644 index 00000000..79f08b9f --- /dev/null +++ b/TESTING/EIG/ddrgev3.f @@ -0,0 +1,940 @@ +*> \brief \b DDRGEV3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, +* ALPHAR, ALPHAI, BETA, ALPHR1, ALPHI1, BETA1, +* WORK, LWORK, RESULT, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, +* $ NTYPES +* DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. +* LOGICAL DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ), +* $ ALPHI1( * ), ALPHR1( * ), B( LDA, * ), +* $ BETA( * ), BETA1( * ), Q( LDQ, * ), +* $ QE( LDQE, * ), RESULT( * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DDRGEV3 checks the nonsymmetric generalized eigenvalue problem driver +*> routine DGGEV3. +*> +*> DGGEV3 computes for a pair of n-by-n nonsymmetric matrices (A,B) the +*> generalized eigenvalues and, optionally, the left and right +*> eigenvectors. +*> +*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w +*> or a ratio alpha/beta = w, such that A - w*B is singular. It is +*> usually represented as the pair (alpha,beta), as there is reasonable +*> interpretation for beta=0, and even for both being zero. +*> +*> A right generalized eigenvector corresponding to a generalized +*> eigenvalue w for a pair of matrices (A,B) is a vector r such that +*> (A - wB) * r = 0. A left generalized eigenvector is a vector l such +*> that l**H * (A - wB) = 0, where l**H is the conjugate-transpose of l. +*> +*> When DDRGEV3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following tests +*> will be performed and compared with the threshhold THRESH. +*> +*> Results from DGGEV3: +*> +*> (1) max over all left eigenvalue/-vector pairs (alpha/beta,l) of +*> +*> | VL**H * (beta A - alpha B) |/( ulp max(|beta A|, |alpha B|) ) +*> +*> where VL**H is the conjugate-transpose of VL. +*> +*> (2) | |VL(i)| - 1 | / ulp and whether largest component real +*> +*> VL(i) denotes the i-th column of VL. +*> +*> (3) max over all left eigenvalue/-vector pairs (alpha/beta,r) of +*> +*> | (beta A - alpha B) * VR | / ( ulp max(|beta A|, |alpha B|) ) +*> +*> (4) | |VR(i)| - 1 | / ulp and whether largest component real +*> +*> VR(i) denotes the i-th column of VR. +*> +*> (5) W(full) = W(partial) +*> W(full) denotes the eigenvalues computed when both l and r +*> are also computed, and W(partial) denotes the eigenvalues +*> computed when only W, only W and r, or only W and l are +*> computed. +*> +*> (6) VL(full) = VL(partial) +*> VL(full) denotes the left eigenvectors computed when both l +*> and r are computed, and VL(partial) denotes the result +*> when only l is computed. +*> +*> (7) VR(full) = VR(partial) +*> VR(full) denotes the right eigenvectors computed when both l +*> and r are also computed, and VR(partial) denotes the result +*> when only l is computed. +*> +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> DDRGEV3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, DDRGEV3 +*> 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. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 DDRGEV3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is DOUBLE PRECISION +*> 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. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IERR not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is DOUBLE PRECISION array, +*> dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by DGGEV3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is DOUBLE PRECISION array, +*> dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by DGGEV3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is DOUBLE PRECISION array, +*> dimension (LDQ, max(NN)) +*> The (left) eigenvectors matrix computed by DGGEV3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by DGGEV3. +*> \endverbatim +*> +*> \param[out] QE +*> \verbatim +*> QE is DOUBLE PRECISION array, dimension( LDQ, max(NN) ) +*> QE holds the computed right or left eigenvectors. +*> \endverbatim +*> +*> \param[in] LDQE +*> \verbatim +*> LDQE is INTEGER +*> The leading dimension of QE. LDQE >= max(1,max(NN)). +*> \endverbatim +*> +*> \param[out] ALPHAR +*> \verbatim +*> ALPHAR is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHAI +*> \verbatim +*> ALPHAI is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by DGGEV3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] ALPHR1 +*> \verbatim +*> ALPHR1 is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHI1 +*> \verbatim +*> ALPHI1 is DOUBLE PRECISION array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA1 +*> \verbatim +*> BETA1 is DOUBLE PRECISION array, dimension (max(NN)) +*> +*> Like ALPHAR, ALPHAI, BETA, these arrays contain the +*> eigenvalues of A and B, but those computed when DGGEV3 only +*> computes a partial eigendecomposition, i.e. not the +*> eigenvalues and left and right eigenvectors. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The number of entries in WORK. LWORK >= MAX( 8*N, N*(N+1) ). +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is DOUBLE PRECISION array, dimension (2) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup double_eig +* +* ===================================================================== + SUBROUTINE DDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, + $ ALPHAR, ALPHAI, BETA, ALPHR1, ALPHI1, BETA1, + $ WORK, LWORK, RESULT, INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, + $ NTYPES + DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. + LOGICAL DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ), + $ ALPHI1( * ), ALPHR1( * ), B( LDA, * ), + $ BETA( * ), BETA1( * ), Q( LDQ, * ), + $ QE( LDQE, * ), RESULT( * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN + INTEGER I, IADD, IERR, IN, J, JC, JR, JSIZE, JTYPE, + $ MAXWRK, MINWRK, MTYPES, N, N1, NERRS, NMATS, + $ NMAX, NTESTT + DOUBLE PRECISION SAFMAX, SAFMIN, ULP, ULPINV +* .. +* .. Local Arrays .. + INTEGER IASIGN( MAXTYP ), IBSIGN( MAXTYP ), + $ IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + DOUBLE PRECISION RMAGN( 0: 3 ) +* .. +* .. External Functions .. + INTEGER ILAENV + DOUBLE PRECISION DLAMCH, DLARND + EXTERNAL ILAENV, DLAMCH, DLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, DGET52, DGGEV3, DLABAD, DLACPY, DLARFG, + $ DLASET, DLATM4, DORM2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, MAX, MIN, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA IASIGN / 6*0, 2, 0, 2*2, 2*0, 3*2, 0, 2, 3*0, + $ 5*2, 0 / + DATA IBSIGN / 7*0, 2, 2*0, 2*2, 2*0, 2, 0, 2, 9*0 / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + ELSE IF( LDQE.LE.1 .OR. LDQE.LT.NMAX ) THEN + INFO = -17 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = MAX( 1, 8*NMAX, NMAX*( NMAX+1 ) ) + MAXWRK = 7*NMAX + NMAX*ILAENV( 1, 'DGEQRF', ' ', NMAX, 1, NMAX, + $ 0 ) + MAXWRK = MAX( MAXWRK, NMAX*( NMAX+1 ) ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -25 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DDRGEV3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + SAFMIN = DLAMCH( 'Safe minimum' ) + ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL DLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over sizes, types +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 220 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / DBLE( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*N1 +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* + DO 210 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 210 + NMATS = NMATS + 1 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Generate test matrices A and B +* +* Description of control parameters: +* +* KZLASS: =1 means w/o rotation, =2 means w/ rotation, +* =3 means random. +* KATYPE: the "type" to be passed to DLATM4 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.GT.MAXTYP ) + $ GO TO 100 + IERR = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL DLASET( 'Full', N, N, ZERO, ZERO, A, LDA ) + ELSE + IN = N + END IF + CALL DLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), IASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = ONE +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL DLASET( 'Full', N, N, ZERO, ZERO, B, LDA ) + ELSE + IN = N + END IF + CALL DLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), IBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = ONE +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 40 JC = 1, N - 1 + DO 30 JR = JC, N + Q( JR, JC ) = DLARND( 3, ISEED ) + Z( JR, JC ) = DLARND( 3, ISEED ) + 30 CONTINUE + CALL DLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, Q( JC, JC ) ) + Q( JC, JC ) = ONE + CALL DLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, Z( JC, JC ) ) + Z( JC, JC ) = ONE + 40 CONTINUE + Q( N, N ) = ONE + WORK( N ) = ZERO + WORK( 3*N ) = SIGN( ONE, DLARND( 2, ISEED ) ) + Z( N, N ) = ONE + WORK( 2*N ) = ZERO + WORK( 4*N ) = SIGN( ONE, DLARND( 2, ISEED ) ) +* +* Apply the diagonal matrices +* + DO 60 JC = 1, N + DO 50 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ B( JR, JC ) + 50 CONTINUE + 60 CONTINUE + CALL DORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL DORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL DORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL DORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + END IF + ELSE +* +* Random matrices +* + DO 80 JC = 1, N + DO 70 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ DLARND( 2, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ DLARND( 2, ISEED ) + 70 CONTINUE + 80 CONTINUE + END IF +* + 90 CONTINUE +* + IF( IERR.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + RETURN + END IF +* + 100 CONTINUE +* + DO 110 I = 1, 7 + RESULT( I ) = -ONE + 110 CONTINUE +* +* Call DGGEV3 to compute eigenvalues and eigenvectors. +* + CALL DLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL DLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL DGGEV3( 'V', 'V', N, S, LDA, T, LDA, ALPHAR, ALPHAI, + $ BETA, Q, LDQ, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'DGGEV31', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* +* Do the tests (1) and (2) +* + CALL DGET52( .TRUE., N, A, LDA, B, LDA, Q, LDQ, ALPHAR, + $ ALPHAI, BETA, WORK, RESULT( 1 ) ) + IF( RESULT( 2 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Left', 'DGGEV31', + $ RESULT( 2 ), N, JTYPE, IOLDSD + END IF +* +* Do the tests (3) and (4) +* + CALL DGET52( .FALSE., N, A, LDA, B, LDA, Z, LDQ, ALPHAR, + $ ALPHAI, BETA, WORK, RESULT( 3 ) ) + IF( RESULT( 4 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Right', 'DGGEV31', + $ RESULT( 4 ), N, JTYPE, IOLDSD + END IF +* +* Do the test (5) +* + CALL DLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL DLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL DGGEV3( 'N', 'N', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, Q, LDQ, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'DGGEV32', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 120 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. ALPHAI( J ).NE. + $ ALPHI1( J ) .OR. BETA( J ).NE.BETA1( J ) )RESULT( 5 ) + $ = ULPINV + 120 CONTINUE +* +* Do the test (6): Compute eigenvalues and left eigenvectors, +* and test them +* + CALL DLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL DLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL DGGEV3( 'V', 'N', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, QE, LDQE, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'DGGEV33', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 130 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. ALPHAI( J ).NE. + $ ALPHI1( J ) .OR. BETA( J ).NE.BETA1( J ) )RESULT( 6 ) + $ = ULPINV + 130 CONTINUE +* + DO 150 J = 1, N + DO 140 JC = 1, N + IF( Q( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 6 ) = ULPINV + 140 CONTINUE + 150 CONTINUE +* +* DO the test (7): Compute eigenvalues and right eigenvectors, +* and test them +* + CALL DLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL DLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL DGGEV3( 'N', 'V', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, Q, LDQ, QE, LDQE, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'DGGEV34', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 160 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. ALPHAI( J ).NE. + $ ALPHI1( J ) .OR. BETA( J ).NE.BETA1( J ) )RESULT( 7 ) + $ = ULPINV + 160 CONTINUE +* + DO 180 J = 1, N + DO 170 JC = 1, N + IF( Z( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 7 ) = ULPINV + 170 CONTINUE + 180 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 190 CONTINUE +* + NTESTT = NTESTT + 7 +* +* Print out tests which fail. +* + DO 200 JR = 1, 7 + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'DGV' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0D0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 200 CONTINUE +* + 210 CONTINUE + 220 CONTINUE +* +* Summary +* + CALL ALASVM( 'DGV', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' DDRGEV3: ', A, ' returned INFO=', I6, '.', / 3X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' DDRGEV3: ', A, ' Eigenvectors from ', A, ' incorrectly ', + $ 'normalized.', / ' Bits of error=', 0P, G10.3, ',', 3X, + $ 'N=', I4, ', JTYPE=', I3, ', ISEED=(', 4( I4, ',' ), I5, + $ ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Real Generalized eigenvalue problem driver' + $ ) +* + 9996 FORMAT( ' Matrix types (see DDRGEV3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: ', + $ / ' 1 = max | ( b A - a B )''*l | / const.,', + $ / ' 2 = | |VR(i)| - 1 | / ulp,', + $ / ' 3 = max | ( b A - a B )*r | / const.', + $ / ' 4 = | |VL(i)| - 1 | / ulp,', + $ / ' 5 = 0 if W same no matter if r or l computed,', + $ / ' 6 = 0 if l same no matter if l computed,', + $ / ' 7 = 0 if r same no matter if r computed,', / 1X ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, D10.3 ) +* +* End of DDRGEV3 +* + END diff --git a/TESTING/EIG/derrgg.f b/TESTING/EIG/derrgg.f index 07e09a5d..e43ce273 100644 --- a/TESTING/EIG/derrgg.f +++ b/TESTING/EIG/derrgg.f @@ -21,9 +21,10 @@ *> *> \verbatim *> -*> DERRGG tests the error exits for DGGES, DGGESX, DGGEV, DGGEVX, +*> DERRGG tests the error exits for DGGES, DGGESX, DGGEV, DGGEVX, *> DGGGLM, DGGHRD, DGGLSE, DGGQRF, DGGRQF, DGGSVD, DGGSVP, DHGEQZ, -*> DORCSD, DTGEVC, DTGEXC, DTGSEN, DTGSJA, DTGSNA, and DTGSYL. +*> DORCSD, DTGEVC, DTGEXC, DTGSEN, DTGSJA, DTGSNA, DGGES3, DGGEV3, +*> and DTGSYL. *> \endverbatim * * Arguments: @@ -97,7 +98,7 @@ EXTERNAL CHKXER, DGGES, DGGESX, DGGEV, DGGEVX, DGGGLM, $ DGGHRD, DGGLSE, DGGQRF, DGGRQF, DGGSVD, DGGSVP, $ DHGEQZ, DORCSD, DTGEVC, DTGEXC, DTGSEN, DTGSJA, - $ DTGSNA, DTGSYL + $ DTGSNA, DTGSYL, DGGHD3, DGGES3, DGGEV3 * .. * .. Scalars in Common .. LOGICAL LERR, OK @@ -170,6 +171,47 @@ CALL CHKXER( 'DGGHRD', INFOT, NOUT, LERR, OK ) NT = NT + 9 * +* DGGHD3 +* + SRNAMT = 'DGGHD3' + INFOT = 1 + CALL DGGHD3( '/', 'N', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL DGGHD3( 'N', '/', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL DGGHD3( 'N', 'N', -1, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 4 + CALL DGGHD3( 'N', 'N', 0, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL DGGHD3( 'N', 'N', 0, 1, 1, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL DGGHD3( 'N', 'N', 2, 1, 1, A, 1, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL DGGHD3( 'N', 'N', 2, 1, 1, A, 2, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL DGGHD3( 'V', 'N', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL DGGHD3( 'N', 'V', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'DGGHD3', INFOT, NOUT, LERR, OK ) + NT = NT + 9 +* * DHGEQZ * SRNAMT = 'DHGEQZ' @@ -662,6 +704,55 @@ CALL CHKXER( 'DGGES ', INFOT, NOUT, LERR, OK ) NT = NT + 11 * +* DGGES3 +* + SRNAMT = 'DGGES3 ' + INFOT = 1 + CALL DGGES3( '/', 'N', 'S', DLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL DGGES3( 'N', '/', 'S', DLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL DGGES3( 'N', 'V', '/', DLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL DGGES3( 'N', 'V', 'S', DLCTES, -1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL DGGES3( 'N', 'V', 'S', DLCTES, 1, A, 0, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL DGGES3( 'N', 'V', 'S', DLCTES, 1, A, 1, B, 0, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL DGGES3( 'N', 'V', 'S', DLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 0, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL DGGES3( 'V', 'V', 'S', DLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 1, U, 2, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 17 + CALL DGGES3( 'N', 'V', 'S', DLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 0, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 17 + CALL DGGES3( 'V', 'V', 'S', DLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 2, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 19 + CALL DGGES3( 'V', 'V', 'S', DLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 2, U, 2, W, 1, BW, INFO ) + CALL CHKXER( 'DGGES3 ', INFOT, NOUT, LERR, OK ) + NT = NT + 11 +* * DGGESX * SRNAMT = 'DGGESX' @@ -776,6 +867,51 @@ $ 1, INFO ) CALL CHKXER( 'DGGEV ', INFOT, NOUT, LERR, OK ) NT = NT + 10 +* +* DGGEV3 +* + SRNAMT = 'DGGEV3 ' + INFOT = 1 + CALL DGGEV3( '/', 'N', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL DGGEV3( 'N', '/', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL DGGEV3( 'V', 'V', -1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL DGGEV3( 'V', 'V', 1, A, 0, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL DGGEV3( 'V', 'V', 1, A, 1, B, 0, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 12 + CALL DGGEV3( 'N', 'V', 1, A, 1, B, 1, R1, R2, R3, Q, 0, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 12 + CALL DGGEV3( 'V', 'V', 2, A, 2, B, 2, R1, R2, R3, Q, 1, U, 2, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL DGGEV3( 'V', 'N', 2, A, 2, B, 2, R1, R2, R3, Q, 2, U, 0, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL DGGEV3( 'V', 'V', 2, A, 2, B, 2, R1, R2, R3, Q, 2, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL DGGEV3( 'V', 'V', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'DGGEV3 ', INFOT, NOUT, LERR, OK ) + NT = NT + 10 * * DGGEVX * diff --git a/TESTING/EIG/schkee.f b/TESTING/EIG/schkee.f index 5b6a9ba1..d323d200 100644 --- a/TESTING/EIG/schkee.f +++ b/TESTING/EIG/schkee.f @@ -44,7 +44,7 @@ *> Test SGEESX *> *> SGG (Generalized Nonsymmetric Eigenvalue Problem): -*> Test SGGHRD, SGGBAL, SGGBAK, SHGEQZ, and STGEVC +*> Test SGGHD3, SGGBAL, SGGBAK, SHGEQZ, and STGEVC *> and the driver routines SGEGS and SGEGV *> *> SGS (Generalized Nonsymmetric Schur form Driver): @@ -493,38 +493,41 @@ *> line 8: MXBVAL, INTEGER array, dimension (NPARMS) *> The values for MAXB, used in determining minimum blocksize. *> -*> line 9: NBCOL, INTEGER array, dimension (NPARMS) +*> line 9: IACC22, INTEGER array, dimension (NPARMS) +*> select structured matrix multiply: 1 or 2) +*> +*> line 10: NBCOL, INTEGER array, dimension (NPARMS) *> The values for NBCOL, the minimum column dimension for *> blocks. *> -*> line 10: THRESH +*> line 11: THRESH *> Threshold value for the test ratios. Information will be *> printed about each test for which the test ratio is greater *> than or equal to the threshold. *> -*> line 11: TSTCHK, LOGICAL +*> line 12: TSTCHK, LOGICAL *> Flag indicating whether or not to test the LAPACK routines. *> -*> line 12: TSTDRV, LOGICAL +*> line 13: TSTDRV, LOGICAL *> Flag indicating whether or not to test the driver routines. *> -*> line 13: TSTERR, LOGICAL +*> line 14: TSTERR, LOGICAL *> Flag indicating whether or not to test the error exits for *> the LAPACK routines and driver routines. *> -*> line 14: NEWSD, INTEGER +*> line 15: NEWSD, INTEGER *> A code indicating how to set the random number seed. *> = 0: Set the seed to a default value before each run *> = 1: Initialize the seed to a default value only before the *> first run *> = 2: Like 1, but use the seed values on the next line *> -*> If line 14 was 2: +*> If line 15 was 2: *> -*> line 15: INTEGER array, dimension (4) +*> line 16: INTEGER array, dimension (4) *> Four integer values for the random number seed. *> -*> lines 15-EOF: Lines specifying matrix types, as for NEP. +*> lines 17-EOF: Lines specifying matrix types, as for NEP. *> The 3-character path name is 'SGG' for the generalized *> eigenvalue problem routines and driver routines. *> @@ -1104,7 +1107,8 @@ $ SCKCSD, SCKGLM, SCKGQR, SCKGSV, SCKLSE, SDRGES, $ SDRGEV, SDRGSX, SDRGVX, SDRVBD, SDRVES, SDRVEV, $ SDRVGG, SDRVSG, SDRVST, SDRVSX, SDRVVX, SERRBD, - $ SERRED, SERRGG, SERRHS, SERRST, ILAVER, XLAENV + $ SERRED, SERRGG, SERRHS, SERRST, ILAVER, XLAENV, + $ SDRGES3, SDRGEV3 * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN @@ -1630,7 +1634,7 @@ * * Read the values for IACC22. * - IF( NEP ) THEN + IF( NEP .OR. SGG ) THEN READ( NIN, FMT = * )( IACC22( I ), I = 1, NPARMS ) DO 620 I = 1, NPARMS IF( IACC22( I ).LT.0 ) THEN @@ -2097,6 +2101,7 @@ * NBMIN = minimum block size * NS = number of shifts * MAXB = minimum submatrix size +* IACC22: structured matrix multiply * NBCOL = minimum column dimension for blocks * MAXTYP = 26 @@ -2109,6 +2114,7 @@ CALL XLAENV( 2, NBMIN( I ) ) CALL XLAENV( 4, NSVAL( I ) ) CALL XLAENV( 8, MXBVAL( I ) ) + CALL XLAENV( 16, IACC22( I ) ) CALL XLAENV( 5, NBCOL( I ) ) * IF( NEWSD.EQ.0 ) THEN @@ -2117,7 +2123,7 @@ 340 CONTINUE END IF WRITE( NOUT, FMT = 9996 )C3, NBVAL( I ), NBMIN( I ), - $ NSVAL( I ), MXBVAL( I ), NBCOL( I ) + $ NSVAL( I ), MXBVAL( I ), IACC22( I ), NBCOL( I ) TSTDIF = .FALSE. THRSHN = 10. IF( TSTCHK ) THEN @@ -2170,6 +2176,17 @@ * IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'SDRGES', INFO +* +* Blocked version +* + CALL SDRGES3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ D( 1, 1 ), D( 1, 2 ), D( 1, 3 ), WORK, LWORK, + $ RESULT, LOGWRK, INFO ) +* + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'SDRGES3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2224,6 +2241,17 @@ $ WORK, LWORK, RESULT, INFO ) IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'SDRGEV', INFO +* +* Blocked version +* + CALL SDRGEV3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ A( 1, 9 ), NMAX, D( 1, 1 ), D( 1, 2 ), + $ D( 1, 3 ), D( 1, 4 ), D( 1, 5 ), D( 1, 6 ), + $ WORK, LWORK, RESULT, INFO ) + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'SDRGEV3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2395,7 +2423,7 @@ 9999 FORMAT( / ' Execution not attempted due to input errors' ) 9997 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4 ) 9996 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NS =', I4, - $ ', MAXB =', I4, ', NBCOL =', I4 ) + $ ', MAXB =', I4, ', IACC22 =', I4, ', NBCOL =', I4 ) 9995 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4, $ ', NRHS =', I4 ) 9994 FORMAT( / / ' End of tests' ) diff --git a/TESTING/EIG/sdrges3.f b/TESTING/EIG/sdrges3.f new file mode 100644 index 00000000..6fed3c84 --- /dev/null +++ b/TESTING/EIG/sdrges3.f @@ -0,0 +1,997 @@ +*> \brief \b SDRGES3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE SDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHAR, +* ALPHAI, BETA, WORK, LWORK, RESULT, BWORK, +* INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES +* REAL THRESH +* .. +* .. Array Arguments .. +* LOGICAL BWORK( * ), DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ), +* $ B( LDA, * ), BETA( * ), Q( LDQ, * ), +* $ RESULT( 13 ), S( LDA, * ), T( LDA, * ), +* $ WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> SDRGES3 checks the nonsymmetric generalized eigenvalue (Schur form) +*> problem driver SGGES3. +*> +*> SGGES3 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(j),beta(j)), j=1,...,n, +*> Thus, w(j) = alpha(j)/beta(j) is a root of the characteristic +*> equation +*> det( A - w(j) B ) = 0 +*> Optionally it also reorder the eigenvalues so that a selected +*> cluster of eigenvalues appears in the leading diagonal block of the +*> Schur forms. +*> +*> When SDRGES3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following 13 tests +*> will be performed and compared with the threshhold THRESH except +*> the tests (5), (11) and (13). +*> +*> +*> (1) | A - Q S Z' | / ( |A| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (2) | B - Q T Z' | / ( |B| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (3) | I - QQ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> +*> (4) | I - ZZ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> (5) if A is in Schur form (i.e. quasi-triangular form) +*> (no sorting of eigenvalues) +*> +*> (6) if eigenvalues = diagonal blocks of the Schur form (S, T), +*> i.e., test the 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 and j+1-th eigenvalues. +*> (no sorting of eigenvalues) +*> +*> (7) | (A,B) - Q (S,T) Z' | / ( | (A,B) | n ulp ) +*> (with sorting of eigenvalues). +*> +*> (8) | I - QQ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (9) | I - ZZ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (10) if A is in Schur form (i.e. quasi-triangular form) +*> (with sorting of eigenvalues). +*> +*> (11) if eigenvalues = diagonal blocks of the Schur form (S, T), +*> i.e. test the 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 and j+1-th eigenvalues. +*> (with sorting of eigenvalues). +*> +*> (12) if sorting worked and SDIM is the number of eigenvalues +*> which were SELECTed. +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> SDRGES3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, SDRGES3 +*> 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 on input. +*> This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and +*> DOTYPE(MAXTYP+1) is .TRUE. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 SDRGES3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is 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. THRESH >= 0. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IINFO not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is REAL array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by SGGES3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is REAL array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by SGGES3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is REAL array, dimension (LDQ, max(NN)) +*> The (left) orthogonal matrix computed by SGGES3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is REAL array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by SGGES3. +*> \endverbatim +*> +*> \param[out] ALPHAR +*> \verbatim +*> ALPHAR is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHAI +*> \verbatim +*> ALPHAI is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is REAL array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by SGGES3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is REAL array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. +*> LWORK >= MAX( 10*(N+1), 3*N*N ), where N is the largest +*> matrix dimension. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is REAL array, dimension (15) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] BWORK +*> \verbatim +*> BWORK is LOGICAL array, dimension (N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup single_eig +* +* ===================================================================== + SUBROUTINE SDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHAR, + $ ALPHAI, BETA, WORK, LWORK, RESULT, BWORK, + $ INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES + REAL THRESH +* .. +* .. Array Arguments .. + LOGICAL BWORK( * ), DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ), + $ B( LDA, * ), BETA( * ), Q( LDQ, * ), + $ RESULT( 13 ), S( LDA, * ), T( LDA, * ), + $ WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + REAL ZERO, ONE + PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN, ILABAD + CHARACTER SORT + INTEGER I, I1, IADD, IERR, IINFO, IN, ISORT, J, JC, JR, + $ JSIZE, JTYPE, KNTEIG, MAXWRK, MINWRK, MTYPES, + $ N, N1, NB, NERRS, NMATS, NMAX, NTEST, NTESTT, + $ RSUB, SDIM + REAL SAFMAX, SAFMIN, TEMP1, TEMP2, ULP, ULPINV +* .. +* .. Local Arrays .. + INTEGER IASIGN( MAXTYP ), IBSIGN( MAXTYP ), + $ IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + REAL RMAGN( 0: 3 ) +* .. +* .. External Functions .. + LOGICAL SLCTES + INTEGER ILAENV + REAL SLAMCH, SLARND + EXTERNAL SLCTES, ILAENV, SLAMCH, SLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, SGET51, SGET53, SGET54, SGGES3, SLABAD, + $ SLACPY, SLARFG, SLASET, SLATM4, SORM2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, REAL, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA IASIGN / 6*0, 2, 0, 2*2, 2*0, 3*2, 0, 2, 3*0, + $ 5*2, 0 / + DATA IBSIGN / 7*0, 2, 2*0, 2*2, 2*0, 2, 0, 2, 9*0 / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = MAX( 10*( NMAX+1 ), 3*NMAX*NMAX ) + NB = MAX( 1, ILAENV( 1, 'SGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'SORMQR', 'LT', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'SORGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( 10*( NMAX+1 ), 2*NMAX+NMAX*NB, 3*NMAX*NMAX ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -20 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'SDRGES3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + SAFMIN = SLAMCH( 'Safe minimum' ) + ULP = SLAMCH( 'Epsilon' )*SLAMCH( 'Base' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL SLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over matrix sizes +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 190 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / REAL( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*REAL( N1 ) +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* +* Loop over matrix types +* + DO 180 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 180 + NMATS = NMATS + 1 + NTEST = 0 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Initialize RESULT +* + DO 30 J = 1, 13 + RESULT( J ) = ZERO + 30 CONTINUE +* +* Generate test matrices 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.GT.MAXTYP ) + $ GO TO 110 + IINFO = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL SLASET( 'Full', N, N, ZERO, ZERO, A, LDA ) + ELSE + IN = N + END IF + CALL SLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), IASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = ONE +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL SLASET( 'Full', N, N, ZERO, ZERO, B, LDA ) + ELSE + IN = N + END IF + CALL SLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), IBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = ONE +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 50 JC = 1, N - 1 + DO 40 JR = JC, N + Q( JR, JC ) = SLARND( 3, ISEED ) + Z( JR, JC ) = SLARND( 3, ISEED ) + 40 CONTINUE + CALL SLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, Q( JC, JC ) ) + Q( JC, JC ) = ONE + CALL SLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, Z( JC, JC ) ) + Z( JC, JC ) = ONE + 50 CONTINUE + Q( N, N ) = ONE + WORK( N ) = ZERO + WORK( 3*N ) = SIGN( ONE, SLARND( 2, ISEED ) ) + Z( N, N ) = ONE + WORK( 2*N ) = ZERO + WORK( 4*N ) = SIGN( ONE, SLARND( 2, ISEED ) ) +* +* Apply the diagonal matrices +* + DO 70 JC = 1, N + DO 60 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ B( JR, JC ) + 60 CONTINUE + 70 CONTINUE + CALL SORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL SORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL SORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL SORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + END IF + ELSE +* +* Random matrices +* + DO 90 JC = 1, N + DO 80 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ SLARND( 2, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ SLARND( 2, ISEED ) + 80 CONTINUE + 90 CONTINUE + END IF +* + 100 CONTINUE +* + IF( IINFO.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + RETURN + END IF +* + 110 CONTINUE +* + DO 120 I = 1, 13 + RESULT( I ) = -ONE + 120 CONTINUE +* +* Test with and without sorting of eigenvalues +* + DO 150 ISORT = 0, 1 + IF( ISORT.EQ.0 ) THEN + SORT = 'N' + RSUB = 0 + ELSE + SORT = 'S' + RSUB = 5 + END IF +* +* Call SGGES3 to compute H, T, Q, Z, alpha, and beta. +* + CALL SLACPY( 'Full', N, N, A, LDA, S, LDA ) + CALL SLACPY( 'Full', N, N, B, LDA, T, LDA ) + NTEST = 1 + RSUB + ISORT + RESULT( 1+RSUB+ISORT ) = ULPINV + CALL SGGES3( 'V', 'V', SORT, SLCTES, N, S, LDA, T, LDA, + $ SDIM, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDQ, + $ WORK, LWORK, BWORK, IINFO ) + IF( IINFO.NE.0 .AND. IINFO.NE.N+2 ) THEN + RESULT( 1+RSUB+ISORT ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'SGGES3', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + GO TO 160 + END IF +* + NTEST = 4 + RSUB +* +* Do tests 1--4 (or tests 7--9 when reordering ) +* + IF( ISORT.EQ.0 ) THEN + CALL SGET51( 1, N, A, LDA, S, LDA, Q, LDQ, Z, LDQ, + $ WORK, RESULT( 1 ) ) + CALL SGET51( 1, N, B, LDA, T, LDA, Q, LDQ, Z, LDQ, + $ WORK, RESULT( 2 ) ) + ELSE + CALL SGET54( N, A, LDA, B, LDA, S, LDA, T, LDA, Q, + $ LDQ, Z, LDQ, WORK, RESULT( 7 ) ) + END IF + CALL SGET51( 3, N, A, LDA, T, LDA, Q, LDQ, Q, LDQ, WORK, + $ RESULT( 3+RSUB ) ) + CALL SGET51( 3, N, B, LDA, T, LDA, Z, LDQ, Z, LDQ, WORK, + $ RESULT( 4+RSUB ) ) +* +* Do test 5 and 6 (or Tests 10 and 11 when reordering): +* check Schur form of A and compare eigenvalues with +* diagonals. +* + NTEST = 6 + RSUB + TEMP1 = ZERO +* + DO 130 J = 1, N + ILABAD = .FALSE. + IF( ALPHAI( J ).EQ.ZERO ) THEN + TEMP2 = ( ABS( ALPHAR( J )-S( J, J ) ) / + $ MAX( SAFMIN, ABS( ALPHAR( J ) ), ABS( S( J, + $ J ) ) )+ABS( BETA( J )-T( J, J ) ) / + $ MAX( SAFMIN, ABS( BETA( J ) ), ABS( T( J, + $ J ) ) ) ) / ULP +* + IF( J.LT.N ) THEN + IF( S( J+1, J ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( J.GT.1 ) THEN + IF( S( J, J-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF +* + ELSE + IF( ALPHAI( J ).GT.ZERO ) THEN + I1 = J + ELSE + I1 = J - 1 + END IF + IF( I1.LE.0 .OR. I1.GE.N ) THEN + ILABAD = .TRUE. + ELSE IF( I1.LT.N-1 ) THEN + IF( S( I1+2, I1+1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + ELSE IF( I1.GT.1 ) THEN + IF( S( I1, I1-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( .NOT.ILABAD ) THEN + CALL SGET53( S( I1, I1 ), LDA, T( I1, I1 ), LDA, + $ BETA( J ), ALPHAR( J ), + $ ALPHAI( J ), TEMP2, IERR ) + IF( IERR.GE.3 ) THEN + WRITE( NOUNIT, FMT = 9998 )IERR, J, N, + $ JTYPE, IOLDSD + INFO = ABS( IERR ) + END IF + ELSE + TEMP2 = ULPINV + END IF +* + END IF + TEMP1 = MAX( TEMP1, TEMP2 ) + IF( ILABAD ) THEN + WRITE( NOUNIT, FMT = 9997 )J, N, JTYPE, IOLDSD + END IF + 130 CONTINUE + RESULT( 6+RSUB ) = TEMP1 +* + IF( ISORT.GE.1 ) THEN +* +* Do test 12 +* + NTEST = 12 + RESULT( 12 ) = ZERO + KNTEIG = 0 + DO 140 I = 1, N + IF( SLCTES( ALPHAR( I ), ALPHAI( I ), + $ BETA( I ) ) .OR. SLCTES( ALPHAR( I ), + $ -ALPHAI( I ), BETA( I ) ) ) THEN + KNTEIG = KNTEIG + 1 + END IF + IF( I.LT.N ) THEN + IF( ( SLCTES( ALPHAR( I+1 ), ALPHAI( I+1 ), + $ BETA( I+1 ) ) .OR. SLCTES( ALPHAR( I+1 ), + $ -ALPHAI( I+1 ), BETA( I+1 ) ) ) .AND. + $ ( .NOT.( SLCTES( ALPHAR( I ), ALPHAI( I ), + $ BETA( I ) ) .OR. SLCTES( ALPHAR( I ), + $ -ALPHAI( I ), BETA( I ) ) ) ) .AND. + $ IINFO.NE.N+2 ) THEN + RESULT( 12 ) = ULPINV + END IF + END IF + 140 CONTINUE + IF( SDIM.NE.KNTEIG ) THEN + RESULT( 12 ) = ULPINV + END IF + END IF +* + 150 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 160 CONTINUE +* + NTESTT = NTESTT + NTEST +* +* Print out tests which fail. +* + DO 170 JR = 1, NTEST + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9996 )'SGS' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 ) + WRITE( NOUNIT, FMT = 9993 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9992 )'orthogonal', '''', + $ 'transpose', ( '''', J = 1, 8 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0 ) THEN + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9990 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 170 CONTINUE +* + 180 CONTINUE + 190 CONTINUE +* +* Summary +* + CALL ALASVM( 'SGS', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' SDRGES3: ', A, ' returned INFO=', I6, '.', / 9X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' SDRGES3: SGET53 returned INFO=', I1, ' for eigenvalue ', + $ I6, '.', / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', + $ 4( I4, ',' ), I5, ')' ) +* + 9997 FORMAT( ' SDRGES3: S not in Schur form at eigenvalue ', I6, '.', + $ / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), + $ I5, ')' ) +* + 9996 FORMAT( / 1X, A3, ' -- Real Generalized Schur form driver' ) +* + 9995 FORMAT( ' Matrix types (see SDRGES3 for details): ' ) +* + 9994 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9993 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9992 FORMAT( / ' Tests performed: (S is Schur, T is triangular, ', + $ 'Q and Z are ', A, ',', / 19X, + $ 'l and r are the appropriate left and right', / 19X, + $ 'eigenvectors, resp., a is alpha, b is beta, and', / 19X, A, + $ ' means ', A, '.)', / ' Without ordering: ', + $ / ' 1 = | A - Q S Z', A, + $ ' | / ( |A| n ulp ) 2 = | B - Q T Z', A, + $ ' | / ( |B| n ulp )', / ' 3 = | I - QQ', A, + $ ' | / ( n ulp ) 4 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 5 = A is in Schur form S', + $ / ' 6 = difference between (alpha,beta)', + $ ' and diagonals of (S,T)', / ' With ordering: ', + $ / ' 7 = | (A,B) - Q (S,T) Z', A, + $ ' | / ( |(A,B)| n ulp ) ', / ' 8 = | I - QQ', A, + $ ' | / ( n ulp ) 9 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 10 = A is in Schur form S', + $ / ' 11 = difference between (alpha,beta) and diagonals', + $ ' of (S,T)', / ' 12 = SDIM is the correct number of ', + $ 'selected eigenvalues', / ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9990 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, E10.3 ) +* +* End of SDRGES3 +* + END diff --git a/TESTING/EIG/sdrgev3.f b/TESTING/EIG/sdrgev3.f new file mode 100644 index 00000000..29adafbb --- /dev/null +++ b/TESTING/EIG/sdrgev3.f @@ -0,0 +1,941 @@ +*> \brief \b SDRGEV3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE SDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, +* ALPHAR, ALPHAI, BETA, ALPHR1, ALPHI1, BETA1, +* WORK, LWORK, RESULT, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, +* $ NTYPES +* REAL THRESH +* .. +* .. Array Arguments .. +* LOGICAL DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* REAL A( LDA, * ), ALPHAI( * ), ALPHI1( * ), +* $ ALPHAR( * ), ALPHR1( * ), B( LDA, * ), +* $ BETA( * ), BETA1( * ), Q( LDQ, * ), +* $ QE( LDQE, * ), RESULT( * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> SDRGEV3 checks the nonsymmetric generalized eigenvalue problem driver +*> routine SGGEV3. +*> +*> SGGEV3 computes for a pair of n-by-n nonsymmetric matrices (A,B) the +*> generalized eigenvalues and, optionally, the left and right +*> eigenvectors. +*> +*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w +*> or a ratio alpha/beta = w, such that A - w*B is singular. It is +*> usually represented as the pair (alpha,beta), as there is reasonable +*> interpretation for beta=0, and even for both being zero. +*> +*> A right generalized eigenvector corresponding to a generalized +*> eigenvalue w for a pair of matrices (A,B) is a vector r such that +*> (A - wB) * r = 0. A left generalized eigenvector is a vector l such +*> that l**H * (A - wB) = 0, where l**H is the conjugate-transpose of l. +*> +*> When SDRGEV3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following tests +*> will be performed and compared with the threshhold THRESH. +*> +*> Results from SGGEV3: +*> +*> (1) max over all left eigenvalue/-vector pairs (alpha/beta,l) of +*> +*> | VL**H * (beta A - alpha B) |/( ulp max(|beta A|, |alpha B|) ) +*> +*> where VL**H is the conjugate-transpose of VL. +*> +*> (2) | |VL(i)| - 1 | / ulp and whether largest component real +*> +*> VL(i) denotes the i-th column of VL. +*> +*> (3) max over all left eigenvalue/-vector pairs (alpha/beta,r) of +*> +*> | (beta A - alpha B) * VR | / ( ulp max(|beta A|, |alpha B|) ) +*> +*> (4) | |VR(i)| - 1 | / ulp and whether largest component real +*> +*> VR(i) denotes the i-th column of VR. +*> +*> (5) W(full) = W(partial) +*> W(full) denotes the eigenvalues computed when both l and r +*> are also computed, and W(partial) denotes the eigenvalues +*> computed when only W, only W and r, or only W and l are +*> computed. +*> +*> (6) VL(full) = VL(partial) +*> VL(full) denotes the left eigenvectors computed when both l +*> and r are computed, and VL(partial) denotes the result +*> when only l is computed. +*> +*> (7) VR(full) = VR(partial) +*> VR(full) denotes the right eigenvectors computed when both l +*> and r are also computed, and VR(partial) denotes the result +*> when only l is computed. +*> +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> SDRGEV3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, SDRGEV3 +*> 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. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 SDRGEV3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is 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. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IERR not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is REAL array, +*> dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by SGGEV3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is REAL array, +*> dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by SGGEV3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is REAL array, +*> dimension (LDQ, max(NN)) +*> The (left) eigenvectors matrix computed by SGGEV3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is REAL array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by SGGEV3. +*> \endverbatim +*> +*> \param[out] QE +*> \verbatim +*> QE is REAL array, dimension( LDQ, max(NN) ) +*> QE holds the computed right or left eigenvectors. +*> \endverbatim +*> +*> \param[in] LDQE +*> \verbatim +*> LDQE is INTEGER +*> The leading dimension of QE. LDQE >= max(1,max(NN)). +*> \endverbatim +*> +*> \param[out] ALPHAR +*> \verbatim +*> ALPHAR is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHAI +*> \verbatim +*> ALPHAI is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is REAL array, dimension (max(NN)) +*> \verbatim +*> The generalized eigenvalues of (A,B) computed by SGGEV3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] ALPHR1 +*> \verbatim +*> ALPHR1 is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] ALPHI1 +*> \verbatim +*> ALPHI1 is REAL array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA1 +*> \verbatim +*> BETA1 is REAL array, dimension (max(NN)) +*> +*> Like ALPHAR, ALPHAI, BETA, these arrays contain the +*> eigenvalues of A and B, but those computed when SGGEV3 only +*> computes a partial eigendecomposition, i.e. not the +*> eigenvalues and left and right eigenvectors. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is REAL array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The number of entries in WORK. LWORK >= MAX( 8*N, N*(N+1) ). +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is REAL array, dimension (2) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup single_eig +* +* ===================================================================== + SUBROUTINE SDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, + $ ALPHAR, ALPHAI, BETA, ALPHR1, ALPHI1, BETA1, + $ WORK, LWORK, RESULT, INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, + $ NTYPES + REAL THRESH +* .. +* .. Array Arguments .. + LOGICAL DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + REAL A( LDA, * ), ALPHAI( * ), ALPHI1( * ), + $ ALPHAR( * ), ALPHR1( * ), B( LDA, * ), + $ BETA( * ), BETA1( * ), Q( LDQ, * ), + $ QE( LDQE, * ), RESULT( * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + REAL ZERO, ONE + PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN + INTEGER I, IADD, IERR, IN, J, JC, JR, JSIZE, JTYPE, + $ MAXWRK, MINWRK, MTYPES, N, N1, NERRS, NMATS, + $ NMAX, NTESTT + REAL SAFMAX, SAFMIN, ULP, ULPINV +* .. +* .. Local Arrays .. + INTEGER IASIGN( MAXTYP ), IBSIGN( MAXTYP ), + $ IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + REAL RMAGN( 0: 3 ) +* .. +* .. External Functions .. + INTEGER ILAENV + REAL SLAMCH, SLARND + EXTERNAL ILAENV, SLAMCH, SLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, SGET52, SGGEV3, SLABAD, SLACPY, SLARFG, + $ SLASET, SLATM4, SORM2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, REAL, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA IASIGN / 6*0, 2, 0, 2*2, 2*0, 3*2, 0, 2, 3*0, + $ 5*2, 0 / + DATA IBSIGN / 7*0, 2, 2*0, 2*2, 2*0, 2, 0, 2, 9*0 / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + ELSE IF( LDQE.LE.1 .OR. LDQE.LT.NMAX ) THEN + INFO = -17 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = MAX( 1, 8*NMAX, NMAX*( NMAX+1 ) ) + MAXWRK = 7*NMAX + NMAX*ILAENV( 1, 'SGEQRF', ' ', NMAX, 1, NMAX, + $ 0 ) + MAXWRK = MAX( MAXWRK, NMAX*( NMAX+1 ) ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -25 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'SDRGEV3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + SAFMIN = SLAMCH( 'Safe minimum' ) + ULP = SLAMCH( 'Epsilon' )*SLAMCH( 'Base' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL SLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over sizes, types +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 220 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / REAL( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*N1 +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* + DO 210 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 210 + NMATS = NMATS + 1 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Generate test matrices 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.GT.MAXTYP ) + $ GO TO 100 + IERR = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL SLASET( 'Full', N, N, ZERO, ZERO, A, LDA ) + ELSE + IN = N + END IF + CALL SLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), IASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = ONE +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL SLASET( 'Full', N, N, ZERO, ZERO, B, LDA ) + ELSE + IN = N + END IF + CALL SLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), IBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = ONE +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 40 JC = 1, N - 1 + DO 30 JR = JC, N + Q( JR, JC ) = SLARND( 3, ISEED ) + Z( JR, JC ) = SLARND( 3, ISEED ) + 30 CONTINUE + CALL SLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, Q( JC, JC ) ) + Q( JC, JC ) = ONE + CALL SLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, Z( JC, JC ) ) + Z( JC, JC ) = ONE + 40 CONTINUE + Q( N, N ) = ONE + WORK( N ) = ZERO + WORK( 3*N ) = SIGN( ONE, SLARND( 2, ISEED ) ) + Z( N, N ) = ONE + WORK( 2*N ) = ZERO + WORK( 4*N ) = SIGN( ONE, SLARND( 2, ISEED ) ) +* +* Apply the diagonal matrices +* + DO 60 JC = 1, N + DO 50 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )*WORK( 3*N+JC )* + $ B( JR, JC ) + 50 CONTINUE + 60 CONTINUE + CALL SORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL SORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL SORM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL SORM2R( 'R', 'T', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + END IF + ELSE +* +* Random matrices +* + DO 80 JC = 1, N + DO 70 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ SLARND( 2, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ SLARND( 2, ISEED ) + 70 CONTINUE + 80 CONTINUE + END IF +* + 90 CONTINUE +* + IF( IERR.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + RETURN + END IF +* + 100 CONTINUE +* + DO 110 I = 1, 7 + RESULT( I ) = -ONE + 110 CONTINUE +* +* Call SGGEV3 to compute eigenvalues and eigenvectors. +* + CALL SLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL SLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL SGGEV3( 'V', 'V', N, S, LDA, T, LDA, ALPHAR, ALPHAI, + $ BETA, Q, LDQ, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'SGGEV31', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* +* Do the tests (1) and (2) +* + CALL SGET52( .TRUE., N, A, LDA, B, LDA, Q, LDQ, ALPHAR, + $ ALPHAI, BETA, WORK, RESULT( 1 ) ) + IF( RESULT( 2 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Left', 'SGGEV31', + $ RESULT( 2 ), N, JTYPE, IOLDSD + END IF +* +* Do the tests (3) and (4) +* + CALL SGET52( .FALSE., N, A, LDA, B, LDA, Z, LDQ, ALPHAR, + $ ALPHAI, BETA, WORK, RESULT( 3 ) ) + IF( RESULT( 4 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Right', 'SGGEV31', + $ RESULT( 4 ), N, JTYPE, IOLDSD + END IF +* +* Do the test (5) +* + CALL SLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL SLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL SGGEV3( 'N', 'N', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, Q, LDQ, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'SGGEV32', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 120 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. + $ BETA( J ).NE. BETA1( J ) ) THEN + RESULT( 5 ) = ULPINV + END IF + 120 CONTINUE +* +* Do the test (6): Compute eigenvalues and left eigenvectors, +* and test them +* + CALL SLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL SLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL SGGEV3( 'V', 'N', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, QE, LDQE, Z, LDQ, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'SGGEV33', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 130 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. ALPHAI( J ).NE. + $ ALPHI1( J ) .OR. BETA( J ).NE.BETA1( J ) ) + $ RESULT( 6 ) = ULPINV + 130 CONTINUE +* + DO 150 J = 1, N + DO 140 JC = 1, N + IF( Q( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 6 ) = ULPINV + 140 CONTINUE + 150 CONTINUE +* +* DO the test (7): Compute eigenvalues and right eigenvectors, +* and test them +* + CALL SLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL SLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL SGGEV3( 'N', 'V', N, S, LDA, T, LDA, ALPHR1, ALPHI1, + $ BETA1, Q, LDQ, QE, LDQE, WORK, LWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'SGGEV34', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 160 J = 1, N + IF( ALPHAR( J ).NE.ALPHR1( J ) .OR. ALPHAI( J ).NE. + $ ALPHI1( J ) .OR. BETA( J ).NE.BETA1( J ) ) + $ RESULT( 7 ) = ULPINV + 160 CONTINUE +* + DO 180 J = 1, N + DO 170 JC = 1, N + IF( Z( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 7 ) = ULPINV + 170 CONTINUE + 180 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 190 CONTINUE +* + NTESTT = NTESTT + 7 +* +* Print out tests which fail. +* + DO 200 JR = 1, 7 + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'SGV' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 200 CONTINUE +* + 210 CONTINUE + 220 CONTINUE +* +* Summary +* + CALL ALASVM( 'SGV', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' SDRGEV3: ', A, ' returned INFO=', I6, '.', / 3X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' SDRGEV3: ', A, ' Eigenvectors from ', A, ' incorrectly ', + $ 'normalized.', / ' Bits of error=', 0P, G10.3, ',', 3X, + $ 'N=', I4, ', JTYPE=', I3, ', ISEED=(', 4( I4, ',' ), I5, + $ ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Real Generalized eigenvalue problem driver' + $ ) +* + 9996 FORMAT( ' Matrix types (see SDRGEV3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: ', + $ / ' 1 = max | ( b A - a B )''*l | / const.,', + $ / ' 2 = | |VR(i)| - 1 | / ulp,', + $ / ' 3 = max | ( b A - a B )*r | / const.', + $ / ' 4 = | |VL(i)| - 1 | / ulp,', + $ / ' 5 = 0 if W same no matter if r or l computed,', + $ / ' 6 = 0 if l same no matter if l computed,', + $ / ' 7 = 0 if r same no matter if r computed,', / 1X ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, E10.3 ) +* +* End of SDRGEV3 +* + END diff --git a/TESTING/EIG/serrgg.f b/TESTING/EIG/serrgg.f index f04f6a88..89610320 100644 --- a/TESTING/EIG/serrgg.f +++ b/TESTING/EIG/serrgg.f @@ -2,19 +2,19 @@ * * =========== DOCUMENTATION =========== * -* Online html documentation available at -* http://www.netlib.org/lapack/explore-html/ +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE SERRGG( PATH, NUNIT ) -* +* * .. Scalar Arguments .. * CHARACTER*3 PATH * INTEGER NUNIT * .. -* +* * *> \par Purpose: * ============= @@ -22,8 +22,9 @@ *> \verbatim *> *> SERRGG tests the error exits for SGGES, SGGESX, SGGEV, SGGEVX, -*> SGGGLM, SGGHRD, SGGLSE, SGGQRF, SGGRQF, SGGSVD, SGGSVP, SHGEQZ, -*> SORCSD, STGEVC, STGEXC, STGSEN, STGSJA, STGSNA, and STGSYL. +*> SGGES3, SGGEV3, SGGGLM, SGGHRD, SGGLSE, SGGQRF, SGGRQF, SGGSVD, +*> SGGSVP, SHGEQZ, SORCSD, STGEVC, STGEXC, STGSEN, STGSJA, STGSNA, +*> and STGSYL. *> \endverbatim * * Arguments: @@ -44,10 +45,10 @@ * Authors: * ======== * -*> \author Univ. of Tennessee -*> \author Univ. of California Berkeley -*> \author Univ. of Colorado Denver -*> \author NAG Ltd. +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. * *> \date November 2011 * @@ -97,7 +98,7 @@ EXTERNAL CHKXER, SGGES, SGGESX, SGGEV, SGGEVX, SGGGLM, $ SGGHRD, SGGLSE, SGGQRF, SGGRQF, SGGSVD, SGGSVP, $ SHGEQZ, SORCSD, STGEVC, STGEXC, STGSEN, STGSJA, - $ STGSNA, STGSYL + $ STGSNA, STGSYL, SGGES3, SGGEV3, SGGHD3 * .. * .. Scalars in Common .. LOGICAL LERR, OK @@ -170,6 +171,47 @@ CALL CHKXER( 'SGGHRD', INFOT, NOUT, LERR, OK ) NT = NT + 9 * +* SGGHD3 +* + SRNAMT = 'SGGHD3' + INFOT = 1 + CALL SGGHD3( '/', 'N', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL SGGHD3( 'N', '/', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL SGGHD3( 'N', 'N', -1, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 4 + CALL SGGHD3( 'N', 'N', 0, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL SGGHD3( 'N', 'N', 0, 1, 1, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL SGGHD3( 'N', 'N', 2, 1, 1, A, 1, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL SGGHD3( 'N', 'N', 2, 1, 1, A, 2, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL SGGHD3( 'V', 'N', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL SGGHD3( 'N', 'V', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'SGGHD3', INFOT, NOUT, LERR, OK ) + NT = NT + 9 +* * SHGEQZ * SRNAMT = 'SHGEQZ' @@ -503,56 +545,56 @@ $ -1, 0, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 8 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, -1, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 9 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, -1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 11 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, -1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 20 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, -1, A, 1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 22 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, -1, A, 1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 24 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, -1, A, - $ 1, W, LW, IW, INFO ) + $ 1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) INFOT = 26 CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ -1, W, LW, IW, INFO ) + $ -1, W, LW, IW, INFO ) CALL CHKXER( 'SORCSD', INFOT, NOUT, LERR, OK ) NT = NT + 8 * @@ -662,6 +704,55 @@ CALL CHKXER( 'SGGES ', INFOT, NOUT, LERR, OK ) NT = NT + 11 * +* SGGES3 +* + SRNAMT = 'SGGES3' + INFOT = 1 + CALL SGGES3( '/', 'N', 'S', SLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL SGGES3( 'N', '/', 'S', SLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL SGGES3( 'N', 'V', '/', SLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL SGGES3( 'N', 'V', 'S', SLCTES, -1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL SGGES3( 'N', 'V', 'S', SLCTES, 1, A, 0, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL SGGES3( 'N', 'V', 'S', SLCTES, 1, A, 1, B, 0, SDIM, R1, + $ R2, R3, Q, 1, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL SGGES3( 'N', 'V', 'S', SLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 0, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL SGGES3( 'V', 'V', 'S', SLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 1, U, 2, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 17 + CALL SGGES3( 'N', 'V', 'S', SLCTES, 1, A, 1, B, 1, SDIM, R1, + $ R2, R3, Q, 1, U, 0, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 17 + CALL SGGES3( 'V', 'V', 'S', SLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 2, U, 1, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + INFOT = 19 + CALL SGGES3( 'V', 'V', 'S', SLCTES, 2, A, 2, B, 2, SDIM, R1, + $ R2, R3, Q, 2, U, 2, W, 1, BW, INFO ) + CALL CHKXER( 'SGGES3 ', INFOT, NOUT, LERR, OK ) + NT = NT + 11 +* * SGGESX * SRNAMT = 'SGGESX' @@ -777,6 +868,51 @@ CALL CHKXER( 'SGGEV ', INFOT, NOUT, LERR, OK ) NT = NT + 10 * +* SGGEV3 +* + SRNAMT = 'SGGEV3 ' + INFOT = 1 + CALL SGGEV3( '/', 'N', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL SGGEV3( 'N', '/', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL SGGEV3( 'V', 'V', -1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL SGGEV3( 'V', 'V', 1, A, 0, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL SGGEV3( 'V', 'V', 1, A, 1, B, 0, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 12 + CALL SGGEV3( 'N', 'V', 1, A, 1, B, 1, R1, R2, R3, Q, 0, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 12 + CALL SGGEV3( 'V', 'V', 2, A, 2, B, 2, R1, R2, R3, Q, 1, U, 2, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL SGGEV3( 'V', 'N', 2, A, 2, B, 2, R1, R2, R3, Q, 2, U, 0, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL SGGEV3( 'V', 'V', 2, A, 2, B, 2, R1, R2, R3, Q, 2, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL SGGEV3( 'V', 'V', 1, A, 1, B, 1, R1, R2, R3, Q, 1, U, 1, + $ W, 1, INFO ) + CALL CHKXER( 'SGGEV3 ', INFOT, NOUT, LERR, OK ) + NT = NT + 10 +* * SGGEVX * SRNAMT = 'SGGEVX' diff --git a/TESTING/EIG/zchkee.f b/TESTING/EIG/zchkee.f index ea58f377..7107da2d 100644 --- a/TESTING/EIG/zchkee.f +++ b/TESTING/EIG/zchkee.f @@ -44,7 +44,7 @@ *> Test ZGEESX *> *> ZGG (Generalized Nonsymmetric Eigenvalue Problem): -*> Test ZGGHRD, ZGGBAL, ZGGBAK, ZHGEQZ, and ZTGEVC +*> Test ZGGHD3, ZGGBAL, ZGGBAK, ZHGEQZ, and ZTGEVC *> and the driver routines ZGEGS and ZGEGV *> *> ZGS (Generalized Nonsymmetric Schur form Driver): @@ -489,38 +489,41 @@ *> line 8: MXBVAL, INTEGER array, dimension (NPARMS) *> The values for MAXB, used in determining minimum blocksize. *> -*> line 9: NBCOL, INTEGER array, dimension (NPARMS) +*> line 9: IACC22, INTEGER array, dimension (NPARMS) +*> select structured matrix multiply: 1 or 2) +*> +*> line 10: NBCOL, INTEGER array, dimension (NPARMS) *> The values for NBCOL, the minimum column dimension for *> blocks. *> -*> line 10: THRESH +*> line 11: THRESH *> Threshold value for the test ratios. Information will be *> printed about each test for which the test ratio is greater *> than or equal to the threshold. *> -*> line 11: TSTCHK, LOGICAL +*> line 12: TSTCHK, LOGICAL *> Flag indicating whether or not to test the LAPACK routines. *> -*> line 12: TSTDRV, LOGICAL +*> line 13: TSTDRV, LOGICAL *> Flag indicating whether or not to test the driver routines. *> -*> line 13: TSTERR, LOGICAL +*> line 14: TSTERR, LOGICAL *> Flag indicating whether or not to test the error exits for *> the LAPACK routines and driver routines. *> -*> line 14: NEWSD, INTEGER +*> line 15: NEWSD, INTEGER *> A code indicating how to set the random number seed. *> = 0: Set the seed to a default value before each run *> = 1: Initialize the seed to a default value only before the *> first run *> = 2: Like 1, but use the seed values on the next line *> -*> If line 14 was 2: +*> If line 15 was 2: *> -*> line 15: INTEGER array, dimension (4) +*> line 16: INTEGER array, dimension (4) *> Four integer values for the random number seed. *> -*> lines 16-EOF: Lines specifying matrix types, as for NEP. +*> lines 17-EOF: Lines specifying matrix types, as for NEP. *> The 3-character path name is 'ZGG' for the generalized *> eigenvalue problem routines and driver routines. *> @@ -1100,7 +1103,8 @@ $ ZCHKST, ZCKCSD, ZCKGLM, ZCKGQR, ZCKGSV, ZCKLSE, $ ZDRGES, ZDRGEV, ZDRGSX, ZDRGVX, ZDRVBD, ZDRVES, $ ZDRVEV, ZDRVGG, ZDRVSG, ZDRVST, ZDRVSX, ZDRVVX, - $ ZERRBD, ZERRED, ZERRGG, ZERRHS, ZERRST, ILAVER + $ ZERRBD, ZERRED, ZERRGG, ZERRHS, ZERRST, ILAVER, + $ ZDRGES3, ZDRGEV3 * .. * .. Intrinsic Functions .. INTRINSIC LEN, MIN @@ -1621,7 +1625,7 @@ * * Read the values for IACC22. * - IF( NEP ) THEN + IF( NEP .OR. ZGG ) THEN READ( NIN, FMT = * )( IACC22( I ), I = 1, NPARMS ) DO 620 I = 1, NPARMS IF( IACC22( I ).LT.0 ) THEN @@ -2090,6 +2094,7 @@ * NBMIN = minimum block size * NS = number of shifts * MAXB = minimum submatrix size +* IACC22: structured matrix multiply * NBCOL = minimum column dimension for blocks * MAXTYP = 26 @@ -2102,6 +2107,7 @@ CALL XLAENV( 2, NBMIN( I ) ) CALL XLAENV( 4, NSVAL( I ) ) CALL XLAENV( 8, MXBVAL( I ) ) + CALL XLAENV( 16, IACC22( I ) ) CALL XLAENV( 5, NBCOL( I ) ) * IF( NEWSD.EQ.0 ) THEN @@ -2110,7 +2116,7 @@ 340 CONTINUE END IF WRITE( NOUT, FMT = 9996 )C3, NBVAL( I ), NBMIN( I ), - $ NSVAL( I ), MXBVAL( I ), NBCOL( I ) + $ NSVAL( I ), MXBVAL( I ), IACC22( I ), NBCOL( I ) TSTDIF = .FALSE. THRSHN = 10.D0 IF( TSTCHK ) THEN @@ -2162,6 +2168,17 @@ * IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'ZDRGES', INFO +* +* Blocked version +* + CALL ZDRGES3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ DC( 1, 1 ), DC( 1, 2 ), WORK, LWORK, RWORK, + $ RESULT, LOGWRK, INFO ) +* + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'ZDRGES3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2206,7 +2223,7 @@ WRITE( NOUT, FMT = 9990 )C3 ELSE IF( TSTERR ) - $ CALL ZERRGG( C3, NOUT ) + $ CALL ZERRGG( C3, NOUT ) CALL ALAREQ( C3, NTYPES, DOTYPE, MAXTYP, NIN, NOUT ) CALL ZDRGEV( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), @@ -2216,6 +2233,17 @@ $ RESULT, INFO ) IF( INFO.NE.0 ) $ WRITE( NOUT, FMT = 9980 )'ZDRGEV', INFO +* +* Blocked version +* + CALL ZDRGEV3( NN, NVAL, MAXTYP, DOTYPE, ISEED, THRESH, NOUT, + $ A( 1, 1 ), NMAX, A( 1, 2 ), A( 1, 3 ), + $ A( 1, 4 ), A( 1, 7 ), NMAX, A( 1, 8 ), + $ A( 1, 9 ), NMAX, DC( 1, 1 ), DC( 1, 2 ), + $ DC( 1, 3 ), DC( 1, 4 ), WORK, LWORK, RWORK, + $ RESULT, INFO ) + IF( INFO.NE.0 ) + $ WRITE( NOUT, FMT = 9980 )'ZDRGEV3', INFO END IF WRITE( NOUT, FMT = 9973 ) GO TO 10 @@ -2388,7 +2416,7 @@ 9999 FORMAT( / ' Execution not attempted due to input errors' ) 9997 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4 ) 9996 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NS =', I4, - $ ', MAXB =', I4, ', NBCOL =', I4 ) + $ ', MAXB =', I4, ', IACC22 =', I4, ', NBCOL =', I4 ) 9995 FORMAT( / / 1X, A3, ': NB =', I4, ', NBMIN =', I4, ', NX =', I4, $ ', NRHS =', I4 ) 9994 FORMAT( / / ' End of tests' ) diff --git a/TESTING/EIG/zdrges3.f b/TESTING/EIG/zdrges3.f new file mode 100644 index 00000000..9a427739 --- /dev/null +++ b/TESTING/EIG/zdrges3.f @@ -0,0 +1,940 @@ +*> \brief \b ZDRGES3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE ZDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHA, +* BETA, WORK, LWORK, RWORK, RESULT, BWORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES +* DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. +* LOGICAL BWORK( * ), DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* DOUBLE PRECISION RESULT( 13 ), RWORK( * ) +* COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDA, * ), +* $ BETA( * ), Q( LDQ, * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> ZDRGES3 checks the nonsymmetric generalized eigenvalue (Schur form) +*> problem driver ZGGES3. +*> +*> ZGGES3 factors A and B as Q*S*Z' and Q*T*Z' , where ' means conjugate +*> transpose, S and T are upper triangular (i.e., in generalized Schur +*> form), and Q and Z are unitary. It also computes the generalized +*> eigenvalues (alpha(j),beta(j)), j=1,...,n. Thus, +*> w(j) = alpha(j)/beta(j) is a root of the characteristic equation +*> +*> det( A - w(j) B ) = 0 +*> +*> Optionally it also reorder the eigenvalues so that a selected +*> cluster of eigenvalues appears in the leading diagonal block of the +*> Schur forms. +*> +*> When ZDRGES3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following 13 tests +*> will be performed and compared with the threshhold THRESH except +*> the tests (5), (11) and (13). +*> +*> +*> (1) | A - Q S Z' | / ( |A| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (2) | B - Q T Z' | / ( |B| n ulp ) (no sorting of eigenvalues) +*> +*> +*> (3) | I - QQ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> +*> (4) | I - ZZ' | / ( n ulp ) (no sorting of eigenvalues) +*> +*> (5) if A is in Schur form (i.e. triangular form) (no sorting of +*> eigenvalues) +*> +*> (6) if eigenvalues = diagonal elements of the Schur form (S, T), +*> i.e., test the maximum over j of D(j) where: +*> +*> |alpha(j) - S(j,j)| |beta(j) - T(j,j)| +*> D(j) = ------------------------ + ----------------------- +*> max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|) +*> +*> (no sorting of eigenvalues) +*> +*> (7) | (A,B) - Q (S,T) Z' | / ( |(A,B)| n ulp ) +*> (with sorting of eigenvalues). +*> +*> (8) | I - QQ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (9) | I - ZZ' | / ( n ulp ) (with sorting of eigenvalues). +*> +*> (10) if A is in Schur form (i.e. quasi-triangular form) +*> (with sorting of eigenvalues). +*> +*> (11) if eigenvalues = diagonal elements of the Schur form (S, T), +*> i.e. test the maximum over j of D(j) where: +*> +*> |alpha(j) - S(j,j)| |beta(j) - T(j,j)| +*> D(j) = ------------------------ + ----------------------- +*> max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|) +*> +*> (with sorting of eigenvalues). +*> +*> (12) if sorting worked and SDIM is the number of eigenvalues +*> which were CELECTed. +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> DDRGES3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, DDRGES3 +*> 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 on input. +*> This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and +*> DOTYPE(MAXTYP+1) is .TRUE. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 DDRGES3 to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is DOUBLE PRECISION +*> 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. THRESH >= 0. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IINFO not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is COMPLEX*16 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is COMPLEX*16 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is COMPLEX*16 array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by ZGGES3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is COMPLEX*16 array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by ZGGES3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is COMPLEX*16 array, dimension (LDQ, max(NN)) +*> The (left) orthogonal matrix computed by ZGGES3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is COMPLEX*16 array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by ZGGES3. +*> \endverbatim +*> +*> \param[out] ALPHA +*> \verbatim +*> ALPHA is COMPLEX*16 array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is COMPLEX*16 array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by ZGGES3. +*> ALPHA(k) / BETA(k) is the k-th generalized eigenvalue of A +*> and B. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is COMPLEX*16 array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. LWORK >= 3*N*N. +*> \endverbatim +*> +*> \param[out] RWORK +*> \verbatim +*> RWORK is DOUBLE PRECISION array, dimension ( 8*N ) +*> Real workspace. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is DOUBLE PRECISION array, dimension (15) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] BWORK +*> \verbatim +*> BWORK is LOGICAL array, dimension (N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date February 2015 +* +*> \ingroup complex16_eig +* +* ===================================================================== + SUBROUTINE ZDRGES3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, ALPHA, + $ BETA, WORK, LWORK, RWORK, RESULT, BWORK, + $ INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES + DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. + LOGICAL BWORK( * ), DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + DOUBLE PRECISION RESULT( 13 ), RWORK( * ) + COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDA, * ), + $ BETA( * ), Q( LDQ, * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) + COMPLEX*16 CZERO, CONE + PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ), + $ CONE = ( 1.0D+0, 0.0D+0 ) ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN, ILABAD + CHARACTER SORT + INTEGER I, IADD, IINFO, IN, ISORT, J, JC, JR, JSIZE, + $ JTYPE, KNTEIG, MAXWRK, MINWRK, MTYPES, N, N1, + $ NB, NERRS, NMATS, NMAX, NTEST, NTESTT, RSUB, + $ SDIM + DOUBLE PRECISION SAFMAX, SAFMIN, TEMP1, TEMP2, ULP, ULPINV + COMPLEX*16 CTEMP, X +* .. +* .. Local Arrays .. + LOGICAL LASIGN( MAXTYP ), LBSIGN( MAXTYP ) + INTEGER IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + DOUBLE PRECISION RMAGN( 0: 3 ) +* .. +* .. External Functions .. + LOGICAL ZLCTES + INTEGER ILAENV + DOUBLE PRECISION DLAMCH + COMPLEX*16 ZLARND + EXTERNAL ZLCTES, ILAENV, DLAMCH, ZLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, DLABAD, XERBLA, ZGET51, ZGET54, ZGGES3, + $ ZLACPY, ZLARFG, ZLASET, ZLATM4, ZUNM2R +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SIGN +* .. +* .. Statement Functions .. + DOUBLE PRECISION ABS1 +* .. +* .. Statement Function definitions .. + ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) ) +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA LASIGN / 6*.FALSE., .TRUE., .FALSE., 2*.TRUE., + $ 2*.FALSE., 3*.TRUE., .FALSE., .TRUE., + $ 3*.FALSE., 5*.TRUE., .FALSE. / + DATA LBSIGN / 7*.FALSE., .TRUE., 2*.FALSE., + $ 2*.TRUE., 2*.FALSE., .TRUE., .FALSE., .TRUE., + $ 9*.FALSE. / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = 3*NMAX*NMAX + NB = MAX( 1, ILAENV( 1, 'ZGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'ZUNMQR', 'LC', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'ZUNGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( NMAX+NMAX*NB, 3*NMAX*NMAX ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -19 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'ZDRGES3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + ULP = DLAMCH( 'Precision' ) + SAFMIN = DLAMCH( 'Safe minimum' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL DLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over matrix sizes +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 190 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / DBLE( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*DBLE( N1 ) +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* +* Loop over matrix types +* + DO 180 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 180 + NMATS = NMATS + 1 + NTEST = 0 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Initialize RESULT +* + DO 30 J = 1, 13 + RESULT( J ) = ZERO + 30 CONTINUE +* +* Generate test matrices A and B +* +* Description of control parameters: +* +* KZLASS: =1 means w/o rotation, =2 means w/ rotation, +* =3 means random. +* KATYPE: the "type" to be passed to ZLATM4 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. +* LASIGN: .TRUE. if the diagonal elements of A are to be +* multiplied by a random magnitude 1 number. +* KBTYPE, KBZERO, KBMAGN, LBSIGN: 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.GT.MAXTYP ) + $ GO TO 110 + IINFO = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, A, LDA ) + ELSE + IN = N + END IF + CALL ZLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), LASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = RMAGN( KAMAGN( JTYPE ) ) +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, B, LDA ) + ELSE + IN = N + END IF + CALL ZLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), LBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = RMAGN( KBMAGN( JTYPE ) ) +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 50 JC = 1, N - 1 + DO 40 JR = JC, N + Q( JR, JC ) = ZLARND( 3, ISEED ) + Z( JR, JC ) = ZLARND( 3, ISEED ) + 40 CONTINUE + CALL ZLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, DBLE( Q( JC, JC ) ) ) + Q( JC, JC ) = CONE + CALL ZLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, DBLE( Z( JC, JC ) ) ) + Z( JC, JC ) = CONE + 50 CONTINUE + CTEMP = ZLARND( 3, ISEED ) + Q( N, N ) = CONE + WORK( N ) = CZERO + WORK( 3*N ) = CTEMP / ABS( CTEMP ) + CTEMP = ZLARND( 3, ISEED ) + Z( N, N ) = CONE + WORK( 2*N ) = CZERO + WORK( 4*N ) = CTEMP / ABS( CTEMP ) +* +* Apply the diagonal matrices +* + DO 70 JC = 1, N + DO 60 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )* + $ DCONJG( WORK( 3*N+JC ) )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )* + $ DCONJG( WORK( 3*N+JC ) )* + $ B( JR, JC ) + 60 CONTINUE + 70 CONTINUE + CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IINFO ) + IF( IINFO.NE.0 ) + $ GO TO 100 + END IF + ELSE +* +* Random matrices +* + DO 90 JC = 1, N + DO 80 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ ZLARND( 4, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ ZLARND( 4, ISEED ) + 80 CONTINUE + 90 CONTINUE + END IF +* + 100 CONTINUE +* + IF( IINFO.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + RETURN + END IF +* + 110 CONTINUE +* + DO 120 I = 1, 13 + RESULT( I ) = -ONE + 120 CONTINUE +* +* Test with and without sorting of eigenvalues +* + DO 150 ISORT = 0, 1 + IF( ISORT.EQ.0 ) THEN + SORT = 'N' + RSUB = 0 + ELSE + SORT = 'S' + RSUB = 5 + END IF +* +* Call ZGGES3 to compute H, T, Q, Z, alpha, and beta. +* + CALL ZLACPY( 'Full', N, N, A, LDA, S, LDA ) + CALL ZLACPY( 'Full', N, N, B, LDA, T, LDA ) + NTEST = 1 + RSUB + ISORT + RESULT( 1+RSUB+ISORT ) = ULPINV + CALL ZGGES3( 'V', 'V', SORT, ZLCTES, N, S, LDA, T, LDA, + $ SDIM, ALPHA, BETA, Q, LDQ, Z, LDQ, WORK, + $ LWORK, RWORK, BWORK, IINFO ) + IF( IINFO.NE.0 .AND. IINFO.NE.N+2 ) THEN + RESULT( 1+RSUB+ISORT ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'ZGGES3', IINFO, N, JTYPE, + $ IOLDSD + INFO = ABS( IINFO ) + GO TO 160 + END IF +* + NTEST = 4 + RSUB +* +* Do tests 1--4 (or tests 7--9 when reordering ) +* + IF( ISORT.EQ.0 ) THEN + CALL ZGET51( 1, N, A, LDA, S, LDA, Q, LDQ, Z, LDQ, + $ WORK, RWORK, RESULT( 1 ) ) + CALL ZGET51( 1, N, B, LDA, T, LDA, Q, LDQ, Z, LDQ, + $ WORK, RWORK, RESULT( 2 ) ) + ELSE + CALL ZGET54( N, A, LDA, B, LDA, S, LDA, T, LDA, Q, + $ LDQ, Z, LDQ, WORK, RESULT( 2+RSUB ) ) + END IF +* + CALL ZGET51( 3, N, B, LDA, T, LDA, Q, LDQ, Q, LDQ, WORK, + $ RWORK, RESULT( 3+RSUB ) ) + CALL ZGET51( 3, N, B, LDA, T, LDA, Z, LDQ, Z, LDQ, WORK, + $ RWORK, RESULT( 4+RSUB ) ) +* +* Do test 5 and 6 (or Tests 10 and 11 when reordering): +* check Schur form of A and compare eigenvalues with +* diagonals. +* + NTEST = 6 + RSUB + TEMP1 = ZERO +* + DO 130 J = 1, N + ILABAD = .FALSE. + TEMP2 = ( ABS1( ALPHA( J )-S( J, J ) ) / + $ MAX( SAFMIN, ABS1( ALPHA( J ) ), ABS1( S( J, + $ J ) ) )+ABS1( BETA( J )-T( J, J ) ) / + $ MAX( SAFMIN, ABS1( BETA( J ) ), ABS1( T( J, + $ J ) ) ) ) / ULP +* + IF( J.LT.N ) THEN + IF( S( J+1, J ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + IF( J.GT.1 ) THEN + IF( S( J, J-1 ).NE.ZERO ) THEN + ILABAD = .TRUE. + RESULT( 5+RSUB ) = ULPINV + END IF + END IF + TEMP1 = MAX( TEMP1, TEMP2 ) + IF( ILABAD ) THEN + WRITE( NOUNIT, FMT = 9998 )J, N, JTYPE, IOLDSD + END IF + 130 CONTINUE + RESULT( 6+RSUB ) = TEMP1 +* + IF( ISORT.GE.1 ) THEN +* +* Do test 12 +* + NTEST = 12 + RESULT( 12 ) = ZERO + KNTEIG = 0 + DO 140 I = 1, N + IF( ZLCTES( ALPHA( I ), BETA( I ) ) ) + $ KNTEIG = KNTEIG + 1 + 140 CONTINUE + IF( SDIM.NE.KNTEIG ) + $ RESULT( 13 ) = ULPINV + END IF +* + 150 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 160 CONTINUE +* + NTESTT = NTESTT + NTEST +* +* Print out tests which fail. +* + DO 170 JR = 1, NTEST + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'ZGS' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Unitary' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 )'unitary', '''', + $ 'transpose', ( '''', J = 1, 8 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0D0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 170 CONTINUE +* + 180 CONTINUE + 190 CONTINUE +* +* Summary +* + CALL ALASVM( 'ZGS', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' ZDRGES3: ', A, ' returned INFO=', I6, '.', / 9X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 4( I4, ',' ), I5, ')' ) +* + 9998 FORMAT( ' ZDRGES3: S not in Schur form at eigenvalue ', I6, '.', + $ / 9X, 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), + $ I5, ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Complex Generalized Schur from problem ', + $ 'driver' ) +* + 9996 FORMAT( ' Matrix types (see ZDRGES3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: (S is Schur, T is triangular, ', + $ 'Q and Z are ', A, ',', / 19X, + $ 'l and r are the appropriate left and right', / 19X, + $ 'eigenvectors, resp., a is alpha, b is beta, and', / 19X, A, + $ ' means ', A, '.)', / ' Without ordering: ', + $ / ' 1 = | A - Q S Z', A, + $ ' | / ( |A| n ulp ) 2 = | B - Q T Z', A, + $ ' | / ( |B| n ulp )', / ' 3 = | I - QQ', A, + $ ' | / ( n ulp ) 4 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 5 = A is in Schur form S', + $ / ' 6 = difference between (alpha,beta)', + $ ' and diagonals of (S,T)', / ' With ordering: ', + $ / ' 7 = | (A,B) - Q (S,T) Z', A, ' | / ( |(A,B)| n ulp )', + $ / ' 8 = | I - QQ', A, + $ ' | / ( n ulp ) 9 = | I - ZZ', A, + $ ' | / ( n ulp )', / ' 10 = A is in Schur form S', + $ / ' 11 = difference between (alpha,beta) and diagonals', + $ ' of (S,T)', / ' 12 = SDIM is the correct number of ', + $ 'selected eigenvalues', / ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, D10.3 ) +* +* End of ZDRGES3 +* + END diff --git a/TESTING/EIG/zdrgev3.f b/TESTING/EIG/zdrgev3.f new file mode 100644 index 00000000..198bf33b --- /dev/null +++ b/TESTING/EIG/zdrgev3.f @@ -0,0 +1,939 @@ +*> \brief \b ZDRGEV3 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE ZDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, +* NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, +* ALPHA, BETA, ALPHA1, BETA1, WORK, LWORK, RWORK, +* RESULT, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, +* $ NTYPES +* DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. +* LOGICAL DOTYPE( * ) +* INTEGER ISEED( 4 ), NN( * ) +* DOUBLE PRECISION RESULT( * ), RWORK( * ) +* COMPLEX*16 A( LDA, * ), ALPHA( * ), ALPHA1( * ), +* $ B( LDA, * ), BETA( * ), BETA1( * ), +* $ Q( LDQ, * ), QE( LDQE, * ), S( LDA, * ), +* $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> ZDRGEV3 checks the nonsymmetric generalized eigenvalue problem driver +*> routine ZGGEV3. +*> +*> ZGGEV3 computes for a pair of n-by-n nonsymmetric matrices (A,B) the +*> generalized eigenvalues and, optionally, the left and right +*> eigenvectors. +*> +*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w +*> or a ratio alpha/beta = w, such that A - w*B is singular. It is +*> usually represented as the pair (alpha,beta), as there is reasonable +*> interpretation for beta=0, and even for both being zero. +*> +*> A right generalized eigenvector corresponding to a generalized +*> eigenvalue w for a pair of matrices (A,B) is a vector r such that +*> (A - wB) * r = 0. A left generalized eigenvector is a vector l such +*> that l**H * (A - wB) = 0, where l**H is the conjugate-transpose of l. +*> +*> When ZDRGEV3 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, a pair of matrices (A, B) will be generated +*> and used for testing. For each matrix pair, the following tests +*> will be performed and compared with the threshhold THRESH. +*> +*> Results from ZGGEV3: +*> +*> (1) max over all left eigenvalue/-vector pairs (alpha/beta,l) of +*> +*> | VL**H * (beta A - alpha B) |/( ulp max(|beta A|, |alpha B|) ) +*> +*> where VL**H is the conjugate-transpose of VL. +*> +*> (2) | |VL(i)| - 1 | / ulp and whether largest component real +*> +*> VL(i) denotes the i-th column of VL. +*> +*> (3) max over all left eigenvalue/-vector pairs (alpha/beta,r) of +*> +*> | (beta A - alpha B) * VR | / ( ulp max(|beta A|, |alpha B|) ) +*> +*> (4) | |VR(i)| - 1 | / ulp and whether largest component real +*> +*> VR(i) denotes the i-th column of VR. +*> +*> (5) W(full) = W(partial) +*> W(full) denotes the eigenvalues computed when both l and r +*> are also computed, and W(partial) denotes the eigenvalues +*> computed when only W, only W and r, or only W and l are +*> computed. +*> +*> (6) VL(full) = VL(partial) +*> VL(full) denotes the left eigenvectors computed when both l +*> and r are computed, and VL(partial) denotes the result +*> when only l is computed. +*> +*> (7) VR(full) = VR(partial) +*> VR(full) denotes the right eigenvectors computed when both l +*> and r are also computed, and VR(partial) denotes the result +*> when only l is computed. +*> +*> +*> 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. +*> +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NSIZES +*> \verbatim +*> NSIZES is INTEGER +*> The number of sizes of matrices to use. If it is zero, +*> ZDRGEV3 does nothing. NSIZES >= 0. +*> \endverbatim +*> +*> \param[in] NN +*> \verbatim +*> NN is INTEGER array, dimension (NSIZES) +*> An array containing the sizes to be used for the matrices. +*> Zero values will be skipped. NN >= 0. +*> \endverbatim +*> +*> \param[in] NTYPES +*> \verbatim +*> NTYPES is INTEGER +*> The number of elements in DOTYPE. If it is zero, ZDRGEV3 +*> 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. . +*> \endverbatim +*> +*> \param[in] DOTYPE +*> \verbatim +*> DOTYPE is 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. +*> \endverbatim +*> +*> \param[in,out] ISEED +*> \verbatim +*> ISEED is 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 ZDRGES to continue the same random number +*> sequence. +*> \endverbatim +*> +*> \param[in] THRESH +*> \verbatim +*> THRESH is DOUBLE PRECISION +*> 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. +*> \endverbatim +*> +*> \param[in] NOUNIT +*> \verbatim +*> NOUNIT is INTEGER +*> The FORTRAN unit number for printing out error messages +*> (e.g., if a routine returns IERR not equal to 0.) +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is COMPLEX*16 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. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of A, B, S, and T. +*> It must be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is COMPLEX*16 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. +*> \endverbatim +*> +*> \param[out] S +*> \verbatim +*> S is COMPLEX*16 array, dimension (LDA, max(NN)) +*> The Schur form matrix computed from A by ZGGEV3. On exit, S +*> contains the Schur form matrix corresponding to the matrix +*> in A. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is COMPLEX*16 array, dimension (LDA, max(NN)) +*> The upper triangular matrix computed from B by ZGGEV3. +*> \endverbatim +*> +*> \param[out] Q +*> \verbatim +*> Q is COMPLEX*16 array, dimension (LDQ, max(NN)) +*> The (left) eigenvectors matrix computed by ZGGEV3. +*> \endverbatim +*> +*> \param[in] LDQ +*> \verbatim +*> LDQ is INTEGER +*> The leading dimension of Q and Z. It must +*> be at least 1 and at least max( NN ). +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is COMPLEX*16 array, dimension( LDQ, max(NN) ) +*> The (right) orthogonal matrix computed by ZGGEV3. +*> \endverbatim +*> +*> \param[out] QE +*> \verbatim +*> QE is COMPLEX*16 array, dimension( LDQ, max(NN) ) +*> QE holds the computed right or left eigenvectors. +*> \endverbatim +*> +*> \param[in] LDQE +*> \verbatim +*> LDQE is INTEGER +*> The leading dimension of QE. LDQE >= max(1,max(NN)). +*> \endverbatim +*> +*> \param[out] ALPHA +*> \verbatim +*> ALPHA is COMPLEX*16 array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA +*> \verbatim +*> BETA is COMPLEX*16 array, dimension (max(NN)) +*> +*> The generalized eigenvalues of (A,B) computed by ZGGEV3. +*> ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th +*> generalized eigenvalue of A and B. +*> \endverbatim +*> +*> \param[out] ALPHA1 +*> \verbatim +*> ALPHA1 is COMPLEX*16 array, dimension (max(NN)) +*> \endverbatim +*> +*> \param[out] BETA1 +*> \verbatim +*> BETA1 is COMPLEX*16 array, dimension (max(NN)) +*> +*> Like ALPHAR, ALPHAI, BETA, these arrays contain the +*> eigenvalues of A and B, but those computed when ZGGEV3 only +*> computes a partial eigendecomposition, i.e. not the +*> eigenvalues and left and right eigenvectors. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is COMPLEX*16 array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The number of entries in WORK. LWORK >= N*(N+1) +*> \endverbatim +*> +*> \param[out] RWORK +*> \verbatim +*> RWORK is DOUBLE PRECISION array, dimension (8*N) +*> Real workspace. +*> \endverbatim +*> +*> \param[out] RESULT +*> \verbatim +*> RESULT is DOUBLE PRECISION array, dimension (2) +*> The values computed by the tests described above. +*> The values are currently limited to 1/ulp, to avoid overflow. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is 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. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date Febuary 2015 +* +*> \ingroup complex16_eig +* +* ===================================================================== + SUBROUTINE ZDRGEV3( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH, + $ NOUNIT, A, LDA, B, S, T, Q, LDQ, Z, QE, LDQE, + $ ALPHA, BETA, ALPHA1, BETA1, WORK, LWORK, + $ RWORK, RESULT, INFO ) +* +* -- LAPACK test routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* February 2015 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDQ, LDQE, LWORK, NOUNIT, NSIZES, + $ NTYPES + DOUBLE PRECISION THRESH +* .. +* .. Array Arguments .. + LOGICAL DOTYPE( * ) + INTEGER ISEED( 4 ), NN( * ) + DOUBLE PRECISION RESULT( * ), RWORK( * ) + COMPLEX*16 A( LDA, * ), ALPHA( * ), ALPHA1( * ), + $ B( LDA, * ), BETA( * ), BETA1( * ), + $ Q( LDQ, * ), QE( LDQE, * ), S( LDA, * ), + $ T( LDA, * ), WORK( * ), Z( LDQ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) + COMPLEX*16 CZERO, CONE + PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ), + $ CONE = ( 1.0D+0, 0.0D+0 ) ) + INTEGER MAXTYP + PARAMETER ( MAXTYP = 26 ) +* .. +* .. Local Scalars .. + LOGICAL BADNN + INTEGER I, IADD, IERR, IN, J, JC, JR, JSIZE, JTYPE, + $ MAXWRK, MINWRK, MTYPES, N, N1, NB, NERRS, + $ NMATS, NMAX, NTESTT + DOUBLE PRECISION SAFMAX, SAFMIN, ULP, ULPINV + COMPLEX*16 CTEMP +* .. +* .. Local Arrays .. + LOGICAL LASIGN( MAXTYP ), LBSIGN( MAXTYP ) + INTEGER IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ), + $ KATYPE( MAXTYP ), KAZERO( MAXTYP ), + $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ), + $ KBZERO( MAXTYP ), KCLASS( MAXTYP ), + $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 ) + DOUBLE PRECISION RMAGN( 0: 3 ) +* .. +* .. External Functions .. + INTEGER ILAENV + DOUBLE PRECISION DLAMCH + COMPLEX*16 ZLARND + EXTERNAL ILAENV, DLAMCH, ZLARND +* .. +* .. External Subroutines .. + EXTERNAL ALASVM, DLABAD, XERBLA, ZGET52, ZGGEV3, ZLACPY, + $ ZLARFG, ZLASET, ZLATM4, ZUNM2R +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, DCONJG, MAX, MIN, SIGN +* .. +* .. Data statements .. + DATA KCLASS / 15*1, 10*2, 1*3 / + DATA KZ1 / 0, 1, 2, 1, 3, 3 / + DATA KZ2 / 0, 0, 1, 2, 1, 1 / + DATA KADD / 0, 0, 0, 0, 3, 2 / + DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4, + $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 / + DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4, + $ 1, 1, -4, 2, -4, 8*8, 0 / + DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3, + $ 4*5, 4*3, 1 / + DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4, + $ 4*6, 4*4, 1 / + DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3, + $ 2, 1 / + DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3, + $ 2, 1 / + DATA KTRIAN / 16*0, 10*1 / + DATA LASIGN / 6*.FALSE., .TRUE., .FALSE., 2*.TRUE., + $ 2*.FALSE., 3*.TRUE., .FALSE., .TRUE., + $ 3*.FALSE., 5*.TRUE., .FALSE. / + DATA LBSIGN / 7*.FALSE., .TRUE., 2*.FALSE., + $ 2*.TRUE., 2*.FALSE., .TRUE., .FALSE., .TRUE., + $ 9*.FALSE. / +* .. +* .. Executable Statements .. +* +* Check for errors +* + INFO = 0 +* + BADNN = .FALSE. + NMAX = 1 + DO 10 J = 1, NSIZES + NMAX = MAX( NMAX, NN( J ) ) + IF( NN( J ).LT.0 ) + $ BADNN = .TRUE. + 10 CONTINUE +* + IF( NSIZES.LT.0 ) THEN + INFO = -1 + ELSE IF( BADNN ) THEN + INFO = -2 + ELSE IF( NTYPES.LT.0 ) THEN + INFO = -3 + ELSE IF( THRESH.LT.ZERO ) THEN + INFO = -6 + ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN + INFO = -9 + ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN + INFO = -14 + ELSE IF( LDQE.LE.1 .OR. LDQE.LT.NMAX ) THEN + INFO = -17 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV. +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MINWRK = NMAX*( NMAX+1 ) + NB = MAX( 1, ILAENV( 1, 'ZGEQRF', ' ', NMAX, NMAX, -1, -1 ), + $ ILAENV( 1, 'ZUNMQR', 'LC', NMAX, NMAX, NMAX, -1 ), + $ ILAENV( 1, 'ZUNGQR', ' ', NMAX, NMAX, NMAX, -1 ) ) + MAXWRK = MAX( 2*NMAX, NMAX*( NB+1 ), NMAX*( NMAX+1 ) ) + WORK( 1 ) = MAXWRK + END IF +* + IF( LWORK.LT.MINWRK ) + $ INFO = -23 +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'ZDRGEV3', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 ) + $ RETURN +* + ULP = DLAMCH( 'Precision' ) + SAFMIN = DLAMCH( 'Safe minimum' ) + SAFMIN = SAFMIN / ULP + SAFMAX = ONE / SAFMIN + CALL DLABAD( SAFMIN, SAFMAX ) + ULPINV = ONE / ULP +* +* The values RMAGN(2:3) depend on N, see below. +* + RMAGN( 0 ) = ZERO + RMAGN( 1 ) = ONE +* +* Loop over sizes, types +* + NTESTT = 0 + NERRS = 0 + NMATS = 0 +* + DO 220 JSIZE = 1, NSIZES + N = NN( JSIZE ) + N1 = MAX( 1, N ) + RMAGN( 2 ) = SAFMAX*ULP / DBLE( N1 ) + RMAGN( 3 ) = SAFMIN*ULPINV*N1 +* + IF( NSIZES.NE.1 ) THEN + MTYPES = MIN( MAXTYP, NTYPES ) + ELSE + MTYPES = MIN( MAXTYP+1, NTYPES ) + END IF +* + DO 210 JTYPE = 1, MTYPES + IF( .NOT.DOTYPE( JTYPE ) ) + $ GO TO 210 + NMATS = NMATS + 1 +* +* Save ISEED in case of an error. +* + DO 20 J = 1, 4 + IOLDSD( J ) = ISEED( J ) + 20 CONTINUE +* +* Generate test matrices A and B +* +* Description of control parameters: +* +* KZLASS: =1 means w/o rotation, =2 means w/ rotation, +* =3 means random. +* KATYPE: the "type" to be passed to ZLATM4 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. +* LASIGN: .TRUE. if the diagonal elements of A are to be +* multiplied by a random magnitude 1 number. +* KBTYPE, KBZERO, KBMAGN, LBSIGN: 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.GT.MAXTYP ) + $ GO TO 100 + IERR = 0 + IF( KCLASS( JTYPE ).LT.3 ) THEN +* +* Generate A (w/o rotation) +* + IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, A, LDA ) + ELSE + IN = N + END IF + CALL ZLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ), + $ KZ2( KAZERO( JTYPE ) ), LASIGN( JTYPE ), + $ RMAGN( KAMAGN( JTYPE ) ), ULP, + $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2, + $ ISEED, A, LDA ) + IADD = KADD( KAZERO( JTYPE ) ) + IF( IADD.GT.0 .AND. IADD.LE.N ) + $ A( IADD, IADD ) = RMAGN( KAMAGN( JTYPE ) ) +* +* Generate B (w/o rotation) +* + IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN + IN = 2*( ( N-1 ) / 2 ) + 1 + IF( IN.NE.N ) + $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, B, LDA ) + ELSE + IN = N + END IF + CALL ZLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ), + $ KZ2( KBZERO( JTYPE ) ), LBSIGN( JTYPE ), + $ RMAGN( KBMAGN( JTYPE ) ), ONE, + $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2, + $ ISEED, B, LDA ) + IADD = KADD( KBZERO( JTYPE ) ) + IF( IADD.NE.0 .AND. IADD.LE.N ) + $ B( IADD, IADD ) = RMAGN( KBMAGN( JTYPE ) ) +* + IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN +* +* Include rotations +* +* Generate Q, Z as Householder transformations times +* a diagonal matrix. +* + DO 40 JC = 1, N - 1 + DO 30 JR = JC, N + Q( JR, JC ) = ZLARND( 3, ISEED ) + Z( JR, JC ) = ZLARND( 3, ISEED ) + 30 CONTINUE + CALL ZLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1, + $ WORK( JC ) ) + WORK( 2*N+JC ) = SIGN( ONE, DBLE( Q( JC, JC ) ) ) + Q( JC, JC ) = CONE + CALL ZLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1, + $ WORK( N+JC ) ) + WORK( 3*N+JC ) = SIGN( ONE, DBLE( Z( JC, JC ) ) ) + Z( JC, JC ) = CONE + 40 CONTINUE + CTEMP = ZLARND( 3, ISEED ) + Q( N, N ) = CONE + WORK( N ) = CZERO + WORK( 3*N ) = CTEMP / ABS( CTEMP ) + CTEMP = ZLARND( 3, ISEED ) + Z( N, N ) = CONE + WORK( 2*N ) = CZERO + WORK( 4*N ) = CTEMP / ABS( CTEMP ) +* +* Apply the diagonal matrices +* + DO 60 JC = 1, N + DO 50 JR = 1, N + A( JR, JC ) = WORK( 2*N+JR )* + $ DCONJG( WORK( 3*N+JC ) )* + $ A( JR, JC ) + B( JR, JC ) = WORK( 2*N+JR )* + $ DCONJG( WORK( 3*N+JC ) )* + $ B( JR, JC ) + 50 CONTINUE + 60 CONTINUE + CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ A, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B, + $ LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ), + $ B, LDA, WORK( 2*N+1 ), IERR ) + IF( IERR.NE.0 ) + $ GO TO 90 + END IF + ELSE +* +* Random matrices +* + DO 80 JC = 1, N + DO 70 JR = 1, N + A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )* + $ ZLARND( 4, ISEED ) + B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )* + $ ZLARND( 4, ISEED ) + 70 CONTINUE + 80 CONTINUE + END IF +* + 90 CONTINUE +* + IF( IERR.NE.0 ) THEN + WRITE( NOUNIT, FMT = 9999 )'Generator', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + RETURN + END IF +* + 100 CONTINUE +* + DO 110 I = 1, 7 + RESULT( I ) = -ONE + 110 CONTINUE +* +* Call ZGGEV3 to compute eigenvalues and eigenvectors. +* + CALL ZLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL ZLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL ZGGEV3( 'V', 'V', N, S, LDA, T, LDA, ALPHA, BETA, Q, + $ LDQ, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'ZGGEV31', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* +* Do the tests (1) and (2) +* + CALL ZGET52( .TRUE., N, A, LDA, B, LDA, Q, LDQ, ALPHA, BETA, + $ WORK, RWORK, RESULT( 1 ) ) + IF( RESULT( 2 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Left', 'ZGGEV31', + $ RESULT( 2 ), N, JTYPE, IOLDSD + END IF +* +* Do the tests (3) and (4) +* + CALL ZGET52( .FALSE., N, A, LDA, B, LDA, Z, LDQ, ALPHA, + $ BETA, WORK, RWORK, RESULT( 3 ) ) + IF( RESULT( 4 ).GT.THRESH ) THEN + WRITE( NOUNIT, FMT = 9998 )'Right', 'ZGGEV31', + $ RESULT( 4 ), N, JTYPE, IOLDSD + END IF +* +* Do test (5) +* + CALL ZLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL ZLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL ZGGEV3( 'N', 'N', N, S, LDA, T, LDA, ALPHA1, BETA1, Q, + $ LDQ, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'ZGGEV32', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 120 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. BETA( J ).NE. + $ BETA1( J ) )RESULT( 5 ) = ULPINV + 120 CONTINUE +* +* Do test (6): Compute eigenvalues and left eigenvectors, +* and test them +* + CALL ZLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL ZLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL ZGGEV3( 'V', 'N', N, S, LDA, T, LDA, ALPHA1, BETA1, QE, + $ LDQE, Z, LDQ, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'ZGGEV33', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 130 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. BETA( J ).NE. + $ BETA1( J ) )RESULT( 6 ) = ULPINV + 130 CONTINUE +* + DO 150 J = 1, N + DO 140 JC = 1, N + IF( Q( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 6 ) = ULPINV + 140 CONTINUE + 150 CONTINUE +* +* Do test (7): Compute eigenvalues and right eigenvectors, +* and test them +* + CALL ZLACPY( ' ', N, N, A, LDA, S, LDA ) + CALL ZLACPY( ' ', N, N, B, LDA, T, LDA ) + CALL ZGGEV3( 'N', 'V', N, S, LDA, T, LDA, ALPHA1, BETA1, Q, + $ LDQ, QE, LDQE, WORK, LWORK, RWORK, IERR ) + IF( IERR.NE.0 .AND. IERR.NE.N+1 ) THEN + RESULT( 1 ) = ULPINV + WRITE( NOUNIT, FMT = 9999 )'ZGGEV34', IERR, N, JTYPE, + $ IOLDSD + INFO = ABS( IERR ) + GO TO 190 + END IF +* + DO 160 J = 1, N + IF( ALPHA( J ).NE.ALPHA1( J ) .OR. BETA( J ).NE. + $ BETA1( J ) )RESULT( 7 ) = ULPINV + 160 CONTINUE +* + DO 180 J = 1, N + DO 170 JC = 1, N + IF( Z( J, JC ).NE.QE( J, JC ) ) + $ RESULT( 7 ) = ULPINV + 170 CONTINUE + 180 CONTINUE +* +* End of Loop -- Check for RESULT(j) > THRESH +* + 190 CONTINUE +* + NTESTT = NTESTT + 7 +* +* Print out tests which fail. +* + DO 200 JR = 1, 7 + IF( RESULT( JR ).GE.THRESH ) THEN +* +* If this is the first test to fail, +* print a header to the data file. +* + IF( NERRS.EQ.0 ) THEN + WRITE( NOUNIT, FMT = 9997 )'ZGV' +* +* Matrix types +* + WRITE( NOUNIT, FMT = 9996 ) + WRITE( NOUNIT, FMT = 9995 ) + WRITE( NOUNIT, FMT = 9994 )'Orthogonal' +* +* Tests performed +* + WRITE( NOUNIT, FMT = 9993 ) +* + END IF + NERRS = NERRS + 1 + IF( RESULT( JR ).LT.10000.0D0 ) THEN + WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + ELSE + WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR, + $ RESULT( JR ) + END IF + END IF + 200 CONTINUE +* + 210 CONTINUE + 220 CONTINUE +* +* Summary +* + CALL ALASVM( 'ZGV3', NOUNIT, NERRS, NTESTT, 0 ) +* + WORK( 1 ) = MAXWRK +* + RETURN +* + 9999 FORMAT( ' ZDRGEV3: ', A, ' returned INFO=', I6, '.', / 3X, 'N=', + $ I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), I5, ')' ) +* + 9998 FORMAT( ' ZDRGEV3: ', A, ' Eigenvectors from ', A, ' incorrectly ', + $ 'normalized.', / ' Bits of error=', 0P, G10.3, ',', 3X, + $ 'N=', I4, ', JTYPE=', I3, ', ISEED=(', 3( I4, ',' ), I5, + $ ')' ) +* + 9997 FORMAT( / 1X, A3, ' -- Complex Generalized eigenvalue problem ', + $ 'driver' ) +* + 9996 FORMAT( ' Matrix types (see ZDRGEV3 for details): ' ) +* + 9995 FORMAT( ' Special Matrices:', 23X, + $ '(J''=transposed Jordan block)', + $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ', + $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ', + $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I', + $ ') 11=(large*I, small*D) 13=(large*D, large*I)', / + $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ', + $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' ) + 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:', + $ / ' 16=Transposed Jordan Blocks 19=geometric ', + $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ', + $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ', + $ 'alpha, beta=0,1 21=random alpha, beta=0,1', + $ / ' Large & Small Matrices:', / ' 22=(large, small) ', + $ '23=(small,large) 24=(small,small) 25=(large,large)', + $ / ' 26=random O(1) matrices.' ) +* + 9993 FORMAT( / ' Tests performed: ', + $ / ' 1 = max | ( b A - a B )''*l | / const.,', + $ / ' 2 = | |VR(i)| - 1 | / ulp,', + $ / ' 3 = max | ( b A - a B )*r | / const.', + $ / ' 4 = | |VL(i)| - 1 | / ulp,', + $ / ' 5 = 0 if W same no matter if r or l computed,', + $ / ' 6 = 0 if l same no matter if l computed,', + $ / ' 7 = 0 if r same no matter if r computed,', / 1X ) + 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 0P, F8.2 ) + 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=', + $ 4( I4, ',' ), ' result ', I2, ' is', 1P, D10.3 ) +* +* End of ZDRGEV3 +* + END diff --git a/TESTING/EIG/zerrgg.f b/TESTING/EIG/zerrgg.f index a3f116a3..5ed7ee61 100644 --- a/TESTING/EIG/zerrgg.f +++ b/TESTING/EIG/zerrgg.f @@ -2,19 +2,19 @@ * * =========== DOCUMENTATION =========== * -* Online html documentation available at -* http://www.netlib.org/lapack/explore-html/ +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ * * Definition: * =========== * * SUBROUTINE ZERRGG( PATH, NUNIT ) -* +* * .. Scalar Arguments .. * CHARACTER*3 PATH * INTEGER NUNIT * .. -* +* * *> \par Purpose: * ============= @@ -22,8 +22,9 @@ *> \verbatim *> *> ZERRGG tests the error exits for ZGGES, ZGGESX, ZGGEV, ZGGEVX, -*> ZGGGLM, ZGGHRD, ZGGLSE, ZGGQRF, ZGGRQF, ZGGSVD, ZGGSVP, ZHGEQZ, -*> ZTGEVC, ZTGEXC, ZTGSEN, ZTGSJA, ZTGSNA, ZTGSYL, and ZUNCSD. +*> ZGGES3, ZGGEV3, ZGGGLM, ZGGHRD, ZGGLSE, ZGGQRF, ZGGRQF, ZGGSVD, +*> ZGGSVP, ZHGEQZ, ZTGEVC, ZTGEXC, ZTGSEN, ZTGSJA, ZTGSNA, ZTGSYL, +*> and ZUNCSD. *> \endverbatim * * Arguments: @@ -44,10 +45,10 @@ * Authors: * ======== * -*> \author Univ. of Tennessee -*> \author Univ. of California Berkeley -*> \author Univ. of Colorado Denver -*> \author NAG Ltd. +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. * *> \date November 2011 * @@ -95,10 +96,10 @@ EXTERNAL LSAMEN, ZLCTES, ZLCTSX * .. * .. External Subroutines .. - EXTERNAL CHKXER, ZGGES, ZGGESX, ZGGEV, ZGGEVX, ZGGGLM, + EXTERNAL CHKXER, ZGGES, ZGGESX, ZGGEV, ZGGEVX, ZGGGLM, $ ZGGHRD, ZGGLSE, ZGGQRF, ZGGRQF, ZGGSVD, ZGGSVP, $ ZHGEQZ, ZTGEVC, ZTGEXC, ZTGSEN, ZTGSJA, ZTGSNA, - $ ZTGSYL, ZUNCSD + $ ZTGSYL, ZUNCSD, ZGGES3, ZGGEV3, ZGGHD3 * .. * .. Scalars in Common .. LOGICAL LERR, OK @@ -171,6 +172,47 @@ CALL CHKXER( 'ZGGHRD', INFOT, NOUT, LERR, OK ) NT = NT + 9 * +* ZGGHD3 +* + SRNAMT = 'ZGGHD3' + INFOT = 1 + CALL ZGGHD3( '/', 'N', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL ZGGHD3( 'N', '/', 0, 1, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL ZGGHD3( 'N', 'N', -1, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 4 + CALL ZGGHD3( 'N', 'N', 0, 0, 0, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL ZGGHD3( 'N', 'N', 0, 1, 1, A, 1, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL ZGGHD3( 'N', 'N', 2, 1, 1, A, 1, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL ZGGHD3( 'N', 'N', 2, 1, 1, A, 2, B, 1, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL ZGGHD3( 'V', 'N', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL ZGGHD3( 'N', 'V', 2, 1, 1, A, 2, B, 2, Q, 1, Z, 1, W, LW, + $ INFO ) + CALL CHKXER( 'ZGGHD3', INFOT, NOUT, LERR, OK ) + NT = NT + 9 +* * ZHGEQZ * SRNAMT = 'ZHGEQZ' @@ -520,56 +562,56 @@ $ -1, 0, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 8 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, -1, 0, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 9 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, -1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 11 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, -1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 20 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, -1, A, 1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 22 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, -1, A, 1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 24 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, -1, A, - $ 1, W, LW, RW, LW, IW, INFO ) + $ 1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) INFOT = 26 CALL ZUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'N', $ 1, 1, 1, A, 1, A, $ 1, A, 1, A, 1, A, $ A, 1, A, 1, A, 1, A, - $ -1, W, LW, RW, LW, IW, INFO ) + $ -1, W, LW, RW, LW, IW, INFO ) CALL CHKXER( 'ZUNCSD', INFOT, NOUT, LERR, OK ) NT = NT + 8 * @@ -679,6 +721,55 @@ CALL CHKXER( 'ZGGES ', INFOT, NOUT, LERR, OK ) NT = NT + 11 * +* ZGGES3 +* + SRNAMT = 'ZGGES3' + INFOT = 1 + CALL ZGGES3( '/', 'N', 'S', ZLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL ZGGES3( 'N', '/', 'S', ZLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL ZGGES3( 'N', 'V', '/', ZLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL ZGGES3( 'N', 'V', 'S', ZLCTES, -1, A, 1, B, 1, SDIM, + $ ALPHA, BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL ZGGES3( 'N', 'V', 'S', ZLCTES, 1, A, 0, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 9 + CALL ZGGES3( 'N', 'V', 'S', ZLCTES, 1, A, 1, B, 0, SDIM, ALPHA, + $ BETA, Q, 1, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL ZGGES3( 'N', 'V', 'S', ZLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 0, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 14 + CALL ZGGES3( 'V', 'V', 'S', ZLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 1, U, 2, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL ZGGES3( 'N', 'V', 'S', ZLCTES, 1, A, 1, B, 1, SDIM, ALPHA, + $ BETA, Q, 1, U, 0, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 16 + CALL ZGGES3( 'V', 'V', 'S', ZLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 2, U, 1, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + INFOT = 18 + CALL ZGGES3( 'V', 'V', 'S', ZLCTES, 2, A, 2, B, 2, SDIM, ALPHA, + $ BETA, Q, 2, U, 2, W, 1, RW, BW, INFO ) + CALL CHKXER( 'ZGGES3', INFOT, NOUT, LERR, OK ) + NT = NT + 11 +* * ZGGESX * SRNAMT = 'ZGGESX' @@ -794,6 +885,51 @@ CALL CHKXER( 'ZGGEV ', INFOT, NOUT, LERR, OK ) NT = NT + 10 * +* ZGGEV3 +* + SRNAMT = 'ZGGEV3' + INFOT = 1 + CALL ZGGEV3( '/', 'N', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 2 + CALL ZGGEV3( 'N', '/', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 3 + CALL ZGGEV3( 'V', 'V', -1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 5 + CALL ZGGEV3( 'V', 'V', 1, A, 0, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 7 + CALL ZGGEV3( 'V', 'V', 1, A, 1, B, 0, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL ZGGEV3( 'N', 'V', 1, A, 1, B, 1, ALPHA, BETA, Q, 0, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 11 + CALL ZGGEV3( 'V', 'V', 2, A, 2, B, 2, ALPHA, BETA, Q, 1, U, 2, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL ZGGEV3( 'V', 'N', 2, A, 2, B, 2, ALPHA, BETA, Q, 2, U, 0, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 13 + CALL ZGGEV3( 'V', 'V', 2, A, 2, B, 2, ALPHA, BETA, Q, 2, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + INFOT = 15 + CALL ZGGEV3( 'V', 'V', 1, A, 1, B, 1, ALPHA, BETA, Q, 1, U, 1, + $ W, 1, RW, INFO ) + CALL CHKXER( 'ZGGEV3', INFOT, NOUT, LERR, OK ) + NT = NT + 10 +* * ZGGEVX * SRNAMT = 'ZGGEVX' diff --git a/TESTING/cgg.in b/TESTING/cgg.in index 8e44e45f..790feeda 100644 --- a/TESTING/cgg.in +++ b/TESTING/cgg.in @@ -1,15 +1,16 @@ CGG: Data file for testing Nonsymmetric Eigenvalue Problem routines -7 Number of values of N -0 1 2 3 5 10 16 Values of N (dimension) +7 Number of values of N +0 1 2 3 5 10 16 Values of N (dimension) 4 Number of parameter values 1 1 2 2 Values of NB (blocksize) 40 40 2 2 Values of NBMIN (minimum blocksize) 2 4 2 4 Values of NSHIFT (no. of shifts) 40 40 2 2 Values of MAXB (multishift crossover pt) +1 2 1 2 Values of IACC22 (struct. matrix mult.) 40 40 2 2 Values of NBCOL (minimum col. dimension) -20.0 Threshold value -T Put T to test the LAPACK routines -T Put T to test the driver routines -T Put T to test the error exits -1 Code to interpret the seed +20.0 Threshold value +T Put T to test the LAPACK routines +T Put T to test the driver routines +T Put T to test the error exits +1 Code to interpret the seed CGG 26 diff --git a/TESTING/dgg.in b/TESTING/dgg.in index fb83aacf..fcc44c0b 100644 --- a/TESTING/dgg.in +++ b/TESTING/dgg.in @@ -6,6 +6,7 @@ DGG: Data file for testing Nonsymmetric Eigenvalue Problem routines 40 40 2 2 Values of NBMIN (minimum blocksize) 2 4 2 4 Values of NSHIFT (no. of shifts) 40 40 2 2 Values of MAXB (multishift crossover pt) +1 2 1 2 Values of IACC22 (struct. matrix mult.) 40 40 2 2 Values of NBCOL (minimum col. dimension) 20.0 Threshold value T Put T to test the LAPACK routines diff --git a/TESTING/sgg.in b/TESTING/sgg.in index 367f9617..162ba3ef 100644 --- a/TESTING/sgg.in +++ b/TESTING/sgg.in @@ -6,6 +6,7 @@ SGG: Data file for testing Nonsymmetric Eigenvalue Problem routines 40 40 2 2 Values of NBMIN (minimum blocksize) 2 4 2 4 Values of NSHIFT (no. of shifts) 40 40 2 2 Values of MAXB (multishift crossover pt) +1 2 1 2 Values of IACC22 (struct. matrix mult.) 40 40 2 2 Values of NBCOL (minimum col. dimension) 20.0 Threshold value T Put T to test the LAPACK routines diff --git a/TESTING/zgg.in b/TESTING/zgg.in index 39376292..802e5ddf 100644 --- a/TESTING/zgg.in +++ b/TESTING/zgg.in @@ -6,6 +6,7 @@ ZGG: Data file for testing Nonsymmetric Eigenvalue Problem routines 40 40 2 2 Values of NBMIN (minimum blocksize) 2 4 2 4 Values of NSHIFT (no. of shifts) 40 40 2 2 Values of MAXB (multishift crossover pt) +1 2 1 2 Values of IACC22 (struct. matrix mult.) 40 40 2 2 Values of NBCOL (minimum col. dimension) 20.0 Threshold value T Put T to test the LAPACK routines |