00001 /* zptcon.f -- translated by f2c (version 20061008). 00002 You must link the resulting object file with libf2c: 00003 on Microsoft Windows system, link with libf2c.lib; 00004 on Linux or Unix systems, link with .../path/to/libf2c.a -lm 00005 or, if you install libf2c.a in a standard place, with -lf2c -lm 00006 -- in that order, at the end of the command line, as in 00007 cc *.o -lf2c -lm 00008 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., 00009 00010 http://www.netlib.org/f2c/libf2c.zip 00011 */ 00012 00013 #include "f2c.h" 00014 #include "blaswrap.h" 00015 00016 /* Table of constant values */ 00017 00018 static integer c__1 = 1; 00019 00020 /* Subroutine */ int zptcon_(integer *n, doublereal *d__, doublecomplex *e, 00021 doublereal *anorm, doublereal *rcond, doublereal *rwork, integer * 00022 info) 00023 { 00024 /* System generated locals */ 00025 integer i__1; 00026 doublereal d__1; 00027 00028 /* Builtin functions */ 00029 double z_abs(doublecomplex *); 00030 00031 /* Local variables */ 00032 integer i__, ix; 00033 extern integer idamax_(integer *, doublereal *, integer *); 00034 extern /* Subroutine */ int xerbla_(char *, integer *); 00035 doublereal ainvnm; 00036 00037 00038 /* -- LAPACK routine (version 3.2) -- */ 00039 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00040 /* November 2006 */ 00041 00042 /* .. Scalar Arguments .. */ 00043 /* .. */ 00044 /* .. Array Arguments .. */ 00045 /* .. */ 00046 00047 /* Purpose */ 00048 /* ======= */ 00049 00050 /* ZPTCON computes the reciprocal of the condition number (in the */ 00051 /* 1-norm) of a complex Hermitian positive definite tridiagonal matrix */ 00052 /* using the factorization A = L*D*L**H or A = U**H*D*U computed by */ 00053 /* ZPTTRF. */ 00054 00055 /* Norm(inv(A)) is computed by a direct method, and the reciprocal of */ 00056 /* the condition number is computed as */ 00057 /* RCOND = 1 / (ANORM * norm(inv(A))). */ 00058 00059 /* Arguments */ 00060 /* ========= */ 00061 00062 /* N (input) INTEGER */ 00063 /* The order of the matrix A. N >= 0. */ 00064 00065 /* D (input) DOUBLE PRECISION array, dimension (N) */ 00066 /* The n diagonal elements of the diagonal matrix D from the */ 00067 /* factorization of A, as computed by ZPTTRF. */ 00068 00069 /* E (input) COMPLEX*16 array, dimension (N-1) */ 00070 /* The (n-1) off-diagonal elements of the unit bidiagonal factor */ 00071 /* U or L from the factorization of A, as computed by ZPTTRF. */ 00072 00073 /* ANORM (input) DOUBLE PRECISION */ 00074 /* The 1-norm of the original matrix A. */ 00075 00076 /* RCOND (output) DOUBLE PRECISION */ 00077 /* The reciprocal of the condition number of the matrix A, */ 00078 /* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is the */ 00079 /* 1-norm of inv(A) computed in this routine. */ 00080 00081 /* RWORK (workspace) DOUBLE PRECISION array, dimension (N) */ 00082 00083 /* INFO (output) INTEGER */ 00084 /* = 0: successful exit */ 00085 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00086 00087 /* Further Details */ 00088 /* =============== */ 00089 00090 /* The method used is described in Nicholas J. Higham, "Efficient */ 00091 /* Algorithms for Computing the Condition Number of a Tridiagonal */ 00092 /* Matrix", SIAM J. Sci. Stat. Comput., Vol. 7, No. 1, January 1986. */ 00093 00094 /* ===================================================================== */ 00095 00096 /* .. Parameters .. */ 00097 /* .. */ 00098 /* .. Local Scalars .. */ 00099 /* .. */ 00100 /* .. External Functions .. */ 00101 /* .. */ 00102 /* .. External Subroutines .. */ 00103 /* .. */ 00104 /* .. Intrinsic Functions .. */ 00105 /* .. */ 00106 /* .. Executable Statements .. */ 00107 00108 /* Test the input arguments. */ 00109 00110 /* Parameter adjustments */ 00111 --rwork; 00112 --e; 00113 --d__; 00114 00115 /* Function Body */ 00116 *info = 0; 00117 if (*n < 0) { 00118 *info = -1; 00119 } else if (*anorm < 0.) { 00120 *info = -4; 00121 } 00122 if (*info != 0) { 00123 i__1 = -(*info); 00124 xerbla_("ZPTCON", &i__1); 00125 return 0; 00126 } 00127 00128 /* Quick return if possible */ 00129 00130 *rcond = 0.; 00131 if (*n == 0) { 00132 *rcond = 1.; 00133 return 0; 00134 } else if (*anorm == 0.) { 00135 return 0; 00136 } 00137 00138 /* Check that D(1:N) is positive. */ 00139 00140 i__1 = *n; 00141 for (i__ = 1; i__ <= i__1; ++i__) { 00142 if (d__[i__] <= 0.) { 00143 return 0; 00144 } 00145 /* L10: */ 00146 } 00147 00148 /* Solve M(A) * x = e, where M(A) = (m(i,j)) is given by */ 00149 00150 /* m(i,j) = abs(A(i,j)), i = j, */ 00151 /* m(i,j) = -abs(A(i,j)), i .ne. j, */ 00152 00153 /* and e = [ 1, 1, ..., 1 ]'. Note M(A) = M(L)*D*M(L)'. */ 00154 00155 /* Solve M(L) * x = e. */ 00156 00157 rwork[1] = 1.; 00158 i__1 = *n; 00159 for (i__ = 2; i__ <= i__1; ++i__) { 00160 rwork[i__] = rwork[i__ - 1] * z_abs(&e[i__ - 1]) + 1.; 00161 /* L20: */ 00162 } 00163 00164 /* Solve D * M(L)' * x = b. */ 00165 00166 rwork[*n] /= d__[*n]; 00167 for (i__ = *n - 1; i__ >= 1; --i__) { 00168 rwork[i__] = rwork[i__] / d__[i__] + rwork[i__ + 1] * z_abs(&e[i__]); 00169 /* L30: */ 00170 } 00171 00172 /* Compute AINVNM = max(x(i)), 1<=i<=n. */ 00173 00174 ix = idamax_(n, &rwork[1], &c__1); 00175 ainvnm = (d__1 = rwork[ix], abs(d__1)); 00176 00177 /* Compute the reciprocal condition number. */ 00178 00179 if (ainvnm != 0.) { 00180 *rcond = 1. / ainvnm / *anorm; 00181 } 00182 00183 return 0; 00184 00185 /* End of ZPTCON */ 00186 00187 } /* zptcon_ */