dtgsna.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /* dtgsna.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 doublereal c_b19 = 1.;
  16. static doublereal c_b21 = 0.;
  17. static integer c__2 = 2;
  18. static logical c_false = FALSE_;
  19. static integer c__3 = 3;
  20. /* Subroutine */ int _starpu_dtgsna_(char *job, char *howmny, logical *select,
  21. integer *n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
  22. doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr,
  23. doublereal *s, doublereal *dif, integer *mm, integer *m, doublereal *
  24. work, integer *lwork, integer *iwork, integer *info)
  25. {
  26. /* System generated locals */
  27. integer a_dim1, a_offset, b_dim1, b_offset, vl_dim1, vl_offset, vr_dim1,
  28. vr_offset, i__1, i__2;
  29. doublereal d__1, d__2;
  30. /* Builtin functions */
  31. double sqrt(doublereal);
  32. /* Local variables */
  33. integer i__, k;
  34. doublereal c1, c2;
  35. integer n1, n2, ks, iz;
  36. doublereal eps, beta, cond;
  37. extern doublereal _starpu_ddot_(integer *, doublereal *, integer *, doublereal *,
  38. integer *);
  39. logical pair;
  40. integer ierr;
  41. doublereal uhav, uhbv;
  42. integer ifst;
  43. doublereal lnrm;
  44. integer ilst;
  45. doublereal rnrm;
  46. extern /* Subroutine */ int _starpu_dlag2_(doublereal *, integer *, doublereal *,
  47. integer *, doublereal *, doublereal *, doublereal *, doublereal *,
  48. doublereal *, doublereal *);
  49. extern doublereal _starpu_dnrm2_(integer *, doublereal *, integer *);
  50. doublereal root1, root2, scale;
  51. extern logical _starpu_lsame_(char *, char *);
  52. extern /* Subroutine */ int _starpu_dgemv_(char *, integer *, integer *,
  53. doublereal *, doublereal *, integer *, doublereal *, integer *,
  54. doublereal *, doublereal *, integer *);
  55. doublereal uhavi, uhbvi, tmpii;
  56. integer lwmin;
  57. logical wants;
  58. doublereal tmpir, tmpri, dummy[1], tmprr;
  59. extern doublereal _starpu_dlapy2_(doublereal *, doublereal *);
  60. doublereal dummy1[1];
  61. extern doublereal _starpu_dlamch_(char *);
  62. doublereal alphai, alphar;
  63. extern /* Subroutine */ int _starpu_dlacpy_(char *, integer *, integer *,
  64. doublereal *, integer *, doublereal *, integer *),
  65. _starpu_xerbla_(char *, integer *), _starpu_dtgexc_(logical *, logical *,
  66. integer *, doublereal *, integer *, doublereal *, integer *,
  67. doublereal *, integer *, doublereal *, integer *, integer *,
  68. integer *, doublereal *, integer *, integer *);
  69. logical wantbh, wantdf, somcon;
  70. doublereal alprqt;
  71. extern /* Subroutine */ int _starpu_dtgsyl_(char *, integer *, integer *, integer
  72. *, doublereal *, integer *, doublereal *, integer *, doublereal *,
  73. integer *, doublereal *, integer *, doublereal *, integer *,
  74. doublereal *, integer *, doublereal *, doublereal *, doublereal *,
  75. integer *, integer *, integer *);
  76. doublereal smlnum;
  77. logical lquery;
  78. /* -- LAPACK routine (version 3.2) -- */
  79. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  80. /* November 2006 */
  81. /* .. Scalar Arguments .. */
  82. /* .. */
  83. /* .. Array Arguments .. */
  84. /* .. */
  85. /* Purpose */
  86. /* ======= */
  87. /* DTGSNA estimates reciprocal condition numbers for specified */
  88. /* eigenvalues and/or eigenvectors of a matrix pair (A, B) in */
  89. /* generalized real Schur canonical form (or of any matrix pair */
  90. /* (Q*A*Z', Q*B*Z') with orthogonal matrices Q and Z, where */
  91. /* Z' denotes the transpose of Z. */
  92. /* (A, B) must be in generalized real Schur form (as returned by DGGES), */
  93. /* i.e. A is block upper triangular with 1-by-1 and 2-by-2 diagonal */
  94. /* blocks. B is upper triangular. */
  95. /* Arguments */
  96. /* ========= */
  97. /* JOB (input) CHARACTER*1 */
  98. /* Specifies whether condition numbers are required for */
  99. /* eigenvalues (S) or eigenvectors (DIF): */
  100. /* = 'E': for eigenvalues only (S); */
  101. /* = 'V': for eigenvectors only (DIF); */
  102. /* = 'B': for both eigenvalues and eigenvectors (S and DIF). */
  103. /* HOWMNY (input) CHARACTER*1 */
  104. /* = 'A': compute condition numbers for all eigenpairs; */
  105. /* = 'S': compute condition numbers for selected eigenpairs */
  106. /* specified by the array SELECT. */
  107. /* SELECT (input) LOGICAL array, dimension (N) */
  108. /* If HOWMNY = 'S', SELECT specifies the eigenpairs for which */
  109. /* condition numbers are required. To select condition numbers */
  110. /* for the eigenpair corresponding to a real eigenvalue w(j), */
  111. /* SELECT(j) must be set to .TRUE.. To select condition numbers */
  112. /* corresponding to a complex conjugate pair of eigenvalues w(j) */
  113. /* and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be */
  114. /* set to .TRUE.. */
  115. /* If HOWMNY = 'A', SELECT is not referenced. */
  116. /* N (input) INTEGER */
  117. /* The order of the square matrix pair (A, B). N >= 0. */
  118. /* A (input) DOUBLE PRECISION array, dimension (LDA,N) */
  119. /* The upper quasi-triangular matrix A in the pair (A,B). */
  120. /* LDA (input) INTEGER */
  121. /* The leading dimension of the array A. LDA >= max(1,N). */
  122. /* B (input) DOUBLE PRECISION array, dimension (LDB,N) */
  123. /* The upper triangular matrix B in the pair (A,B). */
  124. /* LDB (input) INTEGER */
  125. /* The leading dimension of the array B. LDB >= max(1,N). */
  126. /* VL (input) DOUBLE PRECISION array, dimension (LDVL,M) */
  127. /* If JOB = 'E' or 'B', VL must contain left eigenvectors of */
  128. /* (A, B), corresponding to the eigenpairs specified by HOWMNY */
  129. /* and SELECT. The eigenvectors must be stored in consecutive */
  130. /* columns of VL, as returned by DTGEVC. */
  131. /* If JOB = 'V', VL is not referenced. */
  132. /* LDVL (input) INTEGER */
  133. /* The leading dimension of the array VL. LDVL >= 1. */
  134. /* If JOB = 'E' or 'B', LDVL >= N. */
  135. /* VR (input) DOUBLE PRECISION array, dimension (LDVR,M) */
  136. /* If JOB = 'E' or 'B', VR must contain right eigenvectors of */
  137. /* (A, B), corresponding to the eigenpairs specified by HOWMNY */
  138. /* and SELECT. The eigenvectors must be stored in consecutive */
  139. /* columns ov VR, as returned by DTGEVC. */
  140. /* If JOB = 'V', VR is not referenced. */
  141. /* LDVR (input) INTEGER */
  142. /* The leading dimension of the array VR. LDVR >= 1. */
  143. /* If JOB = 'E' or 'B', LDVR >= N. */
  144. /* S (output) DOUBLE PRECISION array, dimension (MM) */
  145. /* If JOB = 'E' or 'B', the reciprocal condition numbers of the */
  146. /* selected eigenvalues, stored in consecutive elements of the */
  147. /* array. For a complex conjugate pair of eigenvalues two */
  148. /* consecutive elements of S are set to the same value. Thus */
  149. /* S(j), DIF(j), and the j-th columns of VL and VR all */
  150. /* correspond to the same eigenpair (but not in general the */
  151. /* j-th eigenpair, unless all eigenpairs are selected). */
  152. /* If JOB = 'V', S is not referenced. */
  153. /* DIF (output) DOUBLE PRECISION array, dimension (MM) */
  154. /* If JOB = 'V' or 'B', the estimated reciprocal condition */
  155. /* numbers of the selected eigenvectors, stored in consecutive */
  156. /* elements of the array. For a complex eigenvector two */
  157. /* consecutive elements of DIF are set to the same value. If */
  158. /* the eigenvalues cannot be reordered to compute DIF(j), DIF(j) */
  159. /* is set to 0; this can only occur when the true value would be */
  160. /* very small anyway. */
  161. /* If JOB = 'E', DIF is not referenced. */
  162. /* MM (input) INTEGER */
  163. /* The number of elements in the arrays S and DIF. MM >= M. */
  164. /* M (output) INTEGER */
  165. /* The number of elements of the arrays S and DIF used to store */
  166. /* the specified condition numbers; for each selected real */
  167. /* eigenvalue one element is used, and for each selected complex */
  168. /* conjugate pair of eigenvalues, two elements are used. */
  169. /* If HOWMNY = 'A', M is set to N. */
  170. /* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
  171. /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
  172. /* LWORK (input) INTEGER */
  173. /* The dimension of the array WORK. LWORK >= max(1,N). */
  174. /* If JOB = 'V' or 'B' LWORK >= 2*N*(N+2)+16. */
  175. /* If LWORK = -1, then a workspace query is assumed; the routine */
  176. /* only calculates the optimal size of the WORK array, returns */
  177. /* this value as the first entry of the WORK array, and no error */
  178. /* message related to LWORK is issued by XERBLA. */
  179. /* IWORK (workspace) INTEGER array, dimension (N + 6) */
  180. /* If JOB = 'E', IWORK is not referenced. */
  181. /* INFO (output) INTEGER */
  182. /* =0: Successful exit */
  183. /* <0: If INFO = -i, the i-th argument had an illegal value */
  184. /* Further Details */
  185. /* =============== */
  186. /* The reciprocal of the condition number of a generalized eigenvalue */
  187. /* w = (a, b) is defined as */
  188. /* S(w) = (|u'Av|**2 + |u'Bv|**2)**(1/2) / (norm(u)*norm(v)) */
  189. /* where u and v are the left and right eigenvectors of (A, B) */
  190. /* corresponding to w; |z| denotes the absolute value of the complex */
  191. /* number, and norm(u) denotes the 2-norm of the vector u. */
  192. /* The pair (a, b) corresponds to an eigenvalue w = a/b (= u'Av/u'Bv) */
  193. /* of the matrix pair (A, B). If both a and b equal zero, then (A B) is */
  194. /* singular and S(I) = -1 is returned. */
  195. /* An approximate error bound on the chordal distance between the i-th */
  196. /* computed generalized eigenvalue w and the corresponding exact */
  197. /* eigenvalue lambda is */
  198. /* chord(w, lambda) <= EPS * norm(A, B) / S(I) */
  199. /* where EPS is the machine precision. */
  200. /* The reciprocal of the condition number DIF(i) of right eigenvector u */
  201. /* and left eigenvector v corresponding to the generalized eigenvalue w */
  202. /* is defined as follows: */
  203. /* a) If the i-th eigenvalue w = (a,b) is real */
  204. /* Suppose U and V are orthogonal transformations such that */
  205. /* U'*(A, B)*V = (S, T) = ( a * ) ( b * ) 1 */
  206. /* ( 0 S22 ),( 0 T22 ) n-1 */
  207. /* 1 n-1 1 n-1 */
  208. /* Then the reciprocal condition number DIF(i) is */
  209. /* Difl((a, b), (S22, T22)) = sigma-min( Zl ), */
  210. /* where sigma-min(Zl) denotes the smallest singular value of the */
  211. /* 2(n-1)-by-2(n-1) matrix */
  212. /* Zl = [ kron(a, In-1) -kron(1, S22) ] */
  213. /* [ kron(b, In-1) -kron(1, T22) ] . */
  214. /* Here In-1 is the identity matrix of size n-1. kron(X, Y) is the */
  215. /* Kronecker product between the matrices X and Y. */
  216. /* Note that if the default method for computing DIF(i) is wanted */
  217. /* (see DLATDF), then the parameter DIFDRI (see below) should be */
  218. /* changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). */
  219. /* See DTGSYL for more details. */
  220. /* b) If the i-th and (i+1)-th eigenvalues are complex conjugate pair, */
  221. /* Suppose U and V are orthogonal transformations such that */
  222. /* U'*(A, B)*V = (S, T) = ( S11 * ) ( T11 * ) 2 */
  223. /* ( 0 S22 ),( 0 T22) n-2 */
  224. /* 2 n-2 2 n-2 */
  225. /* and (S11, T11) corresponds to the complex conjugate eigenvalue */
  226. /* pair (w, conjg(w)). There exist unitary matrices U1 and V1 such */
  227. /* that */
  228. /* U1'*S11*V1 = ( s11 s12 ) and U1'*T11*V1 = ( t11 t12 ) */
  229. /* ( 0 s22 ) ( 0 t22 ) */
  230. /* where the generalized eigenvalues w = s11/t11 and */
  231. /* conjg(w) = s22/t22. */
  232. /* Then the reciprocal condition number DIF(i) is bounded by */
  233. /* min( d1, max( 1, |real(s11)/real(s22)| )*d2 ) */
  234. /* where, d1 = Difl((s11, t11), (s22, t22)) = sigma-min(Z1), where */
  235. /* Z1 is the complex 2-by-2 matrix */
  236. /* Z1 = [ s11 -s22 ] */
  237. /* [ t11 -t22 ], */
  238. /* This is done by computing (using real arithmetic) the */
  239. /* roots of the characteristical polynomial det(Z1' * Z1 - lambda I), */
  240. /* where Z1' denotes the conjugate transpose of Z1 and det(X) denotes */
  241. /* the determinant of X. */
  242. /* and d2 is an upper bound on Difl((S11, T11), (S22, T22)), i.e. an */
  243. /* upper bound on sigma-min(Z2), where Z2 is (2n-2)-by-(2n-2) */
  244. /* Z2 = [ kron(S11', In-2) -kron(I2, S22) ] */
  245. /* [ kron(T11', In-2) -kron(I2, T22) ] */
  246. /* Note that if the default method for computing DIF is wanted (see */
  247. /* DLATDF), then the parameter DIFDRI (see below) should be changed */
  248. /* from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL */
  249. /* for more details. */
  250. /* For each eigenvalue/vector specified by SELECT, DIF stores a */
  251. /* Frobenius norm-based estimate of Difl. */
  252. /* An approximate error bound for the i-th computed eigenvector VL(i) or */
  253. /* VR(i) is given by */
  254. /* EPS * norm(A, B) / DIF(i). */
  255. /* See ref. [2-3] for more details and further references. */
  256. /* Based on contributions by */
  257. /* Bo Kagstrom and Peter Poromaa, Department of Computing Science, */
  258. /* Umea University, S-901 87 Umea, Sweden. */
  259. /* References */
  260. /* ========== */
  261. /* [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the */
  262. /* Generalized Real Schur Form of a Regular Matrix Pair (A, B), in */
  263. /* M.S. Moonen et al (eds), Linear Algebra for Large Scale and */
  264. /* Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218. */
  265. /* [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified */
  266. /* Eigenvalues of a Regular Matrix Pair (A, B) and Condition */
  267. /* Estimation: Theory, Algorithms and Software, */
  268. /* Report UMINF - 94.04, Department of Computing Science, Umea */
  269. /* University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working */
  270. /* Note 87. To appear in Numerical Algorithms, 1996. */
  271. /* [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software */
  272. /* for Solving the Generalized Sylvester Equation and Estimating the */
  273. /* Separation between Regular Matrix Pairs, Report UMINF - 93.23, */
  274. /* Department of Computing Science, Umea University, S-901 87 Umea, */
  275. /* Sweden, December 1993, Revised April 1994, Also as LAPACK Working */
  276. /* Note 75. To appear in ACM Trans. on Math. Software, Vol 22, */
  277. /* No 1, 1996. */
  278. /* ===================================================================== */
  279. /* .. Parameters .. */
  280. /* .. */
  281. /* .. Local Scalars .. */
  282. /* .. */
  283. /* .. Local Arrays .. */
  284. /* .. */
  285. /* .. External Functions .. */
  286. /* .. */
  287. /* .. External Subroutines .. */
  288. /* .. */
  289. /* .. Intrinsic Functions .. */
  290. /* .. */
  291. /* .. Executable Statements .. */
  292. /* Decode and test the input parameters */
  293. /* Parameter adjustments */
  294. --select;
  295. a_dim1 = *lda;
  296. a_offset = 1 + a_dim1;
  297. a -= a_offset;
  298. b_dim1 = *ldb;
  299. b_offset = 1 + b_dim1;
  300. b -= b_offset;
  301. vl_dim1 = *ldvl;
  302. vl_offset = 1 + vl_dim1;
  303. vl -= vl_offset;
  304. vr_dim1 = *ldvr;
  305. vr_offset = 1 + vr_dim1;
  306. vr -= vr_offset;
  307. --s;
  308. --dif;
  309. --work;
  310. --iwork;
  311. /* Function Body */
  312. wantbh = _starpu_lsame_(job, "B");
  313. wants = _starpu_lsame_(job, "E") || wantbh;
  314. wantdf = _starpu_lsame_(job, "V") || wantbh;
  315. somcon = _starpu_lsame_(howmny, "S");
  316. *info = 0;
  317. lquery = *lwork == -1;
  318. if (! wants && ! wantdf) {
  319. *info = -1;
  320. } else if (! _starpu_lsame_(howmny, "A") && ! somcon) {
  321. *info = -2;
  322. } else if (*n < 0) {
  323. *info = -4;
  324. } else if (*lda < max(1,*n)) {
  325. *info = -6;
  326. } else if (*ldb < max(1,*n)) {
  327. *info = -8;
  328. } else if (wants && *ldvl < *n) {
  329. *info = -10;
  330. } else if (wants && *ldvr < *n) {
  331. *info = -12;
  332. } else {
  333. /* Set M to the number of eigenpairs for which condition numbers */
  334. /* are required, and test MM. */
  335. if (somcon) {
  336. *m = 0;
  337. pair = FALSE_;
  338. i__1 = *n;
  339. for (k = 1; k <= i__1; ++k) {
  340. if (pair) {
  341. pair = FALSE_;
  342. } else {
  343. if (k < *n) {
  344. if (a[k + 1 + k * a_dim1] == 0.) {
  345. if (select[k]) {
  346. ++(*m);
  347. }
  348. } else {
  349. pair = TRUE_;
  350. if (select[k] || select[k + 1]) {
  351. *m += 2;
  352. }
  353. }
  354. } else {
  355. if (select[*n]) {
  356. ++(*m);
  357. }
  358. }
  359. }
  360. /* L10: */
  361. }
  362. } else {
  363. *m = *n;
  364. }
  365. if (*n == 0) {
  366. lwmin = 1;
  367. } else if (_starpu_lsame_(job, "V") || _starpu_lsame_(job,
  368. "B")) {
  369. lwmin = (*n << 1) * (*n + 2) + 16;
  370. } else {
  371. lwmin = *n;
  372. }
  373. work[1] = (doublereal) lwmin;
  374. if (*mm < *m) {
  375. *info = -15;
  376. } else if (*lwork < lwmin && ! lquery) {
  377. *info = -18;
  378. }
  379. }
  380. if (*info != 0) {
  381. i__1 = -(*info);
  382. _starpu_xerbla_("DTGSNA", &i__1);
  383. return 0;
  384. } else if (lquery) {
  385. return 0;
  386. }
  387. /* Quick return if possible */
  388. if (*n == 0) {
  389. return 0;
  390. }
  391. /* Get machine constants */
  392. eps = _starpu_dlamch_("P");
  393. smlnum = _starpu_dlamch_("S") / eps;
  394. ks = 0;
  395. pair = FALSE_;
  396. i__1 = *n;
  397. for (k = 1; k <= i__1; ++k) {
  398. /* Determine whether A(k,k) begins a 1-by-1 or 2-by-2 block. */
  399. if (pair) {
  400. pair = FALSE_;
  401. goto L20;
  402. } else {
  403. if (k < *n) {
  404. pair = a[k + 1 + k * a_dim1] != 0.;
  405. }
  406. }
  407. /* Determine whether condition numbers are required for the k-th */
  408. /* eigenpair. */
  409. if (somcon) {
  410. if (pair) {
  411. if (! select[k] && ! select[k + 1]) {
  412. goto L20;
  413. }
  414. } else {
  415. if (! select[k]) {
  416. goto L20;
  417. }
  418. }
  419. }
  420. ++ks;
  421. if (wants) {
  422. /* Compute the reciprocal condition number of the k-th */
  423. /* eigenvalue. */
  424. if (pair) {
  425. /* Complex eigenvalue pair. */
  426. d__1 = _starpu_dnrm2_(n, &vr[ks * vr_dim1 + 1], &c__1);
  427. d__2 = _starpu_dnrm2_(n, &vr[(ks + 1) * vr_dim1 + 1], &c__1);
  428. rnrm = _starpu_dlapy2_(&d__1, &d__2);
  429. d__1 = _starpu_dnrm2_(n, &vl[ks * vl_dim1 + 1], &c__1);
  430. d__2 = _starpu_dnrm2_(n, &vl[(ks + 1) * vl_dim1 + 1], &c__1);
  431. lnrm = _starpu_dlapy2_(&d__1, &d__2);
  432. _starpu_dgemv_("N", n, n, &c_b19, &a[a_offset], lda, &vr[ks * vr_dim1
  433. + 1], &c__1, &c_b21, &work[1], &c__1);
  434. tmprr = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &
  435. c__1);
  436. tmpri = _starpu_ddot_(n, &work[1], &c__1, &vl[(ks + 1) * vl_dim1 + 1],
  437. &c__1);
  438. _starpu_dgemv_("N", n, n, &c_b19, &a[a_offset], lda, &vr[(ks + 1) *
  439. vr_dim1 + 1], &c__1, &c_b21, &work[1], &c__1);
  440. tmpii = _starpu_ddot_(n, &work[1], &c__1, &vl[(ks + 1) * vl_dim1 + 1],
  441. &c__1);
  442. tmpir = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &
  443. c__1);
  444. uhav = tmprr + tmpii;
  445. uhavi = tmpir - tmpri;
  446. _starpu_dgemv_("N", n, n, &c_b19, &b[b_offset], ldb, &vr[ks * vr_dim1
  447. + 1], &c__1, &c_b21, &work[1], &c__1);
  448. tmprr = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &
  449. c__1);
  450. tmpri = _starpu_ddot_(n, &work[1], &c__1, &vl[(ks + 1) * vl_dim1 + 1],
  451. &c__1);
  452. _starpu_dgemv_("N", n, n, &c_b19, &b[b_offset], ldb, &vr[(ks + 1) *
  453. vr_dim1 + 1], &c__1, &c_b21, &work[1], &c__1);
  454. tmpii = _starpu_ddot_(n, &work[1], &c__1, &vl[(ks + 1) * vl_dim1 + 1],
  455. &c__1);
  456. tmpir = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &
  457. c__1);
  458. uhbv = tmprr + tmpii;
  459. uhbvi = tmpir - tmpri;
  460. uhav = _starpu_dlapy2_(&uhav, &uhavi);
  461. uhbv = _starpu_dlapy2_(&uhbv, &uhbvi);
  462. cond = _starpu_dlapy2_(&uhav, &uhbv);
  463. s[ks] = cond / (rnrm * lnrm);
  464. s[ks + 1] = s[ks];
  465. } else {
  466. /* Real eigenvalue. */
  467. rnrm = _starpu_dnrm2_(n, &vr[ks * vr_dim1 + 1], &c__1);
  468. lnrm = _starpu_dnrm2_(n, &vl[ks * vl_dim1 + 1], &c__1);
  469. _starpu_dgemv_("N", n, n, &c_b19, &a[a_offset], lda, &vr[ks * vr_dim1
  470. + 1], &c__1, &c_b21, &work[1], &c__1);
  471. uhav = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &c__1)
  472. ;
  473. _starpu_dgemv_("N", n, n, &c_b19, &b[b_offset], ldb, &vr[ks * vr_dim1
  474. + 1], &c__1, &c_b21, &work[1], &c__1);
  475. uhbv = _starpu_ddot_(n, &work[1], &c__1, &vl[ks * vl_dim1 + 1], &c__1)
  476. ;
  477. cond = _starpu_dlapy2_(&uhav, &uhbv);
  478. if (cond == 0.) {
  479. s[ks] = -1.;
  480. } else {
  481. s[ks] = cond / (rnrm * lnrm);
  482. }
  483. }
  484. }
  485. if (wantdf) {
  486. if (*n == 1) {
  487. dif[ks] = _starpu_dlapy2_(&a[a_dim1 + 1], &b[b_dim1 + 1]);
  488. goto L20;
  489. }
  490. /* Estimate the reciprocal condition number of the k-th */
  491. /* eigenvectors. */
  492. if (pair) {
  493. /* Copy the 2-by 2 pencil beginning at (A(k,k), B(k, k)). */
  494. /* Compute the eigenvalue(s) at position K. */
  495. work[1] = a[k + k * a_dim1];
  496. work[2] = a[k + 1 + k * a_dim1];
  497. work[3] = a[k + (k + 1) * a_dim1];
  498. work[4] = a[k + 1 + (k + 1) * a_dim1];
  499. work[5] = b[k + k * b_dim1];
  500. work[6] = b[k + 1 + k * b_dim1];
  501. work[7] = b[k + (k + 1) * b_dim1];
  502. work[8] = b[k + 1 + (k + 1) * b_dim1];
  503. d__1 = smlnum * eps;
  504. _starpu_dlag2_(&work[1], &c__2, &work[5], &c__2, &d__1, &beta, dummy1,
  505. &alphar, dummy, &alphai);
  506. alprqt = 1.;
  507. c1 = (alphar * alphar + alphai * alphai + beta * beta) * 2.;
  508. c2 = beta * 4. * beta * alphai * alphai;
  509. root1 = c1 + sqrt(c1 * c1 - c2 * 4.);
  510. root2 = c2 / root1;
  511. root1 /= 2.;
  512. /* Computing MIN */
  513. d__1 = sqrt(root1), d__2 = sqrt(root2);
  514. cond = min(d__1,d__2);
  515. }
  516. /* Copy the matrix (A, B) to the array WORK and swap the */
  517. /* diagonal block beginning at A(k,k) to the (1,1) position. */
  518. _starpu_dlacpy_("Full", n, n, &a[a_offset], lda, &work[1], n);
  519. _starpu_dlacpy_("Full", n, n, &b[b_offset], ldb, &work[*n * *n + 1], n);
  520. ifst = k;
  521. ilst = 1;
  522. i__2 = *lwork - (*n << 1) * *n;
  523. _starpu_dtgexc_(&c_false, &c_false, n, &work[1], n, &work[*n * *n + 1], n,
  524. dummy, &c__1, dummy1, &c__1, &ifst, &ilst, &work[(*n * *
  525. n << 1) + 1], &i__2, &ierr);
  526. if (ierr > 0) {
  527. /* Ill-conditioned problem - swap rejected. */
  528. dif[ks] = 0.;
  529. } else {
  530. /* Reordering successful, solve generalized Sylvester */
  531. /* equation for R and L, */
  532. /* A22 * R - L * A11 = A12 */
  533. /* B22 * R - L * B11 = B12, */
  534. /* and compute estimate of Difl((A11,B11), (A22, B22)). */
  535. n1 = 1;
  536. if (work[2] != 0.) {
  537. n1 = 2;
  538. }
  539. n2 = *n - n1;
  540. if (n2 == 0) {
  541. dif[ks] = cond;
  542. } else {
  543. i__ = *n * *n + 1;
  544. iz = (*n << 1) * *n + 1;
  545. i__2 = *lwork - (*n << 1) * *n;
  546. _starpu_dtgsyl_("N", &c__3, &n2, &n1, &work[*n * n1 + n1 + 1], n,
  547. &work[1], n, &work[n1 + 1], n, &work[*n * n1 + n1
  548. + i__], n, &work[i__], n, &work[n1 + i__], n, &
  549. scale, &dif[ks], &work[iz + 1], &i__2, &iwork[1],
  550. &ierr);
  551. if (pair) {
  552. /* Computing MIN */
  553. d__1 = max(1.,alprqt) * dif[ks];
  554. dif[ks] = min(d__1,cond);
  555. }
  556. }
  557. }
  558. if (pair) {
  559. dif[ks + 1] = dif[ks];
  560. }
  561. }
  562. if (pair) {
  563. ++ks;
  564. }
  565. L20:
  566. ;
  567. }
  568. work[1] = (doublereal) lwmin;
  569. return 0;
  570. /* End of DTGSNA */
  571. } /* _starpu_dtgsna_ */