/* Subroutine */ int ctrsen_(char *job, char *compq, logical *select, integer *n, complex *t, integer *ldt, complex *q, integer *ldq, complex *w, integer *m, real *s, real *sep, complex *work, integer *lwork, integer *info) { /* System generated locals */ integer q_dim1, q_offset, t_dim1, t_offset, i__1, i__2, i__3; /* Builtin functions */ double sqrt(doublereal); /* Local variables */ integer k, n1, n2, nn, ks; real est; integer kase, ierr; real scale; extern logical lsame_(char *, char *); integer isave[3], lwmin; logical wantq, wants; real rnorm; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); real rwork[1]; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), xerbla_(char *, integer *); logical wantbh; extern /* Subroutine */ int ctrexc_(char *, integer *, complex *, integer *, complex *, integer *, integer *, integer *, integer *); logical wantsp; extern /* Subroutine */ int ctrsyl_(char *, char *, integer *, integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, real *, integer *); logical lquery; /* -- LAPACK routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTRSEN reorders the Schur factorization of a complex matrix */ /* A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in */ /* the leading positions on the diagonal of the upper triangular matrix */ /* T, and the leading columns of Q form an orthonormal basis of the */ /* corresponding right invariant subspace. */ /* Optionally the routine computes the reciprocal condition numbers of */ /* the cluster of eigenvalues and/or the invariant subspace. */ /* Arguments */ /* ========= */ /* JOB (input) CHARACTER*1 */ /* Specifies whether condition numbers are required for the */ /* cluster of eigenvalues (S) or the invariant subspace (SEP): */ /* = 'N': none; */ /* = 'E': for eigenvalues only (S); */ /* = 'V': for invariant subspace only (SEP); */ /* = 'B': for both eigenvalues and invariant subspace (S and */ /* SEP). */ /* COMPQ (input) CHARACTER*1 */ /* = 'V': update the matrix Q of Schur vectors; */ /* = 'N': do not update Q. */ /* SELECT (input) LOGICAL array, dimension (N) */ /* SELECT specifies the eigenvalues in the selected cluster. To */ /* select the j-th eigenvalue, SELECT(j) must be set to .TRUE.. */ /* N (input) INTEGER */ /* The order of the matrix T. N >= 0. */ /* T (input/output) COMPLEX array, dimension (LDT,N) */ /* On entry, the upper triangular matrix T. */ /* On exit, T is overwritten by the reordered matrix T, with the */ /* selected eigenvalues as the leading diagonal elements. */ /* LDT (input) INTEGER */ /* The leading dimension of the array T. LDT >= max(1,N). */ /* Q (input/output) COMPLEX array, dimension (LDQ,N) */ /* On entry, if COMPQ = 'V', the matrix Q of Schur vectors. */ /* On exit, if COMPQ = 'V', Q has been postmultiplied by the */ /* unitary transformation matrix which reorders T; the leading M */ /* columns of Q form an orthonormal basis for the specified */ /* invariant subspace. */ /* If COMPQ = 'N', Q is not referenced. */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. */ /* LDQ >= 1; and if COMPQ = 'V', LDQ >= N. */ /* W (output) COMPLEX array, dimension (N) */ /* The reordered eigenvalues of T, in the same order as they */ /* appear on the diagonal of T. */ /* M (output) INTEGER */ /* The dimension of the specified invariant subspace. */ /* 0 <= M <= N. */ /* S (output) REAL */ /* If JOB = 'E' or 'B', S is a lower bound on the reciprocal */ /* condition number for the selected cluster of eigenvalues. */ /* S cannot underestimate the true reciprocal condition number */ /* by more than a factor of sqrt(N). If M = 0 or N, S = 1. */ /* If JOB = 'N' or 'V', S is not referenced. */ /* SEP (output) REAL */ /* If JOB = 'V' or 'B', SEP is the estimated reciprocal */ /* condition number of the specified invariant subspace. If */ /* M = 0 or N, SEP = norm(T). */ /* If JOB = 'N' or 'E', SEP is not referenced. */ /* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */ /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. */ /* If JOB = 'N', LWORK >= 1; */ /* if JOB = 'E', LWORK = max(1,M*(N-M)); */ /* if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)). */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the optimal size of the WORK array, returns */ /* this value as the first entry of the WORK array, and no error */ /* message related to LWORK is issued by XERBLA. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* Further Details */ /* =============== */ /* CTRSEN first collects the selected eigenvalues by computing a unitary */ /* transformation Z to move them to the top left corner of T. In other */ /* words, the selected eigenvalues are the eigenvalues of T11 in: */ /* Z'*T*Z = ( T11 T12 ) n1 */ /* ( 0 T22 ) n2 */ /* n1 n2 */ /* where N = n1+n2 and Z' means the conjugate transpose of Z. The first */ /* n1 columns of Z span the specified invariant subspace of T. */ /* If T has been obtained from the Schur factorization of a matrix */ /* A = Q*T*Q', then the reordered Schur factorization of A is given by */ /* A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span the */ /* corresponding invariant subspace of A. */ /* The reciprocal condition number of the average of the eigenvalues of */ /* T11 may be returned in S. S lies between 0 (very badly conditioned) */ /* and 1 (very well conditioned). It is computed as follows. First we */ /* compute R so that */ /* P = ( I R ) n1 */ /* ( 0 0 ) n2 */ /* n1 n2 */ /* is the projector on the invariant subspace associated with T11. */ /* R is the solution of the Sylvester equation: */ /* T11*R - R*T22 = T12. */ /* Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote */ /* the two-norm of M. Then S is computed as the lower bound */ /* (1 + F-norm(R)**2)**(-1/2) */ /* on the reciprocal of 2-norm(P), the true reciprocal condition number. */ /* S cannot underestimate 1 / 2-norm(P) by more than a factor of */ /* sqrt(N). */ /* An approximate error bound for the computed average of the */ /* eigenvalues of T11 is */ /* EPS * norm(T) / S */ /* where EPS is the machine precision. */ /* The reciprocal condition number of the right invariant subspace */ /* spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP. */ /* SEP is defined as the separation of T11 and T22: */ /* sep( T11, T22 ) = sigma-min( C ) */ /* where sigma-min(C) is the smallest singular value of the */ /* n1*n2-by-n1*n2 matrix */ /* C = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) ) */ /* I(m) is an m by m identity matrix, and kprod denotes the Kronecker */ /* product. We estimate sigma-min(C) by the reciprocal of an estimate of */ /* the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C) */ /* cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2). */ /* When SEP is small, small changes in T can cause large changes in */ /* the invariant subspace. An approximate bound on the maximum angular */ /* error in the computed right invariant subspace is */ /* EPS * norm(T) / SEP */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Decode and test the input parameters. */ /* Parameter adjustments */ --select; t_dim1 = *ldt; t_offset = 1 + t_dim1; t -= t_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; --w; --work; /* Function Body */ wantbh = lsame_(job, "B"); wants = lsame_(job, "E") || wantbh; wantsp = lsame_(job, "V") || wantbh; wantq = lsame_(compq, "V"); /* Set M to the number of selected eigenvalues. */ *m = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { if (select[k]) { ++(*m); } /* L10: */ } n1 = *m; n2 = *n - *m; nn = n1 * n2; *info = 0; lquery = *lwork == -1; if (wantsp) { /* Computing MAX */ i__1 = 1, i__2 = nn << 1; lwmin = max(i__1,i__2); } else if (lsame_(job, "N")) { lwmin = 1; } else if (lsame_(job, "E")) { lwmin = max(1,nn); } if (! lsame_(job, "N") && ! wants && ! wantsp) { *info = -1; } else if (! lsame_(compq, "N") && ! wantq) { *info = -2; } else if (*n < 0) { *info = -4; } else if (*ldt < max(1,*n)) { *info = -6; } else if (*ldq < 1 || wantq && *ldq < *n) { *info = -8; } else if (*lwork < lwmin && ! lquery) { *info = -14; } if (*info == 0) { work[1].r = (real) lwmin, work[1].i = 0.f; } if (*info != 0) { i__1 = -(*info); xerbla_("CTRSEN", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == *n || *m == 0) { if (wants) { *s = 1.f; } if (wantsp) { *sep = clange_("1", n, n, &t[t_offset], ldt, rwork); } goto L40; } /* Collect the selected eigenvalues at the top left corner of T. */ ks = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { if (select[k]) { ++ks; /* Swap the K-th eigenvalue to position KS. */ if (k != ks) { ctrexc_(compq, n, &t[t_offset], ldt, &q[q_offset], ldq, &k, & ks, &ierr); } } /* L20: */ } if (wants) { /* Solve the Sylvester equation for R: */ /* T11*R - R*T22 = scale*T12 */ clacpy_("F", &n1, &n2, &t[(n1 + 1) * t_dim1 + 1], ldt, &work[1], &n1); ctrsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, &ierr); /* Estimate the reciprocal of the condition number of the cluster */ /* of eigenvalues. */ rnorm = clange_("F", &n1, &n2, &work[1], &n1, rwork); if (rnorm == 0.f) { *s = 1.f; } else { *s = scale / (sqrt(scale * scale / rnorm + rnorm) * sqrt(rnorm)); } } if (wantsp) { /* Estimate sep(T11,T22). */ est = 0.f; kase = 0; L30: clacn2_(&nn, &work[nn + 1], &work[1], &est, &kase, isave); if (kase != 0) { if (kase == 1) { /* Solve T11*R - R*T22 = scale*X. */ ctrsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, & ierr); } else { /* Solve T11'*R - R*T22' = scale*X. */ ctrsyl_("C", "C", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, & ierr); } goto L30; } *sep = scale / est; } L40: /* Copy reordered eigenvalues to W. */ i__1 = *n; for (k = 1; k <= i__1; ++k) { i__2 = k; i__3 = k + k * t_dim1; w[i__2].r = t[i__3].r, w[i__2].i = t[i__3].i; /* L50: */ } work[1].r = (real) lwmin, work[1].i = 0.f; return 0; /* End of CTRSEN */ } /* ctrsen_ */
/* Subroutine */ int ctrsna_(char *job, char *howmny, logical *select, integer *n, complex *t, integer *ldt, complex *vl, integer *ldvl, complex *vr, integer *ldvr, real *s, real *sep, integer *mm, integer * m, complex *work, integer *ldwork, real *rwork, integer *info) { /* System generated locals */ integer t_dim1, t_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, work_dim1, work_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2; complex q__1; /* Builtin functions */ double c_abs(complex *), r_imag(complex *); /* Local variables */ integer i__, j, k, ks, ix; real eps, est; integer kase, ierr; complex prod; real lnrm, rnrm, scale; extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer *, complex *, integer *); extern logical lsame_(char *, char *); integer isave[3]; complex dummy[1]; logical wants; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); real xnorm; extern doublereal scnrm2_(integer *, complex *, integer *); extern /* Subroutine */ int slabad_(real *, real *); extern integer icamax_(integer *, complex *, integer *); extern doublereal slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), xerbla_(char *, integer *); real bignum; logical wantbh; extern /* Subroutine */ int clatrs_(char *, char *, char *, char *, integer *, complex *, integer *, complex *, real *, real *, integer *), csrscl_(integer *, real *, complex *, integer *), ctrexc_(char *, integer *, complex *, integer *, complex *, integer *, integer *, integer *, integer *); logical somcon; char normin[1]; real smlnum; logical wantsp; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTRSNA estimates reciprocal condition numbers for specified */ /* eigenvalues and/or right eigenvectors of a complex upper triangular */ /* matrix T (or of any matrix Q*T*Q**H with Q unitary). */ /* Arguments */ /* ========= */ /* JOB (input) CHARACTER*1 */ /* Specifies whether condition numbers are required for */ /* eigenvalues (S) or eigenvectors (SEP): */ /* = 'E': for eigenvalues only (S); */ /* = 'V': for eigenvectors only (SEP); */ /* = 'B': for both eigenvalues and eigenvectors (S and SEP). */ /* HOWMNY (input) CHARACTER*1 */ /* = 'A': compute condition numbers for all eigenpairs; */ /* = 'S': compute condition numbers for selected eigenpairs */ /* specified by the array SELECT. */ /* SELECT (input) LOGICAL array, dimension (N) */ /* If HOWMNY = 'S', SELECT specifies the eigenpairs for which */ /* condition numbers are required. To select condition numbers */ /* for the j-th eigenpair, SELECT(j) must be set to .TRUE.. */ /* If HOWMNY = 'A', SELECT is not referenced. */ /* N (input) INTEGER */ /* The order of the matrix T. N >= 0. */ /* T (input) COMPLEX array, dimension (LDT,N) */ /* The upper triangular matrix T. */ /* LDT (input) INTEGER */ /* The leading dimension of the array T. LDT >= max(1,N). */ /* VL (input) COMPLEX array, dimension (LDVL,M) */ /* If JOB = 'E' or 'B', VL must contain left eigenvectors of T */ /* (or of any Q*T*Q**H with Q unitary), corresponding to the */ /* eigenpairs specified by HOWMNY and SELECT. The eigenvectors */ /* must be stored in consecutive columns of VL, as returned by */ /* CHSEIN or CTREVC. */ /* If JOB = 'V', VL is not referenced. */ /* LDVL (input) INTEGER */ /* The leading dimension of the array VL. */ /* LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N. */ /* VR (input) COMPLEX array, dimension (LDVR,M) */ /* If JOB = 'E' or 'B', VR must contain right eigenvectors of T */ /* (or of any Q*T*Q**H with Q unitary), corresponding to the */ /* eigenpairs specified by HOWMNY and SELECT. The eigenvectors */ /* must be stored in consecutive columns of VR, as returned by */ /* CHSEIN or CTREVC. */ /* If JOB = 'V', VR is not referenced. */ /* LDVR (input) INTEGER */ /* The leading dimension of the array VR. */ /* LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N. */ /* S (output) REAL array, dimension (MM) */ /* If JOB = 'E' or 'B', the reciprocal condition numbers of the */ /* selected eigenvalues, stored in consecutive elements of the */ /* array. Thus S(j), SEP(j), and the j-th columns of VL and VR */ /* all correspond to the same eigenpair (but not in general the */ /* j-th eigenpair, unless all eigenpairs are selected). */ /* If JOB = 'V', S is not referenced. */ /* SEP (output) REAL array, dimension (MM) */ /* If JOB = 'V' or 'B', the estimated reciprocal condition */ /* numbers of the selected eigenvectors, stored in consecutive */ /* elements of the array. */ /* If JOB = 'E', SEP is not referenced. */ /* MM (input) INTEGER */ /* The number of elements in the arrays S (if JOB = 'E' or 'B') */ /* and/or SEP (if JOB = 'V' or 'B'). MM >= M. */ /* M (output) INTEGER */ /* The number of elements of the arrays S and/or SEP actually */ /* used to store the estimated condition numbers. */ /* If HOWMNY = 'A', M is set to N. */ /* WORK (workspace) COMPLEX array, dimension (LDWORK,N+6) */ /* If JOB = 'E', WORK is not referenced. */ /* LDWORK (input) INTEGER */ /* The leading dimension of the array WORK. */ /* LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N. */ /* RWORK (workspace) REAL array, dimension (N) */ /* If JOB = 'E', RWORK is not referenced. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* Further Details */ /* =============== */ /* The reciprocal of the condition number of an eigenvalue lambda is */ /* defined as */ /* S(lambda) = |v'*u| / (norm(u)*norm(v)) */ /* where u and v are the right and left eigenvectors of T corresponding */ /* to lambda; v' denotes the conjugate transpose of v, and norm(u) */ /* denotes the Euclidean norm. These reciprocal condition numbers always */ /* lie between zero (very badly conditioned) and one (very well */ /* conditioned). If n = 1, S(lambda) is defined to be 1. */ /* An approximate error bound for a computed eigenvalue W(i) is given by */ /* EPS * norm(T) / S(i) */ /* where EPS is the machine precision. */ /* The reciprocal of the condition number of the right eigenvector u */ /* corresponding to lambda is defined as follows. Suppose */ /* T = ( lambda c ) */ /* ( 0 T22 ) */ /* Then the reciprocal condition number is */ /* SEP( lambda, T22 ) = sigma-min( T22 - lambda*I ) */ /* where sigma-min denotes the smallest singular value. We approximate */ /* the smallest singular value by the reciprocal of an estimate of the */ /* one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is */ /* defined to be abs(T(1,1)). */ /* An approximate error bound for a computed right eigenvector VR(i) */ /* is given by */ /* EPS * norm(T) / SEP(i) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Decode and test the input parameters */ /* Parameter adjustments */ --select; t_dim1 = *ldt; t_offset = 1 + t_dim1; t -= t_offset; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1; vr -= vr_offset; --s; --sep; work_dim1 = *ldwork; work_offset = 1 + work_dim1; work -= work_offset; --rwork; /* Function Body */ wantbh = lsame_(job, "B"); wants = lsame_(job, "E") || wantbh; wantsp = lsame_(job, "V") || wantbh; somcon = lsame_(howmny, "S"); /* Set M to the number of eigenpairs for which condition numbers are */ /* to be computed. */ if (somcon) { *m = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (select[j]) { ++(*m); } /* L10: */ } } else { *m = *n; } *info = 0; if (! wants && ! wantsp) { *info = -1; } else if (! lsame_(howmny, "A") && ! somcon) { *info = -2; } else if (*n < 0) { *info = -4; } else if (*ldt < max(1,*n)) { *info = -6; } else if (*ldvl < 1 || wants && *ldvl < *n) { *info = -8; } else if (*ldvr < 1 || wants && *ldvr < *n) { *info = -10; } else if (*mm < *m) { *info = -13; } else if (*ldwork < 1 || wantsp && *ldwork < *n) { *info = -16; } if (*info != 0) { i__1 = -(*info); xerbla_("CTRSNA", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (*n == 1) { if (somcon) { if (! select[1]) { return 0; } } if (wants) { s[1] = 1.f; } if (wantsp) { sep[1] = c_abs(&t[t_dim1 + 1]); } return 0; } /* Get machine constants */ eps = slamch_("P"); smlnum = slamch_("S") / eps; bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); ks = 1; i__1 = *n; for (k = 1; k <= i__1; ++k) { if (somcon) { if (! select[k]) { goto L50; } } if (wants) { /* Compute the reciprocal condition number of the k-th */ /* eigenvalue. */ cdotc_(&q__1, n, &vr[ks * vr_dim1 + 1], &c__1, &vl[ks * vl_dim1 + 1], &c__1); prod.r = q__1.r, prod.i = q__1.i; rnrm = scnrm2_(n, &vr[ks * vr_dim1 + 1], &c__1); lnrm = scnrm2_(n, &vl[ks * vl_dim1 + 1], &c__1); s[ks] = c_abs(&prod) / (rnrm * lnrm); } if (wantsp) { /* Estimate the reciprocal condition number of the k-th */ /* eigenvector. */ /* Copy the matrix T to the array WORK and swap the k-th */ /* diagonal element to the (1,1) position. */ clacpy_("Full", n, n, &t[t_offset], ldt, &work[work_offset], ldwork); ctrexc_("No Q", n, &work[work_offset], ldwork, dummy, &c__1, &k, & c__1, &ierr); /* Form C = T22 - lambda*I in WORK(2:N,2:N). */ i__2 = *n; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + i__ * work_dim1; i__4 = i__ + i__ * work_dim1; i__5 = work_dim1 + 1; q__1.r = work[i__4].r - work[i__5].r, q__1.i = work[i__4].i - work[i__5].i; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* L20: */ } /* Estimate a lower bound for the 1-norm of inv(C'). The 1st */ /* and (N+1)th columns of WORK are used to store work vectors. */ sep[ks] = 0.f; est = 0.f; kase = 0; *(unsigned char *)normin = 'N'; L30: i__2 = *n - 1; clacn2_(&i__2, &work[(*n + 1) * work_dim1 + 1], &work[work_offset] , &est, &kase, isave); if (kase != 0) { if (kase == 1) { /* Solve C'*x = scale*b */ i__2 = *n - 1; clatrs_("Upper", "Conjugate transpose", "Nonunit", normin, &i__2, &work[(work_dim1 << 1) + 2], ldwork, & work[work_offset], &scale, &rwork[1], &ierr); } else { /* Solve C*x = scale*b */ i__2 = *n - 1; clatrs_("Upper", "No transpose", "Nonunit", normin, &i__2, &work[(work_dim1 << 1) + 2], ldwork, &work[ work_offset], &scale, &rwork[1], &ierr); } *(unsigned char *)normin = 'Y'; if (scale != 1.f) { /* Multiply by 1/SCALE if doing so will not cause */ /* overflow. */ i__2 = *n - 1; ix = icamax_(&i__2, &work[work_offset], &c__1); i__2 = ix + work_dim1; xnorm = (r__1 = work[i__2].r, dabs(r__1)) + (r__2 = r_imag(&work[ix + work_dim1]), dabs(r__2)); if (scale < xnorm * smlnum || scale == 0.f) { goto L40; } csrscl_(n, &scale, &work[work_offset], &c__1); } goto L30; } sep[ks] = 1.f / dmax(est,smlnum); } L40: ++ks; L50: ; } return 0; /* End of CTRSNA */ } /* ctrsna_ */
/* Subroutine */ int cgbcon_(char *norm, integer *n, integer *kl, integer *ku, complex *ab, integer *ldab, integer *ipiv, real *anorm, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer ab_dim1, ab_offset, i__1, i__2, i__3; real r__1, r__2; complex q__1, q__2; /* Local variables */ integer j; complex t; integer kd, lm, jp, ix, kase, kase1; real scale; integer isave[3]; logical lnoti; real ainvnm; logical onenrm; char normin[1]; real smlnum; /* -- LAPACK routine (version 3.2) -- */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* Purpose */ /* ======= */ /* CGBCON estimates the reciprocal of the condition number of a complex */ /* general band matrix A, in either the 1-norm or the infinity-norm, */ /* using the LU factorization computed by CGBTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as */ /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */ /* Arguments */ /* ========= */ /* NORM (input) CHARACTER*1 */ /* Specifies whether the 1-norm condition number or the */ /* infinity-norm condition number is required: */ /* = '1' or 'O': 1-norm; */ /* = 'I': Infinity-norm. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* KL (input) INTEGER */ /* The number of subdiagonals within the band of A. KL >= 0. */ /* KU (input) INTEGER */ /* The number of superdiagonals within the band of A. KU >= 0. */ /* AB (input) COMPLEX array, dimension (LDAB,N) */ /* Details of the LU factorization of the band matrix A, as */ /* computed by CGBTRF. U is stored as an upper triangular band */ /* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and */ /* the multipliers used during the factorization are stored in */ /* rows KL+KU+2 to 2*KL+KU+1. */ /* LDAB (input) INTEGER */ /* The leading dimension of the array AB. LDAB >= 2*KL+KU+1. */ /* IPIV (input) INTEGER array, dimension (N) */ /* The pivot indices; for 1 <= i <= N, row i of the matrix was */ /* interchanged with row IPIV(i). */ /* ANORM (input) REAL */ /* If NORM = '1' or 'O', the 1-norm of the original matrix A. */ /* If NORM = 'I', the infinity-norm of the original matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; --ipiv; --work; --rwork; /* Function Body */ *info = 0; onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*kl < 0) { *info = -3; } else if (*ku < 0) { *info = -4; } else if (*ldab < (*kl << 1) + *ku + 1) { *info = -6; } else if (*anorm < 0.f) { *info = -8; } if (*info != 0) { i__1 = -(*info); xerbla_("CGBCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the norm of inv(A). */ ainvnm = 0.f; *(unsigned char *)normin = 'N'; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kd = *kl + *ku + 1; lnoti = *kl > 0; kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(L). */ if (lnoti) { i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__2 = *kl, i__3 = *n - j; lm = min(i__2,i__3); jp = ipiv[j]; i__2 = jp; t.r = work[i__2].r, t.i = work[i__2].i; if (jp != j) { i__2 = jp; i__3 = j; work[i__2].r = work[i__3].r, work[i__2].i = work[i__3] .i; i__2 = j; work[i__2].r = t.r, work[i__2].i = t.i; } q__1.r = -t.r, q__1.i = -t.i; caxpy_(&lm, &q__1, &ab[kd + 1 + j * ab_dim1], &c__1, & work[j + 1], &c__1); } } /* Multiply by inv(U). */ i__1 = *kl + *ku; clatbs_("Upper", "No transpose", "Non-unit", normin, n, &i__1, & ab[ab_offset], ldab, &work[1], &scale, &rwork[1], info); } else { /* Multiply by inv(U'). */ i__1 = *kl + *ku; clatbs_("Upper", "Conjugate transpose", "Non-unit", normin, n, & i__1, &ab[ab_offset], ldab, &work[1], &scale, &rwork[1], info); /* Multiply by inv(L'). */ if (lnoti) { for (j = *n - 1; j >= 1; --j) { /* Computing MIN */ i__1 = *kl, i__2 = *n - j; lm = min(i__1,i__2); i__1 = j; i__2 = j; cdotc_(&q__2, &lm, &ab[kd + 1 + j * ab_dim1], &c__1, & work[j + 1], &c__1); q__1.r = work[i__2].r - q__2.r, q__1.i = work[i__2].i - q__2.i; work[i__1].r = q__1.r, work[i__1].i = q__1.i; jp = ipiv[j]; if (jp != j) { i__1 = jp; t.r = work[i__1].r, t.i = work[i__1].i; i__1 = jp; i__2 = j; work[i__1].r = work[i__2].r, work[i__1].i = work[i__2] .i; i__1 = j; work[i__1].r = t.r, work[i__1].i = t.i; } } } } /* Divide X by 1/SCALE if doing so will not cause overflow. */ *(unsigned char *)normin = 'Y'; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, dabs(r__1)) + (r__2 = r_imag(& work[ix]), dabs(r__2))) * smlnum || scale == 0.f) { goto L40; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L40: return 0; /* End of CGBCON */ } /* cgbcon_ */
/* Subroutine */ int cgbrfs_(char *trans, integer *n, integer *kl, integer * ku, integer *nrhs, complex *ab, integer *ldab, complex *afb, integer * ldafb, integer *ipiv, complex *b, integer *ldb, complex *x, integer * ldx, real *ferr, real *berr, complex *work, real *rwork, integer * info) { /* System generated locals */ integer ab_dim1, ab_offset, afb_dim1, afb_offset, b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1, r__2, r__3, r__4; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j, k; real s; integer kk; real xk; integer nz; real eps; integer kase; real safe1, safe2; extern /* Subroutine */ int cgbmv_(char *, integer *, integer *, integer * , integer *, complex *, complex *, integer *, complex *, integer * , complex *, complex *, integer *); extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, complex *, integer *), caxpy_(integer *, complex *, complex *, integer *, complex *, integer *); integer count; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern doublereal slamch_(char *); real safmin; extern /* Subroutine */ int xerbla_(char *, integer *), cgbtrs_( char *, integer *, integer *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); logical notran; char transn[1], transt[1]; real lstres; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGBRFS improves the computed solution to a system of linear */ /* equations when the coefficient matrix is banded, and provides */ /* error bounds and backward error estimates for the solution. */ /* Arguments */ /* ========= */ /* TRANS (input) CHARACTER*1 */ /* Specifies the form of the system of equations: */ /* = 'N': A * X = B (No transpose) */ /* = 'T': A**T * X = B (Transpose) */ /* = 'C': A**H * X = B (Conjugate transpose) */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* KL (input) INTEGER */ /* The number of subdiagonals within the band of A. KL >= 0. */ /* KU (input) INTEGER */ /* The number of superdiagonals within the band of A. KU >= 0. */ /* NRHS (input) INTEGER */ /* The number of right hand sides, i.e., the number of columns */ /* of the matrices B and X. NRHS >= 0. */ /* AB (input) COMPLEX array, dimension (LDAB,N) */ /* The original band matrix A, stored in rows 1 to KL+KU+1. */ /* The j-th column of A is stored in the j-th column of the */ /* array AB as follows: */ /* AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(n,j+kl). */ /* LDAB (input) INTEGER */ /* The leading dimension of the array AB. LDAB >= KL+KU+1. */ /* AFB (input) COMPLEX array, dimension (LDAFB,N) */ /* Details of the LU factorization of the band matrix A, as */ /* computed by CGBTRF. U is stored as an upper triangular band */ /* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and */ /* the multipliers used during the factorization are stored in */ /* rows KL+KU+2 to 2*KL+KU+1. */ /* LDAFB (input) INTEGER */ /* The leading dimension of the array AFB. LDAFB >= 2*KL*KU+1. */ /* IPIV (input) INTEGER array, dimension (N) */ /* The pivot indices from CGBTRF; for 1<=i<=N, row i of the */ /* matrix was interchanged with row IPIV(i). */ /* B (input) COMPLEX array, dimension (LDB,NRHS) */ /* The right hand side matrix B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* X (input/output) COMPLEX array, dimension (LDX,NRHS) */ /* On entry, the solution matrix X, as computed by CGBTRS. */ /* On exit, the improved solution matrix X. */ /* LDX (input) INTEGER */ /* The leading dimension of the array X. LDX >= max(1,N). */ /* FERR (output) REAL array, dimension (NRHS) */ /* The estimated forward error bound for each solution vector */ /* X(j) (the j-th column of the solution matrix X). */ /* If XTRUE is the true solution corresponding to X(j), FERR(j) */ /* is an estimated upper bound for the magnitude of the largest */ /* element in (X(j) - XTRUE) divided by the magnitude of the */ /* largest element in X(j). The estimate is as reliable as */ /* the estimate for RCOND, and is almost always a slight */ /* overestimate of the true error. */ /* BERR (output) REAL array, dimension (NRHS) */ /* The componentwise relative backward error of each solution */ /* vector X(j) (i.e., the smallest relative change in */ /* any element of A or B that makes X(j) an exact solution). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* Internal Parameters */ /* =================== */ /* ITMAX is the maximum number of steps of iterative refinement. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; afb_dim1 = *ldafb; afb_offset = 1 + afb_dim1; afb -= afb_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --ferr; --berr; --work; --rwork; /* Function Body */ *info = 0; notran = lsame_(trans, "N"); if (! notran && ! lsame_(trans, "T") && ! lsame_( trans, "C")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*kl < 0) { *info = -3; } else if (*ku < 0) { *info = -4; } else if (*nrhs < 0) { *info = -5; } else if (*ldab < *kl + *ku + 1) { *info = -7; } else if (*ldafb < (*kl << 1) + *ku + 1) { *info = -9; } else if (*ldb < max(1,*n)) { *info = -12; } else if (*ldx < max(1,*n)) { *info = -14; } if (*info != 0) { i__1 = -(*info); xerbla_("CGBRFS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ferr[j] = 0.f; berr[j] = 0.f; /* L10: */ } return 0; } if (notran) { *(unsigned char *)transn = 'N'; *(unsigned char *)transt = 'C'; } else { *(unsigned char *)transn = 'C'; *(unsigned char *)transt = 'N'; } /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ /* Computing MIN */ i__1 = *kl + *ku + 2, i__2 = *n + 1; nz = min(i__1,i__2); eps = slamch_("Epsilon"); safmin = slamch_("Safe minimum"); safe1 = nz * safmin; safe2 = safe1 / eps; /* Do for each right hand side */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { count = 1; lstres = 3.f; L20: /* Loop until stopping criterion is satisfied. */ /* Compute residual R = B - op(A) * X, */ /* where op(A) = A, A**T, or A**H, depending on TRANS. */ ccopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1); q__1.r = -1.f, q__1.i = -0.f; cgbmv_(trans, n, n, kl, ku, &q__1, &ab[ab_offset], ldab, &x[j * x_dim1 + 1], &c__1, &c_b1, &work[1], &c__1); /* Compute componentwise relative backward error from formula */ /* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) */ /* where abs(Z) is the componentwise absolute value of the matrix */ /* or vector Z. If the i-th component of the denominator is less */ /* than SAFE2, then SAFE1 is added to the i-th components of the */ /* numerator and denominator before dividing. */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; rwork[i__] = (r__1 = b[i__3].r, dabs(r__1)) + (r__2 = r_imag(&b[ i__ + j * b_dim1]), dabs(r__2)); /* L30: */ } /* Compute abs(op(A))*abs(X) + abs(B). */ if (notran) { i__2 = *n; for (k = 1; k <= i__2; ++k) { kk = *ku + 1 - k; i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[k + j * x_dim1]), dabs(r__2)); /* Computing MAX */ i__3 = 1, i__4 = k - *ku; /* Computing MIN */ i__6 = *n, i__7 = k + *kl; i__5 = min(i__6,i__7); for (i__ = max(i__3,i__4); i__ <= i__5; ++i__) { i__3 = kk + i__ + k * ab_dim1; rwork[i__] += ((r__1 = ab[i__3].r, dabs(r__1)) + (r__2 = r_imag(&ab[kk + i__ + k * ab_dim1]), dabs(r__2))) * xk; /* L40: */ } /* L50: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; kk = *ku + 1 - k; /* Computing MAX */ i__5 = 1, i__3 = k - *ku; /* Computing MIN */ i__6 = *n, i__7 = k + *kl; i__4 = min(i__6,i__7); for (i__ = max(i__5,i__3); i__ <= i__4; ++i__) { i__5 = kk + i__ + k * ab_dim1; i__3 = i__ + j * x_dim1; s += ((r__1 = ab[i__5].r, dabs(r__1)) + (r__2 = r_imag(& ab[kk + i__ + k * ab_dim1]), dabs(r__2))) * (( r__3 = x[i__3].r, dabs(r__3)) + (r__4 = r_imag(&x[ i__ + j * x_dim1]), dabs(r__4))); /* L60: */ } rwork[k] += s; /* L70: */ } } s = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__4 = i__; r__3 = s, r__4 = ((r__1 = work[i__4].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2))) / rwork[i__]; s = dmax(r__3,r__4); } else { /* Computing MAX */ i__4 = i__; r__3 = s, r__4 = ((r__1 = work[i__4].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + safe1) / (rwork[i__] + safe1); s = dmax(r__3,r__4); } /* L80: */ } berr[j] = s; /* Test stopping criterion. Continue iterating if */ /* 1) The residual BERR(J) is larger than machine epsilon, and */ /* 2) BERR(J) decreased by at least a factor of 2 during the */ /* last iteration, and */ /* 3) At most ITMAX iterations tried. */ if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) { /* Update solution and try again. */ cgbtrs_(trans, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &ipiv[1] , &work[1], n, info); caxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1); lstres = berr[j]; ++count; goto L20; } /* Bound error from formula */ /* norm(X - XTRUE) / norm(X) .le. FERR = */ /* norm( abs(inv(op(A)))* */ /* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) */ /* where */ /* norm(Z) is the magnitude of the largest component of Z */ /* inv(op(A)) is the inverse of op(A) */ /* abs(Z) is the componentwise absolute value of the matrix or */ /* vector Z */ /* NZ is the maximum number of nonzeros in any row of A, plus 1 */ /* EPS is machine epsilon */ /* The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) */ /* is incremented by SAFE1 if the i-th component of */ /* abs(op(A))*abs(X) + abs(B) is less than SAFE2. */ /* Use CLACN2 to estimate the infinity-norm of the matrix */ /* inv(op(A)) * diag(W), */ /* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { i__4 = i__; rwork[i__] = (r__1 = work[i__4].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__]; } else { i__4 = i__; rwork[i__] = (r__1 = work[i__4].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__] + safe1; } /* L90: */ } kase = 0; L100: clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(op(A)**H). */ cgbtrs_(transt, n, kl, ku, &c__1, &afb[afb_offset], ldafb, & ipiv[1], &work[1], n, info); i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__4 = i__; i__5 = i__; i__3 = i__; q__1.r = rwork[i__5] * work[i__3].r, q__1.i = rwork[i__5] * work[i__3].i; work[i__4].r = q__1.r, work[i__4].i = q__1.i; /* L110: */ } } else { /* Multiply by inv(op(A))*diag(W). */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__4 = i__; i__5 = i__; i__3 = i__; q__1.r = rwork[i__5] * work[i__3].r, q__1.i = rwork[i__5] * work[i__3].i; work[i__4].r = q__1.r, work[i__4].i = q__1.i; /* L120: */ } cgbtrs_(transn, n, kl, ku, &c__1, &afb[afb_offset], ldafb, & ipiv[1], &work[1], n, info); } goto L100; } /* Normalize error. */ lstres = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__4 = i__ + j * x_dim1; r__3 = lstres, r__4 = (r__1 = x[i__4].r, dabs(r__1)) + (r__2 = r_imag(&x[i__ + j * x_dim1]), dabs(r__2)); lstres = dmax(r__3,r__4); /* L130: */ } if (lstres != 0.f) { ferr[j] /= lstres; } /* L140: */ } return 0; /* End of CGBRFS */ } /* cgbrfs_ */
/* Subroutine */ int cgtcon_(char *norm, integer *n, complex *dl, complex * d__, complex *du, complex *du2, integer *ipiv, real *anorm, real * rcond, complex *work, integer *info) { /* System generated locals */ integer i__1, i__2; /* Local variables */ integer i__, kase, kase1; extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *); real ainvnm; logical onenrm; extern /* Subroutine */ int cgttrs_(char *, integer *, integer *, complex *, complex *, complex *, complex *, integer *, complex *, integer *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGTCON estimates the reciprocal of the condition number of a complex */ /* tridiagonal matrix A using the LU factorization as computed by */ /* CGTTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* NORM (input) CHARACTER*1 */ /* Specifies whether the 1-norm condition number or the */ /* infinity-norm condition number is required: */ /* = '1' or 'O': 1-norm; */ /* = 'I': Infinity-norm. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* DL (input) COMPLEX array, dimension (N-1) */ /* The (n-1) multipliers that define the matrix L from the */ /* LU factorization of A as computed by CGTTRF. */ /* D (input) COMPLEX array, dimension (N) */ /* The n diagonal elements of the upper triangular matrix U from */ /* the LU factorization of A. */ /* DU (input) COMPLEX array, dimension (N-1) */ /* The (n-1) elements of the first superdiagonal of U. */ /* DU2 (input) COMPLEX array, dimension (N-2) */ /* The (n-2) elements of the second superdiagonal of U. */ /* IPIV (input) INTEGER array, dimension (N) */ /* The pivot indices; for 1 <= i <= n, row i of the matrix was */ /* interchanged with row IPIV(i). IPIV(i) will always be either */ /* i or i+1; IPIV(i) = i indicates a row interchange was not */ /* required. */ /* ANORM (input) REAL */ /* If NORM = '1' or 'O', the 1-norm of the original matrix A. */ /* If NORM = 'I', the infinity-norm of the original matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input arguments. */ /* Parameter adjustments */ --work; --ipiv; --du2; --du; --d__; --dl; /* Function Body */ *info = 0; onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*anorm < 0.f) { *info = -8; } if (*info != 0) { i__1 = -(*info); xerbla_("CGTCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } /* Check that D(1:N) is non-zero. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; if (d__[i__2].r == 0.f && d__[i__2].i == 0.f) { return 0; } /* L10: */ } ainvnm = 0.f; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kase = 0; L20: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(U)*inv(L). */ cgttrs_("No transpose", n, &c__1, &dl[1], &d__[1], &du[1], &du2[1] , &ipiv[1], &work[1], n, info); } else { /* Multiply by inv(L')*inv(U'). */ cgttrs_("Conjugate transpose", n, &c__1, &dl[1], &d__[1], &du[1], &du2[1], &ipiv[1], &work[1], n, info); } goto L20; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } return 0; /* End of CGTCON */ } /* cgtcon_ */
/* Subroutine */ int cppcon_(char *uplo, integer *n, complex *ap, real *anorm, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer i__1; real r__1, r__2; /* Local variables */ integer ix, kase; real scale; integer isave[3]; logical upper; real scalel; real scaleu; real ainvnm; char normin[1]; real smlnum; /* -- LAPACK routine (version 3.2) -- */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* Purpose */ /* ======= */ /* CPPCON estimates the reciprocal of the condition number (in the */ /* 1-norm) of a complex Hermitian positive definite packed matrix using */ /* the Cholesky factorization A = U**H*U or A = L*L**H computed by */ /* CPPTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* AP (input) COMPLEX array, dimension (N*(N+1)/2) */ /* The triangular factor U or L from the Cholesky factorization */ /* A = U**H*U or A = L*L**H, packed columnwise in a linear */ /* array. The j-th column of U or L is stored in the array AP */ /* as follows: */ /* if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j; */ /* if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n. */ /* ANORM (input) REAL */ /* The 1-norm (or infinity-norm) of the Hermitian matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ --rwork; --work; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*anorm < 0.f) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CPPCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the 1-norm of the inverse. */ kase = 0; *(unsigned char *)normin = 'N'; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (upper) { /* Multiply by inv(U'). */ clatps_("Upper", "Conjugate transpose", "Non-unit", normin, n, & ap[1], &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(U). */ clatps_("Upper", "No transpose", "Non-unit", normin, n, &ap[1], & work[1], &scaleu, &rwork[1], info); } else { /* Multiply by inv(L). */ clatps_("Lower", "No transpose", "Non-unit", normin, n, &ap[1], & work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(L'). */ clatps_("Lower", "Conjugate transpose", "Non-unit", normin, n, & ap[1], &work[1], &scaleu, &rwork[1], info); } /* Multiply by 1/SCALE if doing so will not cause overflow. */ scale = scalel * scaleu; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, dabs(r__1)) + (r__2 = r_imag(& work[ix]), dabs(r__2))) * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L20: return 0; /* End of CPPCON */ } /* cppcon_ */
/* Subroutine */ int ctprfs_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, complex *ap, complex *b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork, integer *info) { /* System generated locals */ integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j, k; real s; integer kc; real xk; integer nz; real eps; integer kase; real safe1, safe2; extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, complex *, integer *), caxpy_(integer *, complex *, complex *, integer *, complex *, integer *), ctpmv_(char *, char *, char *, integer *, complex *, complex *, integer *); logical upper; extern /* Subroutine */ int ctpsv_(char *, char *, char *, integer *, complex *, complex *, integer *), clacn2_( integer *, complex *, complex *, real *, integer *, integer *); extern doublereal slamch_(char *); real safmin; extern /* Subroutine */ int xerbla_(char *, integer *); logical notran; char transn[1], transt[1]; logical nounit; real lstres; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTPRFS provides error bounds and backward error estimates for the */ /* solution to a system of linear equations with a triangular packed */ /* coefficient matrix. */ /* The solution matrix X must be computed by CTPTRS or some other */ /* means before entering this routine. CTPRFS does not do iterative */ /* refinement because doing so cannot improve the backward error. */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': A is upper triangular; */ /* = 'L': A is lower triangular. */ /* TRANS (input) CHARACTER*1 */ /* Specifies the form of the system of equations: */ /* = 'N': A * X = B (No transpose) */ /* = 'T': A**T * X = B (Transpose) */ /* = 'C': A**H * X = B (Conjugate transpose) */ /* DIAG (input) CHARACTER*1 */ /* = 'N': A is non-unit triangular; */ /* = 'U': A is unit triangular. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* NRHS (input) INTEGER */ /* The number of right hand sides, i.e., the number of columns */ /* of the matrices B and X. NRHS >= 0. */ /* AP (input) COMPLEX array, dimension (N*(N+1)/2) */ /* The upper or lower triangular matrix A, packed columnwise in */ /* a linear array. The j-th column of A is stored in the array */ /* AP as follows: */ /* if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; */ /* if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n. */ /* If DIAG = 'U', the diagonal elements of A are not referenced */ /* and are assumed to be 1. */ /* B (input) COMPLEX array, dimension (LDB,NRHS) */ /* The right hand side matrix B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* X (input) COMPLEX array, dimension (LDX,NRHS) */ /* The solution matrix X. */ /* LDX (input) INTEGER */ /* The leading dimension of the array X. LDX >= max(1,N). */ /* FERR (output) REAL array, dimension (NRHS) */ /* The estimated forward error bound for each solution vector */ /* X(j) (the j-th column of the solution matrix X). */ /* If XTRUE is the true solution corresponding to X(j), FERR(j) */ /* is an estimated upper bound for the magnitude of the largest */ /* element in (X(j) - XTRUE) divided by the magnitude of the */ /* largest element in X(j). The estimate is as reliable as */ /* the estimate for RCOND, and is almost always a slight */ /* overestimate of the true error. */ /* BERR (output) REAL array, dimension (NRHS) */ /* The componentwise relative backward error of each solution */ /* vector X(j) (i.e., the smallest relative change in */ /* any element of A or B that makes X(j) an exact solution). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --ferr; --berr; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); notran = lsame_(trans, "N"); nounit = lsame_(diag, "N"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (! notran && ! lsame_(trans, "T") && ! lsame_(trans, "C")) { *info = -2; } else if (! nounit && ! lsame_(diag, "U")) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*nrhs < 0) { *info = -5; } else if (*ldb < max(1,*n)) { *info = -8; } else if (*ldx < max(1,*n)) { *info = -10; } if (*info != 0) { i__1 = -(*info); xerbla_("CTPRFS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ferr[j] = 0.f; berr[j] = 0.f; /* L10: */ } return 0; } if (notran) { *(unsigned char *)transn = 'N'; *(unsigned char *)transt = 'C'; } else { *(unsigned char *)transn = 'C'; *(unsigned char *)transt = 'N'; } /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ nz = *n + 1; eps = slamch_("Epsilon"); safmin = slamch_("Safe minimum"); safe1 = nz * safmin; safe2 = safe1 / eps; /* Do for each right hand side */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { /* Compute residual R = B - op(A) * X, */ /* where op(A) = A, A**T, or A**H, depending on TRANS. */ ccopy_(n, &x[j * x_dim1 + 1], &c__1, &work[1], &c__1); ctpmv_(uplo, trans, diag, n, &ap[1], &work[1], &c__1); q__1.r = -1.f, q__1.i = -0.f; caxpy_(n, &q__1, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1); /* Compute componentwise relative backward error from formula */ /* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) */ /* where abs(Z) is the componentwise absolute value of the matrix */ /* or vector Z. If the i-th component of the denominator is less */ /* than SAFE2, then SAFE1 is added to the i-th components of the */ /* numerator and denominator before dividing. */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; rwork[i__] = (r__1 = b[i__3].r, dabs(r__1)) + (r__2 = r_imag(&b[ i__ + j * b_dim1]), dabs(r__2)); /* L20: */ } if (notran) { /* Compute abs(A)*abs(X) + abs(B). */ if (upper) { kc = 1; if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; rwork[i__] += ((r__1 = ap[i__4].r, dabs(r__1)) + ( r__2 = r_imag(&ap[kc + i__ - 1]), dabs( r__2))) * xk; /* L30: */ } kc += k; /* L40: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; rwork[i__] += ((r__1 = ap[i__4].r, dabs(r__1)) + ( r__2 = r_imag(&ap[kc + i__ - 1]), dabs( r__2))) * xk; /* L50: */ } rwork[k] += xk; kc += k; /* L60: */ } } } else { kc = 1; if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; rwork[i__] += ((r__1 = ap[i__4].r, dabs(r__1)) + ( r__2 = r_imag(&ap[kc + i__ - k]), dabs( r__2))) * xk; /* L70: */ } kc = kc + *n - k + 1; /* L80: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; rwork[i__] += ((r__1 = ap[i__4].r, dabs(r__1)) + ( r__2 = r_imag(&ap[kc + i__ - k]), dabs( r__2))) * xk; /* L90: */ } rwork[k] += xk; kc = kc + *n - k + 1; /* L100: */ } } } } else { /* Compute abs(A**H)*abs(X) + abs(B). */ if (upper) { kc = 1; if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; i__5 = i__ + j * x_dim1; s += ((r__1 = ap[i__4].r, dabs(r__1)) + (r__2 = r_imag(&ap[kc + i__ - 1]), dabs(r__2))) * ((r__3 = x[i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))) ; /* L110: */ } rwork[k] += s; kc += k; /* L120: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; s = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; i__5 = i__ + j * x_dim1; s += ((r__1 = ap[i__4].r, dabs(r__1)) + (r__2 = r_imag(&ap[kc + i__ - 1]), dabs(r__2))) * ((r__3 = x[i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))) ; /* L130: */ } rwork[k] += s; kc += k; /* L140: */ } } } else { kc = 1; if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; i__5 = i__ + j * x_dim1; s += ((r__1 = ap[i__4].r, dabs(r__1)) + (r__2 = r_imag(&ap[kc + i__ - k]), dabs(r__2))) * ((r__3 = x[i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))) ; /* L150: */ } rwork[k] += s; kc = kc + *n - k + 1; /* L160: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; s = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), dabs(r__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; i__5 = i__ + j * x_dim1; s += ((r__1 = ap[i__4].r, dabs(r__1)) + (r__2 = r_imag(&ap[kc + i__ - k]), dabs(r__2))) * ((r__3 = x[i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))) ; /* L170: */ } rwork[k] += s; kc = kc + *n - k + 1; /* L180: */ } } } } s = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__3 = i__; r__3 = s, r__4 = ((r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2))) / rwork[i__]; s = dmax(r__3,r__4); } else { /* Computing MAX */ i__3 = i__; r__3 = s, r__4 = ((r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + safe1) / (rwork[i__] + safe1); s = dmax(r__3,r__4); } /* L190: */ } berr[j] = s; /* Bound error from formula */ /* norm(X - XTRUE) / norm(X) .le. FERR = */ /* norm( abs(inv(op(A)))* */ /* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) */ /* where */ /* norm(Z) is the magnitude of the largest component of Z */ /* inv(op(A)) is the inverse of op(A) */ /* abs(Z) is the componentwise absolute value of the matrix or */ /* vector Z */ /* NZ is the maximum number of nonzeros in any row of A, plus 1 */ /* EPS is machine epsilon */ /* The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) */ /* is incremented by SAFE1 if the i-th component of */ /* abs(op(A))*abs(X) + abs(B) is less than SAFE2. */ /* Use CLACN2 to estimate the infinity-norm of the matrix */ /* inv(op(A)) * diag(W), */ /* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__]; } else { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__] + safe1; } /* L200: */ } kase = 0; L210: clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(op(A)**H). */ ctpsv_(uplo, transt, diag, n, &ap[1], &work[1], &c__1); i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r, q__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* L220: */ } } else { /* Multiply by inv(op(A))*diag(W). */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r, q__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* L230: */ } ctpsv_(uplo, transn, diag, n, &ap[1], &work[1], &c__1); } goto L210; } /* Normalize error. */ lstres = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__3 = i__ + j * x_dim1; r__3 = lstres, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[i__ + j * x_dim1]), dabs(r__2)); lstres = dmax(r__3,r__4); /* L240: */ } if (lstres != 0.f) { ferr[j] /= lstres; } /* L250: */ } return 0; /* End of CTPRFS */ } /* ctprfs_ */
/* Subroutine */ int ctgsen_(integer *ijob, logical *wantq, logical *wantz, logical *select, integer *n, complex *a, integer *lda, complex *b, integer *ldb, complex *alpha, complex *beta, complex *q, integer *ldq, complex *z__, integer *ldz, integer *m, real *pl, real *pr, real * dif, complex *work, integer *lwork, integer *iwork, integer *liwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, z_dim1, z_offset, i__1, i__2, i__3; complex q__1, q__2; /* Builtin functions */ double sqrt(doublereal), c_abs(complex *); void r_cnjg(complex *, complex *); /* Local variables */ integer i__, k, n1, n2, ks, mn2, ijb, kase, ierr; real dsum; logical swap; complex temp1, temp2; extern /* Subroutine */ int cscal_(integer *, complex *, complex *, integer *); integer isave[3]; logical wantd; integer lwmin; logical wantp; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); logical wantd1, wantd2; real dscale; extern doublereal slamch_(char *); real rdscal; extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *); real safmin; extern /* Subroutine */ int ctgexc_(logical *, logical *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, integer *, integer *, integer *), xerbla_( char *, integer *), classq_(integer *, complex *, integer *, real *, real *); integer liwmin; extern /* Subroutine */ int ctgsyl_(char *, integer *, integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, real *, real *, complex *, integer *, integer *, integer *); logical lquery; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* January 2007 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTGSEN reorders the generalized Schur decomposition of a complex */ /* matrix pair (A, B) (in terms of an unitary equivalence trans- */ /* formation Q' * (A, B) * Z), so that a selected cluster of eigenvalues */ /* appears in the leading diagonal blocks of the pair (A,B). The leading */ /* columns of Q and Z form unitary bases of the corresponding left and */ /* right eigenspaces (deflating subspaces). (A, B) must be in */ /* generalized Schur canonical form, that is, A and B are both upper */ /* triangular. */ /* CTGSEN also computes the generalized eigenvalues */ /* w(j)= ALPHA(j) / BETA(j) */ /* of the reordered matrix pair (A, B). */ /* Optionally, the routine computes estimates of reciprocal condition */ /* numbers for eigenvalues and eigenspaces. These are Difu[(A11,B11), */ /* (A22,B22)] and Difl[(A11,B11), (A22,B22)], i.e. the separation(s) */ /* between the matrix pairs (A11, B11) and (A22,B22) that correspond to */ /* the selected cluster and the eigenvalues outside the cluster, resp., */ /* and norms of "projections" onto left and right eigenspaces w.r.t. */ /* the selected cluster in the (1,1)-block. */ /* Arguments */ /* ========= */ /* IJOB (input) integer */ /* Specifies whether condition numbers are required for the */ /* cluster of eigenvalues (PL and PR) or the deflating subspaces */ /* (Difu and Difl): */ /* =0: Only reorder w.r.t. SELECT. No extras. */ /* =1: Reciprocal of norms of "projections" onto left and right */ /* eigenspaces w.r.t. the selected cluster (PL and PR). */ /* =2: Upper bounds on Difu and Difl. F-norm-based estimate */ /* (DIF(1:2)). */ /* =3: Estimate of Difu and Difl. 1-norm-based estimate */ /* (DIF(1:2)). */ /* About 5 times as expensive as IJOB = 2. */ /* =4: Compute PL, PR and DIF (i.e. 0, 1 and 2 above): Economic */ /* version to get it all. */ /* =5: Compute PL, PR and DIF (i.e. 0, 1 and 3 above) */ /* WANTQ (input) LOGICAL */ /* .TRUE. : update the left transformation matrix Q; */ /* .FALSE.: do not update Q. */ /* WANTZ (input) LOGICAL */ /* .TRUE. : update the right transformation matrix Z; */ /* .FALSE.: do not update Z. */ /* SELECT (input) LOGICAL array, dimension (N) */ /* SELECT specifies the eigenvalues in the selected cluster. To */ /* select an eigenvalue w(j), SELECT(j) must be set to */ /* .TRUE.. */ /* N (input) INTEGER */ /* The order of the matrices A and B. N >= 0. */ /* A (input/output) COMPLEX array, dimension(LDA,N) */ /* On entry, the upper triangular matrix A, in generalized */ /* Schur canonical form. */ /* On exit, A is overwritten by the reordered matrix A. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* B (input/output) COMPLEX array, dimension(LDB,N) */ /* On entry, the upper triangular matrix B, in generalized */ /* Schur canonical form. */ /* On exit, B is overwritten by the reordered matrix B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* ALPHA (output) COMPLEX array, dimension (N) */ /* BETA (output) COMPLEX array, dimension (N) */ /* The diagonal elements of A and B, respectively, */ /* when the pair (A,B) has been reduced to generalized Schur */ /* form. ALPHA(i)/BETA(i) i=1,...,N are the generalized */ /* eigenvalues. */ /* Q (input/output) COMPLEX array, dimension (LDQ,N) */ /* On entry, if WANTQ = .TRUE., Q is an N-by-N matrix. */ /* On exit, Q has been postmultiplied by the left unitary */ /* transformation matrix which reorder (A, B); The leading M */ /* columns of Q form orthonormal bases for the specified pair of */ /* left eigenspaces (deflating subspaces). */ /* If WANTQ = .FALSE., Q is not referenced. */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. LDQ >= 1. */ /* If WANTQ = .TRUE., LDQ >= N. */ /* Z (input/output) COMPLEX array, dimension (LDZ,N) */ /* On entry, if WANTZ = .TRUE., Z is an N-by-N matrix. */ /* On exit, Z has been postmultiplied by the left unitary */ /* transformation matrix which reorder (A, B); The leading M */ /* columns of Z form orthonormal bases for the specified pair of */ /* left eigenspaces (deflating subspaces). */ /* If WANTZ = .FALSE., Z is not referenced. */ /* LDZ (input) INTEGER */ /* The leading dimension of the array Z. LDZ >= 1. */ /* If WANTZ = .TRUE., LDZ >= N. */ /* M (output) INTEGER */ /* The dimension of the specified pair of left and right */ /* eigenspaces, (deflating subspaces) 0 <= M <= N. */ /* PL (output) REAL */ /* PR (output) REAL */ /* If IJOB = 1, 4 or 5, PL, PR are lower bounds on the */ /* reciprocal of the norm of "projections" onto left and right */ /* eigenspace with respect to the selected cluster. */ /* 0 < PL, PR <= 1. */ /* If M = 0 or M = N, PL = PR = 1. */ /* If IJOB = 0, 2 or 3 PL, PR are not referenced. */ /* DIF (output) REAL array, dimension (2). */ /* If IJOB >= 2, DIF(1:2) store the estimates of Difu and Difl. */ /* If IJOB = 2 or 4, DIF(1:2) are F-norm-based upper bounds on */ /* Difu and Difl. If IJOB = 3 or 5, DIF(1:2) are 1-norm-based */ /* estimates of Difu and Difl, computed using reversed */ /* communication with CLACN2. */ /* If M = 0 or N, DIF(1:2) = F-norm([A, B]). */ /* If IJOB = 0 or 1, DIF is not referenced. */ /* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */ /* IF IJOB = 0, WORK is not referenced. Otherwise, */ /* on exit, if INFO = 0, WORK(1) returns the optimal LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. LWORK >= 1 */ /* If IJOB = 1, 2 or 4, LWORK >= 2*M*(N-M) */ /* If IJOB = 3 or 5, LWORK >= 4*M*(N-M) */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the optimal size of the WORK array, returns */ /* this value as the first entry of the WORK array, and no error */ /* message related to LWORK is issued by XERBLA. */ /* IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK)) */ /* IF IJOB = 0, IWORK is not referenced. Otherwise, */ /* on exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. */ /* LIWORK (input) INTEGER */ /* The dimension of the array IWORK. LIWORK >= 1. */ /* If IJOB = 1, 2 or 4, LIWORK >= N+2; */ /* If IJOB = 3 or 5, LIWORK >= MAX(N+2, 2*M*(N-M)); */ /* If LIWORK = -1, then a workspace query is assumed; the */ /* routine only calculates the optimal size of the IWORK array, */ /* returns this value as the first entry of the IWORK array, and */ /* no error message related to LIWORK is issued by XERBLA. */ /* INFO (output) INTEGER */ /* =0: Successful exit. */ /* <0: If INFO = -i, the i-th argument had an illegal value. */ /* =1: Reordering of (A, B) failed because the transformed */ /* matrix pair (A, B) would be too far from generalized */ /* Schur form; the problem is very ill-conditioned. */ /* (A, B) may have been partially reordered. */ /* If requested, 0 is returned in DIF(*), PL and PR. */ /* Further Details */ /* =============== */ /* CTGSEN first collects the selected eigenvalues by computing unitary */ /* U and W that move them to the top left corner of (A, B). In other */ /* words, the selected eigenvalues are the eigenvalues of (A11, B11) in */ /* U'*(A, B)*W = (A11 A12) (B11 B12) n1 */ /* ( 0 A22),( 0 B22) n2 */ /* n1 n2 n1 n2 */ /* where N = n1+n2 and U' means the conjugate transpose of U. The first */ /* n1 columns of U and W span the specified pair of left and right */ /* eigenspaces (deflating subspaces) of (A, B). */ /* If (A, B) has been obtained from the generalized real Schur */ /* decomposition of a matrix pair (C, D) = Q*(A, B)*Z', then the */ /* reordered generalized Schur form of (C, D) is given by */ /* (C, D) = (Q*U)*(U'*(A, B)*W)*(Z*W)', */ /* and the first n1 columns of Q*U and Z*W span the corresponding */ /* deflating subspaces of (C, D) (Q and Z store Q*U and Z*W, resp.). */ /* Note that if the selected eigenvalue is sufficiently ill-conditioned, */ /* then its value may differ significantly from its value before */ /* reordering. */ /* The reciprocal condition numbers of the left and right eigenspaces */ /* spanned by the first n1 columns of U and W (or Q*U and Z*W) may */ /* be returned in DIF(1:2), corresponding to Difu and Difl, resp. */ /* The Difu and Difl are defined as: */ /* Difu[(A11, B11), (A22, B22)] = sigma-min( Zu ) */ /* and */ /* Difl[(A11, B11), (A22, B22)] = Difu[(A22, B22), (A11, B11)], */ /* where sigma-min(Zu) is the smallest singular value of the */ /* (2*n1*n2)-by-(2*n1*n2) matrix */ /* Zu = [ kron(In2, A11) -kron(A22', In1) ] */ /* [ kron(In2, B11) -kron(B22', In1) ]. */ /* Here, Inx is the identity matrix of size nx and A22' is the */ /* transpose of A22. kron(X, Y) is the Kronecker product between */ /* the matrices X and Y. */ /* When DIF(2) is small, small changes in (A, B) can cause large changes */ /* in the deflating subspace. An approximate (asymptotic) bound on the */ /* maximum angular error in the computed deflating subspaces is */ /* EPS * norm((A, B)) / DIF(2), */ /* where EPS is the machine precision. */ /* The reciprocal norm of the projectors on the left and right */ /* eigenspaces associated with (A11, B11) may be returned in PL and PR. */ /* They are computed as follows. First we compute L and R so that */ /* P*(A, B)*Q is block diagonal, where */ /* P = ( I -L ) n1 Q = ( I R ) n1 */ /* ( 0 I ) n2 and ( 0 I ) n2 */ /* n1 n2 n1 n2 */ /* and (L, R) is the solution to the generalized Sylvester equation */ /* A11*R - L*A22 = -A12 */ /* B11*R - L*B22 = -B12 */ /* Then PL = (F-norm(L)**2+1)**(-1/2) and PR = (F-norm(R)**2+1)**(-1/2). */ /* An approximate (asymptotic) bound on the average absolute error of */ /* the selected eigenvalues is */ /* EPS * norm((A, B)) / PL. */ /* There are also global error bounds which valid for perturbations up */ /* to a certain restriction: A lower bound (x) on the smallest */ /* F-norm(E,F) for which an eigenvalue of (A11, B11) may move and */ /* coalesce with an eigenvalue of (A22, B22) under perturbation (E,F), */ /* (i.e. (A + E, B + F), is */ /* x = min(Difu,Difl)/((1/(PL*PL)+1/(PR*PR))**(1/2)+2*max(1/PL,1/PR)). */ /* An approximate bound on x can be computed from DIF(1:2), PL and PR. */ /* If y = ( F-norm(E,F) / x) <= 1, the angles between the perturbed */ /* (L', R') and unperturbed (L, R) left and right deflating subspaces */ /* associated with the selected cluster in the (1,1)-blocks can be */ /* bounded as */ /* max-angle(L, L') <= arctan( y * PL / (1 - y * (1 - PL * PL)**(1/2)) */ /* max-angle(R, R') <= arctan( y * PR / (1 - y * (1 - PR * PR)**(1/2)) */ /* See LAPACK User's Guide section 4.11 or the following references */ /* for more information. */ /* Note that if the default method for computing the Frobenius-norm- */ /* based estimate DIF is not wanted (see CLATDF), then the parameter */ /* IDIFJB (see below) should be changed from 3 to 4 (routine CLATDF */ /* (IJOB = 2 will be used)). See CTGSYL for more details. */ /* Based on contributions by */ /* Bo Kagstrom and Peter Poromaa, Department of Computing Science, */ /* Umea University, S-901 87 Umea, Sweden. */ /* References */ /* ========== */ /* [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the */ /* Generalized Real Schur Form of a Regular Matrix Pair (A, B), in */ /* M.S. Moonen et al (eds), Linear Algebra for Large Scale and */ /* Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218. */ /* [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified */ /* Eigenvalues of a Regular Matrix Pair (A, B) and Condition */ /* Estimation: Theory, Algorithms and Software, Report */ /* UMINF - 94.04, Department of Computing Science, Umea University, */ /* S-901 87 Umea, Sweden, 1994. Also as LAPACK Working Note 87. */ /* To appear in Numerical Algorithms, 1996. */ /* [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software */ /* for Solving the Generalized Sylvester Equation and Estimating the */ /* Separation between Regular Matrix Pairs, Report UMINF - 93.23, */ /* Department of Computing Science, Umea University, S-901 87 Umea, */ /* Sweden, December 1993, Revised April 1994, Also as LAPACK working */ /* Note 75. To appear in ACM Trans. on Math. Software, Vol 22, No 1, */ /* 1996. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Decode and test the input parameters */ /* Parameter adjustments */ --select; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; --alpha; --beta; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; z_dim1 = *ldz; z_offset = 1 + z_dim1; z__ -= z_offset; --dif; --work; --iwork; /* Function Body */ *info = 0; lquery = *lwork == -1 || *liwork == -1; if (*ijob < 0 || *ijob > 5) { *info = -1; } else if (*n < 0) { *info = -5; } else if (*lda < max(1,*n)) { *info = -7; } else if (*ldb < max(1,*n)) { *info = -9; } else if (*ldq < 1 || *wantq && *ldq < *n) { *info = -13; } else if (*ldz < 1 || *wantz && *ldz < *n) { *info = -15; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGSEN", &i__1); return 0; } ierr = 0; wantp = *ijob == 1 || *ijob >= 4; wantd1 = *ijob == 2 || *ijob == 4; wantd2 = *ijob == 3 || *ijob == 5; wantd = wantd1 || wantd2; /* Set M to the dimension of the specified pair of deflating */ /* subspaces. */ *m = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { i__2 = k; i__3 = k + k * a_dim1; alpha[i__2].r = a[i__3].r, alpha[i__2].i = a[i__3].i; i__2 = k; i__3 = k + k * b_dim1; beta[i__2].r = b[i__3].r, beta[i__2].i = b[i__3].i; if (k < *n) { if (select[k]) { ++(*m); } } else { if (select[*n]) { ++(*m); } } /* L10: */ } if (*ijob == 1 || *ijob == 2 || *ijob == 4) { /* Computing MAX */ i__1 = 1, i__2 = (*m << 1) * (*n - *m); lwmin = max(i__1,i__2); /* Computing MAX */ i__1 = 1, i__2 = *n + 2; liwmin = max(i__1,i__2); } else if (*ijob == 3 || *ijob == 5) { /* Computing MAX */ i__1 = 1, i__2 = (*m << 2) * (*n - *m); lwmin = max(i__1,i__2); /* Computing MAX */ i__1 = 1, i__2 = (*m << 1) * (*n - *m), i__1 = max(i__1,i__2), i__2 = *n + 2; liwmin = max(i__1,i__2); } else { lwmin = 1; liwmin = 1; } work[1].r = (real) lwmin, work[1].i = 0.f; iwork[1] = liwmin; if (*lwork < lwmin && ! lquery) { *info = -21; } else if (*liwork < liwmin && ! lquery) { *info = -23; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGSEN", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible. */ if (*m == *n || *m == 0) { if (wantp) { *pl = 1.f; *pr = 1.f; } if (wantd) { dscale = 0.f; dsum = 1.f; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { classq_(n, &a[i__ * a_dim1 + 1], &c__1, &dscale, &dsum); classq_(n, &b[i__ * b_dim1 + 1], &c__1, &dscale, &dsum); /* L20: */ } dif[1] = dscale * sqrt(dsum); dif[2] = dif[1]; } goto L70; } /* Get machine constant */ safmin = slamch_("S"); /* Collect the selected blocks at the top-left corner of (A, B). */ ks = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { swap = select[k]; if (swap) { ++ks; /* Swap the K-th block to position KS. Compute unitary Q */ /* and Z that will swap adjacent diagonal blocks in (A, B). */ if (k != ks) { ctgexc_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &k, &ks, & ierr); } if (ierr > 0) { /* Swap is rejected: exit. */ *info = 1; if (wantp) { *pl = 0.f; *pr = 0.f; } if (wantd) { dif[1] = 0.f; dif[2] = 0.f; } goto L70; } } /* L30: */ } if (wantp) { /* Solve generalized Sylvester equation for R and L: */ /* A11 * R - L * A22 = A12 */ /* B11 * R - L * B22 = B12 */ n1 = *m; n2 = *n - *m; i__ = n1 + 1; clacpy_("Full", &n1, &n2, &a[i__ * a_dim1 + 1], lda, &work[1], &n1); clacpy_("Full", &n1, &n2, &b[i__ * b_dim1 + 1], ldb, &work[n1 * n2 + 1], &n1); ijb = 0; i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a[i__ + i__ * a_dim1] , lda, &work[1], &n1, &b[b_offset], ldb, &b[i__ + i__ * b_dim1], ldb, &work[n1 * n2 + 1], &n1, &dscale, &dif[1], & work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); /* Estimate the reciprocal of norms of "projections" onto */ /* left and right eigenspaces */ rdscal = 0.f; dsum = 1.f; i__1 = n1 * n2; classq_(&i__1, &work[1], &c__1, &rdscal, &dsum); *pl = rdscal * sqrt(dsum); if (*pl == 0.f) { *pl = 1.f; } else { *pl = dscale / (sqrt(dscale * dscale / *pl + *pl) * sqrt(*pl)); } rdscal = 0.f; dsum = 1.f; i__1 = n1 * n2; classq_(&i__1, &work[n1 * n2 + 1], &c__1, &rdscal, &dsum); *pr = rdscal * sqrt(dsum); if (*pr == 0.f) { *pr = 1.f; } else { *pr = dscale / (sqrt(dscale * dscale / *pr + *pr) * sqrt(*pr)); } } if (wantd) { /* Compute estimates Difu and Difl. */ if (wantd1) { n1 = *m; n2 = *n - *m; i__ = n1 + 1; ijb = 3; /* Frobenius norm-based Difu estimate. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a[i__ + i__ * a_dim1], lda, &work[1], &n1, &b[b_offset], ldb, &b[i__ + i__ * b_dim1], ldb, &work[n1 * n2 + 1], &n1, &dscale, & dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], & ierr); /* Frobenius norm-based Difl estimate. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n2, &n1, &a[i__ + i__ * a_dim1], lda, &a[ a_offset], lda, &work[1], &n2, &b[i__ + i__ * b_dim1], ldb, &b[b_offset], ldb, &work[n1 * n2 + 1], &n2, &dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], & ierr); } else { /* Compute 1-norm-based estimates of Difu and Difl using */ /* reversed communication with CLACN2. In each step a */ /* generalized Sylvester equation or a transposed variant */ /* is solved. */ kase = 0; n1 = *m; n2 = *n - *m; i__ = n1 + 1; ijb = 0; mn2 = (n1 << 1) * n2; /* 1-norm-based estimate of Difu. */ L40: clacn2_(&mn2, &work[mn2 + 1], &work[1], &dif[1], &kase, isave); if (kase != 0) { if (kase == 1) { /* Solve generalized Sylvester equation */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a[i__ + i__ * a_dim1], lda, &work[1], &n1, &b[b_offset], ldb, &b[i__ + i__ * b_dim1], ldb, &work[n1 * n2 + 1], &n1, &dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } else { /* Solve the transposed variant. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("C", &ijb, &n1, &n2, &a[a_offset], lda, &a[i__ + i__ * a_dim1], lda, &work[1], &n1, &b[b_offset], ldb, &b[i__ + i__ * b_dim1], ldb, &work[n1 * n2 + 1], &n1, &dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } goto L40; } dif[1] = dscale / dif[1]; /* 1-norm-based estimate of Difl. */ L50: clacn2_(&mn2, &work[mn2 + 1], &work[1], &dif[2], &kase, isave); if (kase != 0) { if (kase == 1) { /* Solve generalized Sylvester equation */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n2, &n1, &a[i__ + i__ * a_dim1], lda, &a[a_offset], lda, &work[1], &n2, &b[i__ + i__ * b_dim1], ldb, &b[b_offset], ldb, &work[n1 * n2 + 1], &n2, &dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } else { /* Solve the transposed variant. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("C", &ijb, &n2, &n1, &a[i__ + i__ * a_dim1], lda, &a[a_offset], lda, &work[1], &n2, &b[b_offset], ldb, &b[i__ + i__ * b_dim1], ldb, &work[n1 * n2 + 1], &n2, &dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } goto L50; } dif[2] = dscale / dif[2]; } } /* If B(K,K) is complex, make it real and positive (normalization */ /* of the generalized Schur form) and Store the generalized */ /* eigenvalues of reordered pair (A, B) */ i__1 = *n; for (k = 1; k <= i__1; ++k) { dscale = c_abs(&b[k + k * b_dim1]); if (dscale > safmin) { i__2 = k + k * b_dim1; q__2.r = b[i__2].r / dscale, q__2.i = b[i__2].i / dscale; r_cnjg(&q__1, &q__2); temp1.r = q__1.r, temp1.i = q__1.i; i__2 = k + k * b_dim1; q__1.r = b[i__2].r / dscale, q__1.i = b[i__2].i / dscale; temp2.r = q__1.r, temp2.i = q__1.i; i__2 = k + k * b_dim1; b[i__2].r = dscale, b[i__2].i = 0.f; i__2 = *n - k; cscal_(&i__2, &temp1, &b[k + (k + 1) * b_dim1], ldb); i__2 = *n - k + 1; cscal_(&i__2, &temp1, &a[k + k * a_dim1], lda); if (*wantq) { cscal_(n, &temp2, &q[k * q_dim1 + 1], &c__1); } } else { i__2 = k + k * b_dim1; b[i__2].r = 0.f, b[i__2].i = 0.f; } i__2 = k; i__3 = k + k * a_dim1; alpha[i__2].r = a[i__3].r, alpha[i__2].i = a[i__3].i; i__2 = k; i__3 = k + k * b_dim1; beta[i__2].r = b[i__3].r, beta[i__2].i = b[i__3].i; /* L60: */ } L70: work[1].r = (real) lwmin, work[1].i = 0.f; iwork[1] = liwmin; return 0; /* End of CTGSEN */ } /* ctgsen_ */
/* Subroutine */ int cpocon_(char *uplo, integer *n, complex *a, integer *lda, real *anorm, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1; real r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer ix, kase; real scale; extern logical lsame_(char *, char *); integer isave[3]; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern integer icamax_(integer *, complex *, integer *); real scalel; extern real slamch_(char *); real scaleu; extern /* Subroutine */ int xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int clatrs_(char *, char *, char *, char *, integer *, complex *, integer *, complex *, real *, real *, integer *), csrscl_(integer *, real *, complex *, integer *); char normin[1]; real smlnum; /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } else if (*anorm < 0.f) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CPOCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the 1-norm of inv(A). */ kase = 0; *(unsigned char *)normin = 'N'; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (upper) { /* Multiply by inv(U**H). */ clatrs_("Upper", "Conjugate transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(U). */ clatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scaleu, &rwork[1], info); } else { /* Multiply by inv(L). */ clatrs_("Lower", "No transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(L**H). */ clatrs_("Lower", "Conjugate transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scaleu, &rwork[1], info); } /* Multiply by 1/SCALE if doing so will not cause overflow. */ scale = scalel * scaleu; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, abs(r__1)) + (r__2 = r_imag(& work[ix]), abs(r__2))) * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L20: return 0; /* End of CPOCON */ }
int cpbcon_(char *uplo, int *n, int *kd, complex *ab, int *ldab, float *anorm, float *rcond, complex *work, float *rwork, int *info) { /* System generated locals */ int ab_dim1, ab_offset, i__1; float r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ int ix, kase; float scale; extern int lsame_(char *, char *); int isave[3]; int upper; extern int clacn2_(int *, complex *, complex *, float *, int *, int *); extern int icamax_(int *, complex *, int *); float scalel; extern double slamch_(char *); extern int clatbs_(char *, char *, char *, char *, int *, int *, complex *, int *, complex *, float *, float *, int *); float scaleu; extern int xerbla_(char *, int *); float ainvnm; extern int csrscl_(int *, float *, complex *, int *); char normin[1]; float smlnum; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CPBCON estimates the reciprocal of the condition number (in the */ /* 1-norm) of a complex Hermitian positive definite band matrix using */ /* the Cholesky factorization A = U**H*U or A = L*L**H computed by */ /* CPBTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangular factor stored in AB; */ /* = 'L': Lower triangular factor stored in AB. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* KD (input) INTEGER */ /* The number of superdiagonals of the matrix A if UPLO = 'U', */ /* or the number of sub-diagonals if UPLO = 'L'. KD >= 0. */ /* AB (input) COMPLEX array, dimension (LDAB,N) */ /* The triangular factor U or L from the Cholesky factorization */ /* A = U**H*U or A = L*L**H of the band matrix A, stored in the */ /* first KD+1 rows of the array. The j-th column of U or L is */ /* stored in the j-th column of the array AB as follows: */ /* if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for MAX(1,j-kd)<=i<=j; */ /* if UPLO ='L', AB(1+i-j,j) = L(i,j) for j<=i<=MIN(n,j+kd). */ /* LDAB (input) INTEGER */ /* The leading dimension of the array AB. LDAB >= KD+1. */ /* ANORM (input) REAL */ /* The 1-norm (or infinity-norm) of the Hermitian band matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*kd < 0) { *info = -3; } else if (*ldab < *kd + 1) { *info = -5; } else if (*anorm < 0.f) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("CPBCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the 1-norm of the inverse. */ kase = 0; *(unsigned char *)normin = 'N'; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (upper) { /* Multiply by inv(U'). */ clatbs_("Upper", "Conjugate transpose", "Non-unit", normin, n, kd, &ab[ab_offset], ldab, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(U). */ clatbs_("Upper", "No transpose", "Non-unit", normin, n, kd, &ab[ ab_offset], ldab, &work[1], &scaleu, &rwork[1], info); } else { /* Multiply by inv(L). */ clatbs_("Lower", "No transpose", "Non-unit", normin, n, kd, &ab[ ab_offset], ldab, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(L'). */ clatbs_("Lower", "Conjugate transpose", "Non-unit", normin, n, kd, &ab[ab_offset], ldab, &work[1], &scaleu, &rwork[1], info); } /* Multiply by 1/SCALE if doing so will not cause overflow. */ scale = scalel * scaleu; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, ABS(r__1)) + (r__2 = r_imag(& work[ix]), ABS(r__2))) * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L20: return 0; /* End of CPBCON */ } /* cpbcon_ */
/* Subroutine */ int ctrrfs_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, complex *a, integer *lda, complex *b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j, k; real s, xk; integer nz; real eps; integer kase; real safe1, safe2; extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, complex *, integer *), caxpy_(integer *, complex *, complex *, integer *, complex *, integer *); logical upper; extern /* Subroutine */ int ctrmv_(char *, char *, char *, integer *, complex *, integer *, complex *, integer *), ctrsv_(char *, char *, char *, integer *, complex *, integer *, complex *, integer *), clacn2_( integer *, complex *, complex *, real *, integer *, integer *); extern real slamch_(char *); real safmin; extern /* Subroutine */ int xerbla_(char *, integer *); logical notran; char transn[1], transt[1]; logical nounit; real lstres; /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --ferr; --berr; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); notran = lsame_(trans, "N"); nounit = lsame_(diag, "N"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (! notran && ! lsame_(trans, "T") && ! lsame_(trans, "C")) { *info = -2; } else if (! nounit && ! lsame_(diag, "U")) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*nrhs < 0) { *info = -5; } else if (*lda < max(1,*n)) { *info = -7; } else if (*ldb < max(1,*n)) { *info = -9; } else if (*ldx < max(1,*n)) { *info = -11; } if (*info != 0) { i__1 = -(*info); xerbla_("CTRRFS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ferr[j] = 0.f; berr[j] = 0.f; /* L10: */ } return 0; } if (notran) { *(unsigned char *)transn = 'N'; *(unsigned char *)transt = 'C'; } else { *(unsigned char *)transn = 'C'; *(unsigned char *)transt = 'N'; } /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ nz = *n + 1; eps = slamch_("Epsilon"); safmin = slamch_("Safe minimum"); safe1 = nz * safmin; safe2 = safe1 / eps; /* Do for each right hand side */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { /* Compute residual R = B - op(A) * X, */ /* where op(A) = A, A**T, or A**H, depending on TRANS. */ ccopy_(n, &x[j * x_dim1 + 1], &c__1, &work[1], &c__1); ctrmv_(uplo, trans, diag, n, &a[a_offset], lda, &work[1], &c__1); q__1.r = -1.f; q__1.i = -0.f; // , expr subst caxpy_(n, &q__1, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1); /* Compute componentwise relative backward error from formula */ /* max(i) ( f2c_abs(R(i)) / ( f2c_abs(op(A))*f2c_abs(X) + f2c_abs(B) )(i) ) */ /* where f2c_abs(Z) is the componentwise absolute value of the matrix */ /* or vector Z. If the i-th component of the denominator is less */ /* than SAFE2, then SAFE1 is added to the i-th components of the */ /* numerator and denominator before dividing. */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; rwork[i__] = (r__1 = b[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&b[ i__ + j * b_dim1]), f2c_abs(r__2)); /* L20: */ } if (notran) { /* Compute f2c_abs(A)*f2c_abs(X) + f2c_abs(B). */ if (upper) { if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + ( r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs( r__2))) * xk; /* L30: */ } /* L40: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + ( r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs( r__2))) * xk; /* L50: */ } rwork[k] += xk; /* L60: */ } } } else { if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + ( r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs( r__2))) * xk; /* L70: */ } /* L80: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(& x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + ( r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs( r__2))) * xk; /* L90: */ } rwork[k] += xk; /* L100: */ } } } } else { /* Compute f2c_abs(A**H)*f2c_abs(X) + f2c_abs(B). */ if (upper) { if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5].r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))) ; /* L110: */ } rwork[k] += s; /* L120: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; s = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[ k + j * x_dim1]), f2c_abs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5].r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))) ; /* L130: */ } rwork[k] += s; /* L140: */ } } } else { if (nounit) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5].r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))) ; /* L150: */ } rwork[k] += s; /* L160: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; s = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[ k + j * x_dim1]), f2c_abs(r__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5].r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))) ; /* L170: */ } rwork[k] += s; /* L180: */ } } } } s = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__3 = i__; r__3 = s; r__4 = ((r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2))) / rwork[i__]; // , expr subst s = max(r__3,r__4); } else { /* Computing MAX */ i__3 = i__; r__3 = s; r__4 = ((r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + safe1) / (rwork[i__] + safe1); // , expr subst s = max(r__3,r__4); } /* L190: */ } berr[j] = s; /* Bound error from formula */ /* norm(X - XTRUE) / norm(X) .le. FERR = */ /* norm( f2c_abs(inv(op(A)))* */ /* ( f2c_abs(R) + NZ*EPS*( f2c_abs(op(A))*f2c_abs(X)+f2c_abs(B) ))) / norm(X) */ /* where */ /* norm(Z) is the magnitude of the largest component of Z */ /* inv(op(A)) is the inverse of op(A) */ /* f2c_abs(Z) is the componentwise absolute value of the matrix or */ /* vector Z */ /* NZ is the maximum number of nonzeros in any row of A, plus 1 */ /* EPS is machine epsilon */ /* The i-th component of f2c_abs(R)+NZ*EPS*(f2c_abs(op(A))*f2c_abs(X)+f2c_abs(B)) */ /* is incremented by SAFE1 if the i-th component of */ /* f2c_abs(op(A))*f2c_abs(X) + f2c_abs(B) is less than SAFE2. */ /* Use CLACN2 to estimate the infinity-norm of the matrix */ /* inv(op(A)) * diag(W), */ /* where W = f2c_abs(R) + NZ*EPS*( f2c_abs(op(A))*f2c_abs(X)+f2c_abs(B) ))) */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + nz * eps * rwork[i__] ; } else { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + nz * eps * rwork[i__] + safe1; } /* L200: */ } kase = 0; L210: clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(op(A)**H). */ ctrsv_(uplo, transt, diag, n, &a[a_offset], lda, &work[1], & c__1); i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r; q__1.i = rwork[i__4] * work[i__5].i; // , expr subst work[i__3].r = q__1.r; work[i__3].i = q__1.i; // , expr subst /* L220: */ } } else { /* Multiply by inv(op(A))*diag(W). */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r; q__1.i = rwork[i__4] * work[i__5].i; // , expr subst work[i__3].r = q__1.r; work[i__3].i = q__1.i; // , expr subst /* L230: */ } ctrsv_(uplo, transn, diag, n, &a[a_offset], lda, &work[1], & c__1); } goto L210; } /* Normalize error. */ lstres = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__3 = i__ + j * x_dim1; r__3 = lstres; r__4 = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__2)); // , expr subst lstres = max(r__3,r__4); /* L240: */ } if (lstres != 0.f) { ferr[j] /= lstres; } /* L250: */ } return 0; /* End of CTRRFS */ }
/* Subroutine */ int chpcon_(char *uplo, integer *n, complex *ap, integer * ipiv, real *anorm, real *rcond, complex *work, integer *info) { /* System generated locals */ integer i__1, i__2; /* Local variables */ integer i__, ip, kase; extern logical lsame_(char *, char *); integer isave[3]; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int chptrs_(char *, integer *, integer *, complex *, integer *, complex *, integer *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CHPCON estimates the reciprocal of the condition number of a complex */ /* Hermitian packed matrix A using the factorization A = U*D*U**H or */ /* A = L*D*L**H computed by CHPTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* Specifies whether the details of the factorization are stored */ /* as an upper or lower triangular matrix. */ /* = 'U': Upper triangular, form is A = U*D*U**H; */ /* = 'L': Lower triangular, form is A = L*D*L**H. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* AP (input) COMPLEX array, dimension (N*(N+1)/2) */ /* The block diagonal matrix D and the multipliers used to */ /* obtain the factor U or L as computed by CHPTRF, stored as a */ /* packed triangular matrix. */ /* IPIV (input) INTEGER array, dimension (N) */ /* Details of the interchanges and the block structure of D */ /* as determined by CHPTRF. */ /* ANORM (input) REAL */ /* The 1-norm of the original matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --work; --ipiv; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*anorm < 0.f) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CHPCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm <= 0.f) { return 0; } /* Check that the diagonal matrix D is nonsingular. */ if (upper) { /* Upper triangular storage: examine D from bottom to top */ ip = *n * (*n + 1) / 2; for (i__ = *n; i__ >= 1; --i__) { i__1 = ip; if (ipiv[i__] > 0 && (ap[i__1].r == 0.f && ap[i__1].i == 0.f)) { return 0; } ip -= i__; /* L10: */ } } else { /* Lower triangular storage: examine D from top to bottom. */ ip = 1; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = ip; if (ipiv[i__] > 0 && (ap[i__2].r == 0.f && ap[i__2].i == 0.f)) { return 0; } ip = ip + *n - i__ + 1; /* L20: */ } } /* Estimate the 1-norm of the inverse. */ kase = 0; L30: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { /* Multiply by inv(L*D*L') or inv(U*D*U'). */ chptrs_(uplo, n, &c__1, &ap[1], &ipiv[1], &work[1], n, info); goto L30; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } return 0; /* End of CHPCON */ } /* chpcon_ */
doublereal cla_hercond_x__(char *uplo, integer *n, complex *a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex *x, integer *info, complex *work, real *rwork, ftnlen uplo_len) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, i__1, i__2, i__3, i__4; real ret_val, r__1, r__2; complex q__1, q__2; /* Builtin functions */ double r_imag(complex *); void c_div(complex *, complex *, complex *); /* Local variables */ integer i__, j; logical up; real tmp; integer kase; extern logical lsame_(char *, char *); integer isave[3]; real anorm; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int chetrs_(char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); /* -- LAPACK routine (version 3.2.1) -- */ /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */ /* -- Jason Riedy of Univ. of California Berkeley. -- */ /* -- April 2009 -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley and NAG Ltd. -- */ /* .. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CLA_HERCOND_X computes the infinity norm condition number of */ /* op(A) * diag(X) where X is a COMPLEX vector. */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The number of linear equations, i.e., the order of the */ /* matrix A. N >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* On entry, the N-by-N matrix A. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* AF (input) COMPLEX array, dimension (LDAF,N) */ /* The block diagonal matrix D and the multipliers used to */ /* obtain the factor U or L as computed by CHETRF. */ /* LDAF (input) INTEGER */ /* The leading dimension of the array AF. LDAF >= max(1,N). */ /* IPIV (input) INTEGER array, dimension (N) */ /* Details of the interchanges and the block structure of D */ /* as determined by CHETRF. */ /* X (input) COMPLEX array, dimension (N) */ /* The vector X in the formula op(A) * diag(X). */ /* INFO (output) INTEGER */ /* = 0: Successful exit. */ /* i > 0: The ith argument is invalid. */ /* WORK (input) COMPLEX array, dimension (2*N). */ /* Workspace. */ /* RWORK (input) REAL array, dimension (N). */ /* Workspace. */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function Definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; af_dim1 = *ldaf; af_offset = 1 + af_dim1; af -= af_offset; --ipiv; --x; --work; --rwork; /* Function Body */ ret_val = 0.f; *info = 0; if (*n < 0) { *info = -2; } if (*info != 0) { i__1 = -(*info); xerbla_("CLA_HERCOND_X", &i__1); return ret_val; } up = FALSE_; if (lsame_(uplo, "U")) { up = TRUE_; } /* Compute norm of op(A)*op2(C). */ anorm = 0.f; if (up) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; i__4 = j; q__2.r = a[i__3].r * x[i__4].r - a[i__3].i * x[i__4].i, q__2.i = a[i__3].r * x[i__4].i + a[i__3].i * x[i__4] .r; q__1.r = q__2.r, q__1.i = q__2.i; tmp += (r__1 = q__1.r, dabs(r__1)) + (r__2 = r_imag(&q__1), dabs(r__2)); } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; i__4 = j; q__2.r = a[i__3].r * x[i__4].r - a[i__3].i * x[i__4].i, q__2.i = a[i__3].r * x[i__4].i + a[i__3].i * x[i__4] .r; q__1.r = q__2.r, q__1.i = q__2.i; tmp += (r__1 = q__1.r, dabs(r__1)) + (r__2 = r_imag(&q__1), dabs(r__2)); } rwork[i__] = tmp; anorm = dmax(anorm,tmp); } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; i__4 = j; q__2.r = a[i__3].r * x[i__4].r - a[i__3].i * x[i__4].i, q__2.i = a[i__3].r * x[i__4].i + a[i__3].i * x[i__4] .r; q__1.r = q__2.r, q__1.i = q__2.i; tmp += (r__1 = q__1.r, dabs(r__1)) + (r__2 = r_imag(&q__1), dabs(r__2)); } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; i__4 = j; q__2.r = a[i__3].r * x[i__4].r - a[i__3].i * x[i__4].i, q__2.i = a[i__3].r * x[i__4].i + a[i__3].i * x[i__4] .r; q__1.r = q__2.r, q__1.i = q__2.i; tmp += (r__1 = q__1.r, dabs(r__1)) + (r__2 = r_imag(&q__1), dabs(r__2)); } rwork[i__] = tmp; anorm = dmax(anorm,tmp); } } /* Quick return if possible. */ if (*n == 0) { ret_val = 1.f; return ret_val; } else if (anorm == 0.f) { return ret_val; } /* Estimate the norm of inv(op(A)). */ ainvnm = 0.f; kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == 2) { /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r, q__1.i = rwork[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } if (up) { chetrs_("U", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } else { chetrs_("L", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } /* Multiply by inv(X). */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; c_div(&q__1, &work[i__], &x[i__]); work[i__2].r = q__1.r, work[i__2].i = q__1.i; } } else { /* Multiply by inv(X'). */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; c_div(&q__1, &work[i__], &x[i__]); work[i__2].r = q__1.r, work[i__2].i = q__1.i; } if (up) { chetrs_("U", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } else { chetrs_("L", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r, q__1.i = rwork[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { ret_val = 1.f / ainvnm; } return ret_val; } /* cla_hercond_x__ */
/* Subroutine */ int cpocon_(char *uplo, integer *n, complex *a, integer *lda, real *anorm, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1; real r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer ix, kase; real scale; extern logical lsame_(char *, char *); integer isave[3]; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern integer icamax_(integer *, complex *, integer *); real scalel; extern doublereal slamch_(char *); real scaleu; extern /* Subroutine */ int xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int clatrs_(char *, char *, char *, char *, integer *, complex *, integer *, complex *, real *, real *, integer *), csrscl_(integer *, real *, complex *, integer *); char normin[1]; real smlnum; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CPOCON estimates the reciprocal of the condition number (in the */ /* 1-norm) of a complex Hermitian positive definite matrix using the */ /* Cholesky factorization A = U**H*U or A = L*L**H computed by CPOTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The triangular factor U or L from the Cholesky factorization */ /* A = U**H*U or A = L*L**H, as computed by CPOTRF. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* ANORM (input) REAL */ /* The 1-norm (or infinity-norm) of the Hermitian matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } else if (*anorm < 0.f) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CPOCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the 1-norm of inv(A). */ kase = 0; *(unsigned char *)normin = 'N'; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (upper) { /* Multiply by inv(U'). */ clatrs_("Upper", "Conjugate transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(U). */ clatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scaleu, &rwork[1], info); } else { /* Multiply by inv(L). */ clatrs_("Lower", "No transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scalel, &rwork[1], info); *(unsigned char *)normin = 'Y'; /* Multiply by inv(L'). */ clatrs_("Lower", "Conjugate transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &scaleu, &rwork[1], info); } /* Multiply by 1/SCALE if doing so will not cause overflow. */ scale = scalel * scaleu; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, dabs(r__1)) + (r__2 = r_imag(& work[ix]), dabs(r__2))) * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L20: return 0; /* End of CPOCON */ } /* cpocon_ */
/* Subroutine */ int ctbcon_(char *norm, char *uplo, char *diag, integer *n, integer *kd, complex *ab, integer *ldab, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer ab_dim1, ab_offset, i__1; real r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer ix, kase, kase1; real scale; extern logical lsame_(char *, char *); integer isave[3]; real anorm; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); real xnorm; extern integer icamax_(integer *, complex *, integer *); extern doublereal clantb_(char *, char *, char *, integer *, integer *, complex *, integer *, real *), slamch_( char *); extern /* Subroutine */ int clatbs_(char *, char *, char *, char *, integer *, integer *, complex *, integer *, complex *, real *, real *, integer *), xerbla_(char * , integer *); real ainvnm; extern /* Subroutine */ int csrscl_(integer *, real *, complex *, integer *); logical onenrm; char normin[1]; real smlnum; logical nounit; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTBCON estimates the reciprocal of the condition number of a */ /* triangular band matrix A, in either the 1-norm or the infinity-norm. */ /* The norm of A is computed and an estimate is obtained for */ /* norm(inv(A)), then the reciprocal of the condition number is */ /* computed as */ /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */ /* Arguments */ /* ========= */ /* NORM (input) CHARACTER*1 */ /* Specifies whether the 1-norm condition number or the */ /* infinity-norm condition number is required: */ /* = '1' or 'O': 1-norm; */ /* = 'I': Infinity-norm. */ /* UPLO (input) CHARACTER*1 */ /* = 'U': A is upper triangular; */ /* = 'L': A is lower triangular. */ /* DIAG (input) CHARACTER*1 */ /* = 'N': A is non-unit triangular; */ /* = 'U': A is unit triangular. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* KD (input) INTEGER */ /* The number of superdiagonals or subdiagonals of the */ /* triangular band matrix A. KD >= 0. */ /* AB (input) COMPLEX array, dimension (LDAB,N) */ /* The upper or lower triangular band matrix A, stored in the */ /* first kd+1 rows of the array. The j-th column of A is stored */ /* in the j-th column of the array AB as follows: */ /* if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; */ /* if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd). */ /* If DIAG = 'U', the diagonal elements of A are not referenced */ /* and are assumed to be 1. */ /* LDAB (input) INTEGER */ /* The leading dimension of the array AB. LDAB >= KD+1. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); nounit = lsame_(diag, "N"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (! upper && ! lsame_(uplo, "L")) { *info = -2; } else if (! nounit && ! lsame_(diag, "U")) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*kd < 0) { *info = -5; } else if (*ldab < *kd + 1) { *info = -7; } if (*info != 0) { i__1 = -(*info); xerbla_("CTBCON", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { *rcond = 1.f; return 0; } *rcond = 0.f; smlnum = slamch_("Safe minimum") * (real) max(*n,1); /* Compute the 1-norm of the triangular matrix A or A'. */ anorm = clantb_(norm, uplo, diag, n, kd, &ab[ab_offset], ldab, &rwork[1]); /* Continue only if ANORM > 0. */ if (anorm > 0.f) { /* Estimate the 1-norm of the inverse of A. */ ainvnm = 0.f; *(unsigned char *)normin = 'N'; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(A). */ clatbs_(uplo, "No transpose", diag, normin, n, kd, &ab[ ab_offset], ldab, &work[1], &scale, &rwork[1], info); } else { /* Multiply by inv(A'). */ clatbs_(uplo, "Conjugate transpose", diag, normin, n, kd, &ab[ ab_offset], ldab, &work[1], &scale, &rwork[1], info); } *(unsigned char *)normin = 'Y'; /* Multiply by 1/SCALE if doing so will not cause overflow. */ if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; xnorm = (r__1 = work[i__1].r, dabs(r__1)) + (r__2 = r_imag(& work[ix]), dabs(r__2)); if (scale < xnorm * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / anorm / ainvnm; } } L20: return 0; /* End of CTBCON */ } /* ctbcon_ */
doublereal cla_gercond_c__(char *trans, integer *n, complex *a, integer *lda, complex *af, integer *ldaf, integer *ipiv, real *c__, logical *capply, integer *info, complex *work, real *rwork, ftnlen trans_len) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, i__1, i__2, i__3, i__4; real ret_val, r__1, r__2; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j; real tmp; integer kase; extern logical lsame_(char *, char *); integer isave[3]; real anorm; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *), cgetrs_(char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); real ainvnm; logical notrans; /* -- LAPACK routine (version 3.2.1) -- */ /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */ /* -- Jason Riedy of Univ. of California Berkeley. -- */ /* -- April 2009 -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley and NAG Ltd. -- */ /* .. */ /* .. Scalar Aguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CLA_GERCOND_C computes the infinity norm condition number of */ /* op(A) * inv(diag(C)) where C is a REAL vector. */ /* Arguments */ /* ========= */ /* TRANS (input) CHARACTER*1 */ /* Specifies the form of the system of equations: */ /* = 'N': A * X = B (No transpose) */ /* = 'T': A**T * X = B (Transpose) */ /* = 'C': A**H * X = B (Conjugate Transpose = Transpose) */ /* N (input) INTEGER */ /* The number of linear equations, i.e., the order of the */ /* matrix A. N >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* On entry, the N-by-N matrix A */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* AF (input) COMPLEX array, dimension (LDAF,N) */ /* The factors L and U from the factorization */ /* A = P*L*U as computed by CGETRF. */ /* LDAF (input) INTEGER */ /* The leading dimension of the array AF. LDAF >= max(1,N). */ /* IPIV (input) INTEGER array, dimension (N) */ /* The pivot indices from the factorization A = P*L*U */ /* as computed by CGETRF; row i of the matrix was interchanged */ /* with row IPIV(i). */ /* C (input) REAL array, dimension (N) */ /* The vector C in the formula op(A) * inv(diag(C)). */ /* CAPPLY (input) LOGICAL */ /* If .TRUE. then access the vector C in the formula above. */ /* INFO (output) INTEGER */ /* = 0: Successful exit. */ /* i > 0: The ith argument is invalid. */ /* WORK (input) COMPLEX array, dimension (2*N). */ /* Workspace. */ /* RWORK (input) REAL array, dimension (N). */ /* Workspace. */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function Definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; af_dim1 = *ldaf; af_offset = 1 + af_dim1; af -= af_offset; --ipiv; --c__; --work; --rwork; /* Function Body */ ret_val = 0.f; *info = 0; notrans = lsame_(trans, "N"); if (! notrans && ! lsame_(trans, "T") && ! lsame_( trans, "C")) { } else if (*n < 0) { *info = -2; } if (*info != 0) { i__1 = -(*info); xerbla_("CLA_GERCOND_C", &i__1); return ret_val; } /* Compute norm of op(A)*op2(C). */ anorm = 0.f; if (notrans) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; if (*capply) { i__2 = *n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += ((r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(& a[i__ + j * a_dim1]), dabs(r__2))) / c__[j]; } } else { i__2 = *n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[ i__ + j * a_dim1]), dabs(r__2)); } } rwork[i__] = tmp; anorm = dmax(anorm,tmp); } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; if (*capply) { i__2 = *n; for (j = 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += ((r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(& a[j + i__ * a_dim1]), dabs(r__2))) / c__[j]; } } else { i__2 = *n; for (j = 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[ j + i__ * a_dim1]), dabs(r__2)); } } rwork[i__] = tmp; anorm = dmax(anorm,tmp); } } /* Quick return if possible. */ if (*n == 0) { ret_val = 1.f; return ret_val; } else if (anorm == 0.f) { return ret_val; } /* Estimate the norm of inv(op(A)). */ ainvnm = 0.f; kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == 2) { /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r, q__1.i = rwork[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } if (notrans) { cgetrs_("No transpose", n, &c__1, &af[af_offset], ldaf, &ipiv[ 1], &work[1], n, info); } else { cgetrs_("Conjugate transpose", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[1], n, info); } /* Multiply by inv(C). */ if (*capply) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = c__[i__4] * work[i__3].r, q__1.i = c__[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } } } else { /* Multiply by inv(C'). */ if (*capply) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = c__[i__4] * work[i__3].r, q__1.i = c__[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } } if (notrans) { cgetrs_("Conjugate transpose", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[1], n, info); } else { cgetrs_("No transpose", n, &c__1, &af[af_offset], ldaf, &ipiv[ 1], &work[1], n, info); } /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r, q__1.i = rwork[i__4] * work[i__3].i; work[i__2].r = q__1.r, work[i__2].i = q__1.i; } } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { ret_val = 1.f / ainvnm; } return ret_val; } /* cla_gercond_c__ */
/* ===================================================================== */ real cla_syrcond_c_(char *uplo, integer *n, complex *a, integer *lda, complex *af, integer *ldaf, integer *ipiv, real *c__, logical *capply, integer *info, complex *work, real *rwork) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, i__1, i__2, i__3, i__4; real ret_val, r__1, r__2; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j; logical up; real tmp; integer kase; extern logical lsame_(char *, char *); integer isave[3]; real anorm; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int csytrs_(char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); /* -- LAPACK computational routine (version 3.4.2) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* September 2012 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function Definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; af_dim1 = *ldaf; af_offset = 1 + af_dim1; af -= af_offset; --ipiv; --c__; --work; --rwork; /* Function Body */ ret_val = 0.f; *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } else if (*ldaf < max(1,*n)) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("CLA_SYRCOND_C", &i__1); return ret_val; } up = FALSE_; if (lsame_(uplo, "U")) { up = TRUE_; } /* Compute norm of op(A)*op2(C). */ anorm = 0.f; if (up) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; if (*capply) { i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += ((r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ j + i__ * a_dim1]), abs(r__2))) / c__[j]; } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += ((r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ i__ + j * a_dim1]), abs(r__2))) / c__[j]; } } else { i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += (r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ j + i__ * a_dim1]), abs(r__2)); } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += (r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ i__ + j * a_dim1]), abs(r__2)); } } rwork[i__] = tmp; anorm = max(anorm,tmp); } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { tmp = 0.f; if (*capply) { i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += ((r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ i__ + j * a_dim1]), abs(r__2))) / c__[j]; } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += ((r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ j + i__ * a_dim1]), abs(r__2))) / c__[j]; } } else { i__2 = i__; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * a_dim1; tmp += (r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ i__ + j * a_dim1]), abs(r__2)); } i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { i__3 = j + i__ * a_dim1; tmp += (r__1 = a[i__3].r, abs(r__1)) + (r__2 = r_imag(&a[ j + i__ * a_dim1]), abs(r__2)); } } rwork[i__] = tmp; anorm = max(anorm,tmp); } } /* Quick return if possible. */ if (*n == 0) { ret_val = 1.f; return ret_val; } else if (anorm == 0.f) { return ret_val; } /* Estimate the norm of inv(op(A)). */ ainvnm = 0.f; kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == 2) { /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r; q__1.i = rwork[i__4] * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst } if (up) { csytrs_("U", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } else { csytrs_("L", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } /* Multiply by inv(C). */ if (*capply) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = c__[i__4] * work[i__3].r; q__1.i = c__[i__4] * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst } } } else { /* Multiply by inv(C**T). */ if (*capply) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = c__[i__4] * work[i__3].r; q__1.i = c__[i__4] * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst } } if (up) { csytrs_("U", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } else { csytrs_("L", n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } /* Multiply by R. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; i__4 = i__; q__1.r = rwork[i__4] * work[i__3].r; q__1.i = rwork[i__4] * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst } } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { ret_val = 1.f / ainvnm; } return ret_val; }
/* Subroutine */ int cgecon_(char *norm, integer *n, complex *a, integer *lda, real *anorm, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1; real r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ real sl; integer ix; real su; integer kase, kase1; real scale; extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern integer icamax_(integer *, complex *, integer *); extern doublereal slamch_(char *); extern /* Subroutine */ int xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int clatrs_(char *, char *, char *, char *, integer *, complex *, integer *, complex *, real *, real *, integer *), csrscl_(integer *, real *, complex *, integer *); logical onenrm; char normin[1]; real smlnum; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGECON estimates the reciprocal of the condition number of a general */ /* complex matrix A, in either the 1-norm or the infinity-norm, using */ /* the LU factorization computed by CGETRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as */ /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */ /* Arguments */ /* ========= */ /* NORM (input) CHARACTER*1 */ /* Specifies whether the 1-norm condition number or the */ /* infinity-norm condition number is required: */ /* = '1' or 'O': 1-norm; */ /* = 'I': Infinity-norm. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The factors L and U from the factorization A = P*L*U */ /* as computed by CGETRF. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* ANORM (input) REAL */ /* If NORM = '1' or 'O', the 1-norm of the original matrix A. */ /* If NORM = 'I', the infinity-norm of the original matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --work; --rwork; /* Function Body */ *info = 0; onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } else if (*anorm < 0.f) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CGECON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm == 0.f) { return 0; } smlnum = slamch_("Safe minimum"); /* Estimate the norm of inv(A). */ ainvnm = 0.f; *(unsigned char *)normin = 'N'; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(L). */ clatrs_("Lower", "No transpose", "Unit", normin, n, &a[a_offset], lda, &work[1], &sl, &rwork[1], info); /* Multiply by inv(U). */ clatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &su, &rwork[*n + 1], info); } else { /* Multiply by inv(U'). */ clatrs_("Upper", "Conjugate transpose", "Non-unit", normin, n, &a[ a_offset], lda, &work[1], &su, &rwork[*n + 1], info); /* Multiply by inv(L'). */ clatrs_("Lower", "Conjugate transpose", "Unit", normin, n, &a[ a_offset], lda, &work[1], &sl, &rwork[1], info); } /* Divide X by 1/(SL*SU) if doing so will not cause overflow. */ scale = sl * su; *(unsigned char *)normin = 'Y'; if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; if (scale < ((r__1 = work[i__1].r, dabs(r__1)) + (r__2 = r_imag(& work[ix]), dabs(r__2))) * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } L20: return 0; /* End of CGECON */ } /* cgecon_ */
/* Subroutine */ int checon_(char *uplo, integer *n, complex *a, integer *lda, integer *ipiv, real *anorm, real *rcond, complex *work, integer * info) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2; /* Local variables */ integer i__, kase; extern logical lsame_(char *, char *); integer isave[3]; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *), xerbla_(char *, integer *); real ainvnm; extern /* Subroutine */ int chetrs_(char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --ipiv; --work; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } else if (*anorm < 0.f) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("CHECON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm <= 0.f) { return 0; } /* Check that the diagonal matrix D is nonsingular. */ if (upper) { /* Upper triangular storage: examine D from bottom to top */ for (i__ = *n; i__ >= 1; --i__) { i__1 = i__ + i__ * a_dim1; if (ipiv[i__] > 0 && (a[i__1].r == 0.f && a[i__1].i == 0.f)) { return 0; } /* L10: */ } } else { /* Lower triangular storage: examine D from top to bottom. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__ + i__ * a_dim1; if (ipiv[i__] > 0 && (a[i__2].r == 0.f && a[i__2].i == 0.f)) { return 0; } /* L20: */ } } /* Estimate the 1-norm of the inverse. */ kase = 0; L30: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { /* Multiply by inv(L*D*L**H) or inv(U*D*U**H). */ chetrs_(uplo, n, &c__1, &a[a_offset], lda, &ipiv[1], &work[1], n, info); goto L30; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } return 0; /* End of CHECON */ }
/* Subroutine */ int cherfs_(char *uplo, integer *n, integer *nrhs, complex * a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex * b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j, k; real s, xk; integer nz; real eps; integer kase; real safe1, safe2; extern logical lsame_(char *, char *); extern /* Subroutine */ int chemv_(char *, integer *, complex *, complex * , integer *, complex *, integer *, complex *, complex *, integer * ); integer isave[3]; extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, complex *, integer *), caxpy_(integer *, complex *, complex *, integer *, complex *, integer *); integer count; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern real slamch_(char *); real safmin; extern /* Subroutine */ int xerbla_(char *, integer *), chetrs_( char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); real lstres; /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; af_dim1 = *ldaf; af_offset = 1 + af_dim1; af -= af_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --ferr; --berr; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*nrhs < 0) { *info = -3; } else if (*lda < max(1,*n)) { *info = -5; } else if (*ldaf < max(1,*n)) { *info = -7; } else if (*ldb < max(1,*n)) { *info = -10; } else if (*ldx < max(1,*n)) { *info = -12; } if (*info != 0) { i__1 = -(*info); xerbla_("CHERFS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ferr[j] = 0.f; berr[j] = 0.f; /* L10: */ } return 0; } /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ nz = *n + 1; eps = slamch_("Epsilon"); safmin = slamch_("Safe minimum"); safe1 = nz * safmin; safe2 = safe1 / eps; /* Do for each right hand side */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { count = 1; lstres = 3.f; L20: /* Loop until stopping criterion is satisfied. */ /* Compute residual R = B - A * X */ ccopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1); q__1.r = -1.f; q__1.i = -0.f; // , expr subst chemv_(uplo, n, &q__1, &a[a_offset], lda, &x[j * x_dim1 + 1], &c__1, & c_b1, &work[1], &c__1); /* Compute componentwise relative backward error from formula */ /* max(i) ( f2c_abs(R(i)) / ( f2c_abs(A)*f2c_abs(X) + f2c_abs(B) )(i) ) */ /* where f2c_abs(Z) is the componentwise absolute value of the matrix */ /* or vector Z. If the i-th component of the denominator is less */ /* than SAFE2, then SAFE1 is added to the i-th components of the */ /* numerator and denominator before dividing. */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; rwork[i__] = (r__1 = b[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&b[ i__ + j * b_dim1]), f2c_abs(r__2)); /* L30: */ } /* Compute f2c_abs(A)*f2c_abs(X) + f2c_abs(B). */ if (upper) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * xk; i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[ i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5] .r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))); /* L40: */ } i__3 = k + k * a_dim1; rwork[k] = rwork[k] + (r__1 = a[i__3].r, f2c_abs(r__1)) * xk + s; /* L50: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[k + j * x_dim1]), f2c_abs(r__2)); i__3 = k + k * a_dim1; rwork[k] += (r__1 = a[i__3].r, f2c_abs(r__1)) * xk; i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), f2c_abs(r__2))) * xk; i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, f2c_abs(r__1)) + (r__2 = r_imag(&a[ i__ + k * a_dim1]), f2c_abs(r__2))) * ((r__3 = x[i__5] .r, f2c_abs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__4))); /* L60: */ } rwork[k] += s; /* L70: */ } } s = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__3 = i__; r__3 = s; r__4 = ((r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2))) / rwork[i__]; // , expr subst s = max(r__3,r__4); } else { /* Computing MAX */ i__3 = i__; r__3 = s; r__4 = ((r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + safe1) / (rwork[i__] + safe1); // , expr subst s = max(r__3,r__4); } /* L80: */ } berr[j] = s; /* Test stopping criterion. Continue iterating if */ /* 1) The residual BERR(J) is larger than machine epsilon, and */ /* 2) BERR(J) decreased by at least a factor of 2 during the */ /* last iteration, and */ /* 3) At most ITMAX iterations tried. */ if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) { /* Update solution and try again. */ chetrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[1], n, info); caxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1); lstres = berr[j]; ++count; goto L20; } /* Bound error from formula */ /* norm(X - XTRUE) / norm(X) .le. FERR = */ /* norm( f2c_abs(inv(A))* */ /* ( f2c_abs(R) + NZ*EPS*( f2c_abs(A)*f2c_abs(X)+f2c_abs(B) ))) / norm(X) */ /* where */ /* norm(Z) is the magnitude of the largest component of Z */ /* inv(A) is the inverse of A */ /* f2c_abs(Z) is the componentwise absolute value of the matrix or */ /* vector Z */ /* NZ is the maximum number of nonzeros in any row of A, plus 1 */ /* EPS is machine epsilon */ /* The i-th component of f2c_abs(R)+NZ*EPS*(f2c_abs(A)*f2c_abs(X)+f2c_abs(B)) */ /* is incremented by SAFE1 if the i-th component of */ /* f2c_abs(A)*f2c_abs(X) + f2c_abs(B) is less than SAFE2. */ /* Use CLACN2 to estimate the infinity-norm of the matrix */ /* inv(A) * diag(W), */ /* where W = f2c_abs(R) + NZ*EPS*( f2c_abs(A)*f2c_abs(X)+f2c_abs(B) ))) */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + nz * eps * rwork[i__] ; } else { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&work[i__]), f2c_abs(r__2)) + nz * eps * rwork[i__] + safe1; } /* L90: */ } kase = 0; L100: clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(A**H). */ chetrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r; q__1.i = rwork[i__4] * work[i__5].i; // , expr subst work[i__3].r = q__1.r; work[i__3].i = q__1.i; // , expr subst /* L110: */ } } else if (kase == 2) { /* Multiply by inv(A)*diag(W). */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r; q__1.i = rwork[i__4] * work[i__5].i; // , expr subst work[i__3].r = q__1.r; work[i__3].i = q__1.i; // , expr subst /* L120: */ } chetrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } goto L100; } /* Normalize error. */ lstres = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__3 = i__ + j * x_dim1; r__3 = lstres; r__4 = (r__1 = x[i__3].r, f2c_abs(r__1)) + (r__2 = r_imag(&x[i__ + j * x_dim1]), f2c_abs(r__2)); // , expr subst lstres = max(r__3,r__4); /* L130: */ } if (lstres != 0.f) { ferr[j] /= lstres; } /* L140: */ } return 0; /* End of CHERFS */ }
/* Subroutine */ int ctpcon_(char *norm, char *uplo, char *diag, integer *n, complex *ap, real *rcond, complex *work, real *rwork, integer *info) { /* System generated locals */ integer i__1; real r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer ix, kase, kase1; real scale; extern logical lsame_(char *, char *); integer isave[3]; real anorm; logical upper; extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real *, integer *, integer *); real xnorm; extern integer icamax_(integer *, complex *, integer *); extern real slamch_(char *); extern /* Subroutine */ int xerbla_(char *, integer *); extern real clantp_(char *, char *, char *, integer *, complex *, real *); extern /* Subroutine */ int clatps_(char *, char *, char *, char *, integer *, complex *, complex *, real *, real *, integer *); real ainvnm; extern /* Subroutine */ int csrscl_(integer *, real *, complex *, integer *); logical onenrm; char normin[1]; real smlnum; logical nounit; /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --rwork; --work; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); nounit = lsame_(diag, "N"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (! upper && ! lsame_(uplo, "L")) { *info = -2; } else if (! nounit && ! lsame_(diag, "U")) { *info = -3; } else if (*n < 0) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CTPCON", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { *rcond = 1.f; return 0; } *rcond = 0.f; smlnum = slamch_("Safe minimum") * (real) max(1,*n); /* Compute the norm of the triangular matrix A. */ anorm = clantp_(norm, uplo, diag, n, &ap[1], &rwork[1]); /* Continue only if ANORM > 0. */ if (anorm > 0.f) { /* Estimate the norm of the inverse of A. */ ainvnm = 0.f; *(unsigned char *)normin = 'N'; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(A). */ clatps_(uplo, "No transpose", diag, normin, n, &ap[1], &work[ 1], &scale, &rwork[1], info); } else { /* Multiply by inv(A**H). */ clatps_(uplo, "Conjugate transpose", diag, normin, n, &ap[1], &work[1], &scale, &rwork[1], info); } *(unsigned char *)normin = 'Y'; /* Multiply by 1/SCALE if doing so will not cause overflow. */ if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; xnorm = (r__1 = work[i__1].r, abs(r__1)) + (r__2 = r_imag(& work[ix]), abs(r__2)); if (scale < xnorm * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / anorm / ainvnm; } } L20: return 0; /* End of CTPCON */ }
int csycon_(char *uplo, int *n, complex *a, int *lda, int *ipiv, float *anorm, float *rcond, complex *work, int * info) { /* System generated locals */ int a_dim1, a_offset, i__1, i__2; /* Local variables */ int i__, kase; extern int lsame_(char *, char *); int isave[3]; int upper; extern int clacn2_(int *, complex *, complex *, float *, int *, int *), xerbla_(char *, int *); float ainvnm; extern int csytrs_(char *, int *, int *, complex *, int *, int *, complex *, int *, int *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CSYCON estimates the reciprocal of the condition number (in the */ /* 1-norm) of a complex symmetric matrix A using the factorization */ /* A = U*D*U**T or A = L*D*L**T computed by CSYTRF. */ /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ /* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* Specifies whether the details of the factorization are stored */ /* as an upper or lower triangular matrix. */ /* = 'U': Upper triangular, form is A = U*D*U**T; */ /* = 'L': Lower triangular, form is A = L*D*L**T. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The block diagonal matrix D and the multipliers used to */ /* obtain the factor U or L as computed by CSYTRF. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= MAX(1,N). */ /* IPIV (input) INTEGER array, dimension (N) */ /* Details of the interchanges and the block structure of D */ /* as determined by CSYTRF. */ /* ANORM (input) REAL */ /* The 1-norm of the original matrix A. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an */ /* estimate of the 1-norm of inv(A) computed in this routine. */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --ipiv; --work; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX(1,*n)) { *info = -4; } else if (*anorm < 0.f) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("CSYCON", &i__1); return 0; } /* Quick return if possible */ *rcond = 0.f; if (*n == 0) { *rcond = 1.f; return 0; } else if (*anorm <= 0.f) { return 0; } /* Check that the diagonal matrix D is nonsingular. */ if (upper) { /* Upper triangular storage: examine D from bottom to top */ for (i__ = *n; i__ >= 1; --i__) { i__1 = i__ + i__ * a_dim1; if (ipiv[i__] > 0 && (a[i__1].r == 0.f && a[i__1].i == 0.f)) { return 0; } /* L10: */ } } else { /* Lower triangular storage: examine D from top to bottom. */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__ + i__ * a_dim1; if (ipiv[i__] > 0 && (a[i__2].r == 0.f && a[i__2].i == 0.f)) { return 0; } /* L20: */ } } /* Estimate the 1-norm of the inverse. */ kase = 0; L30: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { /* Multiply by inv(L*D*L') or inv(U*D*U'). */ csytrs_(uplo, n, &c__1, &a[a_offset], lda, &ipiv[1], &work[1], n, info); goto L30; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / ainvnm / *anorm; } return 0; /* End of CSYCON */ } /* csycon_ */
/* Subroutine */ int csyrfs_(char *uplo, integer *n, integer *nrhs, complex * a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex * b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4; complex q__1; /* Builtin functions */ double r_imag(complex *); /* Local variables */ integer i__, j, k; real s, xk; integer nz; real eps; integer kase; real safe1, safe2; extern logical lsame_(char *, char *); integer isave[3]; extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, complex *, integer *), caxpy_(integer *, complex *, complex *, integer *, complex *, integer *); integer count; logical upper; extern /* Subroutine */ int csymv_(char *, integer *, complex *, complex * , integer *, complex *, integer *, complex *, complex *, integer * ), clacn2_(integer *, complex *, complex *, real *, integer *, integer *); extern doublereal slamch_(char *); real safmin; extern /* Subroutine */ int xerbla_(char *, integer *); real lstres; extern /* Subroutine */ int csytrs_(char *, integer *, integer *, complex *, integer *, integer *, complex *, integer *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CSYRFS improves the computed solution to a system of linear */ /* equations when the coefficient matrix is symmetric indefinite, and */ /* provides error bounds and backward error estimates for the solution. */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* NRHS (input) INTEGER */ /* The number of right hand sides, i.e., the number of columns */ /* of the matrices B and X. NRHS >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The symmetric matrix A. If UPLO = 'U', the leading N-by-N */ /* upper triangular part of A contains the upper triangular part */ /* of the matrix A, and the strictly lower triangular part of A */ /* is not referenced. If UPLO = 'L', the leading N-by-N lower */ /* triangular part of A contains the lower triangular part of */ /* the matrix A, and the strictly upper triangular part of A is */ /* not referenced. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* AF (input) COMPLEX array, dimension (LDAF,N) */ /* The factored form of the matrix A. AF contains the block */ /* diagonal matrix D and the multipliers used to obtain the */ /* factor U or L from the factorization A = U*D*U**T or */ /* A = L*D*L**T as computed by CSYTRF. */ /* LDAF (input) INTEGER */ /* The leading dimension of the array AF. LDAF >= max(1,N). */ /* IPIV (input) INTEGER array, dimension (N) */ /* Details of the interchanges and the block structure of D */ /* as determined by CSYTRF. */ /* B (input) COMPLEX array, dimension (LDB,NRHS) */ /* The right hand side matrix B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* X (input/output) COMPLEX array, dimension (LDX,NRHS) */ /* On entry, the solution matrix X, as computed by CSYTRS. */ /* On exit, the improved solution matrix X. */ /* LDX (input) INTEGER */ /* The leading dimension of the array X. LDX >= max(1,N). */ /* FERR (output) REAL array, dimension (NRHS) */ /* The estimated forward error bound for each solution vector */ /* X(j) (the j-th column of the solution matrix X). */ /* If XTRUE is the true solution corresponding to X(j), FERR(j) */ /* is an estimated upper bound for the magnitude of the largest */ /* element in (X(j) - XTRUE) divided by the magnitude of the */ /* largest element in X(j). The estimate is as reliable as */ /* the estimate for RCOND, and is almost always a slight */ /* overestimate of the true error. */ /* BERR (output) REAL array, dimension (NRHS) */ /* The componentwise relative backward error of each solution */ /* vector X(j) (i.e., the smallest relative change in */ /* any element of A or B that makes X(j) an exact solution). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* Internal Parameters */ /* =================== */ /* ITMAX is the maximum number of steps of iterative refinement. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; af_dim1 = *ldaf; af_offset = 1 + af_dim1; af -= af_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --ferr; --berr; --work; --rwork; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*nrhs < 0) { *info = -3; } else if (*lda < max(1,*n)) { *info = -5; } else if (*ldaf < max(1,*n)) { *info = -7; } else if (*ldb < max(1,*n)) { *info = -10; } else if (*ldx < max(1,*n)) { *info = -12; } if (*info != 0) { i__1 = -(*info); xerbla_("CSYRFS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ferr[j] = 0.f; berr[j] = 0.f; /* L10: */ } return 0; } /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ nz = *n + 1; eps = slamch_("Epsilon"); safmin = slamch_("Safe minimum"); safe1 = nz * safmin; safe2 = safe1 / eps; /* Do for each right hand side */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { count = 1; lstres = 3.f; L20: /* Loop until stopping criterion is satisfied. */ /* Compute residual R = B - A * X */ ccopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1); q__1.r = -1.f, q__1.i = -0.f; csymv_(uplo, n, &q__1, &a[a_offset], lda, &x[j * x_dim1 + 1], &c__1, & c_b1, &work[1], &c__1); /* Compute componentwise relative backward error from formula */ /* max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) ) */ /* where abs(Z) is the componentwise absolute value of the matrix */ /* or vector Z. If the i-th component of the denominator is less */ /* than SAFE2, then SAFE1 is added to the i-th components of the */ /* numerator and denominator before dividing. */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; rwork[i__] = (r__1 = b[i__3].r, dabs(r__1)) + (r__2 = r_imag(&b[ i__ + j * b_dim1]), dabs(r__2)); /* L30: */ } /* Compute abs(A)*abs(X) + abs(B). */ if (upper) { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[k + j * x_dim1]), dabs(r__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), dabs(r__2))) * xk; i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[ i__ + k * a_dim1]), dabs(r__2))) * ((r__3 = x[ i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))); /* L40: */ } i__3 = k + k * a_dim1; rwork[k] = rwork[k] + ((r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[k + k * a_dim1]), dabs(r__2))) * xk + s; /* L50: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { s = 0.f; i__3 = k + j * x_dim1; xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[k + j * x_dim1]), dabs(r__2)); i__3 = k + k * a_dim1; rwork[k] += ((r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(& a[k + k * a_dim1]), dabs(r__2))) * xk; i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = i__ + k * a_dim1; rwork[i__] += ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[i__ + k * a_dim1]), dabs(r__2))) * xk; i__4 = i__ + k * a_dim1; i__5 = i__ + j * x_dim1; s += ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[ i__ + k * a_dim1]), dabs(r__2))) * ((r__3 = x[ i__5].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ + j * x_dim1]), dabs(r__4))); /* L60: */ } rwork[k] += s; /* L70: */ } } s = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__3 = i__; r__3 = s, r__4 = ((r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2))) / rwork[i__]; s = dmax(r__3,r__4); } else { /* Computing MAX */ i__3 = i__; r__3 = s, r__4 = ((r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + safe1) / (rwork[i__] + safe1); s = dmax(r__3,r__4); } /* L80: */ } berr[j] = s; /* Test stopping criterion. Continue iterating if */ /* 1) The residual BERR(J) is larger than machine epsilon, and */ /* 2) BERR(J) decreased by at least a factor of 2 during the */ /* last iteration, and */ /* 3) At most ITMAX iterations tried. */ if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) { /* Update solution and try again. */ csytrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[1], n, info); caxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1); lstres = berr[j]; ++count; goto L20; } /* Bound error from formula */ /* norm(X - XTRUE) / norm(X) .le. FERR = */ /* norm( abs(inv(A))* */ /* ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X) */ /* where */ /* norm(Z) is the magnitude of the largest component of Z */ /* inv(A) is the inverse of A */ /* abs(Z) is the componentwise absolute value of the matrix or */ /* vector Z */ /* NZ is the maximum number of nonzeros in any row of A, plus 1 */ /* EPS is machine epsilon */ /* The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B)) */ /* is incremented by SAFE1 if the i-th component of */ /* abs(A)*abs(X) + abs(B) is less than SAFE2. */ /* Use CLACN2 to estimate the infinity-norm of the matrix */ /* inv(A) * diag(W), */ /* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__]; } else { i__3 = i__; rwork[i__] = (r__1 = work[i__3].r, dabs(r__1)) + (r__2 = r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[ i__] + safe1; } /* L90: */ } kase = 0; L100: clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(A'). */ csytrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r, q__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* L110: */ } } else if (kase == 2) { /* Multiply by inv(A)*diag(W). */ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = i__; q__1.r = rwork[i__4] * work[i__5].r, q__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* L120: */ } csytrs_(uplo, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[ 1], n, info); } goto L100; } /* Normalize error. */ lstres = 0.f; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__3 = i__ + j * x_dim1; r__3 = lstres, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[i__ + j * x_dim1]), dabs(r__2)); lstres = dmax(r__3,r__4); /* L130: */ } if (lstres != 0.f) { ferr[j] /= lstres; } /* L140: */ } return 0; /* End of CSYRFS */ } /* csyrfs_ */
int ctpcon_(char *norm, char *uplo, char *diag, int *n, complex *ap, float *rcond, complex *work, float *rwork, int *info) { /* System generated locals */ int i__1; float r__1, r__2; /* Builtin functions */ double r_imag(complex *); /* Local variables */ int ix, kase, kase1; float scale; extern int lsame_(char *, char *); int isave[3]; float anorm; int upper; extern int clacn2_(int *, complex *, complex *, float *, int *, int *); float xnorm; extern int icamax_(int *, complex *, int *); extern double slamch_(char *); extern int xerbla_(char *, int *); extern double clantp_(char *, char *, char *, int *, complex *, float *); extern int clatps_(char *, char *, char *, char *, int *, complex *, complex *, float *, float *, int *); float ainvnm; extern int csrscl_(int *, float *, complex *, int *); int onenrm; char normin[1]; float smlnum; int nounit; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTPCON estimates the reciprocal of the condition number of a packed */ /* triangular matrix A, in either the 1-norm or the infinity-norm. */ /* The norm of A is computed and an estimate is obtained for */ /* norm(inv(A)), then the reciprocal of the condition number is */ /* computed as */ /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */ /* Arguments */ /* ========= */ /* NORM (input) CHARACTER*1 */ /* Specifies whether the 1-norm condition number or the */ /* infinity-norm condition number is required: */ /* = '1' or 'O': 1-norm; */ /* = 'I': Infinity-norm. */ /* UPLO (input) CHARACTER*1 */ /* = 'U': A is upper triangular; */ /* = 'L': A is lower triangular. */ /* DIAG (input) CHARACTER*1 */ /* = 'N': A is non-unit triangular; */ /* = 'U': A is unit triangular. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* AP (input) COMPLEX array, dimension (N*(N+1)/2) */ /* The upper or lower triangular matrix A, packed columnwise in */ /* a linear array. The j-th column of A is stored in the array */ /* AP as follows: */ /* if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; */ /* if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n. */ /* If DIAG = 'U', the diagonal elements of A are not referenced */ /* and are assumed to be 1. */ /* RCOND (output) REAL */ /* The reciprocal of the condition number of the matrix A, */ /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */ /* WORK (workspace) COMPLEX array, dimension (2*N) */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --rwork; --work; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O"); nounit = lsame_(diag, "N"); if (! onenrm && ! lsame_(norm, "I")) { *info = -1; } else if (! upper && ! lsame_(uplo, "L")) { *info = -2; } else if (! nounit && ! lsame_(diag, "U")) { *info = -3; } else if (*n < 0) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CTPCON", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { *rcond = 1.f; return 0; } *rcond = 0.f; smlnum = slamch_("Safe minimum") * (float) MAX(1,*n); /* Compute the norm of the triangular matrix A. */ anorm = clantp_(norm, uplo, diag, n, &ap[1], &rwork[1]); /* Continue only if ANORM > 0. */ if (anorm > 0.f) { /* Estimate the norm of the inverse of A. */ ainvnm = 0.f; *(unsigned char *)normin = 'N'; if (onenrm) { kase1 = 1; } else { kase1 = 2; } kase = 0; L10: clacn2_(n, &work[*n + 1], &work[1], &ainvnm, &kase, isave); if (kase != 0) { if (kase == kase1) { /* Multiply by inv(A). */ clatps_(uplo, "No transpose", diag, normin, n, &ap[1], &work[ 1], &scale, &rwork[1], info); } else { /* Multiply by inv(A'). */ clatps_(uplo, "Conjugate transpose", diag, normin, n, &ap[1], &work[1], &scale, &rwork[1], info); } *(unsigned char *)normin = 'Y'; /* Multiply by 1/SCALE if doing so will not cause overflow. */ if (scale != 1.f) { ix = icamax_(n, &work[1], &c__1); i__1 = ix; xnorm = (r__1 = work[i__1].r, ABS(r__1)) + (r__2 = r_imag(& work[ix]), ABS(r__2)); if (scale < xnorm * smlnum || scale == 0.f) { goto L20; } csrscl_(n, &scale, &work[1], &c__1); } goto L10; } /* Compute the estimate of the reciprocal condition number. */ if (ainvnm != 0.f) { *rcond = 1.f / anorm / ainvnm; } } L20: return 0; /* End of CTPCON */ } /* ctpcon_ */