193
194
195
196
197
198
199 CHARACTER VECT
200 INTEGER INFO, KL, KU, LDAB, LDC, LDPT, LDQ, M, N, NCC
201
202
203 DOUBLE PRECISION D( * ), E( * ), RWORK( * )
204 COMPLEX*16 AB( LDAB, * ), C( LDC, * ), PT( LDPT, * ),
205 $ Q( LDQ, * ), WORK( * )
206
207
208
209
210
211 DOUBLE PRECISION ZERO
212 parameter( zero = 0.0d+0 )
213 COMPLEX*16 CZERO, CONE
214 parameter( czero = ( 0.0d+0, 0.0d+0 ),
215 $ cone = ( 1.0d+0, 0.0d+0 ) )
216
217
218 LOGICAL WANTB, WANTC, WANTPT, WANTQ
219 INTEGER I, INCA, J, J1, J2, KB, KB1, KK, KLM, KLU1,
220 $ KUN, L, MINMN, ML, ML0, MU, MU0, NR, NRT
221 DOUBLE PRECISION ABST, RC
222 COMPLEX*16 RA, RB, RS, T
223
224
227
228
229 INTRINSIC abs, dconjg, max, min
230
231
232 LOGICAL LSAME
234
235
236
237
238
239 wantb =
lsame( vect,
'B' )
240 wantq =
lsame( vect,
'Q' ) .OR. wantb
241 wantpt =
lsame( vect,
'P' ) .OR. wantb
242 wantc = ncc.GT.0
243 klu1 = kl + ku + 1
244 info = 0
245 IF( .NOT.wantq .AND. .NOT.wantpt .AND. .NOT.
lsame( vect,
'N' ) )
246 $ THEN
247 info = -1
248 ELSE IF( m.LT.0 ) THEN
249 info = -2
250 ELSE IF( n.LT.0 ) THEN
251 info = -3
252 ELSE IF( ncc.LT.0 ) THEN
253 info = -4
254 ELSE IF( kl.LT.0 ) THEN
255 info = -5
256 ELSE IF( ku.LT.0 ) THEN
257 info = -6
258 ELSE IF( ldab.LT.klu1 ) THEN
259 info = -8
260 ELSE IF( ldq.LT.1 .OR. wantq .AND. ldq.LT.max( 1, m ) ) THEN
261 info = -12
262 ELSE IF( ldpt.LT.1 .OR. wantpt .AND. ldpt.LT.max( 1, n ) ) THEN
263 info = -14
264 ELSE IF( ldc.LT.1 .OR. wantc .AND. ldc.LT.max( 1, m ) ) THEN
265 info = -16
266 END IF
267 IF( info.NE.0 ) THEN
268 CALL xerbla(
'ZGBBRD', -info )
269 RETURN
270 END IF
271
272
273
274 IF( wantq )
275 $
CALL zlaset(
'Full', m, m, czero, cone, q, ldq )
276 IF( wantpt )
277 $
CALL zlaset(
'Full', n, n, czero, cone, pt, ldpt )
278
279
280
281 IF( m.EQ.0 .OR. n.EQ.0 )
282 $ RETURN
283
284 minmn = min( m, n )
285
286 IF( kl+ku.GT.1 ) THEN
287
288
289
290
291
292 IF( ku.GT.0 ) THEN
293 ml0 = 1
294 mu0 = 2
295 ELSE
296 ml0 = 2
297 mu0 = 1
298 END IF
299
300
301
302
303
304
305
306 klm = min( m-1, kl )
307 kun = min( n-1, ku )
308 kb = klm + kun
309 kb1 = kb + 1
310 inca = kb1*ldab
311 nr = 0
312 j1 = klm + 2
313 j2 = 1 - kun
314
315 DO 90 i = 1, minmn
316
317
318
319 ml = klm + 1
320 mu = kun + 1
321 DO 80 kk = 1, kb
322 j1 = j1 + kb
323 j2 = j2 + kb
324
325
326
327
328 IF( nr.GT.0 )
329 $
CALL zlargv( nr, ab( klu1, j1-klm-1 ), inca,
330 $ work( j1 ), kb1, rwork( j1 ), kb1 )
331
332
333
334 DO 10 l = 1, kb
335 IF( j2-klm+l-1.GT.n ) THEN
336 nrt = nr - 1
337 ELSE
338 nrt = nr
339 END IF
340 IF( nrt.GT.0 )
341 $
CALL zlartv( nrt, ab( klu1-l, j1-klm+l-1 ), inca,
342 $ ab( klu1-l+1, j1-klm+l-1 ), inca,
343 $ rwork( j1 ), work( j1 ), kb1 )
344 10 CONTINUE
345
346 IF( ml.GT.ml0 ) THEN
347 IF( ml.LE.m-i+1 ) THEN
348
349
350
351
352 CALL zlartg( ab( ku+ml-1, i ), ab( ku+ml, i ),
353 $ rwork( i+ml-1 ), work( i+ml-1 ), ra )
354 ab( ku+ml-1, i ) = ra
355 IF( i.LT.n )
356 $
CALL zrot( min( ku+ml-2, n-i ),
357 $ ab( ku+ml-2, i+1 ), ldab-1,
358 $ ab( ku+ml-1, i+1 ), ldab-1,
359 $ rwork( i+ml-1 ), work( i+ml-1 ) )
360 END IF
361 nr = nr + 1
362 j1 = j1 - kb1
363 END IF
364
365 IF( wantq ) THEN
366
367
368
369 DO 20 j = j1, j2, kb1
370 CALL zrot( m, q( 1, j-1 ), 1, q( 1, j ), 1,
371 $ rwork( j ), dconjg( work( j ) ) )
372 20 CONTINUE
373 END IF
374
375 IF( wantc ) THEN
376
377
378
379 DO 30 j = j1, j2, kb1
380 CALL zrot( ncc, c( j-1, 1 ), ldc, c( j, 1 ), ldc,
381 $ rwork( j ), work( j ) )
382 30 CONTINUE
383 END IF
384
385 IF( j2+kun.GT.n ) THEN
386
387
388
389 nr = nr - 1
390 j2 = j2 - kb1
391 END IF
392
393 DO 40 j = j1, j2, kb1
394
395
396
397
398 work( j+kun ) = work( j )*ab( 1, j+kun )
399 ab( 1, j+kun ) = rwork( j )*ab( 1, j+kun )
400 40 CONTINUE
401
402
403
404
405 IF( nr.GT.0 )
406 $
CALL zlargv( nr, ab( 1, j1+kun-1 ), inca,
407 $ work( j1+kun ), kb1, rwork( j1+kun ),
408 $ kb1 )
409
410
411
412 DO 50 l = 1, kb
413 IF( j2+l-1.GT.m ) THEN
414 nrt = nr - 1
415 ELSE
416 nrt = nr
417 END IF
418 IF( nrt.GT.0 )
419 $
CALL zlartv( nrt, ab( l+1, j1+kun-1 ), inca,
420 $ ab( l, j1+kun ), inca,
421 $ rwork( j1+kun ), work( j1+kun ), kb1 )
422 50 CONTINUE
423
424 IF( ml.EQ.ml0 .AND. mu.GT.mu0 ) THEN
425 IF( mu.LE.n-i+1 ) THEN
426
427
428
429
430 CALL zlartg( ab( ku-mu+3, i+mu-2 ),
431 $ ab( ku-mu+2, i+mu-1 ),
432 $ rwork( i+mu-1 ), work( i+mu-1 ), ra )
433 ab( ku-mu+3, i+mu-2 ) = ra
434 CALL zrot( min( kl+mu-2, m-i ),
435 $ ab( ku-mu+4, i+mu-2 ), 1,
436 $ ab( ku-mu+3, i+mu-1 ), 1,
437 $ rwork( i+mu-1 ), work( i+mu-1 ) )
438 END IF
439 nr = nr + 1
440 j1 = j1 - kb1
441 END IF
442
443 IF( wantpt ) THEN
444
445
446
447 DO 60 j = j1, j2, kb1
448 CALL zrot( n, pt( j+kun-1, 1 ), ldpt,
449 $ pt( j+kun, 1 ), ldpt, rwork( j+kun ),
450 $ dconjg( work( j+kun ) ) )
451 60 CONTINUE
452 END IF
453
454 IF( j2+kb.GT.m ) THEN
455
456
457
458 nr = nr - 1
459 j2 = j2 - kb1
460 END IF
461
462 DO 70 j = j1, j2, kb1
463
464
465
466
467 work( j+kb ) = work( j+kun )*ab( klu1, j+kun )
468 ab( klu1, j+kun ) = rwork( j+kun )*ab( klu1, j+kun )
469 70 CONTINUE
470
471 IF( ml.GT.ml0 ) THEN
472 ml = ml - 1
473 ELSE
474 mu = mu - 1
475 END IF
476 80 CONTINUE
477 90 CONTINUE
478 END IF
479
480 IF( ku.EQ.0 .AND. kl.GT.0 ) THEN
481
482
483
484
485
486
487
488 DO 100 i = 1, min( m-1, n )
489 CALL zlartg( ab( 1, i ), ab( 2, i ), rc, rs, ra )
490 ab( 1, i ) = ra
491 IF( i.LT.n ) THEN
492 ab( 2, i ) = rs*ab( 1, i+1 )
493 ab( 1, i+1 ) = rc*ab( 1, i+1 )
494 END IF
495 IF( wantq )
496 $
CALL zrot( m, q( 1, i ), 1, q( 1, i+1 ), 1, rc,
497 $ dconjg( rs ) )
498 IF( wantc )
499 $
CALL zrot( ncc, c( i, 1 ), ldc, c( i+1, 1 ), ldc, rc,
500 $ rs )
501 100 CONTINUE
502 ELSE
503
504
505
506
507 IF( ku.GT.0 .AND. m.LT.n ) THEN
508
509
510
511
512 rb = ab( ku, m+1 )
513 DO 110 i = m, 1, -1
514 CALL zlartg( ab( ku+1, i ), rb, rc, rs, ra )
515 ab( ku+1, i ) = ra
516 IF( i.GT.1 ) THEN
517 rb = -dconjg( rs )*ab( ku, i )
518 ab( ku, i ) = rc*ab( ku, i )
519 END IF
520 IF( wantpt )
521 $
CALL zrot( n, pt( i, 1 ), ldpt, pt( m+1, 1 ), ldpt,
522 $ rc, dconjg( rs ) )
523 110 CONTINUE
524 END IF
525 END IF
526
527
528
529
530 t = ab( ku+1, 1 )
531 DO 120 i = 1, minmn
532 abst = abs( t )
533 d( i ) = abst
534 IF( abst.NE.zero ) THEN
535 t = t / abst
536 ELSE
537 t = cone
538 END IF
539 IF( wantq )
540 $
CALL zscal( m, t, q( 1, i ), 1 )
541 IF( wantc )
542 $
CALL zscal( ncc, dconjg( t ), c( i, 1 ), ldc )
543 IF( i.LT.minmn ) THEN
544 IF( ku.EQ.0 .AND. kl.EQ.0 ) THEN
545 e( i ) = zero
546 t = ab( 1, i+1 )
547 ELSE
548 IF( ku.EQ.0 ) THEN
549 t = ab( 2, i )*dconjg( t )
550 ELSE
551 t = ab( ku, i+1 )*dconjg( t )
552 END IF
553 abst = abs( t )
554 e( i ) = abst
555 IF( abst.NE.zero ) THEN
556 t = t / abst
557 ELSE
558 t = cone
559 END IF
560 IF( wantpt )
561 $
CALL zscal( n, t, pt( i+1, 1 ), ldpt )
562 t = ab( ku+1, i+1 )*dconjg( t )
563 END IF
564 END IF
565 120 CONTINUE
566 RETURN
567
568
569
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
subroutine xerbla(SRNAME, INFO)
XERBLA
logical function lsame(CA, CB)
LSAME
subroutine zscal(N, ZA, ZX, INCX)
ZSCAL
subroutine zrot(N, CX, INCX, CY, INCY, C, S)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zlartv(N, X, INCX, Y, INCY, C, S, INCC)
ZLARTV applies a vector of plane rotations with real cosines and complex sines to the elements of a p...
subroutine zlargv(N, X, INCX, Y, INCY, C, INCC)
ZLARGV generates a vector of plane rotations with real cosines and complex sines.