00001 SUBROUTINE SGEQP3( 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 REAL 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 SGEQRF, SLAQP2, SLAQPS, SORMQR, SSWAP, XERBLA
00101
00102
00103 INTEGER ILAENV
00104 REAL SNRM2
00105 EXTERNAL ILAENV, SNRM2
00106
00107
00108 INTRINSIC INT, MAX, MIN
00109
00110
00111
00112 INFO = 0
00113 LQUERY = ( LWORK.EQ.-1 )
00114 IF( M.LT.0 ) THEN
00115 INFO = -1
00116 ELSE IF( N.LT.0 ) THEN
00117 INFO = -2
00118 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00119 INFO = -4
00120 END IF
00121
00122 IF( INFO.EQ.0 ) THEN
00123 MINMN = MIN( M, N )
00124 IF( MINMN.EQ.0 ) THEN
00125 IWS = 1
00126 LWKOPT = 1
00127 ELSE
00128 IWS = 3*N + 1
00129 NB = ILAENV( INB, 'SGEQRF', ' ', M, N, -1, -1 )
00130 LWKOPT = 2*N + ( N + 1 )*NB
00131 END IF
00132 WORK( 1 ) = LWKOPT
00133
00134 IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
00135 INFO = -8
00136 END IF
00137 END IF
00138
00139 IF( INFO.NE.0 ) THEN
00140 CALL XERBLA( 'SGEQP3', -INFO )
00141 RETURN
00142 ELSE IF( LQUERY ) THEN
00143 RETURN
00144 END IF
00145
00146
00147
00148 IF( MINMN.EQ.0 ) THEN
00149 RETURN
00150 END IF
00151
00152
00153
00154 NFXD = 1
00155 DO 10 J = 1, N
00156 IF( JPVT( J ).NE.0 ) THEN
00157 IF( J.NE.NFXD ) THEN
00158 CALL SSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )
00159 JPVT( J ) = JPVT( NFXD )
00160 JPVT( NFXD ) = J
00161 ELSE
00162 JPVT( J ) = J
00163 END IF
00164 NFXD = NFXD + 1
00165 ELSE
00166 JPVT( J ) = J
00167 END IF
00168 10 CONTINUE
00169 NFXD = NFXD - 1
00170
00171
00172
00173
00174
00175
00176
00177 IF( NFXD.GT.0 ) THEN
00178 NA = MIN( M, NFXD )
00179
00180 CALL SGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )
00181 IWS = MAX( IWS, INT( WORK( 1 ) ) )
00182 IF( NA.LT.N ) THEN
00183
00184
00185 CALL SORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,
00186 $ A( 1, NA+1 ), LDA, WORK, LWORK, INFO )
00187 IWS = MAX( IWS, INT( WORK( 1 ) ) )
00188 END IF
00189 END IF
00190
00191
00192
00193
00194 IF( NFXD.LT.MINMN ) THEN
00195
00196 SM = M - NFXD
00197 SN = N - NFXD
00198 SMINMN = MINMN - NFXD
00199
00200
00201
00202 NB = ILAENV( INB, 'SGEQRF', ' ', SM, SN, -1, -1 )
00203 NBMIN = 2
00204 NX = 0
00205
00206 IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN
00207
00208
00209
00210 NX = MAX( 0, ILAENV( IXOVER, 'SGEQRF', ' ', SM, SN, -1,
00211 $ -1 ) )
00212
00213
00214 IF( NX.LT.SMINMN ) THEN
00215
00216
00217
00218 MINWS = 2*SN + ( SN+1 )*NB
00219 IWS = MAX( IWS, MINWS )
00220 IF( LWORK.LT.MINWS ) THEN
00221
00222
00223
00224
00225 NB = ( LWORK-2*SN ) / ( SN+1 )
00226 NBMIN = MAX( 2, ILAENV( INBMIN, 'SGEQRF', ' ', SM, SN,
00227 $ -1, -1 ) )
00228
00229
00230 END IF
00231 END IF
00232 END IF
00233
00234
00235
00236
00237 DO 20 J = NFXD + 1, N
00238 WORK( J ) = SNRM2( SM, A( NFXD+1, J ), 1 )
00239 WORK( N+J ) = WORK( J )
00240 20 CONTINUE
00241
00242 IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.
00243 $ ( NX.LT.SMINMN ) ) THEN
00244
00245
00246
00247 J = NFXD + 1
00248
00249
00250
00251
00252 TOPBMN = MINMN - NX
00253 30 CONTINUE
00254 IF( J.LE.TOPBMN ) THEN
00255 JB = MIN( NB, TOPBMN-J+1 )
00256
00257
00258
00259 CALL SLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,
00260 $ JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),
00261 $ WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )
00262
00263 J = J + FJB
00264 GO TO 30
00265 END IF
00266 ELSE
00267 J = NFXD + 1
00268 END IF
00269
00270
00271
00272
00273 IF( J.LE.MINMN )
00274 $ CALL SLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),
00275 $ TAU( J ), WORK( J ), WORK( N+J ),
00276 $ WORK( 2*N+1 ) )
00277
00278 END IF
00279
00280 WORK( 1 ) = IWS
00281 RETURN
00282
00283
00284
00285 END