SUBROUTINE DSFRK( TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, + C ) * * -- 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 .. DOUBLE PRECISION ALPHA, BETA INTEGER K, LDA, N CHARACTER TRANS, TRANSR, UPLO * .. * .. Array Arguments .. DOUBLE PRECISION A( LDA, * ), C( * ) * .. * * Purpose * ======= * * Level 3 BLAS like routine for C in RFP Format. * * DSFRK performs one of the symmetric rank--k operations * * C := alpha*A*A' + beta*C, * * or * * C := alpha*A'*A + beta*C, * * where alpha and beta are real scalars, C is an n--by--n symmetric * 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; * = 'T': The 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*A' + beta*C. * * TRANS = 'T' or 't' C := alpha*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 = 'T' * or 't', K specifies the number of rows of the matrix A. K * must be at least zero. * Unchanged on exit. * * ALPHA - (input) DOUBLE PRECISION. * On entry, ALPHA specifies the scalar alpha. * Unchanged on exit. * * A - (input) DOUBLE PRECISION 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) DOUBLE PRECISION. * On entry, BETA specifies the scalar beta. * Unchanged on exit. * * * C - (input/output) DOUBLE PRECISION array, dimension ( NT ); * NT = N*(N+1)/2. On entry, the symmetric matrix C in RFP * Format. RFP Format is described by TRANSR, UPLO and N. * * Arguments * ========== * * .. * .. Parameters .. DOUBLE PRECISION ONE, ZERO PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) * .. * .. Local Scalars .. LOGICAL LOWER, NORMALTRANSR, NISODD, NOTRANS INTEGER INFO, NROWA, J, NK, N1, N2 * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL XERBLA, DGEMM, DSYRK * .. * .. Intrinsic Functions .. INTRINSIC MAX * .. * .. Executable Statements .. * * Test the input parameters. * INFO = 0 NORMALTRANSR = LSAME( TRANSR, 'N' ) LOWER = LSAME( UPLO, 'L' ) NOTRANS = LSAME( TRANS, 'N' ) * IF( NOTRANS ) THEN NROWA = N ELSE NROWA = K END IF * IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THEN INFO = -1 ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THEN INFO = -2 ELSE IF( .NOT.NOTRANS .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN INFO = -3 ELSE IF( N.LT.0 ) THEN INFO = -4 ELSE IF( K.LT.0 ) THEN INFO = -5 ELSE IF( LDA.LT.MAX( 1, NROWA ) ) THEN INFO = -8 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'DSFRK ', -INFO ) RETURN END IF * * Quick return if possible. * * The quick return case: ((ALPHA.EQ.0).AND.(BETA.NE.ZERO)) is not * done (it is in DSYRK for example) and left in the general case. * IF( ( N.EQ.0 ) .OR. ( ( ( ALPHA.EQ.ZERO ) .OR. ( K.EQ.0 ) ) .AND. + ( BETA.EQ.ONE ) ) )RETURN * IF( ( ALPHA.EQ.ZERO ) .AND. ( BETA.EQ.ZERO ) ) THEN DO J = 1, ( ( N*( N+1 ) ) / 2 ) C( J ) = ZERO END DO RETURN END IF * * 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( MOD( N, 2 ).EQ.0 ) THEN NISODD = .FALSE. NK = N / 2 ELSE NISODD = .TRUE. IF( LOWER ) THEN N2 = N / 2 N1 = N - N2 ELSE N1 = N / 2 N2 = N - N1 END IF END IF * IF( NISODD ) THEN * * N is odd * IF( NORMALTRANSR ) THEN * * N is odd and TRANSR = 'N' * IF( LOWER ) THEN * * N is odd, TRANSR = 'N', and UPLO = 'L' * IF( NOTRANS ) THEN * * N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'N' * CALL DSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 1 ), N ) CALL DSYRK( 'U', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, + BETA, C( N+1 ), N ) CALL DGEMM( 'N', 'T', N2, N1, K, ALPHA, A( N1+1, 1 ), + LDA, A( 1, 1 ), LDA, BETA, C( N1+1 ), N ) * ELSE * * N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'T' * CALL DSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 1 ), N ) CALL DSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, + BETA, C( N+1 ), N ) CALL DGEMM( 'T', 'N', N2, N1, K, ALPHA, A( 1, N1+1 ), + LDA, A( 1, 1 ), LDA, BETA, C( N1+1 ), N ) * END IF * ELSE * * N is odd, TRANSR = 'N', and UPLO = 'U' * IF( NOTRANS ) THEN * * N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'N' * CALL DSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( N2+1 ), N ) CALL DSYRK( 'U', 'N', N2, K, ALPHA, A( N2, 1 ), LDA, + BETA, C( N1+1 ), N ) CALL DGEMM( 'N', 'T', N1, N2, K, ALPHA, A( 1, 1 ), + LDA, A( N2, 1 ), LDA, BETA, C( 1 ), N ) * ELSE * * N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'T' * CALL DSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( N2+1 ), N ) CALL DSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N2 ), LDA, + BETA, C( N1+1 ), N ) CALL DGEMM( 'T', 'N', N1, N2, K, ALPHA, A( 1, 1 ), + LDA, A( 1, N2 ), LDA, BETA, C( 1 ), N ) * END IF * END IF * ELSE * * N is odd, and TRANSR = 'T' * IF( LOWER ) THEN * * N is odd, TRANSR = 'T', and UPLO = 'L' * IF( NOTRANS ) THEN * * N is odd, TRANSR = 'T', UPLO = 'L', and TRANS = 'N' * CALL DSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 1 ), N1 ) CALL DSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, + BETA, C( 2 ), N1 ) CALL DGEMM( 'N', 'T', N1, N2, K, ALPHA, A( 1, 1 ), + LDA, A( N1+1, 1 ), LDA, BETA, + C( N1*N1+1 ), N1 ) * ELSE * * N is odd, TRANSR = 'T', UPLO = 'L', and TRANS = 'T' * CALL DSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 1 ), N1 ) CALL DSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, + BETA, C( 2 ), N1 ) CALL DGEMM( 'T', 'N', N1, N2, K, ALPHA, A( 1, 1 ), + LDA, A( 1, N1+1 ), LDA, BETA, + C( N1*N1+1 ), N1 ) * END IF * ELSE * * N is odd, TRANSR = 'T', and UPLO = 'U' * IF( NOTRANS ) THEN * * N is odd, TRANSR = 'T', UPLO = 'U', and TRANS = 'N' * CALL DSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( N2*N2+1 ), N2 ) CALL DSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, + BETA, C( N1*N2+1 ), N2 ) CALL DGEMM( 'N', 'T', N2, N1, K, ALPHA, A( N1+1, 1 ), + LDA, A( 1, 1 ), LDA, BETA, C( 1 ), N2 ) * ELSE * * N is odd, TRANSR = 'T', UPLO = 'U', and TRANS = 'T' * CALL DSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( N2*N2+1 ), N2 ) CALL DSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, + BETA, C( N1*N2+1 ), N2 ) CALL DGEMM( 'T', 'N', N2, N1, K, ALPHA, A( 1, N1+1 ), + LDA, A( 1, 1 ), LDA, BETA, C( 1 ), N2 ) * END IF * END IF * END IF * ELSE * * N is even * IF( NORMALTRANSR ) THEN * * N is even and TRANSR = 'N' * IF( LOWER ) THEN * * N is even, TRANSR = 'N', and UPLO = 'L' * IF( NOTRANS ) THEN * * N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'N' * CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 2 ), N+1 ) CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, + BETA, C( 1 ), N+1 ) CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( NK+1, 1 ), + LDA, A( 1, 1 ), LDA, BETA, C( NK+2 ), + N+1 ) * ELSE * * N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'T' * CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( 2 ), N+1 ) CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, + BETA, C( 1 ), N+1 ) CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, NK+1 ), + LDA, A( 1, 1 ), LDA, BETA, C( NK+2 ), + N+1 ) * END IF * ELSE * * N is even, TRANSR = 'N', and UPLO = 'U' * IF( NOTRANS ) THEN * * N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'N' * CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK+2 ), N+1 ) CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, + BETA, C( NK+1 ), N+1 ) CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( 1, 1 ), + LDA, A( NK+1, 1 ), LDA, BETA, C( 1 ), + N+1 ) * ELSE * * N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'T' * CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK+2 ), N+1 ) CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, + BETA, C( NK+1 ), N+1 ) CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, 1 ), + LDA, A( 1, NK+1 ), LDA, BETA, C( 1 ), + N+1 ) * END IF * END IF * ELSE * * N is even, and TRANSR = 'T' * IF( LOWER ) THEN * * N is even, TRANSR = 'T', and UPLO = 'L' * IF( NOTRANS ) THEN * * N is even, TRANSR = 'T', UPLO = 'L', and TRANS = 'N' * CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK+1 ), NK ) CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, + BETA, C( 1 ), NK ) CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( 1, 1 ), + LDA, A( NK+1, 1 ), LDA, BETA, + C( ( ( NK+1 )*NK )+1 ), NK ) * ELSE * * N is even, TRANSR = 'T', UPLO = 'L', and TRANS = 'T' * CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK+1 ), NK ) CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, + BETA, C( 1 ), NK ) CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, 1 ), + LDA, A( 1, NK+1 ), LDA, BETA, + C( ( ( NK+1 )*NK )+1 ), NK ) * END IF * ELSE * * N is even, TRANSR = 'T', and UPLO = 'U' * IF( NOTRANS ) THEN * * N is even, TRANSR = 'T', UPLO = 'U', and TRANS = 'N' * CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK*( NK+1 )+1 ), NK ) CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, + BETA, C( NK*NK+1 ), NK ) CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( NK+1, 1 ), + LDA, A( 1, 1 ), LDA, BETA, C( 1 ), NK ) * ELSE * * N is even, TRANSR = 'T', UPLO = 'U', and TRANS = 'T' * CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, + BETA, C( NK*( NK+1 )+1 ), NK ) CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, + BETA, C( NK*NK+1 ), NK ) CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, NK+1 ), + LDA, A( 1, 1 ), LDA, BETA, C( 1 ), NK ) * END IF * END IF * END IF * END IF * RETURN * * End of DSFRK * END