diff options
author | shmel1k <shmel1k@ydb.tech> | 2022-09-02 12:44:59 +0300 |
---|---|---|
committer | shmel1k <shmel1k@ydb.tech> | 2022-09-02 12:44:59 +0300 |
commit | 90d450f74722da7859d6f510a869f6c6908fd12f (patch) | |
tree | 538c718dedc76cdfe37ad6d01ff250dd930d9278 /contrib/libs/clapack/dhsein.c | |
parent | 01f64c1ecd0d4ffa9e3a74478335f1745f26cc75 (diff) | |
download | ydb-90d450f74722da7859d6f510a869f6c6908fd12f.tar.gz |
[] add metering mode to CLI
Diffstat (limited to 'contrib/libs/clapack/dhsein.c')
-rw-r--r-- | contrib/libs/clapack/dhsein.c | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/contrib/libs/clapack/dhsein.c b/contrib/libs/clapack/dhsein.c new file mode 100644 index 0000000000..7220f147a0 --- /dev/null +++ b/contrib/libs/clapack/dhsein.c @@ -0,0 +1,491 @@ +/* dhsein.f -- translated by f2c (version 20061008). + You must link the resulting object file with libf2c: + on Microsoft Windows system, link with libf2c.lib; + 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 +*/ + +#include "f2c.h" +#include "blaswrap.h" + +/* Table of constant values */ + +static logical c_false = FALSE_; +static logical c_true = TRUE_; + +/* Subroutine */ 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) +{ + /* System generated locals */ + integer h_dim1, h_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, + i__2; + doublereal d__1, d__2; + + /* Local variables */ + integer i__, k, kl, kr, kln, ksi; + doublereal wki; + integer ksr; + doublereal ulp, wkr, eps3; + logical pair; + doublereal unfl; + extern logical lsame_(char *, char *); + integer iinfo; + logical leftv, bothv; + doublereal hnorm; + extern doublereal dlamch_(char *); + extern /* Subroutine */ int dlaein_(logical *, logical *, integer *, + doublereal *, integer *, doublereal *, doublereal *, doublereal *, + doublereal *, doublereal *, integer *, doublereal *, doublereal * +, doublereal *, doublereal *, integer *); + extern doublereal dlanhs_(char *, integer *, doublereal *, integer *, + doublereal *); + extern /* Subroutine */ int xerbla_(char *, integer *); + doublereal bignum; + logical noinit; + integer ldwork; + logical rightv, fromqr; + doublereal smlnum; + + +/* -- LAPACK routine (version 3.2) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ +/* November 2006 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DHSEIN uses inverse iteration to find specified right and/or left */ +/* eigenvectors of a real upper Hessenberg matrix H. */ + +/* The right eigenvector x and the left eigenvector y of the matrix H */ +/* corresponding to an eigenvalue w are defined by: */ + +/* H * x = w * x, y**h * H = w * y**h */ + +/* where y**h denotes the conjugate transpose of the vector y. */ + +/* Arguments */ +/* ========= */ + +/* SIDE (input) CHARACTER*1 */ +/* = 'R': compute right eigenvectors only; */ +/* = 'L': compute left eigenvectors only; */ +/* = 'B': compute both right and left eigenvectors. */ + +/* EIGSRC (input) CHARACTER*1 */ +/* Specifies the source of eigenvalues supplied in (WR,WI): */ +/* = 'Q': the eigenvalues were found using DHSEQR; thus, if */ +/* H has zero subdiagonal elements, and so is */ +/* block-triangular, then the j-th eigenvalue can be */ +/* assumed to be an eigenvalue of the block containing */ +/* the j-th row/column. This property allows DHSEIN to */ +/* perform inverse iteration on just one diagonal block. */ +/* = 'N': no assumptions are made on the correspondence */ +/* between eigenvalues and diagonal blocks. In this */ +/* case, DHSEIN must always perform inverse iteration */ +/* using the whole matrix H. */ + +/* INITV (input) CHARACTER*1 */ +/* = 'N': no initial vectors are supplied; */ +/* = 'U': user-supplied initial vectors are stored in the arrays */ +/* VL and/or VR. */ + +/* SELECT (input/output) LOGICAL array, dimension (N) */ +/* Specifies the eigenvectors to be computed. To select the */ +/* real eigenvector corresponding to a real eigenvalue WR(j), */ +/* SELECT(j) must be set to .TRUE.. To select the complex */ +/* eigenvector corresponding to a complex eigenvalue */ +/* (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)), */ +/* either SELECT(j) or SELECT(j+1) or both must be set to */ +/* .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is */ +/* .FALSE.. */ + +/* N (input) INTEGER */ +/* The order of the matrix H. N >= 0. */ + +/* H (input) DOUBLE PRECISION array, dimension (LDH,N) */ +/* The upper Hessenberg matrix H. */ + +/* LDH (input) INTEGER */ +/* The leading dimension of the array H. LDH >= max(1,N). */ + +/* WR (input/output) DOUBLE PRECISION array, dimension (N) */ +/* WI (input) DOUBLE PRECISION array, dimension (N) */ +/* On entry, the real and imaginary parts of the eigenvalues of */ +/* H; a complex conjugate pair of eigenvalues must be stored in */ +/* consecutive elements of WR and WI. */ +/* On exit, WR may have been altered since close eigenvalues */ +/* are perturbed slightly in searching for independent */ +/* eigenvectors. */ + +/* VL (input/output) DOUBLE PRECISION array, dimension (LDVL,MM) */ +/* On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must */ +/* contain starting vectors for the inverse iteration for the */ +/* left eigenvectors; the starting vector for each eigenvector */ +/* must be in the same column(s) in which the eigenvector will */ +/* be stored. */ +/* On exit, if SIDE = 'L' or 'B', the left eigenvectors */ +/* specified by SELECT will be stored consecutively in the */ +/* columns of VL, in the same order as their eigenvalues. A */ +/* complex eigenvector corresponding to a complex eigenvalue is */ +/* stored in two consecutive columns, the first holding the real */ +/* part and the second the imaginary part. */ +/* If SIDE = 'R', VL is not referenced. */ + +/* LDVL (input) INTEGER */ +/* The leading dimension of the array VL. */ +/* LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise. */ + +/* VR (input/output) DOUBLE PRECISION array, dimension (LDVR,MM) */ +/* On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must */ +/* contain starting vectors for the inverse iteration for the */ +/* right eigenvectors; the starting vector for each eigenvector */ +/* must be in the same column(s) in which the eigenvector will */ +/* be stored. */ +/* On exit, if SIDE = 'R' or 'B', the right eigenvectors */ +/* specified by SELECT will be stored consecutively in the */ +/* columns of VR, in the same order as their eigenvalues. A */ +/* complex eigenvector corresponding to a complex eigenvalue is */ +/* stored in two consecutive columns, the first holding the real */ +/* part and the second the imaginary part. */ +/* If SIDE = 'L', VR is not referenced. */ + +/* LDVR (input) INTEGER */ +/* The leading dimension of the array VR. */ +/* LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise. */ + +/* MM (input) INTEGER */ +/* The number of columns in the arrays VL and/or VR. MM >= M. */ + +/* M (output) INTEGER */ +/* The number of columns in the arrays VL and/or VR required to */ +/* store the eigenvectors; each selected real eigenvector */ +/* occupies one column and each selected complex eigenvector */ +/* occupies two columns. */ + +/* WORK (workspace) DOUBLE PRECISION array, dimension ((N+2)*N) */ + +/* IFAILL (output) INTEGER array, dimension (MM) */ +/* If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left */ +/* eigenvector in the i-th column of VL (corresponding to the */ +/* eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the */ +/* eigenvector converged satisfactorily. If the i-th and (i+1)th */ +/* columns of VL hold a complex eigenvector, then IFAILL(i) and */ +/* IFAILL(i+1) are set to the same value. */ +/* If SIDE = 'R', IFAILL is not referenced. */ + +/* IFAILR (output) INTEGER array, dimension (MM) */ +/* If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right */ +/* eigenvector in the i-th column of VR (corresponding to the */ +/* eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the */ +/* eigenvector converged satisfactorily. If the i-th and (i+1)th */ +/* columns of VR hold a complex eigenvector, then IFAILR(i) and */ +/* IFAILR(i+1) are set to the same value. */ +/* If SIDE = 'L', IFAILR is not referenced. */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ +/* > 0: if INFO = i, i is the number of eigenvectors which */ +/* failed to converge; see IFAILL and IFAILR for further */ +/* details. */ + +/* Further Details */ +/* =============== */ + +/* Each eigenvector is normalized so that the element of largest */ +/* magnitude has magnitude 1; here the magnitude of a complex number */ +/* (x,y) is taken to be |x|+|y|. */ + +/* ===================================================================== */ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Decode and test the input parameters. */ + + /* Parameter adjustments */ + --select; + h_dim1 = *ldh; + h_offset = 1 + h_dim1; + h__ -= h_offset; + --wr; + --wi; + vl_dim1 = *ldvl; + vl_offset = 1 + vl_dim1; + vl -= vl_offset; + vr_dim1 = *ldvr; + vr_offset = 1 + vr_dim1; + vr -= vr_offset; + --work; + --ifaill; + --ifailr; + + /* Function Body */ + bothv = lsame_(side, "B"); + rightv = lsame_(side, "R") || bothv; + leftv = lsame_(side, "L") || bothv; + + fromqr = lsame_(eigsrc, "Q"); + + noinit = lsame_(initv, "N"); + +/* Set M to the number of columns required to store the selected */ +/* eigenvectors, and standardize the array SELECT. */ + + *m = 0; + pair = FALSE_; + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + if (pair) { + pair = FALSE_; + select[k] = FALSE_; + } else { + if (wi[k] == 0.) { + if (select[k]) { + ++(*m); + } + } else { + pair = TRUE_; + if (select[k] || select[k + 1]) { + select[k] = TRUE_; + *m += 2; + } + } + } +/* L10: */ + } + + *info = 0; + if (! rightv && ! leftv) { + *info = -1; + } else if (! fromqr && ! lsame_(eigsrc, "N")) { + *info = -2; + } else if (! noinit && ! lsame_(initv, "U")) { + *info = -3; + } else if (*n < 0) { + *info = -5; + } else if (*ldh < max(1,*n)) { + *info = -7; + } else if (*ldvl < 1 || leftv && *ldvl < *n) { + *info = -11; + } else if (*ldvr < 1 || rightv && *ldvr < *n) { + *info = -13; + } else if (*mm < *m) { + *info = -14; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DHSEIN", &i__1); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0) { + return 0; + } + +/* Set machine-dependent constants. */ + + unfl = dlamch_("Safe minimum"); + ulp = dlamch_("Precision"); + smlnum = unfl * (*n / ulp); + bignum = (1. - ulp) / smlnum; + + ldwork = *n + 1; + + kl = 1; + kln = 0; + if (fromqr) { + kr = 0; + } else { + kr = *n; + } + ksr = 1; + + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + if (select[k]) { + +/* Compute eigenvector(s) corresponding to W(K). */ + + if (fromqr) { + +/* If affiliation of eigenvalues is known, check whether */ +/* the matrix splits. */ + +/* Determine KL and KR such that 1 <= KL <= K <= KR <= N */ +/* and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or */ +/* KR = N). */ + +/* Then inverse iteration can be performed with the */ +/* submatrix H(KL:N,KL:N) for a left eigenvector, and with */ +/* the submatrix H(1:KR,1:KR) for a right eigenvector. */ + + i__2 = kl + 1; + for (i__ = k; i__ >= i__2; --i__) { + if (h__[i__ + (i__ - 1) * h_dim1] == 0.) { + goto L30; + } +/* L20: */ + } +L30: + kl = i__; + if (k > kr) { + i__2 = *n - 1; + for (i__ = k; i__ <= i__2; ++i__) { + if (h__[i__ + 1 + i__ * h_dim1] == 0.) { + goto L50; + } +/* L40: */ + } +L50: + kr = i__; + } + } + + if (kl != kln) { + kln = kl; + +/* Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it */ +/* has not ben computed before. */ + + i__2 = kr - kl + 1; + hnorm = dlanhs_("I", &i__2, &h__[kl + kl * h_dim1], ldh, & + work[1]); + if (hnorm > 0.) { + eps3 = hnorm * ulp; + } else { + eps3 = smlnum; + } + } + +/* Perturb eigenvalue if it is close to any previous */ +/* selected eigenvalues affiliated to the submatrix */ +/* H(KL:KR,KL:KR). Close roots are modified by EPS3. */ + + wkr = wr[k]; + wki = wi[k]; +L60: + i__2 = kl; + for (i__ = k - 1; i__ >= i__2; --i__) { + if (select[i__] && (d__1 = wr[i__] - wkr, abs(d__1)) + (d__2 = + wi[i__] - wki, abs(d__2)) < eps3) { + wkr += eps3; + goto L60; + } +/* L70: */ + } + wr[k] = wkr; + + pair = wki != 0.; + if (pair) { + ksi = ksr + 1; + } else { + ksi = ksr; + } + if (leftv) { + +/* Compute left eigenvector. */ + + i__2 = *n - kl + 1; + 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); + if (iinfo > 0) { + if (pair) { + *info += 2; + } else { + ++(*info); + } + ifaill[ksr] = k; + ifaill[ksi] = k; + } else { + ifaill[ksr] = 0; + ifaill[ksi] = 0; + } + i__2 = kl - 1; + for (i__ = 1; i__ <= i__2; ++i__) { + vl[i__ + ksr * vl_dim1] = 0.; +/* L80: */ + } + if (pair) { + i__2 = kl - 1; + for (i__ = 1; i__ <= i__2; ++i__) { + vl[i__ + ksi * vl_dim1] = 0.; +/* L90: */ + } + } + } + if (rightv) { + +/* Compute right eigenvector. */ + + 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); + if (iinfo > 0) { + if (pair) { + *info += 2; + } else { + ++(*info); + } + ifailr[ksr] = k; + ifailr[ksi] = k; + } else { + ifailr[ksr] = 0; + ifailr[ksi] = 0; + } + i__2 = *n; + for (i__ = kr + 1; i__ <= i__2; ++i__) { + vr[i__ + ksr * vr_dim1] = 0.; +/* L100: */ + } + if (pair) { + i__2 = *n; + for (i__ = kr + 1; i__ <= i__2; ++i__) { + vr[i__ + ksi * vr_dim1] = 0.; +/* L110: */ + } + } + } + + if (pair) { + ksr += 2; + } else { + ++ksr; + } + } +/* L120: */ + } + + return 0; + +/* End of DHSEIN */ + +} /* dhsein_ */ |