--- rpl/lapack/lapack/dgsvj0.f 2011/07/22 07:38:05 1.6 +++ rpl/lapack/lapack/dgsvj0.f 2023/08/07 08:38:51 1.21 @@ -1,22 +1,225 @@ - SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, - $ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO ) +*> \brief \b DGSVJ0 pre-processor for the routine dgesvj. +* +* =========== DOCUMENTATION =========== * -* -- LAPACK routine (version 3.3.1) -- +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ * -* -- Contributed by Zlatko Drmac of the University of Zagreb and -- -* -- Kresimir Veselic of the Fernuniversitaet Hagen -- -* -- April 2011 -- +*> \htmlonly +*> Download DGSVJ0 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, +* SFMIN, TOL, NSWEEP, WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP +* DOUBLE PRECISION EPS, SFMIN, TOL +* CHARACTER*1 JOBV +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ), +* $ WORK( LWORK ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DGSVJ0 is called from DGESVJ as a pre-processor and that is its main +*> purpose. It applies Jacobi rotations in the same way as DGESVJ does, but +*> it does not check convergence (stopping criterion). Few tuning +*> parameters (marked by [TP]) are available for the implementer. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] JOBV +*> \verbatim +*> JOBV is CHARACTER*1 +*> Specifies whether the output from this procedure is used +*> to compute the matrix V: +*> = 'V': the product of the Jacobi rotations is accumulated +*> by postmulyiplying the N-by-N array V. +*> (See the description of V.) +*> = 'A': the product of the Jacobi rotations is accumulated +*> by postmulyiplying the MV-by-N array V. +*> (See the descriptions of MV and V.) +*> = 'N': the Jacobi rotations are not accumulated. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the input matrix A. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the input matrix A. +*> M >= N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, M-by-N matrix A, such that A*diag(D) represents +*> the input matrix. +*> On exit, +*> A_onexit * D_onexit represents the input matrix A*diag(D) +*> post-multiplied by a sequence of Jacobi rotations, where the +*> rotation threshold and the total number of sweeps are given in +*> TOL and NSWEEP, respectively. +*> (See the descriptions of D, TOL and NSWEEP.) +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[in,out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> The array D accumulates the scaling factors from the fast scaled +*> Jacobi rotations. +*> On entry, A*diag(D) represents the input matrix. +*> On exit, A_onexit*diag(D_onexit) represents the input matrix +*> post-multiplied by a sequence of Jacobi rotations, where the +*> rotation threshold and the total number of sweeps are given in +*> TOL and NSWEEP, respectively. +*> (See the descriptions of A, TOL and NSWEEP.) +*> \endverbatim +*> +*> \param[in,out] SVA +*> \verbatim +*> SVA is DOUBLE PRECISION array, dimension (N) +*> On entry, SVA contains the Euclidean norms of the columns of +*> the matrix A*diag(D). +*> On exit, SVA contains the Euclidean norms of the columns of +*> the matrix onexit*diag(D_onexit). +*> \endverbatim +*> +*> \param[in] MV +*> \verbatim +*> MV is INTEGER +*> If JOBV = 'A', then MV rows of V are post-multipled by a +*> sequence of Jacobi rotations. +*> If JOBV = 'N', then MV is not referenced. +*> \endverbatim +*> +*> \param[in,out] V +*> \verbatim +*> V is DOUBLE PRECISION array, dimension (LDV,N) +*> If JOBV = 'V' then N rows of V are post-multipled by a +*> sequence of Jacobi rotations. +*> If JOBV = 'A' then MV rows of V are post-multipled by a +*> sequence of Jacobi rotations. +*> If JOBV = 'N', then V is not referenced. +*> \endverbatim +*> +*> \param[in] LDV +*> \verbatim +*> LDV is INTEGER +*> The leading dimension of the array V, LDV >= 1. +*> If JOBV = 'V', LDV >= N. +*> If JOBV = 'A', LDV >= MV. +*> \endverbatim +*> +*> \param[in] EPS +*> \verbatim +*> EPS is DOUBLE PRECISION +*> EPS = DLAMCH('Epsilon') +*> \endverbatim +*> +*> \param[in] SFMIN +*> \verbatim +*> SFMIN is DOUBLE PRECISION +*> SFMIN = DLAMCH('Safe Minimum') +*> \endverbatim +*> +*> \param[in] TOL +*> \verbatim +*> TOL is DOUBLE PRECISION +*> TOL is the threshold for Jacobi rotations. For a pair +*> A(:,p), A(:,q) of pivot columns, the Jacobi rotation is +*> applied only if DABS(COS(angle(A(:,p),A(:,q)))) > TOL. +*> \endverbatim +*> +*> \param[in] NSWEEP +*> \verbatim +*> NSWEEP is INTEGER +*> NSWEEP is the number of sweeps of Jacobi rotations to be +*> performed. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (LWORK) +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> LWORK is the dimension of WORK. LWORK >= M. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit. +*> < 0: if INFO = -i, then the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup doubleOTHERcomputational +* +*> \par Further Details: +* ===================== +*> +*> DGSVJ0 is used just to enable DGESVJ to call a simplified version of +*> itself to work on a submatrix of the original matrix. +*> +*> \par Contributors: +* ================== +*> +*> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany) +*> +*> \par Bugs, Examples and Comments: +* ================================= +*> +*> Please report all bugs and send interesting test examples and comments to +*> drmac@math.hr. Thank you. * +* ===================================================================== + SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, + $ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO ) +* +* -- LAPACK computational routine -- * -- LAPACK is a software package provided by Univ. of Tennessee, -- * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- * -* This routine is also part of SIGMA (version 1.23, October 23. 2008.) -* SIGMA is a library of algorithms for highly accurate algorithms for -* computation of SVD, PSVD, QSVD, (H,K)-SVD, and for solution of the -* eigenvalue problems Hx = lambda M x, H M x = lambda x with H, M > 0. -* - IMPLICIT NONE -* .. * .. Scalar Arguments .. INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP DOUBLE PRECISION EPS, SFMIN, TOL @@ -27,125 +230,11 @@ $ WORK( LWORK ) * .. * -* Purpose -* ======= -* -* DGSVJ0 is called from DGESVJ as a pre-processor and that is its main -* purpose. It applies Jacobi rotations in the same way as DGESVJ does, but -* it does not check convergence (stopping criterion). Few tuning -* parameters (marked by [TP]) are available for the implementer. -* -* Further Details -* ~~~~~~~~~~~~~~~ -* DGSVJ0 is used just to enable SGESVJ to call a simplified version of -* itself to work on a submatrix of the original matrix. -* -* Contributors -* ~~~~~~~~~~~~ -* Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany) -* -* Bugs, Examples and Comments -* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Please report all bugs and send interesting test examples and comments to -* drmac@math.hr. Thank you. -* -* Arguments -* ========= -* -* JOBV (input) CHARACTER*1 -* Specifies whether the output from this procedure is used -* to compute the matrix V: -* = 'V': the product of the Jacobi rotations is accumulated -* by postmulyiplying the N-by-N array V. -* (See the description of V.) -* = 'A': the product of the Jacobi rotations is accumulated -* by postmulyiplying the MV-by-N array V. -* (See the descriptions of MV and V.) -* = 'N': the Jacobi rotations are not accumulated. -* -* M (input) INTEGER -* The number of rows of the input matrix A. M >= 0. -* -* N (input) INTEGER -* The number of columns of the input matrix A. -* M >= N >= 0. -* -* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) -* On entry, M-by-N matrix A, such that A*diag(D) represents -* the input matrix. -* On exit, -* A_onexit * D_onexit represents the input matrix A*diag(D) -* post-multiplied by a sequence of Jacobi rotations, where the -* rotation threshold and the total number of sweeps are given in -* TOL and NSWEEP, respectively. -* (See the descriptions of D, TOL and NSWEEP.) -* -* LDA (input) INTEGER -* The leading dimension of the array A. LDA >= max(1,M). -* -* D (input/workspace/output) DOUBLE PRECISION array, dimension (N) -* The array D accumulates the scaling factors from the fast scaled -* Jacobi rotations. -* On entry, A*diag(D) represents the input matrix. -* On exit, A_onexit*diag(D_onexit) represents the input matrix -* post-multiplied by a sequence of Jacobi rotations, where the -* rotation threshold and the total number of sweeps are given in -* TOL and NSWEEP, respectively. -* (See the descriptions of A, TOL and NSWEEP.) -* -* SVA (input/workspace/output) DOUBLE PRECISION array, dimension (N) -* On entry, SVA contains the Euclidean norms of the columns of -* the matrix A*diag(D). -* On exit, SVA contains the Euclidean norms of the columns of -* the matrix onexit*diag(D_onexit). -* -* MV (input) INTEGER -* If JOBV .EQ. 'A', then MV rows of V are post-multipled by a -* sequence of Jacobi rotations. -* If JOBV = 'N', then MV is not referenced. -* -* V (input/output) DOUBLE PRECISION array, dimension (LDV,N) -* If JOBV .EQ. 'V' then N rows of V are post-multipled by a -* sequence of Jacobi rotations. -* If JOBV .EQ. 'A' then MV rows of V are post-multipled by a -* sequence of Jacobi rotations. -* If JOBV = 'N', then V is not referenced. -* -* LDV (input) INTEGER -* The leading dimension of the array V, LDV >= 1. -* If JOBV = 'V', LDV .GE. N. -* If JOBV = 'A', LDV .GE. MV. -* -* EPS (input) DOUBLE PRECISION -* EPS = DLAMCH('Epsilon') -* -* SFMIN (input) DOUBLE PRECISION -* SFMIN = DLAMCH('Safe Minimum') -* -* TOL (input) DOUBLE PRECISION -* TOL is the threshold for Jacobi rotations. For a pair -* A(:,p), A(:,q) of pivot columns, the Jacobi rotation is -* applied only if DABS(COS(angle(A(:,p),A(:,q)))) .GT. TOL. -* -* NSWEEP (input) INTEGER -* NSWEEP is the number of sweeps of Jacobi rotations to be -* performed. -* -* WORK (workspace) DOUBLE PRECISION array, dimension (LWORK) -* -* LWORK (input) INTEGER -* LWORK is the dimension of WORK. LWORK .GE. M. -* -* INFO (output) INTEGER -* = 0 : successful exit. -* < 0 : if INFO = -i, then the i-th argument had an illegal value -* * ===================================================================== * * .. Local Parameters .. - DOUBLE PRECISION ZERO, HALF, ONE, TWO - PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0, - $ TWO = 2.0D0 ) + DOUBLE PRECISION ZERO, HALF, ONE + PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0) * .. * .. Local Scalars .. DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG, @@ -161,7 +250,7 @@ DOUBLE PRECISION FASTR( 5 ) * .. * .. Intrinsic Functions .. - INTRINSIC DABS, DMAX1, DBLE, MIN0, DSIGN, DSQRT + INTRINSIC DABS, MAX, DBLE, MIN, DSIGN, DSQRT * .. * .. External Functions .. DOUBLE PRECISION DDOT, DNRM2 @@ -170,7 +259,8 @@ EXTERNAL IDAMAX, LSAME, DDOT, DNRM2 * .. * .. External Subroutines .. - EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP + EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP, + $ XERBLA * .. * .. Executable Statements .. * @@ -188,7 +278,7 @@ INFO = -5 ELSE IF( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THEN INFO = -8 - ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR. + ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR. $ ( APPLV.AND.( LDV.LT.MV ) ) ) THEN INFO = -10 ELSE IF( TOL.LE.EPS ) THEN @@ -237,7 +327,7 @@ * Jacobi SVD algorithm SGESVJ. For sweeps i=1:SWBAND the procedure * ...... - KBL = MIN0( 8, N ) + KBL = MIN( 8, N ) *[TP] KBL is a tuning parameter that defines the tile size in the * tiling of the p-q loops of pivot pairs. In general, an optimal * value of KBL depends on the matrix dimensions and on the @@ -249,7 +339,7 @@ BLSKIP = ( KBL**2 ) + 1 *[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL. - ROWSKIP = MIN0( 5, KBL ) + ROWSKIP = MIN( 5, KBL ) *[TP] ROWSKIP is a tuning parameter. LKAHEAD = 1 @@ -271,11 +361,11 @@ igl = ( ibr-1 )*KBL + 1 * - DO 1002 ir1 = 0, MIN0( LKAHEAD, NBL-ibr ) + DO 1002 ir1 = 0, MIN( LKAHEAD, NBL-ibr ) * igl = igl + ir1*KBL * - DO 2001 p = igl, MIN0( igl+KBL-1, N-1 ) + DO 2001 p = igl, MIN( igl+KBL-1, N-1 ) * .. de Rijk's pivoting q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1 @@ -299,7 +389,7 @@ * Some BLAS implementations compute DNRM2(M,A(1,p),1) * as DSQRT(DDOT(M,A(1,p),1,A(1,p),1)), which may result in * overflow for ||A(:,p)||_2 > DSQRT(overflow_threshold), and -* undeflow for ||A(:,p)||_2 < DSQRT(underflow_threshold). +* underflow for ||A(:,p)||_2 < DSQRT(underflow_threshold). * Hence, DNRM2 cannot be trusted, not even in the case when * the true norm is far from the under(over)flow boundaries. * If properly implemented DNRM2 is available, the IF-THEN-ELSE @@ -324,7 +414,7 @@ * PSKIPPED = 0 * - DO 2002 q = p + 1, MIN0( igl+KBL-1, N ) + DO 2002 q = p + 1, MIN( igl+KBL-1, N ) * AAQQ = SVA( q ) @@ -359,7 +449,7 @@ END IF END IF * - MXAAPQ = DMAX1( MXAAPQ, DABS( AAPQ ) ) + MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) ) * * TO rotate or NOT to rotate, THAT is the question ... * @@ -391,11 +481,11 @@ $ V( 1, p ), 1, $ V( 1, q ), 1, $ FASTR ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE+T*APOAQ*AAPQ ) ) - AAPP = AAPP*DSQRT( DMAX1( ZERO, + AAPP = AAPP*DSQRT( MAX( ZERO, $ ONE-T*AQOAP*AAPQ ) ) - MXSINJ = DMAX1( MXSINJ, DABS( T ) ) + MXSINJ = MAX( MXSINJ, DABS( T ) ) * ELSE * @@ -407,10 +497,10 @@ CS = DSQRT( ONE / ( ONE+T*T ) ) SN = T*CS * - MXSINJ = DMAX1( MXSINJ, DABS( SN ) ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + MXSINJ = MAX( MXSINJ, DABS( SN ) ) + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE+T*APOAQ*AAPQ ) ) - AAPP = AAPP*DSQRT( DMAX1( ZERO, + AAPP = AAPP*DSQRT( MAX( ZERO, $ ONE-T*AQOAP*AAPQ ) ) * APOAQ = D( p ) / D( q ) @@ -521,9 +611,9 @@ $ A( 1, q ), 1 ) CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M, $ 1, A( 1, q ), LDA, IERR ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE-AAPQ*AAPQ ) ) - MXSINJ = DMAX1( MXSINJ, SFMIN ) + MXSINJ = MAX( MXSINJ, SFMIN ) END IF * END IF ROTOK THEN ... ELSE * @@ -587,7 +677,7 @@ ELSE SVA( p ) = AAPP IF( ( ir1.EQ.0 ) .AND. ( AAPP.EQ.ZERO ) ) - $ NOTROT = NOTROT + MIN0( igl+KBL-1, N ) - p + $ NOTROT = NOTROT + MIN( igl+KBL-1, N ) - p END IF * 2001 CONTINUE @@ -608,7 +698,7 @@ * doing the block at ( ibr, jbc ) * IJBLSK = 0 - DO 2100 p = igl, MIN0( igl+KBL-1, N ) + DO 2100 p = igl, MIN( igl+KBL-1, N ) * AAPP = SVA( p ) * @@ -616,7 +706,7 @@ * PSKIPPED = 0 * - DO 2200 q = jgl, MIN0( jgl+KBL-1, N ) + DO 2200 q = jgl, MIN( jgl+KBL-1, N ) * AAQQ = SVA( q ) * @@ -663,7 +753,7 @@ END IF END IF * - MXAAPQ = DMAX1( MXAAPQ, DABS( AAPQ ) ) + MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) ) * * TO rotate or NOT to rotate, THAT is the question ... * @@ -690,11 +780,11 @@ $ V( 1, p ), 1, $ V( 1, q ), 1, $ FASTR ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE+T*APOAQ*AAPQ ) ) - AAPP = AAPP*DSQRT( DMAX1( ZERO, + AAPP = AAPP*DSQRT( MAX( ZERO, $ ONE-T*AQOAP*AAPQ ) ) - MXSINJ = DMAX1( MXSINJ, DABS( T ) ) + MXSINJ = MAX( MXSINJ, DABS( T ) ) ELSE * * .. choose correct signum for THETA and rotate @@ -705,10 +795,10 @@ $ DSQRT( ONE+THETA*THETA ) ) CS = DSQRT( ONE / ( ONE+T*T ) ) SN = T*CS - MXSINJ = DMAX1( MXSINJ, DABS( SN ) ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + MXSINJ = MAX( MXSINJ, DABS( SN ) ) + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE+T*APOAQ*AAPQ ) ) - AAPP = AAPP*DSQRT( DMAX1( ZERO, + AAPP = AAPP*DSQRT( MAX( ZERO, $ ONE-T*AQOAP*AAPQ ) ) * APOAQ = D( p ) / D( q ) @@ -823,9 +913,9 @@ CALL DLASCL( 'G', 0, 0, ONE, AAQQ, $ M, 1, A( 1, q ), LDA, $ IERR ) - SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, + SVA( q ) = AAQQ*DSQRT( MAX( ZERO, $ ONE-AAPQ*AAPQ ) ) - MXSINJ = DMAX1( MXSINJ, SFMIN ) + MXSINJ = MAX( MXSINJ, SFMIN ) ELSE CALL DCOPY( M, A( 1, q ), 1, WORK, $ 1 ) @@ -840,9 +930,9 @@ CALL DLASCL( 'G', 0, 0, ONE, AAPP, $ M, 1, A( 1, p ), LDA, $ IERR ) - SVA( p ) = AAPP*DSQRT( DMAX1( ZERO, + SVA( p ) = AAPP*DSQRT( MAX( ZERO, $ ONE-AAPQ*AAPQ ) ) - MXSINJ = DMAX1( MXSINJ, SFMIN ) + MXSINJ = MAX( MXSINJ, SFMIN ) END IF END IF * END IF ROTOK THEN ... ELSE @@ -910,7 +1000,7 @@ * ELSE IF( AAPP.EQ.ZERO )NOTROT = NOTROT + - $ MIN0( jgl+KBL-1, N ) - jgl + 1 + $ MIN( jgl+KBL-1, N ) - jgl + 1 IF( AAPP.LT.ZERO )NOTROT = 0 END IF @@ -920,7 +1010,7 @@ * end of the jbc-loop 2011 CONTINUE *2011 bailed out of the jbc-loop - DO 2012 p = igl, MIN0( igl+KBL-1, N ) + DO 2012 p = igl, MIN( igl+KBL-1, N ) SVA( p ) = DABS( SVA( p ) ) 2012 CONTINUE * @@ -952,7 +1042,7 @@ 1993 CONTINUE * end i=1:NSWEEP loop -* #:) Reaching this point means that the procedure has comleted the given +* #:) Reaching this point means that the procedure has completed the given * number of iterations. INFO = NSWEEP - 1 GO TO 1995