version 1.2, 2010/08/07 13:22:15
|
version 1.21, 2023/08/07 08:38:51
|
Line 1
|
Line 1
|
SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, |
*> \brief \b DGSVJ0 pre-processor for the routine dgesvj. |
+ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO ) |
* |
|
* =========== DOCUMENTATION =========== |
|
* |
|
* Online html documentation available at |
|
* http://www.netlib.org/lapack/explore-html/ |
* |
* |
* -- LAPACK routine (version 3.2.2) -- |
*> \htmlonly |
|
*> Download DGSVJ0 + dependencies |
|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgsvj0.f"> |
|
*> [TGZ]</a> |
|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgsvj0.f"> |
|
*> [ZIP]</a> |
|
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgsvj0.f"> |
|
*> [TXT]</a> |
|
*> \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. |
* |
* |
* -- Contributed by Zlatko Drmac of the University of Zagreb and -- |
* ===================================================================== |
* -- Kresimir Veselic of the Fernuniversitaet Hagen -- |
SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, |
* -- June 2010 -- |
$ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO ) |
* |
* |
|
* -- LAPACK computational routine -- |
* -- LAPACK is a software package provided by Univ. of Tennessee, -- |
* -- LAPACK is a software package provided by Univ. of Tennessee, -- |
* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
* -- 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 .. |
* .. Scalar Arguments .. |
INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP |
INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP |
DOUBLE PRECISION EPS, SFMIN, TOL |
DOUBLE PRECISION EPS, SFMIN, TOL |
Line 23
|
Line 227
|
* .. |
* .. |
* .. Array Arguments .. |
* .. Array Arguments .. |
DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ), |
DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ), |
+ WORK( LWORK ) |
$ 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 .. |
* .. Local Parameters .. |
DOUBLE PRECISION ZERO, HALF, ONE, TWO |
DOUBLE PRECISION ZERO, HALF, ONE |
PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0, |
PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0) |
+ TWO = 2.0D0 ) |
|
* .. |
* .. |
* .. Local Scalars .. |
* .. Local Scalars .. |
DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG, |
DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG, |
+ BIGTHETA, CS, MXAAPQ, MXSINJ, ROOTBIG, ROOTEPS, |
$ BIGTHETA, CS, MXAAPQ, MXSINJ, ROOTBIG, ROOTEPS, |
+ ROOTSFMIN, ROOTTOL, SMALL, SN, T, TEMP1, THETA, |
$ ROOTSFMIN, ROOTTOL, SMALL, SN, T, TEMP1, THETA, |
+ THSIGN |
$ THSIGN |
INTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1, |
INTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1, |
+ ISWROT, jbc, jgl, KBL, LKAHEAD, MVL, NBL, |
$ ISWROT, jbc, jgl, KBL, LKAHEAD, MVL, NBL, |
+ NOTROT, p, PSKIPPED, q, ROWSKIP, SWBAND |
$ NOTROT, p, PSKIPPED, q, ROWSKIP, SWBAND |
LOGICAL APPLV, ROTOK, RSVEC |
LOGICAL APPLV, ROTOK, RSVEC |
* .. |
* .. |
* .. Local Arrays .. |
* .. Local Arrays .. |
DOUBLE PRECISION FASTR( 5 ) |
DOUBLE PRECISION FASTR( 5 ) |
* .. |
* .. |
* .. Intrinsic Functions .. |
* .. Intrinsic Functions .. |
INTRINSIC DABS, DMAX1, DBLE, MIN0, DSIGN, DSQRT |
INTRINSIC DABS, MAX, DBLE, MIN, DSIGN, DSQRT |
* .. |
* .. |
* .. External Functions .. |
* .. External Functions .. |
DOUBLE PRECISION DDOT, DNRM2 |
DOUBLE PRECISION DDOT, DNRM2 |
Line 169
|
Line 259
|
EXTERNAL IDAMAX, LSAME, DDOT, DNRM2 |
EXTERNAL IDAMAX, LSAME, DDOT, DNRM2 |
* .. |
* .. |
* .. External Subroutines .. |
* .. External Subroutines .. |
EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP |
EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP, |
|
$ XERBLA |
* .. |
* .. |
* .. Executable Statements .. |
* .. Executable Statements .. |
* |
* |
|
* Test the input parameters. |
|
* |
APPLV = LSAME( JOBV, 'A' ) |
APPLV = LSAME( JOBV, 'A' ) |
RSVEC = LSAME( JOBV, 'V' ) |
RSVEC = LSAME( JOBV, 'V' ) |
IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THEN |
IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THEN |
Line 183
|
Line 276
|
INFO = -3 |
INFO = -3 |
ELSE IF( LDA.LT.M ) THEN |
ELSE IF( LDA.LT.M ) THEN |
INFO = -5 |
INFO = -5 |
ELSE IF( MV.LT.0 ) THEN |
ELSE IF( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THEN |
INFO = -8 |
INFO = -8 |
ELSE IF( LDV.LT.M ) THEN |
ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR. |
|
$ ( APPLV.AND.( LDV.LT.MV ) ) ) THEN |
INFO = -10 |
INFO = -10 |
ELSE IF( TOL.LE.EPS ) THEN |
ELSE IF( TOL.LE.EPS ) THEN |
INFO = -13 |
INFO = -13 |
Line 218
|
Line 312
|
BIGTHETA = ONE / ROOTEPS |
BIGTHETA = ONE / ROOTEPS |
ROOTTOL = DSQRT( TOL ) |
ROOTTOL = DSQRT( TOL ) |
* |
* |
* |
|
* -#- Row-cyclic Jacobi SVD algorithm with column pivoting -#- |
* -#- Row-cyclic Jacobi SVD algorithm with column pivoting -#- |
* |
* |
EMPTSW = ( N*( N-1 ) ) / 2 |
EMPTSW = ( N*( N-1 ) ) / 2 |
Line 234
|
Line 327
|
* Jacobi SVD algorithm SGESVJ. For sweeps i=1:SWBAND the procedure |
* 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 |
*[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 |
* tiling of the p-q loops of pivot pairs. In general, an optimal |
* value of KBL depends on the matrix dimensions and on the |
* value of KBL depends on the matrix dimensions and on the |
Line 246
|
Line 339
|
BLSKIP = ( KBL**2 ) + 1 |
BLSKIP = ( KBL**2 ) + 1 |
*[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL. |
*[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. |
*[TP] ROWSKIP is a tuning parameter. |
|
|
LKAHEAD = 1 |
LKAHEAD = 1 |
Line 268
|
Line 361
|
|
|
igl = ( ibr-1 )*KBL + 1 |
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 |
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 |
* .. de Rijk's pivoting |
q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1 |
q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1 |
IF( p.NE.q ) THEN |
IF( p.NE.q ) THEN |
CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 ) |
CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 ) |
IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, |
IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
TEMP1 = SVA( p ) |
TEMP1 = SVA( p ) |
SVA( p ) = SVA( q ) |
SVA( p ) = SVA( q ) |
SVA( q ) = TEMP1 |
SVA( q ) = TEMP1 |
Line 296
|
Line 389
|
* Some BLAS implementations compute DNRM2(M,A(1,p),1) |
* 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 |
* 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 |
* 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 |
* Hence, DNRM2 cannot be trusted, not even in the case when |
* the true norm is far from the under(over)flow boundaries. |
* the true norm is far from the under(over)flow boundaries. |
* If properly implemented DNRM2 is available, the IF-THEN-ELSE |
* If properly implemented DNRM2 is available, the IF-THEN-ELSE |
* below should read "AAPP = DNRM2( M, A(1,p), 1 ) * D(p)". |
* below should read "AAPP = DNRM2( M, A(1,p), 1 ) * D(p)". |
* |
* |
IF( ( SVA( p ).LT.ROOTBIG ) .AND. |
IF( ( SVA( p ).LT.ROOTBIG ) .AND. |
+ ( SVA( p ).GT.ROOTSFMIN ) ) THEN |
$ ( SVA( p ).GT.ROOTSFMIN ) ) THEN |
SVA( p ) = DNRM2( M, A( 1, p ), 1 )*D( p ) |
SVA( p ) = DNRM2( M, A( 1, p ), 1 )*D( p ) |
ELSE |
ELSE |
TEMP1 = ZERO |
TEMP1 = ZERO |
AAPP = ZERO |
AAPP = ONE |
CALL DLASSQ( M, A( 1, p ), 1, TEMP1, AAPP ) |
CALL DLASSQ( M, A( 1, p ), 1, TEMP1, AAPP ) |
SVA( p ) = TEMP1*DSQRT( AAPP )*D( p ) |
SVA( p ) = TEMP1*DSQRT( AAPP )*D( p ) |
END IF |
END IF |
Line 321
|
Line 414
|
* |
* |
PSKIPPED = 0 |
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 ) |
AAQQ = SVA( q ) |
|
|
Line 332
|
Line 425
|
ROTOK = ( SMALL*AAPP ).LE.AAQQ |
ROTOK = ( SMALL*AAPP ).LE.AAQQ |
IF( AAPP.LT.( BIG / AAQQ ) ) THEN |
IF( AAPP.LT.( BIG / AAQQ ) ) THEN |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
+ q ), 1 )*D( p )*D( q ) / AAQQ ) |
$ q ), 1 )*D( p )*D( q ) / AAQQ ) |
+ / AAPP |
$ / AAPP |
ELSE |
ELSE |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DLASCL( 'G', 0, 0, AAPP, D( p ), |
CALL DLASCL( 'G', 0, 0, AAPP, D( p ), |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
AAPQ = DDOT( M, WORK, 1, A( 1, q ), |
AAPQ = DDOT( M, WORK, 1, A( 1, q ), |
+ 1 )*D( q ) / AAQQ |
$ 1 )*D( q ) / AAQQ |
END IF |
END IF |
ELSE |
ELSE |
ROTOK = AAPP.LE.( AAQQ / SMALL ) |
ROTOK = AAPP.LE.( AAQQ / SMALL ) |
IF( AAPP.GT.( SMALL / AAQQ ) ) THEN |
IF( AAPP.GT.( SMALL / AAQQ ) ) THEN |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
+ q ), 1 )*D( p )*D( q ) / AAQQ ) |
$ q ), 1 )*D( p )*D( q ) / AAQQ ) |
+ / AAPP |
$ / AAPP |
ELSE |
ELSE |
CALL DCOPY( M, A( 1, q ), 1, WORK, 1 ) |
CALL DCOPY( M, A( 1, q ), 1, WORK, 1 ) |
CALL DLASCL( 'G', 0, 0, AAQQ, D( q ), |
CALL DLASCL( 'G', 0, 0, AAQQ, D( q ), |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
AAPQ = DDOT( M, WORK, 1, A( 1, p ), |
AAPQ = DDOT( M, WORK, 1, A( 1, p ), |
+ 1 )*D( p ) / AAPP |
$ 1 )*D( p ) / AAPP |
END IF |
END IF |
END IF |
END IF |
* |
* |
MXAAPQ = DMAX1( MXAAPQ, DABS( AAPQ ) ) |
MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) ) |
* |
* |
* TO rotate or NOT to rotate, THAT is the question ... |
* TO rotate or NOT to rotate, THAT is the question ... |
* |
* |
Line 375
|
Line 468
|
* |
* |
AQOAP = AAQQ / AAPP |
AQOAP = AAQQ / AAPP |
APOAQ = AAPP / AAQQ |
APOAQ = AAPP / AAQQ |
THETA = -HALF*DABS( AQOAP-APOAQ ) / |
THETA = -HALF*DABS( AQOAP-APOAQ )/AAPQ |
+ AAPQ |
|
* |
* |
IF( DABS( THETA ).GT.BIGTHETA ) THEN |
IF( DABS( THETA ).GT.BIGTHETA ) THEN |
* |
* |
Line 384
|
Line 476
|
FASTR( 3 ) = T*D( p ) / D( q ) |
FASTR( 3 ) = T*D( p ) / D( q ) |
FASTR( 4 ) = -T*D( q ) / D( p ) |
FASTR( 4 ) = -T*D( q ) / D( p ) |
CALL DROTM( M, A( 1, p ), 1, |
CALL DROTM( M, A( 1, p ), 1, |
+ A( 1, q ), 1, FASTR ) |
$ A( 1, q ), 1, FASTR ) |
IF( RSVEC )CALL DROTM( MVL, |
IF( RSVEC )CALL DROTM( MVL, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ FASTR ) |
$ FASTR ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE+T*APOAQ*AAPQ ) ) |
$ ONE+T*APOAQ*AAPQ ) ) |
AAPP = AAPP*DSQRT( ONE-T*AQOAP* |
AAPP = AAPP*DSQRT( MAX( ZERO, |
+ AAPQ ) |
$ ONE-T*AQOAP*AAPQ ) ) |
MXSINJ = DMAX1( MXSINJ, DABS( T ) ) |
MXSINJ = MAX( MXSINJ, DABS( T ) ) |
* |
* |
ELSE |
ELSE |
* |
* |
Line 401
|
Line 493
|
* |
* |
THSIGN = -DSIGN( ONE, AAPQ ) |
THSIGN = -DSIGN( ONE, AAPQ ) |
T = ONE / ( THETA+THSIGN* |
T = ONE / ( THETA+THSIGN* |
+ DSQRT( ONE+THETA*THETA ) ) |
$ DSQRT( ONE+THETA*THETA ) ) |
CS = DSQRT( ONE / ( ONE+T*T ) ) |
CS = DSQRT( ONE / ( ONE+T*T ) ) |
SN = T*CS |
SN = T*CS |
* |
* |
MXSINJ = DMAX1( MXSINJ, DABS( SN ) ) |
MXSINJ = MAX( MXSINJ, DABS( SN ) ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE+T*APOAQ*AAPQ ) ) |
$ ONE+T*APOAQ*AAPQ ) ) |
AAPP = AAPP*DSQRT( DMAX1( ZERO, |
AAPP = AAPP*DSQRT( MAX( ZERO, |
+ ONE-T*AQOAP*AAPQ ) ) |
$ ONE-T*AQOAP*AAPQ ) ) |
* |
* |
APOAQ = D( p ) / D( q ) |
APOAQ = D( p ) / D( q ) |
AQOAP = D( q ) / D( p ) |
AQOAP = D( q ) / D( p ) |
Line 420
|
Line 512
|
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
CALL DROTM( M, A( 1, p ), 1, |
CALL DROTM( M, A( 1, p ), 1, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ FASTR ) |
$ FASTR ) |
IF( RSVEC )CALL DROTM( MVL, |
IF( RSVEC )CALL DROTM( MVL, |
+ V( 1, p ), 1, V( 1, q ), |
$ V( 1, p ), 1, V( 1, q ), |
+ 1, FASTR ) |
$ 1, FASTR ) |
ELSE |
ELSE |
CALL DAXPY( M, -T*AQOAP, |
CALL DAXPY( M, -T*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
CALL DAXPY( M, CS*SN*APOAQ, |
CALL DAXPY( M, CS*SN*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q ) / CS |
D( q ) = D( q ) / CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, -T*AQOAP, |
CALL DAXPY( MVL, -T*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ CS*SN*APOAQ, |
$ CS*SN*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
END IF |
END IF |
END IF |
END IF |
ELSE |
ELSE |
IF( D( q ).GE.ONE ) THEN |
IF( D( q ).GE.ONE ) THEN |
CALL DAXPY( M, T*APOAQ, |
CALL DAXPY( M, T*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DAXPY( M, -CS*SN*AQOAP, |
CALL DAXPY( M, -CS*SN*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
D( p ) = D( p ) / CS |
D( p ) = D( p ) / CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, T*APOAQ, |
CALL DAXPY( MVL, T*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
END IF |
END IF |
ELSE |
ELSE |
IF( D( p ).GE.D( q ) ) THEN |
IF( D( p ).GE.D( q ) ) THEN |
CALL DAXPY( M, -T*AQOAP, |
CALL DAXPY( M, -T*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
CALL DAXPY( M, CS*SN*APOAQ, |
CALL DAXPY( M, CS*SN*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q ) / CS |
D( q ) = D( q ) / CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -T*AQOAP, |
$ -T*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ CS*SN*APOAQ, |
$ CS*SN*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
END IF |
END IF |
ELSE |
ELSE |
CALL DAXPY( M, T*APOAQ, |
CALL DAXPY( M, T*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DAXPY( M, |
CALL DAXPY( M, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
D( p ) = D( p ) / CS |
D( p ) = D( p ) / CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ T*APOAQ, V( 1, p ), |
$ T*APOAQ, V( 1, p ), |
+ 1, V( 1, q ), 1 ) |
$ 1, V( 1, q ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
END IF |
END IF |
END IF |
END IF |
END IF |
END IF |
Line 511
|
Line 603
|
* .. have to use modified Gram-Schmidt like transformation |
* .. have to use modified Gram-Schmidt like transformation |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, M, |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, M, |
+ 1, WORK, LDA, IERR ) |
$ 1, WORK, LDA, IERR ) |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, M, |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, M, |
+ 1, A( 1, q ), LDA, IERR ) |
$ 1, A( 1, q ), LDA, IERR ) |
TEMP1 = -AAPQ*D( p ) / D( q ) |
TEMP1 = -AAPQ*D( p ) / D( q ) |
CALL DAXPY( M, TEMP1, WORK, 1, |
CALL DAXPY( M, TEMP1, WORK, 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M, |
CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M, |
+ 1, A( 1, q ), LDA, IERR ) |
$ 1, A( 1, q ), LDA, IERR ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE-AAPQ*AAPQ ) ) |
$ ONE-AAPQ*AAPQ ) ) |
MXSINJ = DMAX1( MXSINJ, SFMIN ) |
MXSINJ = MAX( MXSINJ, SFMIN ) |
END IF |
END IF |
* END IF ROTOK THEN ... ELSE |
* END IF ROTOK THEN ... ELSE |
* |
* |
* In the case of cancellation in updating SVA(q), SVA(p) |
* In the case of cancellation in updating SVA(q), SVA(p) |
* recompute SVA(q), SVA(p). |
* recompute SVA(q), SVA(p). |
IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS ) |
IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS ) |
+ THEN |
$ THEN |
IF( ( AAQQ.LT.ROOTBIG ) .AND. |
IF( ( AAQQ.LT.ROOTBIG ) .AND. |
+ ( AAQQ.GT.ROOTSFMIN ) ) THEN |
$ ( AAQQ.GT.ROOTSFMIN ) ) THEN |
SVA( q ) = DNRM2( M, A( 1, q ), 1 )* |
SVA( q ) = DNRM2( M, A( 1, q ), 1 )* |
+ D( q ) |
$ D( q ) |
ELSE |
ELSE |
T = ZERO |
T = ZERO |
AAQQ = ZERO |
AAQQ = ONE |
CALL DLASSQ( M, A( 1, q ), 1, T, |
CALL DLASSQ( M, A( 1, q ), 1, T, |
+ AAQQ ) |
$ AAQQ ) |
SVA( q ) = T*DSQRT( AAQQ )*D( q ) |
SVA( q ) = T*DSQRT( AAQQ )*D( q ) |
END IF |
END IF |
END IF |
END IF |
IF( ( AAPP / AAPP0 ).LE.ROOTEPS ) THEN |
IF( ( AAPP / AAPP0 ).LE.ROOTEPS ) THEN |
IF( ( AAPP.LT.ROOTBIG ) .AND. |
IF( ( AAPP.LT.ROOTBIG ) .AND. |
+ ( AAPP.GT.ROOTSFMIN ) ) THEN |
$ ( AAPP.GT.ROOTSFMIN ) ) THEN |
AAPP = DNRM2( M, A( 1, p ), 1 )* |
AAPP = DNRM2( M, A( 1, p ), 1 )* |
+ D( p ) |
$ D( p ) |
ELSE |
ELSE |
T = ZERO |
T = ZERO |
AAPP = ZERO |
AAPP = ONE |
CALL DLASSQ( M, A( 1, p ), 1, T, |
CALL DLASSQ( M, A( 1, p ), 1, T, |
+ AAPP ) |
$ AAPP ) |
AAPP = T*DSQRT( AAPP )*D( p ) |
AAPP = T*DSQRT( AAPP )*D( p ) |
END IF |
END IF |
SVA( p ) = AAPP |
SVA( p ) = AAPP |
Line 568
|
Line 660
|
END IF |
END IF |
* |
* |
IF( ( i.LE.SWBAND ) .AND. |
IF( ( i.LE.SWBAND ) .AND. |
+ ( PSKIPPED.GT.ROWSKIP ) ) THEN |
$ ( PSKIPPED.GT.ROWSKIP ) ) THEN |
IF( ir1.EQ.0 )AAPP = -AAPP |
IF( ir1.EQ.0 )AAPP = -AAPP |
NOTROT = 0 |
NOTROT = 0 |
GO TO 2103 |
GO TO 2103 |
Line 585
|
Line 677
|
ELSE |
ELSE |
SVA( p ) = AAPP |
SVA( p ) = AAPP |
IF( ( ir1.EQ.0 ) .AND. ( AAPP.EQ.ZERO ) ) |
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 |
END IF |
* |
* |
2001 CONTINUE |
2001 CONTINUE |
Line 606
|
Line 698
|
* doing the block at ( ibr, jbc ) |
* doing the block at ( ibr, jbc ) |
* |
* |
IJBLSK = 0 |
IJBLSK = 0 |
DO 2100 p = igl, MIN0( igl+KBL-1, N ) |
DO 2100 p = igl, MIN( igl+KBL-1, N ) |
* |
* |
AAPP = SVA( p ) |
AAPP = SVA( p ) |
* |
* |
Line 614
|
Line 706
|
* |
* |
PSKIPPED = 0 |
PSKIPPED = 0 |
* |
* |
DO 2200 q = jgl, MIN0( jgl+KBL-1, N ) |
DO 2200 q = jgl, MIN( jgl+KBL-1, N ) |
* |
* |
AAQQ = SVA( q ) |
AAQQ = SVA( q ) |
* |
* |
Line 633
|
Line 725
|
END IF |
END IF |
IF( AAPP.LT.( BIG / AAQQ ) ) THEN |
IF( AAPP.LT.( BIG / AAQQ ) ) THEN |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
+ q ), 1 )*D( p )*D( q ) / AAQQ ) |
$ q ), 1 )*D( p )*D( q ) / AAQQ ) |
+ / AAPP |
$ / AAPP |
ELSE |
ELSE |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DCOPY( M, A( 1, p ), 1, WORK, 1 ) |
CALL DLASCL( 'G', 0, 0, AAPP, D( p ), |
CALL DLASCL( 'G', 0, 0, AAPP, D( p ), |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
AAPQ = DDOT( M, WORK, 1, A( 1, q ), |
AAPQ = DDOT( M, WORK, 1, A( 1, q ), |
+ 1 )*D( q ) / AAQQ |
$ 1 )*D( q ) / AAQQ |
END IF |
END IF |
ELSE |
ELSE |
IF( AAPP.GE.AAQQ ) THEN |
IF( AAPP.GE.AAQQ ) THEN |
Line 650
|
Line 742
|
END IF |
END IF |
IF( AAPP.GT.( SMALL / AAQQ ) ) THEN |
IF( AAPP.GT.( SMALL / AAQQ ) ) THEN |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1, |
+ q ), 1 )*D( p )*D( q ) / AAQQ ) |
$ q ), 1 )*D( p )*D( q ) / AAQQ ) |
+ / AAPP |
$ / AAPP |
ELSE |
ELSE |
CALL DCOPY( M, A( 1, q ), 1, WORK, 1 ) |
CALL DCOPY( M, A( 1, q ), 1, WORK, 1 ) |
CALL DLASCL( 'G', 0, 0, AAQQ, D( q ), |
CALL DLASCL( 'G', 0, 0, AAQQ, D( q ), |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
AAPQ = DDOT( M, WORK, 1, A( 1, p ), |
AAPQ = DDOT( M, WORK, 1, A( 1, p ), |
+ 1 )*D( p ) / AAPP |
$ 1 )*D( p ) / AAPP |
END IF |
END IF |
END IF |
END IF |
* |
* |
MXAAPQ = DMAX1( MXAAPQ, DABS( AAPQ ) ) |
MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) ) |
* |
* |
* TO rotate or NOT to rotate, THAT is the question ... |
* TO rotate or NOT to rotate, THAT is the question ... |
* |
* |
Line 675
|
Line 767
|
* |
* |
AQOAP = AAQQ / AAPP |
AQOAP = AAQQ / AAPP |
APOAQ = AAPP / AAQQ |
APOAQ = AAPP / AAQQ |
THETA = -HALF*DABS( AQOAP-APOAQ ) / |
THETA = -HALF*DABS( AQOAP-APOAQ )/AAPQ |
+ AAPQ |
|
IF( AAQQ.GT.AAPP0 )THETA = -THETA |
IF( AAQQ.GT.AAPP0 )THETA = -THETA |
* |
* |
IF( DABS( THETA ).GT.BIGTHETA ) THEN |
IF( DABS( THETA ).GT.BIGTHETA ) THEN |
Line 684
|
Line 775
|
FASTR( 3 ) = T*D( p ) / D( q ) |
FASTR( 3 ) = T*D( p ) / D( q ) |
FASTR( 4 ) = -T*D( q ) / D( p ) |
FASTR( 4 ) = -T*D( q ) / D( p ) |
CALL DROTM( M, A( 1, p ), 1, |
CALL DROTM( M, A( 1, p ), 1, |
+ A( 1, q ), 1, FASTR ) |
$ A( 1, q ), 1, FASTR ) |
IF( RSVEC )CALL DROTM( MVL, |
IF( RSVEC )CALL DROTM( MVL, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ FASTR ) |
$ FASTR ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE+T*APOAQ*AAPQ ) ) |
$ ONE+T*APOAQ*AAPQ ) ) |
AAPP = AAPP*DSQRT( DMAX1( ZERO, |
AAPP = AAPP*DSQRT( MAX( ZERO, |
+ ONE-T*AQOAP*AAPQ ) ) |
$ ONE-T*AQOAP*AAPQ ) ) |
MXSINJ = DMAX1( MXSINJ, DABS( T ) ) |
MXSINJ = MAX( MXSINJ, DABS( T ) ) |
ELSE |
ELSE |
* |
* |
* .. choose correct signum for THETA and rotate |
* .. choose correct signum for THETA and rotate |
Line 701
|
Line 792
|
THSIGN = -DSIGN( ONE, AAPQ ) |
THSIGN = -DSIGN( ONE, AAPQ ) |
IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGN |
IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGN |
T = ONE / ( THETA+THSIGN* |
T = ONE / ( THETA+THSIGN* |
+ DSQRT( ONE+THETA*THETA ) ) |
$ DSQRT( ONE+THETA*THETA ) ) |
CS = DSQRT( ONE / ( ONE+T*T ) ) |
CS = DSQRT( ONE / ( ONE+T*T ) ) |
SN = T*CS |
SN = T*CS |
MXSINJ = DMAX1( MXSINJ, DABS( SN ) ) |
MXSINJ = MAX( MXSINJ, DABS( SN ) ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE+T*APOAQ*AAPQ ) ) |
$ ONE+T*APOAQ*AAPQ ) ) |
AAPP = AAPP*DSQRT( ONE-T*AQOAP* |
AAPP = AAPP*DSQRT( MAX( ZERO, |
+ AAPQ ) |
$ ONE-T*AQOAP*AAPQ ) ) |
* |
* |
APOAQ = D( p ) / D( q ) |
APOAQ = D( p ) / D( q ) |
AQOAP = D( q ) / D( p ) |
AQOAP = D( q ) / D( p ) |
Line 720
|
Line 811
|
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
CALL DROTM( M, A( 1, p ), 1, |
CALL DROTM( M, A( 1, p ), 1, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ FASTR ) |
$ FASTR ) |
IF( RSVEC )CALL DROTM( MVL, |
IF( RSVEC )CALL DROTM( MVL, |
+ V( 1, p ), 1, V( 1, q ), |
$ V( 1, p ), 1, V( 1, q ), |
+ 1, FASTR ) |
$ 1, FASTR ) |
ELSE |
ELSE |
CALL DAXPY( M, -T*AQOAP, |
CALL DAXPY( M, -T*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
CALL DAXPY( M, CS*SN*APOAQ, |
CALL DAXPY( M, CS*SN*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, -T*AQOAP, |
CALL DAXPY( MVL, -T*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ CS*SN*APOAQ, |
$ CS*SN*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
END IF |
END IF |
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q ) / CS |
D( q ) = D( q ) / CS |
Line 747
|
Line 838
|
ELSE |
ELSE |
IF( D( q ).GE.ONE ) THEN |
IF( D( q ).GE.ONE ) THEN |
CALL DAXPY( M, T*APOAQ, |
CALL DAXPY( M, T*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DAXPY( M, -CS*SN*AQOAP, |
CALL DAXPY( M, -CS*SN*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, T*APOAQ, |
CALL DAXPY( MVL, T*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
END IF |
END IF |
D( p ) = D( p ) / CS |
D( p ) = D( p ) / CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
ELSE |
ELSE |
IF( D( p ).GE.D( q ) ) THEN |
IF( D( p ).GE.D( q ) ) THEN |
CALL DAXPY( M, -T*AQOAP, |
CALL DAXPY( M, -T*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
CALL DAXPY( M, CS*SN*APOAQ, |
CALL DAXPY( M, CS*SN*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
D( p ) = D( p )*CS |
D( p ) = D( p )*CS |
D( q ) = D( q ) / CS |
D( q ) = D( q ) / CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -T*AQOAP, |
$ -T*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ CS*SN*APOAQ, |
$ CS*SN*APOAQ, |
+ V( 1, p ), 1, |
$ V( 1, p ), 1, |
+ V( 1, q ), 1 ) |
$ V( 1, q ), 1 ) |
END IF |
END IF |
ELSE |
ELSE |
CALL DAXPY( M, T*APOAQ, |
CALL DAXPY( M, T*APOAQ, |
+ A( 1, p ), 1, |
$ A( 1, p ), 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DAXPY( M, |
CALL DAXPY( M, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ A( 1, q ), 1, |
$ A( 1, q ), 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
D( p ) = D( p ) / CS |
D( p ) = D( p ) / CS |
D( q ) = D( q )*CS |
D( q ) = D( q )*CS |
IF( RSVEC ) THEN |
IF( RSVEC ) THEN |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ T*APOAQ, V( 1, p ), |
$ T*APOAQ, V( 1, p ), |
+ 1, V( 1, q ), 1 ) |
$ 1, V( 1, q ), 1 ) |
CALL DAXPY( MVL, |
CALL DAXPY( MVL, |
+ -CS*SN*AQOAP, |
$ -CS*SN*AQOAP, |
+ V( 1, q ), 1, |
$ V( 1, q ), 1, |
+ V( 1, p ), 1 ) |
$ V( 1, p ), 1 ) |
END IF |
END IF |
END IF |
END IF |
END IF |
END IF |
Line 810
|
Line 901
|
ELSE |
ELSE |
IF( AAPP.GT.AAQQ ) THEN |
IF( AAPP.GT.AAQQ ) THEN |
CALL DCOPY( M, A( 1, p ), 1, WORK, |
CALL DCOPY( M, A( 1, p ), 1, WORK, |
+ 1 ) |
$ 1 ) |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, |
+ M, 1, A( 1, q ), LDA, |
$ M, 1, A( 1, q ), LDA, |
+ IERR ) |
$ IERR ) |
TEMP1 = -AAPQ*D( p ) / D( q ) |
TEMP1 = -AAPQ*D( p ) / D( q ) |
CALL DAXPY( M, TEMP1, WORK, 1, |
CALL DAXPY( M, TEMP1, WORK, 1, |
+ A( 1, q ), 1 ) |
$ A( 1, q ), 1 ) |
CALL DLASCL( 'G', 0, 0, ONE, AAQQ, |
CALL DLASCL( 'G', 0, 0, ONE, AAQQ, |
+ M, 1, A( 1, q ), LDA, |
$ M, 1, A( 1, q ), LDA, |
+ IERR ) |
$ IERR ) |
SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO, |
SVA( q ) = AAQQ*DSQRT( MAX( ZERO, |
+ ONE-AAPQ*AAPQ ) ) |
$ ONE-AAPQ*AAPQ ) ) |
MXSINJ = DMAX1( MXSINJ, SFMIN ) |
MXSINJ = MAX( MXSINJ, SFMIN ) |
ELSE |
ELSE |
CALL DCOPY( M, A( 1, q ), 1, WORK, |
CALL DCOPY( M, A( 1, q ), 1, WORK, |
+ 1 ) |
$ 1 ) |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, |
CALL DLASCL( 'G', 0, 0, AAQQ, ONE, |
+ M, 1, WORK, LDA, IERR ) |
$ M, 1, WORK, LDA, IERR ) |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, |
CALL DLASCL( 'G', 0, 0, AAPP, ONE, |
+ M, 1, A( 1, p ), LDA, |
$ M, 1, A( 1, p ), LDA, |
+ IERR ) |
$ IERR ) |
TEMP1 = -AAPQ*D( q ) / D( p ) |
TEMP1 = -AAPQ*D( q ) / D( p ) |
CALL DAXPY( M, TEMP1, WORK, 1, |
CALL DAXPY( M, TEMP1, WORK, 1, |
+ A( 1, p ), 1 ) |
$ A( 1, p ), 1 ) |
CALL DLASCL( 'G', 0, 0, ONE, AAPP, |
CALL DLASCL( 'G', 0, 0, ONE, AAPP, |
+ M, 1, A( 1, p ), LDA, |
$ M, 1, A( 1, p ), LDA, |
+ IERR ) |
$ IERR ) |
SVA( p ) = AAPP*DSQRT( DMAX1( ZERO, |
SVA( p ) = AAPP*DSQRT( MAX( ZERO, |
+ ONE-AAPQ*AAPQ ) ) |
$ ONE-AAPQ*AAPQ ) ) |
MXSINJ = DMAX1( MXSINJ, SFMIN ) |
MXSINJ = MAX( MXSINJ, SFMIN ) |
END IF |
END IF |
END IF |
END IF |
* END IF ROTOK THEN ... ELSE |
* END IF ROTOK THEN ... ELSE |
Line 849
|
Line 940
|
* In the case of cancellation in updating SVA(q) |
* In the case of cancellation in updating SVA(q) |
* .. recompute SVA(q) |
* .. recompute SVA(q) |
IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS ) |
IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS ) |
+ THEN |
$ THEN |
IF( ( AAQQ.LT.ROOTBIG ) .AND. |
IF( ( AAQQ.LT.ROOTBIG ) .AND. |
+ ( AAQQ.GT.ROOTSFMIN ) ) THEN |
$ ( AAQQ.GT.ROOTSFMIN ) ) THEN |
SVA( q ) = DNRM2( M, A( 1, q ), 1 )* |
SVA( q ) = DNRM2( M, A( 1, q ), 1 )* |
+ D( q ) |
$ D( q ) |
ELSE |
ELSE |
T = ZERO |
T = ZERO |
AAQQ = ZERO |
AAQQ = ONE |
CALL DLASSQ( M, A( 1, q ), 1, T, |
CALL DLASSQ( M, A( 1, q ), 1, T, |
+ AAQQ ) |
$ AAQQ ) |
SVA( q ) = T*DSQRT( AAQQ )*D( q ) |
SVA( q ) = T*DSQRT( AAQQ )*D( q ) |
END IF |
END IF |
END IF |
END IF |
IF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THEN |
IF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THEN |
IF( ( AAPP.LT.ROOTBIG ) .AND. |
IF( ( AAPP.LT.ROOTBIG ) .AND. |
+ ( AAPP.GT.ROOTSFMIN ) ) THEN |
$ ( AAPP.GT.ROOTSFMIN ) ) THEN |
AAPP = DNRM2( M, A( 1, p ), 1 )* |
AAPP = DNRM2( M, A( 1, p ), 1 )* |
+ D( p ) |
$ D( p ) |
ELSE |
ELSE |
T = ZERO |
T = ZERO |
AAPP = ZERO |
AAPP = ONE |
CALL DLASSQ( M, A( 1, p ), 1, T, |
CALL DLASSQ( M, A( 1, p ), 1, T, |
+ AAPP ) |
$ AAPP ) |
AAPP = T*DSQRT( AAPP )*D( p ) |
AAPP = T*DSQRT( AAPP )*D( p ) |
END IF |
END IF |
SVA( p ) = AAPP |
SVA( p ) = AAPP |
Line 889
|
Line 980
|
END IF |
END IF |
* |
* |
IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) ) |
IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) ) |
+ THEN |
$ THEN |
SVA( p ) = AAPP |
SVA( p ) = AAPP |
NOTROT = 0 |
NOTROT = 0 |
GO TO 2011 |
GO TO 2011 |
END IF |
END IF |
IF( ( i.LE.SWBAND ) .AND. |
IF( ( i.LE.SWBAND ) .AND. |
+ ( PSKIPPED.GT.ROWSKIP ) ) THEN |
$ ( PSKIPPED.GT.ROWSKIP ) ) THEN |
AAPP = -AAPP |
AAPP = -AAPP |
NOTROT = 0 |
NOTROT = 0 |
GO TO 2203 |
GO TO 2203 |
Line 909
|
Line 1000
|
* |
* |
ELSE |
ELSE |
IF( AAPP.EQ.ZERO )NOTROT = NOTROT + |
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 |
IF( AAPP.LT.ZERO )NOTROT = 0 |
END IF |
END IF |
|
|
Line 919
|
Line 1010
|
* end of the jbc-loop |
* end of the jbc-loop |
2011 CONTINUE |
2011 CONTINUE |
*2011 bailed out of the jbc-loop |
*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 ) ) |
SVA( p ) = DABS( SVA( p ) ) |
2012 CONTINUE |
2012 CONTINUE |
* |
* |
Line 928
|
Line 1019
|
* |
* |
* .. update SVA(N) |
* .. update SVA(N) |
IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) ) |
IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) ) |
+ THEN |
$ THEN |
SVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N ) |
SVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N ) |
ELSE |
ELSE |
T = ZERO |
T = ZERO |
AAPP = ZERO |
AAPP = ONE |
CALL DLASSQ( M, A( 1, N ), 1, T, AAPP ) |
CALL DLASSQ( M, A( 1, N ), 1, T, AAPP ) |
SVA( N ) = T*DSQRT( AAPP )*D( N ) |
SVA( N ) = T*DSQRT( AAPP )*D( N ) |
END IF |
END IF |
Line 940
|
Line 1031
|
* Additional steering devices |
* Additional steering devices |
* |
* |
IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR. |
IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR. |
+ ( ISWROT.LE.N ) ) )SWBAND = i |
$ ( ISWROT.LE.N ) ) )SWBAND = i |
* |
* |
IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND. |
IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND. |
+ ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN |
$ ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN |
GO TO 1994 |
GO TO 1994 |
END IF |
END IF |
* |
* |
Line 951
|
Line 1042
|
|
|
1993 CONTINUE |
1993 CONTINUE |
* end i=1:NSWEEP loop |
* 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. |
* number of iterations. |
INFO = NSWEEP - 1 |
INFO = NSWEEP - 1 |
GO TO 1995 |
GO TO 1995 |