/* DECK CDOTC */ /* Complex */ void cdotc_(complex * ret_val, integer *n, complex *cx, integer *incx, complex *cy, integer *incy) { /* System generated locals */ integer i__1, i__2, i__3; complex q__1, q__2, q__3; /* Local variables */ static integer i__, ns, kx, ky; /* ***BEGIN PROLOGUE CDOTC */ /* ***PURPOSE Dot product of two complex vectors using the complex */ /* conjugate of the first vector. */ /* ***LIBRARY SLATEC (BLAS) */ /* ***CATEGORY D1A4 */ /* ***TYPE COMPLEX (CDOTC-C) */ /* ***KEYWORDS BLAS, INNER PRODUCT, LINEAR ALGEBRA, VECTOR */ /* ***AUTHOR Lawson, C. L., (JPL) */ /* Hanson, R. J., (SNLA) */ /* Kincaid, D. R., (U. of Texas) */ /* Krogh, F. T., (JPL) */ /* ***DESCRIPTION */ /* B L A S Subprogram */ /* Description of Parameters */ /* --Input-- */ /* N number of elements in input vector(s) */ /* CX complex vector with N elements */ /* INCX storage spacing between elements of CX */ /* CY complex vector with N elements */ /* INCY storage spacing between elements of CY */ /* --Output-- */ /* CDOTC complex result (zero if N .LE. 0) */ /* Returns the dot product of complex CX and CY, using CONJUGATE(CX) */ /* CDOTC = SUM for I = 0 to N-1 of CONJ(CX(LX+I*INCX))*CY(LY+I*INCY), */ /* where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is */ /* defined in a similar way using INCY. */ /* ***REFERENCES C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T. */ /* Krogh, Basic linear algebra subprograms for Fortran */ /* usage, Algorithm No. 539, Transactions on Mathematical */ /* Software 5, 3 (September 1979), pp. 308-323. */ /* ***ROUTINES CALLED (NONE) */ /* ***REVISION HISTORY (YYMMDD) */ /* 791001 DATE WRITTEN */ /* 890831 Modified array declarations. (WRB) */ /* 890831 REVISION DATE from Version 3.2 */ /* 891214 Prologue converted to Version 4.0 format. (BAB) */ /* 920310 Corrected definition of LX in DESCRIPTION. (WRB) */ /* 920501 Reformatted the REFERENCES section. (WRB) */ /* ***END PROLOGUE CDOTC */ /* ***FIRST EXECUTABLE STATEMENT CDOTC */ /* Parameter adjustments */ --cy; --cx; /* Function Body */ ret_val->r = 0.f, ret_val->i = 0.f; if (*n <= 0) { return ; } if (*incx == *incy && *incx > 0) { goto L20; } /* Code for unequal or nonpositive increments. */ kx = 1; ky = 1; if (*incx < 0) { kx = (1 - *n) * *incx + 1; } if (*incy < 0) { ky = (1 - *n) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { r_cnjg(&q__3, &cx[kx]); i__2 = ky; q__2.r = q__3.r * cy[i__2].r - q__3.i * cy[i__2].i, q__2.i = q__3.r * cy[i__2].i + q__3.i * cy[i__2].r; q__1.r = ret_val->r + q__2.r, q__1.i = ret_val->i + q__2.i; ret_val->r = q__1.r, ret_val->i = q__1.i; kx += *incx; ky += *incy; /* L10: */ } return ; /* Code for equal, positive increments. */ L20: ns = *n * *incx; i__1 = ns; i__2 = *incx; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { r_cnjg(&q__3, &cx[i__]); i__3 = i__; q__2.r = q__3.r * cy[i__3].r - q__3.i * cy[i__3].i, q__2.i = q__3.r * cy[i__3].i + q__3.i * cy[i__3].r; q__1.r = ret_val->r + q__2.r, q__1.i = ret_val->i + q__2.i; ret_val->r = q__1.r, ret_val->i = q__1.i; /* L30: */ } return ; } /* cdotc_ */
/* Subroutine */ int clatrs_(char *uplo, char *trans, char *diag, char * normin, integer *n, complex *a, integer *lda, complex *x, real *scale, real *cnorm, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4; complex q__1, q__2, q__3, q__4; /* Builtin functions */ double r_imag(complex *); void r_cnjg(complex *, complex *); /* Local variables */ integer i__, j; real xj, rec, tjj; integer jinc; real xbnd; integer imax; real tmax; complex tjjs; real xmax, grow; extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer *, complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *); real tscal; complex uscal; integer jlast; extern /* Complex */ VOID cdotu_(complex *, integer *, complex *, integer *, complex *, integer *); complex csumj; extern /* Subroutine */ int caxpy_(integer *, complex *, complex *, integer *, complex *, integer *); logical upper; extern /* Subroutine */ int ctrsv_(char *, char *, char *, integer *, complex *, integer *, complex *, integer *), slabad_(real *, real *); extern integer icamax_(integer *, complex *, integer *); extern /* Complex */ VOID cladiv_(complex *, complex *, complex *); extern doublereal slamch_(char *); extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer *), xerbla_(char *, integer *); real bignum; extern integer isamax_(integer *, real *, integer *); extern doublereal scasum_(integer *, complex *, integer *); logical notran; integer jfirst; real smlnum; logical nounit; /* -- LAPACK auxiliary routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CLATRS 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. Here A is an upper or lower */ /* triangular matrix, 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 */ /* CTRSV 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. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The triangular matrix A. If UPLO = 'U', the leading n by n */ /* upper triangular part of the array A contains the upper */ /* triangular matrix, and the strictly lower triangular part of */ /* A is not referenced. If UPLO = 'L', the leading n by n lower */ /* triangular part of the array A contains the lower triangular */ /* matrix, and the strictly upper triangular part of A is not */ /* referenced. If DIAG = 'U', the diagonal elements of A are */ /* also not referenced and are assumed to be 1. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max (1,N). */ /* X (input/output) COMPLEX 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) REAL */ /* 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) REAL 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, CTRSV */ /* 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 CTRSV 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 CTRSV if 1/M(n) and 1/G(n) are both greater */ /* than max(underflow, 1/overflow). */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --x; --cnorm; /* 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; } else if (*lda < max(1,*n)) { *info = -7; } if (*info != 0) { i__1 = -(*info); xerbla_("CLATRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine machine dependent parameters to control overflow. */ smlnum = slamch_("Safe minimum"); bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); smlnum /= slamch_("Precision"); bignum = 1.f / smlnum; *scale = 1.f; if (lsame_(normin, "N")) { /* Compute the 1-norm of each column, not including the diagonal. */ if (upper) { /* A is upper triangular. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; cnorm[j] = scasum_(&i__2, &a[j * a_dim1 + 1], &c__1); /* L10: */ } } else { /* A is lower triangular. */ i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { i__2 = *n - j; cnorm[j] = scasum_(&i__2, &a[j + 1 + j * a_dim1], &c__1); /* L20: */ } cnorm[*n] = 0.f; } } /* Scale the column norms by TSCAL if the maximum element in CNORM is */ /* greater than BIGNUM/2. */ imax = isamax_(n, &cnorm[1], &c__1); tmax = cnorm[imax]; if (tmax <= bignum * .5f) { tscal = 1.f; } else { tscal = .5f / (smlnum * tmax); sscal_(n, &tscal, &cnorm[1], &c__1); } /* Compute a bound on the computed solution vector to see if the */ /* Level 2 BLAS routine CTRSV can be used. */ xmax = 0.f; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = j; r__3 = xmax, r__4 = (r__1 = x[i__2].r / 2.f, dabs(r__1)) + (r__2 = r_imag(&x[j]) / 2.f, dabs(r__2)); xmax = dmax(r__3,r__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.f) { grow = 0.f; 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 = .5f / dmax(xbnd,smlnum); xbnd = grow; 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 = j + j * a_dim1; tjjs.r = a[i__3].r, tjjs.i = a[i__3].i; tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj >= smlnum) { /* M(j) = G(j-1) / abs(A(j,j)) */ /* Computing MIN */ r__1 = xbnd, r__2 = dmin(1.f,tjj) * grow; xbnd = dmin(r__1,r__2); } else { /* M(j) could overflow, set XBND to 0. */ xbnd = 0.f; } 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.f; } /* L40: */ } grow = xbnd; } else { /* A is unit triangular. */ /* Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */ /* Computing MIN */ r__1 = 1.f, r__2 = .5f / dmax(xbnd,smlnum); grow = dmin(r__1,r__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.f / (cnorm[j] + 1.f); /* 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.f) { grow = 0.f; 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 = .5f / dmax(xbnd,smlnum); xbnd = grow; 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.f; /* Computing MIN */ r__1 = grow, r__2 = xbnd / xj; grow = dmin(r__1,r__2); i__3 = j + j * a_dim1; tjjs.r = a[i__3].r, tjjs.i = a[i__3].i; tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__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.f; } /* L70: */ } grow = dmin(grow,xbnd); } else { /* A is unit triangular. */ /* Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */ /* Computing MIN */ r__1 = 1.f, r__2 = .5f / dmax(xbnd,smlnum); grow = dmin(r__1,r__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.f; 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. */ ctrsv_(uplo, trans, diag, n, &a[a_offset], lda, &x[1], &c__1); } else { /* Use a Level 1 BLAS solve, scaling intermediate results. */ if (xmax > bignum * .5f) { /* Scale X so that its components are less than or equal to */ /* BIGNUM in absolute value. */ *scale = bignum * .5f / xmax; csscal_(n, scale, &x[1], &c__1); xmax = bignum; } else { xmax *= 2.f; } if (notran) { /* Solve A * x = b */ 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 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), dabs(r__2)); if (nounit) { i__3 = j + j * a_dim1; q__1.r = tscal * a[i__3].r, q__1.i = tscal * a[i__3].i; tjjs.r = q__1.r, tjjs.i = q__1.i; } else { tjjs.r = tscal, tjjs.i = 0.f; if (tscal == 1.f) { goto L105; } } tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.f) { if (xj > tjj * bignum) { /* Scale x by 1/b(j). */ rec = 1.f / xj; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; i__3 = j; xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j] ), dabs(r__2)); } else if (tjj > 0.f) { /* 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.f) { /* Scale by 1/CNORM(j) to avoid overflow when */ /* multiplying x(j) times column j. */ rec /= cnorm[j]; } csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; i__3 = j; xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j] ), dabs(r__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.f, x[i__4].i = 0.f; /* L100: */ } i__3 = j; x[i__3].r = 1.f, x[i__3].i = 0.f; xj = 1.f; *scale = 0.f; xmax = 0.f; } L105: /* Scale x if necessary to avoid overflow when adding a */ /* multiple of column j of A. */ if (xj > 1.f) { rec = 1.f / xj; if (cnorm[j] > (bignum - xmax) * rec) { /* Scale x by 1/(2*abs(x(j))). */ rec *= .5f; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; } } else if (xj * cnorm[j] > bignum - xmax) { /* Scale x by 1/2. */ csscal_(n, &c_b36, &x[1], &c__1); *scale *= .5f; } 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; q__2.r = -x[i__4].r, q__2.i = -x[i__4].i; q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i; caxpy_(&i__3, &q__1, &a[j * a_dim1 + 1], &c__1, &x[1], &c__1); i__3 = j - 1; i__ = icamax_(&i__3, &x[1], &c__1); i__3 = i__; xmax = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[i__]), dabs(r__2)); } } 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; q__2.r = -x[i__4].r, q__2.i = -x[i__4].i; q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i; caxpy_(&i__3, &q__1, &a[j + 1 + j * a_dim1], &c__1, & x[j + 1], &c__1); i__3 = *n - j; i__ = j + icamax_(&i__3, &x[j + 1], &c__1); i__3 = i__; xmax = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[i__]), dabs(r__2)); } } /* L110: */ } } else if (lsame_(trans, "T")) { /* Solve A**T * x = b */ 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 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), dabs(r__2)); uscal.r = tscal, uscal.i = 0.f; rec = 1.f / dmax(xmax,1.f); if (cnorm[j] > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2*XMAX). */ rec *= .5f; if (nounit) { i__3 = j + j * a_dim1; q__1.r = tscal * a[i__3].r, q__1.i = tscal * a[i__3] .i; tjjs.r = q__1.r, tjjs.i = q__1.i; } else { tjjs.r = tscal, tjjs.i = 0.f; } tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj > 1.f) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. */ /* Computing MIN */ r__1 = 1.f, r__2 = rec * tjj; rec = dmin(r__1,r__2); cladiv_(&q__1, &uscal, &tjjs); uscal.r = q__1.r, uscal.i = q__1.i; } if (rec < 1.f) { csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0.f, csumj.i = 0.f; if (uscal.r == 1.f && uscal.i == 0.f) { /* If the scaling needed for A in the dot product is 1, */ /* call CDOTU to perform the dot product. */ if (upper) { i__3 = j - 1; cdotu_(&q__1, &i__3, &a[j * a_dim1 + 1], &c__1, &x[1], &c__1); csumj.r = q__1.r, csumj.i = q__1.i; } else if (j < *n) { i__3 = *n - j; cdotu_(&q__1, &i__3, &a[j + 1 + j * a_dim1], &c__1, & x[j + 1], &c__1); csumj.r = q__1.r, csumj.i = q__1.i; } } 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 = i__ + j * a_dim1; q__3.r = a[i__4].r * uscal.r - a[i__4].i * uscal.i, q__3.i = a[i__4].r * uscal.i + a[ i__4].i * uscal.r; i__5 = i__; q__2.r = q__3.r * x[i__5].r - q__3.i * x[i__5].i, q__2.i = q__3.r * x[i__5].i + q__3.i * x[ i__5].r; q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + q__2.i; csumj.r = q__1.r, csumj.i = q__1.i; /* L120: */ } } else if (j < *n) { i__3 = *n; for (i__ = j + 1; i__ <= i__3; ++i__) { i__4 = i__ + j * a_dim1; q__3.r = a[i__4].r * uscal.r - a[i__4].i * uscal.i, q__3.i = a[i__4].r * uscal.i + a[ i__4].i * uscal.r; i__5 = i__; q__2.r = q__3.r * x[i__5].r - q__3.i * x[i__5].i, q__2.i = q__3.r * x[i__5].i + q__3.i * x[ i__5].r; q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + q__2.i; csumj.r = q__1.r, csumj.i = q__1.i; /* L130: */ } } } q__1.r = tscal, q__1.i = 0.f; if (uscal.r == q__1.r && uscal.i == q__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; q__1.r = x[i__4].r - csumj.r, q__1.i = x[i__4].i - csumj.i; x[i__3].r = q__1.r, x[i__3].i = q__1.i; i__3 = j; xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j] ), dabs(r__2)); if (nounit) { i__3 = j + j * a_dim1; q__1.r = tscal * a[i__3].r, q__1.i = tscal * a[i__3] .i; tjjs.r = q__1.r, tjjs.i = q__1.i; } else { tjjs.r = tscal, tjjs.i = 0.f; if (tscal == 1.f) { goto L145; } } /* Compute x(j) = x(j) / A(j,j), scaling if necessary. */ tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.f) { if (xj > tjj * bignum) { /* Scale X by 1/abs(x(j)). */ rec = 1.f / xj; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; } else if (tjj > 0.f) { /* 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; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; } 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.f, x[i__4].i = 0.f; /* L140: */ } i__3 = j; x[i__3].r = 1.f, x[i__3].i = 0.f; *scale = 0.f; xmax = 0.f; } L145: ; } 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; cladiv_(&q__2, &x[j], &tjjs); q__1.r = q__2.r - csumj.r, q__1.i = q__2.i - csumj.i; x[i__3].r = q__1.r, x[i__3].i = q__1.i; } /* Computing MAX */ i__3 = j; r__3 = xmax, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), dabs(r__2)); xmax = dmax(r__3,r__4); /* L150: */ } } else { /* Solve A**H * x = b */ 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 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), dabs(r__2)); uscal.r = tscal, uscal.i = 0.f; rec = 1.f / dmax(xmax,1.f); if (cnorm[j] > (bignum - xj) * rec) { /* If x(j) could overflow, scale x by 1/(2*XMAX). */ rec *= .5f; if (nounit) { r_cnjg(&q__2, &a[j + j * a_dim1]); q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i; tjjs.r = q__1.r, tjjs.i = q__1.i; } else { tjjs.r = tscal, tjjs.i = 0.f; } tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj > 1.f) { /* Divide by A(j,j) when scaling x if A(j,j) > 1. */ /* Computing MIN */ r__1 = 1.f, r__2 = rec * tjj; rec = dmin(r__1,r__2); cladiv_(&q__1, &uscal, &tjjs); uscal.r = q__1.r, uscal.i = q__1.i; } if (rec < 1.f) { csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } csumj.r = 0.f, csumj.i = 0.f; if (uscal.r == 1.f && uscal.i == 0.f) { /* If the scaling needed for A in the dot product is 1, */ /* call CDOTC to perform the dot product. */ if (upper) { i__3 = j - 1; cdotc_(&q__1, &i__3, &a[j * a_dim1 + 1], &c__1, &x[1], &c__1); csumj.r = q__1.r, csumj.i = q__1.i; } else if (j < *n) { i__3 = *n - j; cdotc_(&q__1, &i__3, &a[j + 1 + j * a_dim1], &c__1, & x[j + 1], &c__1); csumj.r = q__1.r, csumj.i = q__1.i; } } else { /* Otherwise, use in-line code for the dot product. */ if (upper) { i__3 = j - 1; for (i__ = 1; i__ <= i__3; ++i__) { r_cnjg(&q__4, &a[i__ + j * a_dim1]); q__3.r = q__4.r * uscal.r - q__4.i * uscal.i, q__3.i = q__4.r * uscal.i + q__4.i * uscal.r; i__4 = i__; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[ i__4].r; q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + q__2.i; csumj.r = q__1.r, csumj.i = q__1.i; /* L160: */ } } else if (j < *n) { i__3 = *n; for (i__ = j + 1; i__ <= i__3; ++i__) { r_cnjg(&q__4, &a[i__ + j * a_dim1]); q__3.r = q__4.r * uscal.r - q__4.i * uscal.i, q__3.i = q__4.r * uscal.i + q__4.i * uscal.r; i__4 = i__; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[ i__4].r; q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + q__2.i; csumj.r = q__1.r, csumj.i = q__1.i; /* L170: */ } } } q__1.r = tscal, q__1.i = 0.f; if (uscal.r == q__1.r && uscal.i == q__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; q__1.r = x[i__4].r - csumj.r, q__1.i = x[i__4].i - csumj.i; x[i__3].r = q__1.r, x[i__3].i = q__1.i; i__3 = j; xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j] ), dabs(r__2)); if (nounit) { r_cnjg(&q__2, &a[j + j * a_dim1]); q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i; tjjs.r = q__1.r, tjjs.i = q__1.i; } else { tjjs.r = tscal, tjjs.i = 0.f; if (tscal == 1.f) { goto L185; } } /* Compute x(j) = x(j) / A(j,j), scaling if necessary. */ tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), dabs(r__2)); if (tjj > smlnum) { /* abs(A(j,j)) > SMLNUM: */ if (tjj < 1.f) { if (xj > tjj * bignum) { /* Scale X by 1/abs(x(j)). */ rec = 1.f / xj; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; } else if (tjj > 0.f) { /* 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; csscal_(n, &rec, &x[1], &c__1); *scale *= rec; xmax *= rec; } i__3 = j; cladiv_(&q__1, &x[j], &tjjs); x[i__3].r = q__1.r, x[i__3].i = q__1.i; } 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.f, x[i__4].i = 0.f; /* L180: */ } i__3 = j; x[i__3].r = 1.f, x[i__3].i = 0.f; *scale = 0.f; xmax = 0.f; } L185: ; } 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; cladiv_(&q__2, &x[j], &tjjs); q__1.r = q__2.r - csumj.r, q__1.i = q__2.i - csumj.i; x[i__3].r = q__1.r, x[i__3].i = q__1.i; } /* Computing MAX */ i__3 = j; r__3 = xmax, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), dabs(r__2)); xmax = dmax(r__3,r__4); /* L190: */ } } *scale /= tscal; } /* Scale the column norms by 1/TSCAL for return. */ if (tscal != 1.f) { r__1 = 1.f / tscal; sscal_(n, &r__1, &cnorm[1], &c__1); } return 0; /* End of CLATRS */ } /* clatrs_ */
/* Subroutine */ int cgeql2_(integer *m, integer *n, complex *a, integer *lda, complex *tau, complex *work, integer *info) { /* -- LAPACK routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= CGEQL2 computes a QL factorization of a complex m by n matrix A: A = Q * L. Arguments ========= M (input) INTEGER The number of rows of the matrix A. M >= 0. N (input) INTEGER The number of columns of the matrix A. N >= 0. A (input/output) COMPLEX array, dimension (LDA,N) On entry, the m by n matrix A. On exit, if m >= n, the lower triangle of the subarray A(m-n+1:m,1:n) contains the n by n lower triangular matrix L; if m <= n, the elements on and below the (n-m)-th superdiagonal contain the m by n lower trapezoidal matrix L; the remaining elements, with the array TAU, represent the unitary matrix Q as a product of elementary reflectors (see Further Details). LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,M). TAU (output) COMPLEX array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace) COMPLEX array, dimension (N) INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(k) . . . H(2) H(1), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a complex scalar, and v is a complex vector with v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in A(1:m-k+i-1,n-k+i), and tau in TAU(i). ===================================================================== Test the input arguments Parameter adjustments Function Body */ /* Table of constant values */ static integer c__1 = 1; /* System generated locals */ integer a_dim1, a_offset, i__1, i__2; complex q__1; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer i, k; static complex alpha; extern /* Subroutine */ int clarf_(char *, integer *, integer *, complex * , integer *, complex *, complex *, integer *, complex *), clarfg_(integer *, complex *, complex *, integer *, complex *), xerbla_(char *, integer *); #define TAU(I) tau[(I)-1] #define WORK(I) work[(I)-1] #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*m)) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CGEQL2", &i__1); return 0; } k = min(*m,*n); for (i = k; i >= 1; --i) { /* Generate elementary reflector H(i) to annihilate A(1:m-k+i-1,n-k+i) */ i__1 = *m - k + i + (*n - k + i) * a_dim1; alpha.r = A(*m-k+i,*n-k+i).r, alpha.i = A(*m-k+i,*n-k+i).i; i__1 = *m - k + i; clarfg_(&i__1, &alpha, &A(1,*n-k+i), &c__1, &TAU(i)); /* Apply H(i)' to A(1:m-k+i,1:n-k+i-1) from the left */ i__1 = *m - k + i + (*n - k + i) * a_dim1; A(*m-k+i,*n-k+i).r = 1.f, A(*m-k+i,*n-k+i).i = 0.f; i__1 = *m - k + i; i__2 = *n - k + i - 1; r_cnjg(&q__1, &TAU(i)); clarf_("Left", &i__1, &i__2, &A(1,*n-k+i), &c__1, & q__1, &A(1,1), lda, &WORK(1)); i__1 = *m - k + i + (*n - k + i) * a_dim1; A(*m-k+i,*n-k+i).r = alpha.r, A(*m-k+i,*n-k+i).i = alpha.i; /* L10: */ } return 0; /* End of CGEQL2 */ } /* cgeql2_ */
/* Subroutine */ int ctrexc_(char *compq, integer *n, complex *t, integer * ldt, complex *q, integer *ldq, integer *ifst, integer *ilst, integer * info, ftnlen compq_len) { /* System generated locals */ integer q_dim1, q_offset, t_dim1, t_offset, i__1, i__2, i__3; complex q__1; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer k, m1, m2, m3; static real cs; static complex t11, t22, sn, temp; extern /* Subroutine */ int crot_(integer *, complex *, integer *, complex *, integer *, real *, complex *); extern logical lsame_(char *, char *, ftnlen, ftnlen); static logical wantq; extern /* Subroutine */ int clartg_(complex *, complex *, real *, complex *, complex *), xerbla_(char *, integer *, ftnlen); /* -- LAPACK routine (version 3.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ /* Courant Institute, Argonne National Lab, and Rice University */ /* March 31, 1993 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CTREXC reorders the Schur factorization of a complex matrix */ /* A = Q*T*Q**H, so that the diagonal element of T with row index IFST */ /* is moved to row ILST. */ /* The Schur form T is reordered by a unitary similarity transformation */ /* Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by */ /* postmultplying it with Z. */ /* Arguments */ /* ========= */ /* COMPQ (input) CHARACTER*1 */ /* = 'V': update the matrix Q of Schur vectors; */ /* = 'N': do not update Q. */ /* N (input) INTEGER */ /* The order of the matrix T. N >= 0. */ /* T (input/output) COMPLEX array, dimension (LDT,N) */ /* On entry, the upper triangular matrix T. */ /* On exit, the reordered upper triangular matrix. */ /* LDT (input) INTEGER */ /* The leading dimension of the array T. LDT >= max(1,N). */ /* Q (input/output) COMPLEX array, dimension (LDQ,N) */ /* On entry, if COMPQ = 'V', the matrix Q of Schur vectors. */ /* On exit, if COMPQ = 'V', Q has been postmultiplied by the */ /* unitary transformation matrix Z which reorders T. */ /* If COMPQ = 'N', Q is not referenced. */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. LDQ >= max(1,N). */ /* IFST (input) INTEGER */ /* ILST (input) INTEGER */ /* Specify the reordering of the diagonal elements of T: */ /* The element with row index IFST is moved to row ILST by a */ /* sequence of transpositions between adjacent elements. */ /* 1 <= IFST <= N; 1 <= ILST <= 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 .. */ /* Decode and test the input parameters. */ /* Parameter adjustments */ t_dim1 = *ldt; t_offset = 1 + t_dim1; t -= t_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; /* Function Body */ *info = 0; wantq = lsame_(compq, "V", (ftnlen)1, (ftnlen)1); if (! lsame_(compq, "N", (ftnlen)1, (ftnlen)1) && ! wantq) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*ldt < max(1,*n)) { *info = -4; } else if (*ldq < 1 || wantq && *ldq < max(1,*n)) { *info = -6; } else if (*ifst < 1 || *ifst > *n) { *info = -7; } else if (*ilst < 1 || *ilst > *n) { *info = -8; } if (*info != 0) { i__1 = -(*info); xerbla_("CTREXC", &i__1, (ftnlen)6); return 0; } /* Quick return if possible */ if (*n == 1 || *ifst == *ilst) { return 0; } if (*ifst < *ilst) { /* Move the IFST-th diagonal element forward down the diagonal. */ m1 = 0; m2 = -1; m3 = 1; } else { /* Move the IFST-th diagonal element backward up the diagonal. */ m1 = -1; m2 = 0; m3 = -1; } i__1 = *ilst + m2; i__2 = m3; for (k = *ifst + m1; i__2 < 0 ? k >= i__1 : k <= i__1; k += i__2) { /* Interchange the k-th and (k+1)-th diagonal elements. */ i__3 = k + k * t_dim1; t11.r = t[i__3].r, t11.i = t[i__3].i; i__3 = k + 1 + (k + 1) * t_dim1; t22.r = t[i__3].r, t22.i = t[i__3].i; /* Determine the transformation to perform the interchange. */ q__1.r = t22.r - t11.r, q__1.i = t22.i - t11.i; clartg_(&t[k + (k + 1) * t_dim1], &q__1, &cs, &sn, &temp); /* Apply transformation to the matrix T. */ if (k + 2 <= *n) { i__3 = *n - k - 1; crot_(&i__3, &t[k + (k + 2) * t_dim1], ldt, &t[k + 1 + (k + 2) * t_dim1], ldt, &cs, &sn); } i__3 = k - 1; r_cnjg(&q__1, &sn); crot_(&i__3, &t[k * t_dim1 + 1], &c__1, &t[(k + 1) * t_dim1 + 1], & c__1, &cs, &q__1); i__3 = k + k * t_dim1; t[i__3].r = t22.r, t[i__3].i = t22.i; i__3 = k + 1 + (k + 1) * t_dim1; t[i__3].r = t11.r, t[i__3].i = t11.i; if (wantq) { /* Accumulate transformation in the matrix Q. */ r_cnjg(&q__1, &sn); crot_(n, &q[k * q_dim1 + 1], &c__1, &q[(k + 1) * q_dim1 + 1], & c__1, &cs, &q__1); } /* L10: */ } return 0; /* End of CTREXC */ } /* ctrexc_ */
int cgeev_(char *jobvl, char *jobvr, int *n, complex *a, int *lda, complex *w, complex *vl, int *ldvl, complex *vr, int *ldvr, complex *work, int *lwork, float *rwork, int * info) { /* System generated locals */ int a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3; float r__1, r__2; complex q__1, q__2; /* Builtin functions */ double sqrt(double), r_imag(complex *); void r_cnjg(complex *, complex *); /* Local variables */ int i__, k, ihi; float scl; int ilo; float dum[1], eps; complex tmp; int ibal; char side[1]; float anrm; int ierr, itau, iwrk, nout; extern int cscal_(int *, complex *, complex *, int *); extern int lsame_(char *, char *); extern double scnrm2_(int *, complex *, int *); extern int cgebak_(char *, char *, int *, int *, int *, float *, int *, complex *, int *, int *), cgebal_(char *, int *, complex *, int *, int *, int *, float *, int *), slabad_(float *, float *); int scalea; extern double clange_(char *, int *, int *, complex *, int *, float *); float cscale; extern int cgehrd_(int *, int *, int *, complex *, int *, complex *, complex *, int *, int *), clascl_(char *, int *, int *, float *, float *, int *, int *, complex *, int *, int *); extern double slamch_(char *); extern int csscal_(int *, float *, complex *, int *), clacpy_(char *, int *, int *, complex *, int *, complex *, int *), xerbla_(char *, int *); extern int ilaenv_(int *, char *, char *, int *, int *, int *, int *); int select[1]; float bignum; extern int isamax_(int *, float *, int *); extern int chseqr_(char *, char *, int *, int *, int *, complex *, int *, complex *, complex *, int *, complex *, int *, int *), ctrevc_(char *, char *, int *, int *, complex *, int *, complex *, int *, complex *, int *, int *, int *, complex *, float *, int *), cunghr_(int *, int *, int *, complex *, int *, complex *, complex *, int *, int *); int minwrk, maxwrk; int wantvl; float smlnum; int hswork, irwork; int lquery, wantvr; /* -- LAPACK driver routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGEEV computes for an N-by-N complex nonsymmetric matrix A, the */ /* eigenvalues and, optionally, the left and/or right eigenvectors. */ /* The right eigenvector v(j) of A satisfies */ /* A * v(j) = lambda(j) * v(j) */ /* where lambda(j) is its eigenvalue. */ /* The left eigenvector u(j) of A satisfies */ /* u(j)**H * A = lambda(j) * u(j)**H */ /* where u(j)**H denotes the conjugate transpose of u(j). */ /* The computed eigenvectors are normalized to have Euclidean norm */ /* equal to 1 and largest component float. */ /* Arguments */ /* ========= */ /* JOBVL (input) CHARACTER*1 */ /* = 'N': left eigenvectors of A are not computed; */ /* = 'V': left eigenvectors of are computed. */ /* JOBVR (input) CHARACTER*1 */ /* = 'N': right eigenvectors of A are not computed; */ /* = 'V': right eigenvectors of A are computed. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input/output) COMPLEX array, dimension (LDA,N) */ /* On entry, the N-by-N matrix A. */ /* On exit, A has been overwritten. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= MAX(1,N). */ /* W (output) COMPLEX array, dimension (N) */ /* W contains the computed eigenvalues. */ /* VL (output) COMPLEX array, dimension (LDVL,N) */ /* If JOBVL = 'V', the left eigenvectors u(j) are stored one */ /* after another in the columns of VL, in the same order */ /* as their eigenvalues. */ /* If JOBVL = 'N', VL is not referenced. */ /* u(j) = VL(:,j), the j-th column of VL. */ /* LDVL (input) INTEGER */ /* The leading dimension of the array VL. LDVL >= 1; if */ /* JOBVL = 'V', LDVL >= N. */ /* VR (output) COMPLEX array, dimension (LDVR,N) */ /* If JOBVR = 'V', the right eigenvectors v(j) are stored one */ /* after another in the columns of VR, in the same order */ /* as their eigenvalues. */ /* If JOBVR = 'N', VR is not referenced. */ /* v(j) = VR(:,j), the j-th column of VR. */ /* LDVR (input) INTEGER */ /* The leading dimension of the array VR. LDVR >= 1; if */ /* JOBVR = 'V', LDVR >= N. */ /* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */ /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. LWORK >= MAX(1,2*N). */ /* For good performance, LWORK must generally be larger. */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the optimal size of the WORK array, returns */ /* this value as the first entry of the WORK array, and no error */ /* message related to LWORK is issued by XERBLA. */ /* RWORK (workspace) REAL array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value. */ /* > 0: if INFO = i, the QR algorithm failed to compute all the */ /* eigenvalues, and no eigenvectors have been computed; */ /* elements and i+1:N of W contain eigenvalues which have */ /* converged. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input arguments */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --w; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1; vr -= vr_offset; --work; --rwork; /* Function Body */ *info = 0; lquery = *lwork == -1; wantvl = lsame_(jobvl, "V"); wantvr = lsame_(jobvr, "V"); if (! wantvl && ! lsame_(jobvl, "N")) { *info = -1; } else if (! wantvr && ! lsame_(jobvr, "N")) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*lda < MAX(1,*n)) { *info = -5; } else if (*ldvl < 1 || wantvl && *ldvl < *n) { *info = -8; } else if (*ldvr < 1 || wantvr && *ldvr < *n) { *info = -10; } /* Compute workspace */ /* (Note: Comments in the code beginning "Workspace:" describe the */ /* minimal amount of workspace needed at that point in the code, */ /* as well as the preferred amount for good performance. */ /* CWorkspace refers to complex workspace, and RWorkspace to float */ /* workspace. NB refers to the optimal block size for the */ /* immediately following subroutine, as returned by ILAENV. */ /* HSWORK refers to the workspace preferred by CHSEQR, as */ /* calculated below. HSWORK is computed assuming ILO=1 and IHI=N, */ /* the worst case.) */ if (*info == 0) { if (*n == 0) { minwrk = 1; maxwrk = 1; } else { maxwrk = *n + *n * ilaenv_(&c__1, "CGEHRD", " ", n, &c__1, n, & c__0); minwrk = *n << 1; if (wantvl) { /* Computing MAX */ i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "CUNGHR", " ", n, &c__1, n, &c_n1); maxwrk = MAX(i__1,i__2); chseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vl[ vl_offset], ldvl, &work[1], &c_n1, info); } else if (wantvr) { /* Computing MAX */ i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "CUNGHR", " ", n, &c__1, n, &c_n1); maxwrk = MAX(i__1,i__2); chseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[1], &c_n1, info); } else { chseqr_("E", "N", n, &c__1, n, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[1], &c_n1, info); } hswork = work[1].r; /* Computing MAX */ i__1 = MAX(maxwrk,hswork); maxwrk = MAX(i__1,minwrk); } work[1].r = (float) maxwrk, work[1].i = 0.f; if (*lwork < minwrk && ! lquery) { *info = -12; } } if (*info != 0) { i__1 = -(*info); xerbla_("CGEEV ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Get machine constants */ eps = slamch_("P"); smlnum = slamch_("S"); bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); smlnum = sqrt(smlnum) / eps; bignum = 1.f / smlnum; /* Scale A if max element outside range [SMLNUM,BIGNUM] */ anrm = clange_("M", n, n, &a[a_offset], lda, dum); scalea = FALSE; if (anrm > 0.f && anrm < smlnum) { scalea = TRUE; cscale = smlnum; } else if (anrm > bignum) { scalea = TRUE; cscale = bignum; } if (scalea) { clascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, & ierr); } /* Balance the matrix */ /* (CWorkspace: none) */ /* (RWorkspace: need N) */ ibal = 1; cgebal_("B", n, &a[a_offset], lda, &ilo, &ihi, &rwork[ibal], &ierr); /* Reduce to upper Hessenberg form */ /* (CWorkspace: need 2*N, prefer N+N*NB) */ /* (RWorkspace: none) */ itau = 1; iwrk = itau + *n; i__1 = *lwork - iwrk + 1; cgehrd_(n, &ilo, &ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, &ierr); if (wantvl) { /* Want left eigenvectors */ /* Copy Householder vectors to VL */ *(unsigned char *)side = 'L'; clacpy_("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl) ; /* Generate unitary matrix in VL */ /* (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */ /* (RWorkspace: none) */ i__1 = *lwork - iwrk + 1; cunghr_(n, &ilo, &ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk], &i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VL */ /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vl[ vl_offset], ldvl, &work[iwrk], &i__1, info); if (wantvr) { /* Want left and right eigenvectors */ /* Copy Schur vectors to VR */ *(unsigned char *)side = 'B'; clacpy_("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr); } } else if (wantvr) { /* Want right eigenvectors */ /* Copy Householder vectors to VR */ *(unsigned char *)side = 'R'; clacpy_("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr) ; /* Generate unitary matrix in VR */ /* (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */ /* (RWorkspace: none) */ i__1 = *lwork - iwrk + 1; cunghr_(n, &ilo, &ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk], &i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VR */ /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[iwrk], &i__1, info); } else { /* Compute eigenvalues only */ /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_("E", "N", n, &ilo, &ihi, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[iwrk], &i__1, info); } /* If INFO > 0 from CHSEQR, then quit */ if (*info > 0) { goto L50; } if (wantvl || wantvr) { /* Compute left and/or right eigenvectors */ /* (CWorkspace: need 2*N) */ /* (RWorkspace: need 2*N) */ irwork = ibal + *n; ctrevc_(side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &rwork[irwork], &ierr); } if (wantvl) { /* Undo balancing of left eigenvectors */ /* (CWorkspace: none) */ /* (RWorkspace: need N) */ cgebak_("B", "L", n, &ilo, &ihi, &rwork[ibal], n, &vl[vl_offset], ldvl, &ierr); /* Normalize left eigenvectors and make largest component float */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scl = 1.f / scnrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1); csscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + i__ * vl_dim1; /* Computing 2nd power */ r__1 = vl[i__3].r; /* Computing 2nd power */ r__2 = r_imag(&vl[k + i__ * vl_dim1]); rwork[irwork + k - 1] = r__1 * r__1 + r__2 * r__2; /* L10: */ } k = isamax_(n, &rwork[irwork], &c__1); r_cnjg(&q__2, &vl[k + i__ * vl_dim1]); r__1 = sqrt(rwork[irwork + k - 1]); q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; tmp.r = q__1.r, tmp.i = q__1.i; cscal_(n, &tmp, &vl[i__ * vl_dim1 + 1], &c__1); i__2 = k + i__ * vl_dim1; i__3 = k + i__ * vl_dim1; r__1 = vl[i__3].r; q__1.r = r__1, q__1.i = 0.f; vl[i__2].r = q__1.r, vl[i__2].i = q__1.i; /* L20: */ } } if (wantvr) { /* Undo balancing of right eigenvectors */ /* (CWorkspace: none) */ /* (RWorkspace: need N) */ cgebak_("B", "R", n, &ilo, &ihi, &rwork[ibal], n, &vr[vr_offset], ldvr, &ierr); /* Normalize right eigenvectors and make largest component float */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scl = 1.f / scnrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1); csscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + i__ * vr_dim1; /* Computing 2nd power */ r__1 = vr[i__3].r; /* Computing 2nd power */ r__2 = r_imag(&vr[k + i__ * vr_dim1]); rwork[irwork + k - 1] = r__1 * r__1 + r__2 * r__2; /* L30: */ } k = isamax_(n, &rwork[irwork], &c__1); r_cnjg(&q__2, &vr[k + i__ * vr_dim1]); r__1 = sqrt(rwork[irwork + k - 1]); q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; tmp.r = q__1.r, tmp.i = q__1.i; cscal_(n, &tmp, &vr[i__ * vr_dim1 + 1], &c__1); i__2 = k + i__ * vr_dim1; i__3 = k + i__ * vr_dim1; r__1 = vr[i__3].r; q__1.r = r__1, q__1.i = 0.f; vr[i__2].r = q__1.r, vr[i__2].i = q__1.i; /* L40: */ } } /* Undo scaling if necessary */ L50: if (scalea) { i__1 = *n - *info; /* Computing MAX */ i__3 = *n - *info; i__2 = MAX(i__3,1); clascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[*info + 1] , &i__2, &ierr); if (*info > 0) { i__1 = ilo - 1; clascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[1], n, &ierr); } } work[1].r = (float) maxwrk, work[1].i = 0.f; return 0; /* End of CGEEV */ } /* cgeev_ */
int chgeqz_(char *job, char *compq, char *compz, int *n, int *ilo, int *ihi, complex *h__, int *ldh, complex *t, int *ldt, complex *alpha, complex *beta, complex *q, int *ldq, complex *z__, int *ldz, complex *work, int *lwork, float * rwork, int *info) { /* System generated locals */ int h_dim1, h_offset, q_dim1, q_offset, t_dim1, t_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6; float r__1, r__2, r__3, r__4, r__5, r__6; complex q__1, q__2, q__3, q__4, q__5, q__6; /* Builtin functions */ double c_abs(complex *); void r_cnjg(complex *, complex *); double r_imag(complex *); void c_div(complex *, complex *, complex *), pow_ci(complex *, complex *, int *), c_sqrt(complex *, complex *); /* Local variables */ float c__; int j; complex s, t1; int jc, in; complex u12; int jr; complex ad11, ad12, ad21, ad22; int jch; int ilq, ilz; float ulp; complex abi22; float absb, atol, btol, temp; extern int crot_(int *, complex *, int *, complex *, int *, float *, complex *); float temp2; extern int cscal_(int *, complex *, complex *, int *); extern int lsame_(char *, char *); complex ctemp; int iiter, ilast, jiter; float anorm, bnorm; int maxit; complex shift; float tempr; complex ctemp2, ctemp3; int ilazr2; float ascale, bscale; complex signbc; extern double slamch_(char *), clanhs_(char *, int *, complex *, int *, float *); extern int claset_(char *, int *, int *, complex *, complex *, complex *, int *), clartg_(complex *, complex *, float *, complex *, complex *); float safmin; extern int xerbla_(char *, int *); complex eshift; int ilschr; int icompq, ilastm; complex rtdisc; int ischur; int ilazro; int icompz, ifirst, ifrstm, istart; int lquery; /* -- LAPACK routine (version 3.2) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CHGEQZ computes the eigenvalues of a complex matrix pair (H,T), */ /* where H is an upper Hessenberg matrix and T is upper triangular, */ /* using the single-shift QZ method. */ /* Matrix pairs of this type are produced by the reduction to */ /* generalized upper Hessenberg form of a complex matrix pair (A,B): */ /* A = Q1*H*Z1**H, B = Q1*T*Z1**H, */ /* as computed by CGGHRD. */ /* If JOB='S', then the Hessenberg-triangular pair (H,T) is */ /* also reduced to generalized Schur form, */ /* H = Q*S*Z**H, T = Q*P*Z**H, */ /* where Q and Z are unitary matrices and S and P are upper triangular. */ /* Optionally, the unitary matrix Q from the generalized Schur */ /* factorization may be postmultiplied into an input matrix Q1, and the */ /* unitary matrix Z may be postmultiplied into an input matrix Z1. */ /* If Q1 and Z1 are the unitary matrices from CGGHRD that reduced */ /* the matrix pair (A,B) to generalized Hessenberg form, then the output */ /* matrices Q1*Q and Z1*Z are the unitary factors from the generalized */ /* Schur factorization of (A,B): */ /* A = (Q1*Q)*S*(Z1*Z)**H, B = (Q1*Q)*P*(Z1*Z)**H. */ /* To avoid overflow, eigenvalues of the matrix pair (H,T) */ /* (equivalently, of (A,B)) are computed as a pair of complex values */ /* (alpha,beta). If beta is nonzero, lambda = alpha / beta is an */ /* eigenvalue of the generalized nonsymmetric eigenvalue problem (GNEP) */ /* A*x = lambda*B*x */ /* and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the */ /* alternate form of the GNEP */ /* mu*A*y = B*y. */ /* The values of alpha and beta for the i-th eigenvalue can be read */ /* directly from the generalized Schur form: alpha = S(i,i), */ /* beta = P(i,i). */ /* Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix */ /* Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973), */ /* pp. 241--256. */ /* Arguments */ /* ========= */ /* JOB (input) CHARACTER*1 */ /* = 'E': Compute eigenvalues only; */ /* = 'S': Computer eigenvalues and the Schur form. */ /* COMPQ (input) CHARACTER*1 */ /* = 'N': Left Schur vectors (Q) are not computed; */ /* = 'I': Q is initialized to the unit matrix and the matrix Q */ /* of left Schur vectors of (H,T) is returned; */ /* = 'V': Q must contain a unitary matrix Q1 on entry and */ /* the product Q1*Q is returned. */ /* COMPZ (input) CHARACTER*1 */ /* = 'N': Right Schur vectors (Z) are not computed; */ /* = 'I': Q is initialized to the unit matrix and the matrix Z */ /* of right Schur vectors of (H,T) is returned; */ /* = 'V': Z must contain a unitary matrix Z1 on entry and */ /* the product Z1*Z is returned. */ /* N (input) INTEGER */ /* The order of the matrices H, T, Q, and Z. N >= 0. */ /* ILO (input) INTEGER */ /* IHI (input) INTEGER */ /* ILO and IHI mark the rows and columns of H which are in */ /* Hessenberg form. It is assumed that A is already upper */ /* triangular in rows and columns 1:ILO-1 and IHI+1:N. */ /* If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0. */ /* H (input/output) COMPLEX array, dimension (LDH, N) */ /* On entry, the N-by-N upper Hessenberg matrix H. */ /* On exit, if JOB = 'S', H contains the upper triangular */ /* matrix S from the generalized Schur factorization. */ /* If JOB = 'E', the diagonal of H matches that of S, but */ /* the rest of H is unspecified. */ /* LDH (input) INTEGER */ /* The leading dimension of the array H. LDH >= MAX( 1, N ). */ /* T (input/output) COMPLEX array, dimension (LDT, N) */ /* On entry, the N-by-N upper triangular matrix T. */ /* On exit, if JOB = 'S', T contains the upper triangular */ /* matrix P from the generalized Schur factorization. */ /* If JOB = 'E', the diagonal of T matches that of P, but */ /* the rest of T is unspecified. */ /* LDT (input) INTEGER */ /* The leading dimension of the array T. LDT >= MAX( 1, N ). */ /* ALPHA (output) COMPLEX array, dimension (N) */ /* The complex scalars alpha that define the eigenvalues of */ /* GNEP. ALPHA(i) = S(i,i) in the generalized Schur */ /* factorization. */ /* BETA (output) COMPLEX array, dimension (N) */ /* The float non-negative scalars beta that define the */ /* eigenvalues of GNEP. BETA(i) = P(i,i) in the generalized */ /* Schur factorization. */ /* Together, the quantities alpha = ALPHA(j) and beta = BETA(j) */ /* represent the j-th eigenvalue of the matrix pair (A,B), in */ /* one of the forms lambda = alpha/beta or mu = beta/alpha. */ /* Since either lambda or mu may overflow, they should not, */ /* in general, be computed. */ /* Q (input/output) COMPLEX array, dimension (LDQ, N) */ /* On entry, if COMPZ = 'V', the unitary matrix Q1 used in the */ /* reduction of (A,B) to generalized Hessenberg form. */ /* On exit, if COMPZ = 'I', the unitary matrix of left Schur */ /* vectors of (H,T), and if COMPZ = 'V', the unitary matrix of */ /* left Schur vectors of (A,B). */ /* Not referenced if COMPZ = 'N'. */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. LDQ >= 1. */ /* If COMPQ='V' or 'I', then LDQ >= N. */ /* Z (input/output) COMPLEX array, dimension (LDZ, N) */ /* On entry, if COMPZ = 'V', the unitary matrix Z1 used in the */ /* reduction of (A,B) to generalized Hessenberg form. */ /* On exit, if COMPZ = 'I', the unitary matrix of right Schur */ /* vectors of (H,T), and if COMPZ = 'V', the unitary matrix of */ /* right Schur vectors of (A,B). */ /* Not referenced if COMPZ = 'N'. */ /* LDZ (input) INTEGER */ /* The leading dimension of the array Z. LDZ >= 1. */ /* If COMPZ='V' or 'I', then LDZ >= N. */ /* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */ /* On exit, if INFO >= 0, WORK(1) returns the optimal LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. LWORK >= MAX(1,N). */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the optimal size of the WORK array, returns */ /* this value as the first entry of the WORK array, and no error */ /* message related to LWORK is issued by XERBLA. */ /* RWORK (workspace) REAL array, dimension (N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* = 1,...,N: the QZ iteration did not converge. (H,T) is not */ /* in Schur form, but ALPHA(i) and BETA(i), */ /* i=INFO+1,...,N should be correct. */ /* = N+1,...,2*N: the shift calculation failed. (H,T) is not */ /* in Schur form, but ALPHA(i) and BETA(i), */ /* i=INFO-N+1,...,N should be correct. */ /* Further Details */ /* =============== */ /* We assume that complex ABS works as long as its value is less than */ /* overflow. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Decode JOB, COMPQ, COMPZ */ /* Parameter adjustments */ h_dim1 = *ldh; h_offset = 1 + h_dim1; h__ -= h_offset; t_dim1 = *ldt; t_offset = 1 + t_dim1; t -= t_offset; --alpha; --beta; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; z_dim1 = *ldz; z_offset = 1 + z_dim1; z__ -= z_offset; --work; --rwork; /* Function Body */ if (lsame_(job, "E")) { ilschr = FALSE; ischur = 1; } else if (lsame_(job, "S")) { ilschr = TRUE; ischur = 2; } else { ischur = 0; } if (lsame_(compq, "N")) { ilq = FALSE; icompq = 1; } else if (lsame_(compq, "V")) { ilq = TRUE; icompq = 2; } else if (lsame_(compq, "I")) { ilq = TRUE; icompq = 3; } else { icompq = 0; } if (lsame_(compz, "N")) { ilz = FALSE; icompz = 1; } else if (lsame_(compz, "V")) { ilz = TRUE; icompz = 2; } else if (lsame_(compz, "I")) { ilz = TRUE; icompz = 3; } else { icompz = 0; } /* Check Argument Values */ *info = 0; i__1 = MAX(1,*n); work[1].r = (float) i__1, work[1].i = 0.f; lquery = *lwork == -1; if (ischur == 0) { *info = -1; } else if (icompq == 0) { *info = -2; } else if (icompz == 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*ilo < 1) { *info = -5; } else if (*ihi > *n || *ihi < *ilo - 1) { *info = -6; } else if (*ldh < *n) { *info = -8; } else if (*ldt < *n) { *info = -10; } else if (*ldq < 1 || ilq && *ldq < *n) { *info = -14; } else if (*ldz < 1 || ilz && *ldz < *n) { *info = -16; } else if (*lwork < MAX(1,*n) && ! lquery) { *info = -18; } if (*info != 0) { i__1 = -(*info); xerbla_("CHGEQZ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ /* WORK( 1 ) = CMPLX( 1 ) */ if (*n <= 0) { work[1].r = 1.f, work[1].i = 0.f; return 0; } /* Initialize Q and Z */ if (icompq == 3) { claset_("Full", n, n, &c_b1, &c_b2, &q[q_offset], ldq); } if (icompz == 3) { claset_("Full", n, n, &c_b1, &c_b2, &z__[z_offset], ldz); } /* Machine Constants */ in = *ihi + 1 - *ilo; safmin = slamch_("S"); ulp = slamch_("E") * slamch_("B"); anorm = clanhs_("F", &in, &h__[*ilo + *ilo * h_dim1], ldh, &rwork[1]); bnorm = clanhs_("F", &in, &t[*ilo + *ilo * t_dim1], ldt, &rwork[1]); /* Computing MAX */ r__1 = safmin, r__2 = ulp * anorm; atol = MAX(r__1,r__2); /* Computing MAX */ r__1 = safmin, r__2 = ulp * bnorm; btol = MAX(r__1,r__2); ascale = 1.f / MAX(safmin,anorm); bscale = 1.f / MAX(safmin,bnorm); /* Set Eigenvalues IHI+1:N */ i__1 = *n; for (j = *ihi + 1; j <= i__1; ++j) { absb = c_abs(&t[j + j * t_dim1]); if (absb > safmin) { i__2 = j + j * t_dim1; q__2.r = t[i__2].r / absb, q__2.i = t[i__2].i / absb; r_cnjg(&q__1, &q__2); signbc.r = q__1.r, signbc.i = q__1.i; i__2 = j + j * t_dim1; t[i__2].r = absb, t[i__2].i = 0.f; if (ilschr) { i__2 = j - 1; cscal_(&i__2, &signbc, &t[j * t_dim1 + 1], &c__1); cscal_(&j, &signbc, &h__[j * h_dim1 + 1], &c__1); } else { i__2 = j + j * h_dim1; i__3 = j + j * h_dim1; q__1.r = h__[i__3].r * signbc.r - h__[i__3].i * signbc.i, q__1.i = h__[i__3].r * signbc.i + h__[i__3].i * signbc.r; h__[i__2].r = q__1.r, h__[i__2].i = q__1.i; } if (ilz) { cscal_(n, &signbc, &z__[j * z_dim1 + 1], &c__1); } } else { i__2 = j + j * t_dim1; t[i__2].r = 0.f, t[i__2].i = 0.f; } i__2 = j; i__3 = j + j * h_dim1; alpha[i__2].r = h__[i__3].r, alpha[i__2].i = h__[i__3].i; i__2 = j; i__3 = j + j * t_dim1; beta[i__2].r = t[i__3].r, beta[i__2].i = t[i__3].i; /* L10: */ } /* If IHI < ILO, skip QZ steps */ if (*ihi < *ilo) { goto L190; } /* MAIN QZ ITERATION LOOP */ /* Initialize dynamic indices */ /* Eigenvalues ILAST+1:N have been found. */ /* Column operations modify rows IFRSTM:whatever */ /* Row operations modify columns whatever:ILASTM */ /* If only eigenvalues are being computed, then */ /* IFRSTM is the row of the last splitting row above row ILAST; */ /* this is always at least ILO. */ /* IITER counts iterations since the last eigenvalue was found, */ /* to tell when to use an extraordinary shift. */ /* MAXIT is the maximum number of QZ sweeps allowed. */ ilast = *ihi; if (ilschr) { ifrstm = 1; ilastm = *n; } else { ifrstm = *ilo; ilastm = *ihi; } iiter = 0; eshift.r = 0.f, eshift.i = 0.f; maxit = (*ihi - *ilo + 1) * 30; i__1 = maxit; for (jiter = 1; jiter <= i__1; ++jiter) { /* Check for too many iterations. */ if (jiter > maxit) { goto L180; } /* Split the matrix if possible. */ /* Two tests: */ /* 1: H(j,j-1)=0 or j=ILO */ /* 2: T(j,j)=0 */ /* Special case: j=ILAST */ if (ilast == *ilo) { goto L60; } else { i__2 = ilast + (ilast - 1) * h_dim1; if ((r__1 = h__[i__2].r, ABS(r__1)) + (r__2 = r_imag(&h__[ilast + (ilast - 1) * h_dim1]), ABS(r__2)) <= atol) { i__2 = ilast + (ilast - 1) * h_dim1; h__[i__2].r = 0.f, h__[i__2].i = 0.f; goto L60; } } if (c_abs(&t[ilast + ilast * t_dim1]) <= btol) { i__2 = ilast + ilast * t_dim1; t[i__2].r = 0.f, t[i__2].i = 0.f; goto L50; } /* General case: j<ILAST */ i__2 = *ilo; for (j = ilast - 1; j >= i__2; --j) { /* Test 1: for H(j,j-1)=0 or j=ILO */ if (j == *ilo) { ilazro = TRUE; } else { i__3 = j + (j - 1) * h_dim1; if ((r__1 = h__[i__3].r, ABS(r__1)) + (r__2 = r_imag(&h__[j + (j - 1) * h_dim1]), ABS(r__2)) <= atol) { i__3 = j + (j - 1) * h_dim1; h__[i__3].r = 0.f, h__[i__3].i = 0.f; ilazro = TRUE; } else { ilazro = FALSE; } } /* Test 2: for T(j,j)=0 */ if (c_abs(&t[j + j * t_dim1]) < btol) { i__3 = j + j * t_dim1; t[i__3].r = 0.f, t[i__3].i = 0.f; /* Test 1a: Check for 2 consecutive small subdiagonals in A */ ilazr2 = FALSE; if (! ilazro) { i__3 = j + (j - 1) * h_dim1; i__4 = j + 1 + j * h_dim1; i__5 = j + j * h_dim1; if (((r__1 = h__[i__3].r, ABS(r__1)) + (r__2 = r_imag(& h__[j + (j - 1) * h_dim1]), ABS(r__2))) * ( ascale * ((r__3 = h__[i__4].r, ABS(r__3)) + ( r__4 = r_imag(&h__[j + 1 + j * h_dim1]), ABS( r__4)))) <= ((r__5 = h__[i__5].r, ABS(r__5)) + ( r__6 = r_imag(&h__[j + j * h_dim1]), ABS(r__6))) * (ascale * atol)) { ilazr2 = TRUE; } } /* If both tests pass (1 & 2), i.e., the leading diagonal */ /* element of B in the block is zero, split a 1x1 block off */ /* at the top. (I.e., at the J-th row/column) The leading */ /* diagonal element of the remainder can also be zero, so */ /* this may have to be done repeatedly. */ if (ilazro || ilazr2) { i__3 = ilast - 1; for (jch = j; jch <= i__3; ++jch) { i__4 = jch + jch * h_dim1; ctemp.r = h__[i__4].r, ctemp.i = h__[i__4].i; clartg_(&ctemp, &h__[jch + 1 + jch * h_dim1], &c__, & s, &h__[jch + jch * h_dim1]); i__4 = jch + 1 + jch * h_dim1; h__[i__4].r = 0.f, h__[i__4].i = 0.f; i__4 = ilastm - jch; crot_(&i__4, &h__[jch + (jch + 1) * h_dim1], ldh, & h__[jch + 1 + (jch + 1) * h_dim1], ldh, &c__, &s); i__4 = ilastm - jch; crot_(&i__4, &t[jch + (jch + 1) * t_dim1], ldt, &t[ jch + 1 + (jch + 1) * t_dim1], ldt, &c__, &s); if (ilq) { r_cnjg(&q__1, &s); crot_(n, &q[jch * q_dim1 + 1], &c__1, &q[(jch + 1) * q_dim1 + 1], &c__1, &c__, &q__1); } if (ilazr2) { i__4 = jch + (jch - 1) * h_dim1; i__5 = jch + (jch - 1) * h_dim1; q__1.r = c__ * h__[i__5].r, q__1.i = c__ * h__[ i__5].i; h__[i__4].r = q__1.r, h__[i__4].i = q__1.i; } ilazr2 = FALSE; i__4 = jch + 1 + (jch + 1) * t_dim1; if ((r__1 = t[i__4].r, ABS(r__1)) + (r__2 = r_imag(& t[jch + 1 + (jch + 1) * t_dim1]), ABS(r__2)) >= btol) { if (jch + 1 >= ilast) { goto L60; } else { ifirst = jch + 1; goto L70; } } i__4 = jch + 1 + (jch + 1) * t_dim1; t[i__4].r = 0.f, t[i__4].i = 0.f; /* L20: */ } goto L50; } else { /* Only test 2 passed -- chase the zero to T(ILAST,ILAST) */ /* Then process as in the case T(ILAST,ILAST)=0 */ i__3 = ilast - 1; for (jch = j; jch <= i__3; ++jch) { i__4 = jch + (jch + 1) * t_dim1; ctemp.r = t[i__4].r, ctemp.i = t[i__4].i; clartg_(&ctemp, &t[jch + 1 + (jch + 1) * t_dim1], & c__, &s, &t[jch + (jch + 1) * t_dim1]); i__4 = jch + 1 + (jch + 1) * t_dim1; t[i__4].r = 0.f, t[i__4].i = 0.f; if (jch < ilastm - 1) { i__4 = ilastm - jch - 1; crot_(&i__4, &t[jch + (jch + 2) * t_dim1], ldt, & t[jch + 1 + (jch + 2) * t_dim1], ldt, & c__, &s); } i__4 = ilastm - jch + 2; crot_(&i__4, &h__[jch + (jch - 1) * h_dim1], ldh, & h__[jch + 1 + (jch - 1) * h_dim1], ldh, &c__, &s); if (ilq) { r_cnjg(&q__1, &s); crot_(n, &q[jch * q_dim1 + 1], &c__1, &q[(jch + 1) * q_dim1 + 1], &c__1, &c__, &q__1); } i__4 = jch + 1 + jch * h_dim1; ctemp.r = h__[i__4].r, ctemp.i = h__[i__4].i; clartg_(&ctemp, &h__[jch + 1 + (jch - 1) * h_dim1], & c__, &s, &h__[jch + 1 + jch * h_dim1]); i__4 = jch + 1 + (jch - 1) * h_dim1; h__[i__4].r = 0.f, h__[i__4].i = 0.f; i__4 = jch + 1 - ifrstm; crot_(&i__4, &h__[ifrstm + jch * h_dim1], &c__1, &h__[ ifrstm + (jch - 1) * h_dim1], &c__1, &c__, &s) ; i__4 = jch - ifrstm; crot_(&i__4, &t[ifrstm + jch * t_dim1], &c__1, &t[ ifrstm + (jch - 1) * t_dim1], &c__1, &c__, &s) ; if (ilz) { crot_(n, &z__[jch * z_dim1 + 1], &c__1, &z__[(jch - 1) * z_dim1 + 1], &c__1, &c__, &s); } /* L30: */ } goto L50; } } else if (ilazro) { /* Only test 1 passed -- work on J:ILAST */ ifirst = j; goto L70; } /* Neither test passed -- try next J */ /* L40: */ } /* (Drop-through is "impossible") */ *info = (*n << 1) + 1; goto L210; /* T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a */ /* 1x1 block. */ L50: i__2 = ilast + ilast * h_dim1; ctemp.r = h__[i__2].r, ctemp.i = h__[i__2].i; clartg_(&ctemp, &h__[ilast + (ilast - 1) * h_dim1], &c__, &s, &h__[ ilast + ilast * h_dim1]); i__2 = ilast + (ilast - 1) * h_dim1; h__[i__2].r = 0.f, h__[i__2].i = 0.f; i__2 = ilast - ifrstm; crot_(&i__2, &h__[ifrstm + ilast * h_dim1], &c__1, &h__[ifrstm + ( ilast - 1) * h_dim1], &c__1, &c__, &s); i__2 = ilast - ifrstm; crot_(&i__2, &t[ifrstm + ilast * t_dim1], &c__1, &t[ifrstm + (ilast - 1) * t_dim1], &c__1, &c__, &s); if (ilz) { crot_(n, &z__[ilast * z_dim1 + 1], &c__1, &z__[(ilast - 1) * z_dim1 + 1], &c__1, &c__, &s); } /* H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHA and BETA */ L60: absb = c_abs(&t[ilast + ilast * t_dim1]); if (absb > safmin) { i__2 = ilast + ilast * t_dim1; q__2.r = t[i__2].r / absb, q__2.i = t[i__2].i / absb; r_cnjg(&q__1, &q__2); signbc.r = q__1.r, signbc.i = q__1.i; i__2 = ilast + ilast * t_dim1; t[i__2].r = absb, t[i__2].i = 0.f; if (ilschr) { i__2 = ilast - ifrstm; cscal_(&i__2, &signbc, &t[ifrstm + ilast * t_dim1], &c__1); i__2 = ilast + 1 - ifrstm; cscal_(&i__2, &signbc, &h__[ifrstm + ilast * h_dim1], &c__1); } else { i__2 = ilast + ilast * h_dim1; i__3 = ilast + ilast * h_dim1; q__1.r = h__[i__3].r * signbc.r - h__[i__3].i * signbc.i, q__1.i = h__[i__3].r * signbc.i + h__[i__3].i * signbc.r; h__[i__2].r = q__1.r, h__[i__2].i = q__1.i; } if (ilz) { cscal_(n, &signbc, &z__[ilast * z_dim1 + 1], &c__1); } } else { i__2 = ilast + ilast * t_dim1; t[i__2].r = 0.f, t[i__2].i = 0.f; } i__2 = ilast; i__3 = ilast + ilast * h_dim1; alpha[i__2].r = h__[i__3].r, alpha[i__2].i = h__[i__3].i; i__2 = ilast; i__3 = ilast + ilast * t_dim1; beta[i__2].r = t[i__3].r, beta[i__2].i = t[i__3].i; /* Go to next block -- exit if finished. */ --ilast; if (ilast < *ilo) { goto L190; } /* Reset counters */ iiter = 0; eshift.r = 0.f, eshift.i = 0.f; if (! ilschr) { ilastm = ilast; if (ifrstm > ilast) { ifrstm = *ilo; } } goto L160; /* QZ step */ /* This iteration only involves rows/columns IFIRST:ILAST. We */ /* assume IFIRST < ILAST, and that the diagonal of B is non-zero. */ L70: ++iiter; if (! ilschr) { ifrstm = ifirst; } /* Compute the Shift. */ /* At this point, IFIRST < ILAST, and the diagonal elements of */ /* T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in */ /* magnitude) */ if (iiter / 10 * 10 != iiter) { /* The Wilkinson shift (AEP p.512), i.e., the eigenvalue of */ /* the bottom-right 2x2 block of A inv(B) which is nearest to */ /* the bottom-right element. */ /* We factor B as U*D, where U has unit diagonals, and */ /* compute (A*inv(D))*inv(U). */ i__2 = ilast - 1 + ilast * t_dim1; q__2.r = bscale * t[i__2].r, q__2.i = bscale * t[i__2].i; i__3 = ilast + ilast * t_dim1; q__3.r = bscale * t[i__3].r, q__3.i = bscale * t[i__3].i; c_div(&q__1, &q__2, &q__3); u12.r = q__1.r, u12.i = q__1.i; i__2 = ilast - 1 + (ilast - 1) * h_dim1; q__2.r = ascale * h__[i__2].r, q__2.i = ascale * h__[i__2].i; i__3 = ilast - 1 + (ilast - 1) * t_dim1; q__3.r = bscale * t[i__3].r, q__3.i = bscale * t[i__3].i; c_div(&q__1, &q__2, &q__3); ad11.r = q__1.r, ad11.i = q__1.i; i__2 = ilast + (ilast - 1) * h_dim1; q__2.r = ascale * h__[i__2].r, q__2.i = ascale * h__[i__2].i; i__3 = ilast - 1 + (ilast - 1) * t_dim1; q__3.r = bscale * t[i__3].r, q__3.i = bscale * t[i__3].i; c_div(&q__1, &q__2, &q__3); ad21.r = q__1.r, ad21.i = q__1.i; i__2 = ilast - 1 + ilast * h_dim1; q__2.r = ascale * h__[i__2].r, q__2.i = ascale * h__[i__2].i; i__3 = ilast + ilast * t_dim1; q__3.r = bscale * t[i__3].r, q__3.i = bscale * t[i__3].i; c_div(&q__1, &q__2, &q__3); ad12.r = q__1.r, ad12.i = q__1.i; i__2 = ilast + ilast * h_dim1; q__2.r = ascale * h__[i__2].r, q__2.i = ascale * h__[i__2].i; i__3 = ilast + ilast * t_dim1; q__3.r = bscale * t[i__3].r, q__3.i = bscale * t[i__3].i; c_div(&q__1, &q__2, &q__3); ad22.r = q__1.r, ad22.i = q__1.i; q__2.r = u12.r * ad21.r - u12.i * ad21.i, q__2.i = u12.r * ad21.i + u12.i * ad21.r; q__1.r = ad22.r - q__2.r, q__1.i = ad22.i - q__2.i; abi22.r = q__1.r, abi22.i = q__1.i; q__2.r = ad11.r + abi22.r, q__2.i = ad11.i + abi22.i; q__1.r = q__2.r * .5f, q__1.i = q__2.i * .5f; t1.r = q__1.r, t1.i = q__1.i; pow_ci(&q__4, &t1, &c__2); q__5.r = ad12.r * ad21.r - ad12.i * ad21.i, q__5.i = ad12.r * ad21.i + ad12.i * ad21.r; q__3.r = q__4.r + q__5.r, q__3.i = q__4.i + q__5.i; q__6.r = ad11.r * ad22.r - ad11.i * ad22.i, q__6.i = ad11.r * ad22.i + ad11.i * ad22.r; q__2.r = q__3.r - q__6.r, q__2.i = q__3.i - q__6.i; c_sqrt(&q__1, &q__2); rtdisc.r = q__1.r, rtdisc.i = q__1.i; q__1.r = t1.r - abi22.r, q__1.i = t1.i - abi22.i; q__2.r = t1.r - abi22.r, q__2.i = t1.i - abi22.i; temp = q__1.r * rtdisc.r + r_imag(&q__2) * r_imag(&rtdisc); if (temp <= 0.f) { q__1.r = t1.r + rtdisc.r, q__1.i = t1.i + rtdisc.i; shift.r = q__1.r, shift.i = q__1.i; } else { q__1.r = t1.r - rtdisc.r, q__1.i = t1.i - rtdisc.i; shift.r = q__1.r, shift.i = q__1.i; } } else { /* Exceptional shift. Chosen for no particularly good reason. */ i__2 = ilast - 1 + ilast * h_dim1; q__4.r = ascale * h__[i__2].r, q__4.i = ascale * h__[i__2].i; i__3 = ilast - 1 + (ilast - 1) * t_dim1; q__5.r = bscale * t[i__3].r, q__5.i = bscale * t[i__3].i; c_div(&q__3, &q__4, &q__5); r_cnjg(&q__2, &q__3); q__1.r = eshift.r + q__2.r, q__1.i = eshift.i + q__2.i; eshift.r = q__1.r, eshift.i = q__1.i; shift.r = eshift.r, shift.i = eshift.i; } /* Now check for two consecutive small subdiagonals. */ i__2 = ifirst + 1; for (j = ilast - 1; j >= i__2; --j) { istart = j; i__3 = j + j * h_dim1; q__2.r = ascale * h__[i__3].r, q__2.i = ascale * h__[i__3].i; i__4 = j + j * t_dim1; q__4.r = bscale * t[i__4].r, q__4.i = bscale * t[i__4].i; q__3.r = shift.r * q__4.r - shift.i * q__4.i, q__3.i = shift.r * q__4.i + shift.i * q__4.r; q__1.r = q__2.r - q__3.r, q__1.i = q__2.i - q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; temp = (r__1 = ctemp.r, ABS(r__1)) + (r__2 = r_imag(&ctemp), ABS(r__2)); i__3 = j + 1 + j * h_dim1; temp2 = ascale * ((r__1 = h__[i__3].r, ABS(r__1)) + (r__2 = r_imag(&h__[j + 1 + j * h_dim1]), ABS(r__2))); tempr = MAX(temp,temp2); if (tempr < 1.f && tempr != 0.f) { temp /= tempr; temp2 /= tempr; } i__3 = j + (j - 1) * h_dim1; if (((r__1 = h__[i__3].r, ABS(r__1)) + (r__2 = r_imag(&h__[j + ( j - 1) * h_dim1]), ABS(r__2))) * temp2 <= temp * atol) { goto L90; } /* L80: */ } istart = ifirst; i__2 = ifirst + ifirst * h_dim1; q__2.r = ascale * h__[i__2].r, q__2.i = ascale * h__[i__2].i; i__3 = ifirst + ifirst * t_dim1; q__4.r = bscale * t[i__3].r, q__4.i = bscale * t[i__3].i; q__3.r = shift.r * q__4.r - shift.i * q__4.i, q__3.i = shift.r * q__4.i + shift.i * q__4.r; q__1.r = q__2.r - q__3.r, q__1.i = q__2.i - q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; L90: /* Do an implicit-shift QZ sweep. */ /* Initial Q */ i__2 = istart + 1 + istart * h_dim1; q__1.r = ascale * h__[i__2].r, q__1.i = ascale * h__[i__2].i; ctemp2.r = q__1.r, ctemp2.i = q__1.i; clartg_(&ctemp, &ctemp2, &c__, &s, &ctemp3); /* Sweep */ i__2 = ilast - 1; for (j = istart; j <= i__2; ++j) { if (j > istart) { i__3 = j + (j - 1) * h_dim1; ctemp.r = h__[i__3].r, ctemp.i = h__[i__3].i; clartg_(&ctemp, &h__[j + 1 + (j - 1) * h_dim1], &c__, &s, & h__[j + (j - 1) * h_dim1]); i__3 = j + 1 + (j - 1) * h_dim1; h__[i__3].r = 0.f, h__[i__3].i = 0.f; } i__3 = ilastm; for (jc = j; jc <= i__3; ++jc) { i__4 = j + jc * h_dim1; q__2.r = c__ * h__[i__4].r, q__2.i = c__ * h__[i__4].i; i__5 = j + 1 + jc * h_dim1; q__3.r = s.r * h__[i__5].r - s.i * h__[i__5].i, q__3.i = s.r * h__[i__5].i + s.i * h__[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; i__4 = j + 1 + jc * h_dim1; r_cnjg(&q__4, &s); q__3.r = -q__4.r, q__3.i = -q__4.i; i__5 = j + jc * h_dim1; q__2.r = q__3.r * h__[i__5].r - q__3.i * h__[i__5].i, q__2.i = q__3.r * h__[i__5].i + q__3.i * h__[i__5].r; i__6 = j + 1 + jc * h_dim1; q__5.r = c__ * h__[i__6].r, q__5.i = c__ * h__[i__6].i; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; h__[i__4].r = q__1.r, h__[i__4].i = q__1.i; i__4 = j + jc * h_dim1; h__[i__4].r = ctemp.r, h__[i__4].i = ctemp.i; i__4 = j + jc * t_dim1; q__2.r = c__ * t[i__4].r, q__2.i = c__ * t[i__4].i; i__5 = j + 1 + jc * t_dim1; q__3.r = s.r * t[i__5].r - s.i * t[i__5].i, q__3.i = s.r * t[ i__5].i + s.i * t[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp2.r = q__1.r, ctemp2.i = q__1.i; i__4 = j + 1 + jc * t_dim1; r_cnjg(&q__4, &s); q__3.r = -q__4.r, q__3.i = -q__4.i; i__5 = j + jc * t_dim1; q__2.r = q__3.r * t[i__5].r - q__3.i * t[i__5].i, q__2.i = q__3.r * t[i__5].i + q__3.i * t[i__5].r; i__6 = j + 1 + jc * t_dim1; q__5.r = c__ * t[i__6].r, q__5.i = c__ * t[i__6].i; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; t[i__4].r = q__1.r, t[i__4].i = q__1.i; i__4 = j + jc * t_dim1; t[i__4].r = ctemp2.r, t[i__4].i = ctemp2.i; /* L100: */ } if (ilq) { i__3 = *n; for (jr = 1; jr <= i__3; ++jr) { i__4 = jr + j * q_dim1; q__2.r = c__ * q[i__4].r, q__2.i = c__ * q[i__4].i; r_cnjg(&q__4, &s); i__5 = jr + (j + 1) * q_dim1; q__3.r = q__4.r * q[i__5].r - q__4.i * q[i__5].i, q__3.i = q__4.r * q[i__5].i + q__4.i * q[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; i__4 = jr + (j + 1) * q_dim1; q__3.r = -s.r, q__3.i = -s.i; i__5 = jr + j * q_dim1; q__2.r = q__3.r * q[i__5].r - q__3.i * q[i__5].i, q__2.i = q__3.r * q[i__5].i + q__3.i * q[i__5].r; i__6 = jr + (j + 1) * q_dim1; q__4.r = c__ * q[i__6].r, q__4.i = c__ * q[i__6].i; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; q[i__4].r = q__1.r, q[i__4].i = q__1.i; i__4 = jr + j * q_dim1; q[i__4].r = ctemp.r, q[i__4].i = ctemp.i; /* L110: */ } } i__3 = j + 1 + (j + 1) * t_dim1; ctemp.r = t[i__3].r, ctemp.i = t[i__3].i; clartg_(&ctemp, &t[j + 1 + j * t_dim1], &c__, &s, &t[j + 1 + (j + 1) * t_dim1]); i__3 = j + 1 + j * t_dim1; t[i__3].r = 0.f, t[i__3].i = 0.f; /* Computing MIN */ i__4 = j + 2; i__3 = MIN(i__4,ilast); for (jr = ifrstm; jr <= i__3; ++jr) { i__4 = jr + (j + 1) * h_dim1; q__2.r = c__ * h__[i__4].r, q__2.i = c__ * h__[i__4].i; i__5 = jr + j * h_dim1; q__3.r = s.r * h__[i__5].r - s.i * h__[i__5].i, q__3.i = s.r * h__[i__5].i + s.i * h__[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; i__4 = jr + j * h_dim1; r_cnjg(&q__4, &s); q__3.r = -q__4.r, q__3.i = -q__4.i; i__5 = jr + (j + 1) * h_dim1; q__2.r = q__3.r * h__[i__5].r - q__3.i * h__[i__5].i, q__2.i = q__3.r * h__[i__5].i + q__3.i * h__[i__5].r; i__6 = jr + j * h_dim1; q__5.r = c__ * h__[i__6].r, q__5.i = c__ * h__[i__6].i; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; h__[i__4].r = q__1.r, h__[i__4].i = q__1.i; i__4 = jr + (j + 1) * h_dim1; h__[i__4].r = ctemp.r, h__[i__4].i = ctemp.i; /* L120: */ } i__3 = j; for (jr = ifrstm; jr <= i__3; ++jr) { i__4 = jr + (j + 1) * t_dim1; q__2.r = c__ * t[i__4].r, q__2.i = c__ * t[i__4].i; i__5 = jr + j * t_dim1; q__3.r = s.r * t[i__5].r - s.i * t[i__5].i, q__3.i = s.r * t[ i__5].i + s.i * t[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; i__4 = jr + j * t_dim1; r_cnjg(&q__4, &s); q__3.r = -q__4.r, q__3.i = -q__4.i; i__5 = jr + (j + 1) * t_dim1; q__2.r = q__3.r * t[i__5].r - q__3.i * t[i__5].i, q__2.i = q__3.r * t[i__5].i + q__3.i * t[i__5].r; i__6 = jr + j * t_dim1; q__5.r = c__ * t[i__6].r, q__5.i = c__ * t[i__6].i; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; t[i__4].r = q__1.r, t[i__4].i = q__1.i; i__4 = jr + (j + 1) * t_dim1; t[i__4].r = ctemp.r, t[i__4].i = ctemp.i; /* L130: */ } if (ilz) { i__3 = *n; for (jr = 1; jr <= i__3; ++jr) { i__4 = jr + (j + 1) * z_dim1; q__2.r = c__ * z__[i__4].r, q__2.i = c__ * z__[i__4].i; i__5 = jr + j * z_dim1; q__3.r = s.r * z__[i__5].r - s.i * z__[i__5].i, q__3.i = s.r * z__[i__5].i + s.i * z__[i__5].r; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; ctemp.r = q__1.r, ctemp.i = q__1.i; i__4 = jr + j * z_dim1; r_cnjg(&q__4, &s); q__3.r = -q__4.r, q__3.i = -q__4.i; i__5 = jr + (j + 1) * z_dim1; q__2.r = q__3.r * z__[i__5].r - q__3.i * z__[i__5].i, q__2.i = q__3.r * z__[i__5].i + q__3.i * z__[i__5] .r; i__6 = jr + j * z_dim1; q__5.r = c__ * z__[i__6].r, q__5.i = c__ * z__[i__6].i; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; z__[i__4].r = q__1.r, z__[i__4].i = q__1.i; i__4 = jr + (j + 1) * z_dim1; z__[i__4].r = ctemp.r, z__[i__4].i = ctemp.i; /* L140: */ } } /* L150: */ } L160: /* L170: */ ; } /* Drop-through = non-convergence */ L180: *info = ilast; goto L210; /* Successful completion of all QZ steps */ L190: /* Set Eigenvalues 1:ILO-1 */ i__1 = *ilo - 1; for (j = 1; j <= i__1; ++j) { absb = c_abs(&t[j + j * t_dim1]); if (absb > safmin) { i__2 = j + j * t_dim1; q__2.r = t[i__2].r / absb, q__2.i = t[i__2].i / absb; r_cnjg(&q__1, &q__2); signbc.r = q__1.r, signbc.i = q__1.i; i__2 = j + j * t_dim1; t[i__2].r = absb, t[i__2].i = 0.f; if (ilschr) { i__2 = j - 1; cscal_(&i__2, &signbc, &t[j * t_dim1 + 1], &c__1); cscal_(&j, &signbc, &h__[j * h_dim1 + 1], &c__1); } else { i__2 = j + j * h_dim1; i__3 = j + j * h_dim1; q__1.r = h__[i__3].r * signbc.r - h__[i__3].i * signbc.i, q__1.i = h__[i__3].r * signbc.i + h__[i__3].i * signbc.r; h__[i__2].r = q__1.r, h__[i__2].i = q__1.i; } if (ilz) { cscal_(n, &signbc, &z__[j * z_dim1 + 1], &c__1); } } else { i__2 = j + j * t_dim1; t[i__2].r = 0.f, t[i__2].i = 0.f; } i__2 = j; i__3 = j + j * h_dim1; alpha[i__2].r = h__[i__3].r, alpha[i__2].i = h__[i__3].i; i__2 = j; i__3 = j + j * t_dim1; beta[i__2].r = t[i__3].r, beta[i__2].i = t[i__3].i; /* L200: */ } /* Normal Termination */ *info = 0; /* Exit (other than argument error) -- return optimal workspace size */ L210: q__1.r = (float) (*n), q__1.i = 0.f; work[1].r = q__1.r, work[1].i = q__1.i; return 0; /* End of CHGEQZ */ } /* chgeqz_ */
/* Subroutine */ int cgeevx_(char *balanc, char *jobvl, char *jobvr, char * sense, integer *n, complex *a, integer *lda, complex *w, complex *vl, integer *ldvl, complex *vr, integer *ldvr, integer *ilo, integer *ihi, real *scale, real *abnrm, real *rconde, real *rcondv, complex *work, integer *lwork, real *rwork, integer *info) { /* System generated locals */ integer a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3; real r__1, r__2; complex q__1, q__2; /* Local variables */ integer i__, k; char job[1]; real scl, dum[1], eps; complex tmp; char side[1]; real anrm; integer ierr, itau, iwrk, nout; integer icond; logical scalea; real cscale; logical select[1]; real bignum; integer minwrk, maxwrk; logical wantvl, wntsnb; integer hswork; logical wntsne; real smlnum; logical lquery, wantvr, wntsnn, wntsnv; /* -- LAPACK driver routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* CGEEVX computes for an N-by-N complex nonsymmetric matrix A, the */ /* eigenvalues and, optionally, the left and/or right eigenvectors. */ /* Optionally also, it computes a balancing transformation to improve */ /* the conditioning of the eigenvalues and eigenvectors (ILO, IHI, */ /* SCALE, and ABNRM), reciprocal condition numbers for the eigenvalues */ /* (RCONDE), and reciprocal condition numbers for the right */ /* eigenvectors (RCONDV). */ /* The right eigenvector v(j) of A satisfies */ /* A * v(j) = lambda(j) * v(j) */ /* where lambda(j) is its eigenvalue. */ /* The left eigenvector u(j) of A satisfies */ /* u(j)**H * A = lambda(j) * u(j)**H */ /* where u(j)**H denotes the conjugate transpose of u(j). */ /* The computed eigenvectors are normalized to have Euclidean norm */ /* equal to 1 and largest component real. */ /* Balancing a matrix means permuting the rows and columns to make it */ /* more nearly upper triangular, and applying a diagonal similarity */ /* transformation D * A * D**(-1), where D is a diagonal matrix, to */ /* make its rows and columns closer in norm and the condition numbers */ /* of its eigenvalues and eigenvectors smaller. The computed */ /* reciprocal condition numbers correspond to the balanced matrix. */ /* Permuting rows and columns will not change the condition numbers */ /* (in exact arithmetic) but diagonal scaling will. For further */ /* explanation of balancing, see section 4.10.2 of the LAPACK */ /* Users' Guide. */ /* Arguments */ /* ========= */ /* BALANC (input) CHARACTER*1 */ /* Indicates how the input matrix should be diagonally scaled */ /* and/or permuted to improve the conditioning of its */ /* eigenvalues. */ /* = 'N': Do not diagonally scale or permute; */ /* = 'P': Perform permutations to make the matrix more nearly */ /* upper triangular. Do not diagonally scale; */ /* = 'S': Diagonally scale the matrix, ie. replace A by */ /* D*A*D**(-1), where D is a diagonal matrix chosen */ /* to make the rows and columns of A more equal in */ /* norm. Do not permute; */ /* = 'B': Both diagonally scale and permute A. */ /* Computed reciprocal condition numbers will be for the matrix */ /* after balancing and/or permuting. Permuting does not change */ /* condition numbers (in exact arithmetic), but balancing does. */ /* JOBVL (input) CHARACTER*1 */ /* = 'N': left eigenvectors of A are not computed; */ /* = 'V': left eigenvectors of A are computed. */ /* If SENSE = 'E' or 'B', JOBVL must = 'V'. */ /* JOBVR (input) CHARACTER*1 */ /* = 'N': right eigenvectors of A are not computed; */ /* = 'V': right eigenvectors of A are computed. */ /* If SENSE = 'E' or 'B', JOBVR must = 'V'. */ /* SENSE (input) CHARACTER*1 */ /* Determines which reciprocal condition numbers are computed. */ /* = 'N': None are computed; */ /* = 'E': Computed for eigenvalues only; */ /* = 'V': Computed for right eigenvectors only; */ /* = 'B': Computed for eigenvalues and right eigenvectors. */ /* If SENSE = 'E' or 'B', both left and right eigenvectors */ /* must also be computed (JOBVL = 'V' and JOBVR = 'V'). */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input/output) COMPLEX array, dimension (LDA,N) */ /* On entry, the N-by-N matrix A. */ /* On exit, A has been overwritten. If JOBVL = 'V' or */ /* JOBVR = 'V', A contains the Schur form of the balanced */ /* version of the matrix A. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* W (output) COMPLEX array, dimension (N) */ /* W contains the computed eigenvalues. */ /* VL (output) COMPLEX array, dimension (LDVL,N) */ /* If JOBVL = 'V', the left eigenvectors u(j) are stored one */ /* after another in the columns of VL, in the same order */ /* as their eigenvalues. */ /* If JOBVL = 'N', VL is not referenced. */ /* u(j) = VL(:,j), the j-th column of VL. */ /* LDVL (input) INTEGER */ /* The leading dimension of the array VL. LDVL >= 1; if */ /* JOBVL = 'V', LDVL >= N. */ /* VR (output) COMPLEX array, dimension (LDVR,N) */ /* If JOBVR = 'V', the right eigenvectors v(j) are stored one */ /* after another in the columns of VR, in the same order */ /* as their eigenvalues. */ /* If JOBVR = 'N', VR is not referenced. */ /* v(j) = VR(:,j), the j-th column of VR. */ /* LDVR (input) INTEGER */ /* The leading dimension of the array VR. LDVR >= 1; if */ /* JOBVR = 'V', LDVR >= N. */ /* ILO (output) INTEGER */ /* IHI (output) INTEGER */ /* ILO and IHI are integer values determined when A was */ /* balanced. The balanced A(i,j) = 0 if I > J and */ /* SCALE (output) REAL array, dimension (N) */ /* Details of the permutations and scaling factors applied */ /* when balancing A. If P(j) is the index of the row and column */ /* interchanged with row and column j, and D(j) is the scaling */ /* factor applied to row and column j, then */ /* The order in which the interchanges are made is N to IHI+1, */ /* then 1 to ILO-1. */ /* ABNRM (output) REAL */ /* The one-norm of the balanced matrix (the maximum */ /* of the sum of absolute values of elements of any column). */ /* RCONDE (output) REAL array, dimension (N) */ /* RCONDE(j) is the reciprocal condition number of the j-th */ /* eigenvalue. */ /* RCONDV (output) REAL array, dimension (N) */ /* RCONDV(j) is the reciprocal condition number of the j-th */ /* right eigenvector. */ /* WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */ /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. If SENSE = 'N' or 'E', */ /* LWORK >= max(1,2*N), and if SENSE = 'V' or 'B', */ /* LWORK >= N*N+2*N. */ /* For good performance, LWORK must generally be larger. */ /* If LWORK = -1, then a workspace query is assumed; the routine */ /* only calculates the optimal size of the WORK array, returns */ /* this value as the first entry of the WORK array, and no error */ /* message related to LWORK is issued by XERBLA. */ /* RWORK (workspace) REAL array, dimension (2*N) */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value. */ /* > 0: if INFO = i, the QR algorithm failed to compute all the */ /* eigenvalues, and no eigenvectors or condition numbers */ /* have been computed; elements 1:ILO-1 and i+1:N of W */ /* contain eigenvalues which have converged. */ /* ===================================================================== */ /* Test the input arguments */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --w; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1; vr -= vr_offset; --scale; --rconde; --rcondv; --work; --rwork; /* Function Body */ *info = 0; lquery = *lwork == -1; wantvl = lsame_(jobvl, "V"); wantvr = lsame_(jobvr, "V"); wntsnn = lsame_(sense, "N"); wntsne = lsame_(sense, "E"); wntsnv = lsame_(sense, "V"); wntsnb = lsame_(sense, "B"); if (! (lsame_(balanc, "N") || lsame_(balanc, "S") || lsame_(balanc, "P") || lsame_(balanc, "B"))) { *info = -1; } else if (! wantvl && ! lsame_(jobvl, "N")) { *info = -2; } else if (! wantvr && ! lsame_(jobvr, "N")) { *info = -3; } else if (! (wntsnn || wntsne || wntsnb || wntsnv) || (wntsne || wntsnb) && ! (wantvl && wantvr)) { *info = -4; } else if (*n < 0) { *info = -5; } else if (*lda < max(1,*n)) { *info = -7; } else if (*ldvl < 1 || wantvl && *ldvl < *n) { *info = -10; } else if (*ldvr < 1 || wantvr && *ldvr < *n) { *info = -12; } /* Compute workspace */ /* (Note: Comments in the code beginning "Workspace:" describe the */ /* minimal amount of workspace needed at that point in the code, */ /* as well as the preferred amount for good performance. */ /* CWorkspace refers to complex workspace, and RWorkspace to real */ /* workspace. NB refers to the optimal block size for the */ /* immediately following subroutine, as returned by ILAENV. */ /* HSWORK refers to the workspace preferred by CHSEQR, as */ /* calculated below. HSWORK is computed assuming ILO=1 and IHI=N, */ /* the worst case.) */ if (*info == 0) { if (*n == 0) { minwrk = 1; maxwrk = 1; } else { maxwrk = *n + *n * ilaenv_(&c__1, "CGEHRD", " ", n, &c__1, n, & c__0); if (wantvl) { chseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vl[ vl_offset], ldvl, &work[1], &c_n1, info); } else if (wantvr) { chseqr_("S", "V", n, &c__1, n, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[1], &c_n1, info); } else { if (wntsnn) { chseqr_("E", "N", n, &c__1, n, &a[a_offset], lda, &w[1], & vr[vr_offset], ldvr, &work[1], &c_n1, info); } else { chseqr_("S", "N", n, &c__1, n, &a[a_offset], lda, &w[1], & vr[vr_offset], ldvr, &work[1], &c_n1, info); } } hswork = work[1].r; if (! wantvl && ! wantvr) { minwrk = *n << 1; if (! (wntsnn || wntsne)) { /* Computing MAX */ i__1 = minwrk, i__2 = *n * *n + (*n << 1); minwrk = max(i__1,i__2); } maxwrk = max(maxwrk,hswork); if (! (wntsnn || wntsne)) { /* Computing MAX */ i__1 = maxwrk, i__2 = *n * *n + (*n << 1); maxwrk = max(i__1,i__2); } } else { minwrk = *n << 1; if (! (wntsnn || wntsne)) { /* Computing MAX */ i__1 = minwrk, i__2 = *n * *n + (*n << 1); minwrk = max(i__1,i__2); } maxwrk = max(maxwrk,hswork); /* Computing MAX */ i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "CUNGHR", " ", n, &c__1, n, &c_n1); maxwrk = max(i__1,i__2); if (! (wntsnn || wntsne)) { /* Computing MAX */ i__1 = maxwrk, i__2 = *n * *n + (*n << 1); maxwrk = max(i__1,i__2); } /* Computing MAX */ i__1 = maxwrk, i__2 = *n << 1; maxwrk = max(i__1,i__2); } maxwrk = max(maxwrk,minwrk); } work[1].r = (real) maxwrk, work[1].i = 0.f; if (*lwork < minwrk && ! lquery) { *info = -20; } } if (*info != 0) { i__1 = -(*info); xerbla_("CGEEVX", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Get machine constants */ eps = slamch_("P"); smlnum = slamch_("S"); bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); smlnum = sqrt(smlnum) / eps; bignum = 1.f / smlnum; /* Scale A if max element outside range [SMLNUM,BIGNUM] */ icond = 0; anrm = clange_("M", n, n, &a[a_offset], lda, dum); scalea = FALSE_; if (anrm > 0.f && anrm < smlnum) { scalea = TRUE_; cscale = smlnum; } else if (anrm > bignum) { scalea = TRUE_; cscale = bignum; } if (scalea) { clascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, & ierr); } /* Balance the matrix and compute ABNRM */ cgebal_(balanc, n, &a[a_offset], lda, ilo, ihi, &scale[1], &ierr); *abnrm = clange_("1", n, n, &a[a_offset], lda, dum); if (scalea) { dum[0] = *abnrm; slascl_("G", &c__0, &c__0, &cscale, &anrm, &c__1, &c__1, dum, &c__1, & ierr); *abnrm = dum[0]; } /* Reduce to upper Hessenberg form */ /* (CWorkspace: need 2*N, prefer N+N*NB) */ /* (RWorkspace: none) */ itau = 1; iwrk = itau + *n; i__1 = *lwork - iwrk + 1; cgehrd_(n, ilo, ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, & ierr); if (wantvl) { /* Want left eigenvectors */ /* Copy Householder vectors to VL */ *(unsigned char *)side = 'L'; clacpy_("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl) ; /* Generate unitary matrix in VL */ /* (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */ /* (RWorkspace: none) */ i__1 = *lwork - iwrk + 1; cunghr_(n, ilo, ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk], & i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VL */ /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_("S", "V", n, ilo, ihi, &a[a_offset], lda, &w[1], &vl[ vl_offset], ldvl, &work[iwrk], &i__1, info); if (wantvr) { /* Want left and right eigenvectors */ /* Copy Schur vectors to VR */ *(unsigned char *)side = 'B'; clacpy_("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr); } } else if (wantvr) { /* Want right eigenvectors */ /* Copy Householder vectors to VR */ *(unsigned char *)side = 'R'; clacpy_("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr) ; /* Generate unitary matrix in VR */ /* (CWorkspace: need 2*N-1, prefer N+(N-1)*NB) */ /* (RWorkspace: none) */ i__1 = *lwork - iwrk + 1; cunghr_(n, ilo, ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk], & i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VR */ /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_("S", "V", n, ilo, ihi, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[iwrk], &i__1, info); } else { /* Compute eigenvalues only */ /* If condition numbers desired, compute Schur form */ if (wntsnn) { *(unsigned char *)job = 'E'; } else { *(unsigned char *)job = 'S'; } /* (CWorkspace: need 1, prefer HSWORK (see comments) ) */ /* (RWorkspace: none) */ iwrk = itau; i__1 = *lwork - iwrk + 1; chseqr_(job, "N", n, ilo, ihi, &a[a_offset], lda, &w[1], &vr[ vr_offset], ldvr, &work[iwrk], &i__1, info); } /* If INFO > 0 from CHSEQR, then quit */ if (*info > 0) { goto L50; } if (wantvl || wantvr) { /* Compute left and/or right eigenvectors */ /* (CWorkspace: need 2*N) */ /* (RWorkspace: need N) */ ctrevc_(side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &rwork[1], & ierr); } /* Compute condition numbers if desired */ /* (CWorkspace: need N*N+2*N unless SENSE = 'E') */ /* (RWorkspace: need 2*N unless SENSE = 'E') */ if (! wntsnn) { ctrsna_(sense, "A", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, &rconde[1], &rcondv[1], n, &nout, &work[iwrk], n, &rwork[1], &icond); } if (wantvl) { /* Undo balancing of left eigenvectors */ cgebak_(balanc, "L", n, ilo, ihi, &scale[1], n, &vl[vl_offset], ldvl, &ierr); /* Normalize left eigenvectors and make largest component real */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scl = 1.f / scnrm2_(n, &vl[i__ * vl_dim1 + 1], &c__1); csscal_(n, &scl, &vl[i__ * vl_dim1 + 1], &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + i__ * vl_dim1; /* Computing 2nd power */ r__1 = vl[i__3].r; /* Computing 2nd power */ r__2 = r_imag(&vl[k + i__ * vl_dim1]); rwork[k] = r__1 * r__1 + r__2 * r__2; } k = isamax_(n, &rwork[1], &c__1); r_cnjg(&q__2, &vl[k + i__ * vl_dim1]); r__1 = sqrt(rwork[k]); q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; tmp.r = q__1.r, tmp.i = q__1.i; cscal_(n, &tmp, &vl[i__ * vl_dim1 + 1], &c__1); i__2 = k + i__ * vl_dim1; i__3 = k + i__ * vl_dim1; r__1 = vl[i__3].r; q__1.r = r__1, q__1.i = 0.f; vl[i__2].r = q__1.r, vl[i__2].i = q__1.i; } } if (wantvr) { /* Undo balancing of right eigenvectors */ cgebak_(balanc, "R", n, ilo, ihi, &scale[1], n, &vr[vr_offset], ldvr, &ierr); /* Normalize right eigenvectors and make largest component real */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scl = 1.f / scnrm2_(n, &vr[i__ * vr_dim1 + 1], &c__1); csscal_(n, &scl, &vr[i__ * vr_dim1 + 1], &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { i__3 = k + i__ * vr_dim1; /* Computing 2nd power */ r__1 = vr[i__3].r; /* Computing 2nd power */ r__2 = r_imag(&vr[k + i__ * vr_dim1]); rwork[k] = r__1 * r__1 + r__2 * r__2; } k = isamax_(n, &rwork[1], &c__1); r_cnjg(&q__2, &vr[k + i__ * vr_dim1]); r__1 = sqrt(rwork[k]); q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; tmp.r = q__1.r, tmp.i = q__1.i; cscal_(n, &tmp, &vr[i__ * vr_dim1 + 1], &c__1); i__2 = k + i__ * vr_dim1; i__3 = k + i__ * vr_dim1; r__1 = vr[i__3].r; q__1.r = r__1, q__1.i = 0.f; vr[i__2].r = q__1.r, vr[i__2].i = q__1.i; } } /* Undo scaling if necessary */ L50: if (scalea) { i__1 = *n - *info; /* Computing MAX */ i__3 = *n - *info; i__2 = max(i__3,1); clascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[*info + 1] , &i__2, &ierr); if (*info == 0) { if ((wntsnv || wntsnb) && icond == 0) { slascl_("G", &c__0, &c__0, &cscale, &anrm, n, &c__1, &rcondv[ 1], n, &ierr); } } else { i__1 = *ilo - 1; clascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &w[1], n, &ierr); } } work[1].r = (real) maxwrk, work[1].i = 0.f; return 0; /* End of CGEEVX */ } /* cgeevx_ */
/*< subroutine csvdc(x,ldx,n,p,s,e,u,ldu,v,ldv,work,job,info) >*/ /* Subroutine */ int csvdc_(complex *x, integer *ldx, integer *n, integer *p, complex *s, complex *e, complex *u, integer *ldu, complex *v, integer *ldv, complex *work, integer *job, integer *info) { /* System generated locals */ integer x_dim1, x_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4; real r__1, r__2, r__3, r__4; complex q__1, q__2, q__3; /* Builtin functions */ double r_imag(complex *), c_abs(complex *); void c_div(complex *, complex *, complex *), r_cnjg(complex *, complex *); double sqrt(doublereal); /* Local variables */ real b, c__, f, g; integer i__, j, k, l=0, m; complex r__, t; real t1, el; integer kk; real cs; integer ll, mm, ls=0; real sl; integer lu; real sm, sn; integer lm1, mm1, lp1, mp1, nct, ncu, lls, nrt; real emm1, smm1; integer kase, jobu, iter; real test; integer nctp1, nrtp1; extern /* Subroutine */ int cscal_(integer *, complex *, complex *, integer *); real scale; extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer *, complex *, integer *); real shift; extern /* Subroutine */ int cswap_(integer *, complex *, integer *, complex *, integer *); integer maxit; extern /* Subroutine */ int caxpy_(integer *, complex *, complex *, integer *, complex *, integer *), csrot_(integer *, complex *, integer *, complex *, integer *, real *, real *); logical wantu, wantv; extern /* Subroutine */ int srotg_(real *, real *, real *, real *); real ztest; extern doublereal scnrm2_(integer *, complex *, integer *); /*< integer ldx,n,p,ldu,ldv,job,info >*/ /*< complex x(ldx,1),s(1),e(1),u(ldu,1),v(ldv,1),work(1) >*/ /* csvdc is a subroutine to reduce a complex nxp matrix x by */ /* unitary transformations u and v to diagonal form. the */ /* diagonal elements s(i) are the singular values of x. the */ /* columns of u are the corresponding left singular vectors, */ /* and the columns of v the right singular vectors. */ /* on entry */ /* x complex(ldx,p), where ldx.ge.n. */ /* x contains the matrix whose singular value */ /* decomposition is to be computed. x is */ /* destroyed by csvdc. */ /* ldx integer. */ /* ldx is the leading dimension of the array x. */ /* n integer. */ /* n is the number of rows of the matrix x. */ /* p integer. */ /* p is the number of columns of the matrix x. */ /* ldu integer. */ /* ldu is the leading dimension of the array u */ /* (see below). */ /* ldv integer. */ /* ldv is the leading dimension of the array v */ /* (see below). */ /* work complex(n). */ /* work is a scratch array. */ /* job integer. */ /* job controls the computation of the singular */ /* vectors. it has the decimal expansion ab */ /* with the following meaning */ /* a.eq.0 do not compute the left singular */ /* vectors. */ /* a.eq.1 return the n left singular vectors */ /* in u. */ /* a.ge.2 returns the first min(n,p) */ /* left singular vectors in u. */ /* b.eq.0 do not compute the right singular */ /* vectors. */ /* b.eq.1 return the right singular vectors */ /* in v. */ /* on return */ /* s complex(mm), where mm=min(n+1,p). */ /* the first min(n,p) entries of s contain the */ /* singular values of x arranged in descending */ /* order of magnitude. */ /* e complex(p). */ /* e ordinarily contains zeros. however see the */ /* discussion of info for exceptions. */ /* u complex(ldu,k), where ldu.ge.n. if joba.eq.1 then */ /* k.eq.n, if joba.ge.2 then */ /* k.eq.min(n,p). */ /* u contains the matrix of left singular vectors. */ /* u is not referenced if joba.eq.0. if n.le.p */ /* or if joba.gt.2, then u may be identified with x */ /* in the subroutine call. */ /* v complex(ldv,p), where ldv.ge.p. */ /* v contains the matrix of right singular vectors. */ /* v is not referenced if jobb.eq.0. if p.le.n, */ /* then v may be identified whth x in the */ /* subroutine call. */ /* info integer. */ /* the singular values (and their corresponding */ /* singular vectors) s(info+1),s(info+2),...,s(m) */ /* are correct (here m=min(n,p)). thus if */ /* info.eq.0, all the singular values and their */ /* vectors are correct. in any event, the matrix */ /* b = ctrans(u)*x*v is the bidiagonal matrix */ /* with the elements of s on its diagonal and the */ /* elements of e on its super-diagonal (ctrans(u) */ /* is the conjugate-transpose of u). thus the */ /* singular values of x and b are the same. */ /* linpack. this version dated 03/19/79 . */ /* correction to shift calculation made 2/85. */ /* g.w. stewart, university of maryland, argonne national lab. */ /* csvdc uses the following functions and subprograms. */ /* external csrot */ /* blas caxpy,cdotc,cscal,cswap,scnrm2,srotg */ /* fortran abs,aimag,amax1,cabs,cmplx */ /* fortran conjg,max0,min0,mod,real,sqrt */ /* internal variables */ /*< >*/ /*< complex cdotc,t,r >*/ /*< >*/ /*< logical wantu,wantv >*/ /*< complex csign,zdum,zdum1,zdum2 >*/ /*< real cabs1 >*/ /*< cabs1(zdum) = abs(real(zdum)) + abs(aimag(zdum)) >*/ /*< csign(zdum1,zdum2) = cabs(zdum1)*(zdum2/cabs(zdum2)) >*/ /* set the maximum number of iterations. */ /*< maxit = 1000 >*/ /* Parameter adjustments */ x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --s; --e; u_dim1 = *ldu; u_offset = 1 + u_dim1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1; v -= v_offset; --work; /* Function Body */ maxit = 1000; /* determine what is to be computed. */ /*< wantu = .false. >*/ wantu = FALSE_; /*< wantv = .false. >*/ wantv = FALSE_; /*< jobu = mod(job,100)/10 >*/ jobu = *job % 100 / 10; /*< ncu = n >*/ ncu = *n; /*< if (jobu .gt. 1) ncu = min0(n,p) >*/ if (jobu > 1) { ncu = min(*n,*p); } /*< if (jobu .ne. 0) wantu = .true. >*/ if (jobu != 0) { wantu = TRUE_; } /*< if (mod(job,10) .ne. 0) wantv = .true. >*/ if (*job % 10 != 0) { wantv = TRUE_; } /* reduce x to bidiagonal form, storing the diagonal elements */ /* in s and the super-diagonal elements in e. */ /*< info = 0 >*/ *info = 0; /*< nct = min0(n-1,p) >*/ /* Computing MIN */ i__1 = *n - 1; nct = min(i__1,*p); /*< nrt = max0(0,min0(p-2,n)) >*/ /* Computing MAX */ /* Computing MIN */ i__3 = *p - 2; i__1 = 0, i__2 = min(i__3,*n); nrt = max(i__1,i__2); /*< lu = max0(nct,nrt) >*/ lu = max(nct,nrt); /*< if (lu .lt. 1) go to 170 >*/ if (lu < 1) { goto L170; } /*< do 160 l = 1, lu >*/ i__1 = lu; for (l = 1; l <= i__1; ++l) { /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (l .gt. nct) go to 20 >*/ if (l > nct) { goto L20; } /* compute the transformation for the l-th column and */ /* place the l-th diagonal in s(l). */ /*< s(l) = cmplx(scnrm2(n-l+1,x(l,l),1),0.0e0) >*/ i__2 = l; i__3 = *n - l + 1; r__1 = scnrm2_(&i__3, &x[l + l * x_dim1], &c__1); q__1.r = r__1, q__1.i = (float)0.; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< if (cabs1(s(l)) .eq. 0.0e0) go to 10 >*/ i__2 = l; if ((r__1 = s[i__2].r, dabs(r__1)) + (r__2 = r_imag(&s[l]), dabs(r__2) ) == (float)0.) { goto L10; } /*< if (cabs1(x(l,l)) .ne. 0.0e0) s(l) = csign(s(l),x(l,l)) >*/ i__2 = l + l * x_dim1; if ((r__1 = x[i__2].r, dabs(r__1)) + (r__2 = r_imag(&x[l + l * x_dim1] ), dabs(r__2)) != (float)0.) { i__3 = l; r__3 = c_abs(&s[l]); i__4 = l + l * x_dim1; r__4 = c_abs(&x[l + l * x_dim1]); q__2.r = x[i__4].r / r__4, q__2.i = x[i__4].i / r__4; q__1.r = r__3 * q__2.r, q__1.i = r__3 * q__2.i; s[i__3].r = q__1.r, s[i__3].i = q__1.i; } /*< call cscal(n-l+1,1.0e0/s(l),x(l,l),1) >*/ i__2 = *n - l + 1; c_div(&q__1, &c_b8, &s[l]); cscal_(&i__2, &q__1, &x[l + l * x_dim1], &c__1); /*< x(l,l) = (1.0e0,0.0e0) + x(l,l) >*/ i__2 = l + l * x_dim1; i__3 = l + l * x_dim1; q__1.r = x[i__3].r + (float)1., q__1.i = x[i__3].i + (float)0.; x[i__2].r = q__1.r, x[i__2].i = q__1.i; /*< 10 continue >*/ L10: /*< s(l) = -s(l) >*/ i__2 = l; i__3 = l; q__1.r = -s[i__3].r, q__1.i = -s[i__3].i; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< 20 continue >*/ L20: /*< if (p .lt. lp1) go to 50 >*/ if (*p < lp1) { goto L50; } /*< do 40 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< if (l .gt. nct) go to 30 >*/ if (l > nct) { goto L30; } /*< if (cabs1(s(l)) .eq. 0.0e0) go to 30 >*/ i__3 = l; if ((r__1 = s[i__3].r, dabs(r__1)) + (r__2 = r_imag(&s[l]), dabs( r__2)) == (float)0.) { goto L30; } /* apply the transformation. */ /*< t = -cdotc(n-l+1,x(l,l),1,x(l,j),1)/x(l,l) >*/ i__3 = *n - l + 1; cdotc_(&q__3, &i__3, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1] , &c__1); q__2.r = -q__3.r, q__2.i = -q__3.i; c_div(&q__1, &q__2, &x[l + l * x_dim1]); t.r = q__1.r, t.i = q__1.i; /*< call caxpy(n-l+1,t,x(l,l),1,x(l,j),1) >*/ i__3 = *n - l + 1; caxpy_(&i__3, &t, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1], & c__1); /*< 30 continue >*/ L30: /* place the l-th row of x into e for the */ /* subsequent calculation of the row transformation. */ /*< e(j) = conjg(x(l,j)) >*/ i__3 = j; r_cnjg(&q__1, &x[l + j * x_dim1]); e[i__3].r = q__1.r, e[i__3].i = q__1.i; /*< 40 continue >*/ /* L40: */ } /*< 50 continue >*/ L50: /*< if (.not.wantu .or. l .gt. nct) go to 70 >*/ if (! wantu || l > nct) { goto L70; } /* place the transformation in u for subsequent back */ /* multiplication. */ /*< do 60 i = l, n >*/ i__2 = *n; for (i__ = l; i__ <= i__2; ++i__) { /*< u(i,l) = x(i,l) >*/ i__3 = i__ + l * u_dim1; i__4 = i__ + l * x_dim1; u[i__3].r = x[i__4].r, u[i__3].i = x[i__4].i; /*< 60 continue >*/ /* L60: */ } /*< 70 continue >*/ L70: /*< if (l .gt. nrt) go to 150 >*/ if (l > nrt) { goto L150; } /* compute the l-th row transformation and place the */ /* l-th super-diagonal in e(l). */ /*< e(l) = cmplx(scnrm2(p-l,e(lp1),1),0.0e0) >*/ i__2 = l; i__3 = *p - l; r__1 = scnrm2_(&i__3, &e[lp1], &c__1); q__1.r = r__1, q__1.i = (float)0.; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< if (cabs1(e(l)) .eq. 0.0e0) go to 80 >*/ i__2 = l; if ((r__1 = e[i__2].r, dabs(r__1)) + (r__2 = r_imag(&e[l]), dabs(r__2) ) == (float)0.) { goto L80; } /*< if (cabs1(e(lp1)) .ne. 0.0e0) e(l) = csign(e(l),e(lp1)) >*/ i__2 = lp1; if ((r__1 = e[i__2].r, dabs(r__1)) + (r__2 = r_imag(&e[lp1]), dabs( r__2)) != (float)0.) { i__3 = l; r__3 = c_abs(&e[l]); i__4 = lp1; r__4 = c_abs(&e[lp1]); q__2.r = e[i__4].r / r__4, q__2.i = e[i__4].i / r__4; q__1.r = r__3 * q__2.r, q__1.i = r__3 * q__2.i; e[i__3].r = q__1.r, e[i__3].i = q__1.i; } /*< call cscal(p-l,1.0e0/e(l),e(lp1),1) >*/ i__2 = *p - l; c_div(&q__1, &c_b8, &e[l]); cscal_(&i__2, &q__1, &e[lp1], &c__1); /*< e(lp1) = (1.0e0,0.0e0) + e(lp1) >*/ i__2 = lp1; i__3 = lp1; q__1.r = e[i__3].r + (float)1., q__1.i = e[i__3].i + (float)0.; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< 80 continue >*/ L80: /*< e(l) = -conjg(e(l)) >*/ i__2 = l; r_cnjg(&q__2, &e[l]); q__1.r = -q__2.r, q__1.i = -q__2.i; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< if (lp1 .gt. n .or. cabs1(e(l)) .eq. 0.0e0) go to 120 >*/ i__2 = l; if (lp1 > *n || (r__1 = e[i__2].r, dabs(r__1)) + (r__2 = r_imag(&e[l]) , dabs(r__2)) == (float)0.) { goto L120; } /* apply the transformation. */ /*< do 90 i = lp1, n >*/ i__2 = *n; for (i__ = lp1; i__ <= i__2; ++i__) { /*< work(i) = (0.0e0,0.0e0) >*/ i__3 = i__; work[i__3].r = (float)0., work[i__3].i = (float)0.; /*< 90 continue >*/ /* L90: */ } /*< do 100 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< call caxpy(n-l,e(j),x(lp1,j),1,work(lp1),1) >*/ i__3 = *n - l; caxpy_(&i__3, &e[j], &x[lp1 + j * x_dim1], &c__1, &work[lp1], & c__1); /*< 100 continue >*/ /* L100: */ } /*< do 110 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< >*/ i__3 = *n - l; i__4 = j; q__3.r = -e[i__4].r, q__3.i = -e[i__4].i; c_div(&q__2, &q__3, &e[lp1]); r_cnjg(&q__1, &q__2); caxpy_(&i__3, &q__1, &work[lp1], &c__1, &x[lp1 + j * x_dim1], & c__1); /*< 110 continue >*/ /* L110: */ } /*< 120 continue >*/ L120: /*< if (.not.wantv) go to 140 >*/ if (! wantv) { goto L140; } /* place the transformation in v for subsequent */ /* back multiplication. */ /*< do 130 i = lp1, p >*/ i__2 = *p; for (i__ = lp1; i__ <= i__2; ++i__) { /*< v(i,l) = e(i) >*/ i__3 = i__ + l * v_dim1; i__4 = i__; v[i__3].r = e[i__4].r, v[i__3].i = e[i__4].i; /*< 130 continue >*/ /* L130: */ } /*< 140 continue >*/ L140: /*< 150 continue >*/ L150: /*< 160 continue >*/ /* L160: */ ; } /*< 170 continue >*/ L170: /* set up the final bidiagonal matrix or order m. */ /*< m = min0(p,n+1) >*/ /* Computing MIN */ i__1 = *p, i__2 = *n + 1; m = min(i__1,i__2); /*< nctp1 = nct + 1 >*/ nctp1 = nct + 1; /*< nrtp1 = nrt + 1 >*/ nrtp1 = nrt + 1; /*< if (nct .lt. p) s(nctp1) = x(nctp1,nctp1) >*/ if (nct < *p) { i__1 = nctp1; i__2 = nctp1 + nctp1 * x_dim1; s[i__1].r = x[i__2].r, s[i__1].i = x[i__2].i; } /*< if (n .lt. m) s(m) = (0.0e0,0.0e0) >*/ if (*n < m) { i__1 = m; s[i__1].r = (float)0., s[i__1].i = (float)0.; } /*< if (nrtp1 .lt. m) e(nrtp1) = x(nrtp1,m) >*/ if (nrtp1 < m) { i__1 = nrtp1; i__2 = nrtp1 + m * x_dim1; e[i__1].r = x[i__2].r, e[i__1].i = x[i__2].i; } /*< e(m) = (0.0e0,0.0e0) >*/ i__1 = m; e[i__1].r = (float)0., e[i__1].i = (float)0.; /* if required, generate u. */ /*< if (.not.wantu) go to 300 >*/ if (! wantu) { goto L300; } /*< if (ncu .lt. nctp1) go to 200 >*/ if (ncu < nctp1) { goto L200; } /*< do 190 j = nctp1, ncu >*/ i__1 = ncu; for (j = nctp1; j <= i__1; ++j) { /*< do 180 i = 1, n >*/ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,j) = (0.0e0,0.0e0) >*/ i__3 = i__ + j * u_dim1; u[i__3].r = (float)0., u[i__3].i = (float)0.; /*< 180 continue >*/ /* L180: */ } /*< u(j,j) = (1.0e0,0.0e0) >*/ i__2 = j + j * u_dim1; u[i__2].r = (float)1., u[i__2].i = (float)0.; /*< 190 continue >*/ /* L190: */ } /*< 200 continue >*/ L200: /*< if (nct .lt. 1) go to 290 >*/ if (nct < 1) { goto L290; } /*< do 280 ll = 1, nct >*/ i__1 = nct; for (ll = 1; ll <= i__1; ++ll) { /*< l = nct - ll + 1 >*/ l = nct - ll + 1; /*< if (cabs1(s(l)) .eq. 0.0e0) go to 250 >*/ i__2 = l; if ((r__1 = s[i__2].r, dabs(r__1)) + (r__2 = r_imag(&s[l]), dabs(r__2) ) == (float)0.) { goto L250; } /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (ncu .lt. lp1) go to 220 >*/ if (ncu < lp1) { goto L220; } /*< do 210 j = lp1, ncu >*/ i__2 = ncu; for (j = lp1; j <= i__2; ++j) { /*< t = -cdotc(n-l+1,u(l,l),1,u(l,j),1)/u(l,l) >*/ i__3 = *n - l + 1; cdotc_(&q__3, &i__3, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1] , &c__1); q__2.r = -q__3.r, q__2.i = -q__3.i; c_div(&q__1, &q__2, &u[l + l * u_dim1]); t.r = q__1.r, t.i = q__1.i; /*< call caxpy(n-l+1,t,u(l,l),1,u(l,j),1) >*/ i__3 = *n - l + 1; caxpy_(&i__3, &t, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1], & c__1); /*< 210 continue >*/ /* L210: */ } /*< 220 continue >*/ L220: /*< call cscal(n-l+1,(-1.0e0,0.0e0),u(l,l),1) >*/ i__2 = *n - l + 1; cscal_(&i__2, &c_b53, &u[l + l * u_dim1], &c__1); /*< u(l,l) = (1.0e0,0.0e0) + u(l,l) >*/ i__2 = l + l * u_dim1; i__3 = l + l * u_dim1; q__1.r = u[i__3].r + (float)1., q__1.i = u[i__3].i + (float)0.; u[i__2].r = q__1.r, u[i__2].i = q__1.i; /*< lm1 = l - 1 >*/ lm1 = l - 1; /*< if (lm1 .lt. 1) go to 240 >*/ if (lm1 < 1) { goto L240; } /*< do 230 i = 1, lm1 >*/ i__2 = lm1; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,l) = (0.0e0,0.0e0) >*/ i__3 = i__ + l * u_dim1; u[i__3].r = (float)0., u[i__3].i = (float)0.; /*< 230 continue >*/ /* L230: */ } /*< 240 continue >*/ L240: /*< go to 270 >*/ goto L270; /*< 250 continue >*/ L250: /*< do 260 i = 1, n >*/ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,l) = (0.0e0,0.0e0) >*/ i__3 = i__ + l * u_dim1; u[i__3].r = (float)0., u[i__3].i = (float)0.; /*< 260 continue >*/ /* L260: */ } /*< u(l,l) = (1.0e0,0.0e0) >*/ i__2 = l + l * u_dim1; u[i__2].r = (float)1., u[i__2].i = (float)0.; /*< 270 continue >*/ L270: /*< 280 continue >*/ /* L280: */ ; } /*< 290 continue >*/ L290: /*< 300 continue >*/ L300: /* if it is required, generate v. */ /*< if (.not.wantv) go to 350 >*/ if (! wantv) { goto L350; } /*< do 340 ll = 1, p >*/ i__1 = *p; for (ll = 1; ll <= i__1; ++ll) { /*< l = p - ll + 1 >*/ l = *p - ll + 1; /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (l .gt. nrt) go to 320 >*/ if (l > nrt) { goto L320; } /*< if (cabs1(e(l)) .eq. 0.0e0) go to 320 >*/ i__2 = l; if ((r__1 = e[i__2].r, dabs(r__1)) + (r__2 = r_imag(&e[l]), dabs(r__2) ) == (float)0.) { goto L320; } /*< do 310 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< t = -cdotc(p-l,v(lp1,l),1,v(lp1,j),1)/v(lp1,l) >*/ i__3 = *p - l; cdotc_(&q__3, &i__3, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1); q__2.r = -q__3.r, q__2.i = -q__3.i; c_div(&q__1, &q__2, &v[lp1 + l * v_dim1]); t.r = q__1.r, t.i = q__1.i; /*< call caxpy(p-l,t,v(lp1,l),1,v(lp1,j),1) >*/ i__3 = *p - l; caxpy_(&i__3, &t, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1); /*< 310 continue >*/ /* L310: */ } /*< 320 continue >*/ L320: /*< do 330 i = 1, p >*/ i__2 = *p; for (i__ = 1; i__ <= i__2; ++i__) { /*< v(i,l) = (0.0e0,0.0e0) >*/ i__3 = i__ + l * v_dim1; v[i__3].r = (float)0., v[i__3].i = (float)0.; /*< 330 continue >*/ /* L330: */ } /*< v(l,l) = (1.0e0,0.0e0) >*/ i__2 = l + l * v_dim1; v[i__2].r = (float)1., v[i__2].i = (float)0.; /*< 340 continue >*/ /* L340: */ } /*< 350 continue >*/ L350: /* transform s and e so that they are real. */ /*< do 380 i = 1, m >*/ i__1 = m; for (i__ = 1; i__ <= i__1; ++i__) { /*< if (cabs1(s(i)) .eq. 0.0e0) go to 360 >*/ i__2 = i__; if ((r__1 = s[i__2].r, dabs(r__1)) + (r__2 = r_imag(&s[i__]), dabs( r__2)) == (float)0.) { goto L360; } /*< t = cmplx(cabs(s(i)),0.0e0) >*/ r__1 = c_abs(&s[i__]); q__1.r = r__1, q__1.i = (float)0.; t.r = q__1.r, t.i = q__1.i; /*< r = s(i)/t >*/ c_div(&q__1, &s[i__], &t); r__.r = q__1.r, r__.i = q__1.i; /*< s(i) = t >*/ i__2 = i__; s[i__2].r = t.r, s[i__2].i = t.i; /*< if (i .lt. m) e(i) = e(i)/r >*/ if (i__ < m) { i__2 = i__; c_div(&q__1, &e[i__], &r__); e[i__2].r = q__1.r, e[i__2].i = q__1.i; } /*< if (wantu) call cscal(n,r,u(1,i),1) >*/ if (wantu) { cscal_(n, &r__, &u[i__ * u_dim1 + 1], &c__1); } /*< 360 continue >*/ L360: /* ...exit */ /*< if (i .eq. m) go to 390 >*/ if (i__ == m) { goto L390; } /*< if (cabs1(e(i)) .eq. 0.0e0) go to 370 >*/ i__2 = i__; if ((r__1 = e[i__2].r, dabs(r__1)) + (r__2 = r_imag(&e[i__]), dabs( r__2)) == (float)0.) { goto L370; } /*< t = cmplx(cabs(e(i)),0.0e0) >*/ r__1 = c_abs(&e[i__]); q__1.r = r__1, q__1.i = (float)0.; t.r = q__1.r, t.i = q__1.i; /*< r = t/e(i) >*/ c_div(&q__1, &t, &e[i__]); r__.r = q__1.r, r__.i = q__1.i; /*< e(i) = t >*/ i__2 = i__; e[i__2].r = t.r, e[i__2].i = t.i; /*< s(i+1) = s(i+1)*r >*/ i__2 = i__ + 1; i__3 = i__ + 1; q__1.r = s[i__3].r * r__.r - s[i__3].i * r__.i, q__1.i = s[i__3].r * r__.i + s[i__3].i * r__.r; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< if (wantv) call cscal(p,r,v(1,i+1),1) >*/ if (wantv) { cscal_(p, &r__, &v[(i__ + 1) * v_dim1 + 1], &c__1); } /*< 370 continue >*/ L370: /*< 380 continue >*/ /* L380: */ ; } /*< 390 continue >*/ L390: /* main iteration loop for the singular values. */ /*< mm = m >*/ mm = m; /*< iter = 0 >*/ iter = 0; /*< 400 continue >*/ L400: /* quit if all the singular values have been found. */ /* ...exit */ /*< if (m .eq. 0) go to 660 >*/ if (m == 0) { goto L660; } /* if too many iterations have been performed, set */ /* flag and return. */ /*< if (iter .lt. maxit) go to 410 >*/ if (iter < maxit) { goto L410; } /*< info = m >*/ *info = m; /* ......exit */ /*< go to 660 >*/ goto L660; /*< 410 continue >*/ L410: /* this section of the program inspects for */ /* negligible elements in the s and e arrays. on */ /* completion the variables kase and l are set as follows. */ /* kase = 1 if s(m) and e(l-1) are negligible and l.lt.m */ /* kase = 2 if s(l) is negligible and l.lt.m */ /* kase = 3 if e(l-1) is negligible, l.lt.m, and */ /* s(l), ..., s(m) are not negligible (qr step). */ /* kase = 4 if e(m-1) is negligible (convergence). */ /*< do 430 ll = 1, m >*/ i__1 = m; for (ll = 1; ll <= i__1; ++ll) { /*< l = m - ll >*/ l = m - ll; /* ...exit */ /*< if (l .eq. 0) go to 440 >*/ if (l == 0) { goto L440; } /*< test = cabs(s(l)) + cabs(s(l+1)) >*/ test = c_abs(&s[l]) + c_abs(&s[l + 1]); /*< ztest = test + cabs(e(l)) >*/ ztest = test + c_abs(&e[l]); /*< if (ztest .ne. test) go to 420 >*/ if (ztest != test) { goto L420; } /*< e(l) = (0.0e0,0.0e0) >*/ i__2 = l; e[i__2].r = (float)0., e[i__2].i = (float)0.; /* ......exit */ /*< go to 440 >*/ goto L440; /*< 420 continue >*/ L420: /*< 430 continue >*/ /* L430: */ ; } /*< 440 continue >*/ L440: /*< if (l .ne. m - 1) go to 450 >*/ if (l != m - 1) { goto L450; } /*< kase = 4 >*/ kase = 4; /*< go to 520 >*/ goto L520; /*< 450 continue >*/ L450: /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< mp1 = m + 1 >*/ mp1 = m + 1; /*< do 470 lls = lp1, mp1 >*/ i__1 = mp1; for (lls = lp1; lls <= i__1; ++lls) { /*< ls = m - lls + lp1 >*/ ls = m - lls + lp1; /* ...exit */ /*< if (ls .eq. l) go to 480 >*/ if (ls == l) { goto L480; } /*< test = 0.0e0 >*/ test = (float)0.; /*< if (ls .ne. m) test = test + cabs(e(ls)) >*/ if (ls != m) { test += c_abs(&e[ls]); } /*< if (ls .ne. l + 1) test = test + cabs(e(ls-1)) >*/ if (ls != l + 1) { test += c_abs(&e[ls - 1]); } /*< ztest = test + cabs(s(ls)) >*/ ztest = test + c_abs(&s[ls]); /*< if (ztest .ne. test) go to 460 >*/ if (ztest != test) { goto L460; } /*< s(ls) = (0.0e0,0.0e0) >*/ i__2 = ls; s[i__2].r = (float)0., s[i__2].i = (float)0.; /* ......exit */ /*< go to 480 >*/ goto L480; /*< 460 continue >*/ L460: /*< 470 continue >*/ /* L470: */ ; } /*< 480 continue >*/ L480: /*< if (ls .ne. l) go to 490 >*/ if (ls != l) { goto L490; } /*< kase = 3 >*/ kase = 3; /*< go to 510 >*/ goto L510; /*< 490 continue >*/ L490: /*< if (ls .ne. m) go to 500 >*/ if (ls != m) { goto L500; } /*< kase = 1 >*/ kase = 1; /*< go to 510 >*/ goto L510; /*< 500 continue >*/ L500: /*< kase = 2 >*/ kase = 2; /*< l = ls >*/ l = ls; /*< 510 continue >*/ L510: /*< 520 continue >*/ L520: /*< l = l + 1 >*/ ++l; /* perform the task indicated by kase. */ /*< go to (530, 560, 580, 610), kase >*/ switch (kase) { case 1: goto L530; case 2: goto L560; case 3: goto L580; case 4: goto L610; } /* deflate negligible s(m). */ /*< 530 continue >*/ L530: /*< mm1 = m - 1 >*/ mm1 = m - 1; /*< f = real(e(m-1)) >*/ i__1 = m - 1; f = e[i__1].r; /*< e(m-1) = (0.0e0,0.0e0) >*/ i__1 = m - 1; e[i__1].r = (float)0., e[i__1].i = (float)0.; /*< do 550 kk = l, mm1 >*/ i__1 = mm1; for (kk = l; kk <= i__1; ++kk) { /*< k = mm1 - kk + l >*/ k = mm1 - kk + l; /*< t1 = real(s(k)) >*/ i__2 = k; t1 = s[i__2].r; /*< call srotg(t1,f,cs,sn) >*/ srotg_(&t1, &f, &cs, &sn); /*< s(k) = cmplx(t1,0.0e0) >*/ i__2 = k; q__1.r = t1, q__1.i = (float)0.; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< if (k .eq. l) go to 540 >*/ if (k == l) { goto L540; } /*< f = -sn*real(e(k-1)) >*/ i__2 = k - 1; f = -sn * e[i__2].r; /*< e(k-1) = cs*e(k-1) >*/ i__2 = k - 1; i__3 = k - 1; q__1.r = cs * e[i__3].r, q__1.i = cs * e[i__3].i; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< 540 continue >*/ L540: /*< if (wantv) call csrot(p,v(1,k),1,v(1,m),1,cs,sn) >*/ if (wantv) { csrot_(p, &v[k * v_dim1 + 1], &c__1, &v[m * v_dim1 + 1], &c__1, & cs, &sn); } /*< 550 continue >*/ /* L550: */ } /*< go to 650 >*/ goto L650; /* split at negligible s(l). */ /*< 560 continue >*/ L560: /*< f = real(e(l-1)) >*/ i__1 = l - 1; f = e[i__1].r; /*< e(l-1) = (0.0e0,0.0e0) >*/ i__1 = l - 1; e[i__1].r = (float)0., e[i__1].i = (float)0.; /*< do 570 k = l, m >*/ i__1 = m; for (k = l; k <= i__1; ++k) { /*< t1 = real(s(k)) >*/ i__2 = k; t1 = s[i__2].r; /*< call srotg(t1,f,cs,sn) >*/ srotg_(&t1, &f, &cs, &sn); /*< s(k) = cmplx(t1,0.0e0) >*/ i__2 = k; q__1.r = t1, q__1.i = (float)0.; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< f = -sn*real(e(k)) >*/ i__2 = k; f = -sn * e[i__2].r; /*< e(k) = cs*e(k) >*/ i__2 = k; i__3 = k; q__1.r = cs * e[i__3].r, q__1.i = cs * e[i__3].i; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< if (wantu) call csrot(n,u(1,k),1,u(1,l-1),1,cs,sn) >*/ if (wantu) { csrot_(n, &u[k * u_dim1 + 1], &c__1, &u[(l - 1) * u_dim1 + 1], & c__1, &cs, &sn); } /*< 570 continue >*/ /* L570: */ } /*< go to 650 >*/ goto L650; /* perform one qr step. */ /*< 580 continue >*/ L580: /* calculate the shift. */ /*< >*/ /* Computing MAX */ r__1 = c_abs(&s[m]), r__2 = c_abs(&s[m - 1]), r__1 = max(r__1,r__2), r__2 = c_abs(&e[m - 1]), r__1 = max(r__1,r__2), r__2 = c_abs(&s[l]), r__1 = max(r__1,r__2), r__2 = c_abs(&e[l]); scale = dmax(r__1,r__2); /*< sm = real(s(m))/scale >*/ i__1 = m; sm = s[i__1].r / scale; /*< smm1 = real(s(m-1))/scale >*/ i__1 = m - 1; smm1 = s[i__1].r / scale; /*< emm1 = real(e(m-1))/scale >*/ i__1 = m - 1; emm1 = e[i__1].r / scale; /*< sl = real(s(l))/scale >*/ i__1 = l; sl = s[i__1].r / scale; /*< el = real(e(l))/scale >*/ i__1 = l; el = e[i__1].r / scale; /*< b = ((smm1 + sm)*(smm1 - sm) + emm1**2)/2.0e0 >*/ /* Computing 2nd power */ r__1 = emm1; b = ((smm1 + sm) * (smm1 - sm) + r__1 * r__1) / (float)2.; /*< c = (sm*emm1)**2 >*/ /* Computing 2nd power */ r__1 = sm * emm1; c__ = r__1 * r__1; /*< shift = 0.0e0 >*/ shift = (float)0.; /*< if (b .eq. 0.0e0 .and. c .eq. 0.0e0) go to 590 >*/ if (b == (float)0. && c__ == (float)0.) { goto L590; } /*< shift = sqrt(b**2+c) >*/ /* Computing 2nd power */ r__1 = b; shift = sqrt(r__1 * r__1 + c__); /*< if (b .lt. 0.0e0) shift = -shift >*/ if (b < (float)0.) { shift = -shift; } /*< shift = c/(b + shift) >*/ shift = c__ / (b + shift); /*< 590 continue >*/ L590: /*< f = (sl + sm)*(sl - sm) + shift >*/ f = (sl + sm) * (sl - sm) + shift; /*< g = sl*el >*/ g = sl * el; /* chase zeros. */ /*< mm1 = m - 1 >*/ mm1 = m - 1; /*< do 600 k = l, mm1 >*/ i__1 = mm1; for (k = l; k <= i__1; ++k) { /*< call srotg(f,g,cs,sn) >*/ srotg_(&f, &g, &cs, &sn); /*< if (k .ne. l) e(k-1) = cmplx(f,0.0e0) >*/ if (k != l) { i__2 = k - 1; q__1.r = f, q__1.i = (float)0.; e[i__2].r = q__1.r, e[i__2].i = q__1.i; } /*< f = cs*real(s(k)) + sn*real(e(k)) >*/ i__2 = k; i__3 = k; f = cs * s[i__2].r + sn * e[i__3].r; /*< e(k) = cs*e(k) - sn*s(k) >*/ i__2 = k; i__3 = k; q__2.r = cs * e[i__3].r, q__2.i = cs * e[i__3].i; i__4 = k; q__3.r = sn * s[i__4].r, q__3.i = sn * s[i__4].i; q__1.r = q__2.r - q__3.r, q__1.i = q__2.i - q__3.i; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< g = sn*real(s(k+1)) >*/ i__2 = k + 1; g = sn * s[i__2].r; /*< s(k+1) = cs*s(k+1) >*/ i__2 = k + 1; i__3 = k + 1; q__1.r = cs * s[i__3].r, q__1.i = cs * s[i__3].i; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< if (wantv) call csrot(p,v(1,k),1,v(1,k+1),1,cs,sn) >*/ if (wantv) { csrot_(p, &v[k * v_dim1 + 1], &c__1, &v[(k + 1) * v_dim1 + 1], & c__1, &cs, &sn); } /*< call srotg(f,g,cs,sn) >*/ srotg_(&f, &g, &cs, &sn); /*< s(k) = cmplx(f,0.0e0) >*/ i__2 = k; q__1.r = f, q__1.i = (float)0.; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< f = cs*real(e(k)) + sn*real(s(k+1)) >*/ i__2 = k; i__3 = k + 1; f = cs * e[i__2].r + sn * s[i__3].r; /*< s(k+1) = -sn*e(k) + cs*s(k+1) >*/ i__2 = k + 1; r__1 = -sn; i__3 = k; q__2.r = r__1 * e[i__3].r, q__2.i = r__1 * e[i__3].i; i__4 = k + 1; q__3.r = cs * s[i__4].r, q__3.i = cs * s[i__4].i; q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i; s[i__2].r = q__1.r, s[i__2].i = q__1.i; /*< g = sn*real(e(k+1)) >*/ i__2 = k + 1; g = sn * e[i__2].r; /*< e(k+1) = cs*e(k+1) >*/ i__2 = k + 1; i__3 = k + 1; q__1.r = cs * e[i__3].r, q__1.i = cs * e[i__3].i; e[i__2].r = q__1.r, e[i__2].i = q__1.i; /*< >*/ if (wantu && k < *n) { csrot_(n, &u[k * u_dim1 + 1], &c__1, &u[(k + 1) * u_dim1 + 1], & c__1, &cs, &sn); } /*< 600 continue >*/ /* L600: */ } /*< e(m-1) = cmplx(f,0.0e0) >*/ i__1 = m - 1; q__1.r = f, q__1.i = (float)0.; e[i__1].r = q__1.r, e[i__1].i = q__1.i; /*< iter = iter + 1 >*/ ++iter; /*< go to 650 >*/ goto L650; /* convergence. */ /*< 610 continue >*/ L610: /* make the singular value positive */ /*< if (real(s(l)) .ge. 0.0e0) go to 620 >*/ i__1 = l; if (s[i__1].r >= (float)0.) { goto L620; } /*< s(l) = -s(l) >*/ i__1 = l; i__2 = l; q__1.r = -s[i__2].r, q__1.i = -s[i__2].i; s[i__1].r = q__1.r, s[i__1].i = q__1.i; /*< if (wantv) call cscal(p,(-1.0e0,0.0e0),v(1,l),1) >*/ if (wantv) { cscal_(p, &c_b53, &v[l * v_dim1 + 1], &c__1); } /*< 620 continue >*/ L620: /* order the singular value. */ /*< 630 if (l .eq. mm) go to 640 >*/ L630: if (l == mm) { goto L640; } /* ...exit */ /*< if (real(s(l)) .ge. real(s(l+1))) go to 640 >*/ i__1 = l; i__2 = l + 1; if (s[i__1].r >= s[i__2].r) { goto L640; } /*< t = s(l) >*/ i__1 = l; t.r = s[i__1].r, t.i = s[i__1].i; /*< s(l) = s(l+1) >*/ i__1 = l; i__2 = l + 1; s[i__1].r = s[i__2].r, s[i__1].i = s[i__2].i; /*< s(l+1) = t >*/ i__1 = l + 1; s[i__1].r = t.r, s[i__1].i = t.i; /*< >*/ if (wantv && l < *p) { cswap_(p, &v[l * v_dim1 + 1], &c__1, &v[(l + 1) * v_dim1 + 1], &c__1); } /*< >*/ if (wantu && l < *n) { cswap_(n, &u[l * u_dim1 + 1], &c__1, &u[(l + 1) * u_dim1 + 1], &c__1); } /*< l = l + 1 >*/ ++l; /*< go to 630 >*/ goto L630; /*< 640 continue >*/ L640: /*< iter = 0 >*/ iter = 0; /*< m = m - 1 >*/ --m; /*< 650 continue >*/ L650: /*< go to 400 >*/ goto L400; /*< 660 continue >*/ L660: /*< return >*/ return 0; /*< end >*/ } /* csvdc_ */
/* Subroutine */ int chemv_(char *uplo, integer *n, complex *alpha, complex * a, integer *lda, complex *x, integer *incx, complex *beta, complex *y, integer *incy) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; doublereal d__1; complex q__1, q__2, q__3, q__4; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer info; static complex temp1, temp2; static integer i, j; extern logical lsame_(char *, char *); static integer ix, iy, jx, jy, kx, ky; extern /* Subroutine */ int xerbla_(char *, integer *); /* Purpose ======= CHEMV performs the matrix-vector operation y := alpha*A*x + beta*y, where alpha and beta are scalars, x and y are n element vectors and A is an n by n hermitian matrix. Parameters ========== UPLO - CHARACTER*1. On entry, UPLO specifies whether the upper or lower triangular part of the array A is to be referenced as follows: UPLO = 'U' or 'u' Only the upper triangular part of A is to be referenced. UPLO = 'L' or 'l' Only the lower triangular part of A is to be referenced. Unchanged on exit. N - INTEGER. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - COMPLEX . On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - COMPLEX array of DIMENSION ( LDA, n ). Before entry with UPLO = 'U' or 'u', the leading n by n upper triangular part of the array A must contain the upper triangular part of the hermitian matrix and the strictly lower triangular part of A is not referenced. Before entry with UPLO = 'L' or 'l', the leading n by n lower triangular part of the array A must contain the lower triangular part of the hermitian matrix and the strictly upper triangular part of A is not referenced. Note that the imaginary parts of the diagonal elements need not be set and are assumed to be zero. Unchanged on exit. LDA - INTEGER. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, n ). Unchanged on exit. X - COMPLEX array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. Unchanged on exit. INCX - INTEGER. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. BETA - COMPLEX . On entry, BETA specifies the scalar beta. When BETA is supplied as zero then Y need not be set on input. Unchanged on exit. Y - COMPLEX array of dimension at least ( 1 + ( n - 1 )*abs( INCY ) ). Before entry, the incremented array Y must contain the n element vector y. On exit, Y is overwritten by the updated vector y. INCY - INTEGER. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. Test the input parameters. Parameter adjustments Function Body */ #define X(I) x[(I)-1] #define Y(I) y[(I)-1] #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*lda < max(1,*n)) { info = 5; } else if (*incx == 0) { info = 7; } else if (*incy == 0) { info = 10; } if (info != 0) { xerbla_("CHEMV ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || alpha->r == 0.f && alpha->i == 0.f && (beta->r == 1.f && beta->i == 0.f)) { return 0; } /* Set up the start points in X and Y. */ if (*incx > 0) { kx = 1; } else { kx = 1 - (*n - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (*n - 1) * *incy; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through the triangular part of A. First form y := beta*y. */ if (beta->r != 1.f || beta->i != 0.f) { if (*incy == 1) { if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i = 1; i <= *n; ++i) { i__2 = i; Y(i).r = 0.f, Y(i).i = 0.f; /* L10: */ } } else { i__1 = *n; for (i = 1; i <= *n; ++i) { i__2 = i; i__3 = i; q__1.r = beta->r * Y(i).r - beta->i * Y(i).i, q__1.i = beta->r * Y(i).i + beta->i * Y(i) .r; Y(i).r = q__1.r, Y(i).i = q__1.i; /* L20: */ } } } else { iy = ky; if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i = 1; i <= *n; ++i) { i__2 = iy; Y(iy).r = 0.f, Y(iy).i = 0.f; iy += *incy; /* L30: */ } } else { i__1 = *n; for (i = 1; i <= *n; ++i) { i__2 = iy; i__3 = iy; q__1.r = beta->r * Y(iy).r - beta->i * Y(iy).i, q__1.i = beta->r * Y(iy).i + beta->i * Y(iy) .r; Y(iy).r = q__1.r, Y(iy).i = q__1.i; iy += *incy; /* L40: */ } } } } if (alpha->r == 0.f && alpha->i == 0.f) { return 0; } if (lsame_(uplo, "U")) { /* Form y when A is stored in upper triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = j; q__1.r = alpha->r * X(j).r - alpha->i * X(j).i, q__1.i = alpha->r * X(j).i + alpha->i * X(j).r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__2 = j - 1; for (i = 1; i <= j-1; ++i) { i__3 = i; i__4 = i; i__5 = i + j * a_dim1; q__2.r = temp1.r * A(i,j).r - temp1.i * A(i,j).i, q__2.i = temp1.r * A(i,j).i + temp1.i * A(i,j) .r; q__1.r = Y(i).r + q__2.r, q__1.i = Y(i).i + q__2.i; Y(i).r = q__1.r, Y(i).i = q__1.i; r_cnjg(&q__3, &A(i,j)); i__3 = i; q__2.r = q__3.r * X(i).r - q__3.i * X(i).i, q__2.i = q__3.r * X(i).i + q__3.i * X(i).r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L50: */ } i__2 = j; i__3 = j; i__4 = j + j * a_dim1; d__1 = A(j,j).r; q__3.r = d__1 * temp1.r, q__3.i = d__1 * temp1.i; q__2.r = Y(j).r + q__3.r, q__2.i = Y(j).i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; Y(j).r = q__1.r, Y(j).i = q__1.i; /* L60: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = jx; q__1.r = alpha->r * X(jx).r - alpha->i * X(jx).i, q__1.i = alpha->r * X(jx).i + alpha->i * X(jx).r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; ix = kx; iy = ky; i__2 = j - 1; for (i = 1; i <= j-1; ++i) { i__3 = iy; i__4 = iy; i__5 = i + j * a_dim1; q__2.r = temp1.r * A(i,j).r - temp1.i * A(i,j).i, q__2.i = temp1.r * A(i,j).i + temp1.i * A(i,j) .r; q__1.r = Y(iy).r + q__2.r, q__1.i = Y(iy).i + q__2.i; Y(iy).r = q__1.r, Y(iy).i = q__1.i; r_cnjg(&q__3, &A(i,j)); i__3 = ix; q__2.r = q__3.r * X(ix).r - q__3.i * X(ix).i, q__2.i = q__3.r * X(ix).i + q__3.i * X(ix).r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; ix += *incx; iy += *incy; /* L70: */ } i__2 = jy; i__3 = jy; i__4 = j + j * a_dim1; d__1 = A(j,j).r; q__3.r = d__1 * temp1.r, q__3.i = d__1 * temp1.i; q__2.r = Y(jy).r + q__3.r, q__2.i = Y(jy).i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; Y(jy).r = q__1.r, Y(jy).i = q__1.i; jx += *incx; jy += *incy; /* L80: */ } } } else { /* Form y when A is stored in lower triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = j; q__1.r = alpha->r * X(j).r - alpha->i * X(j).i, q__1.i = alpha->r * X(j).i + alpha->i * X(j).r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__2 = j; i__3 = j; i__4 = j + j * a_dim1; d__1 = A(j,j).r; q__2.r = d__1 * temp1.r, q__2.i = d__1 * temp1.i; q__1.r = Y(j).r + q__2.r, q__1.i = Y(j).i + q__2.i; Y(j).r = q__1.r, Y(j).i = q__1.i; i__2 = *n; for (i = j + 1; i <= *n; ++i) { i__3 = i; i__4 = i; i__5 = i + j * a_dim1; q__2.r = temp1.r * A(i,j).r - temp1.i * A(i,j).i, q__2.i = temp1.r * A(i,j).i + temp1.i * A(i,j) .r; q__1.r = Y(i).r + q__2.r, q__1.i = Y(i).i + q__2.i; Y(i).r = q__1.r, Y(i).i = q__1.i; r_cnjg(&q__3, &A(i,j)); i__3 = i; q__2.r = q__3.r * X(i).r - q__3.i * X(i).i, q__2.i = q__3.r * X(i).i + q__3.i * X(i).r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L90: */ } i__2 = j; i__3 = j; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = Y(j).r + q__2.r, q__1.i = Y(j).i + q__2.i; Y(j).r = q__1.r, Y(j).i = q__1.i; /* L100: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = jx; q__1.r = alpha->r * X(jx).r - alpha->i * X(jx).i, q__1.i = alpha->r * X(jx).i + alpha->i * X(jx).r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__2 = jy; i__3 = jy; i__4 = j + j * a_dim1; d__1 = A(j,j).r; q__2.r = d__1 * temp1.r, q__2.i = d__1 * temp1.i; q__1.r = Y(jy).r + q__2.r, q__1.i = Y(jy).i + q__2.i; Y(jy).r = q__1.r, Y(jy).i = q__1.i; ix = jx; iy = jy; i__2 = *n; for (i = j + 1; i <= *n; ++i) { ix += *incx; iy += *incy; i__3 = iy; i__4 = iy; i__5 = i + j * a_dim1; q__2.r = temp1.r * A(i,j).r - temp1.i * A(i,j).i, q__2.i = temp1.r * A(i,j).i + temp1.i * A(i,j) .r; q__1.r = Y(iy).r + q__2.r, q__1.i = Y(iy).i + q__2.i; Y(iy).r = q__1.r, Y(iy).i = q__1.i; r_cnjg(&q__3, &A(i,j)); i__3 = ix; q__2.r = q__3.r * X(ix).r - q__3.i * X(ix).i, q__2.i = q__3.r * X(ix).i + q__3.i * X(ix).r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L110: */ } i__2 = jy; i__3 = jy; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = Y(jy).r + q__2.r, q__1.i = Y(jy).i + q__2.i; Y(jy).r = q__1.r, Y(jy).i = q__1.i; jx += *incx; jy += *incy; /* L120: */ } } } return 0; /* End of CHEMV . */ } /* chemv_ */
/* Subroutine */ int clagtm_(char *trans, integer *n, integer *nrhs, real * alpha, complex *dl, complex *d__, complex *du, complex *x, integer * ldx, real *beta, complex *b, integer *ldb) { /* System generated locals */ integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7, i__8, i__9, i__10; complex q__1, q__2, q__3, q__4, q__5, q__6, q__7, q__8, q__9; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ integer i__, j; extern logical lsame_(char *, char *); /* -- LAPACK auxiliary routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CLAGTM performs a matrix-vector product of the form */ /* B := alpha * A * X + beta * B */ /* where A is a tridiagonal matrix of order N, B and X are N by NRHS */ /* matrices, and alpha and beta are real scalars, each of which may be */ /* 0., 1., or -1. */ /* Arguments */ /* ========= */ /* TRANS (input) CHARACTER*1 */ /* Specifies the operation applied to A. */ /* = 'N': No transpose, B := alpha * A * X + beta * B */ /* = 'T': Transpose, B := alpha * A**T * X + beta * B */ /* = 'C': Conjugate transpose, B := alpha * A**H * X + beta * B */ /* 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 X and B. */ /* ALPHA (input) REAL */ /* The scalar alpha. ALPHA must be 0., 1., or -1.; otherwise, */ /* it is assumed to be 0. */ /* DL (input) COMPLEX array, dimension (N-1) */ /* The (n-1) sub-diagonal elements of T. */ /* D (input) COMPLEX array, dimension (N) */ /* The diagonal elements of T. */ /* DU (input) COMPLEX array, dimension (N-1) */ /* The (n-1) super-diagonal elements of T. */ /* X (input) COMPLEX array, dimension (LDX,NRHS) */ /* The N by NRHS matrix X. */ /* LDX (input) INTEGER */ /* The leading dimension of the array X. LDX >= max(N,1). */ /* BETA (input) REAL */ /* The scalar beta. BETA must be 0., 1., or -1.; otherwise, */ /* it is assumed to be 1. */ /* B (input/output) COMPLEX array, dimension (LDB,NRHS) */ /* On entry, the N by NRHS matrix B. */ /* On exit, B is overwritten by the matrix expression */ /* B := alpha * A * X + beta * B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(N,1). */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ --dl; --d__; --du; x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; /* Function Body */ if (*n == 0) { return 0; } /* Multiply B by BETA if BETA.NE.1. */ if (*beta == 0.f) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; b[i__3].r = 0.f, b[i__3].i = 0.f; /* L10: */ } /* L20: */ } } else if (*beta == -1.f) { i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; q__1.r = -b[i__4].r, q__1.i = -b[i__4].i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L30: */ } /* L40: */ } } if (*alpha == 1.f) { if (lsame_(trans, "N")) { /* Compute B := B + A*X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__2.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__2.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__1.r = b[i__3].r + q__2.r, q__1.i = b[i__3].i + q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__3.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__3.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; i__5 = j * x_dim1 + 2; q__4.r = du[1].r * x[i__5].r - du[1].i * x[i__5].i, q__4.i = du[1].r * x[i__5].i + du[1].i * x[i__5] .r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; i__4 = *n - 1; i__5 = *n - 1 + j * x_dim1; q__3.r = dl[i__4].r * x[i__5].r - dl[i__4].i * x[i__5].i, q__3.i = dl[i__4].r * x[i__5].i + dl[i__4].i * x[ i__5].r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; i__6 = *n; i__7 = *n + j * x_dim1; q__4.r = d__[i__6].r * x[i__7].r - d__[i__6].i * x[i__7] .i, q__4.i = d__[i__6].r * x[i__7].i + d__[i__6] .i * x[i__7].r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; i__5 = i__ - 1; i__6 = i__ - 1 + j * x_dim1; q__4.r = dl[i__5].r * x[i__6].r - dl[i__5].i * x[i__6] .i, q__4.i = dl[i__5].r * x[i__6].i + dl[i__5] .i * x[i__6].r; q__3.r = b[i__4].r + q__4.r, q__3.i = b[i__4].i + q__4.i; i__7 = i__; i__8 = i__ + j * x_dim1; q__5.r = d__[i__7].r * x[i__8].r - d__[i__7].i * x[ i__8].i, q__5.i = d__[i__7].r * x[i__8].i + d__[i__7].i * x[i__8].r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; i__9 = i__; i__10 = i__ + 1 + j * x_dim1; q__6.r = du[i__9].r * x[i__10].r - du[i__9].i * x[ i__10].i, q__6.i = du[i__9].r * x[i__10].i + du[i__9].i * x[i__10].r; q__1.r = q__2.r + q__6.r, q__1.i = q__2.i + q__6.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L50: */ } } /* L60: */ } } else if (lsame_(trans, "T")) { /* Compute B := B + A**T * X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__2.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__2.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__1.r = b[i__3].r + q__2.r, q__1.i = b[i__3].i + q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__3.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__3.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; i__5 = j * x_dim1 + 2; q__4.r = dl[1].r * x[i__5].r - dl[1].i * x[i__5].i, q__4.i = dl[1].r * x[i__5].i + dl[1].i * x[i__5] .r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; i__4 = *n - 1; i__5 = *n - 1 + j * x_dim1; q__3.r = du[i__4].r * x[i__5].r - du[i__4].i * x[i__5].i, q__3.i = du[i__4].r * x[i__5].i + du[i__4].i * x[ i__5].r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; i__6 = *n; i__7 = *n + j * x_dim1; q__4.r = d__[i__6].r * x[i__7].r - d__[i__6].i * x[i__7] .i, q__4.i = d__[i__6].r * x[i__7].i + d__[i__6] .i * x[i__7].r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; i__5 = i__ - 1; i__6 = i__ - 1 + j * x_dim1; q__4.r = du[i__5].r * x[i__6].r - du[i__5].i * x[i__6] .i, q__4.i = du[i__5].r * x[i__6].i + du[i__5] .i * x[i__6].r; q__3.r = b[i__4].r + q__4.r, q__3.i = b[i__4].i + q__4.i; i__7 = i__; i__8 = i__ + j * x_dim1; q__5.r = d__[i__7].r * x[i__8].r - d__[i__7].i * x[ i__8].i, q__5.i = d__[i__7].r * x[i__8].i + d__[i__7].i * x[i__8].r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; i__9 = i__; i__10 = i__ + 1 + j * x_dim1; q__6.r = dl[i__9].r * x[i__10].r - dl[i__9].i * x[ i__10].i, q__6.i = dl[i__9].r * x[i__10].i + dl[i__9].i * x[i__10].r; q__1.r = q__2.r + q__6.r, q__1.i = q__2.i + q__6.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L70: */ } } /* L80: */ } } else if (lsame_(trans, "C")) { /* Compute B := B + A**H * X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; r_cnjg(&q__3, &d__[1]); i__4 = j * x_dim1 + 1; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[i__4].r; q__1.r = b[i__3].r + q__2.r, q__1.i = b[i__3].i + q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; r_cnjg(&q__4, &d__[1]); i__4 = j * x_dim1 + 1; q__3.r = q__4.r * x[i__4].r - q__4.i * x[i__4].i, q__3.i = q__4.r * x[i__4].i + q__4.i * x[i__4].r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; r_cnjg(&q__6, &dl[1]); i__5 = j * x_dim1 + 2; q__5.r = q__6.r * x[i__5].r - q__6.i * x[i__5].i, q__5.i = q__6.r * x[i__5].i + q__6.i * x[i__5].r; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; r_cnjg(&q__4, &du[*n - 1]); i__4 = *n - 1 + j * x_dim1; q__3.r = q__4.r * x[i__4].r - q__4.i * x[i__4].i, q__3.i = q__4.r * x[i__4].i + q__4.i * x[i__4].r; q__2.r = b[i__3].r + q__3.r, q__2.i = b[i__3].i + q__3.i; r_cnjg(&q__6, &d__[*n]); i__5 = *n + j * x_dim1; q__5.r = q__6.r * x[i__5].r - q__6.i * x[i__5].i, q__5.i = q__6.r * x[i__5].i + q__6.i * x[i__5].r; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; r_cnjg(&q__5, &du[i__ - 1]); i__5 = i__ - 1 + j * x_dim1; q__4.r = q__5.r * x[i__5].r - q__5.i * x[i__5].i, q__4.i = q__5.r * x[i__5].i + q__5.i * x[i__5] .r; q__3.r = b[i__4].r + q__4.r, q__3.i = b[i__4].i + q__4.i; r_cnjg(&q__7, &d__[i__]); i__6 = i__ + j * x_dim1; q__6.r = q__7.r * x[i__6].r - q__7.i * x[i__6].i, q__6.i = q__7.r * x[i__6].i + q__7.i * x[i__6] .r; q__2.r = q__3.r + q__6.r, q__2.i = q__3.i + q__6.i; r_cnjg(&q__9, &dl[i__]); i__7 = i__ + 1 + j * x_dim1; q__8.r = q__9.r * x[i__7].r - q__9.i * x[i__7].i, q__8.i = q__9.r * x[i__7].i + q__9.i * x[i__7] .r; q__1.r = q__2.r + q__8.r, q__1.i = q__2.i + q__8.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L90: */ } } /* L100: */ } } } else if (*alpha == -1.f) { if (lsame_(trans, "N")) { /* Compute B := B - A*X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__2.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__2.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__1.r = b[i__3].r - q__2.r, q__1.i = b[i__3].i - q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__3.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__3.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; i__5 = j * x_dim1 + 2; q__4.r = du[1].r * x[i__5].r - du[1].i * x[i__5].i, q__4.i = du[1].r * x[i__5].i + du[1].i * x[i__5] .r; q__1.r = q__2.r - q__4.r, q__1.i = q__2.i - q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; i__4 = *n - 1; i__5 = *n - 1 + j * x_dim1; q__3.r = dl[i__4].r * x[i__5].r - dl[i__4].i * x[i__5].i, q__3.i = dl[i__4].r * x[i__5].i + dl[i__4].i * x[ i__5].r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; i__6 = *n; i__7 = *n + j * x_dim1; q__4.r = d__[i__6].r * x[i__7].r - d__[i__6].i * x[i__7] .i, q__4.i = d__[i__6].r * x[i__7].i + d__[i__6] .i * x[i__7].r; q__1.r = q__2.r - q__4.r, q__1.i = q__2.i - q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; i__5 = i__ - 1; i__6 = i__ - 1 + j * x_dim1; q__4.r = dl[i__5].r * x[i__6].r - dl[i__5].i * x[i__6] .i, q__4.i = dl[i__5].r * x[i__6].i + dl[i__5] .i * x[i__6].r; q__3.r = b[i__4].r - q__4.r, q__3.i = b[i__4].i - q__4.i; i__7 = i__; i__8 = i__ + j * x_dim1; q__5.r = d__[i__7].r * x[i__8].r - d__[i__7].i * x[ i__8].i, q__5.i = d__[i__7].r * x[i__8].i + d__[i__7].i * x[i__8].r; q__2.r = q__3.r - q__5.r, q__2.i = q__3.i - q__5.i; i__9 = i__; i__10 = i__ + 1 + j * x_dim1; q__6.r = du[i__9].r * x[i__10].r - du[i__9].i * x[ i__10].i, q__6.i = du[i__9].r * x[i__10].i + du[i__9].i * x[i__10].r; q__1.r = q__2.r - q__6.r, q__1.i = q__2.i - q__6.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L110: */ } } /* L120: */ } } else if (lsame_(trans, "T")) { /* Compute B := B - A'*X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__2.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__2.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__1.r = b[i__3].r - q__2.r, q__1.i = b[i__3].i - q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; i__4 = j * x_dim1 + 1; q__3.r = d__[1].r * x[i__4].r - d__[1].i * x[i__4].i, q__3.i = d__[1].r * x[i__4].i + d__[1].i * x[i__4] .r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; i__5 = j * x_dim1 + 2; q__4.r = dl[1].r * x[i__5].r - dl[1].i * x[i__5].i, q__4.i = dl[1].r * x[i__5].i + dl[1].i * x[i__5] .r; q__1.r = q__2.r - q__4.r, q__1.i = q__2.i - q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; i__4 = *n - 1; i__5 = *n - 1 + j * x_dim1; q__3.r = du[i__4].r * x[i__5].r - du[i__4].i * x[i__5].i, q__3.i = du[i__4].r * x[i__5].i + du[i__4].i * x[ i__5].r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; i__6 = *n; i__7 = *n + j * x_dim1; q__4.r = d__[i__6].r * x[i__7].r - d__[i__6].i * x[i__7] .i, q__4.i = d__[i__6].r * x[i__7].i + d__[i__6] .i * x[i__7].r; q__1.r = q__2.r - q__4.r, q__1.i = q__2.i - q__4.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; i__5 = i__ - 1; i__6 = i__ - 1 + j * x_dim1; q__4.r = du[i__5].r * x[i__6].r - du[i__5].i * x[i__6] .i, q__4.i = du[i__5].r * x[i__6].i + du[i__5] .i * x[i__6].r; q__3.r = b[i__4].r - q__4.r, q__3.i = b[i__4].i - q__4.i; i__7 = i__; i__8 = i__ + j * x_dim1; q__5.r = d__[i__7].r * x[i__8].r - d__[i__7].i * x[ i__8].i, q__5.i = d__[i__7].r * x[i__8].i + d__[i__7].i * x[i__8].r; q__2.r = q__3.r - q__5.r, q__2.i = q__3.i - q__5.i; i__9 = i__; i__10 = i__ + 1 + j * x_dim1; q__6.r = dl[i__9].r * x[i__10].r - dl[i__9].i * x[ i__10].i, q__6.i = dl[i__9].r * x[i__10].i + dl[i__9].i * x[i__10].r; q__1.r = q__2.r - q__6.r, q__1.i = q__2.i - q__6.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L130: */ } } /* L140: */ } } else if (lsame_(trans, "C")) { /* Compute B := B - A'*X */ i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { if (*n == 1) { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; r_cnjg(&q__3, &d__[1]); i__4 = j * x_dim1 + 1; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[i__4].r; q__1.r = b[i__3].r - q__2.r, q__1.i = b[i__3].i - q__2.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; } else { i__2 = j * b_dim1 + 1; i__3 = j * b_dim1 + 1; r_cnjg(&q__4, &d__[1]); i__4 = j * x_dim1 + 1; q__3.r = q__4.r * x[i__4].r - q__4.i * x[i__4].i, q__3.i = q__4.r * x[i__4].i + q__4.i * x[i__4].r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; r_cnjg(&q__6, &dl[1]); i__5 = j * x_dim1 + 2; q__5.r = q__6.r * x[i__5].r - q__6.i * x[i__5].i, q__5.i = q__6.r * x[i__5].i + q__6.i * x[i__5].r; q__1.r = q__2.r - q__5.r, q__1.i = q__2.i - q__5.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n + j * b_dim1; i__3 = *n + j * b_dim1; r_cnjg(&q__4, &du[*n - 1]); i__4 = *n - 1 + j * x_dim1; q__3.r = q__4.r * x[i__4].r - q__4.i * x[i__4].i, q__3.i = q__4.r * x[i__4].i + q__4.i * x[i__4].r; q__2.r = b[i__3].r - q__3.r, q__2.i = b[i__3].i - q__3.i; r_cnjg(&q__6, &d__[*n]); i__5 = *n + j * x_dim1; q__5.r = q__6.r * x[i__5].r - q__6.i * x[i__5].i, q__5.i = q__6.r * x[i__5].i + q__6.i * x[i__5].r; q__1.r = q__2.r - q__5.r, q__1.i = q__2.i - q__5.i; b[i__2].r = q__1.r, b[i__2].i = q__1.i; i__2 = *n - 1; for (i__ = 2; i__ <= i__2; ++i__) { i__3 = i__ + j * b_dim1; i__4 = i__ + j * b_dim1; r_cnjg(&q__5, &du[i__ - 1]); i__5 = i__ - 1 + j * x_dim1; q__4.r = q__5.r * x[i__5].r - q__5.i * x[i__5].i, q__4.i = q__5.r * x[i__5].i + q__5.i * x[i__5] .r; q__3.r = b[i__4].r - q__4.r, q__3.i = b[i__4].i - q__4.i; r_cnjg(&q__7, &d__[i__]); i__6 = i__ + j * x_dim1; q__6.r = q__7.r * x[i__6].r - q__7.i * x[i__6].i, q__6.i = q__7.r * x[i__6].i + q__7.i * x[i__6] .r; q__2.r = q__3.r - q__6.r, q__2.i = q__3.i - q__6.i; r_cnjg(&q__9, &dl[i__]); i__7 = i__ + 1 + j * x_dim1; q__8.r = q__9.r * x[i__7].r - q__9.i * x[i__7].i, q__8.i = q__9.r * x[i__7].i + q__9.i * x[i__7] .r; q__1.r = q__2.r - q__8.r, q__1.i = q__2.i - q__8.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L150: */ } } /* L160: */ } } } return 0; /* End of CLAGTM */ } /* clagtm_ */
/** CHETRF_ROOK_REC2 computes a partial factorization of a complex Hermitian indefinite matrix using the boun ded Bunch-Kaufman ("rook") diagonal pivoting method * * This routine is a minor modification of LAPACK's clahef_rook. * It serves as an unblocked kernel in the recursive algorithms. * The blocked BLAS Level 3 updates were removed and moved to the * recursive algorithm. * */ /* Subroutine */ void RELAPACK_chetrf_rook_rec2(char *uplo, int *n, int *nb, int *kb, complex *a, int *lda, int *ipiv, complex *w, int *ldw, int *info, ftnlen uplo_len) { /* System generated locals */ int a_dim1, a_offset, w_dim1, w_offset, i__1, i__2, i__3, i__4; float r__1, r__2; complex q__1, q__2, q__3, q__4, q__5; /* Builtin functions */ double sqrt(double), r_imag(complex *); void r_cnjg(complex *, complex *), c_div(complex *, complex *, complex *); /* Local variables */ static int j, k, p; static float t, r1; static complex d11, d21, d22; static int ii, jj, kk, kp, kw, jp1, jp2, kkw; static logical done; static int imax, jmax; static float alpha; extern logical lsame_(char *, char *, ftnlen, ftnlen); extern /* Subroutine */ int cgemv_(char *, int *, int *, complex * , complex *, int *, complex *, int *, complex *, complex * , int *, ftnlen); static float sfmin; extern /* Subroutine */ int ccopy_(int *, complex *, int *, complex *, int *); static int itemp; extern /* Subroutine */ int cswap_(int *, complex *, int *, complex *, int *); static int kstep; static float stemp, absakk; extern /* Subroutine */ int clacgv_(int *, complex *, int *); extern int icamax_(int *, complex *, int *); extern double slamch_(char *, ftnlen); extern /* Subroutine */ int csscal_(int *, float *, complex *, int *); static float colmax, rowmax; /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --ipiv; w_dim1 = *ldw; w_offset = 1 + w_dim1; w -= w_offset; /* Function Body */ *info = 0; alpha = (sqrt(17.f) + 1.f) / 8.f; sfmin = slamch_("S", (ftnlen)1); if (lsame_(uplo, "U", (ftnlen)1, (ftnlen)1)) { k = *n; L10: kw = *nb + k - *n; if ((k <= *n - *nb + 1 && *nb < *n) || k < 1) { goto L30; } kstep = 1; p = k; if (k > 1) { i__1 = k - 1; ccopy_(&i__1, &a[k * a_dim1 + 1], &c__1, &w[kw * w_dim1 + 1], & c__1); } i__1 = k + kw * w_dim1; i__2 = k + k * a_dim1; r__1 = a[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; if (k < *n) { i__1 = *n - k; q__1.r = -1.f, q__1.i = -0.f; cgemv_("No transpose", &k, &i__1, &q__1, &a[(k + 1) * a_dim1 + 1], lda, &w[k + (kw + 1) * w_dim1], ldw, &c_b1, &w[kw * w_dim1 + 1], &c__1, (ftnlen)12); i__1 = k + kw * w_dim1; i__2 = k + kw * w_dim1; r__1 = w[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; } i__1 = k + kw * w_dim1; absakk = (r__1 = w[i__1].r, dabs(r__1)); if (k > 1) { i__1 = k - 1; imax = icamax_(&i__1, &w[kw * w_dim1 + 1], &c__1); i__1 = imax + kw * w_dim1; colmax = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(&w[imax + kw * w_dim1]), dabs(r__2)); } else { colmax = 0.f; } if (dmax(absakk,colmax) == 0.f) { if (*info == 0) { *info = k; } kp = k; i__1 = k + k * a_dim1; i__2 = k + kw * w_dim1; r__1 = w[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; if (k > 1) { i__1 = k - 1; ccopy_(&i__1, &w[kw * w_dim1 + 1], &c__1, &a[k * a_dim1 + 1], &c__1); } } else { if (! (absakk < alpha * colmax)) { kp = k; } else { done = FALSE_; L12: if (imax > 1) { i__1 = imax - 1; ccopy_(&i__1, &a[imax * a_dim1 + 1], &c__1, &w[(kw - 1) * w_dim1 + 1], &c__1); } i__1 = imax + (kw - 1) * w_dim1; i__2 = imax + imax * a_dim1; r__1 = a[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; i__1 = k - imax; ccopy_(&i__1, &a[imax + (imax + 1) * a_dim1], lda, &w[imax + 1 + (kw - 1) * w_dim1], &c__1); i__1 = k - imax; clacgv_(&i__1, &w[imax + 1 + (kw - 1) * w_dim1], &c__1); if (k < *n) { i__1 = *n - k; q__1.r = -1.f, q__1.i = -0.f; cgemv_("No transpose", &k, &i__1, &q__1, &a[(k + 1) * a_dim1 + 1], lda, &w[imax + (kw + 1) * w_dim1], ldw, &c_b1, &w[(kw - 1) * w_dim1 + 1], &c__1, ( ftnlen)12); i__1 = imax + (kw - 1) * w_dim1; i__2 = imax + (kw - 1) * w_dim1; r__1 = w[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; } if (imax != k) { i__1 = k - imax; jmax = imax + icamax_(&i__1, &w[imax + 1 + (kw - 1) * w_dim1], &c__1); i__1 = jmax + (kw - 1) * w_dim1; rowmax = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(& w[jmax + (kw - 1) * w_dim1]), dabs(r__2)); } else { rowmax = 0.f; } if (imax > 1) { i__1 = imax - 1; itemp = icamax_(&i__1, &w[(kw - 1) * w_dim1 + 1], &c__1); i__1 = itemp + (kw - 1) * w_dim1; stemp = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(& w[itemp + (kw - 1) * w_dim1]), dabs(r__2)); if (stemp > rowmax) { rowmax = stemp; jmax = itemp; } } i__1 = imax + (kw - 1) * w_dim1; if (! ((r__1 = w[i__1].r, dabs(r__1)) < alpha * rowmax)) { kp = imax; ccopy_(&k, &w[(kw - 1) * w_dim1 + 1], &c__1, &w[kw * w_dim1 + 1], &c__1); done = TRUE_; } else if (p == jmax || rowmax <= colmax) { kp = imax; kstep = 2; done = TRUE_; } else { p = imax; colmax = rowmax; imax = jmax; ccopy_(&k, &w[(kw - 1) * w_dim1 + 1], &c__1, &w[kw * w_dim1 + 1], &c__1); } if (! done) { goto L12; } } kk = k - kstep + 1; kkw = *nb + kk - *n; if (kstep == 2 && p != k) { i__1 = p + p * a_dim1; i__2 = k + k * a_dim1; r__1 = a[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; i__1 = k - 1 - p; ccopy_(&i__1, &a[p + 1 + k * a_dim1], &c__1, &a[p + (p + 1) * a_dim1], lda); i__1 = k - 1 - p; clacgv_(&i__1, &a[p + (p + 1) * a_dim1], lda); if (p > 1) { i__1 = p - 1; ccopy_(&i__1, &a[k * a_dim1 + 1], &c__1, &a[p * a_dim1 + 1], &c__1); } if (k < *n) { i__1 = *n - k; cswap_(&i__1, &a[k + (k + 1) * a_dim1], lda, &a[p + (k + 1) * a_dim1], lda); } i__1 = *n - kk + 1; cswap_(&i__1, &w[k + kkw * w_dim1], ldw, &w[p + kkw * w_dim1], ldw); } if (kp != kk) { i__1 = kp + kp * a_dim1; i__2 = kk + kk * a_dim1; r__1 = a[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; i__1 = kk - 1 - kp; ccopy_(&i__1, &a[kp + 1 + kk * a_dim1], &c__1, &a[kp + (kp + 1) * a_dim1], lda); i__1 = kk - 1 - kp; clacgv_(&i__1, &a[kp + (kp + 1) * a_dim1], lda); if (kp > 1) { i__1 = kp - 1; ccopy_(&i__1, &a[kk * a_dim1 + 1], &c__1, &a[kp * a_dim1 + 1], &c__1); } if (k < *n) { i__1 = *n - k; cswap_(&i__1, &a[kk + (k + 1) * a_dim1], lda, &a[kp + (k + 1) * a_dim1], lda); } i__1 = *n - kk + 1; cswap_(&i__1, &w[kk + kkw * w_dim1], ldw, &w[kp + kkw * w_dim1], ldw); } if (kstep == 1) { ccopy_(&k, &w[kw * w_dim1 + 1], &c__1, &a[k * a_dim1 + 1], & c__1); if (k > 1) { i__1 = k + k * a_dim1; t = a[i__1].r; if (dabs(t) >= sfmin) { r1 = 1.f / t; i__1 = k - 1; csscal_(&i__1, &r1, &a[k * a_dim1 + 1], &c__1); } else { i__1 = k - 1; for (ii = 1; ii <= i__1; ++ii) { i__2 = ii + k * a_dim1; i__3 = ii + k * a_dim1; q__1.r = a[i__3].r / t, q__1.i = a[i__3].i / t; a[i__2].r = q__1.r, a[i__2].i = q__1.i; /* L14: */ } } i__1 = k - 1; clacgv_(&i__1, &w[kw * w_dim1 + 1], &c__1); } } else { if (k > 2) { i__1 = k - 1 + kw * w_dim1; d21.r = w[i__1].r, d21.i = w[i__1].i; r_cnjg(&q__2, &d21); c_div(&q__1, &w[k + kw * w_dim1], &q__2); d11.r = q__1.r, d11.i = q__1.i; c_div(&q__1, &w[k - 1 + (kw - 1) * w_dim1], &d21); d22.r = q__1.r, d22.i = q__1.i; q__1.r = d11.r * d22.r - d11.i * d22.i, q__1.i = d11.r * d22.i + d11.i * d22.r; t = 1.f / (q__1.r - 1.f); i__1 = k - 2; for (j = 1; j <= i__1; ++j) { i__2 = j + (k - 1) * a_dim1; i__3 = j + (kw - 1) * w_dim1; q__4.r = d11.r * w[i__3].r - d11.i * w[i__3].i, q__4.i = d11.r * w[i__3].i + d11.i * w[i__3] .r; i__4 = j + kw * w_dim1; q__3.r = q__4.r - w[i__4].r, q__3.i = q__4.i - w[i__4] .i; c_div(&q__2, &q__3, &d21); q__1.r = t * q__2.r, q__1.i = t * q__2.i; a[i__2].r = q__1.r, a[i__2].i = q__1.i; i__2 = j + k * a_dim1; i__3 = j + kw * w_dim1; q__4.r = d22.r * w[i__3].r - d22.i * w[i__3].i, q__4.i = d22.r * w[i__3].i + d22.i * w[i__3] .r; i__4 = j + (kw - 1) * w_dim1; q__3.r = q__4.r - w[i__4].r, q__3.i = q__4.i - w[i__4] .i; r_cnjg(&q__5, &d21); c_div(&q__2, &q__3, &q__5); q__1.r = t * q__2.r, q__1.i = t * q__2.i; a[i__2].r = q__1.r, a[i__2].i = q__1.i; /* L20: */ } } i__1 = k - 1 + (k - 1) * a_dim1; i__2 = k - 1 + (kw - 1) * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = k - 1 + k * a_dim1; i__2 = k - 1 + kw * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = k + k * a_dim1; i__2 = k + kw * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = k - 1; clacgv_(&i__1, &w[kw * w_dim1 + 1], &c__1); i__1 = k - 2; clacgv_(&i__1, &w[(kw - 1) * w_dim1 + 1], &c__1); } } if (kstep == 1) { ipiv[k] = kp; } else { ipiv[k] = -p; ipiv[k - 1] = -kp; } k -= kstep; goto L10; L30: j = k + 1; L60: kstep = 1; jp1 = 1; jj = j; jp2 = ipiv[j]; if (jp2 < 0) { jp2 = -jp2; ++j; jp1 = -ipiv[j]; kstep = 2; } ++j; if (jp2 != jj && j <= *n) { i__1 = *n - j + 1; cswap_(&i__1, &a[jp2 + j * a_dim1], lda, &a[jj + j * a_dim1], lda) ; } ++jj; if (kstep == 2 && jp1 != jj && j <= *n) { i__1 = *n - j + 1; cswap_(&i__1, &a[jp1 + j * a_dim1], lda, &a[jj + j * a_dim1], lda) ; } if (j < *n) { goto L60; } *kb = *n - k; } else { k = 1; L70: if ((k >= *nb && *nb < *n) || k > *n) { goto L90; } kstep = 1; p = k; i__1 = k + k * w_dim1; i__2 = k + k * a_dim1; r__1 = a[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; if (k < *n) { i__1 = *n - k; ccopy_(&i__1, &a[k + 1 + k * a_dim1], &c__1, &w[k + 1 + k * w_dim1], &c__1); } if (k > 1) { i__1 = *n - k + 1; i__2 = k - 1; q__1.r = -1.f, q__1.i = -0.f; cgemv_("No transpose", &i__1, &i__2, &q__1, &a[k + a_dim1], lda, & w[k + w_dim1], ldw, &c_b1, &w[k + k * w_dim1], &c__1, ( ftnlen)12); i__1 = k + k * w_dim1; i__2 = k + k * w_dim1; r__1 = w[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; } i__1 = k + k * w_dim1; absakk = (r__1 = w[i__1].r, dabs(r__1)); if (k < *n) { i__1 = *n - k; imax = k + icamax_(&i__1, &w[k + 1 + k * w_dim1], &c__1); i__1 = imax + k * w_dim1; colmax = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(&w[imax + k * w_dim1]), dabs(r__2)); } else { colmax = 0.f; } if (dmax(absakk,colmax) == 0.f) { if (*info == 0) { *info = k; } kp = k; i__1 = k + k * a_dim1; i__2 = k + k * w_dim1; r__1 = w[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; if (k < *n) { i__1 = *n - k; ccopy_(&i__1, &w[k + 1 + k * w_dim1], &c__1, &a[k + 1 + k * a_dim1], &c__1); } } else { if (! (absakk < alpha * colmax)) { kp = k; } else { done = FALSE_; L72: i__1 = imax - k; ccopy_(&i__1, &a[imax + k * a_dim1], lda, &w[k + (k + 1) * w_dim1], &c__1); i__1 = imax - k; clacgv_(&i__1, &w[k + (k + 1) * w_dim1], &c__1); i__1 = imax + (k + 1) * w_dim1; i__2 = imax + imax * a_dim1; r__1 = a[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; if (imax < *n) { i__1 = *n - imax; ccopy_(&i__1, &a[imax + 1 + imax * a_dim1], &c__1, &w[ imax + 1 + (k + 1) * w_dim1], &c__1); } if (k > 1) { i__1 = *n - k + 1; i__2 = k - 1; q__1.r = -1.f, q__1.i = -0.f; cgemv_("No transpose", &i__1, &i__2, &q__1, &a[k + a_dim1] , lda, &w[imax + w_dim1], ldw, &c_b1, &w[k + (k + 1) * w_dim1], &c__1, (ftnlen)12); i__1 = imax + (k + 1) * w_dim1; i__2 = imax + (k + 1) * w_dim1; r__1 = w[i__2].r; w[i__1].r = r__1, w[i__1].i = 0.f; } if (imax != k) { i__1 = imax - k; jmax = k - 1 + icamax_(&i__1, &w[k + (k + 1) * w_dim1], & c__1); i__1 = jmax + (k + 1) * w_dim1; rowmax = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(& w[jmax + (k + 1) * w_dim1]), dabs(r__2)); } else { rowmax = 0.f; } if (imax < *n) { i__1 = *n - imax; itemp = imax + icamax_(&i__1, &w[imax + 1 + (k + 1) * w_dim1], &c__1); i__1 = itemp + (k + 1) * w_dim1; stemp = (r__1 = w[i__1].r, dabs(r__1)) + (r__2 = r_imag(& w[itemp + (k + 1) * w_dim1]), dabs(r__2)); if (stemp > rowmax) { rowmax = stemp; jmax = itemp; } } i__1 = imax + (k + 1) * w_dim1; if (! ((r__1 = w[i__1].r, dabs(r__1)) < alpha * rowmax)) { kp = imax; i__1 = *n - k + 1; ccopy_(&i__1, &w[k + (k + 1) * w_dim1], &c__1, &w[k + k * w_dim1], &c__1); done = TRUE_; } else if (p == jmax || rowmax <= colmax) { kp = imax; kstep = 2; done = TRUE_; } else { p = imax; colmax = rowmax; imax = jmax; i__1 = *n - k + 1; ccopy_(&i__1, &w[k + (k + 1) * w_dim1], &c__1, &w[k + k * w_dim1], &c__1); } if (! done) { goto L72; } } kk = k + kstep - 1; if (kstep == 2 && p != k) { i__1 = p + p * a_dim1; i__2 = k + k * a_dim1; r__1 = a[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; i__1 = p - k - 1; ccopy_(&i__1, &a[k + 1 + k * a_dim1], &c__1, &a[p + (k + 1) * a_dim1], lda); i__1 = p - k - 1; clacgv_(&i__1, &a[p + (k + 1) * a_dim1], lda); if (p < *n) { i__1 = *n - p; ccopy_(&i__1, &a[p + 1 + k * a_dim1], &c__1, &a[p + 1 + p * a_dim1], &c__1); } if (k > 1) { i__1 = k - 1; cswap_(&i__1, &a[k + a_dim1], lda, &a[p + a_dim1], lda); } cswap_(&kk, &w[k + w_dim1], ldw, &w[p + w_dim1], ldw); } if (kp != kk) { i__1 = kp + kp * a_dim1; i__2 = kk + kk * a_dim1; r__1 = a[i__2].r; a[i__1].r = r__1, a[i__1].i = 0.f; i__1 = kp - kk - 1; ccopy_(&i__1, &a[kk + 1 + kk * a_dim1], &c__1, &a[kp + (kk + 1) * a_dim1], lda); i__1 = kp - kk - 1; clacgv_(&i__1, &a[kp + (kk + 1) * a_dim1], lda); if (kp < *n) { i__1 = *n - kp; ccopy_(&i__1, &a[kp + 1 + kk * a_dim1], &c__1, &a[kp + 1 + kp * a_dim1], &c__1); } if (k > 1) { i__1 = k - 1; cswap_(&i__1, &a[kk + a_dim1], lda, &a[kp + a_dim1], lda); } cswap_(&kk, &w[kk + w_dim1], ldw, &w[kp + w_dim1], ldw); } if (kstep == 1) { i__1 = *n - k + 1; ccopy_(&i__1, &w[k + k * w_dim1], &c__1, &a[k + k * a_dim1], & c__1); if (k < *n) { i__1 = k + k * a_dim1; t = a[i__1].r; if (dabs(t) >= sfmin) { r1 = 1.f / t; i__1 = *n - k; csscal_(&i__1, &r1, &a[k + 1 + k * a_dim1], &c__1); } else { i__1 = *n; for (ii = k + 1; ii <= i__1; ++ii) { i__2 = ii + k * a_dim1; i__3 = ii + k * a_dim1; q__1.r = a[i__3].r / t, q__1.i = a[i__3].i / t; a[i__2].r = q__1.r, a[i__2].i = q__1.i; /* L74: */ } } i__1 = *n - k; clacgv_(&i__1, &w[k + 1 + k * w_dim1], &c__1); } } else { if (k < *n - 1) { i__1 = k + 1 + k * w_dim1; d21.r = w[i__1].r, d21.i = w[i__1].i; c_div(&q__1, &w[k + 1 + (k + 1) * w_dim1], &d21); d11.r = q__1.r, d11.i = q__1.i; r_cnjg(&q__2, &d21); c_div(&q__1, &w[k + k * w_dim1], &q__2); d22.r = q__1.r, d22.i = q__1.i; q__1.r = d11.r * d22.r - d11.i * d22.i, q__1.i = d11.r * d22.i + d11.i * d22.r; t = 1.f / (q__1.r - 1.f); i__1 = *n; for (j = k + 2; j <= i__1; ++j) { i__2 = j + k * a_dim1; i__3 = j + k * w_dim1; q__4.r = d11.r * w[i__3].r - d11.i * w[i__3].i, q__4.i = d11.r * w[i__3].i + d11.i * w[i__3] .r; i__4 = j + (k + 1) * w_dim1; q__3.r = q__4.r - w[i__4].r, q__3.i = q__4.i - w[i__4] .i; r_cnjg(&q__5, &d21); c_div(&q__2, &q__3, &q__5); q__1.r = t * q__2.r, q__1.i = t * q__2.i; a[i__2].r = q__1.r, a[i__2].i = q__1.i; i__2 = j + (k + 1) * a_dim1; i__3 = j + (k + 1) * w_dim1; q__4.r = d22.r * w[i__3].r - d22.i * w[i__3].i, q__4.i = d22.r * w[i__3].i + d22.i * w[i__3] .r; i__4 = j + k * w_dim1; q__3.r = q__4.r - w[i__4].r, q__3.i = q__4.i - w[i__4] .i; c_div(&q__2, &q__3, &d21); q__1.r = t * q__2.r, q__1.i = t * q__2.i; a[i__2].r = q__1.r, a[i__2].i = q__1.i; /* L80: */ } } i__1 = k + k * a_dim1; i__2 = k + k * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = k + 1 + k * a_dim1; i__2 = k + 1 + k * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = k + 1 + (k + 1) * a_dim1; i__2 = k + 1 + (k + 1) * w_dim1; a[i__1].r = w[i__2].r, a[i__1].i = w[i__2].i; i__1 = *n - k; clacgv_(&i__1, &w[k + 1 + k * w_dim1], &c__1); i__1 = *n - k - 1; clacgv_(&i__1, &w[k + 2 + (k + 1) * w_dim1], &c__1); } } if (kstep == 1) { ipiv[k] = kp; } else { ipiv[k] = -p; ipiv[k + 1] = -kp; } k += kstep; goto L70; L90: j = k - 1; L120: kstep = 1; jp1 = 1; jj = j; jp2 = ipiv[j]; if (jp2 < 0) { jp2 = -jp2; --j; jp1 = -ipiv[j]; kstep = 2; } --j; if (jp2 != jj && j >= 1) { cswap_(&j, &a[jp2 + a_dim1], lda, &a[jj + a_dim1], lda); } --jj; if (kstep == 2 && jp1 != jj && j >= 1) { cswap_(&j, &a[jp1 + a_dim1], lda, &a[jj + a_dim1], lda); } if (j > 1) { goto L120; } *kb = k - 1; } return; }
/* Subroutine */ int chseqr_(char *job, char *compz, integer *n, integer *ilo, integer *ihi, complex *h__, integer *ldh, complex *w, complex *z__, integer *ldz, complex *work, integer *lwork, integer *info) { /* System generated locals */ address a__1[2]; integer h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4[2], i__5, i__6; real r__1, r__2, r__3, r__4; complex q__1; char ch__1[2]; /* Builtin functions */ double r_imag(complex *); void r_cnjg(complex *, complex *); /* Subroutine */ int s_cat(char *, char **, integer *, integer *, ftnlen); /* Local variables */ static integer maxb, ierr; static real unfl; static complex temp; static real ovfl, opst; static integer i__, j, k, l; static complex s[225] /* was [15][15] */; extern /* Subroutine */ int cscal_(integer *, complex *, complex *, integer *); static complex v[16]; extern logical lsame_(char *, char *); extern /* Subroutine */ int cgemv_(char *, integer *, integer *, complex * , complex *, integer *, complex *, integer *, complex *, complex * , integer *), ccopy_(integer *, complex *, integer *, complex *, integer *); static integer itemp; static real rtemp; static integer i1, i2; static logical initz, wantt, wantz; static real rwork[1]; extern doublereal slapy2_(real *, real *); static integer ii, nh; extern /* Subroutine */ int slabad_(real *, real *), clarfg_(integer *, complex *, complex *, integer *, complex *); static integer nr, ns; extern integer icamax_(integer *, complex *, integer *); static integer nv; extern doublereal slamch_(char *), clanhs_(char *, integer *, complex *, integer *, real *); extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer *), clahqr_(logical *, logical *, integer *, integer *, integer *, complex *, integer *, complex *, integer *, integer *, complex *, integer *, integer *), clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *); static complex vv[16]; extern /* Subroutine */ int claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *); extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *, ftnlen, ftnlen); extern /* Subroutine */ int clarfx_(char *, integer *, integer *, complex *, complex *, complex *, integer *, complex *), xerbla_( char *, integer *); static real smlnum; static logical lquery; static integer itn; static complex tau; static integer its; static real ulp, tst1; #define h___subscr(a_1,a_2) (a_2)*h_dim1 + a_1 #define h___ref(a_1,a_2) h__[h___subscr(a_1,a_2)] #define s_subscr(a_1,a_2) (a_2)*15 + a_1 - 16 #define s_ref(a_1,a_2) s[s_subscr(a_1,a_2)] #define z___subscr(a_1,a_2) (a_2)*z_dim1 + a_1 #define z___ref(a_1,a_2) z__[z___subscr(a_1,a_2)] /* -- LAPACK routine (instrumented to count operations, version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Common block to return operation count. Purpose ======= CHSEQR computes the eigenvalues of a complex upper Hessenberg matrix H, and, optionally, the matrices T and Z from the Schur decomposition H = Z T Z**H, where T is an upper triangular matrix (the Schur form), and Z is the unitary matrix of Schur vectors. Optionally Z may be postmultiplied into an input unitary matrix Q, so that this routine can give the Schur factorization of a matrix A which has been reduced to the Hessenberg form H by the unitary matrix Q: A = Q*H*Q**H = (QZ)*T*(QZ)**H. Arguments ========= JOB (input) CHARACTER*1 = 'E': compute eigenvalues only; = 'S': compute eigenvalues and the Schur form T. COMPZ (input) CHARACTER*1 = 'N': no Schur vectors are computed; = 'I': Z is initialized to the unit matrix and the matrix Z of Schur vectors of H is returned; = 'V': Z must contain an unitary matrix Q on entry, and the product Q*Z is returned. N (input) INTEGER The order of the matrix H. N >= 0. ILO (input) INTEGER IHI (input) INTEGER It is assumed that H is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to CGEBAL, and then passed to CGEHRD when the matrix output by CGEBAL is reduced to Hessenberg form. Otherwise ILO and IHI should be set to 1 and N respectively. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. H (input/output) COMPLEX array, dimension (LDH,N) On entry, the upper Hessenberg matrix H. On exit, if JOB = 'S', H contains the upper triangular matrix T from the Schur decomposition (the Schur form). If JOB = 'E', the contents of H are unspecified on exit. LDH (input) INTEGER The leading dimension of the array H. LDH >= max(1,N). W (output) COMPLEX array, dimension (N) The computed eigenvalues. If JOB = 'S', the eigenvalues are stored in the same order as on the diagonal of the Schur form returned in H, with W(i) = H(i,i). Z (input/output) COMPLEX array, dimension (LDZ,N) If COMPZ = 'N': Z is not referenced. If COMPZ = 'I': on entry, Z need not be set, and on exit, Z contains the unitary matrix Z of the Schur vectors of H. If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q, which is assumed to be equal to the unit matrix except for the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z. Normally Q is the unitary matrix generated by CUNGHR after the call to CGEHRD which formed the Hessenberg matrix H. LDZ (input) INTEGER The leading dimension of the array Z. LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise. WORK (workspace/output) COMPLEX array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) INTEGER The dimension of the array WORK. LWORK >= max(1,N). If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, CHSEQR failed to compute all the eigenvalues in a total of 30*(IHI-ILO+1) iterations; elements 1:ilo-1 and i+1:n of W contain those eigenvalues which have been successfully computed. ===================================================================== Decode and test the input parameters Parameter adjustments */ h_dim1 = *ldh; h_offset = 1 + h_dim1 * 1; h__ -= h_offset; --w; z_dim1 = *ldz; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; --work; /* Function Body */ wantt = lsame_(job, "S"); initz = lsame_(compz, "I"); wantz = initz || lsame_(compz, "V"); *info = 0; i__1 = max(1,*n); work[1].r = (real) i__1, work[1].i = 0.f; lquery = *lwork == -1; if (! lsame_(job, "E") && ! wantt) { *info = -1; } else if (! lsame_(compz, "N") && ! wantz) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*ilo < 1 || *ilo > max(1,*n)) { *info = -4; } else if (*ihi < min(*ilo,*n) || *ihi > *n) { *info = -5; } else if (*ldh < max(1,*n)) { *info = -7; } else if (*ldz < 1 || wantz && *ldz < max(1,*n)) { *info = -10; } else if (*lwork < max(1,*n) && ! lquery) { *info = -12; } if (*info != 0) { i__1 = -(*info); xerbla_("CHSEQR", &i__1); return 0; } else if (lquery) { return 0; } /* ** Initialize */ opst = 0.f; /* ** Initialize Z, if necessary */ if (initz) { claset_("Full", n, n, &c_b1, &c_b2, &z__[z_offset], ldz); } /* Store the eigenvalues isolated by CGEBAL. */ i__1 = *ilo - 1; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = h___subscr(i__, i__); w[i__2].r = h__[i__3].r, w[i__2].i = h__[i__3].i; /* L10: */ } i__1 = *n; for (i__ = *ihi + 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = h___subscr(i__, i__); w[i__2].r = h__[i__3].r, w[i__2].i = h__[i__3].i; /* L20: */ } /* Quick return if possible. */ if (*n == 0) { return 0; } if (*ilo == *ihi) { i__1 = *ilo; i__2 = h___subscr(*ilo, *ilo); w[i__1].r = h__[i__2].r, w[i__1].i = h__[i__2].i; return 0; } /* Set rows and columns ILO to IHI to zero below the first subdiagonal. */ i__1 = *ihi - 2; for (j = *ilo; j <= i__1; ++j) { i__2 = *n; for (i__ = j + 2; i__ <= i__2; ++i__) { i__3 = h___subscr(i__, j); h__[i__3].r = 0.f, h__[i__3].i = 0.f; /* L30: */ } /* L40: */ } nh = *ihi - *ilo + 1; /* I1 and I2 are the indices of the first row and last column of H to which transformations must be applied. If eigenvalues only are being computed, I1 and I2 are re-set inside the main loop. */ if (wantt) { i1 = 1; i2 = *n; } else { i1 = *ilo; i2 = *ihi; } /* Ensure that the subdiagonal elements are real. */ i__1 = *ihi; for (i__ = *ilo + 1; i__ <= i__1; ++i__) { i__2 = h___subscr(i__, i__ - 1); temp.r = h__[i__2].r, temp.i = h__[i__2].i; if (r_imag(&temp) != 0.f) { r__1 = temp.r; r__2 = r_imag(&temp); rtemp = slapy2_(&r__1, &r__2); i__2 = h___subscr(i__, i__ - 1); h__[i__2].r = rtemp, h__[i__2].i = 0.f; q__1.r = temp.r / rtemp, q__1.i = temp.i / rtemp; temp.r = q__1.r, temp.i = q__1.i; if (i2 > i__) { i__2 = i2 - i__; r_cnjg(&q__1, &temp); cscal_(&i__2, &q__1, &h___ref(i__, i__ + 1), ldh); } i__2 = i__ - i1; cscal_(&i__2, &temp, &h___ref(i1, i__), &c__1); if (i__ < *ihi) { i__2 = h___subscr(i__ + 1, i__); i__3 = h___subscr(i__ + 1, i__); q__1.r = temp.r * h__[i__3].r - temp.i * h__[i__3].i, q__1.i = temp.r * h__[i__3].i + temp.i * h__[i__3].r; h__[i__2].r = q__1.r, h__[i__2].i = q__1.i; } /* ** Increment op count */ opst += (i2 - i1 + 2) * 6; /* ** */ if (wantz) { cscal_(&nh, &temp, &z___ref(*ilo, i__), &c__1); /* ** Increment op count */ opst += nh * 6; /* ** */ } } /* L50: */ } /* Determine the order of the multi-shift QR algorithm to be used. Writing concatenation */ i__4[0] = 1, a__1[0] = job; i__4[1] = 1, a__1[1] = compz; s_cat(ch__1, a__1, i__4, &c__2, (ftnlen)2); ns = ilaenv_(&c__4, "CHSEQR", ch__1, n, ilo, ihi, &c_n1, (ftnlen)6, ( ftnlen)2); /* Writing concatenation */ i__4[0] = 1, a__1[0] = job; i__4[1] = 1, a__1[1] = compz; s_cat(ch__1, a__1, i__4, &c__2, (ftnlen)2); maxb = ilaenv_(&c__8, "CHSEQR", ch__1, n, ilo, ihi, &c_n1, (ftnlen)6, ( ftnlen)2); if (ns <= 1 || ns > nh || maxb >= nh) { /* Use the standard double-shift algorithm */ clahqr_(&wantt, &wantz, n, ilo, ihi, &h__[h_offset], ldh, &w[1], ilo, ihi, &z__[z_offset], ldz, info); return 0; } maxb = max(2,maxb); /* Computing MIN */ i__1 = min(ns,maxb); ns = min(i__1,15); /* Now 1 < NS <= MAXB < NH. Set machine-dependent constants for the stopping criterion. If norm(H) <= sqrt(OVFL), overflow should not occur. */ unfl = slamch_("Safe minimum"); ovfl = 1.f / unfl; slabad_(&unfl, &ovfl); ulp = slamch_("Precision"); smlnum = unfl * (nh / ulp); /* ITN is the total number of multiple-shift QR iterations allowed. */ itn = nh * 30; /* The main loop begins here. I is the loop index and decreases from IHI to ILO in steps of at most MAXB. Each iteration of the loop works with the active submatrix in rows and columns L to I. Eigenvalues I+1 to IHI have already converged. Either L = ILO, or H(L,L-1) is negligible so that the matrix splits. */ i__ = *ihi; L60: if (i__ < *ilo) { goto L180; } /* Perform multiple-shift QR iterations on rows and columns ILO to I until a submatrix of order at most MAXB splits off at the bottom because a subdiagonal element has become negligible. */ l = *ilo; i__1 = itn; for (its = 0; its <= i__1; ++its) { /* Look for a single small subdiagonal element. */ i__2 = l + 1; for (k = i__; k >= i__2; --k) { i__3 = h___subscr(k - 1, k - 1); i__5 = h___subscr(k, k); tst1 = (r__1 = h__[i__3].r, dabs(r__1)) + (r__2 = r_imag(&h___ref( k - 1, k - 1)), dabs(r__2)) + ((r__3 = h__[i__5].r, dabs( r__3)) + (r__4 = r_imag(&h___ref(k, k)), dabs(r__4))); if (tst1 == 0.f) { i__3 = i__ - l + 1; tst1 = clanhs_("1", &i__3, &h___ref(l, l), ldh, rwork); /* ** Increment op count */ latime_1.ops += (i__ - l + 1) * 5 * (i__ - l) / 2; /* ** */ } i__3 = h___subscr(k, k - 1); /* Computing MAX */ r__2 = ulp * tst1; if ((r__1 = h__[i__3].r, dabs(r__1)) <= dmax(r__2,smlnum)) { goto L80; } /* L70: */ } L80: l = k; /* ** Increment op count */ opst += (i__ - l + 1) * 5; /* ** */ if (l > *ilo) { /* H(L,L-1) is negligible. */ i__2 = h___subscr(l, l - 1); h__[i__2].r = 0.f, h__[i__2].i = 0.f; } /* Exit from loop if a submatrix of order <= MAXB has split off. */ if (l >= i__ - maxb + 1) { goto L170; } /* Now the active submatrix is in rows and columns L to I. If eigenvalues only are being computed, only the active submatrix need be transformed. */ if (! wantt) { i1 = l; i2 = i__; } if (its == 20 || its == 30) { /* Exceptional shifts. */ i__2 = i__; for (ii = i__ - ns + 1; ii <= i__2; ++ii) { i__3 = ii; i__5 = h___subscr(ii, ii - 1); i__6 = h___subscr(ii, ii); r__3 = ((r__1 = h__[i__5].r, dabs(r__1)) + (r__2 = h__[i__6] .r, dabs(r__2))) * 1.5f; w[i__3].r = r__3, w[i__3].i = 0.f; /* L90: */ } /* ** Increment op count */ opst += ns << 1; /* ** */ } else { /* Use eigenvalues of trailing submatrix of order NS as shifts. */ clacpy_("Full", &ns, &ns, &h___ref(i__ - ns + 1, i__ - ns + 1), ldh, s, &c__15); clahqr_(&c_false, &c_false, &ns, &c__1, &ns, s, &c__15, &w[i__ - ns + 1], &c__1, &ns, &z__[z_offset], ldz, &ierr); if (ierr > 0) { /* If CLAHQR failed to compute all NS eigenvalues, use the unconverged diagonal elements as the remaining shifts. */ i__2 = ierr; for (ii = 1; ii <= i__2; ++ii) { i__3 = i__ - ns + ii; i__5 = s_subscr(ii, ii); w[i__3].r = s[i__5].r, w[i__3].i = s[i__5].i; /* L100: */ } } } /* Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns)) where G is the Hessenberg submatrix H(L:I,L:I) and w is the vector of shifts (stored in W). The result is stored in the local array V. */ v[0].r = 1.f, v[0].i = 0.f; i__2 = ns + 1; for (ii = 2; ii <= i__2; ++ii) { i__3 = ii - 1; v[i__3].r = 0.f, v[i__3].i = 0.f; /* L110: */ } nv = 1; i__2 = i__; for (j = i__ - ns + 1; j <= i__2; ++j) { i__3 = nv + 1; ccopy_(&i__3, v, &c__1, vv, &c__1); i__3 = nv + 1; i__5 = j; q__1.r = -w[i__5].r, q__1.i = -w[i__5].i; cgemv_("No transpose", &i__3, &nv, &c_b2, &h___ref(l, l), ldh, vv, &c__1, &q__1, v, &c__1); ++nv; /* ** Increment op count */ opst = opst + (nv << 3) * (*n + 1) + (nv + 1) * 6; /* ** Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero, reset it to the unit vector. */ itemp = icamax_(&nv, v, &c__1); /* ** Increment op count */ opst += nv << 1; /* ** */ i__3 = itemp - 1; rtemp = (r__1 = v[i__3].r, dabs(r__1)) + (r__2 = r_imag(&v[itemp - 1]), dabs(r__2)); if (rtemp == 0.f) { v[0].r = 1.f, v[0].i = 0.f; i__3 = nv; for (ii = 2; ii <= i__3; ++ii) { i__5 = ii - 1; v[i__5].r = 0.f, v[i__5].i = 0.f; /* L120: */ } } else { rtemp = dmax(rtemp,smlnum); r__1 = 1.f / rtemp; csscal_(&nv, &r__1, v, &c__1); /* ** Increment op count */ opst += nv << 1; /* ** */ } /* L130: */ } /* Multiple-shift QR step */ i__2 = i__ - 1; for (k = l; k <= i__2; ++k) { /* The first iteration of this loop determines a reflection G from the vector V and applies it from left and right to H, thus creating a nonzero bulge below the subdiagonal. Each subsequent iteration determines a reflection G to restore the Hessenberg form in the (K-1)th column, and thus chases the bulge one step toward the bottom of the active submatrix. NR is the order of G. Computing MIN */ i__3 = ns + 1, i__5 = i__ - k + 1; nr = min(i__3,i__5); if (k > l) { ccopy_(&nr, &h___ref(k, k - 1), &c__1, v, &c__1); } clarfg_(&nr, v, &v[1], &c__1, &tau); /* ** Increment op count */ opst = opst + nr * 10 + 12; /* ** */ if (k > l) { i__3 = h___subscr(k, k - 1); h__[i__3].r = v[0].r, h__[i__3].i = v[0].i; i__3 = i__; for (ii = k + 1; ii <= i__3; ++ii) { i__5 = h___subscr(ii, k - 1); h__[i__5].r = 0.f, h__[i__5].i = 0.f; /* L140: */ } } v[0].r = 1.f, v[0].i = 0.f; /* Apply G' from the left to transform the rows of the matrix in columns K to I2. */ i__3 = i2 - k + 1; r_cnjg(&q__1, &tau); clarfx_("Left", &nr, &i__3, v, &q__1, &h___ref(k, k), ldh, &work[ 1]); /* Apply G from the right to transform the columns of the matrix in rows I1 to min(K+NR,I). Computing MIN */ i__5 = k + nr; i__3 = min(i__5,i__) - i1 + 1; clarfx_("Right", &i__3, &nr, v, &tau, &h___ref(i1, k), ldh, &work[ 1]); /* ** Increment op count Computing MIN */ i__3 = nr, i__5 = i__ - k; latime_1.ops += ((nr << 2) - 2 << 2) * (i2 - i1 + 2 + min(i__3, i__5)); /* ** */ if (wantz) { /* Accumulate transformations in the matrix Z */ clarfx_("Right", &nh, &nr, v, &tau, &z___ref(*ilo, k), ldz, & work[1]); /* ** Increment op count */ latime_1.ops += ((nr << 2) - 2 << 2) * nh; /* ** */ } /* L150: */ } /* Ensure that H(I,I-1) is real. */ i__2 = h___subscr(i__, i__ - 1); temp.r = h__[i__2].r, temp.i = h__[i__2].i; if (r_imag(&temp) != 0.f) { r__1 = temp.r; r__2 = r_imag(&temp); rtemp = slapy2_(&r__1, &r__2); i__2 = h___subscr(i__, i__ - 1); h__[i__2].r = rtemp, h__[i__2].i = 0.f; q__1.r = temp.r / rtemp, q__1.i = temp.i / rtemp; temp.r = q__1.r, temp.i = q__1.i; if (i2 > i__) { i__2 = i2 - i__; r_cnjg(&q__1, &temp); cscal_(&i__2, &q__1, &h___ref(i__, i__ + 1), ldh); } i__2 = i__ - i1; cscal_(&i__2, &temp, &h___ref(i1, i__), &c__1); /* ** Increment op count */ opst += (i2 - i1 + 1) * 6; /* ** */ if (wantz) { cscal_(&nh, &temp, &z___ref(*ilo, i__), &c__1); /* ** Increment op count */ opst += nh * 6; /* ** */ } } /* L160: */ } /* Failure to converge in remaining number of iterations */ *info = i__; return 0; L170: /* A submatrix of order <= MAXB in rows and columns L to I has split off. Use the double-shift QR algorithm to handle it. */ clahqr_(&wantt, &wantz, n, &l, &i__, &h__[h_offset], ldh, &w[1], ilo, ihi, &z__[z_offset], ldz, info); if (*info > 0) { return 0; } /* Decrement number of remaining iterations, and return to start of the main loop with a new value of I. */ itn -= its; i__ = l - 1; goto L60; L180: /* ** Compute final op count */ latime_1.ops += opst; /* ** */ i__1 = max(1,*n); work[1].r = (real) i__1, work[1].i = 0.f; return 0; /* End of CHSEQR */ } /* chseqr_ */
/* Subroutine */ int chpr_(char *uplo, integer *n, real *alpha, complex *x, integer *incx, complex *ap) { /* System generated locals */ integer i__1, i__2, i__3, i__4, i__5; real r__1; complex q__1, q__2; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer info; static complex temp; static integer i__, j, k; extern logical lsame_(char *, char *); static integer kk, ix, jx, kx; extern /* Subroutine */ int xerbla_(char *, integer *); /* Purpose ======= CHPR performs the hermitian rank 1 operation A := alpha*x*conjg( x' ) + A, where alpha is a real scalar, x is an n element vector and A is an n by n hermitian matrix, supplied in packed form. Parameters ========== UPLO - CHARACTER*1. On entry, UPLO specifies whether the upper or lower triangular part of the matrix A is supplied in the packed array AP as follows: UPLO = 'U' or 'u' The upper triangular part of A is supplied in AP. UPLO = 'L' or 'l' The lower triangular part of A is supplied in AP. Unchanged on exit. N - INTEGER. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - REAL . On entry, ALPHA specifies the scalar alpha. Unchanged on exit. X - COMPLEX array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. Unchanged on exit. INCX - INTEGER. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. AP - COMPLEX array of DIMENSION at least ( ( n*( n + 1 ) )/2 ). Before entry with UPLO = 'U' or 'u', the array AP must contain the upper triangular part of the hermitian matrix packed sequentially, column by column, so that AP( 1 ) contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 ) respectively, and so on. On exit, the array AP is overwritten by the upper triangular part of the updated matrix. Before entry with UPLO = 'L' or 'l', the array AP must contain the lower triangular part of the hermitian matrix packed sequentially, column by column, so that AP( 1 ) contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 ) respectively, and so on. On exit, the array AP is overwritten by the lower triangular part of the updated matrix. Note that the imaginary parts of the diagonal elements need not be set, they are assumed to be zero, and on exit they are set to zero. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. Test the input parameters. Parameter adjustments */ --ap; --x; /* Function Body */ info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*incx == 0) { info = 5; } if (info != 0) { xerbla_("CHPR ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || *alpha == 0.f) { return 0; } /* Set the start point in X if the increment is not unity. */ if (*incx <= 0) { kx = 1 - (*n - 1) * *incx; } else if (*incx != 1) { kx = 1; } /* Start the operations. In this version the elements of the array AP are accessed sequentially with one pass through AP. */ kk = 1; if (lsame_(uplo, "U")) { /* Form A when upper triangle is stored in AP. */ if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[j]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; k = kk; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = k; i__4 = k; i__5 = i__; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = ap[i__4].r + q__2.r, q__1.i = ap[i__4].i + q__2.i; ap[i__3].r = q__1.r, ap[i__3].i = q__1.i; ++k; /* L10: */ } i__2 = kk + j - 1; i__3 = kk + j - 1; i__4 = j; q__1.r = x[i__4].r * temp.r - x[i__4].i * temp.i, q__1.i = x[i__4].r * temp.i + x[i__4].i * temp.r; r__1 = ap[i__3].r + q__1.r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } else { i__2 = kk + j - 1; i__3 = kk + j - 1; r__1 = ap[i__3].r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } kk += j; /* L20: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[jx]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; ix = kx; i__2 = kk + j - 2; for (k = kk; k <= i__2; ++k) { i__3 = k; i__4 = k; i__5 = ix; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = ap[i__4].r + q__2.r, q__1.i = ap[i__4].i + q__2.i; ap[i__3].r = q__1.r, ap[i__3].i = q__1.i; ix += *incx; /* L30: */ } i__2 = kk + j - 1; i__3 = kk + j - 1; i__4 = jx; q__1.r = x[i__4].r * temp.r - x[i__4].i * temp.i, q__1.i = x[i__4].r * temp.i + x[i__4].i * temp.r; r__1 = ap[i__3].r + q__1.r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } else { i__2 = kk + j - 1; i__3 = kk + j - 1; r__1 = ap[i__3].r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } jx += *incx; kk += j; /* L40: */ } } } else { /* Form A when lower triangle is stored in AP. */ if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[j]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; i__2 = kk; i__3 = kk; i__4 = j; q__1.r = temp.r * x[i__4].r - temp.i * x[i__4].i, q__1.i = temp.r * x[i__4].i + temp.i * x[i__4].r; r__1 = ap[i__3].r + q__1.r; ap[i__2].r = r__1, ap[i__2].i = 0.f; k = kk + 1; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { i__3 = k; i__4 = k; i__5 = i__; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = ap[i__4].r + q__2.r, q__1.i = ap[i__4].i + q__2.i; ap[i__3].r = q__1.r, ap[i__3].i = q__1.i; ++k; /* L50: */ } } else { i__2 = kk; i__3 = kk; r__1 = ap[i__3].r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } kk = kk + *n - j + 1; /* L60: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[jx]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; i__2 = kk; i__3 = kk; i__4 = jx; q__1.r = temp.r * x[i__4].r - temp.i * x[i__4].i, q__1.i = temp.r * x[i__4].i + temp.i * x[i__4].r; r__1 = ap[i__3].r + q__1.r; ap[i__2].r = r__1, ap[i__2].i = 0.f; ix = jx; i__2 = kk + *n - j; for (k = kk + 1; k <= i__2; ++k) { ix += *incx; i__3 = k; i__4 = k; i__5 = ix; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = ap[i__4].r + q__2.r, q__1.i = ap[i__4].i + q__2.i; ap[i__3].r = q__1.r, ap[i__3].i = q__1.i; /* L70: */ } } else { i__2 = kk; i__3 = kk; r__1 = ap[i__3].r; ap[i__2].r = r__1, ap[i__2].i = 0.f; } jx += *incx; kk = kk + *n - j + 1; /* L80: */ } } } return 0; /* End of CHPR . */ } /* chpr_ */
/* Subroutine */ int claqp2_(integer *m, integer *n, integer *offset, complex *a, integer *lda, integer *jpvt, complex *tau, real *vn1, real *vn2, complex *work) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3; real r__1; complex q__1; /* Builtin functions */ void r_cnjg(complex *, complex *); double c_abs(complex *), sqrt(doublereal); /* Local variables */ static integer i__, j, mn; static complex aii; static integer pvt; static real temp, temp2; extern /* Subroutine */ int clarf_(char *, integer *, integer *, complex * , integer *, complex *, complex *, integer *, complex *, ftnlen); static integer offpi; extern /* Subroutine */ int cswap_(integer *, complex *, integer *, complex *, integer *); static integer itemp; extern doublereal scnrm2_(integer *, complex *, integer *); extern /* Subroutine */ int clarfg_(integer *, complex *, complex *, integer *, complex *); extern integer isamax_(integer *, real *, integer *); /* -- LAPACK auxiliary routine (version 3.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ /* Courant Institute, Argonne National Lab, and Rice University */ /* June 30, 1999 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CLAQP2 computes a QR factorization with column pivoting of */ /* the block A(OFFSET+1:M,1:N). */ /* The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized. */ /* Arguments */ /* ========= */ /* M (input) INTEGER */ /* The number of rows of the matrix A. M >= 0. */ /* N (input) INTEGER */ /* The number of columns of the matrix A. N >= 0. */ /* OFFSET (input) INTEGER */ /* The number of rows of the matrix A that must be pivoted */ /* but no factorized. OFFSET >= 0. */ /* A (input/output) COMPLEX array, dimension (LDA,N) */ /* On entry, the M-by-N matrix A. */ /* On exit, the upper triangle of block A(OFFSET+1:M,1:N) is */ /* the triangular factor obtained; the elements in block */ /* A(OFFSET+1:M,1:N) below the diagonal, together with the */ /* array TAU, represent the orthogonal matrix Q as a product of */ /* elementary reflectors. Block A(1:OFFSET,1:N) has been */ /* accordingly pivoted, but no factorized. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,M). */ /* JPVT (input/output) INTEGER array, dimension (N) */ /* On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted */ /* to the front of A*P (a leading column); if JPVT(i) = 0, */ /* the i-th column of A is a free column. */ /* On exit, if JPVT(i) = k, then the i-th column of A*P */ /* was the k-th column of A. */ /* TAU (output) COMPLEX array, dimension (min(M,N)) */ /* The scalar factors of the elementary reflectors. */ /* VN1 (input/output) REAL array, dimension (N) */ /* The vector with the partial column norms. */ /* VN2 (input/output) REAL array, dimension (N) */ /* The vector with the exact column norms. */ /* WORK (workspace) COMPLEX array, dimension (N) */ /* Further Details */ /* =============== */ /* Based on contributions by */ /* G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain */ /* X. Sun, Computer Science Dept., Duke University, USA */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --jpvt; --tau; --vn1; --vn2; --work; /* Function Body */ /* Computing MIN */ i__1 = *m - *offset; mn = min(i__1,*n); /* Compute factorization. */ i__1 = mn; for (i__ = 1; i__ <= i__1; ++i__) { offpi = *offset + i__; /* Determine ith pivot column and swap if necessary. */ i__2 = *n - i__ + 1; pvt = i__ - 1 + isamax_(&i__2, &vn1[i__], &c__1); if (pvt != i__) { cswap_(m, &a[pvt * a_dim1 + 1], &c__1, &a[i__ * a_dim1 + 1], & c__1); itemp = jpvt[pvt]; jpvt[pvt] = jpvt[i__]; jpvt[i__] = itemp; vn1[pvt] = vn1[i__]; vn2[pvt] = vn2[i__]; } /* Generate elementary reflector H(i). */ if (offpi < *m) { i__2 = *m - offpi + 1; clarfg_(&i__2, &a[offpi + i__ * a_dim1], &a[offpi + 1 + i__ * a_dim1], &c__1, &tau[i__]); } else { clarfg_(&c__1, &a[*m + i__ * a_dim1], &a[*m + i__ * a_dim1], & c__1, &tau[i__]); } if (i__ < *n) { /* Apply H(i)' to A(offset+i:m,i+1:n) from the left. */ i__2 = offpi + i__ * a_dim1; aii.r = a[i__2].r, aii.i = a[i__2].i; i__2 = offpi + i__ * a_dim1; a[i__2].r = 1.f, a[i__2].i = 0.f; i__2 = *m - offpi + 1; i__3 = *n - i__; r_cnjg(&q__1, &tau[i__]); clarf_("Left", &i__2, &i__3, &a[offpi + i__ * a_dim1], &c__1, & q__1, &a[offpi + (i__ + 1) * a_dim1], lda, &work[1], ( ftnlen)4); i__2 = offpi + i__ * a_dim1; a[i__2].r = aii.r, a[i__2].i = aii.i; } /* Update partial column norms. */ i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { if (vn1[j] != 0.f) { /* Computing 2nd power */ r__1 = c_abs(&a[offpi + j * a_dim1]) / vn1[j]; temp = 1.f - r__1 * r__1; temp = dmax(temp,0.f); /* Computing 2nd power */ r__1 = vn1[j] / vn2[j]; temp2 = temp * .05f * (r__1 * r__1) + 1.f; if (temp2 == 1.f) { if (offpi < *m) { i__3 = *m - offpi; vn1[j] = scnrm2_(&i__3, &a[offpi + 1 + j * a_dim1], & c__1); vn2[j] = vn1[j]; } else { vn1[j] = 0.f; vn2[j] = 0.f; } } else { vn1[j] *= sqrt(temp); } } /* L10: */ } /* L20: */ } return 0; /* End of CLAQP2 */ } /* claqp2_ */
/* Subroutine */ int ctgsen_(integer *ijob, logical *wantq, logical *wantz, logical *select, integer *n, complex *a, integer *lda, complex *b, integer *ldb, complex *alpha, complex *beta, complex *q, integer *ldq, complex *z__, integer *ldz, integer *m, real *pl, real *pr, real * dif, complex *work, integer *lwork, integer *iwork, integer *liwork, integer *info) { /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= CTGSEN reorders the generalized Schur decomposition of a complex matrix pair (A, B) (in terms of an unitary equivalence trans- formation Q' * (A, B) * Z), so that a selected cluster of eigenvalues appears in the leading diagonal blocks of the pair (A,B). The leading columns of Q and Z form unitary bases of the corresponding left and right eigenspaces (deflating subspaces). (A, B) must be in generalized Schur canonical form, that is, A and B are both upper triangular. CTGSEN also computes the generalized eigenvalues w(j)= ALPHA(j) / BETA(j) of the reordered matrix pair (A, B). Optionally, the routine computes estimates of reciprocal condition numbers for eigenvalues and eigenspaces. These are Difu[(A11,B11), (A22,B22)] and Difl[(A11,B11), (A22,B22)], i.e. the separation(s) between the matrix pairs (A11, B11) and (A22,B22) that correspond to the selected cluster and the eigenvalues outside the cluster, resp., and norms of "projections" onto left and right eigenspaces w.r.t. the selected cluster in the (1,1)-block. Arguments ========= IJOB (input) integer Specifies whether condition numbers are required for the cluster of eigenvalues (PL and PR) or the deflating subspaces (Difu and Difl): =0: Only reorder w.r.t. SELECT. No extras. =1: Reciprocal of norms of "projections" onto left and right eigenspaces w.r.t. the selected cluster (PL and PR). =2: Upper bounds on Difu and Difl. F-norm-based estimate (DIF(1:2)). =3: Estimate of Difu and Difl. 1-norm-based estimate (DIF(1:2)). About 5 times as expensive as IJOB = 2. =4: Compute PL, PR and DIF (i.e. 0, 1 and 2 above): Economic version to get it all. =5: Compute PL, PR and DIF (i.e. 0, 1 and 3 above) WANTQ (input) LOGICAL .TRUE. : update the left transformation matrix Q; .FALSE.: do not update Q. WANTZ (input) LOGICAL .TRUE. : update the right transformation matrix Z; .FALSE.: do not update Z. SELECT (input) LOGICAL array, dimension (N) SELECT specifies the eigenvalues in the selected cluster. To select an eigenvalue w(j), SELECT(j) must be set to .TRUE.. N (input) INTEGER The order of the matrices A and B. N >= 0. A (input/output) COMPLEX array, dimension(LDA,N) On entry, the upper triangular matrix A, in generalized Schur canonical form. On exit, A is overwritten by the reordered matrix A. LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,N). B (input/output) COMPLEX array, dimension(LDB,N) On entry, the upper triangular matrix B, in generalized Schur canonical form. On exit, B is overwritten by the reordered matrix B. LDB (input) INTEGER The leading dimension of the array B. LDB >= max(1,N). ALPHA (output) COMPLEX array, dimension (N) BETA (output) COMPLEX array, dimension (N) The diagonal elements of A and B, respectively, when the pair (A,B) has been reduced to generalized Schur form. ALPHA(i)/BETA(i) i=1,...,N are the generalized eigenvalues. Q (input/output) COMPLEX array, dimension (LDQ,N) On entry, if WANTQ = .TRUE., Q is an N-by-N matrix. On exit, Q has been postmultiplied by the left unitary transformation matrix which reorder (A, B); The leading M columns of Q form orthonormal bases for the specified pair of left eigenspaces (deflating subspaces). If WANTQ = .FALSE., Q is not referenced. LDQ (input) INTEGER The leading dimension of the array Q. LDQ >= 1. If WANTQ = .TRUE., LDQ >= N. Z (input/output) COMPLEX array, dimension (LDZ,N) On entry, if WANTZ = .TRUE., Z is an N-by-N matrix. On exit, Z has been postmultiplied by the left unitary transformation matrix which reorder (A, B); The leading M columns of Z form orthonormal bases for the specified pair of left eigenspaces (deflating subspaces). If WANTZ = .FALSE., Z is not referenced. LDZ (input) INTEGER The leading dimension of the array Z. LDZ >= 1. If WANTZ = .TRUE., LDZ >= N. M (output) INTEGER The dimension of the specified pair of left and right eigenspaces, (deflating subspaces) 0 <= M <= N. PL, PR (output) REAL If IJOB = 1, 4 or 5, PL, PR are lower bounds on the reciprocal of the norm of "projections" onto left and right eigenspace with respect to the selected cluster. 0 < PL, PR <= 1. If M = 0 or M = N, PL = PR = 1. If IJOB = 0, 2 or 3 PL, PR are not referenced. DIF (output) REAL array, dimension (2). If IJOB >= 2, DIF(1:2) store the estimates of Difu and Difl. If IJOB = 2 or 4, DIF(1:2) are F-norm-based upper bounds on Difu and Difl. If IJOB = 3 or 5, DIF(1:2) are 1-norm-based estimates of Difu and Difl, computed using reversed communication with CLACON. If M = 0 or N, DIF(1:2) = F-norm([A, B]). If IJOB = 0 or 1, DIF is not referenced. WORK (workspace/output) COMPLEX array, dimension (LWORK) IF IJOB = 0, WORK is not referenced. Otherwise, on exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) INTEGER The dimension of the array WORK. LWORK >= 1 If IJOB = 1, 2 or 4, LWORK >= 2*M*(N-M) If IJOB = 3 or 5, LWORK >= 4*M*(N-M) If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. IWORK (workspace/output) INTEGER, dimension (LIWORK) IF IJOB = 0, IWORK is not referenced. Otherwise, on exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. LIWORK (input) INTEGER The dimension of the array IWORK. LIWORK >= 1. If IJOB = 1, 2 or 4, LIWORK >= N+2; If IJOB = 3 or 5, LIWORK >= MAX(N+2, 2*M*(N-M)); If LIWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the IWORK array, returns this value as the first entry of the IWORK array, and no error message related to LIWORK is issued by XERBLA. INFO (output) INTEGER =0: Successful exit. <0: If INFO = -i, the i-th argument had an illegal value. =1: Reordering of (A, B) failed because the transformed matrix pair (A, B) would be too far from generalized Schur form; the problem is very ill-conditioned. (A, B) may have been partially reordered. If requested, 0 is returned in DIF(*), PL and PR. Further Details =============== CTGSEN first collects the selected eigenvalues by computing unitary U and W that move them to the top left corner of (A, B). In other words, the selected eigenvalues are the eigenvalues of (A11, B11) in U'*(A, B)*W = (A11 A12) (B11 B12) n1 ( 0 A22),( 0 B22) n2 n1 n2 n1 n2 where N = n1+n2 and U' means the conjugate transpose of U. The first n1 columns of U and W span the specified pair of left and right eigenspaces (deflating subspaces) of (A, B). If (A, B) has been obtained from the generalized real Schur decomposition of a matrix pair (C, D) = Q*(A, B)*Z', then the reordered generalized Schur form of (C, D) is given by (C, D) = (Q*U)*(U'*(A, B)*W)*(Z*W)', and the first n1 columns of Q*U and Z*W span the corresponding deflating subspaces of (C, D) (Q and Z store Q*U and Z*W, resp.). Note that if the selected eigenvalue is sufficiently ill-conditioned, then its value may differ significantly from its value before reordering. The reciprocal condition numbers of the left and right eigenspaces spanned by the first n1 columns of U and W (or Q*U and Z*W) may be returned in DIF(1:2), corresponding to Difu and Difl, resp. The Difu and Difl are defined as: Difu[(A11, B11), (A22, B22)] = sigma-min( Zu ) and Difl[(A11, B11), (A22, B22)] = Difu[(A22, B22), (A11, B11)], where sigma-min(Zu) is the smallest singular value of the (2*n1*n2)-by-(2*n1*n2) matrix Zu = [ kron(In2, A11) -kron(A22', In1) ] [ kron(In2, B11) -kron(B22', In1) ]. Here, Inx is the identity matrix of size nx and A22' is the transpose of A22. kron(X, Y) is the Kronecker product between the matrices X and Y. When DIF(2) is small, small changes in (A, B) can cause large changes in the deflating subspace. An approximate (asymptotic) bound on the maximum angular error in the computed deflating subspaces is EPS * norm((A, B)) / DIF(2), where EPS is the machine precision. The reciprocal norm of the projectors on the left and right eigenspaces associated with (A11, B11) may be returned in PL and PR. They are computed as follows. First we compute L and R so that P*(A, B)*Q is block diagonal, where P = ( I -L ) n1 Q = ( I R ) n1 ( 0 I ) n2 and ( 0 I ) n2 n1 n2 n1 n2 and (L, R) is the solution to the generalized Sylvester equation A11*R - L*A22 = -A12 B11*R - L*B22 = -B12 Then PL = (F-norm(L)**2+1)**(-1/2) and PR = (F-norm(R)**2+1)**(-1/2). An approximate (asymptotic) bound on the average absolute error of the selected eigenvalues is EPS * norm((A, B)) / PL. There are also global error bounds which valid for perturbations up to a certain restriction: A lower bound (x) on the smallest F-norm(E,F) for which an eigenvalue of (A11, B11) may move and coalesce with an eigenvalue of (A22, B22) under perturbation (E,F), (i.e. (A + E, B + F), is x = min(Difu,Difl)/((1/(PL*PL)+1/(PR*PR))**(1/2)+2*max(1/PL,1/PR)). An approximate bound on x can be computed from DIF(1:2), PL and PR. If y = ( F-norm(E,F) / x) <= 1, the angles between the perturbed (L', R') and unperturbed (L, R) left and right deflating subspaces associated with the selected cluster in the (1,1)-blocks can be bounded as max-angle(L, L') <= arctan( y * PL / (1 - y * (1 - PL * PL)**(1/2)) max-angle(R, R') <= arctan( y * PR / (1 - y * (1 - PR * PR)**(1/2)) See LAPACK User's Guide section 4.11 or the following references for more information. Note that if the default method for computing the Frobenius-norm- based estimate DIF is not wanted (see CLATDF), then the parameter IDIFJB (see below) should be changed from 3 to 4 (routine CLATDF (IJOB = 2 will be used)). See CTGSYL for more details. Based on contributions by Bo Kagstrom and Peter Poromaa, Department of Computing Science, Umea University, S-901 87 Umea, Sweden. References ========== [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the Generalized Real Schur Form of a Regular Matrix Pair (A, B), in M.S. Moonen et al (eds), Linear Algebra for Large Scale and Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218. [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified Eigenvalues of a Regular Matrix Pair (A, B) and Condition Estimation: Theory, Algorithms and Software, Report UMINF - 94.04, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working Note 87. To appear in Numerical Algorithms, 1996. [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software for Solving the Generalized Sylvester Equation and Estimating the Separation between Regular Matrix Pairs, Report UMINF - 93.23, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, December 1993, Revised April 1994, Also as LAPACK working Note 75. To appear in ACM Trans. on Math. Software, Vol 22, No 1, 1996. ===================================================================== Decode and test the input parameters Parameter adjustments */ /* Table of constant values */ static integer c__1 = 1; /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, z_dim1, z_offset, i__1, i__2, i__3; complex q__1, q__2; /* Builtin functions */ double sqrt(doublereal), c_abs(complex *); void r_cnjg(complex *, complex *); /* Local variables */ static integer kase, ierr; static real dsum; static logical swap; static integer i__, k; extern /* Subroutine */ int cscal_(integer *, complex *, complex *, integer *); static logical wantd; static integer lwmin; static logical wantp; static integer n1, n2; static logical wantd1, wantd2; static real dscale; static integer ks; extern /* Subroutine */ int clacon_(integer *, complex *, complex *, real *, integer *); extern doublereal slamch_(char *); static real rdscal; extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *); static real safmin; extern /* Subroutine */ int ctgexc_(logical *, logical *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, integer *, integer *, integer *), xerbla_( char *, integer *), classq_(integer *, complex *, integer *, real *, real *); static integer liwmin; extern /* Subroutine */ int ctgsyl_(char *, integer *, integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, real *, real *, complex *, integer *, integer *, integer *); static integer mn2; static logical lquery; static integer ijb; #define a_subscr(a_1,a_2) (a_2)*a_dim1 + a_1 #define a_ref(a_1,a_2) a[a_subscr(a_1,a_2)] #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)] #define q_subscr(a_1,a_2) (a_2)*q_dim1 + a_1 #define q_ref(a_1,a_2) q[q_subscr(a_1,a_2)] --select; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --alpha; --beta; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; z_dim1 = *ldz; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; --dif; --work; --iwork; /* Function Body */ *info = 0; lquery = *lwork == -1 || *liwork == -1; if (*ijob < 0 || *ijob > 5) { *info = -1; } else if (*n < 0) { *info = -5; } else if (*lda < max(1,*n)) { *info = -7; } else if (*ldb < max(1,*n)) { *info = -9; } else if (*ldq < 1 || *wantq && *ldq < *n) { *info = -13; } else if (*ldz < 1 || *wantz && *ldz < *n) { *info = -15; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGSEN", &i__1); return 0; } ierr = 0; wantp = *ijob == 1 || *ijob >= 4; wantd1 = *ijob == 2 || *ijob == 4; wantd2 = *ijob == 3 || *ijob == 5; wantd = wantd1 || wantd2; /* Set M to the dimension of the specified pair of deflating subspaces. */ *m = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { i__2 = k; i__3 = a_subscr(k, k); alpha[i__2].r = a[i__3].r, alpha[i__2].i = a[i__3].i; i__2 = k; i__3 = b_subscr(k, k); beta[i__2].r = b[i__3].r, beta[i__2].i = b[i__3].i; if (k < *n) { if (select[k]) { ++(*m); } } else { if (select[*n]) { ++(*m); } } /* L10: */ } if (*ijob == 1 || *ijob == 2 || *ijob == 4) { /* Computing MAX */ i__1 = 1, i__2 = (*m << 1) * (*n - *m); lwmin = max(i__1,i__2); /* Computing MAX */ i__1 = 1, i__2 = *n + 2; liwmin = max(i__1,i__2); } else if (*ijob == 3 || *ijob == 5) { /* Computing MAX */ i__1 = 1, i__2 = (*m << 2) * (*n - *m); lwmin = max(i__1,i__2); /* Computing MAX */ i__1 = 1, i__2 = (*m << 1) * (*n - *m), i__1 = max(i__1,i__2), i__2 = *n + 2; liwmin = max(i__1,i__2); } else { lwmin = 1; liwmin = 1; } work[1].r = (real) lwmin, work[1].i = 0.f; iwork[1] = liwmin; if (*lwork < lwmin && ! lquery) { *info = -21; } else if (*liwork < liwmin && ! lquery) { *info = -23; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGSEN", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible. */ if (*m == *n || *m == 0) { if (wantp) { *pl = 1.f; *pr = 1.f; } if (wantd) { dscale = 0.f; dsum = 1.f; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { classq_(n, &a_ref(1, i__), &c__1, &dscale, &dsum); classq_(n, &b_ref(1, i__), &c__1, &dscale, &dsum); /* L20: */ } dif[1] = dscale * sqrt(dsum); dif[2] = dif[1]; } goto L70; } /* Get machine constant */ safmin = slamch_("S"); /* Collect the selected blocks at the top-left corner of (A, B). */ ks = 0; i__1 = *n; for (k = 1; k <= i__1; ++k) { swap = select[k]; if (swap) { ++ks; /* Swap the K-th block to position KS. Compute unitary Q and Z that will swap adjacent diagonal blocks in (A, B). */ if (k != ks) { ctgexc_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &k, &ks, & ierr); } if (ierr > 0) { /* Swap is rejected: exit. */ *info = 1; if (wantp) { *pl = 0.f; *pr = 0.f; } if (wantd) { dif[1] = 0.f; dif[2] = 0.f; } goto L70; } } /* L30: */ } if (wantp) { /* Solve generalized Sylvester equation for R and L: A11 * R - L * A22 = A12 B11 * R - L * B22 = B12 */ n1 = *m; n2 = *n - *m; i__ = n1 + 1; clacpy_("Full", &n1, &n2, &a_ref(1, i__), lda, &work[1], &n1); clacpy_("Full", &n1, &n2, &b_ref(1, i__), ldb, &work[n1 * n2 + 1], & n1); ijb = 0; i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a_ref(i__, i__), lda, &work[1], &n1, &b[b_offset], ldb, &b_ref(i__, i__), ldb, & work[n1 * n2 + 1], &n1, &dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); /* Estimate the reciprocal of norms of "projections" onto left and right eigenspaces */ rdscal = 0.f; dsum = 1.f; i__1 = n1 * n2; classq_(&i__1, &work[1], &c__1, &rdscal, &dsum); *pl = rdscal * sqrt(dsum); if (*pl == 0.f) { *pl = 1.f; } else { *pl = dscale / (sqrt(dscale * dscale / *pl + *pl) * sqrt(*pl)); } rdscal = 0.f; dsum = 1.f; i__1 = n1 * n2; classq_(&i__1, &work[n1 * n2 + 1], &c__1, &rdscal, &dsum); *pr = rdscal * sqrt(dsum); if (*pr == 0.f) { *pr = 1.f; } else { *pr = dscale / (sqrt(dscale * dscale / *pr + *pr) * sqrt(*pr)); } } if (wantd) { /* Compute estimates Difu and Difl. */ if (wantd1) { n1 = *m; n2 = *n - *m; i__ = n1 + 1; ijb = 3; /* Frobenius norm-based Difu estimate. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a_ref(i__, i__), lda, &work[1], &n1, &b[b_offset], ldb, &b_ref(i__, i__), ldb, &work[n1 * n2 + 1], &n1, &dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); /* Frobenius norm-based Difl estimate. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n2, &n1, &a_ref(i__, i__), lda, &a[a_offset], lda, &work[1], &n2, &b_ref(i__, i__), ldb, &b[b_offset], ldb, &work[n1 * n2 + 1], &n2, &dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } else { /* Compute 1-norm-based estimates of Difu and Difl using reversed communication with CLACON. In each step a generalized Sylvester equation or a transposed variant is solved. */ kase = 0; n1 = *m; n2 = *n - *m; i__ = n1 + 1; ijb = 0; mn2 = (n1 << 1) * n2; /* 1-norm-based estimate of Difu. */ L40: clacon_(&mn2, &work[mn2 + 1], &work[1], &dif[1], &kase); if (kase != 0) { if (kase == 1) { /* Solve generalized Sylvester equation */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n1, &n2, &a[a_offset], lda, &a_ref( i__, i__), lda, &work[1], &n1, &b[b_offset], ldb, &b_ref(i__, i__), ldb, &work[n1 * n2 + 1], &n1, & dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } else { /* Solve the transposed variant. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("C", &ijb, &n1, &n2, &a[a_offset], lda, &a_ref( i__, i__), lda, &work[1], &n1, &b[b_offset], ldb, &b_ref(i__, i__), ldb, &work[n1 * n2 + 1], &n1, & dscale, &dif[1], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } goto L40; } dif[1] = dscale / dif[1]; /* 1-norm-based estimate of Difl. */ L50: clacon_(&mn2, &work[mn2 + 1], &work[1], &dif[2], &kase); if (kase != 0) { if (kase == 1) { /* Solve generalized Sylvester equation */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("N", &ijb, &n2, &n1, &a_ref(i__, i__), lda, &a[ a_offset], lda, &work[1], &n2, &b_ref(i__, i__), ldb, &b[b_offset], ldb, &work[n1 * n2 + 1], &n2, & dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } else { /* Solve the transposed variant. */ i__1 = *lwork - (n1 << 1) * n2; ctgsyl_("C", &ijb, &n2, &n1, &a_ref(i__, i__), lda, &a[ a_offset], lda, &work[1], &n2, &b[b_offset], ldb, &b_ref(i__, i__), ldb, &work[n1 * n2 + 1], &n2, & dscale, &dif[2], &work[(n1 * n2 << 1) + 1], &i__1, &iwork[1], &ierr); } goto L50; } dif[2] = dscale / dif[2]; } } /* If B(K,K) is complex, make it real and positive (normalization of the generalized Schur form) and Store the generalized eigenvalues of reordered pair (A, B) */ i__1 = *n; for (k = 1; k <= i__1; ++k) { dscale = c_abs(&b_ref(k, k)); if (dscale > safmin) { i__2 = b_subscr(k, k); q__2.r = b[i__2].r / dscale, q__2.i = b[i__2].i / dscale; r_cnjg(&q__1, &q__2); work[1].r = q__1.r, work[1].i = q__1.i; i__2 = b_subscr(k, k); q__1.r = b[i__2].r / dscale, q__1.i = b[i__2].i / dscale; work[2].r = q__1.r, work[2].i = q__1.i; i__2 = b_subscr(k, k); b[i__2].r = dscale, b[i__2].i = 0.f; i__2 = *n - k; cscal_(&i__2, &work[1], &b_ref(k, k + 1), ldb); i__2 = *n - k + 1; cscal_(&i__2, &work[1], &a_ref(k, k), lda); if (*wantq) { cscal_(n, &work[2], &q_ref(1, k), &c__1); } } else { i__2 = b_subscr(k, k); b[i__2].r = 0.f, b[i__2].i = 0.f; } i__2 = k; i__3 = a_subscr(k, k); alpha[i__2].r = a[i__3].r, alpha[i__2].i = a[i__3].i; i__2 = k; i__3 = b_subscr(k, k); beta[i__2].r = b[i__3].r, beta[i__2].i = b[i__3].i; /* L60: */ } L70: work[1].r = (real) lwmin, work[1].i = 0.f; iwork[1] = liwmin; return 0; /* End of CTGSEN */ } /* ctgsen_ */
/* Subroutine */ int ctgsy2_(char *trans, integer *ijob, integer *m, integer * n, complex *a, integer *lda, complex *b, integer *ldb, complex *c__, integer *ldc, complex *d__, integer *ldd, complex *e, integer *lde, complex *f, integer *ldf, real *scale, real *rdsum, real *rdscal, integer *info) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, d_dim1, d_offset, e_dim1, e_offset, f_dim1, f_offset, i__1, i__2, i__3, i__4; complex q__1, q__2, q__3, q__4, q__5, q__6; /* Local variables */ integer i__, j, k; complex z__[4] /* was [2][2] */, rhs[2]; integer ierr, ipiv[2], jpiv[2]; complex alpha; real scaloc; logical notran; /* -- LAPACK auxiliary routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* CTGSY2 solves the generalized Sylvester equation */ /* A * R - L * B = scale * C (1) */ /* D * R - L * E = scale * F */ /* using Level 1 and 2 BLAS, where R and L are unknown M-by-N matrices, */ /* (A, D), (B, E) and (C, F) are given matrix pairs of size M-by-M, */ /* N-by-N and M-by-N, respectively. A, B, D and E are upper triangular */ /* (i.e., (A,D) and (B,E) in generalized Schur form). */ /* The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 is an output */ /* scaling factor chosen to avoid overflow. */ /* In matrix notation solving equation (1) corresponds to solve */ /* Zx = scale * b, where Z is defined as */ /* Z = [ kron(In, A) -kron(B', Im) ] (2) */ /* [ kron(In, D) -kron(E', Im) ], */ /* Ik is the identity matrix of size k and X' is the transpose of X. */ /* kron(X, Y) is the Kronecker product between the matrices X and Y. */ /* If TRANS = 'C', y in the conjugate transposed system Z'y = scale*b */ /* is solved for, which is equivalent to solve for R and L in */ /* A' * R + D' * L = scale * C (3) */ /* R * B' + L * E' = scale * -F */ /* This case is used to compute an estimate of Dif[(A, D), (B, E)] = */ /* = sigma_min(Z) using reverse communicaton with CLACON. */ /* CTGSY2 also (IJOB >= 1) contributes to the computation in CTGSYL */ /* of an upper bound on the separation between to matrix pairs. Then */ /* the input (A, D), (B, E) are sub-pencils of two matrix pairs in */ /* CTGSYL. */ /* Arguments */ /* ========= */ /* TRANS (input) CHARACTER*1 */ /* = 'N', solve the generalized Sylvester equation (1). */ /* = 'T': solve the 'transposed' system (3). */ /* IJOB (input) INTEGER */ /* Specifies what kind of functionality to be performed. */ /* =0: solve (1) only. */ /* =1: A contribution from this subsystem to a Frobenius */ /* norm-based estimate of the separation between two matrix */ /* pairs is computed. (look ahead strategy is used). */ /* =2: A contribution from this subsystem to a Frobenius */ /* norm-based estimate of the separation between two matrix */ /* pairs is computed. (SGECON on sub-systems is used.) */ /* Not referenced if TRANS = 'T'. */ /* M (input) INTEGER */ /* On entry, M specifies the order of A and D, and the row */ /* dimension of C, F, R and L. */ /* N (input) INTEGER */ /* On entry, N specifies the order of B and E, and the column */ /* dimension of C, F, R and L. */ /* A (input) COMPLEX array, dimension (LDA, M) */ /* On entry, A contains an upper triangular matrix. */ /* LDA (input) INTEGER */ /* The leading dimension of the matrix A. LDA >= max(1, M). */ /* B (input) COMPLEX array, dimension (LDB, N) */ /* On entry, B contains an upper triangular matrix. */ /* LDB (input) INTEGER */ /* The leading dimension of the matrix B. LDB >= max(1, N). */ /* C (input/output) COMPLEX array, dimension (LDC, N) */ /* On entry, C contains the right-hand-side of the first matrix */ /* equation in (1). */ /* On exit, if IJOB = 0, C has been overwritten by the solution */ /* R. */ /* LDC (input) INTEGER */ /* The leading dimension of the matrix C. LDC >= max(1, M). */ /* D (input) COMPLEX array, dimension (LDD, M) */ /* On entry, D contains an upper triangular matrix. */ /* LDD (input) INTEGER */ /* The leading dimension of the matrix D. LDD >= max(1, M). */ /* E (input) COMPLEX array, dimension (LDE, N) */ /* On entry, E contains an upper triangular matrix. */ /* LDE (input) INTEGER */ /* The leading dimension of the matrix E. LDE >= max(1, N). */ /* F (input/output) COMPLEX array, dimension (LDF, N) */ /* On entry, F contains the right-hand-side of the second matrix */ /* equation in (1). */ /* On exit, if IJOB = 0, F has been overwritten by the solution */ /* L. */ /* LDF (input) INTEGER */ /* The leading dimension of the matrix F. LDF >= max(1, M). */ /* SCALE (output) REAL */ /* On exit, 0 <= SCALE <= 1. If 0 < SCALE < 1, the solutions */ /* R and L (C and F on entry) will hold the solutions to a */ /* slightly perturbed system but the input matrices A, B, D and */ /* E have not been changed. If SCALE = 0, R and L will hold the */ /* solutions to the homogeneous system with C = F = 0. */ /* Normally, SCALE = 1. */ /* RDSUM (input/output) REAL */ /* On entry, the sum of squares of computed contributions to */ /* the Dif-estimate under computation by CTGSYL, where the */ /* scaling factor RDSCAL (see below) has been factored out. */ /* On exit, the corresponding sum of squares updated with the */ /* contributions from the current sub-system. */ /* If TRANS = 'T' RDSUM is not touched. */ /* NOTE: RDSUM only makes sense when CTGSY2 is called by */ /* CTGSYL. */ /* RDSCAL (input/output) REAL */ /* On entry, scaling factor used to prevent overflow in RDSUM. */ /* On exit, RDSCAL is updated w.r.t. the current contributions */ /* in RDSUM. */ /* If TRANS = 'T', RDSCAL is not touched. */ /* NOTE: RDSCAL only makes sense when CTGSY2 is called by */ /* CTGSYL. */ /* INFO (output) INTEGER */ /* On exit, if INFO is set to */ /* =0: Successful exit */ /* <0: If INFO = -i, input argument number i is illegal. */ /* >0: The matrix pairs (A, D) and (B, E) have common or very */ /* close eigenvalues. */ /* Further Details */ /* =============== */ /* Based on contributions by */ /* Bo Kagstrom and Peter Poromaa, Department of Computing Science, */ /* Umea University, S-901 87 Umea, Sweden. */ /* ===================================================================== */ /* Decode and test input parameters */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1; c__ -= c_offset; d_dim1 = *ldd; d_offset = 1 + d_dim1; d__ -= d_offset; e_dim1 = *lde; e_offset = 1 + e_dim1; e -= e_offset; f_dim1 = *ldf; f_offset = 1 + f_dim1; f -= f_offset; /* Function Body */ *info = 0; ierr = 0; notran = lsame_(trans, "N"); if (! notran && ! lsame_(trans, "C")) { *info = -1; } else if (notran) { if (*ijob < 0 || *ijob > 2) { *info = -2; } } if (*info == 0) { if (*m <= 0) { *info = -3; } else if (*n <= 0) { *info = -4; } else if (*lda < max(1,*m)) { *info = -5; } else if (*ldb < max(1,*n)) { *info = -8; } else if (*ldc < max(1,*m)) { *info = -10; } else if (*ldd < max(1,*m)) { *info = -12; } else if (*lde < max(1,*n)) { *info = -14; } else if (*ldf < max(1,*m)) { *info = -16; } } if (*info != 0) { i__1 = -(*info); xerbla_("CTGSY2", &i__1); return 0; } if (notran) { /* Solve (I, J) - system */ /* A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J) */ /* D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J) */ *scale = 1.f; scaloc = 1.f; i__1 = *n; for (j = 1; j <= i__1; ++j) { for (i__ = *m; i__ >= 1; --i__) { /* Build 2 by 2 system */ i__2 = i__ + i__ * a_dim1; z__[0].r = a[i__2].r, z__[0].i = a[i__2].i; i__2 = i__ + i__ * d_dim1; z__[1].r = d__[i__2].r, z__[1].i = d__[i__2].i; i__2 = j + j * b_dim1; q__1.r = -b[i__2].r, q__1.i = -b[i__2].i; z__[2].r = q__1.r, z__[2].i = q__1.i; i__2 = j + j * e_dim1; q__1.r = -e[i__2].r, q__1.i = -e[i__2].i; z__[3].r = q__1.r, z__[3].i = q__1.i; /* Set up right hand side(s) */ i__2 = i__ + j * c_dim1; rhs[0].r = c__[i__2].r, rhs[0].i = c__[i__2].i; i__2 = i__ + j * f_dim1; rhs[1].r = f[i__2].r, rhs[1].i = f[i__2].i; /* Solve Z * x = RHS */ cgetc2_(&c__2, z__, &c__2, ipiv, jpiv, &ierr); if (ierr > 0) { *info = ierr; } if (*ijob == 0) { cgesc2_(&c__2, z__, &c__2, rhs, ipiv, jpiv, &scaloc); if (scaloc != 1.f) { i__2 = *n; for (k = 1; k <= i__2; ++k) { q__1.r = scaloc, q__1.i = 0.f; cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1); q__1.r = scaloc, q__1.i = 0.f; cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1); } *scale *= scaloc; } } else { clatdf_(ijob, &c__2, z__, &c__2, rhs, rdsum, rdscal, ipiv, jpiv); } /* Unpack solution vector(s) */ i__2 = i__ + j * c_dim1; c__[i__2].r = rhs[0].r, c__[i__2].i = rhs[0].i; i__2 = i__ + j * f_dim1; f[i__2].r = rhs[1].r, f[i__2].i = rhs[1].i; /* Substitute R(I, J) and L(I, J) into remaining equation. */ if (i__ > 1) { q__1.r = -rhs[0].r, q__1.i = -rhs[0].i; alpha.r = q__1.r, alpha.i = q__1.i; i__2 = i__ - 1; caxpy_(&i__2, &alpha, &a[i__ * a_dim1 + 1], &c__1, &c__[j * c_dim1 + 1], &c__1); i__2 = i__ - 1; caxpy_(&i__2, &alpha, &d__[i__ * d_dim1 + 1], &c__1, &f[j * f_dim1 + 1], &c__1); } if (j < *n) { i__2 = *n - j; caxpy_(&i__2, &rhs[1], &b[j + (j + 1) * b_dim1], ldb, & c__[i__ + (j + 1) * c_dim1], ldc); i__2 = *n - j; caxpy_(&i__2, &rhs[1], &e[j + (j + 1) * e_dim1], lde, &f[ i__ + (j + 1) * f_dim1], ldf); } } } } else { /* Solve transposed (I, J) - system: */ /* A(I, I)' * R(I, J) + D(I, I)' * L(J, J) = C(I, J) */ /* R(I, I) * B(J, J) + L(I, J) * E(J, J) = -F(I, J) */ *scale = 1.f; scaloc = 1.f; i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { for (j = *n; j >= 1; --j) { /* Build 2 by 2 system Z' */ r_cnjg(&q__1, &a[i__ + i__ * a_dim1]); z__[0].r = q__1.r, z__[0].i = q__1.i; r_cnjg(&q__2, &b[j + j * b_dim1]); q__1.r = -q__2.r, q__1.i = -q__2.i; z__[1].r = q__1.r, z__[1].i = q__1.i; r_cnjg(&q__1, &d__[i__ + i__ * d_dim1]); z__[2].r = q__1.r, z__[2].i = q__1.i; r_cnjg(&q__2, &e[j + j * e_dim1]); q__1.r = -q__2.r, q__1.i = -q__2.i; z__[3].r = q__1.r, z__[3].i = q__1.i; /* Set up right hand side(s) */ i__2 = i__ + j * c_dim1; rhs[0].r = c__[i__2].r, rhs[0].i = c__[i__2].i; i__2 = i__ + j * f_dim1; rhs[1].r = f[i__2].r, rhs[1].i = f[i__2].i; /* Solve Z' * x = RHS */ cgetc2_(&c__2, z__, &c__2, ipiv, jpiv, &ierr); if (ierr > 0) { *info = ierr; } cgesc2_(&c__2, z__, &c__2, rhs, ipiv, jpiv, &scaloc); if (scaloc != 1.f) { i__2 = *n; for (k = 1; k <= i__2; ++k) { q__1.r = scaloc, q__1.i = 0.f; cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1); q__1.r = scaloc, q__1.i = 0.f; cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1); } *scale *= scaloc; } /* Unpack solution vector(s) */ i__2 = i__ + j * c_dim1; c__[i__2].r = rhs[0].r, c__[i__2].i = rhs[0].i; i__2 = i__ + j * f_dim1; f[i__2].r = rhs[1].r, f[i__2].i = rhs[1].i; /* Substitute R(I, J) and L(I, J) into remaining equation. */ i__2 = j - 1; for (k = 1; k <= i__2; ++k) { i__3 = i__ + k * f_dim1; i__4 = i__ + k * f_dim1; r_cnjg(&q__4, &b[k + j * b_dim1]); q__3.r = rhs[0].r * q__4.r - rhs[0].i * q__4.i, q__3.i = rhs[0].r * q__4.i + rhs[0].i * q__4.r; q__2.r = f[i__4].r + q__3.r, q__2.i = f[i__4].i + q__3.i; r_cnjg(&q__6, &e[k + j * e_dim1]); q__5.r = rhs[1].r * q__6.r - rhs[1].i * q__6.i, q__5.i = rhs[1].r * q__6.i + rhs[1].i * q__6.r; q__1.r = q__2.r + q__5.r, q__1.i = q__2.i + q__5.i; f[i__3].r = q__1.r, f[i__3].i = q__1.i; } i__2 = *m; for (k = i__ + 1; k <= i__2; ++k) { i__3 = k + j * c_dim1; i__4 = k + j * c_dim1; r_cnjg(&q__4, &a[i__ + k * a_dim1]); q__3.r = q__4.r * rhs[0].r - q__4.i * rhs[0].i, q__3.i = q__4.r * rhs[0].i + q__4.i * rhs[0].r; q__2.r = c__[i__4].r - q__3.r, q__2.i = c__[i__4].i - q__3.i; r_cnjg(&q__6, &d__[i__ + k * d_dim1]); q__5.r = q__6.r * rhs[1].r - q__6.i * rhs[1].i, q__5.i = q__6.r * rhs[1].i + q__6.i * rhs[1].r; q__1.r = q__2.r - q__5.r, q__1.i = q__2.i - q__5.i; c__[i__3].r = q__1.r, c__[i__3].i = q__1.i; } } } } return 0; /* End of CTGSY2 */ } /* ctgsy2_ */
/* Subroutine */ int cher_(char *uplo, integer *n, real *alpha, complex *x, integer *incx, complex *a, integer *lda) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; real r__1; complex q__1, q__2; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ integer i__, j, ix, jx, kx, info; complex temp; extern logical lsame_(char *, char *); extern /* Subroutine */ int xerbla_(char *, integer *); /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CHER performs the hermitian rank 1 operation */ /* A := alpha*x*conjg( x' ) + A, */ /* where alpha is a real scalar, x is an n element vector and A is an */ /* n by n hermitian matrix. */ /* Arguments */ /* ========== */ /* UPLO - CHARACTER*1. */ /* On entry, UPLO specifies whether the upper or lower */ /* triangular part of the array A is to be referenced as */ /* follows: */ /* UPLO = 'U' or 'u' Only the upper triangular part of A */ /* is to be referenced. */ /* UPLO = 'L' or 'l' Only the lower triangular part of A */ /* is to be referenced. */ /* Unchanged on exit. */ /* N - INTEGER. */ /* On entry, N specifies the order of the matrix A. */ /* N must be at least zero. */ /* Unchanged on exit. */ /* ALPHA - REAL . */ /* On entry, ALPHA specifies the scalar alpha. */ /* Unchanged on exit. */ /* X - COMPLEX array of dimension at least */ /* ( 1 + ( n - 1 )*abs( INCX ) ). */ /* Before entry, the incremented array X must contain the n */ /* element vector x. */ /* Unchanged on exit. */ /* INCX - INTEGER. */ /* On entry, INCX specifies the increment for the elements of */ /* X. INCX must not be zero. */ /* Unchanged on exit. */ /* A - COMPLEX array of DIMENSION ( LDA, n ). */ /* Before entry with UPLO = 'U' or 'u', the leading n by n */ /* upper triangular part of the array A must contain the upper */ /* triangular part of the hermitian matrix and the strictly */ /* lower triangular part of A is not referenced. On exit, the */ /* upper triangular part of the array A is overwritten by the */ /* upper triangular part of the updated matrix. */ /* Before entry with UPLO = 'L' or 'l', the leading n by n */ /* lower triangular part of the array A must contain the lower */ /* triangular part of the hermitian matrix and the strictly */ /* upper triangular part of A is not referenced. On exit, the */ /* lower triangular part of the array A is overwritten by the */ /* lower triangular part of the updated matrix. */ /* Note that the imaginary parts of the diagonal elements need */ /* not be set, they are assumed to be zero, and on exit they */ /* are set to zero. */ /* LDA - INTEGER. */ /* On entry, LDA specifies the first dimension of A as declared */ /* in the calling (sub) program. LDA must be at least */ /* max( 1, n ). */ /* Unchanged on exit. */ /* Level 2 Blas routine. */ /* -- Written on 22-October-1986. */ /* Jack Dongarra, Argonne National Lab. */ /* Jeremy Du Croz, Nag Central Office. */ /* Sven Hammarling, Nag Central Office. */ /* Richard Hanson, Sandia National Labs. */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* Test the input parameters. */ /* Parameter adjustments */ --x; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; /* Function Body */ info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*incx == 0) { info = 5; } else if (*lda < max(1,*n)) { info = 7; } if (info != 0) { xerbla_("CHER ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || *alpha == 0.f) { return 0; } /* Set the start point in X if the increment is not unity. */ if (*incx <= 0) { kx = 1 - (*n - 1) * *incx; } else if (*incx != 1) { kx = 1; } /* Start the operations. In this version the elements of A are */ /* accessed sequentially with one pass through the triangular part */ /* of A. */ if (lsame_(uplo, "U")) { /* Form A when A is stored in upper triangle. */ if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[j]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * a_dim1; i__4 = i__ + j * a_dim1; i__5 = i__; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = a[i__4].r + q__2.r, q__1.i = a[i__4].i + q__2.i; a[i__3].r = q__1.r, a[i__3].i = q__1.i; /* L10: */ } i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; i__4 = j; q__1.r = x[i__4].r * temp.r - x[i__4].i * temp.i, q__1.i = x[i__4].r * temp.i + x[i__4].i * temp.r; r__1 = a[i__3].r + q__1.r; a[i__2].r = r__1, a[i__2].i = 0.f; } else { i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; r__1 = a[i__3].r; a[i__2].r = r__1, a[i__2].i = 0.f; } /* L20: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[jx]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; ix = kx; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * a_dim1; i__4 = i__ + j * a_dim1; i__5 = ix; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = a[i__4].r + q__2.r, q__1.i = a[i__4].i + q__2.i; a[i__3].r = q__1.r, a[i__3].i = q__1.i; ix += *incx; /* L30: */ } i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; i__4 = jx; q__1.r = x[i__4].r * temp.r - x[i__4].i * temp.i, q__1.i = x[i__4].r * temp.i + x[i__4].i * temp.r; r__1 = a[i__3].r + q__1.r; a[i__2].r = r__1, a[i__2].i = 0.f; } else { i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; r__1 = a[i__3].r; a[i__2].r = r__1, a[i__2].i = 0.f; } jx += *incx; /* L40: */ } } } else { /* Form A when A is stored in lower triangle. */ if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[j]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; i__4 = j; q__1.r = temp.r * x[i__4].r - temp.i * x[i__4].i, q__1.i = temp.r * x[i__4].i + temp.i * x[i__4].r; r__1 = a[i__3].r + q__1.r; a[i__2].r = r__1, a[i__2].i = 0.f; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { i__3 = i__ + j * a_dim1; i__4 = i__ + j * a_dim1; i__5 = i__; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = a[i__4].r + q__2.r, q__1.i = a[i__4].i + q__2.i; a[i__3].r = q__1.r, a[i__3].i = q__1.i; /* L50: */ } } else { i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; r__1 = a[i__3].r; a[i__2].r = r__1, a[i__2].i = 0.f; } /* L60: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; if (x[i__2].r != 0.f || x[i__2].i != 0.f) { r_cnjg(&q__2, &x[jx]); q__1.r = *alpha * q__2.r, q__1.i = *alpha * q__2.i; temp.r = q__1.r, temp.i = q__1.i; i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; i__4 = jx; q__1.r = temp.r * x[i__4].r - temp.i * x[i__4].i, q__1.i = temp.r * x[i__4].i + temp.i * x[i__4].r; r__1 = a[i__3].r + q__1.r; a[i__2].r = r__1, a[i__2].i = 0.f; ix = jx; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { ix += *incx; i__3 = i__ + j * a_dim1; i__4 = i__ + j * a_dim1; i__5 = ix; q__2.r = x[i__5].r * temp.r - x[i__5].i * temp.i, q__2.i = x[i__5].r * temp.i + x[i__5].i * temp.r; q__1.r = a[i__4].r + q__2.r, q__1.i = a[i__4].i + q__2.i; a[i__3].r = q__1.r, a[i__3].i = q__1.i; /* L70: */ } } else { i__2 = j + j * a_dim1; i__3 = j + j * a_dim1; r__1 = a[i__3].r; a[i__2].r = r__1, a[i__2].i = 0.f; } jx += *incx; /* L80: */ } } } return 0; /* End of CHER . */ } /* cher_ */
/* Subroutine */ int ctgevc_(char *side, char *howmny, logical *select, integer *n, complex *s, integer *lds, complex *p, integer *ldp, complex *vl, integer *ldvl, complex *vr, integer *ldvr, integer *mm, integer *m, complex *work, real *rwork, integer *info) { /* System generated locals */ integer p_dim1, p_offset, s_dim1, s_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3, i__4, i__5; real r__1, r__2, r__3, r__4, r__5, r__6; complex q__1, q__2, q__3, q__4; /* Builtin functions */ double r_imag(complex *); void r_cnjg(complex *, complex *); /* Local variables */ complex d__; integer i__, j; complex ca, cb; integer je, im, jr; real big; logical lsa, lsb; real ulp; complex sum; integer ibeg, ieig, iend; real dmin__; integer isrc; real temp; complex suma, sumb; real xmax, scale; logical ilall; integer iside; real sbeta; extern logical lsame_(char *, char *); extern /* Subroutine */ int cgemv_(char *, integer *, integer *, complex * , complex *, integer *, complex *, integer *, complex *, complex * , integer *); real small; logical compl; real anorm, bnorm; logical compr, ilbbad; real acoefa, bcoefa, acoeff; complex bcoeff; logical ilback; extern /* Subroutine */ int slabad_(real *, real *); real ascale, bscale; extern /* Complex */ VOID cladiv_(complex *, complex *, complex *); extern real slamch_(char *); complex salpha; real safmin; extern /* Subroutine */ int xerbla_(char *, integer *); real bignum; logical ilcomp; integer ihwmny; /* -- 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 Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Statement Functions .. */ /* .. */ /* .. Statement Function definitions .. */ /* .. */ /* .. Executable Statements .. */ /* Decode and Test the input parameters */ /* Parameter adjustments */ --select; s_dim1 = *lds; s_offset = 1 + s_dim1; s -= s_offset; p_dim1 = *ldp; p_offset = 1 + p_dim1; p -= p_offset; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1; vr -= vr_offset; --work; --rwork; /* Function Body */ if (lsame_(howmny, "A")) { ihwmny = 1; ilall = TRUE_; ilback = FALSE_; } else if (lsame_(howmny, "S")) { ihwmny = 2; ilall = FALSE_; ilback = FALSE_; } else if (lsame_(howmny, "B")) { ihwmny = 3; ilall = TRUE_; ilback = TRUE_; } else { ihwmny = -1; } if (lsame_(side, "R")) { iside = 1; compl = FALSE_; compr = TRUE_; } else if (lsame_(side, "L")) { iside = 2; compl = TRUE_; compr = FALSE_; } else if (lsame_(side, "B")) { iside = 3; compl = TRUE_; compr = TRUE_; } else { iside = -1; } *info = 0; if (iside < 0) { *info = -1; } else if (ihwmny < 0) { *info = -2; } else if (*n < 0) { *info = -4; } else if (*lds < max(1,*n)) { *info = -6; } else if (*ldp < max(1,*n)) { *info = -8; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGEVC", &i__1); return 0; } /* Count the number of eigenvectors */ if (! ilall) { im = 0; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (select[j]) { ++im; } /* L10: */ } } else { im = *n; } /* Check diagonal of B */ ilbbad = FALSE_; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (r_imag(&p[j + j * p_dim1]) != 0.f) { ilbbad = TRUE_; } /* L20: */ } if (ilbbad) { *info = -7; } else if (compl && *ldvl < *n || *ldvl < 1) { *info = -10; } else if (compr && *ldvr < *n || *ldvr < 1) { *info = -12; } else if (*mm < im) { *info = -13; } if (*info != 0) { i__1 = -(*info); xerbla_("CTGEVC", &i__1); return 0; } /* Quick return if possible */ *m = im; if (*n == 0) { return 0; } /* Machine Constants */ safmin = slamch_("Safe minimum"); big = 1.f / safmin; slabad_(&safmin, &big); ulp = slamch_("Epsilon") * slamch_("Base"); small = safmin * *n / ulp; big = 1.f / small; bignum = 1.f / (safmin * *n); /* Compute the 1-norm of each column of the strictly upper triangular */ /* part of A and B to check for possible overflow in the triangular */ /* solver. */ i__1 = s_dim1 + 1; anorm = (r__1 = s[i__1].r, abs(r__1)) + (r__2 = r_imag(&s[s_dim1 + 1]), abs(r__2)); i__1 = p_dim1 + 1; bnorm = (r__1 = p[i__1].r, abs(r__1)) + (r__2 = r_imag(&p[p_dim1 + 1]), abs(r__2)); rwork[1] = 0.f; rwork[*n + 1] = 0.f; i__1 = *n; for (j = 2; j <= i__1; ++j) { rwork[j] = 0.f; rwork[*n + j] = 0.f; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * s_dim1; rwork[j] += (r__1 = s[i__3].r, abs(r__1)) + (r__2 = r_imag(&s[i__ + j * s_dim1]), abs(r__2)); i__3 = i__ + j * p_dim1; rwork[*n + j] += (r__1 = p[i__3].r, abs(r__1)) + (r__2 = r_imag(& p[i__ + j * p_dim1]), abs(r__2)); /* L30: */ } /* Computing MAX */ i__2 = j + j * s_dim1; r__3 = anorm; r__4 = rwork[j] + ((r__1 = s[i__2].r, abs(r__1)) + ( r__2 = r_imag(&s[j + j * s_dim1]), abs(r__2))); // , expr subst anorm = max(r__3,r__4); /* Computing MAX */ i__2 = j + j * p_dim1; r__3 = bnorm; r__4 = rwork[*n + j] + ((r__1 = p[i__2].r, abs(r__1)) + (r__2 = r_imag(&p[j + j * p_dim1]), abs(r__2))); // , expr subst bnorm = max(r__3,r__4); /* L40: */ } ascale = 1.f / max(anorm,safmin); bscale = 1.f / max(bnorm,safmin); /* Left eigenvectors */ if (compl) { ieig = 0; /* Main loop over eigenvalues */ i__1 = *n; for (je = 1; je <= i__1; ++je) { if (ilall) { ilcomp = TRUE_; } else { ilcomp = select[je]; } if (ilcomp) { ++ieig; i__2 = je + je * s_dim1; i__3 = je + je * p_dim1; if ((r__2 = s[i__2].r, abs(r__2)) + (r__3 = r_imag(&s[je + je * s_dim1]), abs(r__3)) <= safmin && (r__1 = p[i__3].r, abs(r__1)) <= safmin) { /* Singular matrix pencil -- return unit eigenvector */ i__2 = *n; for (jr = 1; jr <= i__2; ++jr) { i__3 = jr + ieig * vl_dim1; vl[i__3].r = 0.f; vl[i__3].i = 0.f; // , expr subst /* L50: */ } i__2 = ieig + ieig * vl_dim1; vl[i__2].r = 1.f; vl[i__2].i = 0.f; // , expr subst goto L140; } /* Non-singular eigenvalue: */ /* Compute coefficients a and b in */ /* H */ /* y ( a A - b B ) = 0 */ /* Computing MAX */ i__2 = je + je * s_dim1; i__3 = je + je * p_dim1; r__4 = ((r__2 = s[i__2].r, abs(r__2)) + (r__3 = r_imag(&s[je + je * s_dim1]), abs(r__3))) * ascale; r__5 = (r__1 = p[i__3].r, abs(r__1)) * bscale; r__4 = max(r__4,r__5); // ; expr subst temp = 1.f / max(r__4,safmin); i__2 = je + je * s_dim1; q__2.r = temp * s[i__2].r; q__2.i = temp * s[i__2].i; // , expr subst q__1.r = ascale * q__2.r; q__1.i = ascale * q__2.i; // , expr subst salpha.r = q__1.r; salpha.i = q__1.i; // , expr subst i__2 = je + je * p_dim1; sbeta = temp * p[i__2].r * bscale; acoeff = sbeta * ascale; q__1.r = bscale * salpha.r; q__1.i = bscale * salpha.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst /* Scale to avoid underflow */ lsa = abs(sbeta) >= safmin && abs(acoeff) < small; lsb = (r__1 = salpha.r, abs(r__1)) + (r__2 = r_imag(&salpha), abs(r__2)) >= safmin && (r__3 = bcoeff.r, abs(r__3)) + (r__4 = r_imag(&bcoeff), abs(r__4)) < small; scale = 1.f; if (lsa) { scale = small / abs(sbeta) * min(anorm,big); } if (lsb) { /* Computing MAX */ r__3 = scale; r__4 = small / ((r__1 = salpha.r, abs(r__1)) + (r__2 = r_imag(&salpha), abs(r__2))) * min( bnorm,big); // , expr subst scale = max(r__3,r__4); } if (lsa || lsb) { /* Computing MIN */ /* Computing MAX */ r__5 = 1.f, r__6 = abs(acoeff); r__5 = max(r__5,r__6); r__6 = (r__1 = bcoeff.r, abs(r__1)) + (r__2 = r_imag(&bcoeff), abs(r__2)); // ; expr subst r__3 = scale; r__4 = 1.f / (safmin * max(r__5,r__6)); // , expr subst scale = min(r__3,r__4); if (lsa) { acoeff = ascale * (scale * sbeta); } else { acoeff = scale * acoeff; } if (lsb) { q__2.r = scale * salpha.r; q__2.i = scale * salpha.i; // , expr subst q__1.r = bscale * q__2.r; q__1.i = bscale * q__2.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst } else { q__1.r = scale * bcoeff.r; q__1.i = scale * bcoeff.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst } } acoefa = abs(acoeff); bcoefa = (r__1 = bcoeff.r, abs(r__1)) + (r__2 = r_imag(& bcoeff), abs(r__2)); xmax = 1.f; i__2 = *n; for (jr = 1; jr <= i__2; ++jr) { i__3 = jr; work[i__3].r = 0.f; work[i__3].i = 0.f; // , expr subst /* L60: */ } i__2 = je; work[i__2].r = 1.f; work[i__2].i = 0.f; // , expr subst /* Computing MAX */ r__1 = ulp * acoefa * anorm; r__2 = ulp * bcoefa * bnorm; r__1 = max(r__1,r__2); // ; expr subst dmin__ = max(r__1,safmin); /* H */ /* Triangular solve of (a A - b B) y = 0 */ /* H */ /* (rowwise in (a A - b B) , or columnwise in a A - b B) */ i__2 = *n; for (j = je + 1; j <= i__2; ++j) { /* Compute */ /* j-1 */ /* SUM = sum conjg( a*S(k,j) - b*P(k,j) )*x(k) */ /* k=je */ /* (Scale if necessary) */ temp = 1.f / xmax; if (acoefa * rwork[j] + bcoefa * rwork[*n + j] > bignum * temp) { i__3 = j - 1; for (jr = je; jr <= i__3; ++jr) { i__4 = jr; i__5 = jr; q__1.r = temp * work[i__5].r; q__1.i = temp * work[i__5].i; // , expr subst work[i__4].r = q__1.r; work[i__4].i = q__1.i; // , expr subst /* L70: */ } xmax = 1.f; } suma.r = 0.f; suma.i = 0.f; // , expr subst sumb.r = 0.f; sumb.i = 0.f; // , expr subst i__3 = j - 1; for (jr = je; jr <= i__3; ++jr) { r_cnjg(&q__3, &s[jr + j * s_dim1]); i__4 = jr; q__2.r = q__3.r * work[i__4].r - q__3.i * work[i__4] .i; q__2.i = q__3.r * work[i__4].i + q__3.i * work[i__4].r; // , expr subst q__1.r = suma.r + q__2.r; q__1.i = suma.i + q__2.i; // , expr subst suma.r = q__1.r; suma.i = q__1.i; // , expr subst r_cnjg(&q__3, &p[jr + j * p_dim1]); i__4 = jr; q__2.r = q__3.r * work[i__4].r - q__3.i * work[i__4] .i; q__2.i = q__3.r * work[i__4].i + q__3.i * work[i__4].r; // , expr subst q__1.r = sumb.r + q__2.r; q__1.i = sumb.i + q__2.i; // , expr subst sumb.r = q__1.r; sumb.i = q__1.i; // , expr subst /* L80: */ } q__2.r = acoeff * suma.r; q__2.i = acoeff * suma.i; // , expr subst r_cnjg(&q__4, &bcoeff); q__3.r = q__4.r * sumb.r - q__4.i * sumb.i; q__3.i = q__4.r * sumb.i + q__4.i * sumb.r; // , expr subst q__1.r = q__2.r - q__3.r; q__1.i = q__2.i - q__3.i; // , expr subst sum.r = q__1.r; sum.i = q__1.i; // , expr subst /* Form x(j) = - SUM / conjg( a*S(j,j) - b*P(j,j) ) */ /* with scaling and perturbation of the denominator */ i__3 = j + j * s_dim1; q__3.r = acoeff * s[i__3].r; q__3.i = acoeff * s[i__3].i; // , expr subst i__4 = j + j * p_dim1; q__4.r = bcoeff.r * p[i__4].r - bcoeff.i * p[i__4].i; q__4.i = bcoeff.r * p[i__4].i + bcoeff.i * p[i__4] .r; // , expr subst q__2.r = q__3.r - q__4.r; q__2.i = q__3.i - q__4.i; // , expr subst r_cnjg(&q__1, &q__2); d__.r = q__1.r; d__.i = q__1.i; // , expr subst if ((r__1 = d__.r, abs(r__1)) + (r__2 = r_imag(&d__), abs( r__2)) <= dmin__) { q__1.r = dmin__; q__1.i = 0.f; // , expr subst d__.r = q__1.r; d__.i = q__1.i; // , expr subst } if ((r__1 = d__.r, abs(r__1)) + (r__2 = r_imag(&d__), abs( r__2)) < 1.f) { if ((r__1 = sum.r, abs(r__1)) + (r__2 = r_imag(&sum), abs(r__2)) >= bignum * ((r__3 = d__.r, abs( r__3)) + (r__4 = r_imag(&d__), abs(r__4)))) { temp = 1.f / ((r__1 = sum.r, abs(r__1)) + (r__2 = r_imag(&sum), abs(r__2))); i__3 = j - 1; for (jr = je; jr <= i__3; ++jr) { i__4 = jr; i__5 = jr; q__1.r = temp * work[i__5].r; q__1.i = temp * work[i__5].i; // , expr subst work[i__4].r = q__1.r; work[i__4].i = q__1.i; // , expr subst /* L90: */ } xmax = temp * xmax; q__1.r = temp * sum.r; q__1.i = temp * sum.i; // , expr subst sum.r = q__1.r; sum.i = q__1.i; // , expr subst } } i__3 = j; q__2.r = -sum.r; q__2.i = -sum.i; // , expr subst cladiv_(&q__1, &q__2, &d__); work[i__3].r = q__1.r; work[i__3].i = q__1.i; // , expr subst /* Computing MAX */ i__3 = j; r__3 = xmax; r__4 = (r__1 = work[i__3].r, abs(r__1)) + ( r__2 = r_imag(&work[j]), abs(r__2)); // , expr subst xmax = max(r__3,r__4); /* L100: */ } /* Back transform eigenvector if HOWMNY='B'. */ if (ilback) { i__2 = *n + 1 - je; cgemv_("N", n, &i__2, &c_b2, &vl[je * vl_dim1 + 1], ldvl, &work[je], &c__1, &c_b1, &work[*n + 1], &c__1); isrc = 2; ibeg = 1; } else { isrc = 1; ibeg = je; } /* Copy and scale eigenvector into column of VL */ xmax = 0.f; i__2 = *n; for (jr = ibeg; jr <= i__2; ++jr) { /* Computing MAX */ i__3 = (isrc - 1) * *n + jr; r__3 = xmax; r__4 = (r__1 = work[i__3].r, abs(r__1)) + ( r__2 = r_imag(&work[(isrc - 1) * *n + jr]), abs( r__2)); // , expr subst xmax = max(r__3,r__4); /* L110: */ } if (xmax > safmin) { temp = 1.f / xmax; i__2 = *n; for (jr = ibeg; jr <= i__2; ++jr) { i__3 = jr + ieig * vl_dim1; i__4 = (isrc - 1) * *n + jr; q__1.r = temp * work[i__4].r; q__1.i = temp * work[ i__4].i; // , expr subst vl[i__3].r = q__1.r; vl[i__3].i = q__1.i; // , expr subst /* L120: */ } } else { ibeg = *n + 1; } i__2 = ibeg - 1; for (jr = 1; jr <= i__2; ++jr) { i__3 = jr + ieig * vl_dim1; vl[i__3].r = 0.f; vl[i__3].i = 0.f; // , expr subst /* L130: */ } } L140: ; } } /* Right eigenvectors */ if (compr) { ieig = im + 1; /* Main loop over eigenvalues */ for (je = *n; je >= 1; --je) { if (ilall) { ilcomp = TRUE_; } else { ilcomp = select[je]; } if (ilcomp) { --ieig; i__1 = je + je * s_dim1; i__2 = je + je * p_dim1; if ((r__2 = s[i__1].r, abs(r__2)) + (r__3 = r_imag(&s[je + je * s_dim1]), abs(r__3)) <= safmin && (r__1 = p[i__2].r, abs(r__1)) <= safmin) { /* Singular matrix pencil -- return unit eigenvector */ i__1 = *n; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr + ieig * vr_dim1; vr[i__2].r = 0.f; vr[i__2].i = 0.f; // , expr subst /* L150: */ } i__1 = ieig + ieig * vr_dim1; vr[i__1].r = 1.f; vr[i__1].i = 0.f; // , expr subst goto L250; } /* Non-singular eigenvalue: */ /* Compute coefficients a and b in */ /* ( a A - b B ) x = 0 */ /* Computing MAX */ i__1 = je + je * s_dim1; i__2 = je + je * p_dim1; r__4 = ((r__2 = s[i__1].r, abs(r__2)) + (r__3 = r_imag(&s[je + je * s_dim1]), abs(r__3))) * ascale; r__5 = (r__1 = p[i__2].r, abs(r__1)) * bscale; r__4 = max(r__4,r__5); // ; expr subst temp = 1.f / max(r__4,safmin); i__1 = je + je * s_dim1; q__2.r = temp * s[i__1].r; q__2.i = temp * s[i__1].i; // , expr subst q__1.r = ascale * q__2.r; q__1.i = ascale * q__2.i; // , expr subst salpha.r = q__1.r; salpha.i = q__1.i; // , expr subst i__1 = je + je * p_dim1; sbeta = temp * p[i__1].r * bscale; acoeff = sbeta * ascale; q__1.r = bscale * salpha.r; q__1.i = bscale * salpha.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst /* Scale to avoid underflow */ lsa = abs(sbeta) >= safmin && abs(acoeff) < small; lsb = (r__1 = salpha.r, abs(r__1)) + (r__2 = r_imag(&salpha), abs(r__2)) >= safmin && (r__3 = bcoeff.r, abs(r__3)) + (r__4 = r_imag(&bcoeff), abs(r__4)) < small; scale = 1.f; if (lsa) { scale = small / abs(sbeta) * min(anorm,big); } if (lsb) { /* Computing MAX */ r__3 = scale; r__4 = small / ((r__1 = salpha.r, abs(r__1)) + (r__2 = r_imag(&salpha), abs(r__2))) * min( bnorm,big); // , expr subst scale = max(r__3,r__4); } if (lsa || lsb) { /* Computing MIN */ /* Computing MAX */ r__5 = 1.f, r__6 = abs(acoeff); r__5 = max(r__5,r__6); r__6 = (r__1 = bcoeff.r, abs(r__1)) + (r__2 = r_imag(&bcoeff), abs(r__2)); // ; expr subst r__3 = scale; r__4 = 1.f / (safmin * max(r__5,r__6)); // , expr subst scale = min(r__3,r__4); if (lsa) { acoeff = ascale * (scale * sbeta); } else { acoeff = scale * acoeff; } if (lsb) { q__2.r = scale * salpha.r; q__2.i = scale * salpha.i; // , expr subst q__1.r = bscale * q__2.r; q__1.i = bscale * q__2.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst } else { q__1.r = scale * bcoeff.r; q__1.i = scale * bcoeff.i; // , expr subst bcoeff.r = q__1.r; bcoeff.i = q__1.i; // , expr subst } } acoefa = abs(acoeff); bcoefa = (r__1 = bcoeff.r, abs(r__1)) + (r__2 = r_imag(& bcoeff), abs(r__2)); xmax = 1.f; i__1 = *n; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr; work[i__2].r = 0.f; work[i__2].i = 0.f; // , expr subst /* L160: */ } i__1 = je; work[i__1].r = 1.f; work[i__1].i = 0.f; // , expr subst /* Computing MAX */ r__1 = ulp * acoefa * anorm; r__2 = ulp * bcoefa * bnorm; r__1 = max(r__1,r__2); // ; expr subst dmin__ = max(r__1,safmin); /* Triangular solve of (a A - b B) x = 0 (columnwise) */ /* WORK(1:j-1) contains sums w, */ /* WORK(j+1:JE) contains x */ i__1 = je - 1; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr; i__3 = jr + je * s_dim1; q__2.r = acoeff * s[i__3].r; q__2.i = acoeff * s[i__3].i; // , expr subst i__4 = jr + je * p_dim1; q__3.r = bcoeff.r * p[i__4].r - bcoeff.i * p[i__4].i; q__3.i = bcoeff.r * p[i__4].i + bcoeff.i * p[i__4] .r; // , expr subst q__1.r = q__2.r - q__3.r; q__1.i = q__2.i - q__3.i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst /* L170: */ } i__1 = je; work[i__1].r = 1.f; work[i__1].i = 0.f; // , expr subst for (j = je - 1; j >= 1; --j) { /* Form x(j) := - w(j) / d */ /* with scaling and perturbation of the denominator */ i__1 = j + j * s_dim1; q__2.r = acoeff * s[i__1].r; q__2.i = acoeff * s[i__1].i; // , expr subst i__2 = j + j * p_dim1; q__3.r = bcoeff.r * p[i__2].r - bcoeff.i * p[i__2].i; q__3.i = bcoeff.r * p[i__2].i + bcoeff.i * p[i__2] .r; // , expr subst q__1.r = q__2.r - q__3.r; q__1.i = q__2.i - q__3.i; // , expr subst d__.r = q__1.r; d__.i = q__1.i; // , expr subst if ((r__1 = d__.r, abs(r__1)) + (r__2 = r_imag(&d__), abs( r__2)) <= dmin__) { q__1.r = dmin__; q__1.i = 0.f; // , expr subst d__.r = q__1.r; d__.i = q__1.i; // , expr subst } if ((r__1 = d__.r, abs(r__1)) + (r__2 = r_imag(&d__), abs( r__2)) < 1.f) { i__1 = j; if ((r__1 = work[i__1].r, abs(r__1)) + (r__2 = r_imag( &work[j]), abs(r__2)) >= bignum * ((r__3 = d__.r, abs(r__3)) + (r__4 = r_imag(&d__), abs( r__4)))) { i__1 = j; temp = 1.f / ((r__1 = work[i__1].r, abs(r__1)) + ( r__2 = r_imag(&work[j]), abs(r__2))); i__1 = je; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr; i__3 = jr; q__1.r = temp * work[i__3].r; q__1.i = temp * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst /* L180: */ } } } i__1 = j; i__2 = j; q__2.r = -work[i__2].r; q__2.i = -work[i__2].i; // , expr subst cladiv_(&q__1, &q__2, &d__); work[i__1].r = q__1.r; work[i__1].i = q__1.i; // , expr subst if (j > 1) { /* w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling */ i__1 = j; if ((r__1 = work[i__1].r, abs(r__1)) + (r__2 = r_imag( &work[j]), abs(r__2)) > 1.f) { i__1 = j; temp = 1.f / ((r__1 = work[i__1].r, abs(r__1)) + ( r__2 = r_imag(&work[j]), abs(r__2))); if (acoefa * rwork[j] + bcoefa * rwork[*n + j] >= bignum * temp) { i__1 = je; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr; i__3 = jr; q__1.r = temp * work[i__3].r; q__1.i = temp * work[i__3].i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst /* L190: */ } } } i__1 = j; q__1.r = acoeff * work[i__1].r; q__1.i = acoeff * work[i__1].i; // , expr subst ca.r = q__1.r; ca.i = q__1.i; // , expr subst i__1 = j; q__1.r = bcoeff.r * work[i__1].r - bcoeff.i * work[ i__1].i; q__1.i = bcoeff.r * work[i__1].i + bcoeff.i * work[i__1].r; // , expr subst cb.r = q__1.r; cb.i = q__1.i; // , expr subst i__1 = j - 1; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr; i__3 = jr; i__4 = jr + j * s_dim1; q__3.r = ca.r * s[i__4].r - ca.i * s[i__4].i; q__3.i = ca.r * s[i__4].i + ca.i * s[i__4] .r; // , expr subst q__2.r = work[i__3].r + q__3.r; q__2.i = work[ i__3].i + q__3.i; // , expr subst i__5 = jr + j * p_dim1; q__4.r = cb.r * p[i__5].r - cb.i * p[i__5].i; q__4.i = cb.r * p[i__5].i + cb.i * p[i__5] .r; // , expr subst q__1.r = q__2.r - q__4.r; q__1.i = q__2.i - q__4.i; // , expr subst work[i__2].r = q__1.r; work[i__2].i = q__1.i; // , expr subst /* L200: */ } } /* L210: */ } /* Back transform eigenvector if HOWMNY='B'. */ if (ilback) { cgemv_("N", n, &je, &c_b2, &vr[vr_offset], ldvr, &work[1], &c__1, &c_b1, &work[*n + 1], &c__1); isrc = 2; iend = *n; } else { isrc = 1; iend = je; } /* Copy and scale eigenvector into column of VR */ xmax = 0.f; i__1 = iend; for (jr = 1; jr <= i__1; ++jr) { /* Computing MAX */ i__2 = (isrc - 1) * *n + jr; r__3 = xmax; r__4 = (r__1 = work[i__2].r, abs(r__1)) + ( r__2 = r_imag(&work[(isrc - 1) * *n + jr]), abs( r__2)); // , expr subst xmax = max(r__3,r__4); /* L220: */ } if (xmax > safmin) { temp = 1.f / xmax; i__1 = iend; for (jr = 1; jr <= i__1; ++jr) { i__2 = jr + ieig * vr_dim1; i__3 = (isrc - 1) * *n + jr; q__1.r = temp * work[i__3].r; q__1.i = temp * work[ i__3].i; // , expr subst vr[i__2].r = q__1.r; vr[i__2].i = q__1.i; // , expr subst /* L230: */ } } else { iend = 0; } i__1 = *n; for (jr = iend + 1; jr <= i__1; ++jr) { i__2 = jr + ieig * vr_dim1; vr[i__2].r = 0.f; vr[i__2].i = 0.f; // , expr subst /* L240: */ } } L250: ; } } return 0; /* End of CTGEVC */ }
/* Complex */ VOID cdotc_(complex * ret_val, int *n, complex *cx, int *incx, complex *cy, int *incy) { /* System generated locals */ int i__1, i__2; complex q__1, q__2, q__3; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ int i__, ix, iy; complex ctemp; /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* forms the dot product of two vectors, conjugating the first */ /* vector. */ /* Further Details */ /* =============== */ /* jack dongarra, linpack, 3/11/78. */ /* modified 12/3/93, array(1) declarations changed to array(*) */ /* .. Local Scalars .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* Parameter adjustments */ --cy; --cx; /* Function Body */ ctemp.r = 0.f, ctemp.i = 0.f; ret_val->r = 0.f, ret_val->i = 0.f; if (*n <= 0) { return ; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments */ /* not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (-(*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (-(*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { r_cnjg(&q__3, &cx[ix]); i__2 = iy; q__2.r = q__3.r * cy[i__2].r - q__3.i * cy[i__2].i, q__2.i = q__3.r * cy[i__2].i + q__3.i * cy[i__2].r; q__1.r = ctemp.r + q__2.r, q__1.i = ctemp.i + q__2.i; ctemp.r = q__1.r, ctemp.i = q__1.i; ix += *incx; iy += *incy; /* L10: */ } ret_val->r = ctemp.r, ret_val->i = ctemp.i; return ; /* code for both increments equal to 1 */ L20: i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { r_cnjg(&q__3, &cx[i__]); i__2 = i__; q__2.r = q__3.r * cy[i__2].r - q__3.i * cy[i__2].i, q__2.i = q__3.r * cy[i__2].i + q__3.i * cy[i__2].r; q__1.r = ctemp.r + q__2.r, q__1.i = ctemp.i + q__2.i; ctemp.r = q__1.r, ctemp.i = q__1.i; /* L30: */ } ret_val->r = ctemp.r, ret_val->i = ctemp.i; return ; } /* cdotc_ */
/* Complex */ VOID clatm2_slu(complex * ret_val, integer *m, integer *n, integer *i, integer *j, integer *kl, integer *ku, integer *idist, integer * iseed, complex *d, integer *igrade, complex *dl, complex *dr, integer *ipvtng, integer *iwork, real *sparse) { /* System generated locals */ integer i__1, i__2; complex q__1, q__2, q__3; /* Builtin functions */ void c_div(complex *, complex *, complex *), r_cnjg(complex *, complex *); /* Local variables */ static integer isub, jsub; static complex ctemp; extern /* Complex */ VOID clarnd_slu(complex *, integer *, integer *); extern doublereal dlaran_sluslu(integer *); /* -- LAPACK auxiliary test routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University February 29, 1992 Purpose ======= CLATM2 returns the (I,J) entry of a random matrix of dimension (M, N) described by the other paramters. It is called by the CLATMR routine in order to build random test matrices. No error checking on parameters is done, because this routine is called in a tight loop by CLATMR which has already checked the parameters. Use of CLATM2 differs from CLATM3 in the order in which the random number generator is called to fill in random matrix entries. With CLATM2, the generator is called to fill in the pivoted matrix columnwise. With CLATM3, the generator is called to fill in the matrix columnwise, after which it is pivoted. Thus, CLATM3 can be used to construct random matrices which differ only in their order of rows and/or columns. CLATM2 is used to construct band matrices while avoiding calling the random number generator for entries outside the band (and therefore generating random numbers The matrix whose (I,J) entry is returned is constructed as follows (this routine only computes one entry): If I is outside (1..M) or J is outside (1..N), return zero (this is convenient for generating matrices in band format). Generate a matrix A with random entries of distribution IDIST. Set the diagonal to D. Grade the matrix, if desired, from the left (by DL) and/or from the right (by DR or DL) as specified by IGRADE. Permute, if desired, the rows and/or columns as specified by IPVTNG and IWORK. Band the matrix to have lower bandwidth KL and upper bandwidth KU. Set random entries to zero as specified by SPARSE. Arguments ========= M - INTEGER Number of rows of matrix. Not modified. N - INTEGER Number of columns of matrix. Not modified. I - INTEGER Row of entry to be returned. Not modified. J - INTEGER Column of entry to be returned. Not modified. KL - INTEGER Lower bandwidth. Not modified. KU - INTEGER Upper bandwidth. Not modified. IDIST - INTEGER On entry, IDIST specifies the type of distribution to be used to generate a random matrix . 1 => real and imaginary parts each UNIFORM( 0, 1 ) 2 => real and imaginary parts each UNIFORM( -1, 1 ) 3 => real and imaginary parts each NORMAL( 0, 1 ) 4 => complex number uniform in DISK( 0 , 1 ) Not modified. ISEED - INTEGER array of dimension ( 4 ) Seed for random number generator. Changed on exit. D - COMPLEX array of dimension ( MIN( I , J ) ) Diagonal entries of matrix. Not modified. IGRADE - INTEGER Specifies grading of matrix as follows: 0 => no grading 1 => matrix premultiplied by diag( DL ) 2 => matrix postmultiplied by diag( DR ) 3 => matrix premultiplied by diag( DL ) and postmultiplied by diag( DR ) 4 => matrix premultiplied by diag( DL ) and postmultiplied by inv( diag( DL ) ) 5 => matrix premultiplied by diag( DL ) and postmultiplied by diag( CONJG(DL) ) 6 => matrix premultiplied by diag( DL ) and postmultiplied by diag( DL ) Not modified. DL - COMPLEX array ( I or J, as appropriate ) Left scale factors for grading matrix. Not modified. DR - COMPLEX array ( I or J, as appropriate ) Right scale factors for grading matrix. Not modified. IPVTNG - INTEGER On entry specifies pivoting permutations as follows: 0 => none. 1 => row pivoting. 2 => column pivoting. 3 => full pivoting, i.e., on both sides. Not modified. IWORK - INTEGER array ( I or J, as appropriate ) This array specifies the permutation used. The row (or column) in position K was originally in position IWORK( K ). This differs from IWORK for CLATM3. Not modified. SPARSE - REAL between 0. and 1. On entry specifies the sparsity of the matrix if sparse matix is to be generated. SPARSE should lie between 0 and 1. A uniform ( 0, 1 ) random number x is generated and compared to SPARSE; if x is larger the matrix entry is unchanged and if x is smaller the entry is set to zero. Thus on the average a fraction SPARSE of the entries will be set to zero. Not modified. ===================================================================== ----------------------------------------------------------------------- Check for I and J in range Parameter adjustments */ --iwork; --dr; --dl; --d; --iseed; /* Function Body */ if (*i < 1 || *i > *m || *j < 1 || *j > *n) { ret_val->r = 0.f, ret_val->i = 0.f; return ; } /* Check for banding */ if (*j > *i + *ku || *j < *i - *kl) { ret_val->r = 0.f, ret_val->i = 0.f; return ; } /* Check for sparsity */ if (*sparse > 0.f) { if (dlaran_sluslu(&iseed[1]) < *sparse) { ret_val->r = 0.f, ret_val->i = 0.f; return ; } } /* Compute subscripts depending on IPVTNG */ if (*ipvtng == 0) { isub = *i; jsub = *j; } else if (*ipvtng == 1) { isub = iwork[*i]; jsub = *j; } else if (*ipvtng == 2) { isub = *i; jsub = iwork[*j]; } else if (*ipvtng == 3) { isub = iwork[*i]; jsub = iwork[*j]; } /* Compute entry and grade it according to IGRADE */ if (isub == jsub) { i__1 = isub; ctemp.r = d[i__1].r, ctemp.i = d[i__1].i; } else { clarnd_slu(&q__1, idist, &iseed[1]); ctemp.r = q__1.r, ctemp.i = q__1.i; } if (*igrade == 1) { i__1 = isub; q__1.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__1.i = ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r; ctemp.r = q__1.r, ctemp.i = q__1.i; } else if (*igrade == 2) { i__1 = jsub; q__1.r = ctemp.r * dr[i__1].r - ctemp.i * dr[i__1].i, q__1.i = ctemp.r * dr[i__1].i + ctemp.i * dr[i__1].r; ctemp.r = q__1.r, ctemp.i = q__1.i; } else if (*igrade == 3) { i__1 = isub; q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r; i__2 = jsub; q__1.r = q__2.r * dr[i__2].r - q__2.i * dr[i__2].i, q__1.i = q__2.r * dr[i__2].i + q__2.i * dr[i__2].r; ctemp.r = q__1.r, ctemp.i = q__1.i; } else if (*igrade == 4 && isub != jsub) { i__1 = isub; q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r; c_div(&q__1, &q__2, &dl[jsub]); ctemp.r = q__1.r, ctemp.i = q__1.i; } else if (*igrade == 5) { i__1 = isub; q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r; r_cnjg(&q__3, &dl[jsub]); q__1.r = q__2.r * q__3.r - q__2.i * q__3.i, q__1.i = q__2.r * q__3.i + q__2.i * q__3.r; ctemp.r = q__1.r, ctemp.i = q__1.i; } else if (*igrade == 6) { i__1 = isub; q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r; i__2 = jsub; q__1.r = q__2.r * dl[i__2].r - q__2.i * dl[i__2].i, q__1.i = q__2.r * dl[i__2].i + q__2.i * dl[i__2].r; ctemp.r = q__1.r, ctemp.i = q__1.i; } ret_val->r = ctemp.r, ret_val->i = ctemp.i; return ; /* End of CLATM2 */ } /* clatm2_slu */
/* Subroutine */ int chpmv_(char *uplo, integer *n, complex *alpha, complex * ap, complex *x, integer *incx, complex *beta, complex *y, integer * incy) { /* System generated locals */ integer i__1, i__2, i__3, i__4, i__5; real r__1; complex q__1, q__2, q__3, q__4; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer info; static complex temp1, temp2; static integer i__, j, k; extern logical lsame_(char *, char *); static integer kk, ix, iy, jx, jy, kx, ky; extern /* Subroutine */ int xerbla_(char *, integer *); /* Purpose ======= CHPMV performs the matrix-vector operation y := alpha*A*x + beta*y, where alpha and beta are scalars, x and y are n element vectors and A is an n by n hermitian matrix, supplied in packed form. Parameters ========== UPLO - CHARACTER*1. On entry, UPLO specifies whether the upper or lower triangular part of the matrix A is supplied in the packed array AP as follows: UPLO = 'U' or 'u' The upper triangular part of A is supplied in AP. UPLO = 'L' or 'l' The lower triangular part of A is supplied in AP. Unchanged on exit. N - INTEGER. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - COMPLEX . On entry, ALPHA specifies the scalar alpha. Unchanged on exit. AP - COMPLEX array of DIMENSION at least ( ( n*( n + 1 ) )/2 ). Before entry with UPLO = 'U' or 'u', the array AP must contain the upper triangular part of the hermitian matrix packed sequentially, column by column, so that AP( 1 ) contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 ) respectively, and so on. Before entry with UPLO = 'L' or 'l', the array AP must contain the lower triangular part of the hermitian matrix packed sequentially, column by column, so that AP( 1 ) contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 ) respectively, and so on. Note that the imaginary parts of the diagonal elements need not be set and are assumed to be zero. Unchanged on exit. X - COMPLEX array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. Unchanged on exit. INCX - INTEGER. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. BETA - COMPLEX . On entry, BETA specifies the scalar beta. When BETA is supplied as zero then Y need not be set on input. Unchanged on exit. Y - COMPLEX array of dimension at least ( 1 + ( n - 1 )*abs( INCY ) ). Before entry, the incremented array Y must contain the n element vector y. On exit, Y is overwritten by the updated vector y. INCY - INTEGER. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. Test the input parameters. Parameter adjustments */ --y; --x; --ap; /* Function Body */ info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*incx == 0) { info = 6; } else if (*incy == 0) { info = 9; } if (info != 0) { xerbla_("CHPMV ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || alpha->r == 0.f && alpha->i == 0.f && (beta->r == 1.f && beta->i == 0.f)) { return 0; } /* Set up the start points in X and Y. */ if (*incx > 0) { kx = 1; } else { kx = 1 - (*n - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (*n - 1) * *incy; } /* Start the operations. In this version the elements of the array AP are accessed sequentially with one pass through AP. First form y := beta*y. */ if (beta->r != 1.f || beta->i != 0.f) { if (*incy == 1) { if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; y[i__2].r = 0.f, y[i__2].i = 0.f; /* L10: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; q__1.r = beta->r * y[i__3].r - beta->i * y[i__3].i, q__1.i = beta->r * y[i__3].i + beta->i * y[i__3] .r; y[i__2].r = q__1.r, y[i__2].i = q__1.i; /* L20: */ } } } else { iy = ky; if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = iy; y[i__2].r = 0.f, y[i__2].i = 0.f; iy += *incy; /* L30: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = iy; i__3 = iy; q__1.r = beta->r * y[i__3].r - beta->i * y[i__3].i, q__1.i = beta->r * y[i__3].i + beta->i * y[i__3] .r; y[i__2].r = q__1.r, y[i__2].i = q__1.i; iy += *incy; /* L40: */ } } } } if (alpha->r == 0.f && alpha->i == 0.f) { return 0; } kk = 1; if (lsame_(uplo, "U")) { /* Form y when AP contains the upper triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; q__1.r = alpha->r * x[i__2].r - alpha->i * x[i__2].i, q__1.i = alpha->r * x[i__2].i + alpha->i * x[i__2].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; k = kk; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = k; q__2.r = temp1.r * ap[i__5].r - temp1.i * ap[i__5].i, q__2.i = temp1.r * ap[i__5].i + temp1.i * ap[i__5] .r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; r_cnjg(&q__3, &ap[k]); i__3 = i__; q__2.r = q__3.r * x[i__3].r - q__3.i * x[i__3].i, q__2.i = q__3.r * x[i__3].i + q__3.i * x[i__3].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; ++k; /* L50: */ } i__2 = j; i__3 = j; i__4 = kk + j - 1; r__1 = ap[i__4].r; q__3.r = r__1 * temp1.r, q__3.i = r__1 * temp1.i; q__2.r = y[i__3].r + q__3.r, q__2.i = y[i__3].i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; kk += j; /* L60: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; q__1.r = alpha->r * x[i__2].r - alpha->i * x[i__2].i, q__1.i = alpha->r * x[i__2].i + alpha->i * x[i__2].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; ix = kx; iy = ky; i__2 = kk + j - 2; for (k = kk; k <= i__2; ++k) { i__3 = iy; i__4 = iy; i__5 = k; q__2.r = temp1.r * ap[i__5].r - temp1.i * ap[i__5].i, q__2.i = temp1.r * ap[i__5].i + temp1.i * ap[i__5] .r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; r_cnjg(&q__3, &ap[k]); i__3 = ix; q__2.r = q__3.r * x[i__3].r - q__3.i * x[i__3].i, q__2.i = q__3.r * x[i__3].i + q__3.i * x[i__3].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; ix += *incx; iy += *incy; /* L70: */ } i__2 = jy; i__3 = jy; i__4 = kk + j - 1; r__1 = ap[i__4].r; q__3.r = r__1 * temp1.r, q__3.i = r__1 * temp1.i; q__2.r = y[i__3].r + q__3.r, q__2.i = y[i__3].i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; jx += *incx; jy += *incy; kk += j; /* L80: */ } } } else { /* Form y when AP contains the lower triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; q__1.r = alpha->r * x[i__2].r - alpha->i * x[i__2].i, q__1.i = alpha->r * x[i__2].i + alpha->i * x[i__2].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__2 = j; i__3 = j; i__4 = kk; r__1 = ap[i__4].r; q__2.r = r__1 * temp1.r, q__2.i = r__1 * temp1.i; q__1.r = y[i__3].r + q__2.r, q__1.i = y[i__3].i + q__2.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; k = kk + 1; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { i__3 = i__; i__4 = i__; i__5 = k; q__2.r = temp1.r * ap[i__5].r - temp1.i * ap[i__5].i, q__2.i = temp1.r * ap[i__5].i + temp1.i * ap[i__5] .r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; r_cnjg(&q__3, &ap[k]); i__3 = i__; q__2.r = q__3.r * x[i__3].r - q__3.i * x[i__3].i, q__2.i = q__3.r * x[i__3].i + q__3.i * x[i__3].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; ++k; /* L90: */ } i__2 = j; i__3 = j; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = y[i__3].r + q__2.r, q__1.i = y[i__3].i + q__2.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; kk += *n - j + 1; /* L100: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = jx; q__1.r = alpha->r * x[i__2].r - alpha->i * x[i__2].i, q__1.i = alpha->r * x[i__2].i + alpha->i * x[i__2].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__2 = jy; i__3 = jy; i__4 = kk; r__1 = ap[i__4].r; q__2.r = r__1 * temp1.r, q__2.i = r__1 * temp1.i; q__1.r = y[i__3].r + q__2.r, q__1.i = y[i__3].i + q__2.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; ix = jx; iy = jy; i__2 = kk + *n - j; for (k = kk + 1; k <= i__2; ++k) { ix += *incx; iy += *incy; i__3 = iy; i__4 = iy; i__5 = k; q__2.r = temp1.r * ap[i__5].r - temp1.i * ap[i__5].i, q__2.i = temp1.r * ap[i__5].i + temp1.i * ap[i__5] .r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; r_cnjg(&q__3, &ap[k]); i__3 = ix; q__2.r = q__3.r * x[i__3].r - q__3.i * x[i__3].i, q__2.i = q__3.r * x[i__3].i + q__3.i * x[i__3].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L110: */ } i__2 = jy; i__3 = jy; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = y[i__3].r + q__2.r, q__1.i = y[i__3].i + q__2.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; jx += *incx; jy += *incy; kk += *n - j + 1; /* L120: */ } } } return 0; /* End of CHPMV . */ } /* chpmv_ */
/* Subroutine */ int claic1_(integer *job, integer *j, complex *x, real *sest, complex *w, complex *gamma, real *sestpr, complex *s, complex *c__) { /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= CLAIC1 applies one step of incremental condition estimation in its simplest version: Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j lower triangular matrix L, such that twonorm(L*x) = sest Then CLAIC1 computes sestpr, s, c such that the vector [ s*x ] xhat = [ c ] is an approximate singular vector of [ L 0 ] Lhat = [ w' gamma ] in the sense that twonorm(Lhat*xhat) = sestpr. Depending on JOB, an estimate for the largest or smallest singular value is computed. Note that [s c]' and sestpr**2 is an eigenpair of the system diag(sest*sest, 0) + [alpha gamma] * [ conjg(alpha) ] [ conjg(gamma) ] where alpha = conjg(x)'*w. Arguments ========= JOB (input) INTEGER = 1: an estimate for the largest singular value is computed. = 2: an estimate for the smallest singular value is computed. J (input) INTEGER Length of X and W X (input) COMPLEX array, dimension (J) The j-vector x. SEST (input) REAL Estimated singular value of j by j matrix L W (input) COMPLEX array, dimension (J) The j-vector w. GAMMA (input) COMPLEX The diagonal element gamma. SESTPR (output) REAL Estimated singular value of (j+1) by (j+1) matrix Lhat. S (output) COMPLEX Sine needed in forming xhat. C (output) COMPLEX Cosine needed in forming xhat. ===================================================================== Parameter adjustments */ /* Table of constant values */ static integer c__1 = 1; /* System generated locals */ real r__1, r__2; complex q__1, q__2, q__3, q__4, q__5, q__6; /* Builtin functions */ double c_abs(complex *); void r_cnjg(complex *, complex *), c_sqrt(complex *, complex *); double sqrt(doublereal); void c_div(complex *, complex *, complex *); /* Local variables */ static complex sine; static real test, zeta1, zeta2, b, t; static complex alpha; extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer *, complex *, integer *); static real norma, s1, s2, absgam, absalp; extern doublereal slamch_(char *); static complex cosine; static real absest, scl, eps, tmp; --w; --x; /* Function Body */ eps = slamch_("Epsilon"); cdotc_(&q__1, j, &x[1], &c__1, &w[1], &c__1); alpha.r = q__1.r, alpha.i = q__1.i; absalp = c_abs(&alpha); absgam = c_abs(gamma); absest = dabs(*sest); if (*job == 1) { /* Estimating largest singular value special cases */ if (*sest == 0.f) { s1 = dmax(absgam,absalp); if (s1 == 0.f) { s->r = 0.f, s->i = 0.f; c__->r = 1.f, c__->i = 0.f; *sestpr = 0.f; } else { q__1.r = alpha.r / s1, q__1.i = alpha.i / s1; s->r = q__1.r, s->i = q__1.i; q__1.r = gamma->r / s1, q__1.i = gamma->i / s1; c__->r = q__1.r, c__->i = q__1.i; r_cnjg(&q__4, s); q__3.r = s->r * q__4.r - s->i * q__4.i, q__3.i = s->r * q__4.i + s->i * q__4.r; r_cnjg(&q__6, c__); q__5.r = c__->r * q__6.r - c__->i * q__6.i, q__5.i = c__->r * q__6.i + c__->i * q__6.r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; c_sqrt(&q__1, &q__2); tmp = q__1.r; q__1.r = s->r / tmp, q__1.i = s->i / tmp; s->r = q__1.r, s->i = q__1.i; q__1.r = c__->r / tmp, q__1.i = c__->i / tmp; c__->r = q__1.r, c__->i = q__1.i; *sestpr = s1 * tmp; } return 0; } else if (absgam <= eps * absest) { s->r = 1.f, s->i = 0.f; c__->r = 0.f, c__->i = 0.f; tmp = dmax(absest,absalp); s1 = absest / tmp; s2 = absalp / tmp; *sestpr = tmp * sqrt(s1 * s1 + s2 * s2); return 0; } else if (absalp <= eps * absest) { s1 = absgam; s2 = absest; if (s1 <= s2) { s->r = 1.f, s->i = 0.f; c__->r = 0.f, c__->i = 0.f; *sestpr = s2; } else { s->r = 0.f, s->i = 0.f; c__->r = 1.f, c__->i = 0.f; *sestpr = s1; } return 0; } else if (absest <= eps * absalp || absest <= eps * absgam) { s1 = absgam; s2 = absalp; if (s1 <= s2) { tmp = s1 / s2; scl = sqrt(tmp * tmp + 1.f); *sestpr = s2 * scl; q__2.r = alpha.r / s2, q__2.i = alpha.i / s2; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; s->r = q__1.r, s->i = q__1.i; q__2.r = gamma->r / s2, q__2.i = gamma->i / s2; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; c__->r = q__1.r, c__->i = q__1.i; } else { tmp = s2 / s1; scl = sqrt(tmp * tmp + 1.f); *sestpr = s1 * scl; q__2.r = alpha.r / s1, q__2.i = alpha.i / s1; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; s->r = q__1.r, s->i = q__1.i; q__2.r = gamma->r / s1, q__2.i = gamma->i / s1; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; c__->r = q__1.r, c__->i = q__1.i; } return 0; } else { /* normal case */ zeta1 = absalp / absest; zeta2 = absgam / absest; b = (1.f - zeta1 * zeta1 - zeta2 * zeta2) * .5f; r__1 = zeta1 * zeta1; c__->r = r__1, c__->i = 0.f; if (b > 0.f) { r__1 = b * b; q__4.r = r__1 + c__->r, q__4.i = c__->i; c_sqrt(&q__3, &q__4); q__2.r = b + q__3.r, q__2.i = q__3.i; c_div(&q__1, c__, &q__2); t = q__1.r; } else { r__1 = b * b; q__3.r = r__1 + c__->r, q__3.i = c__->i; c_sqrt(&q__2, &q__3); q__1.r = q__2.r - b, q__1.i = q__2.i; t = q__1.r; } q__3.r = alpha.r / absest, q__3.i = alpha.i / absest; q__2.r = -q__3.r, q__2.i = -q__3.i; q__1.r = q__2.r / t, q__1.i = q__2.i / t; sine.r = q__1.r, sine.i = q__1.i; q__3.r = gamma->r / absest, q__3.i = gamma->i / absest; q__2.r = -q__3.r, q__2.i = -q__3.i; r__1 = t + 1.f; q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; cosine.r = q__1.r, cosine.i = q__1.i; r_cnjg(&q__4, &sine); q__3.r = sine.r * q__4.r - sine.i * q__4.i, q__3.i = sine.r * q__4.i + sine.i * q__4.r; r_cnjg(&q__6, &cosine); q__5.r = cosine.r * q__6.r - cosine.i * q__6.i, q__5.i = cosine.r * q__6.i + cosine.i * q__6.r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; c_sqrt(&q__1, &q__2); tmp = q__1.r; q__1.r = sine.r / tmp, q__1.i = sine.i / tmp; s->r = q__1.r, s->i = q__1.i; q__1.r = cosine.r / tmp, q__1.i = cosine.i / tmp; c__->r = q__1.r, c__->i = q__1.i; *sestpr = sqrt(t + 1.f) * absest; return 0; } } else if (*job == 2) { /* Estimating smallest singular value special cases */ if (*sest == 0.f) { *sestpr = 0.f; if (dmax(absgam,absalp) == 0.f) { sine.r = 1.f, sine.i = 0.f; cosine.r = 0.f, cosine.i = 0.f; } else { r_cnjg(&q__2, gamma); q__1.r = -q__2.r, q__1.i = -q__2.i; sine.r = q__1.r, sine.i = q__1.i; r_cnjg(&q__1, &alpha); cosine.r = q__1.r, cosine.i = q__1.i; } /* Computing MAX */ r__1 = c_abs(&sine), r__2 = c_abs(&cosine); s1 = dmax(r__1,r__2); q__1.r = sine.r / s1, q__1.i = sine.i / s1; s->r = q__1.r, s->i = q__1.i; q__1.r = cosine.r / s1, q__1.i = cosine.i / s1; c__->r = q__1.r, c__->i = q__1.i; r_cnjg(&q__4, s); q__3.r = s->r * q__4.r - s->i * q__4.i, q__3.i = s->r * q__4.i + s->i * q__4.r; r_cnjg(&q__6, c__); q__5.r = c__->r * q__6.r - c__->i * q__6.i, q__5.i = c__->r * q__6.i + c__->i * q__6.r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; c_sqrt(&q__1, &q__2); tmp = q__1.r; q__1.r = s->r / tmp, q__1.i = s->i / tmp; s->r = q__1.r, s->i = q__1.i; q__1.r = c__->r / tmp, q__1.i = c__->i / tmp; c__->r = q__1.r, c__->i = q__1.i; return 0; } else if (absgam <= eps * absest) { s->r = 0.f, s->i = 0.f; c__->r = 1.f, c__->i = 0.f; *sestpr = absgam; return 0; } else if (absalp <= eps * absest) { s1 = absgam; s2 = absest; if (s1 <= s2) { s->r = 0.f, s->i = 0.f; c__->r = 1.f, c__->i = 0.f; *sestpr = s1; } else { s->r = 1.f, s->i = 0.f; c__->r = 0.f, c__->i = 0.f; *sestpr = s2; } return 0; } else if (absest <= eps * absalp || absest <= eps * absgam) { s1 = absgam; s2 = absalp; if (s1 <= s2) { tmp = s1 / s2; scl = sqrt(tmp * tmp + 1.f); *sestpr = absest * (tmp / scl); r_cnjg(&q__4, gamma); q__3.r = q__4.r / s2, q__3.i = q__4.i / s2; q__2.r = -q__3.r, q__2.i = -q__3.i; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; s->r = q__1.r, s->i = q__1.i; r_cnjg(&q__3, &alpha); q__2.r = q__3.r / s2, q__2.i = q__3.i / s2; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; c__->r = q__1.r, c__->i = q__1.i; } else { tmp = s2 / s1; scl = sqrt(tmp * tmp + 1.f); *sestpr = absest / scl; r_cnjg(&q__4, gamma); q__3.r = q__4.r / s1, q__3.i = q__4.i / s1; q__2.r = -q__3.r, q__2.i = -q__3.i; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; s->r = q__1.r, s->i = q__1.i; r_cnjg(&q__3, &alpha); q__2.r = q__3.r / s1, q__2.i = q__3.i / s1; q__1.r = q__2.r / scl, q__1.i = q__2.i / scl; c__->r = q__1.r, c__->i = q__1.i; } return 0; } else { /* normal case */ zeta1 = absalp / absest; zeta2 = absgam / absest; /* Computing MAX */ r__1 = zeta1 * zeta1 + 1.f + zeta1 * zeta2, r__2 = zeta1 * zeta2 + zeta2 * zeta2; norma = dmax(r__1,r__2); /* See if root is closer to zero or to ONE */ test = (zeta1 - zeta2) * 2.f * (zeta1 + zeta2) + 1.f; if (test >= 0.f) { /* root is close to zero, compute directly */ b = (zeta1 * zeta1 + zeta2 * zeta2 + 1.f) * .5f; r__1 = zeta2 * zeta2; c__->r = r__1, c__->i = 0.f; r__2 = b * b; q__2.r = r__2 - c__->r, q__2.i = -c__->i; r__1 = b + sqrt(c_abs(&q__2)); q__1.r = c__->r / r__1, q__1.i = c__->i / r__1; t = q__1.r; q__2.r = alpha.r / absest, q__2.i = alpha.i / absest; r__1 = 1.f - t; q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; sine.r = q__1.r, sine.i = q__1.i; q__3.r = gamma->r / absest, q__3.i = gamma->i / absest; q__2.r = -q__3.r, q__2.i = -q__3.i; q__1.r = q__2.r / t, q__1.i = q__2.i / t; cosine.r = q__1.r, cosine.i = q__1.i; *sestpr = sqrt(t + eps * 4.f * eps * norma) * absest; } else { /* root is closer to ONE, shift by that amount */ b = (zeta2 * zeta2 + zeta1 * zeta1 - 1.f) * .5f; r__1 = zeta1 * zeta1; c__->r = r__1, c__->i = 0.f; if (b >= 0.f) { q__2.r = -c__->r, q__2.i = -c__->i; r__1 = b * b; q__5.r = r__1 + c__->r, q__5.i = c__->i; c_sqrt(&q__4, &q__5); q__3.r = b + q__4.r, q__3.i = q__4.i; c_div(&q__1, &q__2, &q__3); t = q__1.r; } else { r__1 = b * b; q__3.r = r__1 + c__->r, q__3.i = c__->i; c_sqrt(&q__2, &q__3); q__1.r = b - q__2.r, q__1.i = -q__2.i; t = q__1.r; } q__3.r = alpha.r / absest, q__3.i = alpha.i / absest; q__2.r = -q__3.r, q__2.i = -q__3.i; q__1.r = q__2.r / t, q__1.i = q__2.i / t; sine.r = q__1.r, sine.i = q__1.i; q__3.r = gamma->r / absest, q__3.i = gamma->i / absest; q__2.r = -q__3.r, q__2.i = -q__3.i; r__1 = t + 1.f; q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; cosine.r = q__1.r, cosine.i = q__1.i; *sestpr = sqrt(t + 1.f + eps * 4.f * eps * norma) * absest; } r_cnjg(&q__4, &sine); q__3.r = sine.r * q__4.r - sine.i * q__4.i, q__3.i = sine.r * q__4.i + sine.i * q__4.r; r_cnjg(&q__6, &cosine); q__5.r = cosine.r * q__6.r - cosine.i * q__6.i, q__5.i = cosine.r * q__6.i + cosine.i * q__6.r; q__2.r = q__3.r + q__5.r, q__2.i = q__3.i + q__5.i; c_sqrt(&q__1, &q__2); tmp = q__1.r; q__1.r = sine.r / tmp, q__1.i = sine.i / tmp; s->r = q__1.r, s->i = q__1.i; q__1.r = cosine.r / tmp, q__1.i = cosine.i / tmp; c__->r = q__1.r, c__->i = q__1.i; return 0; } } return 0; /* End of CLAIC1 */ } /* claic1_ */
/* Subroutine */ int cunml2_(char *side, char *trans, integer *m, integer *n, integer *k, complex *a, integer *lda, complex *tau, complex *c__, integer *ldc, complex *work, integer *info) { /* System generated locals */ integer a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__3; complex q__1; /* Local variables */ integer i__, i1, i2, i3, ic, jc, mi, ni, nq; complex aii; logical left; complex taui; logical notran; /* -- LAPACK routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* CUNML2 overwrites the general complex m-by-n matrix C with */ /* Q * C if SIDE = 'L' and TRANS = 'N', or */ /* Q'* C if SIDE = 'L' and TRANS = 'C', or */ /* C * Q if SIDE = 'R' and TRANS = 'N', or */ /* C * Q' if SIDE = 'R' and TRANS = 'C', */ /* where Q is a complex unitary matrix defined as the product of k */ /* elementary reflectors */ /* Q = H(k)' . . . H(2)' H(1)' */ /* as returned by CGELQF. Q is of order m if SIDE = 'L' and of order n */ /* if SIDE = 'R'. */ /* Arguments */ /* ========= */ /* SIDE (input) CHARACTER*1 */ /* = 'L': apply Q or Q' from the Left */ /* = 'R': apply Q or Q' from the Right */ /* TRANS (input) CHARACTER*1 */ /* = 'N': apply Q (No transpose) */ /* = 'C': apply Q' (Conjugate transpose) */ /* M (input) INTEGER */ /* The number of rows of the matrix C. M >= 0. */ /* N (input) INTEGER */ /* The number of columns of the matrix C. N >= 0. */ /* K (input) INTEGER */ /* The number of elementary reflectors whose product defines */ /* the matrix Q. */ /* If SIDE = 'L', M >= K >= 0; */ /* if SIDE = 'R', N >= K >= 0. */ /* A (input) COMPLEX array, dimension */ /* (LDA,M) if SIDE = 'L', */ /* (LDA,N) if SIDE = 'R' */ /* The i-th row must contain the vector which defines the */ /* CGELQF in the first k rows of its array argument A. */ /* A is modified by the routine but restored on exit. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,K). */ /* TAU (input) COMPLEX array, dimension (K) */ /* TAU(i) must contain the scalar factor of the elementary */ /* reflector H(i), as returned by CGELQF. */ /* C (input/output) COMPLEX array, dimension (LDC,N) */ /* On entry, the m-by-n matrix C. */ /* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. */ /* LDC (input) INTEGER */ /* The leading dimension of the array C. LDC >= max(1,M). */ /* WORK (workspace) COMPLEX array, dimension */ /* (N) if SIDE = 'L', */ /* (M) if SIDE = 'R' */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* ===================================================================== */ /* Test the input arguments */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_(side, "L"); notran = lsame_(trans, "N"); /* NQ is the order of Q */ if (left) { nq = *m; } else { nq = *n; } if (! left && ! lsame_(side, "R")) { *info = -1; } else if (! notran && ! lsame_(trans, "C")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < max(1,*k)) { *info = -7; } else if (*ldc < max(1,*m)) { *info = -10; } if (*info != 0) { i__1 = -(*info); xerbla_("CUNML2", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { return 0; } if (left && notran || ! left && ! notran) { i1 = 1; i2 = *k; i3 = 1; } else { i1 = *k; i2 = 1; i3 = -1; } if (left) { ni = *n; jc = 1; } else { mi = *m; ic = 1; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { if (left) { /* H(i) or H(i)' is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H(i) or H(i)' is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H(i) or H(i)' */ if (notran) { r_cnjg(&q__1, &tau[i__]); taui.r = q__1.r, taui.i = q__1.i; } else { i__3 = i__; taui.r = tau[i__3].r, taui.i = tau[i__3].i; } if (i__ < nq) { i__3 = nq - i__; clacgv_(&i__3, &a[i__ + (i__ + 1) * a_dim1], lda); } i__3 = i__ + i__ * a_dim1; aii.r = a[i__3].r, aii.i = a[i__3].i; i__3 = i__ + i__ * a_dim1; a[i__3].r = 1.f, a[i__3].i = 0.f; clarf_(side, &mi, &ni, &a[i__ + i__ * a_dim1], lda, &taui, &c__[ic + jc * c_dim1], ldc, &work[1]); i__3 = i__ + i__ * a_dim1; a[i__3].r = aii.r, a[i__3].i = aii.i; if (i__ < nq) { i__3 = nq - i__; clacgv_(&i__3, &a[i__ + (i__ + 1) * a_dim1], lda); } } return 0; /* End of CUNML2 */ } /* cunml2_ */
int cgbbrd_(char *vect, int *m, int *n, int *ncc, int *kl, int *ku, complex *ab, int *ldab, float *d__, float *e, complex *q, int *ldq, complex *pt, int *ldpt, complex *c__, int *ldc, complex *work, float *rwork, int *info) { /* System generated locals */ int ab_dim1, ab_offset, c_dim1, c_offset, pt_dim1, pt_offset, q_dim1, q_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; complex q__1, q__2, q__3; /* Builtin functions */ void r_cnjg(complex *, complex *); double c_abs(complex *); /* Local variables */ int i__, j, l; complex t; int j1, j2, kb; complex ra, rb; float rc; int kk, ml, nr, mu; complex rs; int kb1, ml0, mu0, klm, kun, nrt, klu1, inca; float abst; extern int crot_(int *, complex *, int *, complex *, int *, float *, complex *), cscal_(int *, complex *, complex *, int *); extern int lsame_(char *, char *); int wantb, wantc; int minmn; int wantq; extern int claset_(char *, int *, int *, complex *, complex *, complex *, int *), clartg_(complex *, complex *, float *, complex *, complex *), xerbla_(char *, int *), clargv_(int *, complex *, int *, complex *, int *, float *, int *), clartv_(int *, complex *, int *, complex *, int *, float *, complex *, int *); int wantpt; /* -- LAPACK routine (version 3.2) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGBBRD reduces a complex general m-by-n band matrix A to float upper */ /* bidiagonal form B by a unitary transformation: Q' * A * P = B. */ /* The routine computes B, and optionally forms Q or P', or computes */ /* Q'*C for a given matrix C. */ /* Arguments */ /* ========= */ /* VECT (input) CHARACTER*1 */ /* Specifies whether or not the matrices Q and P' are to be */ /* formed. */ /* = 'N': do not form Q or P'; */ /* = 'Q': form Q only; */ /* = 'P': form P' only; */ /* = 'B': form both. */ /* M (input) INTEGER */ /* The number of rows of the matrix A. M >= 0. */ /* N (input) INTEGER */ /* The number of columns of the matrix A. N >= 0. */ /* NCC (input) INTEGER */ /* The number of columns of the matrix C. NCC >= 0. */ /* KL (input) INTEGER */ /* The number of subdiagonals of the matrix A. KL >= 0. */ /* KU (input) INTEGER */ /* The number of superdiagonals of the matrix A. KU >= 0. */ /* AB (input/output) COMPLEX array, dimension (LDAB,N) */ /* On entry, the m-by-n band matrix A, stored in rows 1 to */ /* KL+KU+1. The j-th column of A is stored in the j-th column of */ /* the array AB as follows: */ /* AB(ku+1+i-j,j) = A(i,j) for MAX(1,j-ku)<=i<=MIN(m,j+kl). */ /* On exit, A is overwritten by values generated during the */ /* reduction. */ /* LDAB (input) INTEGER */ /* The leading dimension of the array A. LDAB >= KL+KU+1. */ /* D (output) REAL array, dimension (MIN(M,N)) */ /* The diagonal elements of the bidiagonal matrix B. */ /* E (output) REAL array, dimension (MIN(M,N)-1) */ /* The superdiagonal elements of the bidiagonal matrix B. */ /* Q (output) COMPLEX array, dimension (LDQ,M) */ /* If VECT = 'Q' or 'B', the m-by-m unitary matrix Q. */ /* If VECT = 'N' or 'P', the array Q is not referenced. */ /* LDQ (input) INTEGER */ /* The leading dimension of the array Q. */ /* LDQ >= MAX(1,M) if VECT = 'Q' or 'B'; LDQ >= 1 otherwise. */ /* PT (output) COMPLEX array, dimension (LDPT,N) */ /* If VECT = 'P' or 'B', the n-by-n unitary matrix P'. */ /* If VECT = 'N' or 'Q', the array PT is not referenced. */ /* LDPT (input) INTEGER */ /* The leading dimension of the array PT. */ /* LDPT >= MAX(1,N) if VECT = 'P' or 'B'; LDPT >= 1 otherwise. */ /* C (input/output) COMPLEX array, dimension (LDC,NCC) */ /* On entry, an m-by-ncc matrix C. */ /* On exit, C is overwritten by Q'*C. */ /* C is not referenced if NCC = 0. */ /* LDC (input) INTEGER */ /* The leading dimension of the array C. */ /* LDC >= MAX(1,M) if NCC > 0; LDC >= 1 if NCC = 0. */ /* WORK (workspace) COMPLEX array, dimension (MAX(M,N)) */ /* RWORK (workspace) REAL array, dimension (MAX(M,N)) */ /* 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 */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; --d__; --e; q_dim1 = *ldq; q_offset = 1 + q_dim1; q -= q_offset; pt_dim1 = *ldpt; pt_offset = 1 + pt_dim1; pt -= pt_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1; c__ -= c_offset; --work; --rwork; /* Function Body */ wantb = lsame_(vect, "B"); wantq = lsame_(vect, "Q") || wantb; wantpt = lsame_(vect, "P") || wantb; wantc = *ncc > 0; klu1 = *kl + *ku + 1; *info = 0; if (! wantq && ! wantpt && ! lsame_(vect, "N")) { *info = -1; } else if (*m < 0) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*ncc < 0) { *info = -4; } else if (*kl < 0) { *info = -5; } else if (*ku < 0) { *info = -6; } else if (*ldab < klu1) { *info = -8; } else if (*ldq < 1 || wantq && *ldq < MAX(1,*m)) { *info = -12; } else if (*ldpt < 1 || wantpt && *ldpt < MAX(1,*n)) { *info = -14; } else if (*ldc < 1 || wantc && *ldc < MAX(1,*m)) { *info = -16; } if (*info != 0) { i__1 = -(*info); xerbla_("CGBBRD", &i__1); return 0; } /* Initialize Q and P' to the unit matrix, if needed */ if (wantq) { claset_("Full", m, m, &c_b1, &c_b2, &q[q_offset], ldq); } if (wantpt) { claset_("Full", n, n, &c_b1, &c_b2, &pt[pt_offset], ldpt); } /* Quick return if possible. */ if (*m == 0 || *n == 0) { return 0; } minmn = MIN(*m,*n); if (*kl + *ku > 1) { /* Reduce to upper bidiagonal form if KU > 0; if KU = 0, reduce */ /* first to lower bidiagonal form and then transform to upper */ /* bidiagonal */ if (*ku > 0) { ml0 = 1; mu0 = 2; } else { ml0 = 2; mu0 = 1; } /* Wherever possible, plane rotations are generated and applied in */ /* vector operations of length NR over the index set J1:J2:KLU1. */ /* The complex sines of the plane rotations are stored in WORK, */ /* and the float cosines in RWORK. */ /* Computing MIN */ i__1 = *m - 1; klm = MIN(i__1,*kl); /* Computing MIN */ i__1 = *n - 1; kun = MIN(i__1,*ku); kb = klm + kun; kb1 = kb + 1; inca = kb1 * *ldab; nr = 0; j1 = klm + 2; j2 = 1 - kun; i__1 = minmn; for (i__ = 1; i__ <= i__1; ++i__) { /* Reduce i-th column and i-th row of matrix to bidiagonal form */ ml = klm + 1; mu = kun + 1; i__2 = kb; for (kk = 1; kk <= i__2; ++kk) { j1 += kb; j2 += kb; /* generate plane rotations to annihilate nonzero elements */ /* which have been created below the band */ if (nr > 0) { clargv_(&nr, &ab[klu1 + (j1 - klm - 1) * ab_dim1], &inca, &work[j1], &kb1, &rwork[j1], &kb1); } /* apply plane rotations from the left */ i__3 = kb; for (l = 1; l <= i__3; ++l) { if (j2 - klm + l - 1 > *n) { nrt = nr - 1; } else { nrt = nr; } if (nrt > 0) { clartv_(&nrt, &ab[klu1 - l + (j1 - klm + l - 1) * ab_dim1], &inca, &ab[klu1 - l + 1 + (j1 - klm + l - 1) * ab_dim1], &inca, &rwork[j1], &work[ j1], &kb1); } /* L10: */ } if (ml > ml0) { if (ml <= *m - i__ + 1) { /* generate plane rotation to annihilate a(i+ml-1,i) */ /* within the band, and apply rotation from the left */ clartg_(&ab[*ku + ml - 1 + i__ * ab_dim1], &ab[*ku + ml + i__ * ab_dim1], &rwork[i__ + ml - 1], & work[i__ + ml - 1], &ra); i__3 = *ku + ml - 1 + i__ * ab_dim1; ab[i__3].r = ra.r, ab[i__3].i = ra.i; if (i__ < *n) { /* Computing MIN */ i__4 = *ku + ml - 2, i__5 = *n - i__; i__3 = MIN(i__4,i__5); i__6 = *ldab - 1; i__7 = *ldab - 1; crot_(&i__3, &ab[*ku + ml - 2 + (i__ + 1) * ab_dim1], &i__6, &ab[*ku + ml - 1 + (i__ + 1) * ab_dim1], &i__7, &rwork[i__ + ml - 1], &work[i__ + ml - 1]); } } ++nr; j1 -= kb1; } if (wantq) { /* accumulate product of plane rotations in Q */ i__3 = j2; i__4 = kb1; for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) { r_cnjg(&q__1, &work[j]); crot_(m, &q[(j - 1) * q_dim1 + 1], &c__1, &q[j * q_dim1 + 1], &c__1, &rwork[j], &q__1); /* L20: */ } } if (wantc) { /* apply plane rotations to C */ i__4 = j2; i__3 = kb1; for (j = j1; i__3 < 0 ? j >= i__4 : j <= i__4; j += i__3) { crot_(ncc, &c__[j - 1 + c_dim1], ldc, &c__[j + c_dim1] , ldc, &rwork[j], &work[j]); /* L30: */ } } if (j2 + kun > *n) { /* adjust J2 to keep within the bounds of the matrix */ --nr; j2 -= kb1; } i__3 = j2; i__4 = kb1; for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) { /* create nonzero element a(j-1,j+ku) above the band */ /* and store it in WORK(n+1:2*n) */ i__5 = j + kun; i__6 = j; i__7 = (j + kun) * ab_dim1 + 1; q__1.r = work[i__6].r * ab[i__7].r - work[i__6].i * ab[ i__7].i, q__1.i = work[i__6].r * ab[i__7].i + work[i__6].i * ab[i__7].r; work[i__5].r = q__1.r, work[i__5].i = q__1.i; i__5 = (j + kun) * ab_dim1 + 1; i__6 = j; i__7 = (j + kun) * ab_dim1 + 1; q__1.r = rwork[i__6] * ab[i__7].r, q__1.i = rwork[i__6] * ab[i__7].i; ab[i__5].r = q__1.r, ab[i__5].i = q__1.i; /* L40: */ } /* generate plane rotations to annihilate nonzero elements */ /* which have been generated above the band */ if (nr > 0) { clargv_(&nr, &ab[(j1 + kun - 1) * ab_dim1 + 1], &inca, & work[j1 + kun], &kb1, &rwork[j1 + kun], &kb1); } /* apply plane rotations from the right */ i__4 = kb; for (l = 1; l <= i__4; ++l) { if (j2 + l - 1 > *m) { nrt = nr - 1; } else { nrt = nr; } if (nrt > 0) { clartv_(&nrt, &ab[l + 1 + (j1 + kun - 1) * ab_dim1], & inca, &ab[l + (j1 + kun) * ab_dim1], &inca, & rwork[j1 + kun], &work[j1 + kun], &kb1); } /* L50: */ } if (ml == ml0 && mu > mu0) { if (mu <= *n - i__ + 1) { /* generate plane rotation to annihilate a(i,i+mu-1) */ /* within the band, and apply rotation from the right */ clartg_(&ab[*ku - mu + 3 + (i__ + mu - 2) * ab_dim1], &ab[*ku - mu + 2 + (i__ + mu - 1) * ab_dim1], &rwork[i__ + mu - 1], &work[i__ + mu - 1], & ra); i__4 = *ku - mu + 3 + (i__ + mu - 2) * ab_dim1; ab[i__4].r = ra.r, ab[i__4].i = ra.i; /* Computing MIN */ i__3 = *kl + mu - 2, i__5 = *m - i__; i__4 = MIN(i__3,i__5); crot_(&i__4, &ab[*ku - mu + 4 + (i__ + mu - 2) * ab_dim1], &c__1, &ab[*ku - mu + 3 + (i__ + mu - 1) * ab_dim1], &c__1, &rwork[i__ + mu - 1], &work[i__ + mu - 1]); } ++nr; j1 -= kb1; } if (wantpt) { /* accumulate product of plane rotations in P' */ i__4 = j2; i__3 = kb1; for (j = j1; i__3 < 0 ? j >= i__4 : j <= i__4; j += i__3) { r_cnjg(&q__1, &work[j + kun]); crot_(n, &pt[j + kun - 1 + pt_dim1], ldpt, &pt[j + kun + pt_dim1], ldpt, &rwork[j + kun], &q__1); /* L60: */ } } if (j2 + kb > *m) { /* adjust J2 to keep within the bounds of the matrix */ --nr; j2 -= kb1; } i__3 = j2; i__4 = kb1; for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) { /* create nonzero element a(j+kl+ku,j+ku-1) below the */ /* band and store it in WORK(1:n) */ i__5 = j + kb; i__6 = j + kun; i__7 = klu1 + (j + kun) * ab_dim1; q__1.r = work[i__6].r * ab[i__7].r - work[i__6].i * ab[ i__7].i, q__1.i = work[i__6].r * ab[i__7].i + work[i__6].i * ab[i__7].r; work[i__5].r = q__1.r, work[i__5].i = q__1.i; i__5 = klu1 + (j + kun) * ab_dim1; i__6 = j + kun; i__7 = klu1 + (j + kun) * ab_dim1; q__1.r = rwork[i__6] * ab[i__7].r, q__1.i = rwork[i__6] * ab[i__7].i; ab[i__5].r = q__1.r, ab[i__5].i = q__1.i; /* L70: */ } if (ml > ml0) { --ml; } else { --mu; } /* L80: */ } /* L90: */ } } if (*ku == 0 && *kl > 0) { /* A has been reduced to complex lower bidiagonal form */ /* Transform lower bidiagonal form to upper bidiagonal by applying */ /* plane rotations from the left, overwriting superdiagonal */ /* elements on subdiagonal elements */ /* Computing MIN */ i__2 = *m - 1; i__1 = MIN(i__2,*n); for (i__ = 1; i__ <= i__1; ++i__) { clartg_(&ab[i__ * ab_dim1 + 1], &ab[i__ * ab_dim1 + 2], &rc, &rs, &ra); i__2 = i__ * ab_dim1 + 1; ab[i__2].r = ra.r, ab[i__2].i = ra.i; if (i__ < *n) { i__2 = i__ * ab_dim1 + 2; i__4 = (i__ + 1) * ab_dim1 + 1; q__1.r = rs.r * ab[i__4].r - rs.i * ab[i__4].i, q__1.i = rs.r * ab[i__4].i + rs.i * ab[i__4].r; ab[i__2].r = q__1.r, ab[i__2].i = q__1.i; i__2 = (i__ + 1) * ab_dim1 + 1; i__4 = (i__ + 1) * ab_dim1 + 1; q__1.r = rc * ab[i__4].r, q__1.i = rc * ab[i__4].i; ab[i__2].r = q__1.r, ab[i__2].i = q__1.i; } if (wantq) { r_cnjg(&q__1, &rs); crot_(m, &q[i__ * q_dim1 + 1], &c__1, &q[(i__ + 1) * q_dim1 + 1], &c__1, &rc, &q__1); } if (wantc) { crot_(ncc, &c__[i__ + c_dim1], ldc, &c__[i__ + 1 + c_dim1], ldc, &rc, &rs); } /* L100: */ } } else { /* A has been reduced to complex upper bidiagonal form or is */ /* diagonal */ if (*ku > 0 && *m < *n) { /* Annihilate a(m,m+1) by applying plane rotations from the */ /* right */ i__1 = *ku + (*m + 1) * ab_dim1; rb.r = ab[i__1].r, rb.i = ab[i__1].i; for (i__ = *m; i__ >= 1; --i__) { clartg_(&ab[*ku + 1 + i__ * ab_dim1], &rb, &rc, &rs, &ra); i__1 = *ku + 1 + i__ * ab_dim1; ab[i__1].r = ra.r, ab[i__1].i = ra.i; if (i__ > 1) { r_cnjg(&q__3, &rs); q__2.r = -q__3.r, q__2.i = -q__3.i; i__1 = *ku + i__ * ab_dim1; q__1.r = q__2.r * ab[i__1].r - q__2.i * ab[i__1].i, q__1.i = q__2.r * ab[i__1].i + q__2.i * ab[i__1] .r; rb.r = q__1.r, rb.i = q__1.i; i__1 = *ku + i__ * ab_dim1; i__2 = *ku + i__ * ab_dim1; q__1.r = rc * ab[i__2].r, q__1.i = rc * ab[i__2].i; ab[i__1].r = q__1.r, ab[i__1].i = q__1.i; } if (wantpt) { r_cnjg(&q__1, &rs); crot_(n, &pt[i__ + pt_dim1], ldpt, &pt[*m + 1 + pt_dim1], ldpt, &rc, &q__1); } /* L110: */ } } } /* Make diagonal and superdiagonal elements float, storing them in D */ /* and E */ i__1 = *ku + 1 + ab_dim1; t.r = ab[i__1].r, t.i = ab[i__1].i; i__1 = minmn; for (i__ = 1; i__ <= i__1; ++i__) { abst = c_abs(&t); d__[i__] = abst; if (abst != 0.f) { q__1.r = t.r / abst, q__1.i = t.i / abst; t.r = q__1.r, t.i = q__1.i; } else { t.r = 1.f, t.i = 0.f; } if (wantq) { cscal_(m, &t, &q[i__ * q_dim1 + 1], &c__1); } if (wantc) { r_cnjg(&q__1, &t); cscal_(ncc, &q__1, &c__[i__ + c_dim1], ldc); } if (i__ < minmn) { if (*ku == 0 && *kl == 0) { e[i__] = 0.f; i__2 = (i__ + 1) * ab_dim1 + 1; t.r = ab[i__2].r, t.i = ab[i__2].i; } else { if (*ku == 0) { i__2 = i__ * ab_dim1 + 2; r_cnjg(&q__2, &t); q__1.r = ab[i__2].r * q__2.r - ab[i__2].i * q__2.i, q__1.i = ab[i__2].r * q__2.i + ab[i__2].i * q__2.r; t.r = q__1.r, t.i = q__1.i; } else { i__2 = *ku + (i__ + 1) * ab_dim1; r_cnjg(&q__2, &t); q__1.r = ab[i__2].r * q__2.r - ab[i__2].i * q__2.i, q__1.i = ab[i__2].r * q__2.i + ab[i__2].i * q__2.r; t.r = q__1.r, t.i = q__1.i; } abst = c_abs(&t); e[i__] = abst; if (abst != 0.f) { q__1.r = t.r / abst, q__1.i = t.i / abst; t.r = q__1.r, t.i = q__1.i; } else { t.r = 1.f, t.i = 0.f; } if (wantpt) { cscal_(n, &t, &pt[i__ + 1 + pt_dim1], ldpt); } i__2 = *ku + 1 + (i__ + 1) * ab_dim1; r_cnjg(&q__2, &t); q__1.r = ab[i__2].r * q__2.r - ab[i__2].i * q__2.i, q__1.i = ab[i__2].r * q__2.i + ab[i__2].i * q__2.r; t.r = q__1.r, t.i = q__1.i; } } /* L120: */ } return 0; /* End of CGBBRD */ } /* cgbbrd_ */
/* Subroutine */ int cdrgev_(integer *nsizes, integer *nn, integer *ntypes, logical *dotype, integer *iseed, real *thresh, integer *nounit, complex *a, integer *lda, complex *b, complex *s, complex *t, complex *q, integer *ldq, complex *z__, complex *qe, integer *ldqe, complex * alpha, complex *beta, complex *alpha1, complex *beta1, complex *work, integer *lwork, real *rwork, real *result, integer *info) { /* Initialized data */ static integer kclass[26] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2, 2,2,2,3 }; static integer kbmagn[26] = { 1,1,1,1,1,1,1,1,3,2,3,2,2,3,1,1,1,1,1,1,1,3, 2,3,2,1 }; static integer ktrian[26] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,1,1,1 }; static logical lasign[26] = { FALSE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_, TRUE_,FALSE_,TRUE_,TRUE_,FALSE_,FALSE_,TRUE_,TRUE_,TRUE_,FALSE_, TRUE_,FALSE_,FALSE_,FALSE_,TRUE_,TRUE_,TRUE_,TRUE_,TRUE_,FALSE_ }; static logical lbsign[26] = { FALSE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_, FALSE_,TRUE_,FALSE_,FALSE_,TRUE_,TRUE_,FALSE_,FALSE_,TRUE_,FALSE_, TRUE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_,FALSE_, FALSE_ }; static integer kz1[6] = { 0,1,2,1,3,3 }; static integer kz2[6] = { 0,0,1,2,1,1 }; static integer kadd[6] = { 0,0,0,0,3,2 }; static integer katype[26] = { 0,1,0,1,2,3,4,1,4,4,1,1,4,4,4,2,4,5,8,7,9,4, 4,4,4,0 }; static integer kbtype[26] = { 0,0,1,1,2,-3,1,4,1,1,4,4,1,1,-4,2,-4,8,8,8, 8,8,8,8,8,0 }; static integer kazero[26] = { 1,1,1,1,1,1,2,1,2,2,1,1,2,2,3,1,3,5,5,5,5,3, 3,3,3,1 }; static integer kbzero[26] = { 1,1,1,1,1,1,1,2,1,1,2,2,1,1,4,1,4,6,6,6,6,4, 4,4,4,1 }; static integer kamagn[26] = { 1,1,1,1,1,1,1,1,2,3,2,3,2,3,1,1,1,1,1,1,1,2, 3,3,2,1 }; /* Format strings */ static char fmt_9999[] = "(\002 CDRGEV: \002,a,\002 returned INFO=\002,i" "6,\002.\002,/3x,\002N=\002,i6,\002, JTYPE=\002,i6,\002, ISEED=" "(\002,3(i5,\002,\002),i5,\002)\002)"; static char fmt_9998[] = "(\002 CDRGEV: \002,a,\002 Eigenvectors from" " \002,a,\002 incorrectly \002,\002normalized.\002,/\002 Bits of " "error=\002,0p,g10.3,\002,\002,3x,\002N=\002,i4,\002, JTYPE=\002," "i3,\002, ISEED=(\002,3(i4,\002,\002),i5,\002)\002)"; static char fmt_9997[] = "(/1x,a3,\002 -- Complex Generalized eigenvalue" " problem \002,\002driver\002)"; static char fmt_9996[] = "(\002 Matrix types (see CDRGEV for details):" " \002)"; static char fmt_9995[] = "(\002 Special Matrices:\002,23x,\002(J'=transp" "osed Jordan block)\002,/\002 1=(0,0) 2=(I,0) 3=(0,I) 4=(I,I" ") 5=(J',J') \002,\0026=(diag(J',I), diag(I,J'))\002,/\002 Diag" "onal Matrices: ( \002,\002D=diag(0,1,2,...) )\002,/\002 7=(D," "I) 9=(large*D, small*I\002,\002) 11=(large*I, small*D) 13=(l" "arge*D, large*I)\002,/\002 8=(I,D) 10=(small*D, large*I) 12=" "(small*I, large*D) \002,\002 14=(small*D, small*I)\002,/\002 15" "=(D, reversed D)\002)"; static char fmt_9994[] = "(\002 Matrices Rotated by Random \002,a,\002 M" "atrices U, V:\002,/\002 16=Transposed Jordan Blocks " " 19=geometric \002,\002alpha, beta=0,1\002,/\002 17=arithm. alp" "ha&beta \002,\002 20=arithmetic alpha, beta=0," "1\002,/\002 18=clustered \002,\002alpha, beta=0,1 21" "=random alpha, beta=0,1\002,/\002 Large & Small Matrices:\002," "/\002 22=(large, small) \002,\00223=(small,large) 24=(smal" "l,small) 25=(large,large)\002,/\002 26=random O(1) matrices" ".\002)"; static char fmt_9993[] = "(/\002 Tests performed: \002,/\002 1 = max " "| ( b A - a B )'*l | / const.,\002,/\002 2 = | |VR(i)| - 1 | / u" "lp,\002,/\002 3 = max | ( b A - a B )*r | / const.\002,/\002 4 =" " | |VL(i)| - 1 | / ulp,\002,/\002 5 = 0 if W same no matter if r" " or l computed,\002,/\002 6 = 0 if l same no matter if l compute" "d,\002,/\002 7 = 0 if r same no matter if r computed,\002,/1x)"; static char fmt_9992[] = "(\002 Matrix order=\002,i5,\002, type=\002,i2" ",\002, seed=\002,4(i4,\002,\002),\002 result \002,i2,\002 is\002" ",0p,f8.2)"; static char fmt_9991[] = "(\002 Matrix order=\002,i5,\002, type=\002,i2" ",\002, seed=\002,4(i4,\002,\002),\002 result \002,i2,\002 is\002" ",1p,e10.3)"; /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, qe_dim1, qe_offset, s_dim1, s_offset, t_dim1, t_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1, r__2; complex q__1, q__2, q__3; /* Builtin functions */ double r_sign(real *, real *), c_abs(complex *); void r_cnjg(complex *, complex *); integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); /* Local variables */ static integer iadd, ierr, nmax, i__, j, n; static logical badnn; extern /* Subroutine */ int cget52_(logical *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, complex *, complex *, real *, real *), cggev_(char *, char *, integer *, complex *, integer *, complex *, integer *, complex *, complex *, complex *, integer *, complex *, integer *, complex *, integer *, real *, integer *); static real rmagn[4]; static complex ctemp; static integer nmats, jsize, nerrs, jtype, n1; extern /* Subroutine */ int clatm4_(integer *, integer *, integer *, integer *, logical *, real *, real *, real *, integer *, integer * , complex *, integer *), cunm2r_(char *, char *, integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, complex *, integer *); static integer jc, nb, in; extern /* Subroutine */ int slabad_(real *, real *); static integer jr; extern /* Subroutine */ int clarfg_(integer *, complex *, complex *, integer *, complex *); extern /* Complex */ VOID clarnd_(complex *, integer *, integer *); extern doublereal slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *); static real safmin, safmax; static integer ioldsd[4]; extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *, ftnlen, ftnlen); extern /* Subroutine */ int alasvm_(char *, integer *, integer *, integer *, integer *), xerbla_(char *, integer *); static integer minwrk, maxwrk; static real ulpinv; static integer mtypes, ntestt; static real ulp; /* Fortran I/O blocks */ static cilist io___40 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___42 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___43 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___44 = { 0, 0, 0, fmt_9998, 0 }; static cilist io___45 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___46 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___47 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___48 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___49 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___50 = { 0, 0, 0, fmt_9995, 0 }; static cilist io___51 = { 0, 0, 0, fmt_9994, 0 }; static cilist io___52 = { 0, 0, 0, fmt_9993, 0 }; static cilist io___53 = { 0, 0, 0, fmt_9992, 0 }; static cilist io___54 = { 0, 0, 0, fmt_9991, 0 }; #define a_subscr(a_1,a_2) (a_2)*a_dim1 + a_1 #define a_ref(a_1,a_2) a[a_subscr(a_1,a_2)] #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)] #define q_subscr(a_1,a_2) (a_2)*q_dim1 + a_1 #define q_ref(a_1,a_2) q[q_subscr(a_1,a_2)] #define z___subscr(a_1,a_2) (a_2)*z_dim1 + a_1 #define z___ref(a_1,a_2) z__[z___subscr(a_1,a_2)] #define qe_subscr(a_1,a_2) (a_2)*qe_dim1 + a_1 #define qe_ref(a_1,a_2) qe[qe_subscr(a_1,a_2)] /* -- LAPACK test routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= CDRGEV checks the nonsymmetric generalized eigenvalue problem driver routine CGGEV. CGGEV computes for a pair of n-by-n nonsymmetric matrices (A,B) the generalized eigenvalues and, optionally, the left and right eigenvectors. A generalized eigenvalue for a pair of matrices (A,B) is a scalar w or a ratio alpha/beta = w, such that A - w*B is singular. It is usually represented as the pair (alpha,beta), as there is reasonalbe interpretation for beta=0, and even for both being zero. A right generalized eigenvector corresponding to a generalized eigenvalue w for a pair of matrices (A,B) is a vector r such that (A - wB) * r = 0. A left generalized eigenvector is a vector l such that l**H * (A - wB) = 0, where l**H is the conjugate-transpose of l. When CDRGEV is called, a number of matrix "sizes" ("n's") and a number of matrix "types" are specified. For each size ("n") and each type of matrix, a pair of matrices (A, B) will be generated and used for testing. For each matrix pair, the following tests will be performed and compared with the threshhold THRESH. Results from CGGEV: (1) max over all left eigenvalue/-vector pairs (alpha/beta,l) of | VL**H * (beta A - alpha B) |/( ulp max(|beta A|, |alpha B|) ) where VL**H is the conjugate-transpose of VL. (2) | |VL(i)| - 1 | / ulp and whether largest component real VL(i) denotes the i-th column of VL. (3) max over all left eigenvalue/-vector pairs (alpha/beta,r) of | (beta A - alpha B) * VR | / ( ulp max(|beta A|, |alpha B|) ) (4) | |VR(i)| - 1 | / ulp and whether largest component real VR(i) denotes the i-th column of VR. (5) W(full) = W(partial) W(full) denotes the eigenvalues computed when both l and r are also computed, and W(partial) denotes the eigenvalues computed when only W, only W and r, or only W and l are computed. (6) VL(full) = VL(partial) VL(full) denotes the left eigenvectors computed when both l and r are computed, and VL(partial) denotes the result when only l is computed. (7) VR(full) = VR(partial) VR(full) denotes the right eigenvectors computed when both l and r are also computed, and VR(partial) denotes the result when only l is computed. Test Matrices ---- -------- The sizes of the test matrices are specified by an array NN(1:NSIZES); the value of each element NN(j) specifies one size. The "types" are specified by a logical array DOTYPE( 1:NTYPES ); if DOTYPE(j) is .TRUE., then matrix type "j" will be generated. Currently, the list of possible types is: (1) ( 0, 0 ) (a pair of zero matrices) (2) ( I, 0 ) (an identity and a zero matrix) (3) ( 0, I ) (an identity and a zero matrix) (4) ( I, I ) (a pair of identity matrices) t t (5) ( J , J ) (a pair of transposed Jordan blocks) t ( I 0 ) (6) ( X, Y ) where X = ( J 0 ) and Y = ( t ) ( 0 I ) ( 0 J ) and I is a k x k identity and J a (k+1)x(k+1) Jordan block; k=(N-1)/2 (7) ( D, I ) where D is diag( 0, 1,..., N-1 ) (a diagonal matrix with those diagonal entries.) (8) ( I, D ) (9) ( big*D, small*I ) where "big" is near overflow and small=1/big (10) ( small*D, big*I ) (11) ( big*I, small*D ) (12) ( small*I, big*D ) (13) ( big*D, big*I ) (14) ( small*D, small*I ) (15) ( D1, D2 ) where D1 is diag( 0, 0, 1, ..., N-3, 0 ) and D2 is diag( 0, N-3, N-4,..., 1, 0, 0 ) t t (16) Q ( J , J ) Z where Q and Z are random orthogonal matrices. (17) Q ( T1, T2 ) Z where T1 and T2 are upper triangular matrices with random O(1) entries above the diagonal and diagonal entries diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) and diag(T2) = ( 0, N-3, N-4,..., 1, 0, 0 ) (18) Q ( T1, T2 ) Z diag(T1) = ( 0, 0, 1, 1, s, ..., s, 0 ) diag(T2) = ( 0, 1, 0, 1,..., 1, 0 ) s = machine precision. (19) Q ( T1, T2 ) Z diag(T1)=( 0,0,1,1, 1-d, ..., 1-(N-5)*d=s, 0 ) diag(T2) = ( 0, 1, 0, 1, ..., 1, 0 ) N-5 (20) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, 1, a, ..., a =s, 0 ) diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 ) (21) Q ( T1, T2 ) Z diag(T1)=( 0, 0, 1, r1, r2, ..., r(N-4), 0 ) diag(T2) = ( 0, 1, 0, 1, ..., 1, 0, 0 ) where r1,..., r(N-4) are random. (22) Q ( big*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) diag(T2) = ( 0, 1, ..., 1, 0, 0 ) (23) Q ( small*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) diag(T2) = ( 0, 1, ..., 1, 0, 0 ) (24) Q ( small*T1, small*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) diag(T2) = ( 0, 1, ..., 1, 0, 0 ) (25) Q ( big*T1, big*T2 ) Z diag(T1) = ( 0, 0, 1, ..., N-3, 0 ) diag(T2) = ( 0, 1, ..., 1, 0, 0 ) (26) Q ( T1, T2 ) Z where T1 and T2 are random upper-triangular matrices. Arguments ========= NSIZES (input) INTEGER The number of sizes of matrices to use. If it is zero, CDRGES does nothing. NSIZES >= 0. NN (input) INTEGER array, dimension (NSIZES) An array containing the sizes to be used for the matrices. Zero values will be skipped. NN >= 0. NTYPES (input) INTEGER The number of elements in DOTYPE. If it is zero, CDRGEV does nothing. It must be at least zero. If it is MAXTYP+1 and NSIZES is 1, then an additional type, MAXTYP+1 is defined, which is to use whatever matrix is in A. This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and DOTYPE(MAXTYP+1) is .TRUE. . DOTYPE (input) LOGICAL array, dimension (NTYPES) If DOTYPE(j) is .TRUE., then for each size in NN a matrix of that size and of type j will be generated. If NTYPES is smaller than the maximum number of types defined (PARAMETER MAXTYP), then types NTYPES+1 through MAXTYP will not be generated. If NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES) will be ignored. ISEED (input/output) INTEGER array, dimension (4) On entry ISEED specifies the seed of the random number generator. The array elements should be between 0 and 4095; if not they will be reduced mod 4096. Also, ISEED(4) must be odd. The random number generator uses a linear congruential sequence limited to small integers, and so should produce machine independent random numbers. The values of ISEED are changed on exit, and can be used in the next call to CDRGES to continue the same random number sequence. THRESH (input) REAL A test will count as "failed" if the "error", computed as described above, exceeds THRESH. Note that the error is scaled to be O(1), so THRESH should be a reasonably small multiple of 1, e.g., 10 or 100. In particular, it should not depend on the precision (single vs. double) or the size of the matrix. It must be at least zero. NOUNIT (input) INTEGER The FORTRAN unit number for printing out error messages (e.g., if a routine returns IERR not equal to 0.) A (input/workspace) COMPLEX array, dimension(LDA, max(NN)) Used to hold the original A matrix. Used as input only if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and DOTYPE(MAXTYP+1)=.TRUE. LDA (input) INTEGER The leading dimension of A, B, S, and T. It must be at least 1 and at least max( NN ). B (input/workspace) COMPLEX array, dimension(LDA, max(NN)) Used to hold the original B matrix. Used as input only if NTYPES=MAXTYP+1, DOTYPE(1:MAXTYP)=.FALSE., and DOTYPE(MAXTYP+1)=.TRUE. S (workspace) COMPLEX array, dimension (LDA, max(NN)) The Schur form matrix computed from A by CGGEV. On exit, S contains the Schur form matrix corresponding to the matrix in A. T (workspace) COMPLEX array, dimension (LDA, max(NN)) The upper triangular matrix computed from B by CGGEV. Q (workspace) COMPLEX array, dimension (LDQ, max(NN)) The (left) eigenvectors matrix computed by CGGEV. LDQ (input) INTEGER The leading dimension of Q and Z. It must be at least 1 and at least max( NN ). Z (workspace) COMPLEX array, dimension( LDQ, max(NN) ) The (right) orthogonal matrix computed by CGGEV. QE (workspace) COMPLEX array, dimension( LDQ, max(NN) ) QE holds the computed right or left eigenvectors. LDQE (input) INTEGER The leading dimension of QE. LDQE >= max(1,max(NN)). ALPHA (workspace) COMPLEX array, dimension (max(NN)) BETA (workspace) COMPLEX array, dimension (max(NN)) The generalized eigenvalues of (A,B) computed by CGGEV. ( ALPHAR(k)+ALPHAI(k)*i ) / BETA(k) is the k-th generalized eigenvalue of A and B. ALPHA1 (workspace) COMPLEX array, dimension (max(NN)) BETA1 (workspace) COMPLEX array, dimension (max(NN)) Like ALPHAR, ALPHAI, BETA, these arrays contain the eigenvalues of A and B, but those computed when CGGEV only computes a partial eigendecomposition, i.e. not the eigenvalues and left and right eigenvectors. WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The number of entries in WORK. LWORK >= N*(N+1) RWORK (workspace) REAL array, dimension (8*N) Real workspace. RESULT (output) REAL array, dimension (2) The values computed by the tests described above. The values are currently limited to 1/ulp, to avoid overflow. INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. > 0: A routine returned an error code. INFO is the absolute value of the INFO value returned. ===================================================================== Parameter adjustments */ --nn; --dotype; --iseed; t_dim1 = *lda; t_offset = 1 + t_dim1 * 1; t -= t_offset; s_dim1 = *lda; s_offset = 1 + s_dim1 * 1; s -= s_offset; b_dim1 = *lda; b_offset = 1 + b_dim1 * 1; b -= b_offset; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; z_dim1 = *ldq; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; qe_dim1 = *ldqe; qe_offset = 1 + qe_dim1 * 1; qe -= qe_offset; --alpha; --beta; --alpha1; --beta1; --work; --rwork; --result; /* Function Body Check for errors */ *info = 0; badnn = FALSE_; nmax = 1; i__1 = *nsizes; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = nmax, i__3 = nn[j]; nmax = max(i__2,i__3); if (nn[j] < 0) { badnn = TRUE_; } /* L10: */ } if (*nsizes < 0) { *info = -1; } else if (badnn) { *info = -2; } else if (*ntypes < 0) { *info = -3; } else if (*thresh < 0.f) { *info = -6; } else if (*lda <= 1 || *lda < nmax) { *info = -9; } else if (*ldq <= 1 || *ldq < nmax) { *info = -14; } else if (*ldqe <= 1 || *ldqe < nmax) { *info = -17; } /* Compute workspace (Note: Comments in the code beginning "Workspace:" describe the minimal amount of workspace needed at that point in the code, as well as the preferred amount for good performance. NB refers to the optimal block size for the immediately following subroutine, as returned by ILAENV. */ minwrk = 1; if (*info == 0 && *lwork >= 1) { minwrk = nmax * (nmax + 1); /* Computing MAX */ i__1 = 1, i__2 = ilaenv_(&c__1, "CGEQRF", " ", &nmax, &nmax, &c_n1, & c_n1, (ftnlen)6, (ftnlen)1), i__1 = max(i__1,i__2), i__2 = ilaenv_(&c__1, "CUNMQR", "LC", &nmax, &nmax, &nmax, &c_n1, ( ftnlen)6, (ftnlen)2), i__1 = max(i__1,i__2), i__2 = ilaenv_(& c__1, "CUNGQR", " ", &nmax, &nmax, &nmax, &c_n1, (ftnlen)6, ( ftnlen)1); nb = max(i__1,i__2); /* Computing MAX */ i__1 = nmax << 1, i__2 = nmax * (nb + 1), i__1 = max(i__1,i__2), i__2 = nmax * (nmax + 1); maxwrk = max(i__1,i__2); work[1].r = (real) maxwrk, work[1].i = 0.f; } if (*lwork < minwrk) { *info = -23; } if (*info != 0) { i__1 = -(*info); xerbla_("CDRGEV", &i__1); return 0; } /* Quick return if possible */ if (*nsizes == 0 || *ntypes == 0) { return 0; } ulp = slamch_("Precision"); safmin = slamch_("Safe minimum"); safmin /= ulp; safmax = 1.f / safmin; slabad_(&safmin, &safmax); ulpinv = 1.f / ulp; /* The values RMAGN(2:3) depend on N, see below. */ rmagn[0] = 0.f; rmagn[1] = 1.f; /* Loop over sizes, types */ ntestt = 0; nerrs = 0; nmats = 0; i__1 = *nsizes; for (jsize = 1; jsize <= i__1; ++jsize) { n = nn[jsize]; n1 = max(1,n); rmagn[2] = safmax * ulp / (real) n1; rmagn[3] = safmin * ulpinv * n1; if (*nsizes != 1) { mtypes = min(26,*ntypes); } else { mtypes = min(27,*ntypes); } i__2 = mtypes; for (jtype = 1; jtype <= i__2; ++jtype) { if (! dotype[jtype]) { goto L210; } ++nmats; /* Save ISEED in case of an error. */ for (j = 1; j <= 4; ++j) { ioldsd[j - 1] = iseed[j]; /* L20: */ } /* Generate test matrices A and B Description of control parameters: KCLASS: =1 means w/o rotation, =2 means w/ rotation, =3 means random. KATYPE: the "type" to be passed to CLATM4 for computing A. KAZERO: the pattern of zeros on the diagonal for A: =1: ( xxx ), =2: (0, xxx ) =3: ( 0, 0, xxx, 0 ), =4: ( 0, xxx, 0, 0 ), =5: ( 0, 0, 1, xxx, 0 ), =6: ( 0, 1, 0, xxx, 0 ). (xxx means a string of non-zero entries.) KAMAGN: the magnitude of the matrix: =0: zero, =1: O(1), =2: large, =3: small. LASIGN: .TRUE. if the diagonal elements of A are to be multiplied by a random magnitude 1 number. KBTYPE, KBZERO, KBMAGN, LBSIGN: the same, but for B. KTRIAN: =0: don't fill in the upper triangle, =1: do. KZ1, KZ2, KADD: used to implement KAZERO and KBZERO. RMAGN: used to implement KAMAGN and KBMAGN. */ if (mtypes > 26) { goto L100; } ierr = 0; if (kclass[jtype - 1] < 3) { /* Generate A (w/o rotation) */ if ((i__3 = katype[jtype - 1], abs(i__3)) == 3) { in = ((n - 1) / 2 << 1) + 1; if (in != n) { claset_("Full", &n, &n, &c_b1, &c_b1, &a[a_offset], lda); } } else { in = n; } clatm4_(&katype[jtype - 1], &in, &kz1[kazero[jtype - 1] - 1], &kz2[kazero[jtype - 1] - 1], &lasign[jtype - 1], & rmagn[kamagn[jtype - 1]], &ulp, &rmagn[ktrian[jtype - 1] * kamagn[jtype - 1]], &c__2, &iseed[1], &a[ a_offset], lda); iadd = kadd[kazero[jtype - 1] - 1]; if (iadd > 0 && iadd <= n) { i__3 = a_subscr(iadd, iadd); i__4 = kamagn[jtype - 1]; a[i__3].r = rmagn[i__4], a[i__3].i = 0.f; } /* Generate B (w/o rotation) */ if ((i__3 = kbtype[jtype - 1], abs(i__3)) == 3) { in = ((n - 1) / 2 << 1) + 1; if (in != n) { claset_("Full", &n, &n, &c_b1, &c_b1, &b[b_offset], lda); } } else { in = n; } clatm4_(&kbtype[jtype - 1], &in, &kz1[kbzero[jtype - 1] - 1], &kz2[kbzero[jtype - 1] - 1], &lbsign[jtype - 1], & rmagn[kbmagn[jtype - 1]], &c_b28, &rmagn[ktrian[jtype - 1] * kbmagn[jtype - 1]], &c__2, &iseed[1], &b[ b_offset], lda); iadd = kadd[kbzero[jtype - 1] - 1]; if (iadd != 0 && iadd <= n) { i__3 = b_subscr(iadd, iadd); i__4 = kbmagn[jtype - 1]; b[i__3].r = rmagn[i__4], b[i__3].i = 0.f; } if (kclass[jtype - 1] == 2 && n > 0) { /* Include rotations Generate Q, Z as Householder transformations times a diagonal matrix. */ i__3 = n - 1; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = jc; jr <= i__4; ++jr) { i__5 = q_subscr(jr, jc); clarnd_(&q__1, &c__3, &iseed[1]); q[i__5].r = q__1.r, q[i__5].i = q__1.i; i__5 = z___subscr(jr, jc); clarnd_(&q__1, &c__3, &iseed[1]); z__[i__5].r = q__1.r, z__[i__5].i = q__1.i; /* L30: */ } i__4 = n + 1 - jc; clarfg_(&i__4, &q_ref(jc, jc), &q_ref(jc + 1, jc), & c__1, &work[jc]); i__4 = (n << 1) + jc; i__5 = q_subscr(jc, jc); r__2 = q[i__5].r; r__1 = r_sign(&c_b28, &r__2); work[i__4].r = r__1, work[i__4].i = 0.f; i__4 = q_subscr(jc, jc); q[i__4].r = 1.f, q[i__4].i = 0.f; i__4 = n + 1 - jc; clarfg_(&i__4, &z___ref(jc, jc), &z___ref(jc + 1, jc), &c__1, &work[n + jc]); i__4 = n * 3 + jc; i__5 = z___subscr(jc, jc); r__2 = z__[i__5].r; r__1 = r_sign(&c_b28, &r__2); work[i__4].r = r__1, work[i__4].i = 0.f; i__4 = z___subscr(jc, jc); z__[i__4].r = 1.f, z__[i__4].i = 0.f; /* L40: */ } clarnd_(&q__1, &c__3, &iseed[1]); ctemp.r = q__1.r, ctemp.i = q__1.i; i__3 = q_subscr(n, n); q[i__3].r = 1.f, q[i__3].i = 0.f; i__3 = n; work[i__3].r = 0.f, work[i__3].i = 0.f; i__3 = n * 3; r__1 = c_abs(&ctemp); q__1.r = ctemp.r / r__1, q__1.i = ctemp.i / r__1; work[i__3].r = q__1.r, work[i__3].i = q__1.i; clarnd_(&q__1, &c__3, &iseed[1]); ctemp.r = q__1.r, ctemp.i = q__1.i; i__3 = z___subscr(n, n); z__[i__3].r = 1.f, z__[i__3].i = 0.f; i__3 = n << 1; work[i__3].r = 0.f, work[i__3].i = 0.f; i__3 = n << 2; r__1 = c_abs(&ctemp); q__1.r = ctemp.r / r__1, q__1.i = ctemp.i / r__1; work[i__3].r = q__1.r, work[i__3].i = q__1.i; /* Apply the diagonal matrices */ i__3 = n; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = 1; jr <= i__4; ++jr) { i__5 = a_subscr(jr, jc); i__6 = (n << 1) + jr; r_cnjg(&q__3, &work[n * 3 + jc]); q__2.r = work[i__6].r * q__3.r - work[i__6].i * q__3.i, q__2.i = work[i__6].r * q__3.i + work[i__6].i * q__3.r; i__7 = a_subscr(jr, jc); q__1.r = q__2.r * a[i__7].r - q__2.i * a[i__7].i, q__1.i = q__2.r * a[i__7].i + q__2.i * a[ i__7].r; a[i__5].r = q__1.r, a[i__5].i = q__1.i; i__5 = b_subscr(jr, jc); i__6 = (n << 1) + jr; r_cnjg(&q__3, &work[n * 3 + jc]); q__2.r = work[i__6].r * q__3.r - work[i__6].i * q__3.i, q__2.i = work[i__6].r * q__3.i + work[i__6].i * q__3.r; i__7 = b_subscr(jr, jc); q__1.r = q__2.r * b[i__7].r - q__2.i * b[i__7].i, q__1.i = q__2.r * b[i__7].i + q__2.i * b[ i__7].r; b[i__5].r = q__1.r, b[i__5].i = q__1.i; /* L50: */ } /* L60: */ } i__3 = n - 1; cunm2r_("L", "N", &n, &n, &i__3, &q[q_offset], ldq, &work[ 1], &a[a_offset], lda, &work[(n << 1) + 1], &ierr); if (ierr != 0) { goto L90; } i__3 = n - 1; cunm2r_("R", "C", &n, &n, &i__3, &z__[z_offset], ldq, & work[n + 1], &a[a_offset], lda, &work[(n << 1) + 1], &ierr); if (ierr != 0) { goto L90; } i__3 = n - 1; cunm2r_("L", "N", &n, &n, &i__3, &q[q_offset], ldq, &work[ 1], &b[b_offset], lda, &work[(n << 1) + 1], &ierr); if (ierr != 0) { goto L90; } i__3 = n - 1; cunm2r_("R", "C", &n, &n, &i__3, &z__[z_offset], ldq, & work[n + 1], &b[b_offset], lda, &work[(n << 1) + 1], &ierr); if (ierr != 0) { goto L90; } } } else { /* Random matrices */ i__3 = n; for (jc = 1; jc <= i__3; ++jc) { i__4 = n; for (jr = 1; jr <= i__4; ++jr) { i__5 = a_subscr(jr, jc); i__6 = kamagn[jtype - 1]; clarnd_(&q__2, &c__4, &iseed[1]); q__1.r = rmagn[i__6] * q__2.r, q__1.i = rmagn[i__6] * q__2.i; a[i__5].r = q__1.r, a[i__5].i = q__1.i; i__5 = b_subscr(jr, jc); i__6 = kbmagn[jtype - 1]; clarnd_(&q__2, &c__4, &iseed[1]); q__1.r = rmagn[i__6] * q__2.r, q__1.i = rmagn[i__6] * q__2.i; b[i__5].r = q__1.r, b[i__5].i = q__1.i; /* L70: */ } /* L80: */ } } L90: if (ierr != 0) { io___40.ciunit = *nounit; s_wsfe(&io___40); do_fio(&c__1, "Generator", (ftnlen)9); do_fio(&c__1, (char *)&ierr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(ierr); return 0; } L100: for (i__ = 1; i__ <= 7; ++i__) { result[i__] = -1.f; /* L110: */ } /* Call CGGEV to compute eigenvalues and eigenvectors. */ clacpy_(" ", &n, &n, &a[a_offset], lda, &s[s_offset], lda); clacpy_(" ", &n, &n, &b[b_offset], lda, &t[t_offset], lda); cggev_("V", "V", &n, &s[s_offset], lda, &t[t_offset], lda, &alpha[ 1], &beta[1], &q[q_offset], ldq, &z__[z_offset], ldq, & work[1], lwork, &rwork[1], &ierr); if (ierr != 0 && ierr != n + 1) { result[1] = ulpinv; io___42.ciunit = *nounit; s_wsfe(&io___42); do_fio(&c__1, "CGGEV1", (ftnlen)6); do_fio(&c__1, (char *)&ierr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(ierr); goto L190; } /* Do the tests (1) and (2) */ cget52_(&c_true, &n, &a[a_offset], lda, &b[b_offset], lda, &q[ q_offset], ldq, &alpha[1], &beta[1], &work[1], &rwork[1], &result[1]); if (result[2] > *thresh) { io___43.ciunit = *nounit; s_wsfe(&io___43); do_fio(&c__1, "Left", (ftnlen)4); do_fio(&c__1, "CGGEV1", (ftnlen)6); do_fio(&c__1, (char *)&result[2], (ftnlen)sizeof(real)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); } /* Do the tests (3) and (4) */ cget52_(&c_false, &n, &a[a_offset], lda, &b[b_offset], lda, &z__[ z_offset], ldq, &alpha[1], &beta[1], &work[1], &rwork[1], &result[3]); if (result[4] > *thresh) { io___44.ciunit = *nounit; s_wsfe(&io___44); do_fio(&c__1, "Right", (ftnlen)5); do_fio(&c__1, "CGGEV1", (ftnlen)6); do_fio(&c__1, (char *)&result[4], (ftnlen)sizeof(real)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); } /* Do test (5) */ clacpy_(" ", &n, &n, &a[a_offset], lda, &s[s_offset], lda); clacpy_(" ", &n, &n, &b[b_offset], lda, &t[t_offset], lda); cggev_("N", "N", &n, &s[s_offset], lda, &t[t_offset], lda, & alpha1[1], &beta1[1], &q[q_offset], ldq, &z__[z_offset], ldq, &work[1], lwork, &rwork[1], &ierr); if (ierr != 0 && ierr != n + 1) { result[1] = ulpinv; io___45.ciunit = *nounit; s_wsfe(&io___45); do_fio(&c__1, "CGGEV2", (ftnlen)6); do_fio(&c__1, (char *)&ierr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(ierr); goto L190; } i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; i__6 = j; i__7 = j; if (alpha[i__4].r != alpha1[i__5].r || alpha[i__4].i != alpha1[i__5].i || (beta[i__6].r != beta1[i__7].r || beta[i__6].i != beta1[i__7].i)) { result[5] = ulpinv; } /* L120: */ } /* Do test (6): Compute eigenvalues and left eigenvectors, and test them */ clacpy_(" ", &n, &n, &a[a_offset], lda, &s[s_offset], lda); clacpy_(" ", &n, &n, &b[b_offset], lda, &t[t_offset], lda); cggev_("V", "N", &n, &s[s_offset], lda, &t[t_offset], lda, & alpha1[1], &beta1[1], &qe[qe_offset], ldqe, &z__[z_offset] , ldq, &work[1], lwork, &rwork[1], &ierr); if (ierr != 0 && ierr != n + 1) { result[1] = ulpinv; io___46.ciunit = *nounit; s_wsfe(&io___46); do_fio(&c__1, "CGGEV3", (ftnlen)6); do_fio(&c__1, (char *)&ierr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(ierr); goto L190; } i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; i__6 = j; i__7 = j; if (alpha[i__4].r != alpha1[i__5].r || alpha[i__4].i != alpha1[i__5].i || (beta[i__6].r != beta1[i__7].r || beta[i__6].i != beta1[i__7].i)) { result[6] = ulpinv; } /* L130: */ } i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (jc = 1; jc <= i__4; ++jc) { i__5 = q_subscr(j, jc); i__6 = qe_subscr(j, jc); if (q[i__5].r != qe[i__6].r || q[i__5].i != qe[i__6].i) { result[6] = ulpinv; } /* L140: */ } /* L150: */ } /* Do test (7): Compute eigenvalues and right eigenvectors, and test them */ clacpy_(" ", &n, &n, &a[a_offset], lda, &s[s_offset], lda); clacpy_(" ", &n, &n, &b[b_offset], lda, &t[t_offset], lda); cggev_("N", "V", &n, &s[s_offset], lda, &t[t_offset], lda, & alpha1[1], &beta1[1], &q[q_offset], ldq, &qe[qe_offset], ldqe, &work[1], lwork, &rwork[1], &ierr); if (ierr != 0 && ierr != n + 1) { result[1] = ulpinv; io___47.ciunit = *nounit; s_wsfe(&io___47); do_fio(&c__1, "CGGEV4", (ftnlen)6); do_fio(&c__1, (char *)&ierr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)); do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof(integer)); e_wsfe(); *info = abs(ierr); goto L190; } i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = j; i__5 = j; i__6 = j; i__7 = j; if (alpha[i__4].r != alpha1[i__5].r || alpha[i__4].i != alpha1[i__5].i || (beta[i__6].r != beta1[i__7].r || beta[i__6].i != beta1[i__7].i)) { result[7] = ulpinv; } /* L160: */ } i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (jc = 1; jc <= i__4; ++jc) { i__5 = z___subscr(j, jc); i__6 = qe_subscr(j, jc); if (z__[i__5].r != qe[i__6].r || z__[i__5].i != qe[i__6] .i) { result[7] = ulpinv; } /* L170: */ } /* L180: */ } /* End of Loop -- Check for RESULT(j) > THRESH */ L190: ntestt += 7; /* Print out tests which fail. */ for (jr = 1; jr <= 9; ++jr) { if (result[jr] >= *thresh) { /* If this is the first test to fail, print a header to the data file. */ if (nerrs == 0) { io___48.ciunit = *nounit; s_wsfe(&io___48); do_fio(&c__1, "CGV", (ftnlen)3); e_wsfe(); /* Matrix types */ io___49.ciunit = *nounit; s_wsfe(&io___49); e_wsfe(); io___50.ciunit = *nounit; s_wsfe(&io___50); e_wsfe(); io___51.ciunit = *nounit; s_wsfe(&io___51); do_fio(&c__1, "Orthogonal", (ftnlen)10); e_wsfe(); /* Tests performed */ io___52.ciunit = *nounit; s_wsfe(&io___52); e_wsfe(); } ++nerrs; if (result[jr] < 1e4f) { io___53.ciunit = *nounit; s_wsfe(&io___53); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)) ; do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&jr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[jr], (ftnlen)sizeof( real)); e_wsfe(); } else { io___54.ciunit = *nounit; s_wsfe(&io___54); do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&jtype, (ftnlen)sizeof(integer)) ; do_fio(&c__4, (char *)&ioldsd[0], (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&jr, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&result[jr], (ftnlen)sizeof( real)); e_wsfe(); } } /* L200: */ } L210: ; } /* L220: */ } /* Summary */ alasvm_("CGV", nounit, &nerrs, &ntestt, &c__0); work[1].r = (real) maxwrk, work[1].i = 0.f; return 0; /* End of CDRGEV */ } /* cdrgev_ */
/* Subroutine */ int cunmr3_(char *side, char *trans, integer *m, integer *n, integer *k, integer *l, complex *a, integer *lda, complex *tau, complex *c__, integer *ldc, complex *work, integer *info) { /* System generated locals */ integer a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__3; complex q__1; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ integer i__, i1, i2, i3, ja, ic, jc, mi, ni, nq; logical left; complex taui; extern logical lsame_(char *, char *); extern /* Subroutine */ int clarz_(char *, integer *, integer *, integer * , complex *, integer *, complex *, complex *, integer *, complex * ), xerbla_(char *, integer *); logical notran; /* -- LAPACK routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CUNMR3 overwrites the general complex m by n matrix C with */ /* Q * C if SIDE = 'L' and TRANS = 'N', or */ /* Q'* C if SIDE = 'L' and TRANS = 'C', or */ /* C * Q if SIDE = 'R' and TRANS = 'N', or */ /* C * Q' if SIDE = 'R' and TRANS = 'C', */ /* where Q is a complex unitary matrix defined as the product of k */ /* elementary reflectors */ /* Q = H(1) H(2) . . . H(k) */ /* as returned by CTZRZF. Q is of order m if SIDE = 'L' and of order n */ /* if SIDE = 'R'. */ /* Arguments */ /* ========= */ /* SIDE (input) CHARACTER*1 */ /* = 'L': apply Q or Q' from the Left */ /* = 'R': apply Q or Q' from the Right */ /* TRANS (input) CHARACTER*1 */ /* = 'N': apply Q (No transpose) */ /* = 'C': apply Q' (Conjugate transpose) */ /* M (input) INTEGER */ /* The number of rows of the matrix C. M >= 0. */ /* N (input) INTEGER */ /* The number of columns of the matrix C. N >= 0. */ /* K (input) INTEGER */ /* The number of elementary reflectors whose product defines */ /* the matrix Q. */ /* If SIDE = 'L', M >= K >= 0; */ /* if SIDE = 'R', N >= K >= 0. */ /* L (input) INTEGER */ /* The number of columns of the matrix A containing */ /* the meaningful part of the Householder reflectors. */ /* If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0. */ /* A (input) COMPLEX array, dimension */ /* (LDA,M) if SIDE = 'L', */ /* (LDA,N) if SIDE = 'R' */ /* The i-th row must contain the vector which defines the */ /* elementary reflector H(i), for i = 1,2,...,k, as returned by */ /* CTZRZF in the last k rows of its array argument A. */ /* A is modified by the routine but restored on exit. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,K). */ /* TAU (input) COMPLEX array, dimension (K) */ /* TAU(i) must contain the scalar factor of the elementary */ /* reflector H(i), as returned by CTZRZF. */ /* C (input/output) COMPLEX array, dimension (LDC,N) */ /* On entry, the m-by-n matrix C. */ /* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. */ /* LDC (input) INTEGER */ /* The leading dimension of the array C. LDC >= max(1,M). */ /* WORK (workspace) COMPLEX array, dimension */ /* (N) if SIDE = 'L', */ /* (M) if SIDE = 'R' */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* Further Details */ /* =============== */ /* Based on contributions by */ /* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA */ /* ===================================================================== */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input arguments */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_(side, "L"); notran = lsame_(trans, "N"); /* NQ is the order of Q */ if (left) { nq = *m; } else { nq = *n; } if (! left && ! lsame_(side, "R")) { *info = -1; } else if (! notran && ! lsame_(trans, "C")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*l < 0 || left && *l > *m || ! left && *l > *n) { *info = -6; } else if (*lda < max(1,*k)) { *info = -8; } else if (*ldc < max(1,*m)) { *info = -11; } if (*info != 0) { i__1 = -(*info); xerbla_("CUNMR3", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { return 0; } if (left && ! notran || ! left && notran) { i1 = 1; i2 = *k; i3 = 1; } else { i1 = *k; i2 = 1; i3 = -1; } if (left) { ni = *n; ja = *m - *l + 1; jc = 1; } else { mi = *m; ja = *n - *l + 1; ic = 1; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { if (left) { /* H(i) or H(i)' is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H(i) or H(i)' is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H(i) or H(i)' */ if (notran) { i__3 = i__; taui.r = tau[i__3].r, taui.i = tau[i__3].i; } else { r_cnjg(&q__1, &tau[i__]); taui.r = q__1.r, taui.i = q__1.i; } clarz_(side, &mi, &ni, l, &a[i__ + ja * a_dim1], lda, &taui, &c__[ic + jc * c_dim1], ldc, &work[1]); /* L10: */ } return 0; /* End of CUNMR3 */ } /* cunmr3_ */
/* Subroutine */ int cgemv_(char *trans, integer *m, integer *n, complex * alpha, complex *a, integer *lda, complex *x, integer *incx, complex * beta, complex *y, integer *incy) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; complex q__1, q__2, q__3; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ static integer info; static complex temp; static integer lenx, leny, i, j; static integer ix, iy, jx, jy, kx, ky; static logical noconj; extern int input_error(char *, int *); /* Purpose ======= CGEMV performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, or y := alpha*conjg( A' )*x + beta*y, where alpha and beta are scalars, x and y are vectors and A is an m by n matrix. Parameters ========== TRANS - CHARACTER*1. On entry, TRANS specifies the operation to be performed as follows: TRANS = 'N' or 'n' y := alpha*A*x + beta*y. TRANS = 'T' or 't' y := alpha*A'*x + beta*y. TRANS = 'C' or 'c' y := alpha*conjg( A' )*x + beta*y. Unchanged on exit. M - INTEGER. On entry, M specifies the number of rows of the matrix A. M must be at least zero. Unchanged on exit. N - INTEGER. On entry, N specifies the number of columns of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - COMPLEX . On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - COMPLEX array of DIMENSION ( LDA, n ). Before entry, the leading m by n part of the array A must contain the matrix of coefficients. Unchanged on exit. LDA - INTEGER. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, m ). Unchanged on exit. X - COMPLEX array of DIMENSION at least ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' and at least ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. Before entry, the incremented array X must contain the vector x. Unchanged on exit. INCX - INTEGER. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. BETA - COMPLEX . On entry, BETA specifies the scalar beta. When BETA is supplied as zero then Y need not be set on input. Unchanged on exit. Y - COMPLEX array of DIMENSION at least ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' and at least ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. Before entry with BETA non-zero, the incremented array Y must contain the vector y. On exit, Y is overwritten by the updated vector y. INCY - INTEGER. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. Test the input parameters. Parameter adjustments Function Body */ #define X(I) x[(I)-1] #define Y(I) y[(I)-1] #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] info = 0; if ( strncmp(trans, "N", 1)!=0 && strncmp(trans, "T", 1)!=0 && strncmp(trans, "C", 1) != 0) { info = 1; } else if (*m < 0) { info = 2; } else if (*n < 0) { info = 3; } else if (*lda < max(1,*m)) { info = 6; } else if (*incx == 0) { info = 8; } else if (*incy == 0) { info = 11; } if (info != 0) { input_error("CGEMV ", &info); return 0; } /* Quick return if possible. */ if (*m == 0 || *n == 0 || alpha->r == 0.f && alpha->i == 0.f && (beta->r == 1.f && beta->i == 0.f)) { return 0; } noconj = (strncmp(trans, "T", 1)==0); /* Set LENX and LENY, the lengths of the vectors x and y, and set up the start points in X and Y. */ if (strncmp(trans, "N", 1)==0) { lenx = *n; leny = *m; } else { lenx = *m; leny = *n; } if (*incx > 0) { kx = 1; } else { kx = 1 - (lenx - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (leny - 1) * *incy; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through A. First form y := beta*y. */ if (beta->r != 1.f || beta->i != 0.f) { if (*incy == 1) { if (beta->r == 0.f && beta->i == 0.f) { i__1 = leny; for (i = 1; i <= leny; ++i) { i__2 = i; Y(i).r = 0.f, Y(i).i = 0.f; /* L10: */ } } else { i__1 = leny; for (i = 1; i <= leny; ++i) { i__2 = i; i__3 = i; q__1.r = beta->r * Y(i).r - beta->i * Y(i).i, q__1.i = beta->r * Y(i).i + beta->i * Y(i) .r; Y(i).r = q__1.r, Y(i).i = q__1.i; /* L20: */ } } } else { iy = ky; if (beta->r == 0.f && beta->i == 0.f) { i__1 = leny; for (i = 1; i <= leny; ++i) { i__2 = iy; Y(iy).r = 0.f, Y(iy).i = 0.f; iy += *incy; /* L30: */ } } else { i__1 = leny; for (i = 1; i <= leny; ++i) { i__2 = iy; i__3 = iy; q__1.r = beta->r * Y(iy).r - beta->i * Y(iy).i, q__1.i = beta->r * Y(iy).i + beta->i * Y(iy) .r; Y(iy).r = q__1.r, Y(iy).i = q__1.i; iy += *incy; /* L40: */ } } } } if (alpha->r == 0.f && alpha->i == 0.f) { return 0; } if (strncmp(trans, "N", 1)==0) { /* Form y := alpha*A*x + y. */ jx = kx; if (*incy == 1) { i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = jx; if (X(jx).r != 0.f || X(jx).i != 0.f) { i__2 = jx; q__1.r = alpha->r * X(jx).r - alpha->i * X(jx).i, q__1.i = alpha->r * X(jx).i + alpha->i * X(jx) .r; temp.r = q__1.r, temp.i = q__1.i; i__2 = *m; for (i = 1; i <= *m; ++i) { i__3 = i; i__4 = i; i__5 = i + j * a_dim1; q__2.r = temp.r * A(i,j).r - temp.i * A(i,j).i, q__2.i = temp.r * A(i,j).i + temp.i * A(i,j) .r; q__1.r = Y(i).r + q__2.r, q__1.i = Y(i).i + q__2.i; Y(i).r = q__1.r, Y(i).i = q__1.i; /* L50: */ } } jx += *incx; /* L60: */ } } else { i__1 = *n; for (j = 1; j <= *n; ++j) { i__2 = jx; if (X(jx).r != 0.f || X(jx).i != 0.f) { i__2 = jx; q__1.r = alpha->r * X(jx).r - alpha->i * X(jx).i, q__1.i = alpha->r * X(jx).i + alpha->i * X(jx) .r; temp.r = q__1.r, temp.i = q__1.i; iy = ky; i__2 = *m; for (i = 1; i <= *m; ++i) { i__3 = iy; i__4 = iy; i__5 = i + j * a_dim1; q__2.r = temp.r * A(i,j).r - temp.i * A(i,j).i, q__2.i = temp.r * A(i,j).i + temp.i * A(i,j) .r; q__1.r = Y(iy).r + q__2.r, q__1.i = Y(iy).i + q__2.i; Y(iy).r = q__1.r, Y(iy).i = q__1.i; iy += *incy; /* L70: */ } } jx += *incx; /* L80: */ } } } else { /* Form y := alpha*A'*x + y or y := alpha*conjg( A' )*x + y. */ jy = ky; if (*incx == 1) { i__1 = *n; for (j = 1; j <= *n; ++j) { temp.r = 0.f, temp.i = 0.f; if (noconj) { i__2 = *m; for (i = 1; i <= *m; ++i) { i__3 = i + j * a_dim1; i__4 = i; q__2.r = A(i,j).r * X(i).r - A(i,j).i * X(i) .i, q__2.i = A(i,j).r * X(i).i + A(i,j) .i * X(i).r; q__1.r = temp.r + q__2.r, q__1.i = temp.i + q__2.i; temp.r = q__1.r, temp.i = q__1.i; /* L90: */ } } else { i__2 = *m; for (i = 1; i <= *m; ++i) { r_cnjg(&q__3, &A(i,j)); i__3 = i; q__2.r = q__3.r * X(i).r - q__3.i * X(i).i, q__2.i = q__3.r * X(i).i + q__3.i * X(i) .r; q__1.r = temp.r + q__2.r, q__1.i = temp.i + q__2.i; temp.r = q__1.r, temp.i = q__1.i; /* L100: */ } } i__2 = jy; i__3 = jy; q__2.r = alpha->r * temp.r - alpha->i * temp.i, q__2.i = alpha->r * temp.i + alpha->i * temp.r; q__1.r = Y(jy).r + q__2.r, q__1.i = Y(jy).i + q__2.i; Y(jy).r = q__1.r, Y(jy).i = q__1.i; jy += *incy; /* L110: */ } } else { i__1 = *n; for (j = 1; j <= *n; ++j) { temp.r = 0.f, temp.i = 0.f; ix = kx; if (noconj) { i__2 = *m; for (i = 1; i <= *m; ++i) { i__3 = i + j * a_dim1; i__4 = ix; q__2.r = A(i,j).r * X(ix).r - A(i,j).i * X(ix) .i, q__2.i = A(i,j).r * X(ix).i + A(i,j) .i * X(ix).r; q__1.r = temp.r + q__2.r, q__1.i = temp.i + q__2.i; temp.r = q__1.r, temp.i = q__1.i; ix += *incx; /* L120: */ } } else { i__2 = *m; for (i = 1; i <= *m; ++i) { r_cnjg(&q__3, &A(i,j)); i__3 = ix; q__2.r = q__3.r * X(ix).r - q__3.i * X(ix).i, q__2.i = q__3.r * X(ix).i + q__3.i * X(ix) .r; q__1.r = temp.r + q__2.r, q__1.i = temp.i + q__2.i; temp.r = q__1.r, temp.i = q__1.i; ix += *incx; /* L130: */ } } i__2 = jy; i__3 = jy; q__2.r = alpha->r * temp.r - alpha->i * temp.i, q__2.i = alpha->r * temp.i + alpha->i * temp.r; q__1.r = Y(jy).r + q__2.r, q__1.i = Y(jy).i + q__2.i; Y(jy).r = q__1.r, Y(jy).i = q__1.i; jy += *incy; /* L140: */ } } } return 0; /* End of CGEMV . */ } /* cgemv_ */
/* Subroutine */ int cunbdb1_(integer *m, integer *p, integer *q, complex * x11, integer *ldx11, complex *x21, integer *ldx21, real *theta, real * phi, complex *taup1, complex *taup2, complex *tauq1, complex *work, integer *lwork, integer *info) { /* System generated locals */ integer x11_dim1, x11_offset, x21_dim1, x21_offset, i__1, i__2, i__3, i__4; real r__1, r__2; complex q__1; /* Builtin functions */ double atan2(doublereal, doublereal), cos(doublereal), sin(doublereal); void r_cnjg(complex *, complex *); double sqrt(doublereal); /* Local variables */ integer lworkmin, lworkopt; real c__; integer i__; real s; integer childinfo; extern /* Subroutine */ int clarf_(char *, integer *, integer *, complex * , integer *, complex *, complex *, integer *, complex *); integer ilarf, llarf; extern /* Subroutine */ int csrot_(integer *, complex *, integer *, complex *, integer *, real *, real *); extern real scnrm2_(integer *, complex *, integer *, complex *, integer *) ; extern /* Subroutine */ int clacgv_(integer *, complex *, integer *), xerbla_(char *, integer *); logical lquery; extern /* Subroutine */ int cunbdb5_(integer *, integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, integer *); integer iorbdb5, lorbdb5; extern /* Subroutine */ int clarfgp_(integer *, complex *, complex *, integer *, complex *); /* -- LAPACK computational routine (version 3.5.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* July 2012 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ==================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. Intrinsic Function .. */ /* .. */ /* .. Executable Statements .. */ /* Test input arguments */ /* Parameter adjustments */ x11_dim1 = *ldx11; x11_offset = 1 + x11_dim1; x11 -= x11_offset; x21_dim1 = *ldx21; x21_offset = 1 + x21_dim1; x21 -= x21_offset; --theta; --phi; --taup1; --taup2; --tauq1; --work; /* Function Body */ *info = 0; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*p < *q || *m - *p < *q) { *info = -2; } else if (*q < 0 || *m - *q < *q) { *info = -3; } else if (*ldx11 < max(1,*p)) { *info = -5; } else /* if(complicated condition) */ { /* Computing MAX */ i__1 = 1; i__2 = *m - *p; // , expr subst if (*ldx21 < max(i__1,i__2)) { *info = -7; } } /* Compute workspace */ if (*info == 0) { ilarf = 2; /* Computing MAX */ i__1 = *p - 1, i__2 = *m - *p - 1; i__1 = max(i__1,i__2); i__2 = *q - 1; // ; expr subst llarf = max(i__1,i__2); iorbdb5 = 2; lorbdb5 = *q - 2; /* Computing MAX */ i__1 = ilarf + llarf - 1; i__2 = iorbdb5 + lorbdb5 - 1; // , expr subst lworkopt = max(i__1,i__2); lworkmin = lworkopt; work[1].r = (real) lworkopt; work[1].i = 0.f; // , expr subst if (*lwork < lworkmin && ! lquery) { *info = -14; } } if (*info != 0) { i__1 = -(*info); xerbla_("CUNBDB1", &i__1); return 0; } else if (lquery) { return 0; } /* Reduce columns 1, ..., Q of X11 and X21 */ i__1 = *q; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = *p - i__ + 1; clarfgp_(&i__2, &x11[i__ + i__ * x11_dim1], &x11[i__ + 1 + i__ * x11_dim1], &c__1, &taup1[i__]); i__2 = *m - *p - i__ + 1; clarfgp_(&i__2, &x21[i__ + i__ * x21_dim1], &x21[i__ + 1 + i__ * x21_dim1], &c__1, &taup2[i__]); theta[i__] = atan2((real) x21[i__ + i__ * x21_dim1].r, (real) x11[i__ + i__ * x11_dim1].r); c__ = cos(theta[i__]); s = sin(theta[i__]); i__2 = i__ + i__ * x11_dim1; x11[i__2].r = 1.f; x11[i__2].i = 0.f; // , expr subst i__2 = i__ + i__ * x21_dim1; x21[i__2].r = 1.f; x21[i__2].i = 0.f; // , expr subst i__2 = *p - i__ + 1; i__3 = *q - i__; r_cnjg(&q__1, &taup1[i__]); clarf_("L", &i__2, &i__3, &x11[i__ + i__ * x11_dim1], &c__1, &q__1, & x11[i__ + (i__ + 1) * x11_dim1], ldx11, &work[ilarf]); i__2 = *m - *p - i__ + 1; i__3 = *q - i__; r_cnjg(&q__1, &taup2[i__]); clarf_("L", &i__2, &i__3, &x21[i__ + i__ * x21_dim1], &c__1, &q__1, & x21[i__ + (i__ + 1) * x21_dim1], ldx21, &work[ilarf]); if (i__ < *q) { i__2 = *q - i__; csrot_(&i__2, &x11[i__ + (i__ + 1) * x11_dim1], ldx11, &x21[i__ + (i__ + 1) * x21_dim1], ldx21, &c__, &s); i__2 = *q - i__; clacgv_(&i__2, &x21[i__ + (i__ + 1) * x21_dim1], ldx21); i__2 = *q - i__; clarfgp_(&i__2, &x21[i__ + (i__ + 1) * x21_dim1], &x21[i__ + (i__ + 2) * x21_dim1], ldx21, &tauq1[i__]); i__2 = i__ + (i__ + 1) * x21_dim1; s = x21[i__2].r; i__2 = i__ + (i__ + 1) * x21_dim1; x21[i__2].r = 1.f; x21[i__2].i = 0.f; // , expr subst i__2 = *p - i__; i__3 = *q - i__; clarf_("R", &i__2, &i__3, &x21[i__ + (i__ + 1) * x21_dim1], ldx21, &tauq1[i__], &x11[i__ + 1 + (i__ + 1) * x11_dim1], ldx11, &work[ilarf]); i__2 = *m - *p - i__; i__3 = *q - i__; clarf_("R", &i__2, &i__3, &x21[i__ + (i__ + 1) * x21_dim1], ldx21, &tauq1[i__], &x21[i__ + 1 + (i__ + 1) * x21_dim1], ldx21, &work[ilarf]); i__2 = *q - i__; clacgv_(&i__2, &x21[i__ + (i__ + 1) * x21_dim1], ldx21); i__2 = *p - i__; /* Computing 2nd power */ r__1 = scnrm2_(&i__2, &x11[i__ + 1 + (i__ + 1) * x11_dim1], &c__1, &x11[i__ + 1 + (i__ + 1) * x11_dim1], &c__1); i__3 = *m - *p - i__; /* Computing 2nd power */ r__2 = scnrm2_(&i__3, &x21[i__ + 1 + (i__ + 1) * x21_dim1], &c__1, &x21[i__ + 1 + (i__ + 1) * x21_dim1], &c__1); c__ = sqrt(r__1 * r__1 + r__2 * r__2); phi[i__] = atan2(s, c__); i__2 = *p - i__; i__3 = *m - *p - i__; i__4 = *q - i__ - 1; cunbdb5_(&i__2, &i__3, &i__4, &x11[i__ + 1 + (i__ + 1) * x11_dim1] , &c__1, &x21[i__ + 1 + (i__ + 1) * x21_dim1], &c__1, & x11[i__ + 1 + (i__ + 2) * x11_dim1], ldx11, &x21[i__ + 1 + (i__ + 2) * x21_dim1], ldx21, &work[iorbdb5], &lorbdb5, &childinfo); } } return 0; /* End of CUNBDB1 */ }
/* Subroutine */ int claev2_(complex *a, complex *b, complex *c__, real *rt1, real *rt2, real *cs1, complex *sn1) { /* System generated locals */ real r__1, r__2, r__3; complex q__1, q__2; /* Local variables */ real t; complex w; /* -- LAPACK auxiliary routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* CLAEV2 computes the eigendecomposition of a 2-by-2 Hermitian matrix */ /* [ A B ] */ /* [ CONJG(B) C ]. */ /* On return, RT1 is the eigenvalue of larger absolute value, RT2 is the */ /* eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right */ /* eigenvector for RT1, giving the decomposition */ /* [ CS1 CONJG(SN1) ] [ A B ] [ CS1 -CONJG(SN1) ] = [ RT1 0 ] */ /* [-SN1 CS1 ] [ CONJG(B) C ] [ SN1 CS1 ] [ 0 RT2 ]. */ /* Arguments */ /* ========= */ /* A (input) COMPLEX */ /* The (1,1) element of the 2-by-2 matrix. */ /* B (input) COMPLEX */ /* The (1,2) element and the conjugate of the (2,1) element of */ /* the 2-by-2 matrix. */ /* C (input) COMPLEX */ /* The (2,2) element of the 2-by-2 matrix. */ /* RT1 (output) REAL */ /* The eigenvalue of larger absolute value. */ /* RT2 (output) REAL */ /* The eigenvalue of smaller absolute value. */ /* CS1 (output) REAL */ /* SN1 (output) COMPLEX */ /* The vector (CS1, SN1) is a unit right eigenvector for RT1. */ /* Further Details */ /* =============== */ /* RT1 is accurate to a few ulps barring over/underflow. */ /* RT2 may be inaccurate if there is massive cancellation in the */ /* determinant A*C-B*B; higher precision or correctly rounded or */ /* correctly truncated arithmetic would be needed to compute RT2 */ /* accurately in all cases. */ /* CS1 and SN1 are accurate to a few ulps barring over/underflow. */ /* Overflow is possible only if RT1 is within a factor of 5 of overflow. */ /* Underflow is harmless if the input data is 0 or exceeds */ /* underflow_threshold / macheps. */ /* ===================================================================== */ if (c_abs(b) == 0.f) { w.r = 1.f, w.i = 0.f; } else { r_cnjg(&q__2, b); r__1 = c_abs(b); q__1.r = q__2.r / r__1, q__1.i = q__2.i / r__1; w.r = q__1.r, w.i = q__1.i; } r__1 = a->r; r__2 = c_abs(b); r__3 = c__->r; slaev2_(&r__1, &r__2, &r__3, rt1, rt2, cs1, &t); q__1.r = t * w.r, q__1.i = t * w.i; sn1->r = q__1.r, sn1->i = q__1.i; return 0; /* End of CLAEV2 */ } /* claev2_ */
/* Subroutine */ int chbmv_(char *uplo, integer *n, integer *k, complex * alpha, complex *a, integer *lda, complex *x, integer *incx, complex * beta, complex *y, integer *incy, ftnlen uplo_len) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; real r__1; complex q__1, q__2, q__3, q__4; /* Builtin functions */ void r_cnjg(complex *, complex *); /* Local variables */ integer i__, j, l, ix, iy, jx, jy, kx, ky, info; complex temp1, temp2; extern logical lsame_(char *, char *, ftnlen, ftnlen); integer kplus1; extern /* Subroutine */ int xerbla_(char *, integer *, ftnlen); /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CHBMV performs the matrix-vector operation */ /* y := alpha*A*x + beta*y, */ /* where alpha and beta are scalars, x and y are n element vectors and */ /* A is an n by n hermitian band matrix, with k super-diagonals. */ /* Arguments */ /* ========== */ /* UPLO - CHARACTER*1. */ /* On entry, UPLO specifies whether the upper or lower */ /* triangular part of the band matrix A is being supplied as */ /* follows: */ /* UPLO = 'U' or 'u' The upper triangular part of A is */ /* being supplied. */ /* UPLO = 'L' or 'l' The lower triangular part of A is */ /* being supplied. */ /* Unchanged on exit. */ /* N - INTEGER. */ /* On entry, N specifies the order of the matrix A. */ /* N must be at least zero. */ /* Unchanged on exit. */ /* K - INTEGER. */ /* On entry, K specifies the number of super-diagonals of the */ /* matrix A. K must satisfy 0 .le. K. */ /* Unchanged on exit. */ /* ALPHA - COMPLEX . */ /* On entry, ALPHA specifies the scalar alpha. */ /* Unchanged on exit. */ /* A - COMPLEX array of DIMENSION ( LDA, n ). */ /* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 ) */ /* by n part of the array A must contain the upper triangular */ /* band part of the hermitian matrix, supplied column by */ /* column, with the leading diagonal of the matrix in row */ /* ( k + 1 ) of the array, the first super-diagonal starting at */ /* position 2 in row k, and so on. The top left k by k triangle */ /* of the array A is not referenced. */ /* The following program segment will transfer the upper */ /* triangular part of a hermitian band matrix from conventional */ /* full matrix storage to band storage: */ /* DO 20, J = 1, N */ /* M = K + 1 - J */ /* DO 10, I = MAX( 1, J - K ), J */ /* A( M + I, J ) = matrix( I, J ) */ /* 10 CONTINUE */ /* 20 CONTINUE */ /* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 ) */ /* by n part of the array A must contain the lower triangular */ /* band part of the hermitian matrix, supplied column by */ /* column, with the leading diagonal of the matrix in row 1 of */ /* the array, the first sub-diagonal starting at position 1 in */ /* row 2, and so on. The bottom right k by k triangle of the */ /* array A is not referenced. */ /* The following program segment will transfer the lower */ /* triangular part of a hermitian band matrix from conventional */ /* full matrix storage to band storage: */ /* DO 20, J = 1, N */ /* M = 1 - J */ /* DO 10, I = J, MIN( N, J + K ) */ /* A( M + I, J ) = matrix( I, J ) */ /* 10 CONTINUE */ /* 20 CONTINUE */ /* Note that the imaginary parts of the diagonal elements need */ /* not be set and are assumed to be zero. */ /* Unchanged on exit. */ /* LDA - INTEGER. */ /* On entry, LDA specifies the first dimension of A as declared */ /* in the calling (sub) program. LDA must be at least */ /* ( k + 1 ). */ /* Unchanged on exit. */ /* X - COMPLEX array of DIMENSION at least */ /* ( 1 + ( n - 1 )*abs( INCX ) ). */ /* Before entry, the incremented array X must contain the */ /* vector x. */ /* Unchanged on exit. */ /* INCX - INTEGER. */ /* On entry, INCX specifies the increment for the elements of */ /* X. INCX must not be zero. */ /* Unchanged on exit. */ /* BETA - COMPLEX . */ /* On entry, BETA specifies the scalar beta. */ /* Unchanged on exit. */ /* Y - COMPLEX array of DIMENSION at least */ /* ( 1 + ( n - 1 )*abs( INCY ) ). */ /* Before entry, the incremented array Y must contain the */ /* vector y. On exit, Y is overwritten by the updated vector y. */ /* INCY - INTEGER. */ /* On entry, INCY specifies the increment for the elements of */ /* Y. INCY must not be zero. */ /* Unchanged on exit. */ /* Further Details */ /* =============== */ /* Level 2 Blas routine. */ /* -- Written on 22-October-1986. */ /* Jack Dongarra, Argonne National Lab. */ /* Jeremy Du Croz, Nag Central Office. */ /* Sven Hammarling, Nag Central Office. */ /* Richard Hanson, Sandia National Labs. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --x; --y; /* Function Body */ info = 0; if (! lsame_(uplo, "U", (ftnlen)1, (ftnlen)1) && ! lsame_(uplo, "L", ( ftnlen)1, (ftnlen)1)) { info = 1; } else if (*n < 0) { info = 2; } else if (*k < 0) { info = 3; } else if (*lda < *k + 1) { info = 6; } else if (*incx == 0) { info = 8; } else if (*incy == 0) { info = 11; } if (info != 0) { xerbla_("CHBMV ", &info, (ftnlen)6); return 0; } /* Quick return if possible. */ if (*n == 0 || (alpha->r == 0.f && alpha->i == 0.f && (beta->r == 1.f && beta->i == 0.f))) { return 0; } /* Set up the start points in X and Y. */ if (*incx > 0) { kx = 1; } else { kx = 1 - (*n - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (*n - 1) * *incy; } /* Start the operations. In this version the elements of the array A */ /* are accessed sequentially with one pass through A. */ /* First form y := beta*y. */ if (beta->r != 1.f || beta->i != 0.f) { if (*incy == 1) { if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; y[i__2].r = 0.f, y[i__2].i = 0.f; /* L10: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__; i__3 = i__; q__1.r = beta->r * y[i__3].r - beta->i * y[i__3].i, q__1.i = beta->r * y[i__3].i + beta->i * y[i__3] .r; y[i__2].r = q__1.r, y[i__2].i = q__1.i; /* L20: */ } } } else { iy = ky; if (beta->r == 0.f && beta->i == 0.f) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = iy; y[i__2].r = 0.f, y[i__2].i = 0.f; iy += *incy; /* L30: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = iy; i__3 = iy; q__1.r = beta->r * y[i__3].r - beta->i * y[i__3].i, q__1.i = beta->r * y[i__3].i + beta->i * y[i__3] .r; y[i__2].r = q__1.r, y[i__2].i = q__1.i; iy += *incy; /* L40: */ } } } } if (alpha->r == 0.f && alpha->i == 0.f) { return 0; } if (lsame_(uplo, "U", (ftnlen)1, (ftnlen)1)) { /* Form y when upper triangle of A is stored. */ kplus1 = *k + 1; if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; q__1.r = alpha->r * x[i__2].r - alpha->i * x[i__2].i, q__1.i = alpha->r * x[i__2].i + alpha->i * x[i__2].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; l = kplus1 - j; /* Computing MAX */ i__2 = 1, i__3 = j - *k; i__4 = j - 1; for (i__ = max(i__2,i__3); i__ <= i__4; ++i__) { i__2 = i__; i__3 = i__; i__5 = l + i__ + j * a_dim1; q__2.r = temp1.r * a[i__5].r - temp1.i * a[i__5].i, q__2.i = temp1.r * a[i__5].i + temp1.i * a[i__5] .r; q__1.r = y[i__3].r + q__2.r, q__1.i = y[i__3].i + q__2.i; y[i__2].r = q__1.r, y[i__2].i = q__1.i; r_cnjg(&q__3, &a[l + i__ + j * a_dim1]); i__2 = i__; q__2.r = q__3.r * x[i__2].r - q__3.i * x[i__2].i, q__2.i = q__3.r * x[i__2].i + q__3.i * x[i__2].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L50: */ } i__4 = j; i__2 = j; i__3 = kplus1 + j * a_dim1; r__1 = a[i__3].r; q__3.r = r__1 * temp1.r, q__3.i = r__1 * temp1.i; q__2.r = y[i__2].r + q__3.r, q__2.i = y[i__2].i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; y[i__4].r = q__1.r, y[i__4].i = q__1.i; /* L60: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__4 = jx; q__1.r = alpha->r * x[i__4].r - alpha->i * x[i__4].i, q__1.i = alpha->r * x[i__4].i + alpha->i * x[i__4].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; ix = kx; iy = ky; l = kplus1 - j; /* Computing MAX */ i__4 = 1, i__2 = j - *k; i__3 = j - 1; for (i__ = max(i__4,i__2); i__ <= i__3; ++i__) { i__4 = iy; i__2 = iy; i__5 = l + i__ + j * a_dim1; q__2.r = temp1.r * a[i__5].r - temp1.i * a[i__5].i, q__2.i = temp1.r * a[i__5].i + temp1.i * a[i__5] .r; q__1.r = y[i__2].r + q__2.r, q__1.i = y[i__2].i + q__2.i; y[i__4].r = q__1.r, y[i__4].i = q__1.i; r_cnjg(&q__3, &a[l + i__ + j * a_dim1]); i__4 = ix; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[i__4].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; ix += *incx; iy += *incy; /* L70: */ } i__3 = jy; i__4 = jy; i__2 = kplus1 + j * a_dim1; r__1 = a[i__2].r; q__3.r = r__1 * temp1.r, q__3.i = r__1 * temp1.i; q__2.r = y[i__4].r + q__3.r, q__2.i = y[i__4].i + q__3.i; q__4.r = alpha->r * temp2.r - alpha->i * temp2.i, q__4.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = q__2.r + q__4.r, q__1.i = q__2.i + q__4.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; jx += *incx; jy += *incy; if (j > *k) { kx += *incx; ky += *incy; } /* L80: */ } } } else { /* Form y when lower triangle of A is stored. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__3 = j; q__1.r = alpha->r * x[i__3].r - alpha->i * x[i__3].i, q__1.i = alpha->r * x[i__3].i + alpha->i * x[i__3].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__3 = j; i__4 = j; i__2 = j * a_dim1 + 1; r__1 = a[i__2].r; q__2.r = r__1 * temp1.r, q__2.i = r__1 * temp1.i; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; l = 1 - j; /* Computing MIN */ i__4 = *n, i__2 = j + *k; i__3 = min(i__4,i__2); for (i__ = j + 1; i__ <= i__3; ++i__) { i__4 = i__; i__2 = i__; i__5 = l + i__ + j * a_dim1; q__2.r = temp1.r * a[i__5].r - temp1.i * a[i__5].i, q__2.i = temp1.r * a[i__5].i + temp1.i * a[i__5] .r; q__1.r = y[i__2].r + q__2.r, q__1.i = y[i__2].i + q__2.i; y[i__4].r = q__1.r, y[i__4].i = q__1.i; r_cnjg(&q__3, &a[l + i__ + j * a_dim1]); i__4 = i__; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[i__4].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L90: */ } i__3 = j; i__4 = j; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; /* L100: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__3 = jx; q__1.r = alpha->r * x[i__3].r - alpha->i * x[i__3].i, q__1.i = alpha->r * x[i__3].i + alpha->i * x[i__3].r; temp1.r = q__1.r, temp1.i = q__1.i; temp2.r = 0.f, temp2.i = 0.f; i__3 = jy; i__4 = jy; i__2 = j * a_dim1 + 1; r__1 = a[i__2].r; q__2.r = r__1 * temp1.r, q__2.i = r__1 * temp1.i; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; l = 1 - j; ix = jx; iy = jy; /* Computing MIN */ i__4 = *n, i__2 = j + *k; i__3 = min(i__4,i__2); for (i__ = j + 1; i__ <= i__3; ++i__) { ix += *incx; iy += *incy; i__4 = iy; i__2 = iy; i__5 = l + i__ + j * a_dim1; q__2.r = temp1.r * a[i__5].r - temp1.i * a[i__5].i, q__2.i = temp1.r * a[i__5].i + temp1.i * a[i__5] .r; q__1.r = y[i__2].r + q__2.r, q__1.i = y[i__2].i + q__2.i; y[i__4].r = q__1.r, y[i__4].i = q__1.i; r_cnjg(&q__3, &a[l + i__ + j * a_dim1]); i__4 = ix; q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, q__2.i = q__3.r * x[i__4].i + q__3.i * x[i__4].r; q__1.r = temp2.r + q__2.r, q__1.i = temp2.i + q__2.i; temp2.r = q__1.r, temp2.i = q__1.i; /* L110: */ } i__3 = jy; i__4 = jy; q__2.r = alpha->r * temp2.r - alpha->i * temp2.i, q__2.i = alpha->r * temp2.i + alpha->i * temp2.r; q__1.r = y[i__4].r + q__2.r, q__1.i = y[i__4].i + q__2.i; y[i__3].r = q__1.r, y[i__3].i = q__1.i; jx += *incx; jy += *incy; /* L120: */ } } } return 0; /* End of CHBMV . */ } /* chbmv_ */