1 /* ../netlib/dhsein.f -- translated by f2c (version 20100827). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib;
2 on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */
3 #include "FLA_f2c.h" /* Table of constant values */
4 static logical c_false = FALSE_;
5 static logical c_true = TRUE_;
6 /* > \brief \b DHSEIN */
7 /* =========== DOCUMENTATION =========== */
8 /* Online html documentation available at */
9 /* http://www.netlib.org/lapack/explore-html/ */
10 /* > \htmlonly */
11 /* > Download DHSEIN + dependencies */
12 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dhsein. f"> */
13 /* > [TGZ]</a> */
14 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dhsein. f"> */
15 /* > [ZIP]</a> */
16 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dhsein. f"> */
17 /* > [TXT]</a> */
18 /* > \endhtmlonly */
19 /* Definition: */
20 /* =========== */
21 /* SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI, */
22 /* VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL, */
23 /* IFAILR, INFO ) */
24 /* .. Scalar Arguments .. */
25 /* CHARACTER EIGSRC, INITV, SIDE */
26 /* INTEGER INFO, LDH, LDVL, LDVR, M, MM, N */
27 /* .. */
28 /* .. Array Arguments .. */
29 /* LOGICAL SELECT( * ) */
30 /* INTEGER IFAILL( * ), IFAILR( * ) */
31 /* DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ), */
32 /* $ WI( * ), WORK( * ), WR( * ) */
33 /* .. */
34 /* > \par Purpose: */
35 /* ============= */
36 /* > */
37 /* > \verbatim */
38 /* > */
39 /* > DHSEIN uses inverse iteration to find specified right and/or left */
40 /* > eigenvectors of a real upper Hessenberg matrix H. */
41 /* > */
42 /* > The right eigenvector x and the left eigenvector y of the matrix H */
43 /* > corresponding to an eigenvalue w are defined by: */
44 /* > */
45 /* > H * x = w * x, y**h * H = w * y**h */
46 /* > */
47 /* > where y**h denotes the conjugate transpose of the vector y. */
48 /* > \endverbatim */
49 /* Arguments: */
50 /* ========== */
51 /* > \param[in] SIDE */
52 /* > \verbatim */
53 /* > SIDE is CHARACTER*1 */
54 /* > = 'R': compute right eigenvectors only;
55 */
56 /* > = 'L': compute left eigenvectors only;
57 */
58 /* > = 'B': compute both right and left eigenvectors. */
59 /* > \endverbatim */
60 /* > */
61 /* > \param[in] EIGSRC */
62 /* > \verbatim */
63 /* > EIGSRC is CHARACTER*1 */
64 /* > Specifies the source of eigenvalues supplied in (WR,WI): */
65 /* > = 'Q': the eigenvalues were found using DHSEQR;
66 thus, if */
67 /* > H has zero subdiagonal elements, and so is */
68 /* > block-triangular, then the j-th eigenvalue can be */
69 /* > assumed to be an eigenvalue of the block containing */
70 /* > the j-th row/column. This property allows DHSEIN to */
71 /* > perform inverse iteration on just one diagonal block. */
72 /* > = 'N': no assumptions are made on the correspondence */
73 /* > between eigenvalues and diagonal blocks. In this */
74 /* > case, DHSEIN must always perform inverse iteration */
75 /* > using the whole matrix H. */
76 /* > \endverbatim */
77 /* > */
78 /* > \param[in] INITV */
79 /* > \verbatim */
80 /* > INITV is CHARACTER*1 */
81 /* > = 'N': no initial vectors are supplied;
82 */
83 /* > = 'U': user-supplied initial vectors are stored in the arrays */
84 /* > VL and/or VR. */
85 /* > \endverbatim */
86 /* > */
87 /* > \param[in,out] SELECT */
88 /* > \verbatim */
89 /* > SELECT is LOGICAL array, dimension (N) */
90 /* > Specifies the eigenvectors to be computed. To select the */
91 /* > real eigenvector corresponding to a real eigenvalue WR(j), */
92 /* > SELECT(j) must be set to .TRUE.. To select the complex */
93 /* > eigenvector corresponding to a complex eigenvalue */
94 /* > (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)), */
95 /* > either SELECT(j) or SELECT(j+1) or both must be set to */
96 /* > .TRUE.;
97 then on exit SELECT(j) is .TRUE. and SELECT(j+1) is */
98 /* > .FALSE.. */
99 /* > \endverbatim */
100 /* > */
101 /* > \param[in] N */
102 /* > \verbatim */
103 /* > N is INTEGER */
104 /* > The order of the matrix H. N >= 0. */
105 /* > \endverbatim */
106 /* > */
107 /* > \param[in] H */
108 /* > \verbatim */
109 /* > H is DOUBLE PRECISION array, dimension (LDH,N) */
110 /* > The upper Hessenberg matrix H. */
111 /* > If a NaN is detected in H, the routine will return with INFO=-6. */
112 /* > \endverbatim */
113 /* > */
114 /* > \param[in] LDH */
115 /* > \verbatim */
116 /* > LDH is INTEGER */
117 /* > The leading dimension of the array H. LDH >= max(1,N). */
118 /* > \endverbatim */
119 /* > */
120 /* > \param[in,out] WR */
121 /* > \verbatim */
122 /* > WR is DOUBLE PRECISION array, dimension (N) */
123 /* > \endverbatim */
124 /* > */
125 /* > \param[in] WI */
126 /* > \verbatim */
127 /* > WI is DOUBLE PRECISION array, dimension (N) */
128 /* > */
129 /* > On entry, the real and imaginary parts of the eigenvalues of */
130 /* > H;
131 a complex conjugate pair of eigenvalues must be stored in */
132 /* > consecutive elements of WR and WI. */
133 /* > On exit, WR may have been altered since close eigenvalues */
134 /* > are perturbed slightly in searching for independent */
135 /* > eigenvectors. */
136 /* > \endverbatim */
137 /* > */
138 /* > \param[in,out] VL */
139 /* > \verbatim */
140 /* > VL is DOUBLE PRECISION array, dimension (LDVL,MM) */
141 /* > On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must */
142 /* > contain starting vectors for the inverse iteration for the */
143 /* > left eigenvectors;
144 the starting vector for each eigenvector */
145 /* > must be in the same column(s) in which the eigenvector will */
146 /* > be stored. */
147 /* > On exit, if SIDE = 'L' or 'B', the left eigenvectors */
148 /* > specified by SELECT will be stored consecutively in the */
149 /* > columns of VL, in the same order as their eigenvalues. A */
150 /* > complex eigenvector corresponding to a complex eigenvalue is */
151 /* > stored in two consecutive columns, the first holding the real */
152 /* > part and the second the imaginary part. */
153 /* > If SIDE = 'R', VL is not referenced. */
154 /* > \endverbatim */
155 /* > */
156 /* > \param[in] LDVL */
157 /* > \verbatim */
158 /* > LDVL is INTEGER */
159 /* > The leading dimension of the array VL. */
160 /* > LDVL >= max(1,N) if SIDE = 'L' or 'B';
161 LDVL >= 1 otherwise. */
162 /* > \endverbatim */
163 /* > */
164 /* > \param[in,out] VR */
165 /* > \verbatim */
166 /* > VR is DOUBLE PRECISION array, dimension (LDVR,MM) */
167 /* > On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must */
168 /* > contain starting vectors for the inverse iteration for the */
169 /* > right eigenvectors;
170 the starting vector for each eigenvector */
171 /* > must be in the same column(s) in which the eigenvector will */
172 /* > be stored. */
173 /* > On exit, if SIDE = 'R' or 'B', the right eigenvectors */
174 /* > specified by SELECT will be stored consecutively in the */
175 /* > columns of VR, in the same order as their eigenvalues. A */
176 /* > complex eigenvector corresponding to a complex eigenvalue is */
177 /* > stored in two consecutive columns, the first holding the real */
178 /* > part and the second the imaginary part. */
179 /* > If SIDE = 'L', VR is not referenced. */
180 /* > \endverbatim */
181 /* > */
182 /* > \param[in] LDVR */
183 /* > \verbatim */
184 /* > LDVR is INTEGER */
185 /* > The leading dimension of the array VR. */
186 /* > LDVR >= max(1,N) if SIDE = 'R' or 'B';
187 LDVR >= 1 otherwise. */
188 /* > \endverbatim */
189 /* > */
190 /* > \param[in] MM */
191 /* > \verbatim */
192 /* > MM is INTEGER */
193 /* > The number of columns in the arrays VL and/or VR. MM >= M. */
194 /* > \endverbatim */
195 /* > */
196 /* > \param[out] M */
197 /* > \verbatim */
198 /* > M is INTEGER */
199 /* > The number of columns in the arrays VL and/or VR required to */
200 /* > store the eigenvectors;
201 each selected real eigenvector */
202 /* > occupies one column and each selected complex eigenvector */
203 /* > occupies two columns. */
204 /* > \endverbatim */
205 /* > */
206 /* > \param[out] WORK */
207 /* > \verbatim */
208 /* > WORK is DOUBLE PRECISION array, dimension ((N+2)*N) */
209 /* > \endverbatim */
210 /* > */
211 /* > \param[out] IFAILL */
212 /* > \verbatim */
213 /* > IFAILL is INTEGER array, dimension (MM) */
214 /* > If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left */
215 /* > eigenvector in the i-th column of VL (corresponding to the */
216 /* > eigenvalue w(j)) failed to converge;
217 IFAILL(i) = 0 if the */
218 /* > eigenvector converged satisfactorily. If the i-th and (i+1)th */
219 /* > columns of VL hold a complex eigenvector, then IFAILL(i) and */
220 /* > IFAILL(i+1) are set to the same value. */
221 /* > If SIDE = 'R', IFAILL is not referenced. */
222 /* > \endverbatim */
223 /* > */
224 /* > \param[out] IFAILR */
225 /* > \verbatim */
226 /* > IFAILR is INTEGER array, dimension (MM) */
227 /* > If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right */
228 /* > eigenvector in the i-th column of VR (corresponding to the */
229 /* > eigenvalue w(j)) failed to converge;
230 IFAILR(i) = 0 if the */
231 /* > eigenvector converged satisfactorily. If the i-th and (i+1)th */
232 /* > columns of VR hold a complex eigenvector, then IFAILR(i) and */
233 /* > IFAILR(i+1) are set to the same value. */
234 /* > If SIDE = 'L', IFAILR is not referenced. */
235 /* > \endverbatim */
236 /* > */
237 /* > \param[out] INFO */
238 /* > \verbatim */
239 /* > INFO is INTEGER */
240 /* > = 0: successful exit */
241 /* > < 0: if INFO = -i, the i-th argument had an illegal value */
242 /* > > 0: if INFO = i, i is the number of eigenvectors which */
243 /* > failed to converge;
244 see IFAILL and IFAILR for further */
245 /* > details. */
246 /* > \endverbatim */
247 /* Authors: */
248 /* ======== */
249 /* > \author Univ. of Tennessee */
250 /* > \author Univ. of California Berkeley */
251 /* > \author Univ. of Colorado Denver */
252 /* > \author NAG Ltd. */
253 /* > \date November 2013 */
254 /* > \ingroup doubleOTHERcomputational */
255 /* > \par Further Details: */
256 /* ===================== */
257 /* > */
258 /* > \verbatim */
259 /* > */
260 /* > Each eigenvector is normalized so that the element of largest */
261 /* > magnitude has magnitude 1;
262 here the magnitude of a complex number */
263 /* > (x,y) is taken to be |x|+|y|. */
264 /* > \endverbatim */
265 /* > */
266 /* ===================================================================== */
267 /* Subroutine */
dhsein_(char * side,char * eigsrc,char * initv,logical * select,integer * n,doublereal * h__,integer * ldh,doublereal * wr,doublereal * wi,doublereal * vl,integer * ldvl,doublereal * vr,integer * ldvr,integer * mm,integer * m,doublereal * work,integer * ifaill,integer * ifailr,integer * info)268 int dhsein_(char *side, char *eigsrc, char *initv, logical * select, integer *n, doublereal *h__, integer *ldh, doublereal *wr, doublereal *wi, doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr, integer *mm, integer *m, doublereal *work, integer * ifaill, integer *ifailr, integer *info)
269 {
270 /* System generated locals */
271 integer h_dim1, h_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2;
272 doublereal d__1, d__2;
273 /* Local variables */
274 integer i__, k, kl, kr, kln, ksi;
275 doublereal wki;
276 integer ksr;
277 doublereal ulp, wkr, eps3;
278 logical pair;
279 doublereal unfl;
280 extern logical lsame_(char *, char *);
281 integer iinfo;
282 logical leftv, bothv;
283 doublereal hnorm;
284 extern doublereal dlamch_(char *);
285 extern /* Subroutine */
286 int dlaein_(logical *, logical *, integer *, doublereal *, integer *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, integer *, doublereal *, doublereal * , doublereal *, doublereal *, integer *);
287 extern doublereal dlanhs_(char *, integer *, doublereal *, integer *, doublereal *);
288 extern logical disnan_(doublereal *);
289 extern /* Subroutine */
290 int xerbla_(char *, integer *);
291 doublereal bignum;
292 logical noinit;
293 integer ldwork;
294 logical rightv, fromqr;
295 doublereal smlnum;
296 /* -- LAPACK computational routine (version 3.5.0) -- */
297 /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
298 /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
299 /* November 2013 */
300 /* .. Scalar Arguments .. */
301 /* .. */
302 /* .. Array Arguments .. */
303 /* .. */
304 /* ===================================================================== */
305 /* .. Parameters .. */
306 /* .. */
307 /* .. Local Scalars .. */
308 /* .. */
309 /* .. External Functions .. */
310 /* .. */
311 /* .. External Subroutines .. */
312 /* .. */
313 /* .. Intrinsic Functions .. */
314 /* .. */
315 /* .. Executable Statements .. */
316 /* Decode and test the input parameters. */
317 /* Parameter adjustments */
318 --select;
319 h_dim1 = *ldh;
320 h_offset = 1 + h_dim1;
321 h__ -= h_offset;
322 --wr;
323 --wi;
324 vl_dim1 = *ldvl;
325 vl_offset = 1 + vl_dim1;
326 vl -= vl_offset;
327 vr_dim1 = *ldvr;
328 vr_offset = 1 + vr_dim1;
329 vr -= vr_offset;
330 --work;
331 --ifaill;
332 --ifailr;
333 /* Function Body */
334 bothv = lsame_(side, "B");
335 rightv = lsame_(side, "R") || bothv;
336 leftv = lsame_(side, "L") || bothv;
337 fromqr = lsame_(eigsrc, "Q");
338 noinit = lsame_(initv, "N");
339 /* Set M to the number of columns required to store the selected */
340 /* eigenvectors, and standardize the array SELECT. */
341 *m = 0;
342 pair = FALSE_;
343 i__1 = *n;
344 for (k = 1;
345 k <= i__1;
346 ++k)
347 {
348 if (pair)
349 {
350 pair = FALSE_;
351 select[k] = FALSE_;
352 }
353 else
354 {
355 if (wi[k] == 0.)
356 {
357 if (select[k])
358 {
359 ++(*m);
360 }
361 }
362 else
363 {
364 pair = TRUE_;
365 if (select[k] || select[k + 1])
366 {
367 select[k] = TRUE_;
368 *m += 2;
369 }
370 }
371 }
372 /* L10: */
373 }
374 *info = 0;
375 if (! rightv && ! leftv)
376 {
377 *info = -1;
378 }
379 else if (! fromqr && ! lsame_(eigsrc, "N"))
380 {
381 *info = -2;
382 }
383 else if (! noinit && ! lsame_(initv, "U"))
384 {
385 *info = -3;
386 }
387 else if (*n < 0)
388 {
389 *info = -5;
390 }
391 else if (*ldh < max(1,*n))
392 {
393 *info = -7;
394 }
395 else if (*ldvl < 1 || leftv && *ldvl < *n)
396 {
397 *info = -11;
398 }
399 else if (*ldvr < 1 || rightv && *ldvr < *n)
400 {
401 *info = -13;
402 }
403 else if (*mm < *m)
404 {
405 *info = -14;
406 }
407 if (*info != 0)
408 {
409 i__1 = -(*info);
410 xerbla_("DHSEIN", &i__1);
411 return 0;
412 }
413 /* Quick return if possible. */
414 if (*n == 0)
415 {
416 return 0;
417 }
418 /* Set machine-dependent constants. */
419 unfl = dlamch_("Safe minimum");
420 ulp = dlamch_("Precision");
421 smlnum = unfl * (*n / ulp);
422 bignum = (1. - ulp) / smlnum;
423 ldwork = *n + 1;
424 kl = 1;
425 kln = 0;
426 if (fromqr)
427 {
428 kr = 0;
429 }
430 else
431 {
432 kr = *n;
433 }
434 ksr = 1;
435 i__1 = *n;
436 for (k = 1;
437 k <= i__1;
438 ++k)
439 {
440 if (select[k])
441 {
442 /* Compute eigenvector(s) corresponding to W(K). */
443 if (fromqr)
444 {
445 /* If affiliation of eigenvalues is known, check whether */
446 /* the matrix splits. */
447 /* Determine KL and KR such that 1 <= KL <= K <= KR <= N */
448 /* and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or */
449 /* KR = N). */
450 /* Then inverse iteration can be performed with the */
451 /* submatrix H(KL:N,KL:N) for a left eigenvector, and with */
452 /* the submatrix H(1:KR,1:KR) for a right eigenvector. */
453 i__2 = kl + 1;
454 for (i__ = k;
455 i__ >= i__2;
456 --i__)
457 {
458 if (h__[i__ + (i__ - 1) * h_dim1] == 0.)
459 {
460 goto L30;
461 }
462 /* L20: */
463 }
464 L30:
465 kl = i__;
466 if (k > kr)
467 {
468 i__2 = *n - 1;
469 for (i__ = k;
470 i__ <= i__2;
471 ++i__)
472 {
473 if (h__[i__ + 1 + i__ * h_dim1] == 0.)
474 {
475 goto L50;
476 }
477 /* L40: */
478 }
479 L50:
480 kr = i__;
481 }
482 }
483 if (kl != kln)
484 {
485 kln = kl;
486 /* Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it */
487 /* has not ben computed before. */
488 i__2 = kr - kl + 1;
489 hnorm = dlanhs_("I", &i__2, &h__[kl + kl * h_dim1], ldh, & work[1]);
490 if (disnan_(&hnorm))
491 {
492 *info = -6;
493 return 0;
494 }
495 else if (hnorm > 0.)
496 {
497 eps3 = hnorm * ulp;
498 }
499 else
500 {
501 eps3 = smlnum;
502 }
503 }
504 /* Perturb eigenvalue if it is close to any previous */
505 /* selected eigenvalues affiliated to the submatrix */
506 /* H(KL:KR,KL:KR). Close roots are modified by EPS3. */
507 wkr = wr[k];
508 wki = wi[k];
509 L60:
510 i__2 = kl;
511 for (i__ = k - 1;
512 i__ >= i__2;
513 --i__)
514 {
515 if (select[i__] && (d__1 = wr[i__] - wkr, f2c_abs(d__1)) + (d__2 = wi[i__] - wki, f2c_abs(d__2)) < eps3)
516 {
517 wkr += eps3;
518 goto L60;
519 }
520 /* L70: */
521 }
522 wr[k] = wkr;
523 pair = wki != 0.;
524 if (pair)
525 {
526 ksi = ksr + 1;
527 }
528 else
529 {
530 ksi = ksr;
531 }
532 if (leftv)
533 {
534 /* Compute left eigenvector. */
535 i__2 = *n - kl + 1;
536 dlaein_(&c_false, &noinit, &i__2, &h__[kl + kl * h_dim1], ldh, &wkr, &wki, &vl[kl + ksr * vl_dim1], &vl[kl + ksi * vl_dim1], &work[1], &ldwork, &work[*n * *n + *n + 1], &eps3, &smlnum, &bignum, &iinfo);
537 if (iinfo > 0)
538 {
539 if (pair)
540 {
541 *info += 2;
542 }
543 else
544 {
545 ++(*info);
546 }
547 ifaill[ksr] = k;
548 ifaill[ksi] = k;
549 }
550 else
551 {
552 ifaill[ksr] = 0;
553 ifaill[ksi] = 0;
554 }
555 i__2 = kl - 1;
556 for (i__ = 1;
557 i__ <= i__2;
558 ++i__)
559 {
560 vl[i__ + ksr * vl_dim1] = 0.;
561 /* L80: */
562 }
563 if (pair)
564 {
565 i__2 = kl - 1;
566 for (i__ = 1;
567 i__ <= i__2;
568 ++i__)
569 {
570 vl[i__ + ksi * vl_dim1] = 0.;
571 /* L90: */
572 }
573 }
574 }
575 if (rightv)
576 {
577 /* Compute right eigenvector. */
578 dlaein_(&c_true, &noinit, &kr, &h__[h_offset], ldh, &wkr, & wki, &vr[ksr * vr_dim1 + 1], &vr[ksi * vr_dim1 + 1], & work[1], &ldwork, &work[*n * *n + *n + 1], &eps3, & smlnum, &bignum, &iinfo);
579 if (iinfo > 0)
580 {
581 if (pair)
582 {
583 *info += 2;
584 }
585 else
586 {
587 ++(*info);
588 }
589 ifailr[ksr] = k;
590 ifailr[ksi] = k;
591 }
592 else
593 {
594 ifailr[ksr] = 0;
595 ifailr[ksi] = 0;
596 }
597 i__2 = *n;
598 for (i__ = kr + 1;
599 i__ <= i__2;
600 ++i__)
601 {
602 vr[i__ + ksr * vr_dim1] = 0.;
603 /* L100: */
604 }
605 if (pair)
606 {
607 i__2 = *n;
608 for (i__ = kr + 1;
609 i__ <= i__2;
610 ++i__)
611 {
612 vr[i__ + ksi * vr_dim1] = 0.;
613 /* L110: */
614 }
615 }
616 }
617 if (pair)
618 {
619 ksr += 2;
620 }
621 else
622 {
623 ++ksr;
624 }
625 }
626 /* L120: */
627 }
628 return 0;
629 /* End of DHSEIN */
630 }
631 /* dhsein_ */
632