version 1.1, 2015/11/26 11:44:21
|
version 1.2, 2016/08/27 15:27:12
|
Line 27
|
Line 27
|
* INTEGER INFO, LDA, LDU, LDV, LWORK, M, N |
* INTEGER INFO, LDA, LDU, LDV, LWORK, M, N |
* .. |
* .. |
* .. Array Arguments .. |
* .. Array Arguments .. |
* DOUBLE COMPLEX A( LDA, * ), U( LDU, * ), V( LDV, * ), CWORK( LWORK ) |
* COMPLEX*16 A( LDA, * ), U( LDU, * ), V( LDV, * ), CWORK( LWORK ) |
* DOUBLE PRECISION SVA( N ), RWORK( LRWORK ) |
* DOUBLE PRECISION SVA( N ), RWORK( LRWORK ) |
* INTEGER IWORK( * ) |
* INTEGER IWORK( * ) |
* CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV |
* CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV |
Line 39
|
Line 39
|
*> |
*> |
*> \verbatim |
*> \verbatim |
*> |
*> |
* ZGEJSV computes the singular value decomposition (SVD) of a real M-by-N |
*> ZGEJSV computes the singular value decomposition (SVD) of a complex M-by-N |
* matrix [A], where M >= N. The SVD of [A] is written as |
*> matrix [A], where M >= N. The SVD of [A] is written as |
* |
*> |
* [A] = [U] * [SIGMA] * [V]^*, |
*> [A] = [U] * [SIGMA] * [V]^*, |
* |
*> |
* where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N |
*> where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N |
* diagonal elements, [U] is an M-by-N (or M-by-M) orthonormal matrix, and |
*> diagonal elements, [U] is an M-by-N (or M-by-M) unitary matrix, and |
* [V] is an N-by-N orthogonal matrix. The diagonal elements of [SIGMA] are |
*> [V] is an N-by-N unitary matrix. The diagonal elements of [SIGMA] are |
* the singular values of [A]. The columns of [U] and [V] are the left and |
*> the singular values of [A]. The columns of [U] and [V] are the left and |
* the right singular vectors of [A], respectively. The matrices [U] and [V] |
*> the right singular vectors of [A], respectively. The matrices [U] and [V] |
* are computed and stored in the arrays U and V, respectively. The diagonal |
*> are computed and stored in the arrays U and V, respectively. The diagonal |
* of [SIGMA] is computed and stored in the array SVA. |
*> of [SIGMA] is computed and stored in the array SVA. |
* |
*> \endverbatim |
* Arguments: |
*> |
* ========== |
*> Arguments: |
|
*> ========== |
*> |
*> |
*> \param[in] JOBA |
*> \param[in] JOBA |
*> \verbatim |
*> \verbatim |
Line 193
|
Line 194
|
*> |
*> |
*> \param[in,out] A |
*> \param[in,out] A |
*> \verbatim |
*> \verbatim |
*> A is DOUBLE COMPLEX array, dimension (LDA,N) |
*> A is COMPLEX*16 array, dimension (LDA,N) |
*> On entry, the M-by-N matrix A. |
*> On entry, the M-by-N matrix A. |
*> \endverbatim |
*> \endverbatim |
*> |
*> |
Line 221
|
Line 222
|
*> |
*> |
*> \param[out] U |
*> \param[out] U |
*> \verbatim |
*> \verbatim |
*> U is DOUBLE COMPLEX array, dimension ( LDU, N ) |
*> U is COMPLEX*16 array, dimension ( LDU, N ) |
*> If JOBU = 'U', then U contains on exit the M-by-N matrix of |
*> If JOBU = 'U', then U contains on exit the M-by-N matrix of |
*> the left singular vectors. |
*> the left singular vectors. |
*> If JOBU = 'F', then U contains on exit the M-by-M matrix of |
*> If JOBU = 'F', then U contains on exit the M-by-M matrix of |
Line 234
|
Line 235
|
*> copied back to the V array. This 'W' option is just |
*> copied back to the V array. This 'W' option is just |
*> a reminder to the caller that in this case U is |
*> a reminder to the caller that in this case U is |
*> reserved as workspace of length N*N. |
*> reserved as workspace of length N*N. |
*> If JOBU = 'N' U is not referenced. |
*> If JOBU = 'N' U is not referenced, unless JOBT='T'. |
*> \endverbatim |
*> \endverbatim |
*> |
*> |
*> \param[in] LDU |
*> \param[in] LDU |
Line 246
|
Line 247
|
*> |
*> |
*> \param[out] V |
*> \param[out] V |
*> \verbatim |
*> \verbatim |
*> V is DOUBLE COMPLEX array, dimension ( LDV, N ) |
*> V is COMPLEX*16 array, dimension ( LDV, N ) |
*> If JOBV = 'V', 'J' then V contains on exit the N-by-N matrix of |
*> If JOBV = 'V', 'J' then V contains on exit the N-by-N matrix of |
*> the right singular vectors; |
*> the right singular vectors; |
*> If JOBV = 'W', AND (JOBU.EQ.'U' AND JOBT.EQ.'T' AND M.EQ.N), |
*> If JOBV = 'W', AND (JOBU.EQ.'U' AND JOBT.EQ.'T' AND M.EQ.N), |
Line 256
|
Line 257
|
*> copied back to the U array. This 'W' option is just |
*> copied back to the U array. This 'W' option is just |
*> a reminder to the caller that in this case V is |
*> a reminder to the caller that in this case V is |
*> reserved as workspace of length N*N. |
*> reserved as workspace of length N*N. |
*> If JOBV = 'N' V is not referenced. |
*> If JOBV = 'N' V is not referenced, unless JOBT='T'. |
*> \endverbatim |
*> \endverbatim |
*> |
*> |
*> \param[in] LDV |
*> \param[in] LDV |
Line 268
|
Line 269
|
*> |
*> |
*> \param[out] CWORK |
*> \param[out] CWORK |
*> \verbatim |
*> \verbatim |
*> CWORK (workspace) |
*> CWORK is COMPLEX*16 array, dimension at least LWORK. |
*> CWORK is DOUBLE COMPLEX array, dimension at least LWORK. |
|
*> \endverbatim |
*> \endverbatim |
*> |
*> |
*> \param[in] LWORK |
*> \param[in] LWORK |
Line 279
|
Line 279
|
*> LWORK depends on the job: |
*> LWORK depends on the job: |
*> |
*> |
*> 1. If only SIGMA is needed ( JOBU.EQ.'N', JOBV.EQ.'N' ) and |
*> 1. If only SIGMA is needed ( JOBU.EQ.'N', JOBV.EQ.'N' ) and |
*> 1.1 .. no scaled condition estimate required (JOBE.EQ.'N'): |
*> 1.1 .. no scaled condition estimate required (JOBA.NE.'E'.AND.JOBA.NE.'G'): |
*> LWORK >= 2*N+1. This is the minimal requirement. |
*> LWORK >= 2*N+1. This is the minimal requirement. |
*> ->> For optimal performance (blocked code) the optimal value |
*> ->> For optimal performance (blocked code) the optimal value |
*> is LWORK >= N + (N+1)*NB. Here NB is the optimal |
*> is LWORK >= N + (N+1)*NB. Here NB is the optimal |
Line 293
|
Line 293
|
*> is LWORK >= max(N+(N+1)*NB, N*N+3*N). |
*> is LWORK >= max(N+(N+1)*NB, N*N+3*N). |
*> In general, the optimal length LWORK is computed as |
*> In general, the optimal length LWORK is computed as |
*> LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(ZGEQRF), |
*> LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(ZGEQRF), |
*> N+N*N+LWORK(CPOCON)). |
*> N+N*N+LWORK(ZPOCON)). |
*> |
*> |
*> 2. If SIGMA and the right singular vectors are needed (JOBV.EQ.'V'), |
*> 2. If SIGMA and the right singular vectors are needed (JOBV.EQ.'V'), |
*> (JOBU.EQ.'N') |
*> (JOBU.EQ.'N') |
*> -> the minimal requirement is LWORK >= 3*N. |
*> -> the minimal requirement is LWORK >= 3*N. |
*> -> For optimal performance, LWORK >= max(N+(N+1)*NB, 3*N,2*N+N*NB), |
*> -> For optimal performance, LWORK >= max(N+(N+1)*NB, 3*N,2*N+N*NB), |
*> where NB is the optimal block size for ZGEQP3, ZGEQRF, ZGELQ, |
*> where NB is the optimal block size for ZGEQP3, ZGEQRF, ZGELQF, |
*> CUNMLQ. In general, the optimal length LWORK is computed as |
*> ZUNMLQ. In general, the optimal length LWORK is computed as |
*> LWORK >= max(N+LWORK(ZGEQP3), N+LWORK(CPOCON), N+LWORK(ZGESVJ), |
*> LWORK >= max(N+LWORK(ZGEQP3), N+LWORK(ZPOCON), N+LWORK(ZGESVJ), |
*> N+LWORK(ZGELQF), 2*N+LWORK(ZGEQRF), N+LWORK(CUNMLQ)). |
*> N+LWORK(ZGELQF), 2*N+LWORK(ZGEQRF), N+LWORK(ZUNMLQ)). |
*> |
*> |
*> 3. If SIGMA and the left singular vectors are needed |
*> 3. If SIGMA and the left singular vectors are needed |
*> -> the minimal requirement is LWORK >= 3*N. |
*> -> the minimal requirement is LWORK >= 3*N. |
*> -> For optimal performance: |
*> -> For optimal performance: |
*> if JOBU.EQ.'U' :: LWORK >= max(3*N, N+(N+1)*NB, 2*N+N*NB), |
*> if JOBU.EQ.'U' :: LWORK >= max(3*N, N+(N+1)*NB, 2*N+N*NB), |
*> where NB is the optimal block size for ZGEQP3, ZGEQRF, CUNMQR. |
*> where NB is the optimal block size for ZGEQP3, ZGEQRF, ZUNMQR. |
*> In general, the optimal length LWORK is computed as |
*> In general, the optimal length LWORK is computed as |
*> LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(CPOCON), |
*> LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(ZPOCON), |
*> 2*N+LWORK(ZGEQRF), N+LWORK(CUNMQR)). |
*> 2*N+LWORK(ZGEQRF), N+LWORK(ZUNMQR)). |
*> |
*> |
*> 4. If the full SVD is needed: (JOBU.EQ.'U' or JOBU.EQ.'F') and |
*> 4. If the full SVD is needed: (JOBU.EQ.'U' or JOBU.EQ.'F') and |
*> 4.1. if JOBV.EQ.'V' |
*> 4.1. if JOBV.EQ.'V' |
*> the minimal requirement is LWORK >= 5*N+2*N*N. |
*> the minimal requirement is LWORK >= 5*N+2*N*N. |
*> 4.2. if JOBV.EQ.'J' the minimal requirement is |
*> 4.2. if JOBV.EQ.'J' the minimal requirement is |
*> LWORK >= 4*N+N*N. |
*> LWORK >= 4*N+N*N. |
*> In both cases, the allocated CWORK can accomodate blocked runs |
*> In both cases, the allocated CWORK can accommodate blocked runs |
*> of ZGEQP3, ZGEQRF, ZGELQF, SUNMQR, CUNMLQ. |
*> of ZGEQP3, ZGEQRF, ZGELQF, ZUNMQR, ZUNMLQ. |
*> \endverbatim |
*> \endverbatim |
*> |
*> |
*> \param[out] RWORK |
*> \param[out] RWORK |
Line 433
|
Line 433
|
*> \author Univ. of Colorado Denver |
*> \author Univ. of Colorado Denver |
*> \author NAG Ltd. |
*> \author NAG Ltd. |
* |
* |
*> \date November 2015 |
*> \date June 2016 |
* |
* |
*> \ingroup complex16GEsing |
*> \ingroup complex16GEsing |
* |
* |
Line 491
|
Line 491
|
*> |
*> |
*> \verbatim |
*> \verbatim |
*> |
*> |
* [1] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I. |
*> [1] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I. |
* SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342. |
*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342. |
* LAPACK Working note 169. |
*> LAPACK Working note 169. |
* [2] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II. |
*> [2] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II. |
* SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362. |
*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362. |
* LAPACK Working note 170. |
*> LAPACK Working note 170. |
* [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR |
*> [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR |
* factorization software - a case study. |
*> factorization software - a case study. |
* ACM Trans. math. Softw. Vol. 35, No 2 (2008), pp. 1-28. |
*> ACM Trans. Math. Softw. Vol. 35, No 2 (2008), pp. 1-28. |
* LAPACK Working note 176. |
*> LAPACK Working note 176. |
* [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV, |
*> [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV, |
* QSVD, (H,K)-SVD computations. |
*> QSVD, (H,K)-SVD computations. |
* Department of Mathematics, University of Zagreb, 2008. |
*> Department of Mathematics, University of Zagreb, 2008. |
*> \endverbatim |
*> \endverbatim |
* |
* |
*> \par Bugs, examples and comments: |
*> \par Bugs, examples and comments: |
Line 517
|
Line 517
|
$ M, N, A, LDA, SVA, U, LDU, V, LDV, |
$ M, N, A, LDA, SVA, U, LDU, V, LDV, |
$ CWORK, LWORK, RWORK, LRWORK, IWORK, INFO ) |
$ CWORK, LWORK, RWORK, LRWORK, IWORK, INFO ) |
* |
* |
* -- LAPACK computational routine (version 3.6.0) -- |
* -- LAPACK computational routine (version 3.6.1) -- |
* -- 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..-- |
* November 2015 |
* June 2016 |
* |
* |
* .. Scalar Arguments .. |
* .. Scalar Arguments .. |
IMPLICIT NONE |
IMPLICIT NONE |
INTEGER INFO, LDA, LDU, LDV, LWORK, LRWORK, M, N |
INTEGER INFO, LDA, LDU, LDV, LWORK, LRWORK, M, N |
* .. |
* .. |
* .. Array Arguments .. |
* .. Array Arguments .. |
DOUBLE COMPLEX A( LDA, * ), U( LDU, * ), V( LDV, * ), |
COMPLEX*16 A( LDA, * ), U( LDU, * ), V( LDV, * ), |
$ CWORK( LWORK ) |
$ CWORK( LWORK ) |
DOUBLE PRECISION SVA( N ), RWORK( * ) |
DOUBLE PRECISION SVA( N ), RWORK( * ) |
INTEGER IWORK( * ) |
INTEGER IWORK( * ) |
Line 539
|
Line 539
|
* .. Local Parameters .. |
* .. Local Parameters .. |
DOUBLE PRECISION ZERO, ONE |
DOUBLE PRECISION ZERO, ONE |
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) |
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) |
DOUBLE COMPLEX CZERO, CONE |
COMPLEX*16 CZERO, CONE |
PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ), CONE = ( 1.0D0, 0.0D0 ) ) |
PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ), CONE = ( 1.0D0, 0.0D0 ) ) |
* .. |
* .. |
* .. Local Scalars .. |
* .. Local Scalars .. |
DOUBLE COMPLEX CTEMP |
COMPLEX*16 CTEMP |
DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, |
DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, |
$ COND_OK, CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, |
$ COND_OK, CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, |
$ MAXPRJ, SCALEM, SCONDA, SFMIN, SMALL, TEMP1, |
$ MAXPRJ, SCALEM, SCONDA, SFMIN, SMALL, TEMP1, |
Line 554
|
Line 554
|
$ NOSCAL, ROWPIV, RSVEC, TRANSP |
$ NOSCAL, ROWPIV, RSVEC, TRANSP |
* .. |
* .. |
* .. Intrinsic Functions .. |
* .. Intrinsic Functions .. |
INTRINSIC ABS, DCMPLX, DCONJG, DLOG, DMAX1, DMIN1, DFLOAT, |
INTRINSIC ABS, DCMPLX, DCONJG, DLOG, DMAX1, DMIN1, DBLE, |
$ MAX0, MIN0, NINT, DSQRT |
$ MAX0, MIN0, NINT, DSQRT |
* .. |
* .. |
* .. External Functions .. |
* .. External Functions .. |
DOUBLE PRECISION DLAMCH, DZNRM2 |
DOUBLE PRECISION DLAMCH, DZNRM2 |
INTEGER IDAMAX |
INTEGER IDAMAX, IZAMAX |
LOGICAL LSAME |
LOGICAL LSAME |
EXTERNAL IDAMAX, LSAME, DLAMCH, DZNRM2 |
EXTERNAL IDAMAX, IZAMAX, LSAME, DLAMCH, DZNRM2 |
* .. |
* .. |
* .. External Subroutines .. |
* .. External Subroutines .. |
EXTERNAL ZCOPY, ZGELQF, ZGEQP3, ZGEQRF, ZLACPY, ZLASCL, |
EXTERNAL DLASSQ, ZCOPY, ZGELQF, ZGEQP3, ZGEQRF, ZLACPY, ZLASCL, |
$ ZLASET, ZLASSQ, ZLASWP, ZUNGQR, ZUNMLQ, |
$ DLASCL, ZLASET, ZLASSQ, ZLASWP, ZUNGQR, ZUNMLQ, |
$ ZUNMQR, ZPOCON, DSCAL, ZDSCAL, ZSWAP, ZTRSM, XERBLA |
$ ZUNMQR, ZPOCON, DSCAL, ZDSCAL, ZSWAP, ZTRSM, XERBLA |
* |
* |
EXTERNAL ZGESVJ |
EXTERNAL ZGESVJ |
Line 640
|
Line 640
|
* |
* |
* Quick return for void matrix (Y3K safe) |
* Quick return for void matrix (Y3K safe) |
* #:) |
* #:) |
IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN |
IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THEN |
|
IWORK(1:3) = 0 |
|
RWORK(1:7) = 0 |
|
RETURN |
|
ENDIF |
* |
* |
* Determine whether the matrix U should be M x N or M x M |
* Determine whether the matrix U should be M x N or M x M |
* |
* |
Line 665
|
Line 669
|
* overflow. It is possible that this scaling pushes the smallest |
* overflow. It is possible that this scaling pushes the smallest |
* column norm left from the underflow threshold (extreme case). |
* column norm left from the underflow threshold (extreme case). |
* |
* |
SCALEM = ONE / DSQRT(DFLOAT(M)*DFLOAT(N)) |
SCALEM = ONE / DSQRT(DBLE(M)*DBLE(N)) |
NOSCAL = .TRUE. |
NOSCAL = .TRUE. |
GOSCAL = .TRUE. |
GOSCAL = .TRUE. |
DO 1874 p = 1, N |
DO 1874 p = 1, N |
Line 807
|
Line 811
|
1950 CONTINUE |
1950 CONTINUE |
ELSE |
ELSE |
DO 1904 p = 1, M |
DO 1904 p = 1, M |
RWORK(M+N+p) = SCALEM*ABS( A(p,IDAMAX(N,A(p,1),LDA)) ) |
RWORK(M+N+p) = SCALEM*ABS( A(p,IZAMAX(N,A(p,1),LDA)) ) |
AATMAX = DMAX1( AATMAX, RWORK(M+N+p) ) |
AATMAX = DMAX1( AATMAX, RWORK(M+N+p) ) |
AATMIN = DMIN1( AATMIN, RWORK(M+N+p) ) |
AATMIN = DMIN1( AATMIN, RWORK(M+N+p) ) |
1904 CONTINUE |
1904 CONTINUE |
Line 828
|
Line 832
|
* |
* |
XSC = ZERO |
XSC = ZERO |
TEMP1 = ONE |
TEMP1 = ONE |
CALL ZLASSQ( N, SVA, 1, XSC, TEMP1 ) |
CALL DLASSQ( N, SVA, 1, XSC, TEMP1 ) |
TEMP1 = ONE / TEMP1 |
TEMP1 = ONE / TEMP1 |
* |
* |
ENTRA = ZERO |
ENTRA = ZERO |
Line 836
|
Line 840
|
BIG1 = ( ( SVA(p) / XSC )**2 ) * TEMP1 |
BIG1 = ( ( SVA(p) / XSC )**2 ) * TEMP1 |
IF ( BIG1 .NE. ZERO ) ENTRA = ENTRA + BIG1 * DLOG(BIG1) |
IF ( BIG1 .NE. ZERO ) ENTRA = ENTRA + BIG1 * DLOG(BIG1) |
1113 CONTINUE |
1113 CONTINUE |
ENTRA = - ENTRA / DLOG(DFLOAT(N)) |
ENTRA = - ENTRA / DLOG(DBLE(N)) |
* |
* |
* Now, SVA().^2/Trace(A^* * A) is a point in the probability simplex. |
* Now, SVA().^2/Trace(A^* * A) is a point in the probability simplex. |
* It is derived from the diagonal of A^* * A. Do the same with the |
* It is derived from the diagonal of A^* * A. Do the same with the |
Line 849
|
Line 853
|
BIG1 = ( ( RWORK(p) / XSC )**2 ) * TEMP1 |
BIG1 = ( ( RWORK(p) / XSC )**2 ) * TEMP1 |
IF ( BIG1 .NE. ZERO ) ENTRAT = ENTRAT + BIG1 * DLOG(BIG1) |
IF ( BIG1 .NE. ZERO ) ENTRAT = ENTRAT + BIG1 * DLOG(BIG1) |
1114 CONTINUE |
1114 CONTINUE |
ENTRAT = - ENTRAT / DLOG(DFLOAT(M)) |
ENTRAT = - ENTRAT / DLOG(DBLE(M)) |
* |
* |
* Analyze the entropies and decide A or A^*. Smaller entropy |
* Analyze the entropies and decide A or A^*. Smaller entropy |
* usually means better input for the algorithm. |
* usually means better input for the algorithm. |
Line 905
|
Line 909
|
* one should use ZGESVJ instead of ZGEJSV. |
* one should use ZGESVJ instead of ZGEJSV. |
* |
* |
BIG1 = DSQRT( BIG ) |
BIG1 = DSQRT( BIG ) |
TEMP1 = DSQRT( BIG / DFLOAT(N) ) |
TEMP1 = DSQRT( BIG / DBLE(N) ) |
* |
* |
CALL ZLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR ) |
CALL DLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR ) |
IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN |
IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN |
AAQQ = ( AAQQ / AAPP ) * TEMP1 |
AAQQ = ( AAQQ / AAPP ) * TEMP1 |
ELSE |
ELSE |
Line 1009
|
Line 1013
|
* sigma_i < N*EPSLN*||A|| are flushed to zero. This is an |
* sigma_i < N*EPSLN*||A|| are flushed to zero. This is an |
* agressive enforcement of lower numerical rank by introducing a |
* agressive enforcement of lower numerical rank by introducing a |
* backward error of the order of N*EPSLN*||A||. |
* backward error of the order of N*EPSLN*||A||. |
TEMP1 = DSQRT(DFLOAT(N))*EPSLN |
TEMP1 = DSQRT(DBLE(N))*EPSLN |
DO 3001 p = 2, N |
DO 3001 p = 2, N |
IF ( ABS(A(p,p)) .GE. (TEMP1*ABS(A(1,1))) ) THEN |
IF ( ABS(A(p,p)) .GE. (TEMP1*ABS(A(1,1))) ) THEN |
NR = NR + 1 |
NR = NR + 1 |
Line 1056
|
Line 1060
|
TEMP1 = ABS(A(p,p)) / SVA(IWORK(p)) |
TEMP1 = ABS(A(p,p)) / SVA(IWORK(p)) |
MAXPRJ = DMIN1( MAXPRJ, TEMP1 ) |
MAXPRJ = DMIN1( MAXPRJ, TEMP1 ) |
3051 CONTINUE |
3051 CONTINUE |
IF ( MAXPRJ**2 .GE. ONE - DFLOAT(N)*EPSLN ) ALMORT = .TRUE. |
IF ( MAXPRJ**2 .GE. ONE - DBLE(N)*EPSLN ) ALMORT = .TRUE. |
END IF |
END IF |
* |
* |
* |
* |
Line 1136
|
Line 1140
|
* |
* |
IF ( L2PERT ) THEN |
IF ( L2PERT ) THEN |
* XSC = SQRT(SMALL) |
* XSC = SQRT(SMALL) |
XSC = EPSLN / DFLOAT(N) |
XSC = EPSLN / DBLE(N) |
DO 4947 q = 1, NR |
DO 4947 q = 1, NR |
CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO) |
CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO) |
DO 4949 p = 1, N |
DO 4949 p = 1, N |
Line 1168
|
Line 1172
|
* to drown denormals |
* to drown denormals |
IF ( L2PERT ) THEN |
IF ( L2PERT ) THEN |
* XSC = SQRT(SMALL) |
* XSC = SQRT(SMALL) |
XSC = EPSLN / DFLOAT(N) |
XSC = EPSLN / DBLE(N) |
DO 1947 q = 1, NR |
DO 1947 q = 1, NR |
CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO) |
CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO) |
DO 1949 p = 1, NR |
DO 1949 p = 1, NR |
Line 1226
|
Line 1230
|
CALL ZCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 ) |
CALL ZCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 ) |
CALL ZLACGV( NR-p+1, V(p,p), 1 ) |
CALL ZLACGV( NR-p+1, V(p,p), 1 ) |
8998 CONTINUE |
8998 CONTINUE |
CALL ZLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV ) |
CALL ZLASET('Upper', NR-1, NR-1, CZERO, CZERO, V(1,2), LDV) |
* |
* |
CALL ZGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U, |
CALL ZGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U, |
$ LDU, CWORK(N+1), LWORK-N, RWORK, LRWORK, INFO ) |
$ LDU, CWORK(N+1), LWORK-N, RWORK, LRWORK, INFO ) |
Line 1363
|
Line 1367
|
CONDR1 = ONE / DSQRT(TEMP1) |
CONDR1 = ONE / DSQRT(TEMP1) |
* .. here need a second oppinion on the condition number |
* .. here need a second oppinion on the condition number |
* .. then assume worst case scenario |
* .. then assume worst case scenario |
* R1 is OK for inverse <=> CONDR1 .LT. DFLOAT(N) |
* R1 is OK for inverse <=> CONDR1 .LT. DBLE(N) |
* more conservative <=> CONDR1 .LT. SQRT(DFLOAT(N)) |
* more conservative <=> CONDR1 .LT. SQRT(DBLE(N)) |
* |
* |
COND_OK = DSQRT(DSQRT(DFLOAT(NR))) |
COND_OK = DSQRT(DSQRT(DBLE(NR))) |
*[TP] COND_OK is a tuning parameter. |
*[TP] COND_OK is a tuning parameter. |
* |
* |
IF ( CONDR1 .LT. COND_OK ) THEN |
IF ( CONDR1 .LT. COND_OK ) THEN |
Line 1521
|
Line 1525
|
CALL ZTRSM('L','U','C','N',NR,NR,CONE,CWORK(2*N+1), |
CALL ZTRSM('L','U','C','N',NR,NR,CONE,CWORK(2*N+1), |
$ N,V,LDV) |
$ N,V,LDV) |
IF ( NR .LT. N ) THEN |
IF ( NR .LT. N ) THEN |
CALL ZLASET('A',N-NR,NR,ZERO,CZERO,V(NR+1,1),LDV) |
CALL ZLASET('A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV) |
CALL ZLASET('A',NR,N-NR,ZERO,CZERO,V(1,NR+1),LDV) |
CALL ZLASET('A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV) |
CALL ZLASET('A',N-NR,N-NR,ZERO,CONE,V(NR+1,NR+1),LDV) |
CALL ZLASET('A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV) |
END IF |
END IF |
CALL ZUNMQR('L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1), |
CALL ZUNMQR('L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1), |
$ V,LDV,CWORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR) |
$ V,LDV,CWORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR) |
Line 1605
|
Line 1609
|
* first QRF. Also, scale the columns to make them unit in |
* first QRF. Also, scale the columns to make them unit in |
* Euclidean norm. This applies to all cases. |
* Euclidean norm. This applies to all cases. |
* |
* |
TEMP1 = DSQRT(DFLOAT(N)) * EPSLN |
TEMP1 = DSQRT(DBLE(N)) * EPSLN |
DO 1972 q = 1, N |
DO 1972 q = 1, N |
DO 972 p = 1, N |
DO 972 p = 1, N |
CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q) |
CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q) |
Line 1635
|
Line 1639
|
$ LDU, CWORK(N+1), LWORK-N, IERR ) |
$ LDU, CWORK(N+1), LWORK-N, IERR ) |
|
|
* The columns of U are normalized. The cost is O(M*N) flops. |
* The columns of U are normalized. The cost is O(M*N) flops. |
TEMP1 = DSQRT(DFLOAT(M)) * EPSLN |
TEMP1 = DSQRT(DBLE(M)) * EPSLN |
DO 1973 p = 1, NR |
DO 1973 p = 1, NR |
XSC = ONE / DZNRM2( M, U(1,p), 1 ) |
XSC = ONE / DZNRM2( M, U(1,p), 1 ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
Line 1684
|
Line 1688
|
DO 6972 p = 1, N |
DO 6972 p = 1, N |
CALL ZCOPY( N, CWORK(N+p), N, V(IWORK(p),1), LDV ) |
CALL ZCOPY( N, CWORK(N+p), N, V(IWORK(p),1), LDV ) |
6972 CONTINUE |
6972 CONTINUE |
TEMP1 = DSQRT(DFLOAT(N))*EPSLN |
TEMP1 = DSQRT(DBLE(N))*EPSLN |
DO 6971 p = 1, N |
DO 6971 p = 1, N |
XSC = ONE / DZNRM2( N, V(1,p), 1 ) |
XSC = ONE / DZNRM2( N, V(1,p), 1 ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
Line 1702
|
Line 1706
|
END IF |
END IF |
CALL ZUNMQR( 'Left', 'No Tr', M, N1, N, A, LDA, CWORK, U, |
CALL ZUNMQR( 'Left', 'No Tr', M, N1, N, A, LDA, CWORK, U, |
$ LDU, CWORK(N+1), LWORK-N, IERR ) |
$ LDU, CWORK(N+1), LWORK-N, IERR ) |
TEMP1 = DSQRT(DFLOAT(M))*EPSLN |
TEMP1 = DSQRT(DBLE(M))*EPSLN |
DO 6973 p = 1, N1 |
DO 6973 p = 1, N1 |
XSC = ONE / DZNRM2( M, U(1,p), 1 ) |
XSC = ONE / DZNRM2( M, U(1,p), 1 ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) ) |
Line 1779
|
Line 1783
|
NUMRANK = NINT(RWORK(2)) |
NUMRANK = NINT(RWORK(2)) |
|
|
IF ( NR .LT. N ) THEN |
IF ( NR .LT. N ) THEN |
CALL ZLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV ) |
CALL ZLASET( 'A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV ) |
CALL ZLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV ) |
CALL ZLASET( 'A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV ) |
CALL ZLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV ) |
CALL ZLASET( 'A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV ) |
END IF |
END IF |
|
|
CALL ZUNMQR( 'L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1), |
CALL ZUNMQR( 'L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1), |
Line 1791
|
Line 1795
|
* first QRF. Also, scale the columns to make them unit in |
* first QRF. Also, scale the columns to make them unit in |
* Euclidean norm. This applies to all cases. |
* Euclidean norm. This applies to all cases. |
* |
* |
TEMP1 = DSQRT(DFLOAT(N)) * EPSLN |
TEMP1 = DSQRT(DBLE(N)) * EPSLN |
DO 7972 q = 1, N |
DO 7972 q = 1, N |
DO 8972 p = 1, N |
DO 8972 p = 1, N |
CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q) |
CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q) |
Line 1836
|
Line 1840
|
* Undo scaling, if necessary (and possible) |
* Undo scaling, if necessary (and possible) |
* |
* |
IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN |
IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN |
CALL ZLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR ) |
CALL DLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR ) |
USCAL1 = ONE |
USCAL1 = ONE |
USCAL2 = ONE |
USCAL2 = ONE |
END IF |
END IF |