int f2c_ztpsv(char* uplo, char* trans, char* diag, integer* N, doublecomplex* Ap, doublecomplex* X, integer* incX) { ztpsv_(uplo, trans, diag, N, Ap, X, incX); return 0; }
void ztpsv(char uplo, char transa, char diag, int n, doublecomplex *ap, doublecomplex *x, int incx) { ztpsv_( &uplo, &transa, &diag, &n, ap, x, &incx); }
/* Subroutine */ int zlatps_(char *uplo, char *trans, char *diag, char * normin, integer *n, doublecomplex *ap, doublecomplex *x, doublereal * scale, doublereal *cnorm, integer *info) { /* System generated locals */ integer i__1, i__2, i__3, i__4, i__5; doublereal d__1, d__2, d__3, d__4; doublecomplex z__1, z__2, z__3, z__4; /* Builtin functions */ double d_imag(doublecomplex *); void d_cnjg(doublecomplex *, doublecomplex *); /* Local variables */ integer i__, j, ip; doublereal xj, rec, tjj; integer jinc, jlen; doublereal xbnd; integer imax; doublereal tmax; doublecomplex tjjs; doublereal xmax, grow; extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *, integer *); extern logical lsame_(char *, char *); doublereal tscal; doublecomplex uscal; integer jlast; doublecomplex csumj; extern /* Double Complex */ VOID zdotc_f2c_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); logical upper; extern /* Double Complex */ VOID zdotu_f2c_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); extern /* Subroutine */ int zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *), ztpsv_( char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), dlabad_(doublereal *, doublereal *); extern doublereal dlamch_(char *); extern integer idamax_(integer *, doublereal *, integer *); extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_( integer *, doublereal *, doublecomplex *, integer *); doublereal bignum; extern integer izamax_(integer *, doublecomplex *, integer *); extern /* Double Complex */ VOID zladiv_(doublecomplex *, doublecomplex *, doublecomplex *); logical notran; integer jfirst; extern doublereal dzasum_(integer *, doublecomplex *, integer *); doublereal smlnum; logical nounit; /* -- LAPACK auxiliary 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 .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ --cnorm; --x; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); notran = lsame_(trans, "N"); nounit = lsame_(diag, "N"); /* Test the input parameters. */ 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 (! lsame_(normin, "Y") && ! lsame_(normin, "N")) { *info = -4; } else if (*n < 0) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("ZLATPS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine machine dependent parameters to control overflow. */ smlnum = dlamch_("Safe minimum"); bignum = 1. / smlnum; dlabad_(&smlnum, &bignum); smlnum /= dlamch_("Precision"); bignum = 1. / smlnum; *scale = 1.; if (lsame_(normin, "N")) { /* Compute the 1-norm of each column, not including the diagonal. */ if (upper) { /* A is upper triangular. */ ip = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; cnorm[j] = dzasum_(&i__2, &ap[ip], &c__1); ip += j; /* L10: */ } } else { /* A is lower triangular. */ ip = 1; i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { i__2 = *n - j; cnorm[j] = dzasum_(&i__2, &ap[ip + 1], &c__1); ip = ip + *n - j + 1; /* L20: */ } cnorm[*n] = 0.; } } /* Scale the column norms by TSCAL if the maximum element in CNORM is */ /* greater than BIGNUM/2. */ imax = idamax_(n, &cnorm[1], &c__1); tmax = cnorm[imax]; if (tmax <= bignum * .5) { tscal = 1.; } else { tscal = .5 / (smlnum * tmax); dscal_(n, &tscal, &cnorm[1], &c__1); } /* Compute a bound on the computed solution vector to see if the */ /* Level 2 BLAS routine ZTPSV can be used. */ xmax = 0.; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = j; d__3 = xmax; d__4 = (d__1 = x[i__2].r / 2., abs(d__1)) + (d__2 = d_imag(&x[j]) / 2., abs(d__2)); // , expr subst xmax = max(d__3,d__4); /* L30: */ } xbnd = xmax; if (notran) { /* Compute the growth in A * x = b. */ if (upper) { jfirst = *n; jlast = 1; jinc = -1; } else { jfirst = 1; jlast = *n; jinc = 1; } if (tscal != 1.) { grow = 0.; goto L60; } if (nounit) { /* A is non-unit triangular. */ /* Compute GROW = 1/G(j) and XBND = 1/M(j). */ /* Initially, G(0) = max{ x(i), i=1,...,n} . */ grow = .5 / max(xbnd,smlnum); xbnd = grow; ip = jfirst * (jfirst + 1) / 2; jlen = *n; i__1 = jlast; i__2 = jinc; for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Exit the loop if the growth factor is too small. */ if (grow <= smlnum) { goto L60; } i__3 = ip; tjjs.r = ap[i__3].r; tjjs.i = ap[i__3].i; // , expr subst tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj >= smlnum) { /* M(j) = G(j-1) / abs(A(j,j)) */ /* Computing MIN */ d__1 = xbnd; d__2 = min(1.,tjj) * grow; // , expr subst xbnd = min(d__1,d__2); } else { /* M(j) could overflow, set XBND to 0. */ xbnd = 0.; } if (tjj + cnorm[j] >= smlnum) { /* G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) ) */ grow *= tjj / (tjj + cnorm[j]); } else { /* G(j) could overflow, set GROW to 0. */ grow = 0.; } ip += jinc * jlen; --jlen; /* L40: */ } grow = xbnd; } else { /* A is unit triangular. */ /* Compute GROW = 1/G(j), where G(0) = max{ x(i), i=1,...,n} . */ /* Computing MIN */ d__1 = 1.; d__2 = .5 / max(xbnd,smlnum); // , expr subst grow = min(d__1,d__2); i__2 = jlast; i__1 = jinc; for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { /* Exit the loop if the growth factor is too small. */ if (grow <= smlnum) { goto L60; } /* G(j) = G(j-1)*( 1 + CNORM(j) ) */ grow *= 1. / (cnorm[j] + 1.); /* L50: */ } } L60: ; } else { /* Compute the growth in A**T * x = b or A**H * x = b. */ if (upper) { jfirst = 1; jlast = *n; jinc = 1; } else { jfirst = *n; jlast = 1; jinc = -1; } if (tscal != 1.) { grow = 0.; goto L90; } if (nounit) { /* A is non-unit triangular. */ /* Compute GROW = 1/G(j) and XBND = 1/M(j). */ /* Initially, M(0) = max{ x(i), i=1,...,n} . */ grow = .5 / max(xbnd,smlnum); xbnd = grow; ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__1 = jlast; i__2 = jinc; for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Exit the loop if the growth factor is too small. */ if (grow <= smlnum) { goto L90; } /* G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) */ xj = cnorm[j] + 1.; /* Computing MIN */ d__1 = grow; d__2 = xbnd / xj; // , expr subst grow = min(d__1,d__2); i__3 = ip; tjjs.r = ap[i__3].r; tjjs.i = ap[i__3].i; // , expr subst tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj >= smlnum) { /* M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j)) */ if (xj > tjj) { xbnd *= tjj / xj; } } else { /* M(j) could overflow, set XBND to 0. */ xbnd = 0.; } ++jlen; ip += jinc * jlen; /* L70: */ } grow = min(grow,xbnd); } else { /* A is unit triangular. */ /* Compute GROW = 1/G(j), where G(0) = max{ x(i), i=1,...,n} . */ /* Computing MIN */ d__1 = 1.; d__2 = .5 / max(xbnd,smlnum); // , expr subst grow = min(d__1,d__2); i__2 = jlast; i__1 = jinc; for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { /* Exit the loop if the growth factor is too small. */ if (grow <= smlnum) { goto L90; } /* G(j) = ( 1 + CNORM(j) )*G(j-1) */ xj = cnorm[j] + 1.; grow /= xj; /* L80: */ } } L90: ; } if (grow * tscal > smlnum) { /* Use the Level 2 BLAS solve if the reciprocal of the bound on */ /* elements of X is not too small. */ ztpsv_(uplo, trans, diag, n, &ap[1], &x[1], &c__1); } else { /* Use a Level 1 BLAS solve, scaling intermediate results. */ if (xmax > bignum * .5) { /* Scale X so that its components are less than or equal to */ /* BIGNUM in absolute value. */ *scale = bignum * .5 / xmax; zdscal_(n, scale, &x[1], &c__1); xmax = bignum; } else { xmax *= 2.; } if (notran) { /* Solve A * x = b */ ip = jfirst * (jfirst + 1) / 2; i__1 = jlast; i__2 = jinc; for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Compute x(j) = b(j) / A(j,j), scaling x if necessary. */ i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]), abs(d__2)); if (nounit) { i__3 = ip; z__1.r = tscal * ap[i__3].r; z__1.i = tscal * ap[i__3].i; // , expr subst tjjs.r = z__1.r; tjjs.i = z__1.i; // , expr subst } else { tjjs.r = tscal; tjjs.i = 0.; // , expr subst if (tscal == 1.) { goto L110; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale x by 1/b(j). */ rec = 1. / xj; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]) , abs(d__2)); } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM */ /* to avoid overflow when dividing by A(j,j). */ rec = tjj * bignum / xj; if (cnorm[j] > 1.) { /* Scale by 1/CNORM(j) to avoid overflow when */ /* multiplying x(j) times column j. */ rec /= cnorm[j]; } zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]) , abs(d__2)); } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and */ /* scale = 0, and compute a solution to A*x = 0. */ i__3 = *n; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__; x[i__4].r = 0.; x[i__4].i = 0.; // , expr subst /* L100: */ } i__3 = j; x[i__3].r = 1.; x[i__3].i = 0.; // , expr subst xj = 1.; *scale = 0.; xmax = 0.; } L110: /* Scale x if necessary to avoid overflow when adding a */ /* multiple of column j of A. */ if (xj > 1.) { rec = 1. / xj; if (cnorm[j] > (bignum - xmax) * rec) { /* Scale x by 1/(2*abs(x(j))). */ rec *= .5; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; } } else if (xj * cnorm[j] > bignum - xmax) { /* Scale x by 1/2. */ zdscal_(n, &c_b36, &x[1], &c__1); *scale *= .5; } if (upper) { if (j > 1) { /* Compute the update */ /* x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j) */ i__3 = j - 1; i__4 = j; z__2.r = -x[i__4].r; z__2.i = -x[i__4].i; // , expr subst z__1.r = tscal * z__2.r; z__1.i = tscal * z__2.i; // , expr subst zaxpy_(&i__3, &z__1, &ap[ip - j + 1], &c__1, &x[1], & c__1); i__3 = j - 1; i__ = izamax_(&i__3, &x[1], &c__1); i__3 = i__; xmax = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag( &x[i__]), abs(d__2)); } ip -= j; } else { if (j < *n) { /* Compute the update */ /* x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j) */ i__3 = *n - j; i__4 = j; z__2.r = -x[i__4].r; z__2.i = -x[i__4].i; // , expr subst z__1.r = tscal * z__2.r; z__1.i = tscal * z__2.i; // , expr subst zaxpy_(&i__3, &z__1, &ap[ip + 1], &c__1, &x[j + 1], & c__1); i__3 = *n - j; i__ = j + izamax_(&i__3, &x[j + 1], &c__1); i__3 = i__; xmax = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag( &x[i__]), abs(d__2)); } ip = ip + *n - j + 1; } /* L120: */ } } else if (lsame_(trans, "T")) { /* Solve A**T * x = b */ ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__2 = jlast; i__1 = jinc; for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { /* Compute x(j) = b(j) - sum A(k,j)*x(k). */ /* k<>j */ i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]), abs(d__2)); uscal.r = tscal; uscal.i = 0.; // , expr subst rec = 1. / max(xmax,1.); if (cnorm[j] > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2*XMAX). */ rec *= .5; if (nounit) { i__3 = ip; z__1.r = tscal * ap[i__3].r; z__1.i = tscal * ap[i__3] .i; // , expr subst tjjs.r = z__1.r; tjjs.i = z__1.i; // , expr subst } else { tjjs.r = tscal; tjjs.i = 0.; // , expr subst } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > 1.) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. */ /* Computing MIN */ d__1 = 1.; d__2 = rec * tjj; // , expr subst rec = min(d__1,d__2); zladiv_(&z__1, &uscal, &tjjs); uscal.r = z__1.r; uscal.i = z__1.i; // , expr subst } if (rec < 1.) { zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0.; csumj.i = 0.; // , expr subst if (uscal.r == 1. && uscal.i == 0.) { /* If the scaling needed for A in the dot product is 1, */ /* call ZDOTU to perform the dot product. */ if (upper) { i__3 = j - 1; zdotu_f2c_(&z__1, &i__3, &ap[ip - j + 1], &c__1, &x[1], & c__1); csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst } else if (j < *n) { i__3 = *n - j; zdotu_f2c_(&z__1, &i__3, &ap[ip + 1], &c__1, &x[j + 1], & c__1); csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst } } else { /* Otherwise, use in-line code for the dot product. */ if (upper) { i__3 = j - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = ip - j + i__; z__3.r = ap[i__4].r * uscal.r - ap[i__4].i * uscal.i; z__3.i = ap[i__4].r * uscal.i + ap[i__4].i * uscal.r; // , expr subst i__5 = i__; z__2.r = z__3.r * x[i__5].r - z__3.i * x[i__5].i; z__2.i = z__3.r * x[i__5].i + z__3.i * x[ i__5].r; // , expr subst z__1.r = csumj.r + z__2.r; z__1.i = csumj.i + z__2.i; // , expr subst csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst /* L130: */ } } else if (j < *n) { i__3 = *n - j; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = ip + i__; z__3.r = ap[i__4].r * uscal.r - ap[i__4].i * uscal.i; z__3.i = ap[i__4].r * uscal.i + ap[i__4].i * uscal.r; // , expr subst i__5 = j + i__; z__2.r = z__3.r * x[i__5].r - z__3.i * x[i__5].i; z__2.i = z__3.r * x[i__5].i + z__3.i * x[ i__5].r; // , expr subst z__1.r = csumj.r + z__2.r; z__1.i = csumj.i + z__2.i; // , expr subst csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst /* L140: */ } } } z__1.r = tscal; z__1.i = 0.; // , expr subst if (uscal.r == z__1.r && uscal.i == z__1.i) { /* Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j) */ /* was not used to scale the dotproduct. */ i__3 = j; i__4 = j; z__1.r = x[i__4].r - csumj.r; z__1.i = x[i__4].i - csumj.i; // , expr subst x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]) , abs(d__2)); if (nounit) { /* Compute x(j) = x(j) / A(j,j), scaling if necessary. */ i__3 = ip; z__1.r = tscal * ap[i__3].r; z__1.i = tscal * ap[i__3] .i; // , expr subst tjjs.r = z__1.r; tjjs.i = z__1.i; // , expr subst } else { tjjs.r = tscal; tjjs.i = 0.; // , expr subst if (tscal == 1.) { goto L160; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale X by 1/abs(x(j)). */ rec = 1. / xj; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM. */ rec = tjj * bignum / xj; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and */ /* scale = 0 and compute a solution to A**T *x = 0. */ i__3 = *n; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__; x[i__4].r = 0.; x[i__4].i = 0.; // , expr subst /* L150: */ } i__3 = j; x[i__3].r = 1.; x[i__3].i = 0.; // , expr subst *scale = 0.; xmax = 0.; } L160: ; } else { /* Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot */ /* product has already been divided by 1/A(j,j). */ i__3 = j; zladiv_(&z__2, &x[j], &tjjs); z__1.r = z__2.r - csumj.r; z__1.i = z__2.i - csumj.i; // , expr subst x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } /* Computing MAX */ i__3 = j; d__3 = xmax; d__4 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]), abs(d__2)); // , expr subst xmax = max(d__3,d__4); ++jlen; ip += jinc * jlen; /* L170: */ } } else { /* Solve A**H * x = b */ ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__1 = jlast; i__2 = jinc; for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Compute x(j) = b(j) - sum A(k,j)*x(k). */ /* k<>j */ i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]), abs(d__2)); uscal.r = tscal; uscal.i = 0.; // , expr subst rec = 1. / max(xmax,1.); if (cnorm[j] > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2*XMAX). */ rec *= .5; if (nounit) { d_cnjg(&z__2, &ap[ip]); z__1.r = tscal * z__2.r; z__1.i = tscal * z__2.i; // , expr subst tjjs.r = z__1.r; tjjs.i = z__1.i; // , expr subst } else { tjjs.r = tscal; tjjs.i = 0.; // , expr subst } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > 1.) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. */ /* Computing MIN */ d__1 = 1.; d__2 = rec * tjj; // , expr subst rec = min(d__1,d__2); zladiv_(&z__1, &uscal, &tjjs); uscal.r = z__1.r; uscal.i = z__1.i; // , expr subst } if (rec < 1.) { zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0.; csumj.i = 0.; // , expr subst if (uscal.r == 1. && uscal.i == 0.) { /* If the scaling needed for A in the dot product is 1, */ /* call ZDOTC to perform the dot product. */ if (upper) { i__3 = j - 1; zdotc_f2c_(&z__1, &i__3, &ap[ip - j + 1], &c__1, &x[1], & c__1); csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst } else if (j < *n) { i__3 = *n - j; zdotc_f2c_(&z__1, &i__3, &ap[ip + 1], &c__1, &x[j + 1], & c__1); csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst } } else { /* Otherwise, use in-line code for the dot product. */ if (upper) { i__3 = j - 1; for (i__ = 1; i__ <= i__3; ++i__) { d_cnjg(&z__4, &ap[ip - j + i__]); z__3.r = z__4.r * uscal.r - z__4.i * uscal.i; z__3.i = z__4.r * uscal.i + z__4.i * uscal.r; // , expr subst i__4 = i__; z__2.r = z__3.r * x[i__4].r - z__3.i * x[i__4].i; z__2.i = z__3.r * x[i__4].i + z__3.i * x[ i__4].r; // , expr subst z__1.r = csumj.r + z__2.r; z__1.i = csumj.i + z__2.i; // , expr subst csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst /* L180: */ } } else if (j < *n) { i__3 = *n - j; for (i__ = 1; i__ <= i__3; ++i__) { d_cnjg(&z__4, &ap[ip + i__]); z__3.r = z__4.r * uscal.r - z__4.i * uscal.i; z__3.i = z__4.r * uscal.i + z__4.i * uscal.r; // , expr subst i__4 = j + i__; z__2.r = z__3.r * x[i__4].r - z__3.i * x[i__4].i; z__2.i = z__3.r * x[i__4].i + z__3.i * x[ i__4].r; // , expr subst z__1.r = csumj.r + z__2.r; z__1.i = csumj.i + z__2.i; // , expr subst csumj.r = z__1.r; csumj.i = z__1.i; // , expr subst /* L190: */ } } } z__1.r = tscal; z__1.i = 0.; // , expr subst if (uscal.r == z__1.r && uscal.i == z__1.i) { /* Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j) */ /* was not used to scale the dotproduct. */ i__3 = j; i__4 = j; z__1.r = x[i__4].r - csumj.r; z__1.i = x[i__4].i - csumj.i; // , expr subst x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst i__3 = j; xj = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]) , abs(d__2)); if (nounit) { /* Compute x(j) = x(j) / A(j,j), scaling if necessary. */ d_cnjg(&z__2, &ap[ip]); z__1.r = tscal * z__2.r; z__1.i = tscal * z__2.i; // , expr subst tjjs.r = z__1.r; tjjs.i = z__1.i; // , expr subst } else { tjjs.r = tscal; tjjs.i = 0.; // , expr subst if (tscal == 1.) { goto L210; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale X by 1/abs(x(j)). */ rec = 1. / xj; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM. */ rec = tjj * bignum / xj; zdscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &x[j], &tjjs); x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and */ /* scale = 0 and compute a solution to A**H *x = 0. */ i__3 = *n; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = i__; x[i__4].r = 0.; x[i__4].i = 0.; // , expr subst /* L200: */ } i__3 = j; x[i__3].r = 1.; x[i__3].i = 0.; // , expr subst *scale = 0.; xmax = 0.; } L210: ; } else { /* Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot */ /* product has already been divided by 1/A(j,j). */ i__3 = j; zladiv_(&z__2, &x[j], &tjjs); z__1.r = z__2.r - csumj.r; z__1.i = z__2.i - csumj.i; // , expr subst x[i__3].r = z__1.r; x[i__3].i = z__1.i; // , expr subst } /* Computing MAX */ i__3 = j; d__3 = xmax; d__4 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[j]), abs(d__2)); // , expr subst xmax = max(d__3,d__4); ++jlen; ip += jinc * jlen; /* L220: */ } } *scale /= tscal; } /* Scale the column norms by 1/TSCAL for return. */ if (tscal != 1.) { d__1 = 1. / tscal; dscal_(n, &d__1, &cnorm[1], &c__1); } return 0; /* End of ZLATPS */ }
/* Subroutine */ int zhpgst_(integer *itype, char *uplo, integer *n, doublecomplex *ap, doublecomplex *bp, integer *info) { /* System generated locals */ integer i__1, i__2, i__3, i__4; doublereal d__1, d__2; doublecomplex z__1, z__2, z__3; /* Local variables */ integer j, k, j1, k1, jj, kk; doublecomplex ct; doublereal ajj; integer j1j1; doublereal akk; integer k1k1; doublereal bjj, bkk; extern /* Subroutine */ int zhpr2_(char *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *); extern logical lsame_(char *, char *); extern /* Double Complex */ VOID zdotc_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); logical upper; extern /* Subroutine */ int zhpmv_(char *, integer *, doublecomplex *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, integer *), zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *), ztpmv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), ztpsv_(char *, char *, char *, integer *, doublecomplex * , doublecomplex *, integer *), xerbla_( char *, integer *), zdscal_(integer *, doublereal *, doublecomplex *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZHPGST reduces a complex Hermitian-definite generalized */ /* eigenproblem to standard form, using packed storage. */ /* If ITYPE = 1, the problem is A*x = lambda*B*x, */ /* and A is overwritten by inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H) */ /* If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or */ /* B*A*x = lambda*x, and A is overwritten by U*A*U**H or L**H*A*L. */ /* B must have been previously factorized as U**H*U or L*L**H by ZPPTRF. */ /* Arguments */ /* ========= */ /* ITYPE (input) INTEGER */ /* = 1: compute inv(U**H)*A*inv(U) or inv(L)*A*inv(L**H); */ /* = 2 or 3: compute U*A*U**H or L**H*A*L. */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored and B is factored as */ /* U**H*U; */ /* = 'L': Lower triangle of A is stored and B is factored as */ /* L*L**H. */ /* N (input) INTEGER */ /* The order of the matrices A and B. N >= 0. */ /* AP (input/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian 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. */ /* On exit, if INFO = 0, the transformed matrix, stored in the */ /* same format as A. */ /* BP (input) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* The triangular factor from the Cholesky factorization of B, */ /* stored in the same format as A, as returned by ZPPTRF. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --bp; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (*itype < 1 || *itype > 3) { *info = -1; } else if (! upper && ! lsame_(uplo, "L")) { *info = -2; } else if (*n < 0) { *info = -3; } if (*info != 0) { i__1 = -(*info); xerbla_("ZHPGST", &i__1); return 0; } if (*itype == 1) { if (upper) { /* Compute inv(U')*A*inv(U) */ /* J1 and JJ are the indices of A(1,j) and A(j,j) */ jj = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { j1 = jj + 1; jj += j; /* Compute the j-th column of the upper triangle of A */ i__2 = jj; i__3 = jj; d__1 = ap[i__3].r; ap[i__2].r = d__1, ap[i__2].i = 0.; i__2 = jj; bjj = bp[i__2].r; ztpsv_(uplo, "Conjugate transpose", "Non-unit", &j, &bp[1], & ap[j1], &c__1); i__2 = j - 1; z__1.r = -1., z__1.i = -0.; zhpmv_(uplo, &i__2, &z__1, &ap[1], &bp[j1], &c__1, &c_b1, &ap[ j1], &c__1); i__2 = j - 1; d__1 = 1. / bjj; zdscal_(&i__2, &d__1, &ap[j1], &c__1); i__2 = jj; i__3 = jj; i__4 = j - 1; zdotc_(&z__3, &i__4, &ap[j1], &c__1, &bp[j1], &c__1); z__2.r = ap[i__3].r - z__3.r, z__2.i = ap[i__3].i - z__3.i; z__1.r = z__2.r / bjj, z__1.i = z__2.i / bjj; ap[i__2].r = z__1.r, ap[i__2].i = z__1.i; /* L10: */ } } else { /* Compute inv(L)*A*inv(L') */ /* KK and K1K1 are the indices of A(k,k) and A(k+1,k+1) */ kk = 1; i__1 = *n; for (k = 1; k <= i__1; ++k) { k1k1 = kk + *n - k + 1; /* Update the lower triangle of A(k:n,k:n) */ i__2 = kk; akk = ap[i__2].r; i__2 = kk; bkk = bp[i__2].r; /* Computing 2nd power */ d__1 = bkk; akk /= d__1 * d__1; i__2 = kk; ap[i__2].r = akk, ap[i__2].i = 0.; if (k < *n) { i__2 = *n - k; d__1 = 1. / bkk; zdscal_(&i__2, &d__1, &ap[kk + 1], &c__1); d__1 = akk * -.5; ct.r = d__1, ct.i = 0.; i__2 = *n - k; zaxpy_(&i__2, &ct, &bp[kk + 1], &c__1, &ap[kk + 1], &c__1) ; i__2 = *n - k; z__1.r = -1., z__1.i = -0.; zhpr2_(uplo, &i__2, &z__1, &ap[kk + 1], &c__1, &bp[kk + 1] , &c__1, &ap[k1k1]); i__2 = *n - k; zaxpy_(&i__2, &ct, &bp[kk + 1], &c__1, &ap[kk + 1], &c__1) ; i__2 = *n - k; ztpsv_(uplo, "No transpose", "Non-unit", &i__2, &bp[k1k1], &ap[kk + 1], &c__1); } kk = k1k1; /* L20: */ } } } else { if (upper) { /* Compute U*A*U' */ /* K1 and KK are the indices of A(1,k) and A(k,k) */ kk = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { k1 = kk + 1; kk += k; /* Update the upper triangle of A(1:k,1:k) */ i__2 = kk; akk = ap[i__2].r; i__2 = kk; bkk = bp[i__2].r; i__2 = k - 1; ztpmv_(uplo, "No transpose", "Non-unit", &i__2, &bp[1], &ap[ k1], &c__1); d__1 = akk * .5; ct.r = d__1, ct.i = 0.; i__2 = k - 1; zaxpy_(&i__2, &ct, &bp[k1], &c__1, &ap[k1], &c__1); i__2 = k - 1; zhpr2_(uplo, &i__2, &c_b1, &ap[k1], &c__1, &bp[k1], &c__1, & ap[1]); i__2 = k - 1; zaxpy_(&i__2, &ct, &bp[k1], &c__1, &ap[k1], &c__1); i__2 = k - 1; zdscal_(&i__2, &bkk, &ap[k1], &c__1); i__2 = kk; /* Computing 2nd power */ d__2 = bkk; d__1 = akk * (d__2 * d__2); ap[i__2].r = d__1, ap[i__2].i = 0.; /* L30: */ } } else { /* Compute L'*A*L */ /* JJ and J1J1 are the indices of A(j,j) and A(j+1,j+1) */ jj = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { j1j1 = jj + *n - j + 1; /* Compute the j-th column of the lower triangle of A */ i__2 = jj; ajj = ap[i__2].r; i__2 = jj; bjj = bp[i__2].r; i__2 = jj; d__1 = ajj * bjj; i__3 = *n - j; zdotc_(&z__2, &i__3, &ap[jj + 1], &c__1, &bp[jj + 1], &c__1); z__1.r = d__1 + z__2.r, z__1.i = z__2.i; ap[i__2].r = z__1.r, ap[i__2].i = z__1.i; i__2 = *n - j; zdscal_(&i__2, &bjj, &ap[jj + 1], &c__1); i__2 = *n - j; zhpmv_(uplo, &i__2, &c_b1, &ap[j1j1], &bp[jj + 1], &c__1, & c_b1, &ap[jj + 1], &c__1); i__2 = *n - j + 1; ztpmv_(uplo, "Conjugate transpose", "Non-unit", &i__2, &bp[jj] , &ap[jj], &c__1); jj = j1j1; /* L40: */ } } } return 0; /* End of ZHPGST */ } /* zhpgst_ */
/* Subroutine */ int ztprfs_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *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; doublereal d__1, d__2, d__3, d__4; doublecomplex z__1; /* Builtin functions */ double d_imag(doublecomplex *); /* Local variables */ integer i__, j, k; doublereal s; integer kc; doublereal xk; integer nz; doublereal eps; integer kase; doublereal safe1, safe2; extern logical lsame_(char *, char *); integer isave[3]; logical upper; extern /* Subroutine */ int zcopy_(integer *, doublecomplex *, integer *, doublecomplex *, integer *), zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *), ztpmv_( char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), zlacn2_(integer *, doublecomplex *, doublecomplex *, doublereal *, integer *, integer *); extern doublereal dlamch_(char *); doublereal safmin; extern /* Subroutine */ int xerbla_(char *, integer *); logical notran; char transn[1], transt[1]; logical nounit; doublereal lstres; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZTPRFS 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 ZTPTRS or some other */ /* means before entering this routine. ZTPRFS 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*16 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*16 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*16 array, dimension (LDX,NRHS) */ /* The solution matrix X. */ /* LDX (input) INTEGER */ /* The leading dimension of the array X. LDX >= max(1,N). */ /* FERR (output) DOUBLE PRECISION 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) DOUBLE PRECISION 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*16 array, dimension (2*N) */ /* RWORK (workspace) DOUBLE PRECISION 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_("ZTPRFS", &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.; berr[j] = 0.; /* 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 = dlamch_("Epsilon"); safmin = dlamch_("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. */ zcopy_(n, &x[j * x_dim1 + 1], &c__1, &work[1], &c__1); ztpmv_(uplo, trans, diag, n, &ap[1], &work[1], &c__1); z__1.r = -1., z__1.i = -0.; zaxpy_(n, &z__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__] = (d__1 = b[i__3].r, abs(d__1)) + (d__2 = d_imag(&b[ i__ + j * b_dim1]), abs(d__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 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(& x[k + j * x_dim1]), abs(d__2)); i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + ( d__2 = d_imag(&ap[kc + i__ - 1]), abs( d__2))) * xk; /* L30: */ } kc += k; /* L40: */ } } else { i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + j * x_dim1; xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(& x[k + j * x_dim1]), abs(d__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + ( d__2 = d_imag(&ap[kc + i__ - 1]), abs( d__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 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(& x[k + j * x_dim1]), abs(d__2)); i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + ( d__2 = d_imag(&ap[kc + i__ - k]), abs( d__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 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(& x[k + j * x_dim1]), abs(d__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + ( d__2 = d_imag(&ap[kc + i__ - k]), abs( d__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.; i__3 = k; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; i__5 = i__ + j * x_dim1; s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[kc + i__ - 1]), abs(d__2))) * ( (d__3 = x[i__5].r, abs(d__3)) + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__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 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[ k + j * x_dim1]), abs(d__2)); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - 1; i__5 = i__ + j * x_dim1; s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[kc + i__ - 1]), abs(d__2))) * ( (d__3 = x[i__5].r, abs(d__3)) + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__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.; i__3 = *n; for (i__ = k; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; i__5 = i__ + j * x_dim1; s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[kc + i__ - k]), abs(d__2))) * ( (d__3 = x[i__5].r, abs(d__3)) + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__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 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[ k + j * x_dim1]), abs(d__2)); i__3 = *n; for (i__ = k + 1; i__ <= i__3; ++i__) { i__4 = kc + i__ - k; i__5 = i__ + j * x_dim1; s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[kc + i__ - k]), abs(d__2))) * ( (d__3 = x[i__5].r, abs(d__3)) + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__4))); /* L170: */ } rwork[k] += s; kc = kc + *n - k + 1; /* L180: */ } } } } s = 0.; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { if (rwork[i__] > safe2) { /* Computing MAX */ i__3 = i__; d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 = d_imag(&work[i__]), abs(d__2))) / rwork[i__]; s = max(d__3,d__4); } else { /* Computing MAX */ i__3 = i__; d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 = d_imag(&work[i__]), abs(d__2)) + safe1) / (rwork[i__] + safe1); s = max(d__3,d__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 ZLACN2 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__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 = d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__] ; } else { i__3 = i__; rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 = d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__] + safe1; } /* L200: */ } kase = 0; L210: zlacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave); if (kase != 0) { if (kase == 1) { /* Multiply by diag(W)*inv(op(A)**H). */ ztpsv_(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__; z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = z__1.r, work[i__3].i = z__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__; z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4] * work[i__5].i; work[i__3].r = z__1.r, work[i__3].i = z__1.i; /* L230: */ } ztpsv_(uplo, transn, diag, n, &ap[1], &work[1], &c__1); } goto L210; } /* Normalize error. */ lstres = 0.; i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ i__3 = i__ + j * x_dim1; d__3 = lstres, d__4 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[i__ + j * x_dim1]), abs(d__2)); lstres = max(d__3,d__4); /* L240: */ } if (lstres != 0.) { ferr[j] /= lstres; } /* L250: */ } return 0; /* End of ZTPRFS */ } /* ztprfs_ */
/* Subroutine */ int zhpgvx_(integer *itype, char *jobz, char *range, char * uplo, integer *n, doublecomplex *ap, doublecomplex *bp, doublereal * vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol, integer *m, doublereal *w, doublecomplex *z__, integer *ldz, doublecomplex *work, doublereal *rwork, integer *iwork, integer * ifail, integer *info) { /* System generated locals */ integer z_dim1, z_offset, i__1; /* Local variables */ integer j; char trans[1]; logical upper, wantz; logical alleig, indeig, valeig; /* -- LAPACK driver routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* ZHPGVX computes selected eigenvalues and, optionally, eigenvectors */ /* of a complex generalized Hermitian-definite eigenproblem, of the form */ /* A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and */ /* B are assumed to be Hermitian, stored in packed format, and B is also */ /* positive definite. Eigenvalues and eigenvectors can be selected by */ /* specifying either a range of values or a range of indices for the */ /* desired eigenvalues. */ /* Arguments */ /* ========= */ /* ITYPE (input) INTEGER */ /* Specifies the problem type to be solved: */ /* = 1: A*x = (lambda)*B*x */ /* = 2: A*B*x = (lambda)*x */ /* = 3: B*A*x = (lambda)*x */ /* JOBZ (input) CHARACTER*1 */ /* = 'N': Compute eigenvalues only; */ /* = 'V': Compute eigenvalues and eigenvectors. */ /* RANGE (input) CHARACTER*1 */ /* = 'A': all eigenvalues will be found; */ /* = 'V': all eigenvalues in the half-open interval (VL,VU] */ /* will be found; */ /* = 'I': the IL-th through IU-th eigenvalues will be found. */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangles of A and B are stored; */ /* = 'L': Lower triangles of A and B are stored. */ /* N (input) INTEGER */ /* The order of the matrices A and B. N >= 0. */ /* AP (input/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian 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)*(2*n-j)/2) = A(i,j) for j<=i<=n. */ /* On exit, the contents of AP are destroyed. */ /* BP (input/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian matrix */ /* B, packed columnwise in a linear array. The j-th column of B */ /* is stored in the array BP as follows: */ /* if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j; */ /* if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n. */ /* On exit, the triangular factor U or L from the Cholesky */ /* factorization B = U**H*U or B = L*L**H, in the same storage */ /* format as B. */ /* VL (input) DOUBLE PRECISION */ /* VU (input) DOUBLE PRECISION */ /* If RANGE='V', the lower and upper bounds of the interval to */ /* be searched for eigenvalues. VL < VU. */ /* Not referenced if RANGE = 'A' or 'I'. */ /* IL (input) INTEGER */ /* IU (input) INTEGER */ /* If RANGE='I', the indices (in ascending order) of the */ /* smallest and largest eigenvalues to be returned. */ /* 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. */ /* Not referenced if RANGE = 'A' or 'V'. */ /* ABSTOL (input) DOUBLE PRECISION */ /* The absolute error tolerance for the eigenvalues. */ /* An approximate eigenvalue is accepted as converged */ /* when it is determined to lie in an interval [a,b] */ /* of width less than or equal to */ /* ABSTOL + EPS * max( |a|,|b| ) , */ /* where EPS is the machine precision. If ABSTOL is less than */ /* or equal to zero, then EPS*|T| will be used in its place, */ /* where |T| is the 1-norm of the tridiagonal matrix obtained */ /* by reducing AP to tridiagonal form. */ /* Eigenvalues will be computed most accurately when ABSTOL is */ /* set to twice the underflow threshold 2*DLAMCH('S'), not zero. */ /* If this routine returns with INFO>0, indicating that some */ /* eigenvectors did not converge, try setting ABSTOL to */ /* 2*DLAMCH('S'). */ /* M (output) INTEGER */ /* The total number of eigenvalues found. 0 <= M <= N. */ /* If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1. */ /* W (output) DOUBLE PRECISION array, dimension (N) */ /* On normal exit, the first M elements contain the selected */ /* eigenvalues in ascending order. */ /* Z (output) COMPLEX*16 array, dimension (LDZ, N) */ /* If JOBZ = 'N', then Z is not referenced. */ /* If JOBZ = 'V', then if INFO = 0, the first M columns of Z */ /* contain the orthonormal eigenvectors of the matrix A */ /* corresponding to the selected eigenvalues, with the i-th */ /* column of Z holding the eigenvector associated with W(i). */ /* The eigenvectors are normalized as follows: */ /* if ITYPE = 1 or 2, Z**H*B*Z = I; */ /* if ITYPE = 3, Z**H*inv(B)*Z = I. */ /* If an eigenvector fails to converge, then that column of Z */ /* contains the latest approximation to the eigenvector, and the */ /* index of the eigenvector is returned in IFAIL. */ /* Note: the user must ensure that at least max(1,M) columns are */ /* supplied in the array Z; if RANGE = 'V', the exact value of M */ /* is not known in advance and an upper bound must be used. */ /* LDZ (input) INTEGER */ /* The leading dimension of the array Z. LDZ >= 1, and if */ /* JOBZ = 'V', LDZ >= max(1,N). */ /* WORK (workspace) COMPLEX*16 array, dimension (2*N) */ /* RWORK (workspace) DOUBLE PRECISION array, dimension (7*N) */ /* IWORK (workspace) INTEGER array, dimension (5*N) */ /* IFAIL (output) INTEGER array, dimension (N) */ /* If JOBZ = 'V', then if INFO = 0, the first M elements of */ /* IFAIL are zero. If INFO > 0, then IFAIL contains the */ /* indices of the eigenvectors that failed to converge. */ /* If JOBZ = 'N', then IFAIL is not referenced. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: ZPPTRF or ZHPEVX returned an error code: */ /* <= N: if INFO = i, ZHPEVX failed to converge; */ /* i eigenvectors failed to converge. Their indices */ /* are stored in array IFAIL. */ /* > N: if INFO = N + i, for 1 <= i <= n, then the leading */ /* minor of order i of B is not positive definite. */ /* The factorization of B could not be completed and */ /* no eigenvalues or eigenvectors were computed. */ /* Further Details */ /* =============== */ /* Based on contributions by */ /* Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; --bp; --w; z_dim1 = *ldz; z_offset = 1 + z_dim1; z__ -= z_offset; --work; --rwork; --iwork; --ifail; /* Function Body */ wantz = lsame_(jobz, "V"); upper = lsame_(uplo, "U"); alleig = lsame_(range, "A"); valeig = lsame_(range, "V"); indeig = lsame_(range, "I"); *info = 0; if (*itype < 1 || *itype > 3) { *info = -1; } else if (! (wantz || lsame_(jobz, "N"))) { *info = -2; } else if (! (alleig || valeig || indeig)) { *info = -3; } else if (! (upper || lsame_(uplo, "L"))) { *info = -4; } else if (*n < 0) { *info = -5; } else { if (valeig) { if (*n > 0 && *vu <= *vl) { *info = -9; } } else if (indeig) { if (*il < 1) { *info = -10; } else if (*iu < min(*n,*il) || *iu > *n) { *info = -11; } } } if (*info == 0) { if (*ldz < 1 || wantz && *ldz < *n) { *info = -16; } } if (*info != 0) { i__1 = -(*info); xerbla_("ZHPGVX", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Form a Cholesky factorization of B. */ zpptrf_(uplo, n, &bp[1], info); if (*info != 0) { *info = *n + *info; return 0; } /* Transform problem to standard eigenvalue problem and solve. */ zhpgst_(itype, uplo, n, &ap[1], &bp[1], info); zhpevx_(jobz, range, uplo, n, &ap[1], vl, vu, il, iu, abstol, m, &w[1], & z__[z_offset], ldz, &work[1], &rwork[1], &iwork[1], &ifail[1], info); if (wantz) { /* Backtransform eigenvectors to the original problem. */ if (*info > 0) { *m = *info - 1; } if (*itype == 1 || *itype == 2) { /* For A*x=(lambda)*B*x and A*B*x=(lambda)*x; */ /* backtransform eigenvectors: x = inv(L)'*y or inv(U)*y */ if (upper) { *(unsigned char *)trans = 'N'; } else { *(unsigned char *)trans = 'C'; } i__1 = *m; for (j = 1; j <= i__1; ++j) { ztpsv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 1], &c__1); } } else if (*itype == 3) { /* For B*A*x=(lambda)*x; */ /* backtransform eigenvectors: x = L*y or U'*y */ if (upper) { *(unsigned char *)trans = 'C'; } else { *(unsigned char *)trans = 'N'; } i__1 = *m; for (j = 1; j <= i__1; ++j) { ztpmv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 1], &c__1); } } } return 0; /* End of ZHPGVX */ } /* zhpgvx_ */
/* Subroutine */ int zlatps_(char *uplo, char *trans, char *diag, char * normin, integer *n, doublecomplex *ap, doublecomplex *x, doublereal * scale, doublereal *cnorm, integer *info) { /* -- LAPACK auxiliary routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= ZLATPS solves one of the triangular systems A * x = s*b, A**T * x = s*b, or A**H * x = s*b, with scaling to prevent overflow, where A is an upper or lower triangular matrix stored in packed form. Here A**T denotes the transpose of A, A**H denotes the conjugate transpose of A, x and b are n-element vectors, and s is a scaling factor, usually less than or equal to 1, chosen so that the components of x will be less than the overflow threshold. If the unscaled problem will not cause overflow, the Level 2 BLAS routine ZTPSV is called. If the matrix A is singular (A(j,j) = 0 for some j), then s is set to 0 and a non-trivial solution to A*x = 0 is returned. Arguments ========= UPLO (input) CHARACTER*1 Specifies whether the matrix A is upper or lower triangular. = 'U': Upper triangular = 'L': Lower triangular TRANS (input) CHARACTER*1 Specifies the operation applied to A. = 'N': Solve A * x = s*b (No transpose) = 'T': Solve A**T * x = s*b (Transpose) = 'C': Solve A**H * x = s*b (Conjugate transpose) DIAG (input) CHARACTER*1 Specifies whether or not the matrix A is unit triangular. = 'N': Non-unit triangular = 'U': Unit triangular NORMIN (input) CHARACTER*1 Specifies whether CNORM has been set or not. = 'Y': CNORM contains the column norms on entry = 'N': CNORM is not set on entry. On exit, the norms will be computed and stored in CNORM. N (input) INTEGER The order of the matrix A. N >= 0. AP (input) COMPLEX*16 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. X (input/output) COMPLEX*16 array, dimension (N) On entry, the right hand side b of the triangular system. On exit, X is overwritten by the solution vector x. SCALE (output) DOUBLE PRECISION The scaling factor s for the triangular system A * x = s*b, A**T * x = s*b, or A**H * x = s*b. If SCALE = 0, the matrix A is singular or badly scaled, and the vector x is an exact or approximate solution to A*x = 0. CNORM (input or output) DOUBLE PRECISION array, dimension (N) If NORMIN = 'Y', CNORM is an input argument and CNORM(j) contains the norm of the off-diagonal part of the j-th column of A. If TRANS = 'N', CNORM(j) must be greater than or equal to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) must be greater than or equal to the 1-norm. If NORMIN = 'N', CNORM is an output argument and CNORM(j) returns the 1-norm of the offdiagonal part of the j-th column of A. INFO (output) INTEGER = 0: successful exit < 0: if INFO = -k, the k-th argument had an illegal value Further Details ======= ======= A rough bound on x is computed; if that is less than overflow, ZTPSV is called, otherwise, specific code is used which checks for possible overflow or divide-by-zero at every operation. A columnwise scheme is used for solving A*x = b. The basic algorithm if A is lower triangular is x[1:n] := b[1:n] for j = 1, ..., n x(j) := x(j) / A(j,j) x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j] end Define bounds on the components of x after j iterations of the loop: M(j) = bound on x[1:j] G(j) = bound on x[j+1:n] Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}. Then for iteration j+1 we have M(j+1) <= G(j) / | A(j+1,j+1) | G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] | <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | ) where CNORM(j+1) is greater than or equal to the infinity-norm of column j+1 of A, not counting the diagonal. Hence G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | ) 1<=i<=j and |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| ) 1<=i< j Since |x(j)| <= M(j), we use the Level 2 BLAS routine ZTPSV if the reciprocal of the largest M(j), j=1,..,n, is larger than max(underflow, 1/overflow). The bound on x(j) is also used to determine when a step in the columnwise method can be performed without fear of overflow. If the computed bound is greater than a large constant, x is scaled to prevent overflow, but if the bound overflows, x is set to 0, x(j) to 1, and scale to 0, and a non-trivial solution to A*x = 0 is found. Similarly, a row-wise scheme is used to solve A**T *x = b or A**H *x = b. The basic algorithm for A upper triangular is for j = 1, ..., n x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j) end We simultaneously compute two bounds G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j M(j) = bound on x(i), 1<=i<=j The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1. Then the bound on x(j) is M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) | <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| ) 1<=i<=j and we can safely call ZTPSV if 1/M(n) and 1/G(n) are both greater than max(underflow, 1/overflow). ===================================================================== Parameter adjustments Function Body */ /* Table of constant values */ static integer c__1 = 1; static doublereal c_b36 = .5; /* System generated locals */ integer i__1, i__2, i__3, i__4, i__5; doublereal d__1, d__2, d__3, d__4; doublecomplex z__1, z__2, z__3, z__4; /* Builtin functions */ double d_imag(doublecomplex *); void d_cnjg(doublecomplex *, doublecomplex *); /* Local variables */ static integer jinc, jlen; static doublereal xbnd; static integer imax; static doublereal tmax; static doublecomplex tjjs; static doublereal xmax, grow; static integer i, j; extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *, integer *); extern logical lsame_(char *, char *); static doublereal tscal; static doublecomplex uscal; static integer jlast; static doublecomplex csumj; extern /* Double Complex */ VOID zdotc_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); static logical upper; extern /* Double Complex */ VOID zdotu_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); extern /* Subroutine */ int zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *), ztpsv_( char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), dlabad_(doublereal *, doublereal *); extern doublereal dlamch_(char *); static integer ip; static doublereal xj; extern integer idamax_(integer *, doublereal *, integer *); extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_( integer *, doublereal *, doublecomplex *, integer *); static doublereal bignum; extern integer izamax_(integer *, doublecomplex *, integer *); extern /* Double Complex */ VOID zladiv_(doublecomplex *, doublecomplex *, doublecomplex *); static logical notran; static integer jfirst; extern doublereal dzasum_(integer *, doublecomplex *, integer *); static doublereal smlnum; static logical nounit; static doublereal rec, tjj; #define CNORM(I) cnorm[(I)-1] #define X(I) x[(I)-1] #define AP(I) ap[(I)-1] *info = 0; upper = lsame_(uplo, "U"); notran = lsame_(trans, "N"); nounit = lsame_(diag, "N"); /* Test the input parameters. */ 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 (! lsame_(normin, "Y") && ! lsame_(normin, "N")) { *info = -4; } else if (*n < 0) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("ZLATPS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine machine dependent parameters to control overflow. */ smlnum = dlamch_("Safe minimum"); bignum = 1. / smlnum; dlabad_(&smlnum, &bignum); smlnum /= dlamch_("Precision"); bignum = 1. / smlnum; *scale = 1.; if (lsame_(normin, "N")) { /* Compute the 1-norm of each column, not including the diagona l. */ if (upper) { /* A is upper triangular. */ ip = 1; i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = j - 1; CNORM(j) = dzasum_(&i__2, &AP(ip), &c__1); ip += j; /* L10: */ } } else { /* A is lower triangular. */ ip = 1; i__1 = *n - 1; for (j = 1; j <= *n-1; ++j) { i__2 = *n - j; CNORM(j) = dzasum_(&i__2, &AP(ip + 1), &c__1); ip = ip + *n - j + 1; /* L20: */ } CNORM(*n) = 0.; } } /* Scale the column norms by TSCAL if the maximum element in CNORM is greater than BIGNUM/2. */ imax = idamax_(n, &CNORM(1), &c__1); tmax = CNORM(imax); if (tmax <= bignum * .5) { tscal = 1.; } else { tscal = .5 / (smlnum * tmax); dscal_(n, &tscal, &CNORM(1), &c__1); } /* Compute a bound on the computed solution vector to see if the Level 2 BLAS routine ZTPSV can be used. */ xmax = 0.; i__1 = *n; for (j = 1; j <= *n; ++j) { /* Computing MAX */ i__2 = j; d__3 = xmax, d__4 = (d__1 = X(j).r / 2., abs(d__1)) + (d__2 = d_imag(&X(j)) / 2., abs(d__2)); xmax = max(d__3,d__4); /* L30: */ } xbnd = xmax; if (notran) { /* Compute the growth in A * x = b. */ if (upper) { jfirst = *n; jlast = 1; jinc = -1; } else { jfirst = 1; jlast = *n; jinc = 1; } if (tscal != 1.) { grow = 0.; goto L60; } if (nounit) { /* A is non-unit triangular. Compute GROW = 1/G(j) and XBND = 1/M(j). Initially, G(0) = max{x(i), i=1,...,n}. */ grow = .5 / max(xbnd,smlnum); xbnd = grow; ip = jfirst * (jfirst + 1) / 2; jlen = *n; i__1 = jlast; i__2 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Exit the loop if the growth factor is too smal l. */ if (grow <= smlnum) { goto L60; } i__3 = ip; tjjs.r = AP(ip).r, tjjs.i = AP(ip).i; tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj >= smlnum) { /* M(j) = G(j-1) / abs(A(j,j)) Computing MIN */ d__1 = xbnd, d__2 = min(1.,tjj) * grow; xbnd = min(d__1,d__2); } else { /* M(j) could overflow, set XBND to 0. */ xbnd = 0.; } if (tjj + CNORM(j) >= smlnum) { /* G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j, j)) ) */ grow *= tjj / (tjj + CNORM(j)); } else { /* G(j) could overflow, set GROW to 0. */ grow = 0.; } ip += jinc * jlen; --jlen; /* L40: */ } grow = xbnd; } else { /* A is unit triangular. Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,... ,n}. Computing MIN */ d__1 = 1., d__2 = .5 / max(xbnd,smlnum); grow = min(d__1,d__2); i__2 = jlast; i__1 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Exit the loop if the growth factor is too smal l. */ if (grow <= smlnum) { goto L60; } /* G(j) = G(j-1)*( 1 + CNORM(j) ) */ grow *= 1. / (CNORM(j) + 1.); /* L50: */ } } L60: ; } else { /* Compute the growth in A**T * x = b or A**H * x = b. */ if (upper) { jfirst = 1; jlast = *n; jinc = 1; } else { jfirst = *n; jlast = 1; jinc = -1; } if (tscal != 1.) { grow = 0.; goto L90; } if (nounit) { /* A is non-unit triangular. Compute GROW = 1/G(j) and XBND = 1/M(j). Initially, M(0) = max{x(i), i=1,...,n}. */ grow = .5 / max(xbnd,smlnum); xbnd = grow; ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__1 = jlast; i__2 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Exit the loop if the growth factor is too smal l. */ if (grow <= smlnum) { goto L90; } /* G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) */ xj = CNORM(j) + 1.; /* Computing MIN */ d__1 = grow, d__2 = xbnd / xj; grow = min(d__1,d__2); i__3 = ip; tjjs.r = AP(ip).r, tjjs.i = AP(ip).i; tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj >= smlnum) { /* M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A( j,j)) */ if (xj > tjj) { xbnd *= tjj / xj; } } else { /* M(j) could overflow, set XBND to 0. */ xbnd = 0.; } ++jlen; ip += jinc * jlen; /* L70: */ } grow = min(grow,xbnd); } else { /* A is unit triangular. Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,... ,n}. Computing MIN */ d__1 = 1., d__2 = .5 / max(xbnd,smlnum); grow = min(d__1,d__2); i__2 = jlast; i__1 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Exit the loop if the growth factor is too smal l. */ if (grow <= smlnum) { goto L90; } /* G(j) = ( 1 + CNORM(j) )*G(j-1) */ xj = CNORM(j) + 1.; grow /= xj; /* L80: */ } } L90: ; } if (grow * tscal > smlnum) { /* Use the Level 2 BLAS solve if the reciprocal of the bound on elements of X is not too small. */ ztpsv_(uplo, trans, diag, n, &AP(1), &X(1), &c__1); } else { /* Use a Level 1 BLAS solve, scaling intermediate results. */ if (xmax > bignum * .5) { /* Scale X so that its components are less than or equal to BIGNUM in absolute value. */ *scale = bignum * .5 / xmax; zdscal_(n, scale, &X(1), &c__1); xmax = bignum; } else { xmax *= 2.; } if (notran) { /* Solve A * x = b */ ip = jfirst * (jfirst + 1) / 2; i__1 = jlast; i__2 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Compute x(j) = b(j) / A(j,j), scaling x if nec essary. */ i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)), abs(d__2)); if (nounit) { i__3 = ip; z__1.r = tscal * AP(ip).r, z__1.i = tscal * AP(ip).i; tjjs.r = z__1.r, tjjs.i = z__1.i; } else { tjjs.r = tscal, tjjs.i = 0.; if (tscal == 1.) { goto L110; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs( d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale x by 1/b(j). */ rec = 1. / xj; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)) , abs(d__2)); } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j)))*abs( A(j,j))*BIGNUM to avoid overflow when dividi ng by A(j,j). */ rec = tjj * bignum / xj; if (CNORM(j) > 1.) { /* Scale by 1/CNORM(j) to avoid overflow when multiplying x(j) times column j. */ rec /= CNORM(j); } zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)) , abs(d__2)); } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and scale = 0, and compute a solution to A*x = 0. */ i__3 = *n; for (i = 1; i <= *n; ++i) { i__4 = i; X(i).r = 0., X(i).i = 0.; /* L100: */ } i__3 = j; X(j).r = 1., X(j).i = 0.; xj = 1.; *scale = 0.; xmax = 0.; } L110: /* Scale x if necessary to avoid overflow when ad ding a multiple of column j of A. */ if (xj > 1.) { rec = 1. / xj; if (CNORM(j) > (bignum - xmax) * rec) { /* Scale x by 1/(2*abs(x(j))). */ rec *= .5; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; } } else if (xj * CNORM(j) > bignum - xmax) { /* Scale x by 1/2. */ zdscal_(n, &c_b36, &X(1), &c__1); *scale *= .5; } if (upper) { if (j > 1) { /* Compute the update x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j) */ i__3 = j - 1; i__4 = j; z__2.r = -X(j).r, z__2.i = -X(j).i; z__1.r = tscal * z__2.r, z__1.i = tscal * z__2.i; zaxpy_(&i__3, &z__1, &AP(ip - j + 1), &c__1, &X(1), & c__1); i__3 = j - 1; i = izamax_(&i__3, &X(1), &c__1); i__3 = i; xmax = (d__1 = X(i).r, abs(d__1)) + (d__2 = d_imag( &X(i)), abs(d__2)); } ip -= j; } else { if (j < *n) { /* Compute the update x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j) */ i__3 = *n - j; i__4 = j; z__2.r = -X(j).r, z__2.i = -X(j).i; z__1.r = tscal * z__2.r, z__1.i = tscal * z__2.i; zaxpy_(&i__3, &z__1, &AP(ip + 1), &c__1, &X(j + 1), & c__1); i__3 = *n - j; i = j + izamax_(&i__3, &X(j + 1), &c__1); i__3 = i; xmax = (d__1 = X(i).r, abs(d__1)) + (d__2 = d_imag( &X(i)), abs(d__2)); } ip = ip + *n - j + 1; } /* L120: */ } } else if (lsame_(trans, "T")) { /* Solve A**T * x = b */ ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__2 = jlast; i__1 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Compute x(j) = b(j) - sum A(k,j)*x(k). k<>j */ i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)), abs(d__2)); uscal.r = tscal, uscal.i = 0.; rec = 1. / max(xmax,1.); if (CNORM(j) > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2 *XMAX). */ rec *= .5; if (nounit) { i__3 = ip; z__1.r = tscal * AP(ip).r, z__1.i = tscal * AP(ip) .i; tjjs.r = z__1.r, tjjs.i = z__1.i; } else { tjjs.r = tscal, tjjs.i = 0.; } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > 1.) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. Computing MIN */ d__1 = 1., d__2 = rec * tjj; rec = min(d__1,d__2); zladiv_(&z__1, &uscal, &tjjs); uscal.r = z__1.r, uscal.i = z__1.i; } if (rec < 1.) { zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0., csumj.i = 0.; if (uscal.r == 1. && uscal.i == 0.) { /* If the scaling needed for A in the dot product is 1, call ZDOTU to perform the dot product. */ if (upper) { i__3 = j - 1; zdotu_(&z__1, &i__3, &AP(ip - j + 1), &c__1, &X(1), & c__1); csumj.r = z__1.r, csumj.i = z__1.i; } else if (j < *n) { i__3 = *n - j; zdotu_(&z__1, &i__3, &AP(ip + 1), &c__1, &X(j + 1), & c__1); csumj.r = z__1.r, csumj.i = z__1.i; } } else { /* Otherwise, use in-line code for the dot product. */ if (upper) { i__3 = j - 1; for (i = 1; i <= j-1; ++i) { i__4 = ip - j + i; z__3.r = AP(ip-j+i).r * uscal.r - AP(ip-j+i).i * uscal.i, z__3.i = AP(ip-j+i).r * uscal.i + AP(ip-j+i).i * uscal.r; i__5 = i; z__2.r = z__3.r * X(i).r - z__3.i * X(i).i, z__2.i = z__3.r * X(i).i + z__3.i * X( i).r; z__1.r = csumj.r + z__2.r, z__1.i = csumj.i + z__2.i; csumj.r = z__1.r, csumj.i = z__1.i; /* L130: */ } } else if (j < *n) { i__3 = *n - j; for (i = 1; i <= *n-j; ++i) { i__4 = ip + i; z__3.r = AP(ip+i).r * uscal.r - AP(ip+i).i * uscal.i, z__3.i = AP(ip+i).r * uscal.i + AP(ip+i).i * uscal.r; i__5 = j + i; z__2.r = z__3.r * X(j+i).r - z__3.i * X(j+i).i, z__2.i = z__3.r * X(j+i).i + z__3.i * X( j+i).r; z__1.r = csumj.r + z__2.r, z__1.i = csumj.i + z__2.i; csumj.r = z__1.r, csumj.i = z__1.i; /* L140: */ } } } z__1.r = tscal, z__1.i = 0.; if (uscal.r == z__1.r && uscal.i == z__1.i) { /* Compute x(j) := ( x(j) - CSUMJ ) / A(j, j) if 1/A(j,j) was not used to scale the dotproduct. */ i__3 = j; i__4 = j; z__1.r = X(j).r - csumj.r, z__1.i = X(j).i - csumj.i; X(j).r = z__1.r, X(j).i = z__1.i; i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)) , abs(d__2)); if (nounit) { /* Compute x(j) = x(j) / A(j,j), sc aling if necessary. */ i__3 = ip; z__1.r = tscal * AP(ip).r, z__1.i = tscal * AP(ip) .i; tjjs.r = z__1.r, tjjs.i = z__1.i; } else { tjjs.r = tscal, tjjs.i = 0.; if (tscal == 1.) { goto L160; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale X by 1/ab s(x(j)). */ rec = 1. / xj; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j) ))*abs(A(j,j))*BIGNUM. */ rec = tjj * bignum / xj; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and scale = 0 and compute a solut ion to A**T *x = 0. */ i__3 = *n; for (i = 1; i <= *n; ++i) { i__4 = i; X(i).r = 0., X(i).i = 0.; /* L150: */ } i__3 = j; X(j).r = 1., X(j).i = 0.; *scale = 0.; xmax = 0.; } L160: ; } else { /* Compute x(j) := x(j) / A(j,j) - CSUMJ i f the dot product has already been divided by 1/A (j,j). */ i__3 = j; zladiv_(&z__2, &X(j), &tjjs); z__1.r = z__2.r - csumj.r, z__1.i = z__2.i - csumj.i; X(j).r = z__1.r, X(j).i = z__1.i; } /* Computing MAX */ i__3 = j; d__3 = xmax, d__4 = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)), abs(d__2)); xmax = max(d__3,d__4); ++jlen; ip += jinc * jlen; /* L170: */ } } else { /* Solve A**H * x = b */ ip = jfirst * (jfirst + 1) / 2; jlen = 1; i__1 = jlast; i__2 = jinc; for (j = jfirst; jinc < 0 ? j >= jlast : j <= jlast; j += jinc) { /* Compute x(j) = b(j) - sum A(k,j)*x(k). k<>j */ i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)), abs(d__2)); uscal.r = tscal, uscal.i = 0.; rec = 1. / max(xmax,1.); if (CNORM(j) > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2 *XMAX). */ rec *= .5; if (nounit) { d_cnjg(&z__2, &AP(ip)); z__1.r = tscal * z__2.r, z__1.i = tscal * z__2.i; tjjs.r = z__1.r, tjjs.i = z__1.i; } else { tjjs.r = tscal, tjjs.i = 0.; } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > 1.) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. Computing MIN */ d__1 = 1., d__2 = rec * tjj; rec = min(d__1,d__2); zladiv_(&z__1, &uscal, &tjjs); uscal.r = z__1.r, uscal.i = z__1.i; } if (rec < 1.) { zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0., csumj.i = 0.; if (uscal.r == 1. && uscal.i == 0.) { /* If the scaling needed for A in the dot product is 1, call ZDOTC to perform the dot product. */ if (upper) { i__3 = j - 1; zdotc_(&z__1, &i__3, &AP(ip - j + 1), &c__1, &X(1), & c__1); csumj.r = z__1.r, csumj.i = z__1.i; } else if (j < *n) { i__3 = *n - j; zdotc_(&z__1, &i__3, &AP(ip + 1), &c__1, &X(j + 1), & c__1); csumj.r = z__1.r, csumj.i = z__1.i; } } else { /* Otherwise, use in-line code for the dot product. */ if (upper) { i__3 = j - 1; for (i = 1; i <= j-1; ++i) { d_cnjg(&z__4, &AP(ip - j + i)); z__3.r = z__4.r * uscal.r - z__4.i * uscal.i, z__3.i = z__4.r * uscal.i + z__4.i * uscal.r; i__4 = i; z__2.r = z__3.r * X(i).r - z__3.i * X(i).i, z__2.i = z__3.r * X(i).i + z__3.i * X( i).r; z__1.r = csumj.r + z__2.r, z__1.i = csumj.i + z__2.i; csumj.r = z__1.r, csumj.i = z__1.i; /* L180: */ } } else if (j < *n) { i__3 = *n - j; for (i = 1; i <= *n-j; ++i) { d_cnjg(&z__4, &AP(ip + i)); z__3.r = z__4.r * uscal.r - z__4.i * uscal.i, z__3.i = z__4.r * uscal.i + z__4.i * uscal.r; i__4 = j + i; z__2.r = z__3.r * X(j+i).r - z__3.i * X(j+i).i, z__2.i = z__3.r * X(j+i).i + z__3.i * X( j+i).r; z__1.r = csumj.r + z__2.r, z__1.i = csumj.i + z__2.i; csumj.r = z__1.r, csumj.i = z__1.i; /* L190: */ } } } z__1.r = tscal, z__1.i = 0.; if (uscal.r == z__1.r && uscal.i == z__1.i) { /* Compute x(j) := ( x(j) - CSUMJ ) / A(j, j) if 1/A(j,j) was not used to scale the dotproduct. */ i__3 = j; i__4 = j; z__1.r = X(j).r - csumj.r, z__1.i = X(j).i - csumj.i; X(j).r = z__1.r, X(j).i = z__1.i; i__3 = j; xj = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)) , abs(d__2)); if (nounit) { /* Compute x(j) = x(j) / A(j,j), sc aling if necessary. */ d_cnjg(&z__2, &AP(ip)); z__1.r = tscal * z__2.r, z__1.i = tscal * z__2.i; tjjs.r = z__1.r, tjjs.i = z__1.i; } else { tjjs.r = tscal, tjjs.i = 0.; if (tscal == 1.) { goto L210; } } tjj = (d__1 = tjjs.r, abs(d__1)) + (d__2 = d_imag(&tjjs), abs(d__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.) { if (xj > tjj * bignum) { /* Scale X by 1/ab s(x(j)). */ rec = 1. / xj; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; } else if (tjj > 0.) { /* 0 < abs(A(j,j)) <= SMLNUM: */ if (xj > tjj * bignum) { /* Scale x by (1/abs(x(j) ))*abs(A(j,j))*BIGNUM. */ rec = tjj * bignum / xj; zdscal_(n, &rec, &X(1), &c__1); *scale *= rec; xmax *= rec; } i__3 = j; zladiv_(&z__1, &X(j), &tjjs); X(j).r = z__1.r, X(j).i = z__1.i; } else { /* A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and scale = 0 and compute a solut ion to A**H *x = 0. */ i__3 = *n; for (i = 1; i <= *n; ++i) { i__4 = i; X(i).r = 0., X(i).i = 0.; /* L200: */ } i__3 = j; X(j).r = 1., X(j).i = 0.; *scale = 0.; xmax = 0.; } L210: ; } else { /* Compute x(j) := x(j) / A(j,j) - CSUMJ i f the dot product has already been divided by 1/A (j,j). */ i__3 = j; zladiv_(&z__2, &X(j), &tjjs); z__1.r = z__2.r - csumj.r, z__1.i = z__2.i - csumj.i; X(j).r = z__1.r, X(j).i = z__1.i; } /* Computing MAX */ i__3 = j; d__3 = xmax, d__4 = (d__1 = X(j).r, abs(d__1)) + (d__2 = d_imag(&X(j)), abs(d__2)); xmax = max(d__3,d__4); ++jlen; ip += jinc * jlen; /* L220: */ } } *scale /= tscal; } /* Scale the column norms by 1/TSCAL for return. */ if (tscal != 1.) { d__1 = 1. / tscal; dscal_(n, &d__1, &CNORM(1), &c__1); } return 0; /* End of ZLATPS */ } /* zlatps_ */
/* Subroutine */ int zhpgvd_(integer *itype, char *jobz, char *uplo, integer * n, doublecomplex *ap, doublecomplex *bp, doublereal *w, doublecomplex *z__, integer *ldz, doublecomplex *work, integer *lwork, doublereal * rwork, integer *lrwork, integer *iwork, integer *liwork, integer * info) { /* System generated locals */ integer z_dim1, z_offset, i__1; doublereal d__1, d__2; /* Local variables */ integer j, neig; integer lwmin; char trans[1]; logical upper, wantz; integer liwmin; integer lrwmin; logical lquery; /* -- LAPACK driver routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* ZHPGVD computes all the eigenvalues and, optionally, the eigenvectors */ /* of a complex generalized Hermitian-definite eigenproblem, of the form */ /* A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and */ /* B are assumed to be Hermitian, stored in packed format, and B is also */ /* positive definite. */ /* If eigenvectors are desired, it uses a divide and conquer algorithm. */ /* The divide and conquer algorithm makes very mild assumptions about */ /* floating point arithmetic. It will work on machines with a guard */ /* digit in add/subtract, or on those binary machines without guard */ /* digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or */ /* Cray-2. It could conceivably fail on hexadecimal or decimal machines */ /* without guard digits, but we know of none. */ /* Arguments */ /* ========= */ /* ITYPE (input) INTEGER */ /* Specifies the problem type to be solved: */ /* = 1: A*x = (lambda)*B*x */ /* = 2: A*B*x = (lambda)*x */ /* = 3: B*A*x = (lambda)*x */ /* JOBZ (input) CHARACTER*1 */ /* = 'N': Compute eigenvalues only; */ /* = 'V': Compute eigenvalues and eigenvectors. */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangles of A and B are stored; */ /* = 'L': Lower triangles of A and B are stored. */ /* N (input) INTEGER */ /* The order of the matrices A and B. N >= 0. */ /* AP (input/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian 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)*(2*n-j)/2) = A(i,j) for j<=i<=n. */ /* On exit, the contents of AP are destroyed. */ /* BP (input/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian matrix */ /* B, packed columnwise in a linear array. The j-th column of B */ /* is stored in the array BP as follows: */ /* if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j; */ /* if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n. */ /* On exit, the triangular factor U or L from the Cholesky */ /* factorization B = U**H*U or B = L*L**H, in the same storage */ /* format as B. */ /* W (output) DOUBLE PRECISION array, dimension (N) */ /* If INFO = 0, the eigenvalues in ascending order. */ /* Z (output) COMPLEX*16 array, dimension (LDZ, N) */ /* If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of */ /* eigenvectors. The eigenvectors are normalized as follows: */ /* if ITYPE = 1 or 2, Z**H*B*Z = I; */ /* if ITYPE = 3, Z**H*inv(B)*Z = I. */ /* If JOBZ = 'N', then Z is not referenced. */ /* LDZ (input) INTEGER */ /* The leading dimension of the array Z. LDZ >= 1, and if */ /* JOBZ = 'V', LDZ >= max(1,N). */ /* WORK (workspace) COMPLEX*16 array, dimension (MAX(1,LWORK)) */ /* On exit, if INFO = 0, WORK(1) returns the required LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of array WORK. */ /* If N <= 1, LWORK >= 1. */ /* If JOBZ = 'N' and N > 1, LWORK >= N. */ /* If JOBZ = 'V' and N > 1, LWORK >= 2*N. */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the required sizes of the WORK, RWORK and */ /* IWORK arrays, returns these values as the first entries of */ /* the WORK, RWORK and IWORK arrays, and no error message */ /* related to LWORK or LRWORK or LIWORK is issued by XERBLA. */ /* RWORK (workspace) DOUBLE PRECISION array, dimension (MAX(1,LRWORK)) */ /* On exit, if INFO = 0, RWORK(1) returns the required LRWORK. */ /* LRWORK (input) INTEGER */ /* The dimension of array RWORK. */ /* If N <= 1, LRWORK >= 1. */ /* If JOBZ = 'N' and N > 1, LRWORK >= N. */ /* If JOBZ = 'V' and N > 1, LRWORK >= 1 + 5*N + 2*N**2. */ /* If LRWORK = -1, then a workspace query is assumed; the */ /* routine only calculates the required sizes of the WORK, RWORK */ /* and IWORK arrays, returns these values as the first entries */ /* of the WORK, RWORK and IWORK arrays, and no error message */ /* related to LWORK or LRWORK or LIWORK is issued by XERBLA. */ /* IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK)) */ /* On exit, if INFO = 0, IWORK(1) returns the required LIWORK. */ /* LIWORK (input) INTEGER */ /* The dimension of array IWORK. */ /* If JOBZ = 'N' or N <= 1, LIWORK >= 1. */ /* If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N. */ /* If LIWORK = -1, then a workspace query is assumed; the */ /* routine only calculates the required sizes of the WORK, RWORK */ /* and IWORK arrays, returns these values as the first entries */ /* of the WORK, RWORK and IWORK arrays, and no error message */ /* related to LWORK or LRWORK or LIWORK is issued by XERBLA. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: ZPPTRF or ZHPEVD returned an error code: */ /* <= N: if INFO = i, ZHPEVD failed to converge; */ /* i off-diagonal elements of an intermediate */ /* tridiagonal form did not convergeto zero; */ /* > N: if INFO = N + i, for 1 <= i <= n, then the leading */ /* minor of order i of B is not positive definite. */ /* The factorization of B could not be completed and */ /* no eigenvalues or eigenvectors were computed. */ /* Further Details */ /* =============== */ /* Based on contributions by */ /* Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; --bp; --w; z_dim1 = *ldz; z_offset = 1 + z_dim1; z__ -= z_offset; --work; --rwork; --iwork; /* Function Body */ wantz = lsame_(jobz, "V"); upper = lsame_(uplo, "U"); lquery = *lwork == -1 || *lrwork == -1 || *liwork == -1; *info = 0; if (*itype < 1 || *itype > 3) { *info = -1; } else if (! (wantz || lsame_(jobz, "N"))) { *info = -2; } else if (! (upper || lsame_(uplo, "L"))) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*ldz < 1 || wantz && *ldz < *n) { *info = -9; } if (*info == 0) { if (*n <= 1) { lwmin = 1; liwmin = 1; lrwmin = 1; } else { if (wantz) { lwmin = *n << 1; /* Computing 2nd power */ i__1 = *n; lrwmin = *n * 5 + 1 + (i__1 * i__1 << 1); liwmin = *n * 5 + 3; } else { lwmin = *n; lrwmin = *n; liwmin = 1; } } work[1].r = (doublereal) lwmin, work[1].i = 0.; rwork[1] = (doublereal) lrwmin; iwork[1] = liwmin; if (*lwork < lwmin && ! lquery) { *info = -11; } else if (*lrwork < lrwmin && ! lquery) { *info = -13; } else if (*liwork < liwmin && ! lquery) { *info = -15; } } if (*info != 0) { i__1 = -(*info); xerbla_("ZHPGVD", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Form a Cholesky factorization of B. */ zpptrf_(uplo, n, &bp[1], info); if (*info != 0) { *info = *n + *info; return 0; } /* Transform problem to standard eigenvalue problem and solve. */ zhpgst_(itype, uplo, n, &ap[1], &bp[1], info); zhpevd_(jobz, uplo, n, &ap[1], &w[1], &z__[z_offset], ldz, &work[1], lwork, &rwork[1], lrwork, &iwork[1], liwork, info); /* Computing MAX */ d__1 = (doublereal) lwmin, d__2 = work[1].r; lwmin = (integer) max(d__1,d__2); /* Computing MAX */ d__1 = (doublereal) lrwmin; lrwmin = (integer) max(d__1,rwork[1]); /* Computing MAX */ d__1 = (doublereal) liwmin, d__2 = (doublereal) iwork[1]; liwmin = (integer) max(d__1,d__2); if (wantz) { /* Backtransform eigenvectors to the original problem. */ neig = *n; if (*info > 0) { neig = *info - 1; } if (*itype == 1 || *itype == 2) { /* For A*x=(lambda)*B*x and A*B*x=(lambda)*x; */ /* backtransform eigenvectors: x = inv(L)'*y or inv(U)*y */ if (upper) { *(unsigned char *)trans = 'N'; } else { *(unsigned char *)trans = 'C'; } i__1 = neig; for (j = 1; j <= i__1; ++j) { ztpsv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 1], &c__1); } } else if (*itype == 3) { /* For B*A*x=(lambda)*x; */ /* backtransform eigenvectors: x = L*y or U'*y */ if (upper) { *(unsigned char *)trans = 'C'; } else { *(unsigned char *)trans = 'N'; } i__1 = neig; for (j = 1; j <= i__1; ++j) { ztpmv_(uplo, trans, "Non-unit", n, &bp[1], &z__[j * z_dim1 + 1], &c__1); } } } work[1].r = (doublereal) lwmin, work[1].i = 0.; rwork[1] = (doublereal) lrwmin; iwork[1] = liwmin; return 0; /* End of ZHPGVD */ } /* zhpgvd_ */
/* Subroutine */ int zpptrs_(char *uplo, integer *n, integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info) { /* System generated locals */ integer b_dim1, b_offset, i__1; /* Local variables */ integer i__; extern logical lsame_(char *, char *); logical upper; extern /* Subroutine */ int ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), xerbla_(char *, 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 .. */ /* .. */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; /* 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 (*ldb < max(1,*n)) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("ZPPTRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { return 0; } if (upper) { /* Solve A*X = B where A = U**H * U. */ i__1 = *nrhs; for (i__ = 1; i__ <= i__1; ++i__) { /* Solve U**H *X = B, overwriting B with X. */ ztpsv_("Upper", "Conjugate transpose", "Non-unit", n, &ap[1], &b[ i__ * b_dim1 + 1], &c__1); /* Solve U*X = B, overwriting B with X. */ ztpsv_("Upper", "No transpose", "Non-unit", n, &ap[1], &b[i__ * b_dim1 + 1], &c__1); /* L10: */ } } else { /* Solve A*X = B where A = L * L**H. */ i__1 = *nrhs; for (i__ = 1; i__ <= i__1; ++i__) { /* Solve L*Y = B, overwriting B with X. */ ztpsv_("Lower", "No transpose", "Non-unit", n, &ap[1], &b[i__ * b_dim1 + 1], &c__1); /* Solve L**H *X = Y, overwriting B with X. */ ztpsv_("Lower", "Conjugate transpose", "Non-unit", n, &ap[1], &b[ i__ * b_dim1 + 1], &c__1); /* L20: */ } } return 0; /* End of ZPPTRS */ }
/* Subroutine */ int zpptrs_(char *uplo, integer *n, integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info) { /* System generated locals */ integer b_dim1, b_offset, i__1; /* Local variables */ integer i__; extern logical lsame_(char *, char *); logical upper; extern /* Subroutine */ int ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), xerbla_(char *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZPPTRS solves a system of linear equations A*X = B with a Hermitian */ /* positive definite matrix A in packed storage using the Cholesky */ /* factorization A = U**H*U or A = L*L**H computed by ZPPTRF. */ /* 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 matrix B. NRHS >= 0. */ /* AP (input) COMPLEX*16 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. */ /* B (input/output) COMPLEX*16 array, dimension (LDB,NRHS) */ /* On entry, the right hand side matrix B. */ /* On exit, the solution matrix X. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; /* 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 (*ldb < max(1,*n)) { *info = -6; } if (*info != 0) { i__1 = -(*info); xerbla_("ZPPTRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { return 0; } if (upper) { /* Solve A*X = B where A = U'*U. */ i__1 = *nrhs; for (i__ = 1; i__ <= i__1; ++i__) { /* Solve U'*X = B, overwriting B with X. */ ztpsv_("Upper", "Conjugate transpose", "Non-unit", n, &ap[1], &b[ i__ * b_dim1 + 1], &c__1); /* Solve U*X = B, overwriting B with X. */ ztpsv_("Upper", "No transpose", "Non-unit", n, &ap[1], &b[i__ * b_dim1 + 1], &c__1); /* L10: */ } } else { /* Solve A*X = B where A = L*L'. */ i__1 = *nrhs; for (i__ = 1; i__ <= i__1; ++i__) { /* Solve L*Y = B, overwriting B with X. */ ztpsv_("Lower", "No transpose", "Non-unit", n, &ap[1], &b[i__ * b_dim1 + 1], &c__1); /* Solve L'*X = Y, overwriting B with X. */ ztpsv_("Lower", "Conjugate transpose", "Non-unit", n, &ap[1], &b[ i__ * b_dim1 + 1], &c__1); /* L20: */ } } return 0; /* End of ZPPTRS */ } /* zpptrs_ */
/* Subroutine */ int zpptrf_(char *uplo, integer *n, doublecomplex *ap, integer *info) { /* System generated locals */ integer i__1, i__2, i__3; doublereal d__1; doublecomplex z__1, z__2; /* Local variables */ integer j, jc, jj; doublereal ajj; logical upper; /* -- LAPACK routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* ZPPTRF computes the Cholesky factorization of a complex Hermitian */ /* positive definite matrix A stored in packed format. */ /* The factorization has the form */ /* A = U**H * U, if UPLO = 'U', or */ /* A = L * L**H, if UPLO = 'L', */ /* where U is an upper triangular matrix and L is lower triangular. */ /* 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/output) COMPLEX*16 array, dimension (N*(N+1)/2) */ /* On entry, the upper or lower triangle of the Hermitian 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. */ /* See below for further details. */ /* On exit, if INFO = 0, the triangular factor U or L from the */ /* Cholesky factorization A = U**H*U or A = L*L**H, in the same */ /* storage format as A. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: if INFO = i, the leading minor of order i is not */ /* positive definite, and the factorization could not be */ /* completed. */ /* Further Details */ /* =============== */ /* The packed storage scheme is illustrated by the following example */ /* when N = 4, UPLO = 'U': */ /* Two-dimensional storage of the Hermitian matrix A: */ /* a11 a12 a13 a14 */ /* a22 a23 a24 */ /* a33 a34 (aij = conjg(aji)) */ /* a44 */ /* Packed storage of the upper triangle of A: */ /* AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ] */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } if (*info != 0) { i__1 = -(*info); xerbla_("ZPPTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (upper) { /* Compute the Cholesky factorization A = U'*U. */ jj = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { jc = jj + 1; jj += j; /* Compute elements 1:J-1 of column J. */ if (j > 1) { i__2 = j - 1; ztpsv_("Upper", "Conjugate transpose", "Non-unit", &i__2, &ap[ 1], &ap[jc], &c__1); } /* Compute U(J,J) and test for non-positive-definiteness. */ i__2 = jj; d__1 = ap[i__2].r; i__3 = j - 1; zdotc_(&z__2, &i__3, &ap[jc], &c__1, &ap[jc], &c__1); z__1.r = d__1 - z__2.r, z__1.i = -z__2.i; ajj = z__1.r; if (ajj <= 0.) { i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; goto L30; } i__2 = jj; d__1 = sqrt(ajj); ap[i__2].r = d__1, ap[i__2].i = 0.; } } else { /* Compute the Cholesky factorization A = L*L'. */ jj = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Compute L(J,J) and test for non-positive-definiteness. */ i__2 = jj; ajj = ap[i__2].r; if (ajj <= 0.) { i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; goto L30; } ajj = sqrt(ajj); i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; /* Compute elements J+1:N of column J and update the trailing */ /* submatrix. */ if (j < *n) { i__2 = *n - j; d__1 = 1. / ajj; zdscal_(&i__2, &d__1, &ap[jj + 1], &c__1); i__2 = *n - j; zhpr_("Lower", &i__2, &c_b16, &ap[jj + 1], &c__1, &ap[jj + *n - j + 1]); jj = jj + *n - j + 1; } } } goto L40; L30: *info = j; L40: return 0; /* End of ZPPTRF */ } /* zpptrf_ */
/* Subroutine */ int ztptrs_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info) { /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= ZTPTRS solves a triangular system of the form A * X = B, A**T * X = B, or A**H * X = B, where A is a triangular matrix of order N stored in packed format, and B is an N-by-NRHS matrix. A check is made to verify that A is nonsingular. 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 matrix B. NRHS >= 0. AP (input) COMPLEX*16 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)*(2*n-j)/2) = A(i,j) for j<=i<=n. B (input/output) COMPLEX*16 array, dimension (LDB,NRHS) On entry, the right hand side matrix B. On exit, if INFO = 0, the solution matrix X. LDB (input) INTEGER The leading dimension of the array B. LDB >= max(1,N). INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, the i-th diagonal element of A is zero, indicating that the matrix is singular and the solutions X have not been computed. ===================================================================== Test the input parameters. Parameter adjustments */ /* Table of constant values */ static integer c__1 = 1; /* System generated locals */ integer b_dim1, b_offset, i__1, i__2; /* Local variables */ static integer j; extern logical lsame_(char *, char *); static logical upper; extern /* Subroutine */ int ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *); static integer jc; extern /* Subroutine */ int xerbla_(char *, integer *); static logical nounit; #define b_subscr(a_1,a_2) (a_2)*b_dim1 + a_1 #define b_ref(a_1,a_2) b[b_subscr(a_1,a_2)] --ap; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); nounit = lsame_(diag, "N"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (! lsame_(trans, "N") && ! 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; } if (*info != 0) { i__1 = -(*info); xerbla_("ZTPTRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Check for singularity. */ if (nounit) { if (upper) { jc = 1; i__1 = *n; for (*info = 1; *info <= i__1; ++(*info)) { i__2 = jc + *info - 1; if (ap[i__2].r == 0. && ap[i__2].i == 0.) { return 0; } jc += *info; /* L10: */ } } else { jc = 1; i__1 = *n; for (*info = 1; *info <= i__1; ++(*info)) { i__2 = jc; if (ap[i__2].r == 0. && ap[i__2].i == 0.) { return 0; } jc = jc + *n - *info + 1; /* L20: */ } } } *info = 0; /* Solve A * x = b, A**T * x = b, or A**H * x = b. */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ztpsv_(uplo, trans, diag, n, &ap[1], &b_ref(1, j), &c__1); /* L30: */ } return 0; /* End of ZTPTRS */ } /* ztptrs_ */
/* Subroutine */ int ztptrs_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info) { /* System generated locals */ integer b_dim1, b_offset, i__1, i__2; /* Local variables */ integer j, jc; extern logical lsame_(char *, char *); logical upper; extern /* Subroutine */ int ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), xerbla_(char *, integer *); logical nounit; /* -- LAPACK routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* ZTPTRS solves a triangular system of the form */ /* A * X = B, A**T * X = B, or A**H * X = B, */ /* where A is a triangular matrix of order N stored in packed format, */ /* and B is an N-by-NRHS matrix. A check is made to verify that A is */ /* nonsingular. */ /* 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 matrix B. NRHS >= 0. */ /* AP (input) COMPLEX*16 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)*(2*n-j)/2) = A(i,j) for j<=i<=n. */ /* B (input/output) COMPLEX*16 array, dimension (LDB,NRHS) */ /* On entry, the right hand side matrix B. */ /* On exit, if INFO = 0, the solution matrix X. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: if INFO = i, the i-th diagonal element of A is zero, */ /* indicating that the matrix is singular and the */ /* solutions X have not been computed. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --ap; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); nounit = lsame_(diag, "N"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (! lsame_(trans, "N") && ! 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; } if (*info != 0) { i__1 = -(*info); xerbla_("ZTPTRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Check for singularity. */ if (nounit) { if (upper) { jc = 1; i__1 = *n; for (*info = 1; *info <= i__1; ++(*info)) { i__2 = jc + *info - 1; if (ap[i__2].r == 0. && ap[i__2].i == 0.) { return 0; } jc += *info; /* L10: */ } } else { jc = 1; i__1 = *n; for (*info = 1; *info <= i__1; ++(*info)) { i__2 = jc; if (ap[i__2].r == 0. && ap[i__2].i == 0.) { return 0; } jc = jc + *n - *info + 1; /* L20: */ } } } *info = 0; /* Solve A * x = b, A**T * x = b, or A**H * x = b. */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { ztpsv_(uplo, trans, diag, n, &ap[1], &b[j * b_dim1 + 1], &c__1); /* L30: */ } return 0; /* End of ZTPTRS */ } /* ztptrs_ */
/* Subroutine */ int zpptrf_(char *uplo, integer *n, doublecomplex *ap, integer *info) { /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= ZPPTRF computes the Cholesky factorization of a complex Hermitian positive definite matrix A stored in packed format. The factorization has the form A = U**H * U, if UPLO = 'U', or A = L * L**H, if UPLO = 'L', where U is an upper triangular matrix and L is lower triangular. 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/output) COMPLEX*16 array, dimension (N*(N+1)/2) On entry, the upper or lower triangle of the Hermitian 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. See below for further details. On exit, if INFO = 0, the triangular factor U or L from the Cholesky factorization A = U**H*U or A = L*L**H, in the same storage format as A. INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, the leading minor of order i is not positive definite, and the factorization could not be completed. Further Details =============== The packed storage scheme is illustrated by the following example when N = 4, UPLO = 'U': Two-dimensional storage of the Hermitian matrix A: a11 a12 a13 a14 a22 a23 a24 a33 a34 (aij = conjg(aji)) a44 Packed storage of the upper triangle of A: AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ] ===================================================================== Test the input parameters. Parameter adjustments */ /* Table of constant values */ static integer c__1 = 1; static doublereal c_b16 = -1.; /* System generated locals */ integer i__1, i__2, i__3; doublereal d__1; doublecomplex z__1, z__2; /* Builtin functions */ double sqrt(doublereal); /* Local variables */ extern /* Subroutine */ int zhpr_(char *, integer *, doublereal *, doublecomplex *, integer *, doublecomplex *); static integer j; extern logical lsame_(char *, char *); extern /* Double Complex */ VOID zdotc_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); static logical upper; extern /* Subroutine */ int ztpsv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *); static integer jc, jj; extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_( integer *, doublereal *, doublecomplex *, integer *); static doublereal ajj; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } if (*info != 0) { i__1 = -(*info); xerbla_("ZPPTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (upper) { /* Compute the Cholesky factorization A = U'*U. */ jj = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { jc = jj + 1; jj += j; /* Compute elements 1:J-1 of column J. */ if (j > 1) { i__2 = j - 1; ztpsv_("Upper", "Conjugate transpose", "Non-unit", &i__2, &ap[ 1], &ap[jc], &c__1); } /* Compute U(J,J) and test for non-positive-definiteness. */ i__2 = jj; d__1 = ap[i__2].r; i__3 = j - 1; zdotc_(&z__2, &i__3, &ap[jc], &c__1, &ap[jc], &c__1); z__1.r = d__1 - z__2.r, z__1.i = -z__2.i; ajj = z__1.r; if (ajj <= 0.) { i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; goto L30; } i__2 = jj; d__1 = sqrt(ajj); ap[i__2].r = d__1, ap[i__2].i = 0.; /* L10: */ } } else { /* Compute the Cholesky factorization A = L*L'. */ jj = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Compute L(J,J) and test for non-positive-definiteness. */ i__2 = jj; ajj = ap[i__2].r; if (ajj <= 0.) { i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; goto L30; } ajj = sqrt(ajj); i__2 = jj; ap[i__2].r = ajj, ap[i__2].i = 0.; /* Compute elements J+1:N of column J and update the trailing submatrix. */ if (j < *n) { i__2 = *n - j; d__1 = 1. / ajj; zdscal_(&i__2, &d__1, &ap[jj + 1], &c__1); i__2 = *n - j; zhpr_("Lower", &i__2, &c_b16, &ap[jj + 1], &c__1, &ap[jj + *n - j + 1]); jj = jj + *n - j + 1; } /* L20: */ } } goto L40; L30: *info = j; L40: return 0; /* End of ZPPTRF */ } /* zpptrf_ */
/* Subroutine */ int zhpgst_(integer *itype, char *uplo, integer *n, doublecomplex *ap, doublecomplex *bp, integer *info) { /* System generated locals */ integer i__1, i__2, i__3, i__4; doublereal d__1, d__2; doublecomplex z__1, z__2, z__3; /* Local variables */ integer j, k, j1, k1, jj, kk; doublecomplex ct; doublereal ajj; integer j1j1; doublereal akk; integer k1k1; doublereal bjj, bkk; extern /* Subroutine */ int zhpr2_(char *, integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *); extern logical lsame_(char *, char *); extern /* Double Complex */ VOID zdotc_f2c_(doublecomplex *, integer *, doublecomplex *, integer *, doublecomplex *, integer *); logical upper; extern /* Subroutine */ int zhpmv_(char *, integer *, doublecomplex *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, doublecomplex *, integer *), zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, doublecomplex *, integer *), ztpmv_(char *, char *, char *, integer *, doublecomplex *, doublecomplex *, integer *), ztpsv_(char *, char *, char *, integer *, doublecomplex * , doublecomplex *, integer *), xerbla_( char *, integer *), zdscal_(integer *, doublereal *, doublecomplex *, 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 .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ --bp; --ap; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (*itype < 1 || *itype > 3) { *info = -1; } else if (! upper && ! lsame_(uplo, "L")) { *info = -2; } else if (*n < 0) { *info = -3; } if (*info != 0) { i__1 = -(*info); xerbla_("ZHPGST", &i__1); return 0; } if (*itype == 1) { if (upper) { /* Compute inv(U**H)*A*inv(U) */ /* J1 and JJ are the indices of A(1,j) and A(j,j) */ jj = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { j1 = jj + 1; jj += j; /* Compute the j-th column of the upper triangle of A */ i__2 = jj; i__3 = jj; d__1 = ap[i__3].r; ap[i__2].r = d__1; ap[i__2].i = 0.; // , expr subst i__2 = jj; bjj = bp[i__2].r; ztpsv_(uplo, "Conjugate transpose", "Non-unit", &j, &bp[1], & ap[j1], &c__1); i__2 = j - 1; z__1.r = -1.; z__1.i = -0.; // , expr subst zhpmv_(uplo, &i__2, &z__1, &ap[1], &bp[j1], &c__1, &c_b1, &ap[ j1], &c__1); i__2 = j - 1; d__1 = 1. / bjj; zdscal_(&i__2, &d__1, &ap[j1], &c__1); i__2 = jj; i__3 = jj; i__4 = j - 1; zdotc_f2c_(&z__3, &i__4, &ap[j1], &c__1, &bp[j1], &c__1); z__2.r = ap[i__3].r - z__3.r; z__2.i = ap[i__3].i - z__3.i; // , expr subst z__1.r = z__2.r / bjj; z__1.i = z__2.i / bjj; // , expr subst ap[i__2].r = z__1.r; ap[i__2].i = z__1.i; // , expr subst /* L10: */ } } else { /* Compute inv(L)*A*inv(L**H) */ /* KK and K1K1 are the indices of A(k,k) and A(k+1,k+1) */ kk = 1; i__1 = *n; for (k = 1; k <= i__1; ++k) { k1k1 = kk + *n - k + 1; /* Update the lower triangle of A(k:n,k:n) */ i__2 = kk; akk = ap[i__2].r; i__2 = kk; bkk = bp[i__2].r; /* Computing 2nd power */ d__1 = bkk; akk /= d__1 * d__1; i__2 = kk; ap[i__2].r = akk; ap[i__2].i = 0.; // , expr subst if (k < *n) { i__2 = *n - k; d__1 = 1. / bkk; zdscal_(&i__2, &d__1, &ap[kk + 1], &c__1); d__1 = akk * -.5; ct.r = d__1; ct.i = 0.; // , expr subst i__2 = *n - k; zaxpy_(&i__2, &ct, &bp[kk + 1], &c__1, &ap[kk + 1], &c__1) ; i__2 = *n - k; z__1.r = -1.; z__1.i = -0.; // , expr subst zhpr2_(uplo, &i__2, &z__1, &ap[kk + 1], &c__1, &bp[kk + 1] , &c__1, &ap[k1k1]); i__2 = *n - k; zaxpy_(&i__2, &ct, &bp[kk + 1], &c__1, &ap[kk + 1], &c__1) ; i__2 = *n - k; ztpsv_(uplo, "No transpose", "Non-unit", &i__2, &bp[k1k1], &ap[kk + 1], &c__1); } kk = k1k1; /* L20: */ } } } else { if (upper) { /* Compute U*A*U**H */ /* K1 and KK are the indices of A(1,k) and A(k,k) */ kk = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { k1 = kk + 1; kk += k; /* Update the upper triangle of A(1:k,1:k) */ i__2 = kk; akk = ap[i__2].r; i__2 = kk; bkk = bp[i__2].r; i__2 = k - 1; ztpmv_(uplo, "No transpose", "Non-unit", &i__2, &bp[1], &ap[ k1], &c__1); d__1 = akk * .5; ct.r = d__1; ct.i = 0.; // , expr subst i__2 = k - 1; zaxpy_(&i__2, &ct, &bp[k1], &c__1, &ap[k1], &c__1); i__2 = k - 1; zhpr2_(uplo, &i__2, &c_b1, &ap[k1], &c__1, &bp[k1], &c__1, & ap[1]); i__2 = k - 1; zaxpy_(&i__2, &ct, &bp[k1], &c__1, &ap[k1], &c__1); i__2 = k - 1; zdscal_(&i__2, &bkk, &ap[k1], &c__1); i__2 = kk; /* Computing 2nd power */ d__2 = bkk; d__1 = akk * (d__2 * d__2); ap[i__2].r = d__1; ap[i__2].i = 0.; // , expr subst /* L30: */ } } else { /* Compute L**H *A*L */ /* JJ and J1J1 are the indices of A(j,j) and A(j+1,j+1) */ jj = 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { j1j1 = jj + *n - j + 1; /* Compute the j-th column of the lower triangle of A */ i__2 = jj; ajj = ap[i__2].r; i__2 = jj; bjj = bp[i__2].r; i__2 = jj; d__1 = ajj * bjj; i__3 = *n - j; zdotc_f2c_(&z__2, &i__3, &ap[jj + 1], &c__1, &bp[jj + 1], &c__1); z__1.r = d__1 + z__2.r; z__1.i = z__2.i; // , expr subst ap[i__2].r = z__1.r; ap[i__2].i = z__1.i; // , expr subst i__2 = *n - j; zdscal_(&i__2, &bjj, &ap[jj + 1], &c__1); i__2 = *n - j; zhpmv_(uplo, &i__2, &c_b1, &ap[j1j1], &bp[jj + 1], &c__1, & c_b1, &ap[jj + 1], &c__1); i__2 = *n - j + 1; ztpmv_(uplo, "Conjugate transpose", "Non-unit", &i__2, &bp[jj] , &ap[jj], &c__1); jj = j1j1; /* L40: */ } } } return 0; /* End of ZHPGST */ }