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