You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

zdrvgg.f 34 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. *> \brief \b ZDRVGG
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. * Definition:
  9. * ===========
  10. *
  11. * SUBROUTINE ZDRVGG( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH,
  12. * THRSHN, NOUNIT, A, LDA, B, S, T, S2, T2, Q,
  13. * LDQ, Z, ALPHA1, BETA1, ALPHA2, BETA2, VL, VR,
  14. * WORK, LWORK, RWORK, RESULT, INFO )
  15. *
  16. * .. Scalar Arguments ..
  17. * INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES
  18. * DOUBLE PRECISION THRESH, THRSHN
  19. * ..
  20. * .. Array Arguments ..
  21. *
  22. *
  23. *> \par Purpose:
  24. * =============
  25. *>
  26. *> \verbatim
  27. *>
  28. *> ZDRVGG checks the nonsymmetric generalized eigenvalue driver
  29. *> routines.
  30. *> T T T
  31. *> ZGEGS factors A and B as Q S Z and Q T Z , where means
  32. *> transpose, T is upper triangular, S is in generalized Schur form
  33. *> (upper triangular), and Q and Z are unitary. It also
  34. *> computes the generalized eigenvalues (alpha(1),beta(1)), ...,
  35. *> (alpha(n),beta(n)), where alpha(j)=S(j,j) and beta(j)=T(j,j) --
  36. *> thus, w(j) = alpha(j)/beta(j) is a root of the generalized
  37. *> eigenvalue problem
  38. *>
  39. *> det( A - w(j) B ) = 0
  40. *>
  41. *> and m(j) = beta(j)/alpha(j) is a root of the essentially equivalent
  42. *> problem
  43. *>
  44. *> det( m(j) A - B ) = 0
  45. *>
  46. *> ZGEGV computes the generalized eigenvalues (alpha(1),beta(1)), ...,
  47. *> (alpha(n),beta(n)), the matrix L whose columns contain the
  48. *> generalized left eigenvectors l, and the matrix R whose columns
  49. *> contain the generalized right eigenvectors r for the pair (A,B).
  50. *>
  51. *> When ZDRVGG is called, a number of matrix "sizes" ("n's") and a
  52. *> number of matrix "types" are specified. For each size ("n")
  53. *> and each type of matrix, one matrix will be generated and used
  54. *> to test the nonsymmetric eigenroutines. For each matrix, 7
  55. *> tests will be performed and compared with the threshhold THRESH:
  56. *>
  57. *> Results from ZGEGS:
  58. *>
  59. *> H
  60. *> (1) | A - Q S Z | / ( |A| n ulp )
  61. *>
  62. *> H
  63. *> (2) | B - Q T Z | / ( |B| n ulp )
  64. *>
  65. *> H
  66. *> (3) | I - QQ | / ( n ulp )
  67. *>
  68. *> H
  69. *> (4) | I - ZZ | / ( n ulp )
  70. *>
  71. *> (5) maximum over j of D(j) where:
  72. *>
  73. *> |alpha(j) - S(j,j)| |beta(j) - T(j,j)|
  74. *> D(j) = ------------------------ + -----------------------
  75. *> max(|alpha(j)|,|S(j,j)|) max(|beta(j)|,|T(j,j)|)
  76. *>
  77. *> Results from ZGEGV:
  78. *>
  79. *> (6) max over all left eigenvalue/-vector pairs (beta/alpha,l) of
  80. *>
  81. *> | l**H * (beta A - alpha B) | / ( ulp max( |beta A|, |alpha B| ) )
  82. *>
  83. *> where l**H is the conjugate tranpose of l.
  84. *>
  85. *> (7) max over all right eigenvalue/-vector pairs (beta/alpha,r) of
  86. *>
  87. *> | (beta A - alpha B) r | / ( ulp max( |beta A|, |alpha B| ) )
  88. *>
  89. *> Test Matrices
  90. *> ---- --------
  91. *>
  92. *> The sizes of the test matrices are specified by an array
  93. *> NN(1:NSIZES); the value of each element NN(j) specifies one size.
  94. *> The "types" are specified by a logical array DOTYPE( 1:NTYPES ); if
  95. *> DOTYPE(j) is .TRUE., then matrix type "j" will be generated.
  96. *> Currently, the list of possible types is:
  97. *>
  98. *> (1) ( 0, 0 ) (a pair of zero matrices)
  99. *>
  100. *> (2) ( I, 0 ) (an identity and a zero matrix)
  101. *>
  102. *> (3) ( 0, I ) (an identity and a zero matrix)
  103. *>
  104. *> (4) ( I, I ) (a pair of identity matrices)
  105. *>
  106. *> t t
  107. *> (5) ( J , J ) (a pair of transposed Jordan blocks)
  108. *>
  109. *> t ( I 0 )
  110. *> (6) ( X, Y ) where X = ( J 0 ) and Y = ( t )
  111. *> ( 0 I ) ( 0 J )
  112. *> and I is a k x k identity and J a (k+1)x(k+1)
  113. *> Jordan block; k=(N-1)/2
  114. *>
  115. *> (7) ( D, I ) where D is diag( 0, 1,..., N-1 ) (a diagonal
  116. *> matrix with those diagonal entries.)
  117. *> (8) ( I, D )
  118. *>
  119. *> (9) ( big*D, small*I ) where "big" is near overflow and small=1/big
  120. *>
  121. *> (10) ( small*D, big*I )
  122. *>
  123. *> (11) ( big*I, small*D )
  124. *>
  125. *> (12) ( small*I, big*D )
  126. *>
  127. *> (13) ( big*D, big*I )
  128. *>
  129. *> (14) ( small*D, small*I )
  130. *>
  131. *> (15) ( D1, D2 ) where D1 is diag( 0, 0, 1, ..., N-3, 0 ) and
  132. *> D2 is diag( 0, N-3, N-4,..., 1, 0, 0 )
  133. *> t t
  134. *> (16) Q ( J , J ) Z where Q and Z are random unitary matrices.
  135. *>
  136. *> (17) Q ( T1, T2 ) Z where T1 and T2 are upper triangular matrices
  137. *> with random O(1) entries above the diagonal
  138. *> and diagonal entries diag(T1) =
  139. *> ( 0, 0, 1, ..., N-3, 0 ) and diag(T2) =
  140. *> ( 0, N-3, N-4,..., 1, 0, 0 )
  141. *>
  142. *> (18) Q ( T1, T2 ) Z diag(T1) = ( 0, 0, 1, 1, s, ..., s, 0 )
  143. *> diag(T2) = ( 0, 1, 0, 1,..., 1, 0 )
  144. *> s = machine precision.
  145. *>
  146. *> (19) Q ( T1, T2 ) Z diag(T1)=( 0,0,1,1, 1-d, ..., 1-(N-5)*d=s, 0 )
  147. *> diag(T2) = ( 0, 1, 0, 1, ..., 1, 0 )
  148. *>
  149. *> N-5
  150. *> (20) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, 1, a, ..., a =s, 0 )
  151. *> diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 )
  152. *>
  153. *> (21) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, r1, r2, ..., r(N-4), 0 )
  154. *> diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 )
  155. *> where r1,..., r(N-4) are random.
  156. *>
  157. *> (22) Q ( big*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 )
  158. *> diag(T2) = ( 0, 1, ..., 1, 0, 0 )
  159. *>
  160. *> (23) Q ( small*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 )
  161. *> diag(T2) = ( 0, 1, ..., 1, 0, 0 )
  162. *>
  163. *> (24) Q ( small*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 )
  164. *> diag(T2) = ( 0, 1, ..., 1, 0, 0 )
  165. *>
  166. *> (25) Q ( big*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 )
  167. *> diag(T2) = ( 0, 1, ..., 1, 0, 0 )
  168. *>
  169. *> (26) Q ( T1, T2 ) Z where T1 and T2 are random upper-triangular
  170. *> matrices.
  171. *> \endverbatim
  172. *
  173. * Arguments:
  174. * ==========
  175. *
  176. *> \param[in] NSIZES
  177. *> \verbatim
  178. *> NSIZES is INTEGER
  179. *> The number of sizes of matrices to use. If it is zero,
  180. *> ZDRVGG does nothing. It must be at least zero.
  181. *> \endverbatim
  182. *>
  183. *> \param[in] NN
  184. *> \verbatim
  185. *> NN is INTEGER array, dimension (NSIZES)
  186. *> An array containing the sizes to be used for the matrices.
  187. *> Zero values will be skipped. The values must be at least
  188. *> zero.
  189. *> \endverbatim
  190. *>
  191. *> \param[in] NTYPES
  192. *> \verbatim
  193. *> NTYPES is INTEGER
  194. *> The number of elements in DOTYPE. If it is zero, ZDRVGG
  195. *> does nothing. It must be at least zero. If it is MAXTYP+1
  196. *> and NSIZES is 1, then an additional type, MAXTYP+1 is
  197. *> defined, which is to use whatever matrix is in A. This
  198. *> is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
  199. *> DOTYPE(MAXTYP+1) is .TRUE. .
  200. *> \endverbatim
  201. *>
  202. *> \param[in] DOTYPE
  203. *> \verbatim
  204. *> DOTYPE is LOGICAL array, dimension (NTYPES)
  205. *> If DOTYPE(j) is .TRUE., then for each size in NN a
  206. *> matrix of that size and of type j will be generated.
  207. *> If NTYPES is smaller than the maximum number of types
  208. *> defined (PARAMETER MAXTYP), then types NTYPES+1 through
  209. *> MAXTYP will not be generated. If NTYPES is larger
  210. *> than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES)
  211. *> will be ignored.
  212. *> \endverbatim
  213. *>
  214. *> \param[in,out] ISEED
  215. *> \verbatim
  216. *> ISEED is INTEGER array, dimension (4)
  217. *> On entry ISEED specifies the seed of the random number
  218. *> generator. The array elements should be between 0 and 4095;
  219. *> if not they will be reduced mod 4096. Also, ISEED(4) must
  220. *> be odd. The random number generator uses a linear
  221. *> congruential sequence limited to small integers, and so
  222. *> should produce machine independent random numbers. The
  223. *> values of ISEED are changed on exit, and can be used in the
  224. *> next call to ZDRVGG to continue the same random number
  225. *> sequence.
  226. *> \endverbatim
  227. *>
  228. *> \param[in] THRESH
  229. *> \verbatim
  230. *> THRESH is DOUBLE PRECISION
  231. *> A test will count as "failed" if the "error", computed as
  232. *> described above, exceeds THRESH. Note that the error is
  233. *> scaled to be O(1), so THRESH should be a reasonably small
  234. *> multiple of 1, e.g., 10 or 100. In particular, it should
  235. *> not depend on the precision (single vs. double) or the size
  236. *> of the matrix. It must be at least zero.
  237. *> \endverbatim
  238. *>
  239. *> \param[in] THRSHN
  240. *> \verbatim
  241. *> THRSHN is DOUBLE PRECISION
  242. *> Threshhold for reporting eigenvector normalization error.
  243. *> If the normalization of any eigenvector differs from 1 by
  244. *> more than THRSHN*ulp, then a special error message will be
  245. *> printed. (This is handled separately from the other tests,
  246. *> since only a compiler or programming error should cause an
  247. *> error message, at least if THRSHN is at least 5--10.)
  248. *> \endverbatim
  249. *>
  250. *> \param[in] NOUNIT
  251. *> \verbatim
  252. *> NOUNIT is INTEGER
  253. *> The FORTRAN unit number for printing out error messages
  254. *> (e.g., if a routine returns IINFO not equal to 0.)
  255. *> \endverbatim
  256. *>
  257. *> \param[in,out] A
  258. *> \verbatim
  259. *> A is COMPLEX*16 array, dimension (LDA, max(NN))
  260. *> Used to hold the original A matrix. Used as input only
  261. *> if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and
  262. *> DOTYPE(MAXTYP+1)=.TRUE.
  263. *> \endverbatim
  264. *>
  265. *> \param[in] LDA
  266. *> \verbatim
  267. *> LDA is INTEGER
  268. *> The leading dimension of A, B, S, T, S2, and T2.
  269. *> It must be at least 1 and at least max( NN ).
  270. *> \endverbatim
  271. *>
  272. *> \param[in,out] B
  273. *> \verbatim
  274. *> B is COMPLEX*16 array, dimension (LDA, max(NN))
  275. *> Used to hold the original B matrix. Used as input only
  276. *> if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and
  277. *> DOTYPE(MAXTYP+1)=.TRUE.
  278. *> \endverbatim
  279. *>
  280. *> \param[out] S
  281. *> \verbatim
  282. *> S is COMPLEX*16 array, dimension (LDA, max(NN))
  283. *> The upper triangular matrix computed from A by ZGEGS.
  284. *> \endverbatim
  285. *>
  286. *> \param[out] T
  287. *> \verbatim
  288. *> T is COMPLEX*16 array, dimension (LDA, max(NN))
  289. *> The upper triangular matrix computed from B by ZGEGS.
  290. *> \endverbatim
  291. *>
  292. *> \param[out] S2
  293. *> \verbatim
  294. *> S2 is COMPLEX*16 array, dimension (LDA, max(NN))
  295. *> The matrix computed from A by ZGEGV. This will be the
  296. *> Schur (upper triangular) form of some matrix related to A,
  297. *> but will not, in general, be the same as S.
  298. *> \endverbatim
  299. *>
  300. *> \param[out] T2
  301. *> \verbatim
  302. *> T2 is COMPLEX*16 array, dimension (LDA, max(NN))
  303. *> The matrix computed from B by ZGEGV. This will be the
  304. *> Schur form of some matrix related to B, but will not, in
  305. *> general, be the same as T.
  306. *> \endverbatim
  307. *>
  308. *> \param[out] Q
  309. *> \verbatim
  310. *> Q is COMPLEX*16 array, dimension (LDQ, max(NN))
  311. *> The (left) unitary matrix computed by ZGEGS.
  312. *> \endverbatim
  313. *>
  314. *> \param[in] LDQ
  315. *> \verbatim
  316. *> LDQ is INTEGER
  317. *> The leading dimension of Q, Z, VL, and VR. It must
  318. *> be at least 1 and at least max( NN ).
  319. *> \endverbatim
  320. *>
  321. *> \param[out] Z
  322. *> \verbatim
  323. *> Z is COMPLEX*16 array, dimension (LDQ, max(NN))
  324. *> The (right) unitary matrix computed by ZGEGS.
  325. *> \endverbatim
  326. *>
  327. *> \param[out] ALPHA1
  328. *> \verbatim
  329. *> ALPHA1 is COMPLEX*16 array, dimension (max(NN))
  330. *> \endverbatim
  331. *>
  332. *> \param[out] BETA1
  333. *> \verbatim
  334. *> BETA1 is COMPLEX*16 array, dimension (max(NN))
  335. *>
  336. *> The generalized eigenvalues of (A,B) computed by ZGEGS.
  337. *> ALPHA1(k) / BETA1(k) is the k-th generalized eigenvalue of
  338. *> the matrices in A and B.
  339. *> \endverbatim
  340. *>
  341. *> \param[out] ALPHA2
  342. *> \verbatim
  343. *> ALPHA2 is COMPLEX*16 array, dimension (max(NN))
  344. *> \endverbatim
  345. *>
  346. *> \param[out] BETA2
  347. *> \verbatim
  348. *> BETA2 is COMPLEX*16 array, dimension (max(NN))
  349. *>
  350. *> The generalized eigenvalues of (A,B) computed by ZGEGV.
  351. *> ALPHA2(k) / BETA2(k) is the k-th generalized eigenvalue of
  352. *> the matrices in A and B.
  353. *> \endverbatim
  354. *>
  355. *> \param[out] VL
  356. *> \verbatim
  357. *> VL is COMPLEX*16 array, dimension (LDQ, max(NN))
  358. *> The (lower triangular) left eigenvector matrix for the
  359. *> matrices in A and B.
  360. *> \endverbatim
  361. *>
  362. *> \param[out] VR
  363. *> \verbatim
  364. *> VR is COMPLEX*16 array, dimension (LDQ, max(NN))
  365. *> The (upper triangular) right eigenvector matrix for the
  366. *> matrices in A and B.
  367. *> \endverbatim
  368. *>
  369. *> \param[out] WORK
  370. *> \verbatim
  371. *> WORK is COMPLEX*16 array, dimension (LWORK)
  372. *> \endverbatim
  373. *>
  374. *> \param[in] LWORK
  375. *> \verbatim
  376. *> LWORK is INTEGER
  377. *> The number of entries in WORK. This must be at least
  378. *> MAX( 2*N, N*(NB+1), (k+1)*(2*k+N+1) ), where "k" is the
  379. *> sum of the blocksize and number-of-shifts for ZHGEQZ, and
  380. *> NB is the greatest of the blocksizes for ZGEQRF, ZUNMQR,
  381. *> and ZUNGQR. (The blocksizes and the number-of-shifts are
  382. *> retrieved through calls to ILAENV.)
  383. *> \endverbatim
  384. *>
  385. *> \param[out] RWORK
  386. *> \verbatim
  387. *> RWORK is DOUBLE PRECISION array, dimension (8*N)
  388. *> \endverbatim
  389. *>
  390. *> \param[out] RESULT
  391. *> \verbatim
  392. *> RESULT is DOUBLE PRECISION array, dimension (7)
  393. *> The values computed by the tests described above.
  394. *> The values are currently limited to 1/ulp, to avoid
  395. *> overflow.
  396. *> \endverbatim
  397. *>
  398. *> \param[out] INFO
  399. *> \verbatim
  400. *> INFO is INTEGER
  401. *> = 0: successful exit
  402. *> < 0: if INFO = -i, the i-th argument had an illegal value.
  403. *> > 0: A routine returned an error code. INFO is the
  404. *> absolute value of the INFO value returned.
  405. *> \endverbatim
  406. *
  407. * Authors:
  408. * ========
  409. *
  410. *> \author Univ. of Tennessee
  411. *> \author Univ. of California Berkeley
  412. *> \author Univ. of Colorado Denver
  413. *> \author NAG Ltd.
  414. *
  415. *> \date November 2011
  416. *
  417. *> \ingroup complex16_eig
  418. *
  419. * =====================================================================
  420. SUBROUTINE ZDRVGG( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH,
  421. $ THRSHN, NOUNIT, A, LDA, B, S, T, S2, T2, Q,
  422. $ LDQ, Z, ALPHA1, BETA1, ALPHA2, BETA2, VL, VR,
  423. $ WORK, LWORK, RWORK, RESULT, INFO )
  424. *
  425. * -- LAPACK test routine (version 3.4.0) --
  426. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  427. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  428. * November 2011
  429. *
  430. * .. Scalar Arguments ..
  431. INTEGER INFO, LDA, LDQ, LWORK, NOUNIT, NSIZES, NTYPES
  432. DOUBLE PRECISION THRESH, THRSHN
  433. * ..
  434. * .. Array Arguments ..
  435. *
  436. * =====================================================================
  437. *
  438. LOGICAL DOTYPE( * )
  439. INTEGER ISEED( 4 ), NN( * )
  440. DOUBLE PRECISION RESULT( * ), RWORK( * )
  441. COMPLEX*16 A( LDA, * ), ALPHA1( * ), ALPHA2( * ),
  442. $ B( LDA, * ), BETA1( * ), BETA2( * ),
  443. $ Q( LDQ, * ), S( LDA, * ), S2( LDA, * ),
  444. $ T( LDA, * ), T2( LDA, * ), VL( LDQ, * ),
  445. $ VR( LDQ, * ), WORK( * ), Z( LDQ, * )
  446. * ..
  447. * .. Parameters ..
  448. DOUBLE PRECISION ZERO, ONE
  449. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  450. COMPLEX*16 CZERO, CONE
  451. PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
  452. $ CONE = ( 1.0D+0, 0.0D+0 ) )
  453. INTEGER MAXTYP
  454. PARAMETER ( MAXTYP = 26 )
  455. * ..
  456. * .. Local Scalars ..
  457. LOGICAL BADNN
  458. INTEGER I1, IADD, IINFO, IN, J, JC, JR, JSIZE, JTYPE,
  459. $ LWKOPT, MTYPES, N, N1, NB, NBZ, NERRS, NMATS,
  460. $ NMAX, NS, NTEST, NTESTT
  461. DOUBLE PRECISION SAFMAX, SAFMIN, TEMP1, TEMP2, ULP, ULPINV
  462. COMPLEX*16 CTEMP, X
  463. * ..
  464. * .. Local Arrays ..
  465. LOGICAL LASIGN( MAXTYP ), LBSIGN( MAXTYP )
  466. INTEGER IOLDSD( 4 ), KADD( 6 ), KAMAGN( MAXTYP ),
  467. $ KATYPE( MAXTYP ), KAZERO( MAXTYP ),
  468. $ KBMAGN( MAXTYP ), KBTYPE( MAXTYP ),
  469. $ KBZERO( MAXTYP ), KCLASS( MAXTYP ),
  470. $ KTRIAN( MAXTYP ), KZ1( 6 ), KZ2( 6 )
  471. DOUBLE PRECISION DUMMA( 4 ), RMAGN( 0: 3 )
  472. * ..
  473. * .. External Functions ..
  474. INTEGER ILAENV
  475. DOUBLE PRECISION DLAMCH
  476. COMPLEX*16 ZLARND
  477. EXTERNAL ILAENV, DLAMCH, ZLARND
  478. * ..
  479. * .. External Subroutines ..
  480. EXTERNAL ALASVM, DLABAD, XERBLA, ZGEGS, ZGEGV, ZGET51,
  481. $ ZGET52, ZLACPY, ZLARFG, ZLASET, ZLATM4, ZUNM2R
  482. * ..
  483. * .. Intrinsic Functions ..
  484. INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SIGN
  485. * ..
  486. * .. Statement Functions ..
  487. DOUBLE PRECISION ABS1
  488. * ..
  489. * .. Statement Function definitions ..
  490. ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
  491. * ..
  492. * .. Data statements ..
  493. DATA KCLASS / 15*1, 10*2, 1*3 /
  494. DATA KZ1 / 0, 1, 2, 1, 3, 3 /
  495. DATA KZ2 / 0, 0, 1, 2, 1, 1 /
  496. DATA KADD / 0, 0, 0, 0, 3, 2 /
  497. DATA KATYPE / 0, 1, 0, 1, 2, 3, 4, 1, 4, 4, 1, 1, 4,
  498. $ 4, 4, 2, 4, 5, 8, 7, 9, 4*4, 0 /
  499. DATA KBTYPE / 0, 0, 1, 1, 2, -3, 1, 4, 1, 1, 4, 4,
  500. $ 1, 1, -4, 2, -4, 8*8, 0 /
  501. DATA KAZERO / 6*1, 2, 1, 2*2, 2*1, 2*2, 3, 1, 3,
  502. $ 4*5, 4*3, 1 /
  503. DATA KBZERO / 6*1, 1, 2, 2*1, 2*2, 2*1, 4, 1, 4,
  504. $ 4*6, 4*4, 1 /
  505. DATA KAMAGN / 8*1, 2, 3, 2, 3, 2, 3, 7*1, 2, 3, 3,
  506. $ 2, 1 /
  507. DATA KBMAGN / 8*1, 3, 2, 3, 2, 2, 3, 7*1, 3, 2, 3,
  508. $ 2, 1 /
  509. DATA KTRIAN / 16*0, 10*1 /
  510. DATA LASIGN / 6*.FALSE., .TRUE., .FALSE., 2*.TRUE.,
  511. $ 2*.FALSE., 3*.TRUE., .FALSE., .TRUE.,
  512. $ 3*.FALSE., 5*.TRUE., .FALSE. /
  513. DATA LBSIGN / 7*.FALSE., .TRUE., 2*.FALSE.,
  514. $ 2*.TRUE., 2*.FALSE., .TRUE., .FALSE., .TRUE.,
  515. $ 9*.FALSE. /
  516. * ..
  517. * .. Executable Statements ..
  518. *
  519. * Check for errors
  520. *
  521. INFO = 0
  522. *
  523. BADNN = .FALSE.
  524. NMAX = 1
  525. DO 10 J = 1, NSIZES
  526. NMAX = MAX( NMAX, NN( J ) )
  527. IF( NN( J ).LT.0 )
  528. $ BADNN = .TRUE.
  529. 10 CONTINUE
  530. *
  531. * Maximum blocksize and shift -- we assume that blocksize and number
  532. * of shifts are monotone increasing functions of N.
  533. *
  534. NB = MAX( 1, ILAENV( 1, 'ZGEQRF', ' ', NMAX, NMAX, -1, -1 ),
  535. $ ILAENV( 1, 'ZUNMQR', 'LC', NMAX, NMAX, NMAX, -1 ),
  536. $ ILAENV( 1, 'ZUNGQR', ' ', NMAX, NMAX, NMAX, -1 ) )
  537. NBZ = ILAENV( 1, 'ZHGEQZ', 'SII', NMAX, 1, NMAX, 0 )
  538. NS = ILAENV( 4, 'ZHGEQZ', 'SII', NMAX, 1, NMAX, 0 )
  539. I1 = NBZ + NS
  540. LWKOPT = MAX( 2*NMAX, NMAX*( NB+1 ), ( 2*I1+NMAX+1 )*( I1+1 ) )
  541. *
  542. * Check for errors
  543. *
  544. IF( NSIZES.LT.0 ) THEN
  545. INFO = -1
  546. ELSE IF( BADNN ) THEN
  547. INFO = -2
  548. ELSE IF( NTYPES.LT.0 ) THEN
  549. INFO = -3
  550. ELSE IF( THRESH.LT.ZERO ) THEN
  551. INFO = -6
  552. ELSE IF( LDA.LE.1 .OR. LDA.LT.NMAX ) THEN
  553. INFO = -10
  554. ELSE IF( LDQ.LE.1 .OR. LDQ.LT.NMAX ) THEN
  555. INFO = -19
  556. ELSE IF( LWKOPT.GT.LWORK ) THEN
  557. INFO = -30
  558. END IF
  559. *
  560. IF( INFO.NE.0 ) THEN
  561. CALL XERBLA( 'ZDRVGG', -INFO )
  562. RETURN
  563. END IF
  564. *
  565. * Quick return if possible
  566. *
  567. IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 )
  568. $ RETURN
  569. *
  570. ULP = DLAMCH( 'Precision' )
  571. SAFMIN = DLAMCH( 'Safe minimum' )
  572. SAFMIN = SAFMIN / ULP
  573. SAFMAX = ONE / SAFMIN
  574. CALL DLABAD( SAFMIN, SAFMAX )
  575. ULPINV = ONE / ULP
  576. *
  577. * The values RMAGN(2:3) depend on N, see below.
  578. *
  579. RMAGN( 0 ) = ZERO
  580. RMAGN( 1 ) = ONE
  581. *
  582. * Loop over sizes, types
  583. *
  584. NTESTT = 0
  585. NERRS = 0
  586. NMATS = 0
  587. *
  588. DO 160 JSIZE = 1, NSIZES
  589. N = NN( JSIZE )
  590. N1 = MAX( 1, N )
  591. RMAGN( 2 ) = SAFMAX*ULP / DBLE( N1 )
  592. RMAGN( 3 ) = SAFMIN*ULPINV*N1
  593. *
  594. IF( NSIZES.NE.1 ) THEN
  595. MTYPES = MIN( MAXTYP, NTYPES )
  596. ELSE
  597. MTYPES = MIN( MAXTYP+1, NTYPES )
  598. END IF
  599. *
  600. DO 150 JTYPE = 1, MTYPES
  601. IF( .NOT.DOTYPE( JTYPE ) )
  602. $ GO TO 150
  603. NMATS = NMATS + 1
  604. NTEST = 0
  605. *
  606. * Save ISEED in case of an error.
  607. *
  608. DO 20 J = 1, 4
  609. IOLDSD( J ) = ISEED( J )
  610. 20 CONTINUE
  611. *
  612. * Initialize RESULT
  613. *
  614. DO 30 J = 1, 7
  615. RESULT( J ) = ZERO
  616. 30 CONTINUE
  617. *
  618. * Compute A and B
  619. *
  620. * Description of control parameters:
  621. *
  622. * KZLASS: =1 means w/o rotation, =2 means w/ rotation,
  623. * =3 means random.
  624. * KATYPE: the "type" to be passed to ZLATM4 for computing A.
  625. * KAZERO: the pattern of zeros on the diagonal for A:
  626. * =1: ( xxx ), =2: (0, xxx ) =3: ( 0, 0, xxx, 0 ),
  627. * =4: ( 0, xxx, 0, 0 ), =5: ( 0, 0, 1, xxx, 0 ),
  628. * =6: ( 0, 1, 0, xxx, 0 ). (xxx means a string of
  629. * non-zero entries.)
  630. * KAMAGN: the magnitude of the matrix: =0: zero, =1: O(1),
  631. * =2: large, =3: small.
  632. * LASIGN: .TRUE. if the diagonal elements of A are to be
  633. * multiplied by a random magnitude 1 number.
  634. * KBTYPE, KBZERO, KBMAGN, IBSIGN: the same, but for B.
  635. * KTRIAN: =0: don't fill in the upper triangle, =1: do.
  636. * KZ1, KZ2, KADD: used to implement KAZERO and KBZERO.
  637. * RMAGN: used to implement KAMAGN and KBMAGN.
  638. *
  639. IF( MTYPES.GT.MAXTYP )
  640. $ GO TO 110
  641. IINFO = 0
  642. IF( KCLASS( JTYPE ).LT.3 ) THEN
  643. *
  644. * Generate A (w/o rotation)
  645. *
  646. IF( ABS( KATYPE( JTYPE ) ).EQ.3 ) THEN
  647. IN = 2*( ( N-1 ) / 2 ) + 1
  648. IF( IN.NE.N )
  649. $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, A, LDA )
  650. ELSE
  651. IN = N
  652. END IF
  653. CALL ZLATM4( KATYPE( JTYPE ), IN, KZ1( KAZERO( JTYPE ) ),
  654. $ KZ2( KAZERO( JTYPE ) ), LASIGN( JTYPE ),
  655. $ RMAGN( KAMAGN( JTYPE ) ), ULP,
  656. $ RMAGN( KTRIAN( JTYPE )*KAMAGN( JTYPE ) ), 2,
  657. $ ISEED, A, LDA )
  658. IADD = KADD( KAZERO( JTYPE ) )
  659. IF( IADD.GT.0 .AND. IADD.LE.N )
  660. $ A( IADD, IADD ) = RMAGN( KAMAGN( JTYPE ) )
  661. *
  662. * Generate B (w/o rotation)
  663. *
  664. IF( ABS( KBTYPE( JTYPE ) ).EQ.3 ) THEN
  665. IN = 2*( ( N-1 ) / 2 ) + 1
  666. IF( IN.NE.N )
  667. $ CALL ZLASET( 'Full', N, N, CZERO, CZERO, B, LDA )
  668. ELSE
  669. IN = N
  670. END IF
  671. CALL ZLATM4( KBTYPE( JTYPE ), IN, KZ1( KBZERO( JTYPE ) ),
  672. $ KZ2( KBZERO( JTYPE ) ), LBSIGN( JTYPE ),
  673. $ RMAGN( KBMAGN( JTYPE ) ), ONE,
  674. $ RMAGN( KTRIAN( JTYPE )*KBMAGN( JTYPE ) ), 2,
  675. $ ISEED, B, LDA )
  676. IADD = KADD( KBZERO( JTYPE ) )
  677. IF( IADD.NE.0 .AND. IADD.LE.N )
  678. $ B( IADD, IADD ) = RMAGN( KBMAGN( JTYPE ) )
  679. *
  680. IF( KCLASS( JTYPE ).EQ.2 .AND. N.GT.0 ) THEN
  681. *
  682. * Include rotations
  683. *
  684. * Generate Q, Z as Householder transformations times
  685. * a diagonal matrix.
  686. *
  687. DO 50 JC = 1, N - 1
  688. DO 40 JR = JC, N
  689. Q( JR, JC ) = ZLARND( 3, ISEED )
  690. Z( JR, JC ) = ZLARND( 3, ISEED )
  691. 40 CONTINUE
  692. CALL ZLARFG( N+1-JC, Q( JC, JC ), Q( JC+1, JC ), 1,
  693. $ WORK( JC ) )
  694. WORK( 2*N+JC ) = SIGN( ONE, DBLE( Q( JC, JC ) ) )
  695. Q( JC, JC ) = CONE
  696. CALL ZLARFG( N+1-JC, Z( JC, JC ), Z( JC+1, JC ), 1,
  697. $ WORK( N+JC ) )
  698. WORK( 3*N+JC ) = SIGN( ONE, DBLE( Z( JC, JC ) ) )
  699. Z( JC, JC ) = CONE
  700. 50 CONTINUE
  701. CTEMP = ZLARND( 3, ISEED )
  702. Q( N, N ) = CONE
  703. WORK( N ) = CZERO
  704. WORK( 3*N ) = CTEMP / ABS( CTEMP )
  705. CTEMP = ZLARND( 3, ISEED )
  706. Z( N, N ) = CONE
  707. WORK( 2*N ) = CZERO
  708. WORK( 4*N ) = CTEMP / ABS( CTEMP )
  709. *
  710. * Apply the diagonal matrices
  711. *
  712. DO 70 JC = 1, N
  713. DO 60 JR = 1, N
  714. A( JR, JC ) = WORK( 2*N+JR )*
  715. $ DCONJG( WORK( 3*N+JC ) )*
  716. $ A( JR, JC )
  717. B( JR, JC ) = WORK( 2*N+JR )*
  718. $ DCONJG( WORK( 3*N+JC ) )*
  719. $ B( JR, JC )
  720. 60 CONTINUE
  721. 70 CONTINUE
  722. CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, A,
  723. $ LDA, WORK( 2*N+1 ), IINFO )
  724. IF( IINFO.NE.0 )
  725. $ GO TO 100
  726. CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ),
  727. $ A, LDA, WORK( 2*N+1 ), IINFO )
  728. IF( IINFO.NE.0 )
  729. $ GO TO 100
  730. CALL ZUNM2R( 'L', 'N', N, N, N-1, Q, LDQ, WORK, B,
  731. $ LDA, WORK( 2*N+1 ), IINFO )
  732. IF( IINFO.NE.0 )
  733. $ GO TO 100
  734. CALL ZUNM2R( 'R', 'C', N, N, N-1, Z, LDQ, WORK( N+1 ),
  735. $ B, LDA, WORK( 2*N+1 ), IINFO )
  736. IF( IINFO.NE.0 )
  737. $ GO TO 100
  738. END IF
  739. ELSE
  740. *
  741. * Random matrices
  742. *
  743. DO 90 JC = 1, N
  744. DO 80 JR = 1, N
  745. A( JR, JC ) = RMAGN( KAMAGN( JTYPE ) )*
  746. $ ZLARND( 4, ISEED )
  747. B( JR, JC ) = RMAGN( KBMAGN( JTYPE ) )*
  748. $ ZLARND( 4, ISEED )
  749. 80 CONTINUE
  750. 90 CONTINUE
  751. END IF
  752. *
  753. 100 CONTINUE
  754. *
  755. IF( IINFO.NE.0 ) THEN
  756. WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE,
  757. $ IOLDSD
  758. INFO = ABS( IINFO )
  759. RETURN
  760. END IF
  761. *
  762. 110 CONTINUE
  763. *
  764. * Call ZGEGS to compute H, T, Q, Z, alpha, and beta.
  765. *
  766. CALL ZLACPY( ' ', N, N, A, LDA, S, LDA )
  767. CALL ZLACPY( ' ', N, N, B, LDA, T, LDA )
  768. NTEST = 1
  769. RESULT( 1 ) = ULPINV
  770. *
  771. CALL ZGEGS( 'V', 'V', N, S, LDA, T, LDA, ALPHA1, BETA1, Q,
  772. $ LDQ, Z, LDQ, WORK, LWORK, RWORK, IINFO )
  773. IF( IINFO.NE.0 ) THEN
  774. WRITE( NOUNIT, FMT = 9999 )'ZGEGS', IINFO, N, JTYPE,
  775. $ IOLDSD
  776. INFO = ABS( IINFO )
  777. GO TO 130
  778. END IF
  779. *
  780. NTEST = 4
  781. *
  782. * Do tests 1--4
  783. *
  784. CALL ZGET51( 1, N, A, LDA, S, LDA, Q, LDQ, Z, LDQ, WORK,
  785. $ RWORK, RESULT( 1 ) )
  786. CALL ZGET51( 1, N, B, LDA, T, LDA, Q, LDQ, Z, LDQ, WORK,
  787. $ RWORK, RESULT( 2 ) )
  788. CALL ZGET51( 3, N, B, LDA, T, LDA, Q, LDQ, Q, LDQ, WORK,
  789. $ RWORK, RESULT( 3 ) )
  790. CALL ZGET51( 3, N, B, LDA, T, LDA, Z, LDQ, Z, LDQ, WORK,
  791. $ RWORK, RESULT( 4 ) )
  792. *
  793. * Do test 5: compare eigenvalues with diagonals.
  794. *
  795. TEMP1 = ZERO
  796. *
  797. DO 120 J = 1, N
  798. TEMP2 = ( ABS1( ALPHA1( J )-S( J, J ) ) /
  799. $ MAX( SAFMIN, ABS1( ALPHA1( J ) ), ABS1( S( J,
  800. $ J ) ) )+ABS1( BETA1( J )-T( J, J ) ) /
  801. $ MAX( SAFMIN, ABS1( BETA1( J ) ), ABS1( T( J,
  802. $ J ) ) ) ) / ULP
  803. TEMP1 = MAX( TEMP1, TEMP2 )
  804. 120 CONTINUE
  805. RESULT( 5 ) = TEMP1
  806. *
  807. * Call ZGEGV to compute S2, T2, VL, and VR, do tests.
  808. *
  809. * Eigenvalues and Eigenvectors
  810. *
  811. CALL ZLACPY( ' ', N, N, A, LDA, S2, LDA )
  812. CALL ZLACPY( ' ', N, N, B, LDA, T2, LDA )
  813. NTEST = 6
  814. RESULT( 6 ) = ULPINV
  815. *
  816. CALL ZGEGV( 'V', 'V', N, S2, LDA, T2, LDA, ALPHA2, BETA2,
  817. $ VL, LDQ, VR, LDQ, WORK, LWORK, RWORK, IINFO )
  818. IF( IINFO.NE.0 ) THEN
  819. WRITE( NOUNIT, FMT = 9999 )'ZGEGV', IINFO, N, JTYPE,
  820. $ IOLDSD
  821. INFO = ABS( IINFO )
  822. GO TO 130
  823. END IF
  824. *
  825. NTEST = 7
  826. *
  827. * Do Tests 6 and 7
  828. *
  829. CALL ZGET52( .TRUE., N, A, LDA, B, LDA, VL, LDQ, ALPHA2,
  830. $ BETA2, WORK, RWORK, DUMMA( 1 ) )
  831. RESULT( 6 ) = DUMMA( 1 )
  832. IF( DUMMA( 2 ).GT.THRSHN ) THEN
  833. WRITE( NOUNIT, FMT = 9998 )'Left', 'ZGEGV', DUMMA( 2 ),
  834. $ N, JTYPE, IOLDSD
  835. END IF
  836. *
  837. CALL ZGET52( .FALSE., N, A, LDA, B, LDA, VR, LDQ, ALPHA2,
  838. $ BETA2, WORK, RWORK, DUMMA( 1 ) )
  839. RESULT( 7 ) = DUMMA( 1 )
  840. IF( DUMMA( 2 ).GT.THRESH ) THEN
  841. WRITE( NOUNIT, FMT = 9998 )'Right', 'ZGEGV', DUMMA( 2 ),
  842. $ N, JTYPE, IOLDSD
  843. END IF
  844. *
  845. * End of Loop -- Check for RESULT(j) > THRESH
  846. *
  847. 130 CONTINUE
  848. *
  849. NTESTT = NTESTT + NTEST
  850. *
  851. * Print out tests which fail.
  852. *
  853. DO 140 JR = 1, NTEST
  854. IF( RESULT( JR ).GE.THRESH ) THEN
  855. *
  856. * If this is the first test to fail,
  857. * print a header to the data file.
  858. *
  859. IF( NERRS.EQ.0 ) THEN
  860. WRITE( NOUNIT, FMT = 9997 )'ZGG'
  861. *
  862. * Matrix types
  863. *
  864. WRITE( NOUNIT, FMT = 9996 )
  865. WRITE( NOUNIT, FMT = 9995 )
  866. WRITE( NOUNIT, FMT = 9994 )'Unitary'
  867. *
  868. * Tests performed
  869. *
  870. WRITE( NOUNIT, FMT = 9993 )'unitary', '*',
  871. $ 'conjugate transpose', ( '*', J = 1, 5 )
  872. *
  873. END IF
  874. NERRS = NERRS + 1
  875. IF( RESULT( JR ).LT.10000.0D0 ) THEN
  876. WRITE( NOUNIT, FMT = 9992 )N, JTYPE, IOLDSD, JR,
  877. $ RESULT( JR )
  878. ELSE
  879. WRITE( NOUNIT, FMT = 9991 )N, JTYPE, IOLDSD, JR,
  880. $ RESULT( JR )
  881. END IF
  882. END IF
  883. 140 CONTINUE
  884. *
  885. 150 CONTINUE
  886. 160 CONTINUE
  887. *
  888. * Summary
  889. *
  890. CALL ALASVM( 'ZGG', NOUNIT, NERRS, NTESTT, 0 )
  891. RETURN
  892. *
  893. 9999 FORMAT( ' ZDRVGG: ', A, ' returned INFO=', I6, '.', / 9X, 'N=',
  894. $ I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), I5, ')' )
  895. *
  896. 9998 FORMAT( ' ZDRVGG: ', A, ' Eigenvectors from ', A, ' incorrectly ',
  897. $ 'normalized.', / ' Bits of error=', 0P, G10.3, ',', 9X,
  898. $ 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), I5,
  899. $ ')' )
  900. *
  901. 9997 FORMAT( / 1X, A3,
  902. $ ' -- Complex Generalized eigenvalue problem driver' )
  903. *
  904. 9996 FORMAT( ' Matrix types (see ZDRVGG for details): ' )
  905. *
  906. 9995 FORMAT( ' Special Matrices:', 23X,
  907. $ '(J''=transposed Jordan block)',
  908. $ / ' 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I) 5=(J'',J'') ',
  909. $ '6=(diag(J'',I), diag(I,J''))', / ' Diagonal Matrices: ( ',
  910. $ 'D=diag(0,1,2,...) )', / ' 7=(D,I) 9=(large*D, small*I',
  911. $ ') 11=(large*I, small*D) 13=(large*D, large*I)', /
  912. $ ' 8=(I,D) 10=(small*D, large*I) 12=(small*I, large*D) ',
  913. $ ' 14=(small*D, small*I)', / ' 15=(D, reversed D)' )
  914. 9994 FORMAT( ' Matrices Rotated by Random ', A, ' Matrices U, V:',
  915. $ / ' 16=Transposed Jordan Blocks 19=geometric ',
  916. $ 'alpha, beta=0,1', / ' 17=arithm. alpha&beta ',
  917. $ ' 20=arithmetic alpha, beta=0,1', / ' 18=clustered ',
  918. $ 'alpha, beta=0,1 21=random alpha, beta=0,1',
  919. $ / ' Large & Small Matrices:', / ' 22=(large, small) ',
  920. $ '23=(small,large) 24=(small,small) 25=(large,large)',
  921. $ / ' 26=random O(1) matrices.' )
  922. *
  923. 9993 FORMAT( / ' Tests performed: (S is Schur, T is triangular, ',
  924. $ 'Q and Z are ', A, ',', / 20X,
  925. $ 'l and r are the appropriate left and right', / 19X,
  926. $ 'eigenvectors, resp., a is alpha, b is beta, and', / 19X, A,
  927. $ ' means ', A, '.)', / ' 1 = | A - Q S Z', A,
  928. $ ' | / ( |A| n ulp ) 2 = | B - Q T Z', A,
  929. $ ' | / ( |B| n ulp )', / ' 3 = | I - QQ', A,
  930. $ ' | / ( n ulp ) 4 = | I - ZZ', A,
  931. $ ' | / ( n ulp )', /
  932. $ ' 5 = difference between (alpha,beta) and diagonals of',
  933. $ ' (S,T)', / ' 6 = max | ( b A - a B )', A,
  934. $ ' l | / const. 7 = max | ( b A - a B ) r | / const.',
  935. $ / 1X )
  936. 9992 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=',
  937. $ 4( I4, ',' ), ' result ', I3, ' is', 0P, F8.2 )
  938. 9991 FORMAT( ' Matrix order=', I5, ', type=', I2, ', seed=',
  939. $ 4( I4, ',' ), ' result ', I3, ' is', 1P, D10.3 )
  940. *
  941. * End of ZDRVGG
  942. *
  943. END