1*> \brief \b DORGBR 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download DORGBR + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgbr.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgbr.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgbr.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) 22* 23* .. Scalar Arguments .. 24* CHARACTER VECT 25* INTEGER INFO, K, LDA, LWORK, M, N 26* .. 27* .. Array Arguments .. 28* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) 29* .. 30* 31* 32*> \par Purpose: 33* ============= 34*> 35*> \verbatim 36*> 37*> DORGBR generates one of the real orthogonal matrices Q or P**T 38*> determined by DGEBRD when reducing a real matrix A to bidiagonal 39*> form: A = Q * B * P**T. Q and P**T are defined as products of 40*> elementary reflectors H(i) or G(i) respectively. 41*> 42*> If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q 43*> is of order M: 44*> if m >= k, Q = H(1) H(2) . . . H(k) and DORGBR returns the first n 45*> columns of Q, where m >= n >= k; 46*> if m < k, Q = H(1) H(2) . . . H(m-1) and DORGBR returns Q as an 47*> M-by-M matrix. 48*> 49*> If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T 50*> is of order N: 51*> if k < n, P**T = G(k) . . . G(2) G(1) and DORGBR returns the first m 52*> rows of P**T, where n >= m >= k; 53*> if k >= n, P**T = G(n-1) . . . G(2) G(1) and DORGBR returns P**T as 54*> an N-by-N matrix. 55*> \endverbatim 56* 57* Arguments: 58* ========== 59* 60*> \param[in] VECT 61*> \verbatim 62*> VECT is CHARACTER*1 63*> Specifies whether the matrix Q or the matrix P**T is 64*> required, as defined in the transformation applied by DGEBRD: 65*> = 'Q': generate Q; 66*> = 'P': generate P**T. 67*> \endverbatim 68*> 69*> \param[in] M 70*> \verbatim 71*> M is INTEGER 72*> The number of rows of the matrix Q or P**T to be returned. 73*> M >= 0. 74*> \endverbatim 75*> 76*> \param[in] N 77*> \verbatim 78*> N is INTEGER 79*> The number of columns of the matrix Q or P**T to be returned. 80*> N >= 0. 81*> If VECT = 'Q', M >= N >= min(M,K); 82*> if VECT = 'P', N >= M >= min(N,K). 83*> \endverbatim 84*> 85*> \param[in] K 86*> \verbatim 87*> K is INTEGER 88*> If VECT = 'Q', the number of columns in the original M-by-K 89*> matrix reduced by DGEBRD. 90*> If VECT = 'P', the number of rows in the original K-by-N 91*> matrix reduced by DGEBRD. 92*> K >= 0. 93*> \endverbatim 94*> 95*> \param[in,out] A 96*> \verbatim 97*> A is DOUBLE PRECISION array, dimension (LDA,N) 98*> On entry, the vectors which define the elementary reflectors, 99*> as returned by DGEBRD. 100*> On exit, the M-by-N matrix Q or P**T. 101*> \endverbatim 102*> 103*> \param[in] LDA 104*> \verbatim 105*> LDA is INTEGER 106*> The leading dimension of the array A. LDA >= max(1,M). 107*> \endverbatim 108*> 109*> \param[in] TAU 110*> \verbatim 111*> TAU is DOUBLE PRECISION array, dimension 112*> (min(M,K)) if VECT = 'Q' 113*> (min(N,K)) if VECT = 'P' 114*> TAU(i) must contain the scalar factor of the elementary 115*> reflector H(i) or G(i), which determines Q or P**T, as 116*> returned by DGEBRD in its array argument TAUQ or TAUP. 117*> \endverbatim 118*> 119*> \param[out] WORK 120*> \verbatim 121*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) 122*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 123*> \endverbatim 124*> 125*> \param[in] LWORK 126*> \verbatim 127*> LWORK is INTEGER 128*> The dimension of the array WORK. LWORK >= max(1,min(M,N)). 129*> For optimum performance LWORK >= min(M,N)*NB, where NB 130*> is the optimal blocksize. 131*> 132*> If LWORK = -1, then a workspace query is assumed; the routine 133*> only calculates the optimal size of the WORK array, returns 134*> this value as the first entry of the WORK array, and no error 135*> message related to LWORK is issued by XERBLA. 136*> \endverbatim 137*> 138*> \param[out] INFO 139*> \verbatim 140*> INFO is INTEGER 141*> = 0: successful exit 142*> < 0: if INFO = -i, the i-th argument had an illegal value 143*> \endverbatim 144* 145* Authors: 146* ======== 147* 148*> \author Univ. of Tennessee 149*> \author Univ. of California Berkeley 150*> \author Univ. of Colorado Denver 151*> \author NAG Ltd. 152* 153*> \ingroup doubleGBcomputational 154* 155* ===================================================================== 156 SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) 157* 158* -- LAPACK computational routine -- 159* -- LAPACK is a software package provided by Univ. of Tennessee, -- 160* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 161* 162* .. Scalar Arguments .. 163 CHARACTER VECT 164 INTEGER INFO, K, LDA, LWORK, M, N 165* .. 166* .. Array Arguments .. 167 DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) 168* .. 169* 170* ===================================================================== 171* 172* .. Parameters .. 173 DOUBLE PRECISION ZERO, ONE 174 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) 175* .. 176* .. Local Scalars .. 177 LOGICAL LQUERY, WANTQ 178 INTEGER I, IINFO, J, LWKOPT, MN 179* .. 180* .. External Functions .. 181 LOGICAL LSAME 182 EXTERNAL LSAME 183* .. 184* .. External Subroutines .. 185 EXTERNAL DORGLQ, DORGQR, XERBLA 186* .. 187* .. Intrinsic Functions .. 188 INTRINSIC MAX, MIN 189* .. 190* .. Executable Statements .. 191* 192* Test the input arguments 193* 194 INFO = 0 195 WANTQ = LSAME( VECT, 'Q' ) 196 MN = MIN( M, N ) 197 LQUERY = ( LWORK.EQ.-1 ) 198 IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN 199 INFO = -1 200 ELSE IF( M.LT.0 ) THEN 201 INFO = -2 202 ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M, 203 $ K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT. 204 $ MIN( N, K ) ) ) ) THEN 205 INFO = -3 206 ELSE IF( K.LT.0 ) THEN 207 INFO = -4 208 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN 209 INFO = -6 210 ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THEN 211 INFO = -9 212 END IF 213* 214 IF( INFO.EQ.0 ) THEN 215 WORK( 1 ) = 1 216 IF( WANTQ ) THEN 217 IF( M.GE.K ) THEN 218 CALL DORGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO ) 219 ELSE 220 IF( M.GT.1 ) THEN 221 CALL DORGQR( M-1, M-1, M-1, A, LDA, TAU, WORK, -1, 222 $ IINFO ) 223 END IF 224 END IF 225 ELSE 226 IF( K.LT.N ) THEN 227 CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO ) 228 ELSE 229 IF( N.GT.1 ) THEN 230 CALL DORGLQ( N-1, N-1, N-1, A, LDA, TAU, WORK, -1, 231 $ IINFO ) 232 END IF 233 END IF 234 END IF 235 LWKOPT = WORK( 1 ) 236 LWKOPT = MAX (LWKOPT, MN) 237 END IF 238* 239 IF( INFO.NE.0 ) THEN 240 CALL XERBLA( 'DORGBR', -INFO ) 241 RETURN 242 ELSE IF( LQUERY ) THEN 243 WORK( 1 ) = LWKOPT 244 RETURN 245 END IF 246* 247* Quick return if possible 248* 249 IF( M.EQ.0 .OR. N.EQ.0 ) THEN 250 WORK( 1 ) = 1 251 RETURN 252 END IF 253* 254 IF( WANTQ ) THEN 255* 256* Form Q, determined by a call to DGEBRD to reduce an m-by-k 257* matrix 258* 259 IF( M.GE.K ) THEN 260* 261* If m >= k, assume m >= n >= k 262* 263 CALL DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO ) 264* 265 ELSE 266* 267* If m < k, assume m = n 268* 269* Shift the vectors which define the elementary reflectors one 270* column to the right, and set the first row and column of Q 271* to those of the unit matrix 272* 273 DO 20 J = M, 2, -1 274 A( 1, J ) = ZERO 275 DO 10 I = J + 1, M 276 A( I, J ) = A( I, J-1 ) 277 10 CONTINUE 278 20 CONTINUE 279 A( 1, 1 ) = ONE 280 DO 30 I = 2, M 281 A( I, 1 ) = ZERO 282 30 CONTINUE 283 IF( M.GT.1 ) THEN 284* 285* Form Q(2:m,2:m) 286* 287 CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK, 288 $ LWORK, IINFO ) 289 END IF 290 END IF 291 ELSE 292* 293* Form P**T, determined by a call to DGEBRD to reduce a k-by-n 294* matrix 295* 296 IF( K.LT.N ) THEN 297* 298* If k < n, assume k <= m <= n 299* 300 CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO ) 301* 302 ELSE 303* 304* If k >= n, assume m = n 305* 306* Shift the vectors which define the elementary reflectors one 307* row downward, and set the first row and column of P**T to 308* those of the unit matrix 309* 310 A( 1, 1 ) = ONE 311 DO 40 I = 2, N 312 A( I, 1 ) = ZERO 313 40 CONTINUE 314 DO 60 J = 2, N 315 DO 50 I = J - 1, 2, -1 316 A( I, J ) = A( I-1, J ) 317 50 CONTINUE 318 A( 1, J ) = ZERO 319 60 CONTINUE 320 IF( N.GT.1 ) THEN 321* 322* Form P**T(2:n,2:n) 323* 324 CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK, 325 $ LWORK, IINFO ) 326 END IF 327 END IF 328 END IF 329 WORK( 1 ) = LWKOPT 330 RETURN 331* 332* End of DORGBR 333* 334 END 335