191 SUBROUTINE dggglm( N, M, P, A, LDA, B, LDB, D, X, Y, WORK,
200 INTEGER INFO, LDA, LDB, LWORK, M, N, P
203 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), D( * ), WORK( * ),
210 DOUBLE PRECISION ZERO, ONE
211 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
215 INTEGER I, LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3,
228 INTRINSIC int, max, min
236 lquery = ( lwork.EQ.-1 )
239 ELSE IF( m.LT.0 .OR. m.GT.n )
THEN
241 ELSE IF( p.LT.0 .OR. p.LT.n-m )
THEN
243 ELSE IF( lda.LT.max( 1, n ) )
THEN
245 ELSE IF( ldb.LT.max( 1, n ) )
THEN
256 nb1 = ilaenv( 1,
'DGEQRF',
' ', n, m, -1, -1 )
257 nb2 = ilaenv( 1,
'DGERQF',
' ', n, m, -1, -1 )
258 nb3 = ilaenv( 1,
'DORMQR',
' ', n, m, p, -1 )
259 nb4 = ilaenv( 1,
'DORMRQ',
' ', n, m, p, -1 )
260 nb = max( nb1, nb2, nb3, nb4 )
262 lwkopt = m + np + max( n, p )*nb
266 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
272 CALL xerbla(
'DGGGLM', -info )
274 ELSE IF( lquery )
THEN
299 CALL dggqrf( n, m, p, a, lda, work, b, ldb, work( m+1 ),
300 $ work( m+np+1 ), lwork-m-np, info )
301 lopt = int( work( m+np+1 ) )
306 CALL dormqr(
'Left',
'Transpose', n, 1, m, a, lda, work, d,
307 $ max( 1, n ), work( m+np+1 ), lwork-m-np, info )
308 lopt = max( lopt, int( work( m+np+1 ) ) )
313 CALL dtrtrs(
'Upper',
'No transpose',
'Non unit', n-m, 1,
314 $ b( m+1, m+p-n+1 ), ldb, d( m+1 ), n-m, info )
321 CALL dcopy( n-m, d( m+1 ), 1, y( m+p-n+1 ), 1 )
326 DO 10 i = 1, m + p - n
332 CALL dgemv(
'No transpose', m, n-m, -one, b( 1, m+p-n+1 ), ldb,
333 $ y( m+p-n+1 ), 1, one, d, 1 )
338 CALL dtrtrs(
'Upper',
'No Transpose',
'Non unit', m, 1, a,
349 CALL dcopy( m, d, 1, x, 1 )
354 CALL dormrq(
'Left',
'Transpose', p, 1, np,
355 $ b( max( 1, n-p+1 ), 1 ), ldb, work( m+1 ), y,
356 $ max( 1, p ), work( m+np+1 ), lwork-m-np, info )
357 work( 1 ) = m + np + max( lopt, int( work( m+np+1 ) ) )
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dggglm(n, m, p, a, lda, b, ldb, d, x, y, work, lwork, info)
DGGGLM
subroutine dggqrf(n, m, p, a, lda, taua, b, ldb, taub, work, lwork, info)
DGGQRF
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR
subroutine dormrq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMRQ