int f2c_cherk(char* uplo, char* trans, integer* N, integer* K, real* alpha, complex* A, integer* lda, real* beta, complex* C, integer* ldc) { cherk_(uplo, trans, N, K, alpha, A, lda, beta, C, ldc); return 0; }
void cherk(char uplo, char transa, int n, int k, float alpha, complex *a, int lda, float beta, complex *c, int ldc) { cherk_( &uplo, &transa, &n, &k, &alpha, a, &lda, &beta, c, &ldc); }
/* Subroutine */ int cpbtrf_(char *uplo, integer *n, integer *kd, complex *ab, integer *ldab, integer *info) { /* System generated locals */ integer ab_dim1, ab_offset, i__1, i__2, i__3, i__4, i__5, i__6; complex q__1; /* Local variables */ integer i__, j, i2, i3, ib, nb, ii, jj; complex work[1056] /* was [33][32] */; /* -- LAPACK routine (version 3.2) -- */ /* November 2006 */ /* Purpose */ /* ======= */ /* CPBTRF computes the Cholesky factorization of a complex Hermitian */ /* positive definite band matrix A. */ /* The factorization has the form */ /* A = U**H * U, if UPLO = 'U', or */ /* A = L * L**H, if UPLO = 'L', */ /* where U is an upper triangular matrix and L is lower triangular. */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* KD (input) INTEGER */ /* The number of superdiagonals of the matrix A if UPLO = 'U', */ /* or the number of subdiagonals if UPLO = 'L'. KD >= 0. */ /* AB (input/output) COMPLEX array, dimension (LDAB,N) */ /* On entry, the upper or lower triangle of the Hermitian band */ /* matrix A, stored in the first KD+1 rows of the array. The */ /* j-th column of A is stored in the j-th column of the array AB */ /* as follows: */ /* if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; */ /* if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd). */ /* On exit, if INFO = 0, the triangular factor U or L from the */ /* Cholesky factorization A = U**H*U or A = L*L**H of the band */ /* matrix A, in the same storage format as A. */ /* LDAB (input) INTEGER */ /* The leading dimension of the array AB. LDAB >= KD+1. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: if INFO = i, the leading minor of order i is not */ /* positive definite, and the factorization could not be */ /* completed. */ /* Further Details */ /* =============== */ /* The band storage scheme is illustrated by the following example, when */ /* N = 6, KD = 2, and UPLO = 'U': */ /* On entry: On exit: */ /* * * a13 a24 a35 a46 * * u13 u24 u35 u46 */ /* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56 */ /* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66 */ /* Similarly, if UPLO = 'L' the format of A is as follows: */ /* On entry: On exit: */ /* a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66 */ /* a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 * */ /* a31 a42 a53 a64 * * l31 l42 l53 l64 * * */ /* Array elements marked * are not used by the routine. */ /* Contributed by */ /* Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989 */ /* ===================================================================== */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; /* Function Body */ *info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*kd < 0) { *info = -3; } else if (*ldab < *kd + 1) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CPBTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine the block size for this environment */ nb = ilaenv_(&c__1, "CPBTRF", uplo, n, kd, &c_n1, &c_n1); /* The block size must not exceed the semi-bandwidth KD, and must not */ /* exceed the limit set by the size of the local array WORK. */ nb = min(nb,32); if (nb <= 1 || nb > *kd) { /* Use unblocked code */ cpbtf2_(uplo, n, kd, &ab[ab_offset], ldab, info); } else { /* Use blocked code */ if (lsame_(uplo, "U")) { /* Compute the Cholesky factorization of a Hermitian band */ /* matrix, given the upper triangle of the matrix in band */ /* storage. */ /* Zero the upper triangle of the work array. */ i__1 = nb; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * 33 - 34; work[i__3].r = 0.f, work[i__3].i = 0.f; } } /* Process the band matrix one diagonal block at a time. */ i__1 = *n; i__2 = nb; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = nb, i__4 = *n - i__ + 1; ib = min(i__3,i__4); /* Factorize the diagonal block */ i__3 = *ldab - 1; cpotf2_(uplo, &ib, &ab[*kd + 1 + i__ * ab_dim1], &i__3, &ii); if (ii != 0) { *info = i__ + ii - 1; goto L150; } if (i__ + ib <= *n) { /* Update the relevant part of the trailing submatrix. */ /* If A11 denotes the diagonal block which has just been */ /* factorized, then we need to update the remaining */ /* blocks in the diagram: */ /* A11 A12 A13 */ /* A22 A23 */ /* A33 */ /* The numbers of rows and columns in the partitioning */ /* are IB, I2, I3 respectively. The blocks A12, A22 and */ /* A23 are empty if IB = KD. The upper triangle of A13 */ /* lies outside the band. */ /* Computing MIN */ i__3 = *kd - ib, i__4 = *n - i__ - ib + 1; i2 = min(i__3,i__4); /* Computing MIN */ i__3 = ib, i__4 = *n - i__ - *kd + 1; i3 = min(i__3,i__4); if (i2 > 0) { /* Update A12 */ i__3 = *ldab - 1; i__4 = *ldab - 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-" "unit", &ib, &i2, &c_b1, &ab[*kd + 1 + i__ * ab_dim1], &i__3, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__4); /* Update A22 */ i__3 = *ldab - 1; i__4 = *ldab - 1; cherk_("Upper", "Conjugate transpose", &i2, &ib, & c_b21, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__3, &c_b22, &ab[*kd + 1 + (i__ + ib) * ab_dim1], &i__4); } if (i3 > 0) { /* Copy the lower triangle of A13 into the work array. */ i__3 = i3; for (jj = 1; jj <= i__3; ++jj) { i__4 = ib; for (ii = jj; ii <= i__4; ++ii) { i__5 = ii + jj * 33 - 34; i__6 = ii - jj + 1 + (jj + i__ + *kd - 1) * ab_dim1; work[i__5].r = ab[i__6].r, work[i__5].i = ab[ i__6].i; } } /* Update A13 (in the work array). */ i__3 = *ldab - 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-" "unit", &ib, &i3, &c_b1, &ab[*kd + 1 + i__ * ab_dim1], &i__3, work, &c__33); /* Update A23 */ if (i2 > 0) { q__1.r = -1.f, q__1.i = -0.f; i__3 = *ldab - 1; i__4 = *ldab - 1; cgemm_("Conjugate transpose", "No transpose", &i2, &i3, &ib, &q__1, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__3, work, &c__33, & c_b1, &ab[ib + 1 + (i__ + *kd) * ab_dim1], &i__4); } /* Update A33 */ i__3 = *ldab - 1; cherk_("Upper", "Conjugate transpose", &i3, &ib, & c_b21, work, &c__33, &c_b22, &ab[*kd + 1 + ( i__ + *kd) * ab_dim1], &i__3); /* Copy the lower triangle of A13 back into place. */ i__3 = i3; for (jj = 1; jj <= i__3; ++jj) { i__4 = ib; for (ii = jj; ii <= i__4; ++ii) { i__5 = ii - jj + 1 + (jj + i__ + *kd - 1) * ab_dim1; i__6 = ii + jj * 33 - 34; ab[i__5].r = work[i__6].r, ab[i__5].i = work[ i__6].i; } } } } } } else { /* Compute the Cholesky factorization of a Hermitian band */ /* matrix, given the lower triangle of the matrix in band */ /* storage. */ /* Zero the lower triangle of the work array. */ i__2 = nb; for (j = 1; j <= i__2; ++j) { i__1 = nb; for (i__ = j + 1; i__ <= i__1; ++i__) { i__3 = i__ + j * 33 - 34; work[i__3].r = 0.f, work[i__3].i = 0.f; } } /* Process the band matrix one diagonal block at a time. */ i__2 = *n; i__1 = nb; for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) { /* Computing MIN */ i__3 = nb, i__4 = *n - i__ + 1; ib = min(i__3,i__4); /* Factorize the diagonal block */ i__3 = *ldab - 1; cpotf2_(uplo, &ib, &ab[i__ * ab_dim1 + 1], &i__3, &ii); if (ii != 0) { *info = i__ + ii - 1; goto L150; } if (i__ + ib <= *n) { /* Update the relevant part of the trailing submatrix. */ /* If A11 denotes the diagonal block which has just been */ /* factorized, then we need to update the remaining */ /* blocks in the diagram: */ /* A11 */ /* A21 A22 */ /* A31 A32 A33 */ /* The numbers of rows and columns in the partitioning */ /* are IB, I2, I3 respectively. The blocks A21, A22 and */ /* A32 are empty if IB = KD. The lower triangle of A31 */ /* lies outside the band. */ /* Computing MIN */ i__3 = *kd - ib, i__4 = *n - i__ - ib + 1; i2 = min(i__3,i__4); /* Computing MIN */ i__3 = ib, i__4 = *n - i__ - *kd + 1; i3 = min(i__3,i__4); if (i2 > 0) { /* Update A21 */ i__3 = *ldab - 1; i__4 = *ldab - 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non" "-unit", &i2, &ib, &c_b1, &ab[i__ * ab_dim1 + 1], &i__3, &ab[ib + 1 + i__ * ab_dim1], &i__4); /* Update A22 */ i__3 = *ldab - 1; i__4 = *ldab - 1; cherk_("Lower", "No transpose", &i2, &ib, &c_b21, &ab[ ib + 1 + i__ * ab_dim1], &i__3, &c_b22, &ab[( i__ + ib) * ab_dim1 + 1], &i__4); } if (i3 > 0) { /* Copy the upper triangle of A31 into the work array. */ i__3 = ib; for (jj = 1; jj <= i__3; ++jj) { i__4 = min(jj,i3); for (ii = 1; ii <= i__4; ++ii) { i__5 = ii + jj * 33 - 34; i__6 = *kd + 1 - jj + ii + (jj + i__ - 1) * ab_dim1; work[i__5].r = ab[i__6].r, work[i__5].i = ab[ i__6].i; } } /* Update A31 (in the work array). */ i__3 = *ldab - 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non" "-unit", &i3, &ib, &c_b1, &ab[i__ * ab_dim1 + 1], &i__3, work, &c__33); /* Update A32 */ if (i2 > 0) { q__1.r = -1.f, q__1.i = -0.f; i__3 = *ldab - 1; i__4 = *ldab - 1; cgemm_("No transpose", "Conjugate transpose", &i3, &i2, &ib, &q__1, work, &c__33, &ab[ib + 1 + i__ * ab_dim1], &i__3, &c_b1, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__4); } /* Update A33 */ i__3 = *ldab - 1; cherk_("Lower", "No transpose", &i3, &ib, &c_b21, work, &c__33, &c_b22, &ab[(i__ + *kd) * ab_dim1 + 1], &i__3); /* Copy the upper triangle of A31 back into place. */ i__3 = ib; for (jj = 1; jj <= i__3; ++jj) { i__4 = min(jj,i3); for (ii = 1; ii <= i__4; ++ii) { i__5 = *kd + 1 - jj + ii + (jj + i__ - 1) * ab_dim1; i__6 = ii + jj * 33 - 34; ab[i__5].r = work[i__6].r, ab[i__5].i = work[ i__6].i; } } } } } } } return 0; L150: return 0; /* End of CPBTRF */ } /* cpbtrf_ */
/* Subroutine */ int cqlt01_(integer *m, integer *n, complex *a, complex *af, complex *q, complex *l, integer *lda, complex *tau, complex *work, integer *lwork, real *rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, l_dim1, l_offset, q_dim1, q_offset, i__1, i__2; /* Builtin functions Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); /* Local variables */ static integer info; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); static real resid, anorm; static integer minmn; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cgeqlf_(integer *, integer *, complex *, integer *, complex *, 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 *); extern doublereal clansy_(char *, char *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cungql_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); static real eps; #define l_subscr(a_1,a_2) (a_2)*l_dim1 + a_1 #define l_ref(a_1,a_2) l[l_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 af_subscr(a_1,a_2) (a_2)*af_dim1 + a_1 #define af_ref(a_1,a_2) af[af_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 September 30, 1994 Purpose ======= CQLT01 tests CGEQLF, which computes the QL factorization of an m-by-n matrix A, and partially tests CUNGQL which forms the m-by-m orthogonal matrix Q. CQLT01 compares L with Q'*A, and checks that Q is orthogonal. 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) COMPLEX array, dimension (LDA,N) The m-by-n matrix A. AF (output) COMPLEX array, dimension (LDA,N) Details of the QL factorization of A, as returned by CGEQLF. See CGEQLF for further details. Q (output) COMPLEX array, dimension (LDA,M) The m-by-m orthogonal matrix Q. L (workspace) COMPLEX array, dimension (LDA,max(M,N)) LDA (input) INTEGER The leading dimension of the arrays A, AF, Q and R. LDA >= max(M,N). TAU (output) COMPLEX array, dimension (min(M,N)) The scalar factors of the elementary reflectors, as returned by CGEQLF. WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The dimension of the array WORK. RWORK (workspace) REAL array, dimension (M) RESULT (output) REAL array, dimension (2) The test ratios: RESULT(1) = norm( L - Q'*A ) / ( M * norm(A) * EPS ) RESULT(2) = norm( I - Q'*Q ) / ( M * EPS ) ===================================================================== Parameter adjustments */ l_dim1 = *lda; l_offset = 1 + l_dim1 * 1; l -= l_offset; q_dim1 = *lda; q_offset = 1 + q_dim1 * 1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1 * 1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; --rwork; --result; /* Function Body */ minmn = min(*m,*n); eps = slamch_("Epsilon"); /* Copy the matrix A to the array AF. */ clacpy_("Full", m, n, &a[a_offset], lda, &af[af_offset], lda); /* Factorize the matrix A in the array AF. */ s_copy(srnamc_1.srnamt, "CGEQLF", (ftnlen)6, (ftnlen)6); cgeqlf_(m, n, &af[af_offset], lda, &tau[1], &work[1], lwork, &info); /* Copy details of Q */ claset_("Full", m, m, &c_b1, &c_b1, &q[q_offset], lda); if (*m >= *n) { if (*n < *m && *n > 0) { i__1 = *m - *n; clacpy_("Full", &i__1, n, &af[af_offset], lda, &q_ref(1, *m - *n + 1), lda); } if (*n > 1) { i__1 = *n - 1; i__2 = *n - 1; clacpy_("Upper", &i__1, &i__2, &af_ref(*m - *n + 1, 2), lda, & q_ref(*m - *n + 1, *m - *n + 2), lda); } } else { if (*m > 1) { i__1 = *m - 1; i__2 = *m - 1; clacpy_("Upper", &i__1, &i__2, &af_ref(1, *n - *m + 2), lda, & q_ref(1, 2), lda); } } /* Generate the m-by-m matrix Q */ s_copy(srnamc_1.srnamt, "CUNGQL", (ftnlen)6, (ftnlen)6); cungql_(m, m, &minmn, &q[q_offset], lda, &tau[1], &work[1], lwork, &info); /* Copy L */ claset_("Full", m, n, &c_b12, &c_b12, &l[l_offset], lda); if (*m >= *n) { if (*n > 0) { clacpy_("Lower", n, n, &af_ref(*m - *n + 1, 1), lda, &l_ref(*m - * n + 1, 1), lda); } } else { if (*n > *m && *m > 0) { i__1 = *n - *m; clacpy_("Full", m, &i__1, &af[af_offset], lda, &l[l_offset], lda); } if (*m > 0) { clacpy_("Lower", m, m, &af_ref(1, *n - *m + 1), lda, &l_ref(1, *n - *m + 1), lda); } } /* Compute L - Q'*A */ cgemm_("Conjugate transpose", "No transpose", m, n, m, &c_b19, &q[ q_offset], lda, &a[a_offset], lda, &c_b20, &l[l_offset], lda); /* Compute norm( L - Q'*A ) / ( M * norm(A) * EPS ) . */ anorm = clange_("1", m, n, &a[a_offset], lda, &rwork[1]); resid = clange_("1", m, n, &l[l_offset], lda, &rwork[1]); if (anorm > 0.f) { result[1] = resid / (real) max(1,*m) / anorm / eps; } else { result[1] = 0.f; } /* Compute I - Q'*Q */ claset_("Full", m, m, &c_b12, &c_b20, &l[l_offset], lda); cherk_("Upper", "Conjugate transpose", m, m, &c_b28, &q[q_offset], lda, & c_b29, &l[l_offset], lda); /* Compute norm( I - Q'*Q ) / ( M * EPS ) . */ resid = clansy_("1", "Upper", m, &l[l_offset], lda, &rwork[1]); result[2] = resid / (real) max(1,*m) / eps; return 0; /* End of CQLT01 */ } /* cqlt01_ */
/* Subroutine */ int cqlt01_(integer *m, integer *n, complex *a, complex *af, complex *q, complex *l, integer *lda, complex *tau, complex *work, integer *lwork, real *rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, l_dim1, l_offset, q_dim1, q_offset, i__1, i__2; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); /* Local variables */ real eps; integer info; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); real resid, anorm; integer minmn; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cgeqlf_(integer *, integer *, complex *, integer *, complex *, 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 *); extern doublereal clansy_(char *, char *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cungql_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CQLT01 tests CGEQLF, which computes the QL factorization of an m-by-n */ /* matrix A, and partially tests CUNGQL which forms the m-by-m */ /* orthogonal matrix Q. */ /* CQLT01 compares L with Q'*A, and checks that Q is orthogonal. */ /* 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) COMPLEX array, dimension (LDA,N) */ /* The m-by-n matrix A. */ /* AF (output) COMPLEX array, dimension (LDA,N) */ /* Details of the QL factorization of A, as returned by CGEQLF. */ /* See CGEQLF for further details. */ /* Q (output) COMPLEX array, dimension (LDA,M) */ /* The m-by-m orthogonal matrix Q. */ /* L (workspace) COMPLEX array, dimension (LDA,max(M,N)) */ /* LDA (input) INTEGER */ /* The leading dimension of the arrays A, AF, Q and R. */ /* LDA >= max(M,N). */ /* TAU (output) COMPLEX array, dimension (min(M,N)) */ /* The scalar factors of the elementary reflectors, as returned */ /* by CGEQLF. */ /* WORK (workspace) COMPLEX array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. */ /* RWORK (workspace) REAL array, dimension (M) */ /* RESULT (output) REAL array, dimension (2) */ /* The test ratios: */ /* RESULT(1) = norm( L - Q'*A ) / ( M * norm(A) * EPS ) */ /* RESULT(2) = norm( I - Q'*Q ) / ( M * EPS ) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ l_dim1 = *lda; l_offset = 1 + l_dim1; l -= l_offset; q_dim1 = *lda; q_offset = 1 + q_dim1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --tau; --work; --rwork; --result; /* Function Body */ minmn = min(*m,*n); eps = slamch_("Epsilon"); /* Copy the matrix A to the array AF. */ clacpy_("Full", m, n, &a[a_offset], lda, &af[af_offset], lda); /* Factorize the matrix A in the array AF. */ s_copy(srnamc_1.srnamt, "CGEQLF", (ftnlen)6, (ftnlen)6); cgeqlf_(m, n, &af[af_offset], lda, &tau[1], &work[1], lwork, &info); /* Copy details of Q */ claset_("Full", m, m, &c_b1, &c_b1, &q[q_offset], lda); if (*m >= *n) { if (*n < *m && *n > 0) { i__1 = *m - *n; clacpy_("Full", &i__1, n, &af[af_offset], lda, &q[(*m - *n + 1) * q_dim1 + 1], lda); } if (*n > 1) { i__1 = *n - 1; i__2 = *n - 1; clacpy_("Upper", &i__1, &i__2, &af[*m - *n + 1 + (af_dim1 << 1)], lda, &q[*m - *n + 1 + (*m - *n + 2) * q_dim1], lda); } } else { if (*m > 1) { i__1 = *m - 1; i__2 = *m - 1; clacpy_("Upper", &i__1, &i__2, &af[(*n - *m + 2) * af_dim1 + 1], lda, &q[(q_dim1 << 1) + 1], lda); } } /* Generate the m-by-m matrix Q */ s_copy(srnamc_1.srnamt, "CUNGQL", (ftnlen)6, (ftnlen)6); cungql_(m, m, &minmn, &q[q_offset], lda, &tau[1], &work[1], lwork, &info); /* Copy L */ claset_("Full", m, n, &c_b12, &c_b12, &l[l_offset], lda); if (*m >= *n) { if (*n > 0) { clacpy_("Lower", n, n, &af[*m - *n + 1 + af_dim1], lda, &l[*m - * n + 1 + l_dim1], lda); } } else { if (*n > *m && *m > 0) { i__1 = *n - *m; clacpy_("Full", m, &i__1, &af[af_offset], lda, &l[l_offset], lda); } if (*m > 0) { clacpy_("Lower", m, m, &af[(*n - *m + 1) * af_dim1 + 1], lda, &l[( *n - *m + 1) * l_dim1 + 1], lda); } } /* Compute L - Q'*A */ cgemm_("Conjugate transpose", "No transpose", m, n, m, &c_b19, &q[ q_offset], lda, &a[a_offset], lda, &c_b20, &l[l_offset], lda); /* Compute norm( L - Q'*A ) / ( M * norm(A) * EPS ) . */ anorm = clange_("1", m, n, &a[a_offset], lda, &rwork[1]); resid = clange_("1", m, n, &l[l_offset], lda, &rwork[1]); if (anorm > 0.f) { result[1] = resid / (real) max(1,*m) / anorm / eps; } else { result[1] = 0.f; } /* Compute I - Q'*Q */ claset_("Full", m, m, &c_b12, &c_b20, &l[l_offset], lda); cherk_("Upper", "Conjugate transpose", m, m, &c_b28, &q[q_offset], lda, & c_b29, &l[l_offset], lda); /* Compute norm( I - Q'*Q ) / ( M * EPS ) . */ resid = clansy_("1", "Upper", m, &l[l_offset], lda, &rwork[1]); result[2] = resid / (real) max(1,*m) / eps; return 0; /* End of CQLT01 */ } /* cqlt01_ */
/* Subroutine */ int crqt02_(integer *m, integer *n, integer *k, complex *a, complex *af, complex *q, complex *r__, integer *lda, complex *tau, complex *work, integer *lwork, real *rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, q_dim1, q_offset, r_dim1, r_offset, i__1, i__2; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); /* Local variables */ real eps; integer info; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); real resid, anorm; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *), slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *); extern doublereal clansy_(char *, char *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cungrq_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CRQT02 tests CUNGRQ, which generates an m-by-n matrix Q with */ /* orthonornmal rows that is defined as the product of k elementary */ /* reflectors. */ /* Given the RQ factorization of an m-by-n matrix A, CRQT02 generates */ /* the orthogonal matrix Q defined by the factorization of the last k */ /* rows of A; it compares R(m-k+1:m,n-m+1:n) with */ /* A(m-k+1:m,1:n)*Q(n-m+1:n,1:n)', and checks that the rows of Q are */ /* orthonormal. */ /* Arguments */ /* ========= */ /* M (input) INTEGER */ /* The number of rows of the matrix Q to be generated. M >= 0. */ /* N (input) INTEGER */ /* The number of columns of the matrix Q to be generated. */ /* N >= M >= 0. */ /* K (input) INTEGER */ /* The number of elementary reflectors whose product defines the */ /* matrix Q. M >= K >= 0. */ /* A (input) COMPLEX array, dimension (LDA,N) */ /* The m-by-n matrix A which was factorized by CRQT01. */ /* AF (input) COMPLEX array, dimension (LDA,N) */ /* Details of the RQ factorization of A, as returned by CGERQF. */ /* See CGERQF for further details. */ /* Q (workspace) COMPLEX array, dimension (LDA,N) */ /* R (workspace) COMPLEX array, dimension (LDA,M) */ /* LDA (input) INTEGER */ /* The leading dimension of the arrays A, AF, Q and L. LDA >= N. */ /* TAU (input) COMPLEX array, dimension (M) */ /* The scalar factors of the elementary reflectors corresponding */ /* to the RQ factorization in AF. */ /* WORK (workspace) COMPLEX array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK. */ /* RWORK (workspace) REAL array, dimension (M) */ /* RESULT (output) REAL array, dimension (2) */ /* The test ratios: */ /* RESULT(1) = norm( R - A*Q' ) / ( N * norm(A) * EPS ) */ /* RESULT(2) = norm( I - Q*Q' ) / ( N * EPS ) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Executable Statements .. */ /* Quick return if possible */ /* Parameter adjustments */ r_dim1 = *lda; r_offset = 1 + r_dim1; r__ -= r_offset; q_dim1 = *lda; q_offset = 1 + q_dim1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --tau; --work; --rwork; --result; /* Function Body */ if (*m == 0 || *n == 0 || *k == 0) { result[1] = 0.f; result[2] = 0.f; return 0; } eps = slamch_("Epsilon"); /* Copy the last k rows of the factorization to the array Q */ claset_("Full", m, n, &c_b1, &c_b1, &q[q_offset], lda); if (*k < *n) { i__1 = *n - *k; clacpy_("Full", k, &i__1, &af[*m - *k + 1 + af_dim1], lda, &q[*m - *k + 1 + q_dim1], lda); } if (*k > 1) { i__1 = *k - 1; i__2 = *k - 1; clacpy_("Lower", &i__1, &i__2, &af[*m - *k + 2 + (*n - *k + 1) * af_dim1], lda, &q[*m - *k + 2 + (*n - *k + 1) * q_dim1], lda); } /* Generate the last n rows of the matrix Q */ s_copy(srnamc_1.srnamt, "CUNGRQ", (ftnlen)32, (ftnlen)6); cungrq_(m, n, k, &q[q_offset], lda, &tau[*m - *k + 1], &work[1], lwork, & info); /* Copy R(m-k+1:m,n-m+1:n) */ claset_("Full", k, m, &c_b9, &c_b9, &r__[*m - *k + 1 + (*n - *m + 1) * r_dim1], lda); clacpy_("Upper", k, k, &af[*m - *k + 1 + (*n - *k + 1) * af_dim1], lda, & r__[*m - *k + 1 + (*n - *k + 1) * r_dim1], lda); /* Compute R(m-k+1:m,n-m+1:n) - A(m-k+1:m,1:n) * Q(n-m+1:n,1:n)' */ cgemm_("No transpose", "Conjugate transpose", k, m, n, &c_b14, &a[*m - *k + 1 + a_dim1], lda, &q[q_offset], lda, &c_b15, &r__[*m - *k + 1 + (*n - *m + 1) * r_dim1], lda); /* Compute norm( R - A*Q' ) / ( N * norm(A) * EPS ) . */ anorm = clange_("1", k, n, &a[*m - *k + 1 + a_dim1], lda, &rwork[1]); resid = clange_("1", k, m, &r__[*m - *k + 1 + (*n - *m + 1) * r_dim1], lda, &rwork[1]); if (anorm > 0.f) { result[1] = resid / (real) max(1,*n) / anorm / eps; } else { result[1] = 0.f; } /* Compute I - Q*Q' */ claset_("Full", m, m, &c_b9, &c_b15, &r__[r_offset], lda); cherk_("Upper", "No transpose", m, n, &c_b23, &q[q_offset], lda, &c_b24, & r__[r_offset], lda); /* Compute norm( I - Q*Q' ) / ( N * EPS ) . */ resid = clansy_("1", "Upper", m, &r__[r_offset], lda, &rwork[1]); result[2] = resid / (real) max(1,*n) / eps; return 0; /* End of CRQT02 */ } /* crqt02_ */
/* Subroutine */ int cpbtrf_(char *uplo, integer *n, integer *kd, complex *ab, integer *ldab, integer *info) { /* System generated locals */ integer ab_dim1, ab_offset, i__1, i__2, i__3, i__4, i__5, i__6; complex q__1; /* Local variables */ integer i__, j, i2, i3, ib, nb, ii, jj; complex work[1056] /* was [33][32] */ ; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrsm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *), cpbtf2_(char *, integer *, integer *, complex *, integer *, integer *), cpotf2_(char *, integer *, complex *, integer *, integer *), xerbla_(char *, integer *); extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *); /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ ab_dim1 = *ldab; ab_offset = 1 + ab_dim1; ab -= ab_offset; /* Function Body */ *info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*kd < 0) { *info = -3; } else if (*ldab < *kd + 1) { *info = -5; } if (*info != 0) { i__1 = -(*info); xerbla_("CPBTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine the block size for this environment */ nb = ilaenv_(&c__1, "CPBTRF", uplo, n, kd, &c_n1, &c_n1); /* The block size must not exceed the semi-bandwidth KD, and must not */ /* exceed the limit set by the size of the local array WORK. */ nb = min(nb,32); if (nb <= 1 || nb > *kd) { /* Use unblocked code */ cpbtf2_(uplo, n, kd, &ab[ab_offset], ldab, info); } else { /* Use blocked code */ if (lsame_(uplo, "U")) { /* Compute the Cholesky factorization of a Hermitian band */ /* matrix, given the upper triangle of the matrix in band */ /* storage. */ /* Zero the upper triangle of the work array. */ i__1 = nb; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { i__3 = i__ + j * 33 - 34; work[i__3].r = 0.f; work[i__3].i = 0.f; // , expr subst /* L10: */ } /* L20: */ } /* Process the band matrix one diagonal block at a time. */ i__1 = *n; i__2 = nb; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = nb; i__4 = *n - i__ + 1; // , expr subst ib = min(i__3,i__4); /* Factorize the diagonal block */ i__3 = *ldab - 1; cpotf2_(uplo, &ib, &ab[*kd + 1 + i__ * ab_dim1], &i__3, &ii); if (ii != 0) { *info = i__ + ii - 1; goto L150; } if (i__ + ib <= *n) { /* Update the relevant part of the trailing submatrix. */ /* If A11 denotes the diagonal block which has just been */ /* factorized, then we need to update the remaining */ /* blocks in the diagram: */ /* A11 A12 A13 */ /* A22 A23 */ /* A33 */ /* The numbers of rows and columns in the partitioning */ /* are IB, I2, I3 respectively. The blocks A12, A22 and */ /* A23 are empty if IB = KD. The upper triangle of A13 */ /* lies outside the band. */ /* Computing MIN */ i__3 = *kd - ib; i__4 = *n - i__ - ib + 1; // , expr subst i2 = min(i__3,i__4); /* Computing MIN */ i__3 = ib; i__4 = *n - i__ - *kd + 1; // , expr subst i3 = min(i__3,i__4); if (i2 > 0) { /* Update A12 */ i__3 = *ldab - 1; i__4 = *ldab - 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-" "unit", &ib, &i2, &c_b1, &ab[*kd + 1 + i__ * ab_dim1], &i__3, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__4); /* Update A22 */ i__3 = *ldab - 1; i__4 = *ldab - 1; cherk_("Upper", "Conjugate transpose", &i2, &ib, & c_b21, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__3, &c_b22, &ab[*kd + 1 + (i__ + ib) * ab_dim1], &i__4); } if (i3 > 0) { /* Copy the lower triangle of A13 into the work array. */ i__3 = i3; for (jj = 1; jj <= i__3; ++jj) { i__4 = ib; for (ii = jj; ii <= i__4; ++ii) { i__5 = ii + jj * 33 - 34; i__6 = ii - jj + 1 + (jj + i__ + *kd - 1) * ab_dim1; work[i__5].r = ab[i__6].r; work[i__5].i = ab[ i__6].i; // , expr subst /* L30: */ } /* L40: */ } /* Update A13 (in the work array). */ i__3 = *ldab - 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-" "unit", &ib, &i3, &c_b1, &ab[*kd + 1 + i__ * ab_dim1], &i__3, work, &c__33); /* Update A23 */ if (i2 > 0) { q__1.r = -1.f; q__1.i = -0.f; // , expr subst i__3 = *ldab - 1; i__4 = *ldab - 1; cgemm_("Conjugate transpose", "No transpose", &i2, &i3, &ib, &q__1, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__3, work, &c__33, & c_b1, &ab[ib + 1 + (i__ + *kd) * ab_dim1], &i__4); } /* Update A33 */ i__3 = *ldab - 1; cherk_("Upper", "Conjugate transpose", &i3, &ib, & c_b21, work, &c__33, &c_b22, &ab[*kd + 1 + ( i__ + *kd) * ab_dim1], &i__3); /* Copy the lower triangle of A13 back into place. */ i__3 = i3; for (jj = 1; jj <= i__3; ++jj) { i__4 = ib; for (ii = jj; ii <= i__4; ++ii) { i__5 = ii - jj + 1 + (jj + i__ + *kd - 1) * ab_dim1; i__6 = ii + jj * 33 - 34; ab[i__5].r = work[i__6].r; ab[i__5].i = work[ i__6].i; // , expr subst /* L50: */ } /* L60: */ } } } /* L70: */ } } else { /* Compute the Cholesky factorization of a Hermitian band */ /* matrix, given the lower triangle of the matrix in band */ /* storage. */ /* Zero the lower triangle of the work array. */ i__2 = nb; for (j = 1; j <= i__2; ++j) { i__1 = nb; for (i__ = j + 1; i__ <= i__1; ++i__) { i__3 = i__ + j * 33 - 34; work[i__3].r = 0.f; work[i__3].i = 0.f; // , expr subst /* L80: */ } /* L90: */ } /* Process the band matrix one diagonal block at a time. */ i__2 = *n; i__1 = nb; for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) { /* Computing MIN */ i__3 = nb; i__4 = *n - i__ + 1; // , expr subst ib = min(i__3,i__4); /* Factorize the diagonal block */ i__3 = *ldab - 1; cpotf2_(uplo, &ib, &ab[i__ * ab_dim1 + 1], &i__3, &ii); if (ii != 0) { *info = i__ + ii - 1; goto L150; } if (i__ + ib <= *n) { /* Update the relevant part of the trailing submatrix. */ /* If A11 denotes the diagonal block which has just been */ /* factorized, then we need to update the remaining */ /* blocks in the diagram: */ /* A11 */ /* A21 A22 */ /* A31 A32 A33 */ /* The numbers of rows and columns in the partitioning */ /* are IB, I2, I3 respectively. The blocks A21, A22 and */ /* A32 are empty if IB = KD. The lower triangle of A31 */ /* lies outside the band. */ /* Computing MIN */ i__3 = *kd - ib; i__4 = *n - i__ - ib + 1; // , expr subst i2 = min(i__3,i__4); /* Computing MIN */ i__3 = ib; i__4 = *n - i__ - *kd + 1; // , expr subst i3 = min(i__3,i__4); if (i2 > 0) { /* Update A21 */ i__3 = *ldab - 1; i__4 = *ldab - 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non" "-unit", &i2, &ib, &c_b1, &ab[i__ * ab_dim1 + 1], &i__3, &ab[ib + 1 + i__ * ab_dim1], &i__4); /* Update A22 */ i__3 = *ldab - 1; i__4 = *ldab - 1; cherk_("Lower", "No transpose", &i2, &ib, &c_b21, &ab[ ib + 1 + i__ * ab_dim1], &i__3, &c_b22, &ab[( i__ + ib) * ab_dim1 + 1], &i__4); } if (i3 > 0) { /* Copy the upper triangle of A31 into the work array. */ i__3 = ib; for (jj = 1; jj <= i__3; ++jj) { i__4 = min(jj,i3); for (ii = 1; ii <= i__4; ++ii) { i__5 = ii + jj * 33 - 34; i__6 = *kd + 1 - jj + ii + (jj + i__ - 1) * ab_dim1; work[i__5].r = ab[i__6].r; work[i__5].i = ab[ i__6].i; // , expr subst /* L100: */ } /* L110: */ } /* Update A31 (in the work array). */ i__3 = *ldab - 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non" "-unit", &i3, &ib, &c_b1, &ab[i__ * ab_dim1 + 1], &i__3, work, &c__33); /* Update A32 */ if (i2 > 0) { q__1.r = -1.f; q__1.i = -0.f; // , expr subst i__3 = *ldab - 1; i__4 = *ldab - 1; cgemm_("No transpose", "Conjugate transpose", &i3, &i2, &ib, &q__1, work, &c__33, &ab[ib + 1 + i__ * ab_dim1], &i__3, &c_b1, &ab[*kd + 1 - ib + (i__ + ib) * ab_dim1], &i__4); } /* Update A33 */ i__3 = *ldab - 1; cherk_("Lower", "No transpose", &i3, &ib, &c_b21, work, &c__33, &c_b22, &ab[(i__ + *kd) * ab_dim1 + 1], &i__3); /* Copy the upper triangle of A31 back into place. */ i__3 = ib; for (jj = 1; jj <= i__3; ++jj) { i__4 = min(jj,i3); for (ii = 1; ii <= i__4; ++ii) { i__5 = *kd + 1 - jj + ii + (jj + i__ - 1) * ab_dim1; i__6 = ii + jj * 33 - 34; ab[i__5].r = work[i__6].r; ab[i__5].i = work[ i__6].i; // , expr subst /* L120: */ } /* L130: */ } } } /* L140: */ } } } return 0; L150: return 0; /* End of CPBTRF */ }
/* Subroutine */ int cpftri_(char *transr, char *uplo, integer *n, complex *a, integer *info) { /* System generated locals */ integer i__1, i__2; /* Local variables */ integer k, n1, n2; logical normaltransr; extern /* Subroutine */ int cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrmm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *); logical lower; extern /* Subroutine */ int xerbla_(char *, integer *); logical nisodd; extern /* Subroutine */ int clauum_(char *, integer *, complex *, integer *, integer *), ctftri_(char *, char *, char *, integer *, complex *, integer *); /* -- LAPACK computational routine (version 3.4.0) -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* November 2011 */ /* .. Scalar Arguments .. */ /* .. Array Arguments .. */ /* .. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ *info = 0; normaltransr = lsame_(transr, "N"); lower = lsame_(uplo, "L"); if (! normaltransr && ! lsame_(transr, "C")) { *info = -1; } else if (! lower && ! lsame_(uplo, "U")) { *info = -2; } else if (*n < 0) { *info = -3; } if (*info != 0) { i__1 = -(*info); xerbla_("CPFTRI", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Invert the triangular Cholesky factor U or L. */ ctftri_(transr, uplo, "N", n, a, info); if (*info > 0) { return 0; } /* If N is odd, set NISODD = .TRUE. */ /* If N is even, set K = N/2 and NISODD = .FALSE. */ if (*n % 2 == 0) { k = *n / 2; nisodd = FALSE_; } else { nisodd = TRUE_; } /* Set N1 and N2 depending on LOWER */ if (lower) { n2 = *n / 2; n1 = *n - n2; } else { n1 = *n / 2; n2 = *n - n1; } /* Start execution of triangular matrix multiply: inv(U)*inv(U)^C or */ /* inv(L)^C*inv(L). There are eight cases. */ if (nisodd) { /* N is odd */ if (normaltransr) { /* N is odd and TRANSR = 'N' */ if (lower) { /* SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:N1-1) ) */ /* T1 -> a(0,0), T2 -> a(0,1), S -> a(N1,0) */ /* T1 -> a(0), T2 -> a(n), S -> a(N1) */ clauum_("L", &n1, a, n, info); cherk_("L", "C", &n1, &n2, &c_b12, &a[n1], n, &c_b12, a, n); ctrmm_("L", "U", "N", "N", &n2, &n1, &c_b1, &a[*n], n, &a[n1], n); clauum_("U", &n2, &a[*n], n, info); } else { /* SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:N2-1) */ /* T1 -> a(N1+1,0), T2 -> a(N1,0), S -> a(0,0) */ /* T1 -> a(N2), T2 -> a(N1), S -> a(0) */ clauum_("L", &n1, &a[n2], n, info); cherk_("L", "N", &n1, &n2, &c_b12, a, n, &c_b12, &a[n2], n); ctrmm_("R", "U", "C", "N", &n1, &n2, &c_b1, &a[n1], n, a, n); clauum_("U", &n2, &a[n1], n, info); } } else { /* N is odd and TRANSR = 'C' */ if (lower) { /* SRPA for LOWER, TRANSPOSE, and N is odd */ /* T1 -> a(0), T2 -> a(1), S -> a(0+N1*N1) */ clauum_("U", &n1, a, &n1, info); cherk_("U", "N", &n1, &n2, &c_b12, &a[n1 * n1], &n1, &c_b12, a, &n1); ctrmm_("R", "L", "N", "N", &n1, &n2, &c_b1, &a[1], &n1, &a[n1 * n1], &n1); clauum_("L", &n2, &a[1], &n1, info); } else { /* SRPA for UPPER, TRANSPOSE, and N is odd */ /* T1 -> a(0+N2*N2), T2 -> a(0+N1*N2), S -> a(0) */ clauum_("U", &n1, &a[n2 * n2], &n2, info); cherk_("U", "C", &n1, &n2, &c_b12, a, &n2, &c_b12, &a[n2 * n2] , &n2); ctrmm_("L", "L", "C", "N", &n2, &n1, &c_b1, &a[n1 * n2], &n2, a, &n2); clauum_("L", &n2, &a[n1 * n2], &n2, info); } } } else { /* N is even */ if (normaltransr) { /* N is even and TRANSR = 'N' */ if (lower) { /* SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ /* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0) */ /* T1 -> a(1), T2 -> a(0), S -> a(k+1) */ i__1 = *n + 1; clauum_("L", &k, &a[1], &i__1, info); i__1 = *n + 1; i__2 = *n + 1; cherk_("L", "C", &k, &k, &c_b12, &a[k + 1], &i__1, &c_b12, &a[ 1], &i__2); i__1 = *n + 1; i__2 = *n + 1; ctrmm_("L", "U", "N", "N", &k, &k, &c_b1, a, &i__1, &a[k + 1], &i__2); i__1 = *n + 1; clauum_("U", &k, a, &i__1, info); } else { /* SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ /* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0) */ /* T1 -> a(k+1), T2 -> a(k), S -> a(0) */ i__1 = *n + 1; clauum_("L", &k, &a[k + 1], &i__1, info); i__1 = *n + 1; i__2 = *n + 1; cherk_("L", "N", &k, &k, &c_b12, a, &i__1, &c_b12, &a[k + 1], &i__2); i__1 = *n + 1; i__2 = *n + 1; ctrmm_("R", "U", "C", "N", &k, &k, &c_b1, &a[k], &i__1, a, & i__2); i__1 = *n + 1; clauum_("U", &k, &a[k], &i__1, info); } } else { /* N is even and TRANSR = 'C' */ if (lower) { /* SRPA for LOWER, TRANSPOSE, and N is even (see paper) */ /* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1), */ /* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k */ clauum_("U", &k, &a[k], &k, info); cherk_("U", "N", &k, &k, &c_b12, &a[k * (k + 1)], &k, &c_b12, &a[k], &k); ctrmm_("R", "L", "N", "N", &k, &k, &c_b1, a, &k, &a[k * (k + 1)], &k); clauum_("L", &k, a, &k, info); } else { /* SRPA for UPPER, TRANSPOSE, and N is even (see paper) */ /* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0), */ /* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k */ clauum_("U", &k, &a[k * (k + 1)], &k, info); cherk_("U", "C", &k, &k, &c_b12, a, &k, &c_b12, &a[k * (k + 1) ], &k); ctrmm_("L", "L", "C", "N", &k, &k, &c_b1, &a[k * k], &k, a, & k); clauum_("L", &k, &a[k * k], &k, info); } } } return 0; /* End of CPFTRI */ }
/* Subroutine */ int cdrvrf4_(integer *nout, integer *nn, integer *nval, real *thresh, complex *c1, complex *c2, integer *ldc, complex *crf, complex *a, integer *lda, real *s_work_clange__) { /* Initialized data */ static integer iseedy[4] = { 1988,1989,1990,1991 }; static char uplos[1*2] = "U" "L"; static char forms[1*2] = "N" "C"; static char transs[1*2] = "N" "C"; /* Format strings */ static char fmt_9999[] = "(1x,\002 *** Error(s) or Failure(s) while test" "ing CHFRK ***\002)"; static char fmt_9997[] = "(1x,\002 Failure in \002,a5,\002, CFORM=" "'\002,a1,\002',\002,\002 UPLO='\002,a1,\002',\002,\002 TRANS=" "'\002,a1,\002',\002,\002 N=\002,i3,\002, K =\002,i3,\002, test" "=\002,g12.5)"; static char fmt_9996[] = "(1x,\002All tests for \002,a5,\002 auxiliary r" "outine passed the \002,\002threshold (\002,i5,\002 tests run)" "\002)"; static char fmt_9995[] = "(1x,a6,\002 auxiliary routine:\002,i5,\002 out" " of \002,i5,\002 tests failed to pass the threshold\002)"; /* System generated locals */ integer a_dim1, a_offset, c1_dim1, c1_offset, c2_dim1, c2_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7; real r__1; complex q__1; /* Builtin functions */ /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); integer s_wsle(cilist *), e_wsle(void), s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen); /* Local variables */ integer i__, j, k, n, iik, iin; real eps, beta; integer info; char uplo[1]; integer nrun; real alpha; integer nfail, iseed[4]; extern /* Subroutine */ int cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *, integer *), chfrk_(char *, char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *); char cform[1]; integer iform; real norma, normc; char trans[1]; integer iuplo; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); integer ialpha; extern /* Complex */ VOID clarnd_(complex *, integer *, integer *); extern doublereal slamch_(char *), slarnd_(integer *, integer *); integer itrans; extern /* Subroutine */ int ctfttr_(char *, char *, integer *, complex *, complex *, integer *, integer *), ctrttf_(char *, char *, integer *, complex *, integer *, complex *, integer *); real result[1]; /* Fortran I/O blocks */ static cilist io___28 = { 0, 0, 0, 0, 0 }; static cilist io___29 = { 0, 0, 0, fmt_9999, 0 }; static cilist io___30 = { 0, 0, 0, fmt_9997, 0 }; static cilist io___31 = { 0, 0, 0, fmt_9996, 0 }; static cilist io___32 = { 0, 0, 0, fmt_9995, 0 }; /* -- LAPACK test routine (version 3.2.0) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2008 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CDRVRF4 tests the LAPACK RFP routines: */ /* CHFRK */ /* Arguments */ /* ========= */ /* NOUT (input) INTEGER */ /* The unit number for output. */ /* NN (input) INTEGER */ /* The number of values of N contained in the vector NVAL. */ /* NVAL (input) INTEGER array, dimension (NN) */ /* The values of the matrix dimension N. */ /* THRESH (input) REAL */ /* The threshold value for the test ratios. A result is */ /* included in the output file if RESULT >= THRESH. To have */ /* every test ratio printed, use THRESH = 0. */ /* C1 (workspace) COMPLEX array, dimension (LDC,NMAX) */ /* C2 (workspace) COMPLEX array, dimension (LDC,NMAX) */ /* LDC (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* CRF (workspace) COMPLEX array, dimension ((NMAX*(NMAX+1))/2). */ /* A (workspace) COMPLEX array, dimension (LDA,NMAX) */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,NMAX). */ /* S_WORK_CLANGE (workspace) REAL array, dimension (NMAX) */ /* ===================================================================== */ /* .. */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Scalars in Common .. */ /* .. */ /* .. Common blocks .. */ /* .. */ /* .. Data statements .. */ /* Parameter adjustments */ --nval; c2_dim1 = *ldc; c2_offset = 1 + c2_dim1; c2 -= c2_offset; c1_dim1 = *ldc; c1_offset = 1 + c1_dim1; c1 -= c1_offset; --crf; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --s_work_clange__; /* Function Body */ /* .. */ /* .. Executable Statements .. */ /* Initialize constants and the random number seed. */ nrun = 0; nfail = 0; info = 0; for (i__ = 1; i__ <= 4; ++i__) { iseed[i__ - 1] = iseedy[i__ - 1]; /* L10: */ } eps = slamch_("Precision"); i__1 = *nn; for (iin = 1; iin <= i__1; ++iin) { n = nval[iin]; i__2 = *nn; for (iik = 1; iik <= i__2; ++iik) { k = nval[iin]; for (iform = 1; iform <= 2; ++iform) { *(unsigned char *)cform = *(unsigned char *)&forms[iform - 1]; for (iuplo = 1; iuplo <= 2; ++iuplo) { *(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1]; for (itrans = 1; itrans <= 2; ++itrans) { *(unsigned char *)trans = *(unsigned char *)&transs[ itrans - 1]; for (ialpha = 1; ialpha <= 4; ++ialpha) { if (ialpha == 1) { alpha = 0.f; beta = 0.f; } else if (ialpha == 1) { alpha = 1.f; beta = 0.f; } else if (ialpha == 1) { alpha = 0.f; beta = 1.f; } else { alpha = slarnd_(&c__2, iseed); beta = slarnd_(&c__2, iseed); } /* All the parameters are set: */ /* CFORM, UPLO, TRANS, M, N, */ /* ALPHA, and BETA */ /* READY TO TEST! */ ++nrun; if (itrans == 1) { /* In this case we are NOTRANS, so A is N-by-K */ i__3 = k; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * a_dim1; clarnd_(&q__1, &c__4, iseed); a[i__5].r = q__1.r, a[i__5].i = q__1.i; } } norma = clange_("I", &n, &k, &a[a_offset], lda, &s_work_clange__[1]); } else { /* In this case we are TRANS, so A is K-by-N */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = k; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * a_dim1; clarnd_(&q__1, &c__4, iseed); a[i__5].r = q__1.r, a[i__5].i = q__1.i; } } norma = clange_("I", &k, &n, &a[a_offset], lda, &s_work_clange__[1]); } /* Generate C1 our N--by--N Hermitian matrix. */ /* Make sure C2 has the same upper/lower part, */ /* (the one that we do not touch), so */ /* copy the initial C1 in C2 in it. */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * c1_dim1; clarnd_(&q__1, &c__4, iseed); c1[i__5].r = q__1.r, c1[i__5].i = q__1.i; i__5 = i__ + j * c2_dim1; i__6 = i__ + j * c1_dim1; c2[i__5].r = c1[i__6].r, c2[i__5].i = c1[ i__6].i; } } /* (See comment later on for why we use CLANGE and */ /* not CLANHE for C1.) */ normc = clange_("I", &n, &n, &c1[c1_offset], ldc, &s_work_clange__[1]); s_copy(srnamc_1.srnamt, "CTRTTF", (ftnlen)32, ( ftnlen)6); ctrttf_(cform, uplo, &n, &c1[c1_offset], ldc, & crf[1], &info); /* call zherk the BLAS routine -> gives C1 */ s_copy(srnamc_1.srnamt, "CHERK ", (ftnlen)32, ( ftnlen)6); cherk_(uplo, trans, &n, &k, &alpha, &a[a_offset], lda, &beta, &c1[c1_offset], ldc); /* call zhfrk the RFP routine -> gives CRF */ s_copy(srnamc_1.srnamt, "CHFRK ", (ftnlen)32, ( ftnlen)6); chfrk_(cform, uplo, trans, &n, &k, &alpha, &a[ a_offset], lda, &beta, &crf[1]); /* convert CRF in full format -> gives C2 */ s_copy(srnamc_1.srnamt, "CTFTTR", (ftnlen)32, ( ftnlen)6); ctfttr_(cform, uplo, &n, &crf[1], &c2[c2_offset], ldc, &info); /* compare C1 and C2 */ i__3 = n; for (j = 1; j <= i__3; ++j) { i__4 = n; for (i__ = 1; i__ <= i__4; ++i__) { i__5 = i__ + j * c1_dim1; i__6 = i__ + j * c1_dim1; i__7 = i__ + j * c2_dim1; q__1.r = c1[i__6].r - c2[i__7].r, q__1.i = c1[i__6].i - c2[i__7].i; c1[i__5].r = q__1.r, c1[i__5].i = q__1.i; } } /* Yes, C1 is Hermitian so we could call CLANHE, */ /* but we want to check the upper part that is */ /* supposed to be unchanged and the diagonal that */ /* is supposed to be real -> CLANGE */ result[0] = clange_("I", &n, &n, &c1[c1_offset], ldc, &s_work_clange__[1]); /* Computing MAX */ r__1 = dabs(alpha) * norma * norma + dabs(beta) * normc; result[0] = result[0] / dmax(r__1,1.f) / max(n,1) / eps; if (result[0] >= *thresh) { if (nfail == 0) { io___28.ciunit = *nout; s_wsle(&io___28); e_wsle(); io___29.ciunit = *nout; s_wsfe(&io___29); e_wsfe(); } io___30.ciunit = *nout; s_wsfe(&io___30); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, cform, (ftnlen)1); do_fio(&c__1, uplo, (ftnlen)1); do_fio(&c__1, trans, (ftnlen)1); do_fio(&c__1, (char *)&n, (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&k, (ftnlen)sizeof( integer)); do_fio(&c__1, (char *)&result[0], (ftnlen) sizeof(real)); e_wsfe(); ++nfail; } /* L100: */ } /* L110: */ } /* L120: */ } /* L130: */ } /* L140: */ } /* L150: */ } /* Print a summary of the results. */ if (nfail == 0) { io___31.ciunit = *nout; s_wsfe(&io___31); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } else { io___32.ciunit = *nout; s_wsfe(&io___32); do_fio(&c__1, "CHFRK", (ftnlen)5); do_fio(&c__1, (char *)&nfail, (ftnlen)sizeof(integer)); do_fio(&c__1, (char *)&nrun, (ftnlen)sizeof(integer)); e_wsfe(); } return 0; /* End of CDRVRF4 */ } /* cdrvrf4_ */
/* Subroutine */ int cpftri_(char *transr, char *uplo, integer *n, complex *a, integer *info) { /* System generated locals */ integer i__1, i__2; /* Local variables */ integer k, n1, n2; logical normaltransr; extern /* Subroutine */ int cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real *, complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrmm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *); logical lower; extern /* Subroutine */ int xerbla_(char *, integer *); logical nisodd; extern /* Subroutine */ int clauum_(char *, integer *, complex *, integer *, integer *), ctftri_(char *, char *, char *, integer *, complex *, integer *); /* -- LAPACK routine (version 3.2) -- */ /* -- Contributed by Fred Gustavson of the IBM Watson Research Center -- */ /* -- November 2008 -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* .. Scalar Arguments .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CPFTRI computes the inverse of a complex Hermitian positive definite */ /* matrix A using the Cholesky factorization A = U**H*U or A = L*L**H */ /* computed by CPFTRF. */ /* Arguments */ /* ========= */ /* TRANSR (input) CHARACTER */ /* = 'N': The Normal TRANSR of RFP A is stored; */ /* = 'C': The Conjugate-transpose TRANSR of RFP A is stored. */ /* UPLO (input) CHARACTER */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input/output) COMPLEX array, dimension ( N*(N+1)/2 ); */ /* On entry, the Hermitian matrix A in RFP format. RFP format is */ /* described by TRANSR, UPLO, and N as follows: If TRANSR = 'N' */ /* then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is */ /* (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'C' then RFP is */ /* the Conjugate-transpose of RFP A as defined when */ /* TRANSR = 'N'. The contents of RFP A are defined by UPLO as */ /* follows: If UPLO = 'U' the RFP A contains the nt elements of */ /* upper packed A. If UPLO = 'L' the RFP A contains the elements */ /* of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR = */ /* 'C'. When TRANSR is 'N' the LDA is N+1 when N is even and N */ /* is odd. See the Note below for more details. */ /* On exit, the Hermitian inverse of the original matrix, in the */ /* same storage format. */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: if INFO = i, the (i,i) element of the factor U or L is */ /* zero, and the inverse could not be computed. */ /* Note: */ /* ===== */ /* We first consider Standard Packed Format when N is even. */ /* We give an example where N = 6. */ /* AP is Upper AP is Lower */ /* 00 01 02 03 04 05 00 */ /* 11 12 13 14 15 10 11 */ /* 22 23 24 25 20 21 22 */ /* 33 34 35 30 31 32 33 */ /* 44 45 40 41 42 43 44 */ /* 55 50 51 52 53 54 55 */ /* Let TRANSR = 'N'. RFP holds AP as follows: */ /* For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last */ /* three columns of AP upper. The lower triangle A(4:6,0:2) consists of */ /* conjugate-transpose of the first three columns of AP upper. */ /* For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first */ /* three columns of AP lower. The upper triangle A(0:2,0:2) consists of */ /* conjugate-transpose of the last three columns of AP lower. */ /* To denote conjugate we place -- above the element. This covers the */ /* case N even and TRANSR = 'N'. */ /* RFP A RFP A */ /* -- -- -- */ /* 03 04 05 33 43 53 */ /* -- -- */ /* 13 14 15 00 44 54 */ /* -- */ /* 23 24 25 10 11 55 */ /* 33 34 35 20 21 22 */ /* -- */ /* 00 44 45 30 31 32 */ /* -- -- */ /* 01 11 55 40 41 42 */ /* -- -- -- */ /* 02 12 22 50 51 52 */ /* Now let TRANSR = 'C'. RFP A in both UPLO cases is just the conjugate- */ /* transpose of RFP A above. One therefore gets: */ /* RFP A RFP A */ /* -- -- -- -- -- -- -- -- -- -- */ /* 03 13 23 33 00 01 02 33 00 10 20 30 40 50 */ /* -- -- -- -- -- -- -- -- -- -- */ /* 04 14 24 34 44 11 12 43 44 11 21 31 41 51 */ /* -- -- -- -- -- -- -- -- -- -- */ /* 05 15 25 35 45 55 22 53 54 55 22 32 42 52 */ /* We next consider Standard Packed Format when N is odd. */ /* We give an example where N = 5. */ /* AP is Upper AP is Lower */ /* 00 01 02 03 04 00 */ /* 11 12 13 14 10 11 */ /* 22 23 24 20 21 22 */ /* 33 34 30 31 32 33 */ /* 44 40 41 42 43 44 */ /* Let TRANSR = 'N'. RFP holds AP as follows: */ /* For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last */ /* three columns of AP upper. The lower triangle A(3:4,0:1) consists of */ /* conjugate-transpose of the first two columns of AP upper. */ /* For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first */ /* three columns of AP lower. The upper triangle A(0:1,1:2) consists of */ /* conjugate-transpose of the last two columns of AP lower. */ /* To denote conjugate we place -- above the element. This covers the */ /* case N odd and TRANSR = 'N'. */ /* RFP A RFP A */ /* -- -- */ /* 02 03 04 00 33 43 */ /* -- */ /* 12 13 14 10 11 44 */ /* 22 23 24 20 21 22 */ /* -- */ /* 00 33 34 30 31 32 */ /* -- -- */ /* 01 11 44 40 41 42 */ /* Now let TRANSR = 'C'. RFP A in both UPLO cases is just the conjugate- */ /* transpose of RFP A above. One therefore gets: */ /* RFP A RFP A */ /* -- -- -- -- -- -- -- -- -- */ /* 02 12 22 00 01 00 10 20 30 40 50 */ /* -- -- -- -- -- -- -- -- -- */ /* 03 13 23 33 11 33 11 21 31 41 51 */ /* -- -- -- -- -- -- -- -- -- */ /* 04 14 24 34 44 43 44 22 32 42 52 */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ *info = 0; normaltransr = lsame_(transr, "N"); lower = lsame_(uplo, "L"); if (! normaltransr && ! lsame_(transr, "C")) { *info = -1; } else if (! lower && ! lsame_(uplo, "U")) { *info = -2; } else if (*n < 0) { *info = -3; } if (*info != 0) { i__1 = -(*info); xerbla_("CPFTRI", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Invert the triangular Cholesky factor U or L. */ ctftri_(transr, uplo, "N", n, a, info); if (*info > 0) { return 0; } /* If N is odd, set NISODD = .TRUE. */ /* If N is even, set K = N/2 and NISODD = .FALSE. */ if (*n % 2 == 0) { k = *n / 2; nisodd = FALSE_; } else { nisodd = TRUE_; } /* Set N1 and N2 depending on LOWER */ if (lower) { n2 = *n / 2; n1 = *n - n2; } else { n1 = *n / 2; n2 = *n - n1; } /* Start execution of triangular matrix multiply: inv(U)*inv(U)^C or */ /* inv(L)^C*inv(L). There are eight cases. */ if (nisodd) { /* N is odd */ if (normaltransr) { /* N is odd and TRANSR = 'N' */ if (lower) { /* SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:N1-1) ) */ /* T1 -> a(0,0), T2 -> a(0,1), S -> a(N1,0) */ /* T1 -> a(0), T2 -> a(n), S -> a(N1) */ clauum_("L", &n1, a, n, info); cherk_("L", "C", &n1, &n2, &c_b12, &a[n1], n, &c_b12, a, n); ctrmm_("L", "U", "N", "N", &n2, &n1, &c_b1, &a[*n], n, &a[n1], n); clauum_("U", &n2, &a[*n], n, info); } else { /* SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:N2-1) */ /* T1 -> a(N1+1,0), T2 -> a(N1,0), S -> a(0,0) */ /* T1 -> a(N2), T2 -> a(N1), S -> a(0) */ clauum_("L", &n1, &a[n2], n, info); cherk_("L", "N", &n1, &n2, &c_b12, a, n, &c_b12, &a[n2], n); ctrmm_("R", "U", "C", "N", &n1, &n2, &c_b1, &a[n1], n, a, n); clauum_("U", &n2, &a[n1], n, info); } } else { /* N is odd and TRANSR = 'C' */ if (lower) { /* SRPA for LOWER, TRANSPOSE, and N is odd */ /* T1 -> a(0), T2 -> a(1), S -> a(0+N1*N1) */ clauum_("U", &n1, a, &n1, info); cherk_("U", "N", &n1, &n2, &c_b12, &a[n1 * n1], &n1, &c_b12, a, &n1); ctrmm_("R", "L", "N", "N", &n1, &n2, &c_b1, &a[1], &n1, &a[n1 * n1], &n1); clauum_("L", &n2, &a[1], &n1, info); } else { /* SRPA for UPPER, TRANSPOSE, and N is odd */ /* T1 -> a(0+N2*N2), T2 -> a(0+N1*N2), S -> a(0) */ clauum_("U", &n1, &a[n2 * n2], &n2, info); cherk_("U", "C", &n1, &n2, &c_b12, a, &n2, &c_b12, &a[n2 * n2] , &n2); ctrmm_("L", "L", "C", "N", &n2, &n1, &c_b1, &a[n1 * n2], &n2, a, &n2); clauum_("L", &n2, &a[n1 * n2], &n2, info); } } } else { /* N is even */ if (normaltransr) { /* N is even and TRANSR = 'N' */ if (lower) { /* SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ /* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0) */ /* T1 -> a(1), T2 -> a(0), S -> a(k+1) */ i__1 = *n + 1; clauum_("L", &k, &a[1], &i__1, info); i__1 = *n + 1; i__2 = *n + 1; cherk_("L", "C", &k, &k, &c_b12, &a[k + 1], &i__1, &c_b12, &a[ 1], &i__2); i__1 = *n + 1; i__2 = *n + 1; ctrmm_("L", "U", "N", "N", &k, &k, &c_b1, a, &i__1, &a[k + 1], &i__2); i__1 = *n + 1; clauum_("U", &k, a, &i__1, info); } else { /* SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ /* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0) */ /* T1 -> a(k+1), T2 -> a(k), S -> a(0) */ i__1 = *n + 1; clauum_("L", &k, &a[k + 1], &i__1, info); i__1 = *n + 1; i__2 = *n + 1; cherk_("L", "N", &k, &k, &c_b12, a, &i__1, &c_b12, &a[k + 1], &i__2); i__1 = *n + 1; i__2 = *n + 1; ctrmm_("R", "U", "C", "N", &k, &k, &c_b1, &a[k], &i__1, a, & i__2); i__1 = *n + 1; clauum_("U", &k, &a[k], &i__1, info); } } else { /* N is even and TRANSR = 'C' */ if (lower) { /* SRPA for LOWER, TRANSPOSE, and N is even (see paper) */ /* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1), */ /* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k */ clauum_("U", &k, &a[k], &k, info); cherk_("U", "N", &k, &k, &c_b12, &a[k * (k + 1)], &k, &c_b12, &a[k], &k); ctrmm_("R", "L", "N", "N", &k, &k, &c_b1, a, &k, &a[k * (k + 1)], &k); clauum_("L", &k, a, &k, info); } else { /* SRPA for UPPER, TRANSPOSE, and N is even (see paper) */ /* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0), */ /* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k */ clauum_("U", &k, &a[k * (k + 1)], &k, info); cherk_("U", "C", &k, &k, &c_b12, a, &k, &c_b12, &a[k * (k + 1) ], &k); ctrmm_("L", "L", "C", "N", &k, &k, &c_b1, &a[k * k], &k, a, & k); clauum_("L", &k, &a[k * k], &k, info); } } } return 0; /* End of CPFTRI */ } /* cpftri_ */
/* Subroutine */ int cgsvts_(integer *m, integer *p, integer *n, complex *a, complex *af, integer *lda, complex *b, complex *bf, integer *ldb, complex *u, integer *ldu, complex *v, integer *ldv, complex *q, integer *ldq, real *alpha, real *beta, complex *r__, integer *ldr, integer *iwork, complex *work, integer *lwork, real *rwork, real * result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, bf_dim1, bf_offset, q_dim1, q_offset, r_dim1, r_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4, i__5, i__6; real r__1; complex q__1, q__2; /* Local variables */ static integer info; static real unfl, temp; static integer i__, j, k, l; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); static real resid, anorm, bnorm; extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, integer *); extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *), clanhe_(char *, char *, integer *, complex *, integer *, real *), slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), cggsvd_(char *, char *, char *, integer *, integer *, integer *, integer *, integer *, complex *, integer *, complex *, integer *, real *, real *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, real *, integer *, integer *); static real ulpinv, ulp; #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 r___subscr(a_1,a_2) (a_2)*r_dim1 + a_1 #define r___ref(a_1,a_2) r__[r___subscr(a_1,a_2)] #define af_subscr(a_1,a_2) (a_2)*af_dim1 + a_1 #define af_ref(a_1,a_2) af[af_subscr(a_1,a_2)] #define bf_subscr(a_1,a_2) (a_2)*bf_dim1 + a_1 #define bf_ref(a_1,a_2) bf[bf_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 ======= CGSVTS tests CGGSVD, which computes the GSVD of an M-by-N matrix A and a P-by-N matrix B: U'*A*Q = D1*R and V'*B*Q = D2*R. Arguments ========= M (input) INTEGER The number of rows of the matrix A. M >= 0. P (input) INTEGER The number of rows of the matrix B. P >= 0. N (input) INTEGER The number of columns of the matrices A and B. N >= 0. A (input) COMPLEX array, dimension (LDA,M) The M-by-N matrix A. AF (output) COMPLEX array, dimension (LDA,N) Details of the GSVD of A and B, as returned by CGGSVD, see CGGSVD for further details. LDA (input) INTEGER The leading dimension of the arrays A and AF. LDA >= max( 1,M ). B (input) COMPLEX array, dimension (LDB,P) On entry, the P-by-N matrix B. BF (output) COMPLEX array, dimension (LDB,N) Details of the GSVD of A and B, as returned by CGGSVD, see CGGSVD for further details. LDB (input) INTEGER The leading dimension of the arrays B and BF. LDB >= max(1,P). U (output) COMPLEX array, dimension(LDU,M) The M by M unitary matrix U. LDU (input) INTEGER The leading dimension of the array U. LDU >= max(1,M). V (output) COMPLEX array, dimension(LDV,M) The P by P unitary matrix V. LDV (input) INTEGER The leading dimension of the array V. LDV >= max(1,P). Q (output) COMPLEX array, dimension(LDQ,N) The N by N unitary matrix Q. LDQ (input) INTEGER The leading dimension of the array Q. LDQ >= max(1,N). ALPHA (output) REAL array, dimension (N) BETA (output) REAL array, dimension (N) The generalized singular value pairs of A and B, the ``diagonal'' matrices D1 and D2 are constructed from ALPHA and BETA, see subroutine CGGSVD for details. R (output) COMPLEX array, dimension(LDQ,N) The upper triangular matrix R. LDR (input) INTEGER The leading dimension of the array R. LDR >= max(1,N). IWORK (workspace) INTEGER array, dimension (N) WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The dimension of the array WORK, LWORK >= max(M,P,N)*max(M,P,N). RWORK (workspace) REAL array, dimension (max(M,P,N)) RESULT (output) REAL array, dimension (5) The test ratios: RESULT(1) = norm( U'*A*Q - D1*R ) / ( MAX(M,N)*norm(A)*ULP) RESULT(2) = norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP) RESULT(3) = norm( I - U'*U ) / ( M*ULP ) RESULT(4) = norm( I - V'*V ) / ( P*ULP ) RESULT(5) = norm( I - Q'*Q ) / ( N*ULP ) RESULT(6) = 0 if ALPHA is in decreasing order; = ULPINV otherwise. ===================================================================== Parameter adjustments */ af_dim1 = *lda; af_offset = 1 + af_dim1 * 1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; bf_dim1 = *ldb; bf_offset = 1 + bf_dim1 * 1; bf -= bf_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; --alpha; --beta; r_dim1 = *ldr; r_offset = 1 + r_dim1 * 1; r__ -= r_offset; --iwork; --work; --rwork; --result; /* Function Body */ ulp = slamch_("Precision"); ulpinv = 1.f / ulp; unfl = slamch_("Safe minimum"); /* Copy the matrix A to the array AF. */ clacpy_("Full", m, n, &a[a_offset], lda, &af[af_offset], lda); clacpy_("Full", p, n, &b[b_offset], ldb, &bf[bf_offset], ldb); /* Computing MAX */ r__1 = clange_("1", m, n, &a[a_offset], lda, &rwork[1]); anorm = dmax(r__1,unfl); /* Computing MAX */ r__1 = clange_("1", p, n, &b[b_offset], ldb, &rwork[1]); bnorm = dmax(r__1,unfl); /* Factorize the matrices A and B in the arrays AF and BF. */ cggsvd_("U", "V", "Q", m, n, p, &k, &l, &af[af_offset], lda, &bf[ bf_offset], ldb, &alpha[1], &beta[1], &u[u_offset], ldu, &v[ v_offset], ldv, &q[q_offset], ldq, &work[1], &rwork[1], &iwork[1], &info); /* Copy R Computing MIN */ i__2 = k + l; i__1 = min(i__2,*m); for (i__ = 1; i__ <= i__1; ++i__) { i__2 = k + l; for (j = i__; j <= i__2; ++j) { i__3 = r___subscr(i__, j); i__4 = af_subscr(i__, *n - k - l + j); r__[i__3].r = af[i__4].r, r__[i__3].i = af[i__4].i; /* L10: */ } /* L20: */ } if (*m - k - l < 0) { i__1 = k + l; for (i__ = *m + 1; i__ <= i__1; ++i__) { i__2 = k + l; for (j = i__; j <= i__2; ++j) { i__3 = r___subscr(i__, j); i__4 = bf_subscr(i__ - k, *n - k - l + j); r__[i__3].r = bf[i__4].r, r__[i__3].i = bf[i__4].i; /* L30: */ } /* L40: */ } } /* Compute A:= U'*A*Q - D1*R */ cgemm_("No transpose", "No transpose", m, n, n, &c_b2, &a[a_offset], lda, &q[q_offset], ldq, &c_b1, &work[1], lda); cgemm_("Conjugate transpose", "No transpose", m, n, m, &c_b2, &u[u_offset] , ldu, &work[1], lda, &c_b1, &a[a_offset], lda); i__1 = k; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = k + l; for (j = i__; j <= i__2; ++j) { i__3 = a_subscr(i__, *n - k - l + j); i__4 = a_subscr(i__, *n - k - l + j); i__5 = r___subscr(i__, j); q__1.r = a[i__4].r - r__[i__5].r, q__1.i = a[i__4].i - r__[i__5] .i; a[i__3].r = q__1.r, a[i__3].i = q__1.i; /* L50: */ } /* L60: */ } /* Computing MIN */ i__2 = k + l; i__1 = min(i__2,*m); for (i__ = k + 1; i__ <= i__1; ++i__) { i__2 = k + l; for (j = i__; j <= i__2; ++j) { i__3 = a_subscr(i__, *n - k - l + j); i__4 = a_subscr(i__, *n - k - l + j); i__5 = i__; i__6 = r___subscr(i__, j); q__2.r = alpha[i__5] * r__[i__6].r, q__2.i = alpha[i__5] * r__[ i__6].i; 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: */ } /* L80: */ } /* Compute norm( U'*A*Q - D1*R ) / ( MAX(1,M,N)*norm(A)*ULP ) . */ resid = clange_("1", m, n, &a[a_offset], lda, &rwork[1]); if (anorm > 0.f) { /* Computing MAX */ i__1 = max(1,*m); result[1] = resid / (real) max(i__1,*n) / anorm / ulp; } else { result[1] = 0.f; } /* Compute B := V'*B*Q - D2*R */ cgemm_("No transpose", "No transpose", p, n, n, &c_b2, &b[b_offset], ldb, &q[q_offset], ldq, &c_b1, &work[1], ldb); cgemm_("Conjugate transpose", "No transpose", p, n, p, &c_b2, &v[v_offset] , ldv, &work[1], ldb, &c_b1, &b[b_offset], ldb); i__1 = l; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = l; for (j = i__; j <= i__2; ++j) { i__3 = b_subscr(i__, *n - l + j); i__4 = b_subscr(i__, *n - l + j); i__5 = k + i__; i__6 = r___subscr(k + i__, k + j); q__2.r = beta[i__5] * r__[i__6].r, q__2.i = beta[i__5] * r__[i__6] .i; q__1.r = b[i__4].r - q__2.r, q__1.i = b[i__4].i - q__2.i; b[i__3].r = q__1.r, b[i__3].i = q__1.i; /* L90: */ } /* L100: */ } /* Compute norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP ) . */ resid = clange_("1", p, n, &b[b_offset], ldb, &rwork[1]); if (bnorm > 0.f) { /* Computing MAX */ i__1 = max(1,*p); result[2] = resid / (real) max(i__1,*n) / bnorm / ulp; } else { result[2] = 0.f; } /* Compute I - U'*U */ claset_("Full", m, m, &c_b1, &c_b2, &work[1], ldq); cherk_("Upper", "Conjugate transpose", m, m, &c_b36, &u[u_offset], ldu, & c_b37, &work[1], ldu); /* Compute norm( I - U'*U ) / ( M * ULP ) . */ resid = clanhe_("1", "Upper", m, &work[1], ldu, &rwork[1]); result[3] = resid / (real) max(1,*m) / ulp; /* Compute I - V'*V */ claset_("Full", p, p, &c_b1, &c_b2, &work[1], ldv); cherk_("Upper", "Conjugate transpose", p, p, &c_b36, &v[v_offset], ldv, & c_b37, &work[1], ldv); /* Compute norm( I - V'*V ) / ( P * ULP ) . */ resid = clanhe_("1", "Upper", p, &work[1], ldv, &rwork[1]); result[4] = resid / (real) max(1,*p) / ulp; /* Compute I - Q'*Q */ claset_("Full", n, n, &c_b1, &c_b2, &work[1], ldq); cherk_("Upper", "Conjugate transpose", n, n, &c_b36, &q[q_offset], ldq, & c_b37, &work[1], ldq); /* Compute norm( I - Q'*Q ) / ( N * ULP ) . */ resid = clanhe_("1", "Upper", n, &work[1], ldq, &rwork[1]); result[5] = resid / (real) max(1,*n) / ulp; /* Check sorting */ scopy_(n, &alpha[1], &c__1, &rwork[1], &c__1); /* Computing MIN */ i__2 = k + l; i__1 = min(i__2,*m); for (i__ = k + 1; i__ <= i__1; ++i__) { j = iwork[i__]; if (i__ != j) { temp = rwork[i__]; rwork[i__] = rwork[j]; rwork[j] = temp; } /* L110: */ } result[6] = 0.f; /* Computing MIN */ i__2 = k + l; i__1 = min(i__2,*m) - 1; for (i__ = k + 1; i__ <= i__1; ++i__) { if (rwork[i__] < rwork[i__ + 1]) { result[6] = ulpinv; } /* L120: */ } return 0; /* End of CGSVTS */ } /* cgsvts_ */
/* Subroutine */ int cpotrf_(char *uplo, integer *n, complex *a, integer *lda, integer *info) { /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= CPOTRF computes the Cholesky factorization of a complex Hermitian positive definite matrix A. The factorization has the form A = U**H * U, if UPLO = 'U', or A = L * L**H, if UPLO = 'L', where U is an upper triangular matrix and L is lower triangular. This is the block version of the algorithm, calling Level 3 BLAS. Arguments ========= UPLO (input) CHARACTER*1 = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. N (input) INTEGER The order of the matrix A. N >= 0. A (input/output) COMPLEX array, dimension (LDA,N) On entry, the Hermitian matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit, if INFO = 0, the factor U or L from the Cholesky factorization A = U**H*U or A = L*L**H. LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,N). INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, the leading minor of order i is not positive definite, and the factorization could not be completed. ===================================================================== Test the input parameters. Parameter adjustments */ /* Table of constant values */ static complex c_b1 = {1.f,0.f}; static integer c__1 = 1; static integer c_n1 = -1; static real c_b14 = -1.f; static real c_b15 = 1.f; /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4; complex q__1; /* Local variables */ static integer j; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrsm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *); static logical upper; extern /* Subroutine */ int cpotf2_(char *, integer *, complex *, integer *, integer *); static integer jb, nb; extern /* Subroutine */ int xerbla_(char *, integer *); extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *, ftnlen, ftnlen); #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)] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CPOTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine the block size for this environment. */ nb = ilaenv_(&c__1, "CPOTRF", uplo, n, &c_n1, &c_n1, &c_n1, (ftnlen)6, ( ftnlen)1); if (nb <= 1 || nb >= *n) { /* Use unblocked code. */ cpotf2_(uplo, n, &a[a_offset], lda, info); } else { /* Use blocked code. */ if (upper) { /* Compute the Cholesky factorization A = U'*U. */ i__1 = *n; i__2 = nb; for (j = 1; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Update and factorize the current diagonal block and test for non-positive-definiteness. Computing MIN */ i__3 = nb, i__4 = *n - j + 1; jb = min(i__3,i__4); i__3 = j - 1; cherk_("Upper", "Conjugate transpose", &jb, &i__3, &c_b14, & a_ref(1, j), lda, &c_b15, &a_ref(j, j), lda); cpotf2_("Upper", &jb, &a_ref(j, j), lda, info); if (*info != 0) { goto L30; } if (j + jb <= *n) { /* Compute the current block row. */ i__3 = *n - j - jb + 1; i__4 = j - 1; q__1.r = -1.f, q__1.i = 0.f; cgemm_("Conjugate transpose", "No transpose", &jb, &i__3, &i__4, &q__1, &a_ref(1, j), lda, &a_ref(1, j + jb) , lda, &c_b1, &a_ref(j, j + jb), lda); i__3 = *n - j - jb + 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-unit", &jb, &i__3, &c_b1, &a_ref(j, j), lda, &a_ref(j, j + jb), lda); } /* L10: */ } } else { /* Compute the Cholesky factorization A = L*L'. */ i__2 = *n; i__1 = nb; for (j = 1; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { /* Update and factorize the current diagonal block and test for non-positive-definiteness. Computing MIN */ i__3 = nb, i__4 = *n - j + 1; jb = min(i__3,i__4); i__3 = j - 1; cherk_("Lower", "No transpose", &jb, &i__3, &c_b14, &a_ref(j, 1), lda, &c_b15, &a_ref(j, j), lda); cpotf2_("Lower", &jb, &a_ref(j, j), lda, info); if (*info != 0) { goto L30; } if (j + jb <= *n) { /* Compute the current block column. */ i__3 = *n - j - jb + 1; i__4 = j - 1; q__1.r = -1.f, q__1.i = 0.f; cgemm_("No transpose", "Conjugate transpose", &i__3, &jb, &i__4, &q__1, &a_ref(j + jb, 1), lda, &a_ref(j, 1) , lda, &c_b1, &a_ref(j + jb, j), lda); i__3 = *n - j - jb + 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non-unit" , &i__3, &jb, &c_b1, &a_ref(j, j), lda, &a_ref(j + jb, j), lda); } /* L20: */ } } } goto L40; L30: *info = *info + j - 1; L40: return 0; /* End of CPOTRF */ } /* cpotrf_ */
/* Subroutine */ int cgqrts_(integer *n, integer *m, integer *p, complex *a, complex *af, complex *q, complex *r__, integer *lda, complex *taua, complex *b, complex *bf, complex *z__, complex *t, complex *bwk, integer *ldb, complex *taub, complex *work, integer *lwork, real * rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, r_dim1, r_offset, q_dim1, q_offset, b_dim1, b_offset, bf_dim1, bf_offset, t_dim1, t_offset, z_dim1, z_offset, bwk_dim1, bwk_offset, i__1, i__2; real r__1; complex q__1; /* Local variables */ real ulp; integer info; real unfl; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); real resid, anorm, bnorm; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *), clanhe_(char *, char *, integer *, complex *, integer *, real *), slamch_(char *); extern /* Subroutine */ int cggqrf_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, complex *, complex *, integer *, integer *), clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), cungqr_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *), cungrq_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGQRTS tests CGGQRF, which computes the GQR factorization of an */ /* N-by-M matrix A and a N-by-P matrix B: A = Q*R and B = Q*T*Z. */ /* Arguments */ /* ========= */ /* N (input) INTEGER */ /* The number of rows of the matrices A and B. N >= 0. */ /* M (input) INTEGER */ /* The number of columns of the matrix A. M >= 0. */ /* P (input) INTEGER */ /* The number of columns of the matrix B. P >= 0. */ /* A (input) COMPLEX array, dimension (LDA,M) */ /* The N-by-M matrix A. */ /* AF (output) COMPLEX array, dimension (LDA,N) */ /* Details of the GQR factorization of A and B, as returned */ /* by CGGQRF, see CGGQRF for further details. */ /* Q (output) COMPLEX array, dimension (LDA,N) */ /* The M-by-M unitary matrix Q. */ /* R (workspace) COMPLEX array, dimension (LDA,MAX(M,N)) */ /* LDA (input) INTEGER */ /* The leading dimension of the arrays A, AF, R and Q. */ /* LDA >= max(M,N). */ /* TAUA (output) COMPLEX array, dimension (min(M,N)) */ /* The scalar factors of the elementary reflectors, as returned */ /* by CGGQRF. */ /* B (input) COMPLEX array, dimension (LDB,P) */ /* On entry, the N-by-P matrix A. */ /* BF (output) COMPLEX array, dimension (LDB,N) */ /* Details of the GQR factorization of A and B, as returned */ /* by CGGQRF, see CGGQRF for further details. */ /* Z (output) COMPLEX array, dimension (LDB,P) */ /* The P-by-P unitary matrix Z. */ /* T (workspace) COMPLEX array, dimension (LDB,max(P,N)) */ /* BWK (workspace) COMPLEX array, dimension (LDB,N) */ /* LDB (input) INTEGER */ /* The leading dimension of the arrays B, BF, Z and T. */ /* LDB >= max(P,N). */ /* TAUB (output) COMPLEX array, dimension (min(P,N)) */ /* The scalar factors of the elementary reflectors, as returned */ /* by SGGRQF. */ /* WORK (workspace) COMPLEX array, dimension (LWORK) */ /* LWORK (input) INTEGER */ /* The dimension of the array WORK, LWORK >= max(N,M,P)**2. */ /* RWORK (workspace) REAL array, dimension (max(N,M,P)) */ /* RESULT (output) REAL array, dimension (4) */ /* The test ratios: */ /* RESULT(1) = norm( R - Q'*A ) / ( MAX(M,N)*norm(A)*ULP) */ /* RESULT(2) = norm( T*Z - Q'*B ) / (MAX(P,N)*norm(B)*ULP) */ /* RESULT(3) = norm( I - Q'*Q ) / ( M*ULP ) */ /* RESULT(4) = norm( I - Z'*Z ) / ( P*ULP ) */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ r_dim1 = *lda; r_offset = 1 + r_dim1; r__ -= r_offset; q_dim1 = *lda; q_offset = 1 + q_dim1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --taua; bwk_dim1 = *ldb; bwk_offset = 1 + bwk_dim1; bwk -= bwk_offset; t_dim1 = *ldb; t_offset = 1 + t_dim1; t -= t_offset; z_dim1 = *ldb; z_offset = 1 + z_dim1; z__ -= z_offset; bf_dim1 = *ldb; bf_offset = 1 + bf_dim1; bf -= bf_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; --taub; --work; --rwork; --result; /* Function Body */ ulp = slamch_("Precision"); unfl = slamch_("Safe minimum"); /* Copy the matrix A to the array AF. */ clacpy_("Full", n, m, &a[a_offset], lda, &af[af_offset], lda); clacpy_("Full", n, p, &b[b_offset], ldb, &bf[bf_offset], ldb); /* Computing MAX */ r__1 = clange_("1", n, m, &a[a_offset], lda, &rwork[1]); anorm = dmax(r__1,unfl); /* Computing MAX */ r__1 = clange_("1", n, p, &b[b_offset], ldb, &rwork[1]); bnorm = dmax(r__1,unfl); /* Factorize the matrices A and B in the arrays AF and BF. */ cggqrf_(n, m, p, &af[af_offset], lda, &taua[1], &bf[bf_offset], ldb, & taub[1], &work[1], lwork, &info); /* Generate the N-by-N matrix Q */ claset_("Full", n, n, &c_b3, &c_b3, &q[q_offset], lda); i__1 = *n - 1; clacpy_("Lower", &i__1, m, &af[af_dim1 + 2], lda, &q[q_dim1 + 2], lda); i__1 = min(*n,*m); cungqr_(n, n, &i__1, &q[q_offset], lda, &taua[1], &work[1], lwork, &info); /* Generate the P-by-P matrix Z */ claset_("Full", p, p, &c_b3, &c_b3, &z__[z_offset], ldb); if (*n <= *p) { if (*n > 0 && *n < *p) { i__1 = *p - *n; clacpy_("Full", n, &i__1, &bf[bf_offset], ldb, &z__[*p - *n + 1 + z_dim1], ldb); } if (*n > 1) { i__1 = *n - 1; i__2 = *n - 1; clacpy_("Lower", &i__1, &i__2, &bf[(*p - *n + 1) * bf_dim1 + 2], ldb, &z__[*p - *n + 2 + (*p - *n + 1) * z_dim1], ldb); } } else { if (*p > 1) { i__1 = *p - 1; i__2 = *p - 1; clacpy_("Lower", &i__1, &i__2, &bf[*n - *p + 2 + bf_dim1], ldb, & z__[z_dim1 + 2], ldb); } } i__1 = min(*n,*p); cungrq_(p, p, &i__1, &z__[z_offset], ldb, &taub[1], &work[1], lwork, & info); /* Copy R */ claset_("Full", n, m, &c_b1, &c_b1, &r__[r_offset], lda); clacpy_("Upper", n, m, &af[af_offset], lda, &r__[r_offset], lda); /* Copy T */ claset_("Full", n, p, &c_b1, &c_b1, &t[t_offset], ldb); if (*n <= *p) { clacpy_("Upper", n, n, &bf[(*p - *n + 1) * bf_dim1 + 1], ldb, &t[(*p - *n + 1) * t_dim1 + 1], ldb); } else { i__1 = *n - *p; clacpy_("Full", &i__1, p, &bf[bf_offset], ldb, &t[t_offset], ldb); clacpy_("Upper", p, p, &bf[*n - *p + 1 + bf_dim1], ldb, &t[*n - *p + 1 + t_dim1], ldb); } /* Compute R - Q'*A */ q__1.r = -1.f, q__1.i = -0.f; cgemm_("Conjugate transpose", "No transpose", n, m, n, &q__1, &q[q_offset] , lda, &a[a_offset], lda, &c_b2, &r__[r_offset], lda); /* Compute norm( R - Q'*A ) / ( MAX(M,N)*norm(A)*ULP ) . */ resid = clange_("1", n, m, &r__[r_offset], lda, &rwork[1]); if (anorm > 0.f) { /* Computing MAX */ i__1 = max(1,*m); result[1] = resid / (real) max(i__1,*n) / anorm / ulp; } else { result[1] = 0.f; } /* Compute T*Z - Q'*B */ cgemm_("No Transpose", "No transpose", n, p, p, &c_b2, &t[t_offset], ldb, &z__[z_offset], ldb, &c_b1, &bwk[bwk_offset], ldb); q__1.r = -1.f, q__1.i = -0.f; cgemm_("Conjugate transpose", "No transpose", n, p, n, &q__1, &q[q_offset] , lda, &b[b_offset], ldb, &c_b2, &bwk[bwk_offset], ldb); /* Compute norm( T*Z - Q'*B ) / ( MAX(P,N)*norm(A)*ULP ) . */ resid = clange_("1", n, p, &bwk[bwk_offset], ldb, &rwork[1]); if (bnorm > 0.f) { /* Computing MAX */ i__1 = max(1,*p); result[2] = resid / (real) max(i__1,*n) / bnorm / ulp; } else { result[2] = 0.f; } /* Compute I - Q'*Q */ claset_("Full", n, n, &c_b1, &c_b2, &r__[r_offset], lda); cherk_("Upper", "Conjugate transpose", n, n, &c_b34, &q[q_offset], lda, & c_b35, &r__[r_offset], lda); /* Compute norm( I - Q'*Q ) / ( N * ULP ) . */ resid = clanhe_("1", "Upper", n, &r__[r_offset], lda, &rwork[1]); result[3] = resid / (real) max(1,*n) / ulp; /* Compute I - Z'*Z */ claset_("Full", p, p, &c_b1, &c_b2, &t[t_offset], ldb); cherk_("Upper", "Conjugate transpose", p, p, &c_b34, &z__[z_offset], ldb, &c_b35, &t[t_offset], ldb); /* Compute norm( I - Z'*Z ) / ( P*ULP ) . */ resid = clanhe_("1", "Upper", p, &t[t_offset], ldb, &rwork[1]); result[4] = resid / (real) max(1,*p) / ulp; return 0; /* End of CGQRTS */ } /* cgqrts_ */
/* Subroutine */ int cgrqts_(integer *m, integer *p, integer *n, complex *a, complex *af, complex *q, complex *r__, integer *lda, complex *taua, complex *b, complex *bf, complex *z__, complex *t, complex *bwk, integer *ldb, complex *taub, complex *work, integer *lwork, real * rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, r_dim1, r_offset, q_dim1, q_offset, b_dim1, b_offset, bf_dim1, bf_offset, t_dim1, t_offset, z_dim1, z_offset, bwk_dim1, bwk_offset, i__1, i__2; real r__1; complex q__1; /* Local variables */ static integer info; static real unfl; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); static real resid, anorm, bnorm; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *), clanhe_(char *, char *, integer *, complex *, integer *, real *), slamch_(char *); extern /* Subroutine */ int cggrqf_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, complex *, complex *, integer *, integer *), clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), cungqr_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *), cungrq_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); static real ulp; #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 r___subscr(a_1,a_2) (a_2)*r_dim1 + a_1 #define r___ref(a_1,a_2) r__[r___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 af_subscr(a_1,a_2) (a_2)*af_dim1 + a_1 #define af_ref(a_1,a_2) af[af_subscr(a_1,a_2)] #define bf_subscr(a_1,a_2) (a_2)*bf_dim1 + a_1 #define bf_ref(a_1,a_2) bf[bf_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 September 30, 1994 Purpose ======= CGRQTS tests CGGRQF, which computes the GRQ factorization of an M-by-N matrix A and a P-by-N matrix B: A = R*Q and B = Z*T*Q. Arguments ========= M (input) INTEGER The number of rows of the matrix A. M >= 0. P (input) INTEGER The number of rows of the matrix B. P >= 0. N (input) INTEGER The number of columns of the matrices A and B. N >= 0. A (input) COMPLEX array, dimension (LDA,N) The M-by-N matrix A. AF (output) COMPLEX array, dimension (LDA,N) Details of the GRQ factorization of A and B, as returned by CGGRQF, see CGGRQF for further details. Q (output) COMPLEX array, dimension (LDA,N) The N-by-N unitary matrix Q. R (workspace) COMPLEX array, dimension (LDA,MAX(M,N)) LDA (input) INTEGER The leading dimension of the arrays A, AF, R and Q. LDA >= max(M,N). TAUA (output) COMPLEX array, dimension (min(M,N)) The scalar factors of the elementary reflectors, as returned by SGGQRC. B (input) COMPLEX array, dimension (LDB,N) On entry, the P-by-N matrix A. BF (output) COMPLEX array, dimension (LDB,N) Details of the GQR factorization of A and B, as returned by CGGRQF, see CGGRQF for further details. Z (output) REAL array, dimension (LDB,P) The P-by-P unitary matrix Z. T (workspace) COMPLEX array, dimension (LDB,max(P,N)) BWK (workspace) COMPLEX array, dimension (LDB,N) LDB (input) INTEGER The leading dimension of the arrays B, BF, Z and T. LDB >= max(P,N). TAUB (output) COMPLEX array, dimension (min(P,N)) The scalar factors of the elementary reflectors, as returned by SGGRQF. WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The dimension of the array WORK, LWORK >= max(M,P,N)**2. RWORK (workspace) REAL array, dimension (M) RESULT (output) REAL array, dimension (4) The test ratios: RESULT(1) = norm( R - A*Q' ) / ( MAX(M,N)*norm(A)*ULP) RESULT(2) = norm( T*Q - Z'*B ) / (MAX(P,N)*norm(B)*ULP) RESULT(3) = norm( I - Q'*Q ) / ( N*ULP ) RESULT(4) = norm( I - Z'*Z ) / ( P*ULP ) ===================================================================== Parameter adjustments */ r_dim1 = *lda; r_offset = 1 + r_dim1 * 1; r__ -= r_offset; q_dim1 = *lda; q_offset = 1 + q_dim1 * 1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1 * 1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --taua; bwk_dim1 = *ldb; bwk_offset = 1 + bwk_dim1 * 1; bwk -= bwk_offset; t_dim1 = *ldb; t_offset = 1 + t_dim1 * 1; t -= t_offset; z_dim1 = *ldb; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; bf_dim1 = *ldb; bf_offset = 1 + bf_dim1 * 1; bf -= bf_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --taub; --work; --rwork; --result; /* Function Body */ ulp = slamch_("Precision"); unfl = slamch_("Safe minimum"); /* Copy the matrix A to the array AF. */ clacpy_("Full", m, n, &a[a_offset], lda, &af[af_offset], lda); clacpy_("Full", p, n, &b[b_offset], ldb, &bf[bf_offset], ldb); /* Computing MAX */ r__1 = clange_("1", m, n, &a[a_offset], lda, &rwork[1]); anorm = dmax(r__1,unfl); /* Computing MAX */ r__1 = clange_("1", p, n, &b[b_offset], ldb, &rwork[1]); bnorm = dmax(r__1,unfl); /* Factorize the matrices A and B in the arrays AF and BF. */ cggrqf_(m, p, n, &af[af_offset], lda, &taua[1], &bf[bf_offset], ldb, & taub[1], &work[1], lwork, &info); /* Generate the N-by-N matrix Q */ claset_("Full", n, n, &c_b3, &c_b3, &q[q_offset], lda); if (*m <= *n) { if (*m > 0 && *m < *n) { i__1 = *n - *m; clacpy_("Full", m, &i__1, &af[af_offset], lda, &q_ref(*n - *m + 1, 1), lda); } if (*m > 1) { i__1 = *m - 1; i__2 = *m - 1; clacpy_("Lower", &i__1, &i__2, &af_ref(2, *n - *m + 1), lda, & q_ref(*n - *m + 2, *n - *m + 1), lda); } } else { if (*n > 1) { i__1 = *n - 1; i__2 = *n - 1; clacpy_("Lower", &i__1, &i__2, &af_ref(*m - *n + 2, 1), lda, & q_ref(2, 1), lda); } } i__1 = min(*m,*n); cungrq_(n, n, &i__1, &q[q_offset], lda, &taua[1], &work[1], lwork, &info); /* Generate the P-by-P matrix Z */ claset_("Full", p, p, &c_b3, &c_b3, &z__[z_offset], ldb); if (*p > 1) { i__1 = *p - 1; clacpy_("Lower", &i__1, n, &bf_ref(2, 1), ldb, &z___ref(2, 1), ldb); } i__1 = min(*p,*n); cungqr_(p, p, &i__1, &z__[z_offset], ldb, &taub[1], &work[1], lwork, & info); /* Copy R */ claset_("Full", m, n, &c_b1, &c_b1, &r__[r_offset], lda); if (*m <= *n) { clacpy_("Upper", m, m, &af_ref(1, *n - *m + 1), lda, &r___ref(1, *n - *m + 1), lda); } else { i__1 = *m - *n; clacpy_("Full", &i__1, n, &af[af_offset], lda, &r__[r_offset], lda); clacpy_("Upper", n, n, &af_ref(*m - *n + 1, 1), lda, &r___ref(*m - *n + 1, 1), lda); } /* Copy T */ claset_("Full", p, n, &c_b1, &c_b1, &t[t_offset], ldb); clacpy_("Upper", p, n, &bf[bf_offset], ldb, &t[t_offset], ldb); /* Compute R - A*Q' */ q__1.r = -1.f, q__1.i = 0.f; cgemm_("No transpose", "Conjugate transpose", m, n, n, &q__1, &a[a_offset] , lda, &q[q_offset], lda, &c_b2, &r__[r_offset], lda); /* Compute norm( R - A*Q' ) / ( MAX(M,N)*norm(A)*ULP ) . */ resid = clange_("1", m, n, &r__[r_offset], lda, &rwork[1]); if (anorm > 0.f) { /* Computing MAX */ i__1 = max(1,*m); result[1] = resid / (real) max(i__1,*n) / anorm / ulp; } else { result[1] = 0.f; } /* Compute T*Q - Z'*B */ cgemm_("Conjugate transpose", "No transpose", p, n, p, &c_b2, &z__[ z_offset], ldb, &b[b_offset], ldb, &c_b1, &bwk[bwk_offset], ldb); q__1.r = -1.f, q__1.i = 0.f; cgemm_("No transpose", "No transpose", p, n, n, &c_b2, &t[t_offset], ldb, &q[q_offset], lda, &q__1, &bwk[bwk_offset], ldb); /* Compute norm( T*Q - Z'*B ) / ( MAX(P,N)*norm(A)*ULP ) . */ resid = clange_("1", p, n, &bwk[bwk_offset], ldb, &rwork[1]); if (bnorm > 0.f) { /* Computing MAX */ i__1 = max(1,*p); result[2] = resid / (real) max(i__1,*m) / bnorm / ulp; } else { result[2] = 0.f; } /* Compute I - Q*Q' */ claset_("Full", n, n, &c_b1, &c_b2, &r__[r_offset], lda); cherk_("Upper", "No Transpose", n, n, &c_b34, &q[q_offset], lda, &c_b35, & r__[r_offset], lda); /* Compute norm( I - Q'*Q ) / ( N * ULP ) . */ resid = clanhe_("1", "Upper", n, &r__[r_offset], lda, &rwork[1]); result[3] = resid / (real) max(1,*n) / ulp; /* Compute I - Z'*Z */ claset_("Full", p, p, &c_b1, &c_b2, &t[t_offset], ldb); cherk_("Upper", "Conjugate transpose", p, p, &c_b34, &z__[z_offset], ldb, &c_b35, &t[t_offset], ldb); /* Compute norm( I - Z'*Z ) / ( P*ULP ) . */ resid = clanhe_("1", "Upper", p, &t[t_offset], ldb, &rwork[1]); result[4] = resid / (real) max(1,*p) / ulp; return 0; /* End of CGRQTS */ } /* cgrqts_ */
/* Subroutine */ int chfrk_(char *transr, char *uplo, char *trans, integer *n, integer *k, real *alpha, complex *a, integer *lda, real *beta, complex *c__) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2; complex q__1; /* Local variables */ integer j, n1, n2, nk, info; complex cbeta; logical normaltransr; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); extern logical lsame_(char *, char *); integer nrowa; logical lower; complex calpha; extern /* Subroutine */ int xerbla_(char *, integer *); logical nisodd, notrans; /* -- LAPACK routine (version 3.2) -- */ /* -- Contributed by Julien Langou of the Univ. of Colorado Denver -- */ /* -- November 2008 -- */ /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ /* .. */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* Level 3 BLAS like routine for C in RFP Format. */ /* CHFRK performs one of the Hermitian rank--k operations */ /* C := alpha*A*conjg( A' ) + beta*C, */ /* or */ /* C := alpha*conjg( A' )*A + beta*C, */ /* where alpha and beta are real scalars, C is an n--by--n Hermitian */ /* matrix and A is an n--by--k matrix in the first case and a k--by--n */ /* matrix in the second case. */ /* Arguments */ /* ========== */ /* TRANSR - (input) CHARACTER. */ /* = 'N': The Normal Form of RFP A is stored; */ /* = 'C': The Conjugate-transpose Form of RFP A is stored. */ /* UPLO - (input) CHARACTER. */ /* On entry, UPLO specifies whether the upper or lower */ /* triangular part of the array C is to be referenced as */ /* follows: */ /* UPLO = 'U' or 'u' Only the upper triangular part of C */ /* is to be referenced. */ /* UPLO = 'L' or 'l' Only the lower triangular part of C */ /* is to be referenced. */ /* Unchanged on exit. */ /* TRANS - (input) CHARACTER. */ /* On entry, TRANS specifies the operation to be performed as */ /* follows: */ /* TRANS = 'N' or 'n' C := alpha*A*conjg( A' ) + beta*C. */ /* TRANS = 'C' or 'c' C := alpha*conjg( A' )*A + beta*C. */ /* Unchanged on exit. */ /* N - (input) INTEGER. */ /* On entry, N specifies the order of the matrix C. N must be */ /* at least zero. */ /* Unchanged on exit. */ /* K - (input) INTEGER. */ /* On entry with TRANS = 'N' or 'n', K specifies the number */ /* of columns of the matrix A, and on entry with */ /* TRANS = 'C' or 'c', K specifies the number of rows of the */ /* matrix A. K must be at least zero. */ /* Unchanged on exit. */ /* ALPHA - (input) REAL. */ /* On entry, ALPHA specifies the scalar alpha. */ /* Unchanged on exit. */ /* A - (input) COMPLEX array of DIMENSION ( LDA, ka ), where KA */ /* is K when TRANS = 'N' or 'n', and is N otherwise. Before */ /* entry with TRANS = 'N' or 'n', the leading N--by--K part of */ /* the array A must contain the matrix A, otherwise the leading */ /* K--by--N part of the array A must contain the matrix A. */ /* Unchanged on exit. */ /* LDA - (input) INTEGER. */ /* On entry, LDA specifies the first dimension of A as declared */ /* in the calling (sub) program. When TRANS = 'N' or 'n' */ /* then LDA must be at least max( 1, n ), otherwise LDA must */ /* be at least max( 1, k ). */ /* Unchanged on exit. */ /* BETA - (input) REAL. */ /* On entry, BETA specifies the scalar beta. */ /* Unchanged on exit. */ /* C - (input/output) COMPLEX array, dimension ( N*(N+1)/2 ). */ /* On entry, the matrix A in RFP Format. RFP Format is */ /* described by TRANSR, UPLO and N. 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. */ /* Arguments */ /* ========== */ /* .. */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --c__; /* Function Body */ info = 0; normaltransr = lsame_(transr, "N"); lower = lsame_(uplo, "L"); notrans = lsame_(trans, "N"); if (notrans) { nrowa = *n; } else { nrowa = *k; } if (! normaltransr && ! lsame_(transr, "C")) { info = -1; } else if (! lower && ! lsame_(uplo, "U")) { info = -2; } else if (! notrans && ! lsame_(trans, "C")) { info = -3; } else if (*n < 0) { info = -4; } else if (*k < 0) { info = -5; } else if (*lda < max(1,nrowa)) { info = -8; } if (info != 0) { i__1 = -info; xerbla_("CHFRK ", &i__1); return 0; } /* Quick return if possible. */ /* The quick return case: ((ALPHA.EQ.0).AND.(BETA.NE.ZERO)) is not */ /* done (it is in CHERK for example) and left in the general case. */ if (*n == 0 || (*alpha == 0.f || *k == 0) && *beta == 1.f) { return 0; } if (*alpha == 0.f && *beta == 0.f) { i__1 = *n * (*n + 1) / 2; for (j = 1; j <= i__1; ++j) { i__2 = j; c__[i__2].r = 0.f, c__[i__2].i = 0.f; } return 0; } q__1.r = *alpha, q__1.i = 0.f; calpha.r = q__1.r, calpha.i = q__1.i; q__1.r = *beta, q__1.i = 0.f; cbeta.r = q__1.r, cbeta.i = q__1.i; /* C is N-by-N. */ /* If N is odd, set NISODD = .TRUE., and N1 and N2. */ /* If N is even, NISODD = .FALSE., and NK. */ if (*n % 2 == 0) { nisodd = FALSE_; nk = *n / 2; } else { nisodd = TRUE_; if (lower) { n2 = *n / 2; n1 = *n - n2; } else { n1 = *n / 2; n2 = *n - n1; } } if (nisodd) { /* N is odd */ if (normaltransr) { /* N is odd and TRANSR = 'N' */ if (lower) { /* N is odd, TRANSR = 'N', and UPLO = 'L' */ if (notrans) { /* N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'N' */ cherk_("L", "N", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[1], n); cherk_("U", "N", &n2, k, alpha, &a[n1 + 1 + a_dim1], lda, beta, &c__[*n + 1], n); cgemm_("N", "C", &n2, &n1, k, &calpha, &a[n1 + 1 + a_dim1] , lda, &a[a_dim1 + 1], lda, &cbeta, &c__[n1 + 1], n); } else { /* N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'C' */ cherk_("L", "C", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[1], n); cherk_("U", "C", &n2, k, alpha, &a[(n1 + 1) * a_dim1 + 1], lda, beta, &c__[*n + 1], n) ; cgemm_("C", "N", &n2, &n1, k, &calpha, &a[(n1 + 1) * a_dim1 + 1], lda, &a[a_dim1 + 1], lda, &cbeta, & c__[n1 + 1], n); } } else { /* N is odd, TRANSR = 'N', and UPLO = 'U' */ if (notrans) { /* N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'N' */ cherk_("L", "N", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[n2 + 1], n); cherk_("U", "N", &n2, k, alpha, &a[n2 + a_dim1], lda, beta, &c__[n1 + 1], n); cgemm_("N", "C", &n1, &n2, k, &calpha, &a[a_dim1 + 1], lda, &a[n2 + a_dim1], lda, &cbeta, &c__[1], n); } else { /* N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'C' */ cherk_("L", "C", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[n2 + 1], n); cherk_("U", "C", &n2, k, alpha, &a[n2 * a_dim1 + 1], lda, beta, &c__[n1 + 1], n); cgemm_("C", "N", &n1, &n2, k, &calpha, &a[a_dim1 + 1], lda, &a[n2 * a_dim1 + 1], lda, &cbeta, &c__[1], n); } } } else { /* N is odd, and TRANSR = 'C' */ if (lower) { /* N is odd, TRANSR = 'C', and UPLO = 'L' */ if (notrans) { /* N is odd, TRANSR = 'C', UPLO = 'L', and TRANS = 'N' */ cherk_("U", "N", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[1], &n1); cherk_("L", "N", &n2, k, alpha, &a[n1 + 1 + a_dim1], lda, beta, &c__[2], &n1); cgemm_("N", "C", &n1, &n2, k, &calpha, &a[a_dim1 + 1], lda, &a[n1 + 1 + a_dim1], lda, &cbeta, &c__[n1 * n1 + 1], &n1); } else { /* N is odd, TRANSR = 'C', UPLO = 'L', and TRANS = 'C' */ cherk_("U", "C", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[1], &n1); cherk_("L", "C", &n2, k, alpha, &a[(n1 + 1) * a_dim1 + 1], lda, beta, &c__[2], &n1); cgemm_("C", "N", &n1, &n2, k, &calpha, &a[a_dim1 + 1], lda, &a[(n1 + 1) * a_dim1 + 1], lda, &cbeta, &c__[ n1 * n1 + 1], &n1); } } else { /* N is odd, TRANSR = 'C', and UPLO = 'U' */ if (notrans) { /* N is odd, TRANSR = 'C', UPLO = 'U', and TRANS = 'N' */ cherk_("U", "N", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[n2 * n2 + 1], &n2); cherk_("L", "N", &n2, k, alpha, &a[n1 + 1 + a_dim1], lda, beta, &c__[n1 * n2 + 1], &n2); cgemm_("N", "C", &n2, &n1, k, &calpha, &a[n1 + 1 + a_dim1] , lda, &a[a_dim1 + 1], lda, &cbeta, &c__[1], &n2); } else { /* N is odd, TRANSR = 'C', UPLO = 'U', and TRANS = 'C' */ cherk_("U", "C", &n1, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[n2 * n2 + 1], &n2); cherk_("L", "C", &n2, k, alpha, &a[(n1 + 1) * a_dim1 + 1], lda, beta, &c__[n1 * n2 + 1], &n2); cgemm_("C", "N", &n2, &n1, k, &calpha, &a[(n1 + 1) * a_dim1 + 1], lda, &a[a_dim1 + 1], lda, &cbeta, & c__[1], &n2); } } } } else { /* N is even */ if (normaltransr) { /* N is even and TRANSR = 'N' */ if (lower) { /* N is even, TRANSR = 'N', and UPLO = 'L' */ if (notrans) { /* N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'N' */ i__1 = *n + 1; cherk_("L", "N", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[2], &i__1); i__1 = *n + 1; cherk_("U", "N", &nk, k, alpha, &a[nk + 1 + a_dim1], lda, beta, &c__[1], &i__1); i__1 = *n + 1; cgemm_("N", "C", &nk, &nk, k, &calpha, &a[nk + 1 + a_dim1] , lda, &a[a_dim1 + 1], lda, &cbeta, &c__[nk + 2], &i__1); } else { /* N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'C' */ i__1 = *n + 1; cherk_("L", "C", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[2], &i__1); i__1 = *n + 1; cherk_("U", "C", &nk, k, alpha, &a[(nk + 1) * a_dim1 + 1], lda, beta, &c__[1], &i__1); i__1 = *n + 1; cgemm_("C", "N", &nk, &nk, k, &calpha, &a[(nk + 1) * a_dim1 + 1], lda, &a[a_dim1 + 1], lda, &cbeta, & c__[nk + 2], &i__1); } } else { /* N is even, TRANSR = 'N', and UPLO = 'U' */ if (notrans) { /* N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'N' */ i__1 = *n + 1; cherk_("L", "N", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk + 2], &i__1); i__1 = *n + 1; cherk_("U", "N", &nk, k, alpha, &a[nk + 1 + a_dim1], lda, beta, &c__[nk + 1], &i__1); i__1 = *n + 1; cgemm_("N", "C", &nk, &nk, k, &calpha, &a[a_dim1 + 1], lda, &a[nk + 1 + a_dim1], lda, &cbeta, &c__[1], & i__1); } else { /* N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'C' */ i__1 = *n + 1; cherk_("L", "C", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk + 2], &i__1); i__1 = *n + 1; cherk_("U", "C", &nk, k, alpha, &a[(nk + 1) * a_dim1 + 1], lda, beta, &c__[nk + 1], &i__1); i__1 = *n + 1; cgemm_("C", "N", &nk, &nk, k, &calpha, &a[a_dim1 + 1], lda, &a[(nk + 1) * a_dim1 + 1], lda, &cbeta, &c__[ 1], &i__1); } } } else { /* N is even, and TRANSR = 'C' */ if (lower) { /* N is even, TRANSR = 'C', and UPLO = 'L' */ if (notrans) { /* N is even, TRANSR = 'C', UPLO = 'L', and TRANS = 'N' */ cherk_("U", "N", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk + 1], &nk); cherk_("L", "N", &nk, k, alpha, &a[nk + 1 + a_dim1], lda, beta, &c__[1], &nk); cgemm_("N", "C", &nk, &nk, k, &calpha, &a[a_dim1 + 1], lda, &a[nk + 1 + a_dim1], lda, &cbeta, &c__[(nk + 1) * nk + 1], &nk); } else { /* N is even, TRANSR = 'C', UPLO = 'L', and TRANS = 'C' */ cherk_("U", "C", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk + 1], &nk); cherk_("L", "C", &nk, k, alpha, &a[(nk + 1) * a_dim1 + 1], lda, beta, &c__[1], &nk); cgemm_("C", "N", &nk, &nk, k, &calpha, &a[a_dim1 + 1], lda, &a[(nk + 1) * a_dim1 + 1], lda, &cbeta, &c__[ (nk + 1) * nk + 1], &nk); } } else { /* N is even, TRANSR = 'C', and UPLO = 'U' */ if (notrans) { /* N is even, TRANSR = 'C', UPLO = 'U', and TRANS = 'N' */ cherk_("U", "N", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk * (nk + 1) + 1], &nk); cherk_("L", "N", &nk, k, alpha, &a[nk + 1 + a_dim1], lda, beta, &c__[nk * nk + 1], &nk); cgemm_("N", "C", &nk, &nk, k, &calpha, &a[nk + 1 + a_dim1] , lda, &a[a_dim1 + 1], lda, &cbeta, &c__[1], &nk); } else { /* N is even, TRANSR = 'C', UPLO = 'U', and TRANS = 'C' */ cherk_("U", "C", &nk, k, alpha, &a[a_dim1 + 1], lda, beta, &c__[nk * (nk + 1) + 1], &nk); cherk_("L", "C", &nk, k, alpha, &a[(nk + 1) * a_dim1 + 1], lda, beta, &c__[nk * nk + 1], &nk); cgemm_("C", "N", &nk, &nk, k, &calpha, &a[(nk + 1) * a_dim1 + 1], lda, &a[a_dim1 + 1], lda, &cbeta, & c__[1], &nk); } } } } return 0; /* End of CHFRK */ } /* chfrk_ */
int main( int argc, char** argv ) { obj_t a, c; obj_t c_save; obj_t alpha, beta; dim_t m, k; dim_t p; dim_t p_begin, p_end, p_inc; int m_input, k_input; num_t dt; int r, n_repeats; uplo_t uploc; trans_t transa; f77_char f77_uploc; f77_char f77_transa; double dtime; double dtime_save; double gflops; bli_init(); //bli_error_checking_level_set( BLIS_NO_ERROR_CHECKING ); n_repeats = 3; #ifndef PRINT p_begin = 200; p_end = 2000; p_inc = 200; m_input = -1; k_input = -1; #else p_begin = 16; p_end = 16; p_inc = 1; m_input = 3; k_input = 1; #endif #if 1 //dt = BLIS_FLOAT; dt = BLIS_DOUBLE; #else //dt = BLIS_SCOMPLEX; dt = BLIS_DCOMPLEX; #endif uploc = BLIS_LOWER; //uploc = BLIS_UPPER; transa = BLIS_NO_TRANSPOSE; bli_param_map_blis_to_netlib_uplo( uploc, &f77_uploc ); bli_param_map_blis_to_netlib_trans( transa, &f77_transa ); for ( p = p_begin; p <= p_end; p += p_inc ) { if ( m_input < 0 ) m = p * ( dim_t )abs(m_input); else m = ( dim_t ) m_input; if ( k_input < 0 ) k = p * ( dim_t )abs(k_input); else k = ( dim_t ) k_input; bli_obj_create( dt, 1, 1, 0, 0, &alpha ); bli_obj_create( dt, 1, 1, 0, 0, &beta ); if ( bli_does_trans( transa ) ) bli_obj_create( dt, k, m, 0, 0, &a ); else bli_obj_create( dt, m, k, 0, 0, &a ); bli_obj_create( dt, m, m, 0, 0, &c ); bli_obj_create( dt, m, m, 0, 0, &c_save ); bli_randm( &a ); bli_randm( &c ); bli_obj_set_struc( BLIS_HERMITIAN, c ); bli_obj_set_uplo( uploc, c ); bli_obj_set_conjtrans( transa, a ); bli_setsc( (2.0/1.0), 0.0, &alpha ); bli_setsc( -(1.0/1.0), 0.0, &beta ); bli_copym( &c, &c_save ); dtime_save = 1.0e9; for ( r = 0; r < n_repeats; ++r ) { bli_copym( &c_save, &c ); dtime = bli_clock(); #ifdef PRINT bli_printm( "a", &a, "%4.1f", "" ); bli_printm( "c", &c, "%4.1f", "" ); #endif #ifdef BLIS bli_herk( &alpha, &a, &beta, &c ); #else if ( bli_is_float( dt ) ) { f77_int mm = bli_obj_length( c ); f77_int kk = bli_obj_width_after_trans( a ); f77_int lda = bli_obj_col_stride( a ); f77_int ldc = bli_obj_col_stride( c ); float* alphap = bli_obj_buffer( alpha ); float* ap = bli_obj_buffer( a ); float* betap = bli_obj_buffer( beta ); float* cp = bli_obj_buffer( c ); ssyrk_( &f77_uploc, &f77_transa, &mm, &kk, alphap, ap, &lda, betap, cp, &ldc ); } else if ( bli_is_double( dt ) ) { f77_int mm = bli_obj_length( c ); f77_int kk = bli_obj_width_after_trans( a ); f77_int lda = bli_obj_col_stride( a ); f77_int ldc = bli_obj_col_stride( c ); double* alphap = bli_obj_buffer( alpha ); double* ap = bli_obj_buffer( a ); double* betap = bli_obj_buffer( beta ); double* cp = bli_obj_buffer( c ); dsyrk_( &f77_uploc, &f77_transa, &mm, &kk, alphap, ap, &lda, betap, cp, &ldc ); } else if ( bli_is_scomplex( dt ) ) { f77_int mm = bli_obj_length( c ); f77_int kk = bli_obj_width_after_trans( a ); f77_int lda = bli_obj_col_stride( a ); f77_int ldc = bli_obj_col_stride( c ); float* alphap = bli_obj_buffer( alpha ); scomplex* ap = bli_obj_buffer( a ); float* betap = bli_obj_buffer( beta ); scomplex* cp = bli_obj_buffer( c ); cherk_( &f77_uploc, &f77_transa, &mm, &kk, alphap, ap, &lda, betap, cp, &ldc ); } else if ( bli_is_dcomplex( dt ) ) { f77_int mm = bli_obj_length( c ); f77_int kk = bli_obj_width_after_trans( a ); f77_int lda = bli_obj_col_stride( a ); f77_int ldc = bli_obj_col_stride( c ); double* alphap = bli_obj_buffer( alpha ); dcomplex* ap = bli_obj_buffer( a ); double* betap = bli_obj_buffer( beta ); dcomplex* cp = bli_obj_buffer( c ); zherk_( &f77_uploc, &f77_transa, &mm, &kk, alphap, ap, &lda, betap, cp, &ldc ); } #endif #ifdef PRINT bli_printm( "c after", &c, "%4.1f", "" ); exit(1); #endif dtime_save = bli_clock_min_diff( dtime_save, dtime ); } gflops = ( 1.0 * m * k * m ) / ( dtime_save * 1.0e9 ); if ( bli_is_complex( dt ) ) gflops *= 4.0; #ifdef BLIS printf( "data_herk_blis" ); #else printf( "data_herk_%s", BLAS ); #endif printf( "( %2lu, 1:4 ) = [ %4lu %4lu %10.3e %6.3f ];\n", ( unsigned long )(p - p_begin + 1)/p_inc + 1, ( unsigned long )m, ( unsigned long )k, dtime_save, gflops ); bli_obj_free( &alpha ); bli_obj_free( &beta ); bli_obj_free( &a ); bli_obj_free( &c ); bli_obj_free( &c_save ); } bli_finalize(); return 0; }
/* Subroutine */ int clauum_(char *uplo, integer *n, complex *a, integer *lda, integer *info) { /* -- LAPACK auxiliary routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= CLAUUM computes the product U * U' or L' * L, where the triangular factor U or L is stored in the upper or lower triangular part of the array A. If UPLO = 'U' or 'u' then the upper triangle of the result is stored, overwriting the factor U in A. If UPLO = 'L' or 'l' then the lower triangle of the result is stored, overwriting the factor L in A. This is the blocked form of the algorithm, calling Level 3 BLAS. Arguments ========= UPLO (input) CHARACTER*1 Specifies whether the triangular factor stored in the array A is upper or lower triangular: = 'U': Upper triangular = 'L': Lower triangular N (input) INTEGER The order of the triangular factor U or L. N >= 0. A (input/output) COMPLEX array, dimension (LDA,N) On entry, the triangular factor U or L. On exit, if UPLO = 'U', the upper triangle of A is overwritten with the upper triangle of the product U * U'; if UPLO = 'L', the lower triangle of A is overwritten with the lower triangle of the product L' * L. LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,N). INFO (output) INTEGER = 0: successful exit < 0: if INFO = -k, the k-th argument had an illegal value ===================================================================== Test the input parameters. Parameter adjustments Function Body */ /* Table of constant values */ static complex c_b1 = {1.f,0.f}; static integer c__1 = 1; static integer c_n1 = -1; static real c_b21 = 1.f; /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static integer i; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrmm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *); static logical upper; extern /* Subroutine */ int clauu2_(char *, integer *, complex *, integer *, integer *); static integer ib, nb; extern /* Subroutine */ int xerbla_(char *, integer *); extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *, ftnlen, ftnlen); #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CLAUUM", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine the block size for this environment. */ nb = ilaenv_(&c__1, "CLAUUM", uplo, n, &c_n1, &c_n1, &c_n1, 6L, 1L); if (nb <= 1 || nb >= *n) { /* Use unblocked code */ clauu2_(uplo, n, &A(1,1), lda, info); } else { /* Use blocked code */ if (upper) { /* Compute the product U * U'. */ i__1 = *n; i__2 = nb; for (i = 1; nb < 0 ? i >= *n : i <= *n; i += nb) { /* Computing MIN */ i__3 = nb, i__4 = *n - i + 1; ib = min(i__3,i__4); i__3 = i - 1; ctrmm_("Right", "Upper", "Conjugate transpose", "Non-unit", & i__3, &ib, &c_b1, &A(i,i), lda, &A(1,i), lda); clauu2_("Upper", &ib, &A(i,i), lda, info); if (i + ib <= *n) { i__3 = i - 1; i__4 = *n - i - ib + 1; cgemm_("No transpose", "Conjugate transpose", &i__3, &ib, &i__4, &c_b1, &A(1,i+ib), lda, &A(i,i+ib), lda, &c_b1, &A(1,i), lda); i__3 = *n - i - ib + 1; cherk_("Upper", "No transpose", &ib, &i__3, &c_b21, &A(i,i+ib), lda, &c_b21, &A(i,i), lda); } /* L10: */ } } else { /* Compute the product L' * L. */ i__2 = *n; i__1 = nb; for (i = 1; nb < 0 ? i >= *n : i <= *n; i += nb) { /* Computing MIN */ i__3 = nb, i__4 = *n - i + 1; ib = min(i__3,i__4); i__3 = i - 1; ctrmm_("Left", "Lower", "Conjugate transpose", "Non-unit", & ib, &i__3, &c_b1, &A(i,i), lda, &A(i,1), lda); clauu2_("Lower", &ib, &A(i,i), lda, info); if (i + ib <= *n) { i__3 = i - 1; i__4 = *n - i - ib + 1; cgemm_("Conjugate transpose", "No transpose", &ib, &i__3, &i__4, &c_b1, &A(i+ib,i), lda, &A(i+ib,1), lda, &c_b1, &A(i,1), lda); i__3 = *n - i - ib + 1; cherk_("Lower", "Conjugate transpose", &ib, &i__3, &c_b21, &A(i+ib,i), lda, &c_b21, &A(i,i), lda); } /* L20: */ } } } return 0; /* End of CLAUUM */ } /* clauum_ */
/* Subroutine */ int cpotrf_(char *uplo, integer *n, complex *a, integer *lda, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3, i__4; complex q__1; /* Local variables */ integer j, jb, nb; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int ctrsm_(char *, char *, char *, char *, integer *, integer *, complex *, complex *, integer *, complex *, integer *); logical upper; extern /* Subroutine */ int cpotf2_(char *, integer *, complex *, integer *, integer *), xerbla_(char *, integer *); extern integer ilaenv_(integer *, char *, char *, integer *, integer *, integer *, integer *); /* -- LAPACK routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CPOTRF computes the Cholesky factorization of a complex Hermitian */ /* positive definite matrix A. */ /* The factorization has the form */ /* A = U**H * U, if UPLO = 'U', or */ /* A = L * L**H, if UPLO = 'L', */ /* where U is an upper triangular matrix and L is lower triangular. */ /* This is the block version of the algorithm, calling Level 3 BLAS. */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* = 'U': Upper triangle of A is stored; */ /* = 'L': Lower triangle of A is stored. */ /* N (input) INTEGER */ /* The order of the matrix A. N >= 0. */ /* A (input/output) COMPLEX array, dimension (LDA,N) */ /* On entry, the Hermitian matrix A. If UPLO = 'U', the leading */ /* N-by-N upper triangular part of A contains the upper */ /* triangular part of the matrix A, and the strictly lower */ /* triangular part of A is not referenced. If UPLO = 'L', the */ /* leading N-by-N lower triangular part of A contains the lower */ /* triangular part of the matrix A, and the strictly upper */ /* triangular part of A is not referenced. */ /* On exit, if INFO = 0, the factor U or L from the Cholesky */ /* factorization A = U**H*U or A = L*L**H. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -i, the i-th argument had an illegal value */ /* > 0: if INFO = i, the leading minor of order i is not */ /* positive definite, and the factorization could not be */ /* completed. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; /* Function Body */ *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("CPOTRF", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Determine the block size for this environment. */ nb = ilaenv_(&c__1, "CPOTRF", uplo, n, &c_n1, &c_n1, &c_n1); if (nb <= 1 || nb >= *n) { /* Use unblocked code. */ cpotf2_(uplo, n, &a[a_offset], lda, info); } else { /* Use blocked code. */ if (upper) { /* Compute the Cholesky factorization A = U'*U. */ i__1 = *n; i__2 = nb; for (j = 1; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Update and factorize the current diagonal block and test */ /* for non-positive-definiteness. */ /* Computing MIN */ i__3 = nb, i__4 = *n - j + 1; jb = min(i__3,i__4); i__3 = j - 1; cherk_("Upper", "Conjugate transpose", &jb, &i__3, &c_b14, &a[ j * a_dim1 + 1], lda, &c_b15, &a[j + j * a_dim1], lda); cpotf2_("Upper", &jb, &a[j + j * a_dim1], lda, info); if (*info != 0) { goto L30; } if (j + jb <= *n) { /* Compute the current block row. */ i__3 = *n - j - jb + 1; i__4 = j - 1; q__1.r = -1.f, q__1.i = -0.f; cgemm_("Conjugate transpose", "No transpose", &jb, &i__3, &i__4, &q__1, &a[j * a_dim1 + 1], lda, &a[(j + jb) * a_dim1 + 1], lda, &c_b1, &a[j + (j + jb) * a_dim1], lda); i__3 = *n - j - jb + 1; ctrsm_("Left", "Upper", "Conjugate transpose", "Non-unit", &jb, &i__3, &c_b1, &a[j + j * a_dim1], lda, &a[j + (j + jb) * a_dim1], lda); } /* L10: */ } } else { /* Compute the Cholesky factorization A = L*L'. */ i__2 = *n; i__1 = nb; for (j = 1; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { /* Update and factorize the current diagonal block and test */ /* for non-positive-definiteness. */ /* Computing MIN */ i__3 = nb, i__4 = *n - j + 1; jb = min(i__3,i__4); i__3 = j - 1; cherk_("Lower", "No transpose", &jb, &i__3, &c_b14, &a[j + a_dim1], lda, &c_b15, &a[j + j * a_dim1], lda); cpotf2_("Lower", &jb, &a[j + j * a_dim1], lda, info); if (*info != 0) { goto L30; } if (j + jb <= *n) { /* Compute the current block column. */ i__3 = *n - j - jb + 1; i__4 = j - 1; q__1.r = -1.f, q__1.i = -0.f; cgemm_("No transpose", "Conjugate transpose", &i__3, &jb, &i__4, &q__1, &a[j + jb + a_dim1], lda, &a[j + a_dim1], lda, &c_b1, &a[j + jb + j * a_dim1], lda); i__3 = *n - j - jb + 1; ctrsm_("Right", "Lower", "Conjugate transpose", "Non-unit" , &i__3, &jb, &c_b1, &a[j + j * a_dim1], lda, &a[ j + jb + j * a_dim1], lda); } /* L20: */ } } } goto L40; L30: *info = *info + j - 1; L40: return 0; /* End of CPOTRF */ } /* cpotrf_ */
/* Subroutine */ int cqrt02_(integer *m, integer *n, integer *k, complex *a, complex *af, complex *q, complex *r__, integer *lda, complex *tau, complex *work, integer *lwork, real *rwork, real *result) { /* System generated locals */ integer a_dim1, a_offset, af_dim1, af_offset, q_dim1, q_offset, r_dim1, r_offset, i__1; /* Builtin functions Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); /* Local variables */ static integer info; extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, integer *, complex *, complex *, integer *, complex *, integer *, complex *, complex *, integer *), cherk_(char *, char *, integer *, integer *, real *, complex *, integer *, real * , complex *, integer *); static real resid, anorm; extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *), slamch_(char *); extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *); extern doublereal clansy_(char *, char *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cungqr_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); static real eps; #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 af_subscr(a_1,a_2) (a_2)*af_dim1 + a_1 #define af_ref(a_1,a_2) af[af_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 September 30, 1994 Purpose ======= CQRT02 tests CUNGQR, which generates an m-by-n matrix Q with orthonornmal columns that is defined as the product of k elementary reflectors. Given the QR factorization of an m-by-n matrix A, CQRT02 generates the orthogonal matrix Q defined by the factorization of the first k columns of A; it compares R(1:n,1:k) with Q(1:m,1:n)'*A(1:m,1:k), and checks that the columns of Q are orthonormal. Arguments ========= M (input) INTEGER The number of rows of the matrix Q to be generated. M >= 0. N (input) INTEGER The number of columns of the matrix Q to be generated. M >= N >= 0. K (input) INTEGER The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. A (input) COMPLEX array, dimension (LDA,N) The m-by-n matrix A which was factorized by CQRT01. AF (input) COMPLEX array, dimension (LDA,N) Details of the QR factorization of A, as returned by CGEQRF. See CGEQRF for further details. Q (workspace) COMPLEX array, dimension (LDA,N) R (workspace) COMPLEX array, dimension (LDA,N) LDA (input) INTEGER The leading dimension of the arrays A, AF, Q and R. LDA >= M. TAU (input) COMPLEX array, dimension (N) The scalar factors of the elementary reflectors corresponding to the QR factorization in AF. WORK (workspace) COMPLEX array, dimension (LWORK) LWORK (input) INTEGER The dimension of the array WORK. RWORK (workspace) REAL array, dimension (M) RESULT (output) REAL array, dimension (2) The test ratios: RESULT(1) = norm( R - Q'*A ) / ( M * norm(A) * EPS ) RESULT(2) = norm( I - Q'*Q ) / ( M * EPS ) ===================================================================== Parameter adjustments */ r_dim1 = *lda; r_offset = 1 + r_dim1 * 1; r__ -= r_offset; q_dim1 = *lda; q_offset = 1 + q_dim1 * 1; q -= q_offset; af_dim1 = *lda; af_offset = 1 + af_dim1 * 1; af -= af_offset; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; --rwork; --result; /* Function Body */ eps = slamch_("Epsilon"); /* Copy the first k columns of the factorization to the array Q */ claset_("Full", m, n, &c_b1, &c_b1, &q[q_offset], lda); i__1 = *m - 1; clacpy_("Lower", &i__1, k, &af_ref(2, 1), lda, &q_ref(2, 1), lda); /* Generate the first n columns of the matrix Q */ s_copy(srnamc_1.srnamt, "CUNGQR", (ftnlen)6, (ftnlen)6); cungqr_(m, n, k, &q[q_offset], lda, &tau[1], &work[1], lwork, &info); /* Copy R(1:n,1:k) */ claset_("Full", n, k, &c_b8, &c_b8, &r__[r_offset], lda); clacpy_("Upper", n, k, &af[af_offset], lda, &r__[r_offset], lda); /* Compute R(1:n,1:k) - Q(1:m,1:n)' * A(1:m,1:k) */ cgemm_("Conjugate transpose", "No transpose", n, k, m, &c_b13, &q[ q_offset], lda, &a[a_offset], lda, &c_b14, &r__[r_offset], lda); /* Compute norm( R - Q'*A ) / ( M * norm(A) * EPS ) . */ anorm = clange_("1", m, k, &a[a_offset], lda, &rwork[1]); resid = clange_("1", n, k, &r__[r_offset], lda, &rwork[1]); if (anorm > 0.f) { result[1] = resid / (real) max(1,*m) / anorm / eps; } else { result[1] = 0.f; } /* Compute I - Q'*Q */ claset_("Full", n, n, &c_b8, &c_b14, &r__[r_offset], lda); cherk_("Upper", "Conjugate transpose", n, m, &c_b22, &q[q_offset], lda, & c_b23, &r__[r_offset], lda); /* Compute norm( I - Q'*Q ) / ( M * EPS ) . */ resid = clansy_("1", "Upper", n, &r__[r_offset], lda, &rwork[1]); result[2] = resid / (real) max(1,*m) / eps; return 0; /* End of CQRT02 */ } /* cqrt02_ */