dgges.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /* dgges.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Table of constant values */
  14. static integer c__1 = 1;
  15. static integer c__0 = 0;
  16. static integer c_n1 = -1;
  17. static doublereal c_b38 = 0.;
  18. static doublereal c_b39 = 1.;
  19. /* Subroutine */ int _starpu_dgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
  20. selctg, integer *n, doublereal *a, integer *lda, doublereal *b,
  21. integer *ldb, integer *sdim, doublereal *alphar, doublereal *alphai,
  22. doublereal *beta, doublereal *vsl, integer *ldvsl, doublereal *vsr,
  23. integer *ldvsr, doublereal *work, integer *lwork, logical *bwork,
  24. integer *info)
  25. {
  26. /* System generated locals */
  27. integer a_dim1, a_offset, b_dim1, b_offset, vsl_dim1, vsl_offset,
  28. vsr_dim1, vsr_offset, i__1, i__2;
  29. doublereal d__1;
  30. /* Builtin functions */
  31. double sqrt(doublereal);
  32. /* Local variables */
  33. integer i__, ip;
  34. doublereal dif[2];
  35. integer ihi, ilo;
  36. doublereal eps, anrm, bnrm;
  37. integer idum[1], ierr, itau, iwrk;
  38. doublereal pvsl, pvsr;
  39. extern logical _starpu_lsame_(char *, char *);
  40. integer ileft, icols;
  41. logical cursl, ilvsl, ilvsr;
  42. integer irows;
  43. extern /* Subroutine */ int _starpu_dlabad_(doublereal *, doublereal *), _starpu_dggbak_(
  44. char *, char *, integer *, integer *, integer *, doublereal *,
  45. doublereal *, integer *, doublereal *, integer *, integer *), _starpu_dggbal_(char *, integer *, doublereal *, integer
  46. *, doublereal *, integer *, integer *, integer *, doublereal *,
  47. doublereal *, doublereal *, integer *);
  48. logical lst2sl;
  49. extern doublereal _starpu_dlamch_(char *), _starpu_dlange_(char *, integer *,
  50. integer *, doublereal *, integer *, doublereal *);
  51. extern /* Subroutine */ int _starpu_dgghrd_(char *, char *, integer *, integer *,
  52. integer *, doublereal *, integer *, doublereal *, integer *,
  53. doublereal *, integer *, doublereal *, integer *, integer *), _starpu_dlascl_(char *, integer *, integer *, doublereal
  54. *, doublereal *, integer *, integer *, doublereal *, integer *,
  55. integer *);
  56. logical ilascl, ilbscl;
  57. extern /* Subroutine */ int _starpu_dgeqrf_(integer *, integer *, doublereal *,
  58. integer *, doublereal *, doublereal *, integer *, integer *),
  59. _starpu_dlacpy_(char *, integer *, integer *, doublereal *, integer *,
  60. doublereal *, integer *);
  61. doublereal safmin;
  62. extern /* Subroutine */ int _starpu_dlaset_(char *, integer *, integer *,
  63. doublereal *, doublereal *, doublereal *, integer *);
  64. doublereal safmax;
  65. extern /* Subroutine */ int _starpu_xerbla_(char *, integer *);
  66. doublereal bignum;
  67. extern /* Subroutine */ int _starpu_dhgeqz_(char *, char *, char *, integer *,
  68. integer *, integer *, doublereal *, integer *, doublereal *,
  69. integer *, doublereal *, doublereal *, doublereal *, doublereal *,
  70. integer *, doublereal *, integer *, doublereal *, integer *,
  71. integer *), _starpu_dtgsen_(integer *, logical *,
  72. logical *, logical *, integer *, doublereal *, integer *,
  73. doublereal *, integer *, doublereal *, doublereal *, doublereal *,
  74. doublereal *, integer *, doublereal *, integer *, integer *,
  75. doublereal *, doublereal *, doublereal *, doublereal *, integer *,
  76. integer *, integer *, integer *);
  77. integer ijobvl, iright;
  78. extern integer _starpu_ilaenv_(integer *, char *, char *, integer *, integer *,
  79. integer *, integer *);
  80. integer ijobvr;
  81. extern /* Subroutine */ int _starpu_dorgqr_(integer *, integer *, integer *,
  82. doublereal *, integer *, doublereal *, doublereal *, integer *,
  83. integer *);
  84. doublereal anrmto, bnrmto;
  85. logical lastsl;
  86. extern /* Subroutine */ int _starpu_dormqr_(char *, char *, integer *, integer *,
  87. integer *, doublereal *, integer *, doublereal *, doublereal *,
  88. integer *, doublereal *, integer *, integer *);
  89. integer minwrk, maxwrk;
  90. doublereal smlnum;
  91. logical wantst, lquery;
  92. /* -- LAPACK driver routine (version 3.2) -- */
  93. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  94. /* November 2006 */
  95. /* .. Scalar Arguments .. */
  96. /* .. */
  97. /* .. Array Arguments .. */
  98. /* .. */
  99. /* .. Function Arguments .. */
  100. /* .. */
  101. /* Purpose */
  102. /* ======= */
  103. /* DGGES computes for a pair of N-by-N real nonsymmetric matrices (A,B), */
  104. /* the generalized eigenvalues, the generalized real Schur form (S,T), */
  105. /* optionally, the left and/or right matrices of Schur vectors (VSL and */
  106. /* VSR). This gives the generalized Schur factorization */
  107. /* (A,B) = ( (VSL)*S*(VSR)**T, (VSL)*T*(VSR)**T ) */
  108. /* Optionally, it also orders the eigenvalues so that a selected cluster */
  109. /* of eigenvalues appears in the leading diagonal blocks of the upper */
  110. /* quasi-triangular matrix S and the upper triangular matrix T.The */
  111. /* leading columns of VSL and VSR then form an orthonormal basis for the */
  112. /* corresponding left and right eigenspaces (deflating subspaces). */
  113. /* (If only the generalized eigenvalues are needed, use the driver */
  114. /* DGGEV instead, which is faster.) */
  115. /* A generalized eigenvalue for a pair of matrices (A,B) is a scalar w */
  116. /* or a ratio alpha/beta = w, such that A - w*B is singular. It is */
  117. /* usually represented as the pair (alpha,beta), as there is a */
  118. /* reasonable interpretation for beta=0 or both being zero. */
  119. /* A pair of matrices (S,T) is in generalized real Schur form if T is */
  120. /* upper triangular with non-negative diagonal and S is block upper */
  121. /* triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond */
  122. /* to real generalized eigenvalues, while 2-by-2 blocks of S will be */
  123. /* "standardized" by making the corresponding elements of T have the */
  124. /* form: */
  125. /* [ a 0 ] */
  126. /* [ 0 b ] */
  127. /* and the pair of corresponding 2-by-2 blocks in S and T will have a */
  128. /* complex conjugate pair of generalized eigenvalues. */
  129. /* Arguments */
  130. /* ========= */
  131. /* JOBVSL (input) CHARACTER*1 */
  132. /* = 'N': do not compute the left Schur vectors; */
  133. /* = 'V': compute the left Schur vectors. */
  134. /* JOBVSR (input) CHARACTER*1 */
  135. /* = 'N': do not compute the right Schur vectors; */
  136. /* = 'V': compute the right Schur vectors. */
  137. /* SORT (input) CHARACTER*1 */
  138. /* Specifies whether or not to order the eigenvalues on the */
  139. /* diagonal of the generalized Schur form. */
  140. /* = 'N': Eigenvalues are not ordered; */
  141. /* = 'S': Eigenvalues are ordered (see SELCTG); */
  142. /* SELCTG (external procedure) LOGICAL FUNCTION of three DOUBLE PRECISION arguments */
  143. /* SELCTG must be declared EXTERNAL in the calling subroutine. */
  144. /* If SORT = 'N', SELCTG is not referenced. */
  145. /* If SORT = 'S', SELCTG is used to select eigenvalues to sort */
  146. /* to the top left of the Schur form. */
  147. /* An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if */
  148. /* SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either */
  149. /* one of a complex conjugate pair of eigenvalues is selected, */
  150. /* then both complex eigenvalues are selected. */
  151. /* Note that in the ill-conditioned case, a selected complex */
  152. /* eigenvalue may no longer satisfy SELCTG(ALPHAR(j),ALPHAI(j), */
  153. /* BETA(j)) = .TRUE. after ordering. INFO is to be set to N+2 */
  154. /* in this case. */
  155. /* N (input) INTEGER */
  156. /* The order of the matrices A, B, VSL, and VSR. N >= 0. */
  157. /* A (input/output) DOUBLE PRECISION array, dimension (LDA, N) */
  158. /* On entry, the first of the pair of matrices. */
  159. /* On exit, A has been overwritten by its generalized Schur */
  160. /* form S. */
  161. /* LDA (input) INTEGER */
  162. /* The leading dimension of A. LDA >= max(1,N). */
  163. /* B (input/output) DOUBLE PRECISION array, dimension (LDB, N) */
  164. /* On entry, the second of the pair of matrices. */
  165. /* On exit, B has been overwritten by its generalized Schur */
  166. /* form T. */
  167. /* LDB (input) INTEGER */
  168. /* The leading dimension of B. LDB >= max(1,N). */
  169. /* SDIM (output) INTEGER */
  170. /* If SORT = 'N', SDIM = 0. */
  171. /* If SORT = 'S', SDIM = number of eigenvalues (after sorting) */
  172. /* for which SELCTG is true. (Complex conjugate pairs for which */
  173. /* SELCTG is true for either eigenvalue count as 2.) */
  174. /* ALPHAR (output) DOUBLE PRECISION array, dimension (N) */
  175. /* ALPHAI (output) DOUBLE PRECISION array, dimension (N) */
  176. /* BETA (output) DOUBLE PRECISION array, dimension (N) */
  177. /* On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will */
  178. /* be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i, */
  179. /* and BETA(j),j=1,...,N are the diagonals of the complex Schur */
  180. /* form (S,T) that would result if the 2-by-2 diagonal blocks of */
  181. /* the real Schur form of (A,B) were further reduced to */
  182. /* triangular form using 2-by-2 complex unitary transformations. */
  183. /* If ALPHAI(j) is zero, then the j-th eigenvalue is real; if */
  184. /* positive, then the j-th and (j+1)-st eigenvalues are a */
  185. /* complex conjugate pair, with ALPHAI(j+1) negative. */
  186. /* Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) */
  187. /* may easily over- or underflow, and BETA(j) may even be zero. */
  188. /* Thus, the user should avoid naively computing the ratio. */
  189. /* However, ALPHAR and ALPHAI will be always less than and */
  190. /* usually comparable with norm(A) in magnitude, and BETA always */
  191. /* less than and usually comparable with norm(B). */
  192. /* VSL (output) DOUBLE PRECISION array, dimension (LDVSL,N) */
  193. /* If JOBVSL = 'V', VSL will contain the left Schur vectors. */
  194. /* Not referenced if JOBVSL = 'N'. */
  195. /* LDVSL (input) INTEGER */
  196. /* The leading dimension of the matrix VSL. LDVSL >=1, and */
  197. /* if JOBVSL = 'V', LDVSL >= N. */
  198. /* VSR (output) DOUBLE PRECISION array, dimension (LDVSR,N) */
  199. /* If JOBVSR = 'V', VSR will contain the right Schur vectors. */
  200. /* Not referenced if JOBVSR = 'N'. */
  201. /* LDVSR (input) INTEGER */
  202. /* The leading dimension of the matrix VSR. LDVSR >= 1, and */
  203. /* if JOBVSR = 'V', LDVSR >= N. */
  204. /* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
  205. /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
  206. /* LWORK (input) INTEGER */
  207. /* The dimension of the array WORK. */
  208. /* If N = 0, LWORK >= 1, else LWORK >= 8*N+16. */
  209. /* For good performance , LWORK must generally be larger. */
  210. /* If LWORK = -1, then a workspace query is assumed; the routine */
  211. /* only calculates the optimal size of the WORK array, returns */
  212. /* this value as the first entry of the WORK array, and no error */
  213. /* message related to LWORK is issued by XERBLA. */
  214. /* BWORK (workspace) LOGICAL array, dimension (N) */
  215. /* Not referenced if SORT = 'N'. */
  216. /* INFO (output) INTEGER */
  217. /* = 0: successful exit */
  218. /* < 0: if INFO = -i, the i-th argument had an illegal value. */
  219. /* = 1,...,N: */
  220. /* The QZ iteration failed. (A,B) are not in Schur */
  221. /* form, but ALPHAR(j), ALPHAI(j), and BETA(j) should */
  222. /* be correct for j=INFO+1,...,N. */
  223. /* > N: =N+1: other than QZ iteration failed in DHGEQZ. */
  224. /* =N+2: after reordering, roundoff changed values of */
  225. /* some complex eigenvalues so that leading */
  226. /* eigenvalues in the Generalized Schur form no */
  227. /* longer satisfy SELCTG=.TRUE. This could also */
  228. /* be caused due to scaling. */
  229. /* =N+3: reordering failed in DTGSEN. */
  230. /* ===================================================================== */
  231. /* .. Parameters .. */
  232. /* .. */
  233. /* .. Local Scalars .. */
  234. /* .. */
  235. /* .. Local Arrays .. */
  236. /* .. */
  237. /* .. External Subroutines .. */
  238. /* .. */
  239. /* .. External Functions .. */
  240. /* .. */
  241. /* .. Intrinsic Functions .. */
  242. /* .. */
  243. /* .. Executable Statements .. */
  244. /* Decode the input arguments */
  245. /* Parameter adjustments */
  246. a_dim1 = *lda;
  247. a_offset = 1 + a_dim1;
  248. a -= a_offset;
  249. b_dim1 = *ldb;
  250. b_offset = 1 + b_dim1;
  251. b -= b_offset;
  252. --alphar;
  253. --alphai;
  254. --beta;
  255. vsl_dim1 = *ldvsl;
  256. vsl_offset = 1 + vsl_dim1;
  257. vsl -= vsl_offset;
  258. vsr_dim1 = *ldvsr;
  259. vsr_offset = 1 + vsr_dim1;
  260. vsr -= vsr_offset;
  261. --work;
  262. --bwork;
  263. /* Function Body */
  264. if (_starpu_lsame_(jobvsl, "N")) {
  265. ijobvl = 1;
  266. ilvsl = FALSE_;
  267. } else if (_starpu_lsame_(jobvsl, "V")) {
  268. ijobvl = 2;
  269. ilvsl = TRUE_;
  270. } else {
  271. ijobvl = -1;
  272. ilvsl = FALSE_;
  273. }
  274. if (_starpu_lsame_(jobvsr, "N")) {
  275. ijobvr = 1;
  276. ilvsr = FALSE_;
  277. } else if (_starpu_lsame_(jobvsr, "V")) {
  278. ijobvr = 2;
  279. ilvsr = TRUE_;
  280. } else {
  281. ijobvr = -1;
  282. ilvsr = FALSE_;
  283. }
  284. wantst = _starpu_lsame_(sort, "S");
  285. /* Test the input arguments */
  286. *info = 0;
  287. lquery = *lwork == -1;
  288. if (ijobvl <= 0) {
  289. *info = -1;
  290. } else if (ijobvr <= 0) {
  291. *info = -2;
  292. } else if (! wantst && ! _starpu_lsame_(sort, "N")) {
  293. *info = -3;
  294. } else if (*n < 0) {
  295. *info = -5;
  296. } else if (*lda < max(1,*n)) {
  297. *info = -7;
  298. } else if (*ldb < max(1,*n)) {
  299. *info = -9;
  300. } else if (*ldvsl < 1 || ilvsl && *ldvsl < *n) {
  301. *info = -15;
  302. } else if (*ldvsr < 1 || ilvsr && *ldvsr < *n) {
  303. *info = -17;
  304. }
  305. /* Compute workspace */
  306. /* (Note: Comments in the code beginning "Workspace:" describe the */
  307. /* minimal amount of workspace needed at that point in the code, */
  308. /* as well as the preferred amount for good performance. */
  309. /* NB refers to the optimal block size for the immediately */
  310. /* following subroutine, as returned by ILAENV.) */
  311. if (*info == 0) {
  312. if (*n > 0) {
  313. /* Computing MAX */
  314. i__1 = *n << 3, i__2 = *n * 6 + 16;
  315. minwrk = max(i__1,i__2);
  316. maxwrk = minwrk - *n + *n * _starpu_ilaenv_(&c__1, "DGEQRF", " ", n, &
  317. c__1, n, &c__0);
  318. /* Computing MAX */
  319. i__1 = maxwrk, i__2 = minwrk - *n + *n * _starpu_ilaenv_(&c__1, "DORMQR",
  320. " ", n, &c__1, n, &c_n1);
  321. maxwrk = max(i__1,i__2);
  322. if (ilvsl) {
  323. /* Computing MAX */
  324. i__1 = maxwrk, i__2 = minwrk - *n + *n * _starpu_ilaenv_(&c__1, "DOR"
  325. "GQR", " ", n, &c__1, n, &c_n1);
  326. maxwrk = max(i__1,i__2);
  327. }
  328. } else {
  329. minwrk = 1;
  330. maxwrk = 1;
  331. }
  332. work[1] = (doublereal) maxwrk;
  333. if (*lwork < minwrk && ! lquery) {
  334. *info = -19;
  335. }
  336. }
  337. if (*info != 0) {
  338. i__1 = -(*info);
  339. _starpu_xerbla_("DGGES ", &i__1);
  340. return 0;
  341. } else if (lquery) {
  342. return 0;
  343. }
  344. /* Quick return if possible */
  345. if (*n == 0) {
  346. *sdim = 0;
  347. return 0;
  348. }
  349. /* Get machine constants */
  350. eps = _starpu_dlamch_("P");
  351. safmin = _starpu_dlamch_("S");
  352. safmax = 1. / safmin;
  353. _starpu_dlabad_(&safmin, &safmax);
  354. smlnum = sqrt(safmin) / eps;
  355. bignum = 1. / smlnum;
  356. /* Scale A if max element outside range [SMLNUM,BIGNUM] */
  357. anrm = _starpu_dlange_("M", n, n, &a[a_offset], lda, &work[1]);
  358. ilascl = FALSE_;
  359. if (anrm > 0. && anrm < smlnum) {
  360. anrmto = smlnum;
  361. ilascl = TRUE_;
  362. } else if (anrm > bignum) {
  363. anrmto = bignum;
  364. ilascl = TRUE_;
  365. }
  366. if (ilascl) {
  367. _starpu_dlascl_("G", &c__0, &c__0, &anrm, &anrmto, n, n, &a[a_offset], lda, &
  368. ierr);
  369. }
  370. /* Scale B if max element outside range [SMLNUM,BIGNUM] */
  371. bnrm = _starpu_dlange_("M", n, n, &b[b_offset], ldb, &work[1]);
  372. ilbscl = FALSE_;
  373. if (bnrm > 0. && bnrm < smlnum) {
  374. bnrmto = smlnum;
  375. ilbscl = TRUE_;
  376. } else if (bnrm > bignum) {
  377. bnrmto = bignum;
  378. ilbscl = TRUE_;
  379. }
  380. if (ilbscl) {
  381. _starpu_dlascl_("G", &c__0, &c__0, &bnrm, &bnrmto, n, n, &b[b_offset], ldb, &
  382. ierr);
  383. }
  384. /* Permute the matrix to make it more nearly triangular */
  385. /* (Workspace: need 6*N + 2*N space for storing balancing factors) */
  386. ileft = 1;
  387. iright = *n + 1;
  388. iwrk = iright + *n;
  389. _starpu_dggbal_("P", n, &a[a_offset], lda, &b[b_offset], ldb, &ilo, &ihi, &work[
  390. ileft], &work[iright], &work[iwrk], &ierr);
  391. /* Reduce B to triangular form (QR decomposition of B) */
  392. /* (Workspace: need N, prefer N*NB) */
  393. irows = ihi + 1 - ilo;
  394. icols = *n + 1 - ilo;
  395. itau = iwrk;
  396. iwrk = itau + irows;
  397. i__1 = *lwork + 1 - iwrk;
  398. _starpu_dgeqrf_(&irows, &icols, &b[ilo + ilo * b_dim1], ldb, &work[itau], &work[
  399. iwrk], &i__1, &ierr);
  400. /* Apply the orthogonal transformation to matrix A */
  401. /* (Workspace: need N, prefer N*NB) */
  402. i__1 = *lwork + 1 - iwrk;
  403. _starpu_dormqr_("L", "T", &irows, &icols, &irows, &b[ilo + ilo * b_dim1], ldb, &
  404. work[itau], &a[ilo + ilo * a_dim1], lda, &work[iwrk], &i__1, &
  405. ierr);
  406. /* Initialize VSL */
  407. /* (Workspace: need N, prefer N*NB) */
  408. if (ilvsl) {
  409. _starpu_dlaset_("Full", n, n, &c_b38, &c_b39, &vsl[vsl_offset], ldvsl);
  410. if (irows > 1) {
  411. i__1 = irows - 1;
  412. i__2 = irows - 1;
  413. _starpu_dlacpy_("L", &i__1, &i__2, &b[ilo + 1 + ilo * b_dim1], ldb, &vsl[
  414. ilo + 1 + ilo * vsl_dim1], ldvsl);
  415. }
  416. i__1 = *lwork + 1 - iwrk;
  417. _starpu_dorgqr_(&irows, &irows, &irows, &vsl[ilo + ilo * vsl_dim1], ldvsl, &
  418. work[itau], &work[iwrk], &i__1, &ierr);
  419. }
  420. /* Initialize VSR */
  421. if (ilvsr) {
  422. _starpu_dlaset_("Full", n, n, &c_b38, &c_b39, &vsr[vsr_offset], ldvsr);
  423. }
  424. /* Reduce to generalized Hessenberg form */
  425. /* (Workspace: none needed) */
  426. _starpu_dgghrd_(jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[b_offset],
  427. ldb, &vsl[vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, &ierr);
  428. /* Perform QZ algorithm, computing Schur vectors if desired */
  429. /* (Workspace: need N) */
  430. iwrk = itau;
  431. i__1 = *lwork + 1 - iwrk;
  432. _starpu_dhgeqz_("S", jobvsl, jobvsr, n, &ilo, &ihi, &a[a_offset], lda, &b[
  433. b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vsl[vsl_offset]
  434. , ldvsl, &vsr[vsr_offset], ldvsr, &work[iwrk], &i__1, &ierr);
  435. if (ierr != 0) {
  436. if (ierr > 0 && ierr <= *n) {
  437. *info = ierr;
  438. } else if (ierr > *n && ierr <= *n << 1) {
  439. *info = ierr - *n;
  440. } else {
  441. *info = *n + 1;
  442. }
  443. goto L50;
  444. }
  445. /* Sort eigenvalues ALPHA/BETA if desired */
  446. /* (Workspace: need 4*N+16 ) */
  447. *sdim = 0;
  448. if (wantst) {
  449. /* Undo scaling on eigenvalues before SELCTGing */
  450. if (ilascl) {
  451. _starpu_dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphar[1],
  452. n, &ierr);
  453. _starpu_dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphai[1],
  454. n, &ierr);
  455. }
  456. if (ilbscl) {
  457. _starpu_dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n,
  458. &ierr);
  459. }
  460. /* Select eigenvalues */
  461. i__1 = *n;
  462. for (i__ = 1; i__ <= i__1; ++i__) {
  463. bwork[i__] = (*selctg)(&alphar[i__], &alphai[i__], &beta[i__]);
  464. /* L10: */
  465. }
  466. i__1 = *lwork - iwrk + 1;
  467. _starpu_dtgsen_(&c__0, &ilvsl, &ilvsr, &bwork[1], n, &a[a_offset], lda, &b[
  468. b_offset], ldb, &alphar[1], &alphai[1], &beta[1], &vsl[
  469. vsl_offset], ldvsl, &vsr[vsr_offset], ldvsr, sdim, &pvsl, &
  470. pvsr, dif, &work[iwrk], &i__1, idum, &c__1, &ierr);
  471. if (ierr == 1) {
  472. *info = *n + 3;
  473. }
  474. }
  475. /* Apply back-permutation to VSL and VSR */
  476. /* (Workspace: none needed) */
  477. if (ilvsl) {
  478. _starpu_dggbak_("P", "L", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsl[
  479. vsl_offset], ldvsl, &ierr);
  480. }
  481. if (ilvsr) {
  482. _starpu_dggbak_("P", "R", n, &ilo, &ihi, &work[ileft], &work[iright], n, &vsr[
  483. vsr_offset], ldvsr, &ierr);
  484. }
  485. /* Check if unscaling would cause over/underflow, if so, rescale */
  486. /* (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of */
  487. /* B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I) */
  488. if (ilascl) {
  489. i__1 = *n;
  490. for (i__ = 1; i__ <= i__1; ++i__) {
  491. if (alphai[i__] != 0.) {
  492. if (alphar[i__] / safmax > anrmto / anrm || safmin / alphar[
  493. i__] > anrm / anrmto) {
  494. work[1] = (d__1 = a[i__ + i__ * a_dim1] / alphar[i__],
  495. abs(d__1));
  496. beta[i__] *= work[1];
  497. alphar[i__] *= work[1];
  498. alphai[i__] *= work[1];
  499. } else if (alphai[i__] / safmax > anrmto / anrm || safmin /
  500. alphai[i__] > anrm / anrmto) {
  501. work[1] = (d__1 = a[i__ + (i__ + 1) * a_dim1] / alphai[
  502. i__], abs(d__1));
  503. beta[i__] *= work[1];
  504. alphar[i__] *= work[1];
  505. alphai[i__] *= work[1];
  506. }
  507. }
  508. /* L20: */
  509. }
  510. }
  511. if (ilbscl) {
  512. i__1 = *n;
  513. for (i__ = 1; i__ <= i__1; ++i__) {
  514. if (alphai[i__] != 0.) {
  515. if (beta[i__] / safmax > bnrmto / bnrm || safmin / beta[i__]
  516. > bnrm / bnrmto) {
  517. work[1] = (d__1 = b[i__ + i__ * b_dim1] / beta[i__], abs(
  518. d__1));
  519. beta[i__] *= work[1];
  520. alphar[i__] *= work[1];
  521. alphai[i__] *= work[1];
  522. }
  523. }
  524. /* L30: */
  525. }
  526. }
  527. /* Undo scaling */
  528. if (ilascl) {
  529. _starpu_dlascl_("H", &c__0, &c__0, &anrmto, &anrm, n, n, &a[a_offset], lda, &
  530. ierr);
  531. _starpu_dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphar[1], n, &
  532. ierr);
  533. _starpu_dlascl_("G", &c__0, &c__0, &anrmto, &anrm, n, &c__1, &alphai[1], n, &
  534. ierr);
  535. }
  536. if (ilbscl) {
  537. _starpu_dlascl_("U", &c__0, &c__0, &bnrmto, &bnrm, n, n, &b[b_offset], ldb, &
  538. ierr);
  539. _starpu_dlascl_("G", &c__0, &c__0, &bnrmto, &bnrm, n, &c__1, &beta[1], n, &
  540. ierr);
  541. }
  542. if (wantst) {
  543. /* Check if reordering is correct */
  544. lastsl = TRUE_;
  545. lst2sl = TRUE_;
  546. *sdim = 0;
  547. ip = 0;
  548. i__1 = *n;
  549. for (i__ = 1; i__ <= i__1; ++i__) {
  550. cursl = (*selctg)(&alphar[i__], &alphai[i__], &beta[i__]);
  551. if (alphai[i__] == 0.) {
  552. if (cursl) {
  553. ++(*sdim);
  554. }
  555. ip = 0;
  556. if (cursl && ! lastsl) {
  557. *info = *n + 2;
  558. }
  559. } else {
  560. if (ip == 1) {
  561. /* Last eigenvalue of conjugate pair */
  562. cursl = cursl || lastsl;
  563. lastsl = cursl;
  564. if (cursl) {
  565. *sdim += 2;
  566. }
  567. ip = -1;
  568. if (cursl && ! lst2sl) {
  569. *info = *n + 2;
  570. }
  571. } else {
  572. /* First eigenvalue of conjugate pair */
  573. ip = 1;
  574. }
  575. }
  576. lst2sl = lastsl;
  577. lastsl = cursl;
  578. /* L40: */
  579. }
  580. }
  581. L50:
  582. work[1] = (doublereal) maxwrk;
  583. return 0;
  584. /* End of DGGES */
  585. } /* _starpu_dgges_ */