00001 SUBROUTINE DGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 INTEGER INFO, LDA, LWORK, M, N
00010
00011
00012 INTEGER JPVT( * )
00013 DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 INTEGER INB, INBMIN, IXOVER
00092 PARAMETER ( INB = 1, INBMIN = 2, IXOVER = 3 )
00093
00094
00095 LOGICAL LQUERY
00096 INTEGER FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,
00097 $ NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN
00098
00099
00100 EXTERNAL DGEQRF, DLAQP2, DLAQPS, DORMQR, DSWAP, XERBLA
00101
00102
00103 INTEGER ILAENV
00104 DOUBLE PRECISION DNRM2
00105 EXTERNAL ILAENV, DNRM2
00106
00107
00108 INTRINSIC INT, MAX, MIN
00109
00110
00111
00112
00113
00114
00115 INFO = 0
00116 LQUERY = ( LWORK.EQ.-1 )
00117 IF( M.LT.0 ) THEN
00118 INFO = -1
00119 ELSE IF( N.LT.0 ) THEN
00120 INFO = -2
00121 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00122 INFO = -4
00123 END IF
00124
00125 IF( INFO.EQ.0 ) THEN
00126 MINMN = MIN( M, N )
00127 IF( MINMN.EQ.0 ) THEN
00128 IWS = 1
00129 LWKOPT = 1
00130 ELSE
00131 IWS = 3*N + 1
00132 NB = ILAENV( INB, 'DGEQRF', ' ', M, N, -1, -1 )
00133 LWKOPT = 2*N + ( N + 1 )*NB
00134 END IF
00135 WORK( 1 ) = LWKOPT
00136
00137 IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
00138 INFO = -8
00139 END IF
00140 END IF
00141
00142 IF( INFO.NE.0 ) THEN
00143 CALL XERBLA( 'DGEQP3', -INFO )
00144 RETURN
00145 ELSE IF( LQUERY ) THEN
00146 RETURN
00147 END IF
00148
00149
00150
00151 IF( MINMN.EQ.0 ) THEN
00152 RETURN
00153 END IF
00154
00155
00156
00157 NFXD = 1
00158 DO 10 J = 1, N
00159 IF( JPVT( J ).NE.0 ) THEN
00160 IF( J.NE.NFXD ) THEN
00161 CALL DSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
00162 JPVT( J ) = JPVT( NFXD )
00163 JPVT( NFXD ) = J
00164 ELSE
00165 JPVT( J ) = J
00166 END IF
00167 NFXD = NFXD + 1
00168 ELSE
00169 JPVT( J ) = J
00170 END IF
00171 10 CONTINUE
00172 NFXD = NFXD - 1
00173
00174
00175
00176
00177
00178
00179
00180 IF( NFXD.GT.0 ) THEN
00181 NA = MIN( M, NFXD )
00182
00183 CALL DGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
00184 IWS = MAX( IWS, INT( WORK( 1 ) ) )
00185 IF( NA.LT.N ) THEN
00186
00187
00188 CALL DORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,
00189 $ A( 1, NA+1 ), LDA, WORK, LWORK, INFO )
00190 IWS = MAX( IWS, INT( WORK( 1 ) ) )
00191 END IF
00192 END IF
00193
00194
00195
00196
00197 IF( NFXD.LT.MINMN ) THEN
00198
00199 SM = M - NFXD
00200 SN = N - NFXD
00201 SMINMN = MINMN - NFXD
00202
00203
00204
00205 NB = ILAENV( INB, 'DGEQRF', ' ', SM, SN, -1, -1 )
00206 NBMIN = 2
00207 NX = 0
00208
00209 IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
00210
00211
00212
00213 NX = MAX( 0, ILAENV( IXOVER, 'DGEQRF', ' ', SM, SN, -1,
00214 $ -1 ) )
00215
00216
00217 IF( NX.LT.SMINMN ) THEN
00218
00219
00220
00221 MINWS = 2*SN + ( SN+1 )*NB
00222 IWS = MAX( IWS, MINWS )
00223 IF( LWORK.LT.MINWS ) THEN
00224
00225
00226
00227
00228 NB = ( LWORK-2*SN ) / ( SN+1 )
00229 NBMIN = MAX( 2, ILAENV( INBMIN, 'DGEQRF', ' ', SM, SN,
00230 $ -1, -1 ) )
00231
00232
00233 END IF
00234 END IF
00235 END IF
00236
00237
00238
00239
00240 DO 20 J = NFXD + 1, N
00241 WORK( J ) = DNRM2( SM, A( NFXD+1, J ), 1 )
00242 WORK( N+J ) = WORK( J )
00243 20 CONTINUE
00244
00245 IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
00246 $ ( NX.LT.SMINMN ) ) THEN
00247
00248
00249
00250 J = NFXD + 1
00251
00252
00253
00254
00255 TOPBMN = MINMN - NX
00256 30 CONTINUE
00257 IF( J.LE.TOPBMN ) THEN
00258 JB = MIN( NB, TOPBMN-J+1 )
00259
00260
00261
00262 CALL DLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
00263 $ JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),
00264 $ WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )
00265
00266 J = J + FJB
00267 GO TO 30
00268 END IF
00269 ELSE
00270 J = NFXD + 1
00271 END IF
00272
00273
00274
00275
00276 IF( J.LE.MINMN )
00277 $ CALL DLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
00278 $ TAU( J ), WORK( J ), WORK( N+J ),
00279 $ WORK( 2*N+1 ) )
00280
00281 END IF
00282
00283 WORK( 1 ) = IWS
00284 RETURN
00285
00286
00287
00288 END