*> \brief \b SSFRK performs a symmetric rank-k operation for matrix in RFP format. * * =========== DOCUMENTATION =========== * * Online html documentation available at * http://www.netlib.org/lapack/explore-html/ * *> \htmlonly *> Download SSFRK + dependencies *> *> [TGZ] *> *> [ZIP] *> *> [TXT] *> \endhtmlonly * * Definition: * =========== * * SUBROUTINE SSFRK( TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, * C ) * * .. Scalar Arguments .. * REAL ALPHA, BETA * INTEGER K, LDA, N * CHARACTER TRANS, TRANSR, UPLO * .. * .. Array Arguments .. * REAL A( LDA, * ), C( * ) * .. * * *> \par Purpose: * ============= *> *> \verbatim *> *> Level 3 BLAS like routine for C in RFP Format. *> *> SSFRK performs one of the symmetric rank--k operations *> *> C := alpha*A*A**T + beta*C, *> *> or *> *> C := alpha*A**T*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. *> \endverbatim * * Arguments: * ========== * *> \param[in] TRANSR *> \verbatim *> TRANSR is CHARACTER*1 *> = 'N': The Normal Form of RFP A is stored; *> = 'T': The Transpose Form of RFP A is stored. *> \endverbatim *> *> \param[in] UPLO *> \verbatim *> UPLO is CHARACTER*1 *> 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. *> \endverbatim *> *> \param[in] TRANS *> \verbatim *> TRANS is CHARACTER*1 *> On entry, TRANS specifies the operation to be performed as *> follows: *> *> TRANS = 'N' or 'n' C := alpha*A*A**T + beta*C. *> *> TRANS = 'T' or 't' C := alpha*A**T*A + beta*C. *> *> Unchanged on exit. *> \endverbatim *> *> \param[in] N *> \verbatim *> N is INTEGER *> On entry, N specifies the order of the matrix C. N must be *> at least zero. *> Unchanged on exit. *> \endverbatim *> *> \param[in] K *> \verbatim *> K is 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. *> \endverbatim *> *> \param[in] ALPHA *> \verbatim *> ALPHA is REAL *> On entry, ALPHA specifies the scalar alpha. *> Unchanged on exit. *> \endverbatim *> *> \param[in] A *> \verbatim *> A is REAL array, 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. *> \endverbatim *> *> \param[in] LDA *> \verbatim *> LDA is 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. *> \endverbatim *> *> \param[in] BETA *> \verbatim *> BETA is REAL *> On entry, BETA specifies the scalar beta. *> Unchanged on exit. *> \endverbatim *> *> \param[in,out] C *> \verbatim *> C is REAL 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. *> \endverbatim * * Authors: * ======== * *> \author Univ. of Tennessee *> \author Univ. of California Berkeley *> \author Univ. of Colorado Denver *> \author NAG Ltd. * *> \date December 2016 * *> \ingroup realOTHERcomputational * * ===================================================================== SUBROUTINE SSFRK( TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, $ C ) * * -- LAPACK computational routine (version 3.7.0) -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * December 2016 * * .. Scalar Arguments .. REAL ALPHA, BETA INTEGER K, LDA, N CHARACTER TRANS, TRANSR, UPLO * .. * .. Array Arguments .. REAL A( LDA, * ), C( * ) * .. * * ===================================================================== * * .. Parameters .. REAL ONE, ZERO PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) * .. * .. Local Scalars .. LOGICAL LOWER, NORMALTRANSR, NISODD, NOTRANS INTEGER INFO, NROWA, J, NK, N1, N2 * .. * .. External Functions .. LOGICAL LSAME EXTERNAL LSAME * .. * .. External Subroutines .. EXTERNAL SGEMM, SSYRK, XERBLA * .. * .. 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( 'SSFRK ', -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 SSYRK 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 SSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 1 ), N ) CALL SSYRK( 'U', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, $ BETA, C( N+1 ), N ) CALL SGEMM( '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 SSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 1 ), N ) CALL SSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, $ BETA, C( N+1 ), N ) CALL SGEMM( '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 SSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( N2+1 ), N ) CALL SSYRK( 'U', 'N', N2, K, ALPHA, A( N2, 1 ), LDA, $ BETA, C( N1+1 ), N ) CALL SGEMM( '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 SSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( N2+1 ), N ) CALL SSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N2 ), LDA, $ BETA, C( N1+1 ), N ) CALL SGEMM( '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 SSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 1 ), N1 ) CALL SSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, $ BETA, C( 2 ), N1 ) CALL SGEMM( '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 SSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 1 ), N1 ) CALL SSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, $ BETA, C( 2 ), N1 ) CALL SGEMM( '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 SSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( N2*N2+1 ), N2 ) CALL SSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA, $ BETA, C( N1*N2+1 ), N2 ) CALL SGEMM( '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 SSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( N2*N2+1 ), N2 ) CALL SSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA, $ BETA, C( N1*N2+1 ), N2 ) CALL SGEMM( '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 SSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 2 ), N+1 ) CALL SSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, $ BETA, C( 1 ), N+1 ) CALL SGEMM( '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 SSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( 2 ), N+1 ) CALL SSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, $ BETA, C( 1 ), N+1 ) CALL SGEMM( '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 SSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK+2 ), N+1 ) CALL SSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, $ BETA, C( NK+1 ), N+1 ) CALL SGEMM( '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 SSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK+2 ), N+1 ) CALL SSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, $ BETA, C( NK+1 ), N+1 ) CALL SGEMM( '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 SSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK+1 ), NK ) CALL SSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, $ BETA, C( 1 ), NK ) CALL SGEMM( '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 SSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK+1 ), NK ) CALL SSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, $ BETA, C( 1 ), NK ) CALL SGEMM( '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 SSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK*( NK+1 )+1 ), NK ) CALL SSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA, $ BETA, C( NK*NK+1 ), NK ) CALL SGEMM( '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 SSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA, $ BETA, C( NK*( NK+1 )+1 ), NK ) CALL SSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA, $ BETA, C( NK*NK+1 ), NK ) CALL SGEMM( '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 SSFRK * END