252 SUBROUTINE zuncsd2by1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11,
253 $ X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T,
254 $ LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK,
262 CHARACTER JOBU1, JOBU2, JOBV1T
263 INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21,
265 INTEGER LRWORK, LRWORKMIN, LRWORKOPT
268 DOUBLE PRECISION RWORK(*)
269 DOUBLE PRECISION THETA(*)
270 COMPLEX*16 U1(ldu1,*), U2(ldu2,*), V1T(ldv1t,*), WORK(*),
271 $ x11(ldx11,*), x21(ldx21,*)
279 parameter( one = (1.0d0,0.0d0), zero = (0.0d0,0.0d0) )
282 INTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E,
283 $ ib21d, ib21e, ib22d, ib22e, ibbcsd, iorbdb,
284 $ iorglq, iorgqr, iphi, itaup1, itaup2, itauq1,
285 $ j, lbbcsd, lorbdb, lorglq, lorglqmin,
286 $ lorglqopt, lorgqr, lorgqrmin, lorgqropt,
287 $ lworkmin, lworkopt, r
288 LOGICAL LQUERY, WANTU1, WANTU2, WANTV1T
291 DOUBLE PRECISION DUM( 1 )
292 COMPLEX*16 CDUM( 1, 1 )
304 INTRINSIC int, max, min
311 wantu1 = lsame( jobu1,
'Y' )
312 wantu2 = lsame( jobu2,
'Y' )
313 wantv1t = lsame( jobv1t,
'Y' )
314 lquery = ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 )
318 ELSE IF( p .LT. 0 .OR. p .GT. m )
THEN 320 ELSE IF( q .LT. 0 .OR. q .GT. m )
THEN 322 ELSE IF( ldx11 .LT. max( 1, p ) )
THEN 324 ELSE IF( ldx21 .LT. max( 1, m-p ) )
THEN 326 ELSE IF( wantu1 .AND. ldu1 .LT. max( 1, p ) )
THEN 328 ELSE IF( wantu2 .AND. ldu2 .LT. max( 1, m - p ) )
THEN 330 ELSE IF( wantv1t .AND. ldv1t .LT. max( 1, q ) )
THEN 334 r = min( p, m-p, q, m-q )
369 IF( info .EQ. 0 )
THEN 371 ib11d = iphi + max( 1, r-1 )
372 ib11e = ib11d + max( 1, r )
373 ib12d = ib11e + max( 1, r - 1 )
374 ib12e = ib12d + max( 1, r )
375 ib21d = ib12e + max( 1, r - 1 )
376 ib21e = ib21d + max( 1, r )
377 ib22d = ib21e + max( 1, r - 1 )
378 ib22e = ib22d + max( 1, r )
379 ibbcsd = ib22e + max( 1, r - 1 )
381 itaup2 = itaup1 + max( 1, p )
382 itauq1 = itaup2 + max( 1, m-p )
383 iorbdb = itauq1 + max( 1, q )
384 iorgqr = itauq1 + max( 1, q )
385 iorglq = itauq1 + max( 1, q )
391 CALL zunbdb1( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
392 $ cdum, cdum, cdum, work, -1, childinfo )
393 lorbdb = int( work(1) )
394 IF( wantu1 .AND. p .GT. 0 )
THEN 395 CALL zungqr( p, p, q, u1, ldu1, cdum, work(1), -1,
397 lorgqrmin = max( lorgqrmin, p )
398 lorgqropt = max( lorgqropt, int( work(1) ) )
400 IF( wantu2 .AND. m-p .GT. 0 )
THEN 401 CALL zungqr( m-p, m-p, q, u2, ldu2, cdum, work(1), -1,
403 lorgqrmin = max( lorgqrmin, m-p )
404 lorgqropt = max( lorgqropt, int( work(1) ) )
406 IF( wantv1t .AND. q .GT. 0 )
THEN 407 CALL zunglq( q-1, q-1, q-1, v1t, ldv1t,
408 $ cdum, work(1), -1, childinfo )
409 lorglqmin = max( lorglqmin, q-1 )
410 lorglqopt = max( lorglqopt, int( work(1) ) )
412 CALL zbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
413 $ dum, u1, ldu1, u2, ldu2, v1t, ldv1t, cdum, 1,
414 $ dum, dum, dum, dum, dum, dum, dum, dum,
415 $ rwork(1), -1, childinfo )
416 lbbcsd = int( rwork(1) )
417 ELSE IF( r .EQ. p )
THEN 418 CALL zunbdb2( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
419 $ cdum, cdum, cdum, work(1), -1, childinfo )
420 lorbdb = int( work(1) )
421 IF( wantu1 .AND. p .GT. 0 )
THEN 422 CALL zungqr( p-1, p-1, p-1, u1(2,2), ldu1, cdum, work(1),
424 lorgqrmin = max( lorgqrmin, p-1 )
425 lorgqropt = max( lorgqropt, int( work(1) ) )
427 IF( wantu2 .AND. m-p .GT. 0 )
THEN 428 CALL zungqr( m-p, m-p, q, u2, ldu2, cdum, work(1), -1,
430 lorgqrmin = max( lorgqrmin, m-p )
431 lorgqropt = max( lorgqropt, int( work(1) ) )
433 IF( wantv1t .AND. q .GT. 0 )
THEN 434 CALL zunglq( q, q, r, v1t, ldv1t, cdum, work(1), -1,
436 lorglqmin = max( lorglqmin, q )
437 lorglqopt = max( lorglqopt, int( work(1) ) )
439 CALL zbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
440 $ dum, v1t, ldv1t, cdum, 1, u1, ldu1, u2, ldu2,
441 $ dum, dum, dum, dum, dum, dum, dum, dum,
442 $ rwork(1), -1, childinfo )
443 lbbcsd = int( rwork(1) )
444 ELSE IF( r .EQ. m-p )
THEN 445 CALL zunbdb3( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
446 $ cdum, cdum, cdum, work(1), -1, childinfo )
447 lorbdb = int( work(1) )
448 IF( wantu1 .AND. p .GT. 0 )
THEN 449 CALL zungqr( p, p, q, u1, ldu1, cdum, work(1), -1,
451 lorgqrmin = max( lorgqrmin, p )
452 lorgqropt = max( lorgqropt, int( work(1) ) )
454 IF( wantu2 .AND. m-p .GT. 0 )
THEN 455 CALL zungqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2, cdum,
456 $ work(1), -1, childinfo )
457 lorgqrmin = max( lorgqrmin, m-p-1 )
458 lorgqropt = max( lorgqropt, int( work(1) ) )
460 IF( wantv1t .AND. q .GT. 0 )
THEN 461 CALL zunglq( q, q, r, v1t, ldv1t, cdum, work(1), -1,
463 lorglqmin = max( lorglqmin, q )
464 lorglqopt = max( lorglqopt, int( work(1) ) )
466 CALL zbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
467 $ theta, dum, cdum, 1, v1t, ldv1t, u2, ldu2, u1,
468 $ ldu1, dum, dum, dum, dum, dum, dum, dum, dum,
469 $ rwork(1), -1, childinfo )
470 lbbcsd = int( rwork(1) )
472 CALL zunbdb4( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
473 $ cdum, cdum, cdum, cdum, work(1), -1, childinfo
475 lorbdb = m + int( work(1) )
476 IF( wantu1 .AND. p .GT. 0 )
THEN 477 CALL zungqr( p, p, m-q, u1, ldu1, cdum, work(1), -1,
479 lorgqrmin = max( lorgqrmin, p )
480 lorgqropt = max( lorgqropt, int( work(1) ) )
482 IF( wantu2 .AND. m-p .GT. 0 )
THEN 483 CALL zungqr( m-p, m-p, m-q, u2, ldu2, cdum, work(1), -1,
485 lorgqrmin = max( lorgqrmin, m-p )
486 lorgqropt = max( lorgqropt, int( work(1) ) )
488 IF( wantv1t .AND. q .GT. 0 )
THEN 489 CALL zunglq( q, q, q, v1t, ldv1t, cdum, work(1), -1,
491 lorglqmin = max( lorglqmin, q )
492 lorglqopt = max( lorglqopt, int( work(1) ) )
494 CALL zbbcsd( jobu2, jobu1,
'N', jobv1t,
'N', m, m-p, m-q,
495 $ theta, dum, u2, ldu2, u1, ldu1, cdum, 1, v1t,
496 $ ldv1t, dum, dum, dum, dum, dum, dum, dum, dum,
497 $ rwork(1), -1, childinfo )
498 lbbcsd = int( rwork(1) )
500 lrworkmin = ibbcsd+lbbcsd-1
501 lrworkopt = lrworkmin
503 lworkmin = max( iorbdb+lorbdb-1,
504 $ iorgqr+lorgqrmin-1,
505 $ iorglq+lorglqmin-1 )
506 lworkopt = max( iorbdb+lorbdb-1,
507 $ iorgqr+lorgqropt-1,
508 $ iorglq+lorglqopt-1 )
510 IF( lwork .LT. lworkmin .AND. .NOT.lquery )
THEN 513 IF( lrwork .LT. lrworkmin .AND. .NOT.lquery )
THEN 517 IF( info .NE. 0 )
THEN 518 CALL xerbla(
'ZUNCSD2BY1', -info )
520 ELSE IF( lquery )
THEN 523 lorgqr = lwork-iorgqr+1
524 lorglq = lwork-iorglq+1
535 CALL zunbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
536 $ rwork(iphi), work(itaup1), work(itaup2),
537 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
541 IF( wantu1 .AND. p .GT. 0 )
THEN 542 CALL zlacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
543 CALL zungqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
544 $ lorgqr, childinfo )
546 IF( wantu2 .AND. m-p .GT. 0 )
THEN 547 CALL zlacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
548 CALL zungqr( m-p, m-p, q, u2, ldu2, work(itaup2),
549 $ work(iorgqr), lorgqr, childinfo )
551 IF( wantv1t .AND. q .GT. 0 )
THEN 557 CALL zlacpy(
'U', q-1, q-1, x21(1,2), ldx21, v1t(2,2),
559 CALL zunglq( q-1, q-1, q-1, v1t(2,2), ldv1t, work(itauq1),
560 $ work(iorglq), lorglq, childinfo )
565 CALL zbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
566 $ rwork(iphi), u1, ldu1, u2, ldu2, v1t, ldv1t, cdum,
567 $ 1, rwork(ib11d), rwork(ib11e), rwork(ib12d),
568 $ rwork(ib12e), rwork(ib21d), rwork(ib21e),
569 $ rwork(ib22d), rwork(ib22e), rwork(ibbcsd),
570 $ lrwork-ibbcsd+1, childinfo )
575 IF( q .GT. 0 .AND. wantu2 )
THEN 577 iwork(i) = m - p - q + i
582 CALL zlapmt( .false., m-p, m-p, u2, ldu2, iwork )
584 ELSE IF( r .EQ. p )
THEN 590 CALL zunbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
591 $ rwork(iphi), work(itaup1), work(itaup2),
592 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
596 IF( wantu1 .AND. p .GT. 0 )
THEN 602 CALL zlacpy(
'L', p-1, p-1, x11(2,1), ldx11, u1(2,2), ldu1 )
603 CALL zungqr( p-1, p-1, p-1, u1(2,2), ldu1, work(itaup1),
604 $ work(iorgqr), lorgqr, childinfo )
606 IF( wantu2 .AND. m-p .GT. 0 )
THEN 607 CALL zlacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
608 CALL zungqr( m-p, m-p, q, u2, ldu2, work(itaup2),
609 $ work(iorgqr), lorgqr, childinfo )
611 IF( wantv1t .AND. q .GT. 0 )
THEN 612 CALL zlacpy(
'U', p, q, x11, ldx11, v1t, ldv1t )
613 CALL zunglq( q, q, r, v1t, ldv1t, work(itauq1),
614 $ work(iorglq), lorglq, childinfo )
619 CALL zbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
620 $ rwork(iphi), v1t, ldv1t, cdum, 1, u1, ldu1, u2,
621 $ ldu2, rwork(ib11d), rwork(ib11e), rwork(ib12d),
622 $ rwork(ib12e), rwork(ib21d), rwork(ib21e),
623 $ rwork(ib22d), rwork(ib22e), rwork(ibbcsd), lbbcsd,
629 IF( q .GT. 0 .AND. wantu2 )
THEN 631 iwork(i) = m - p - q + i
636 CALL zlapmt( .false., m-p, m-p, u2, ldu2, iwork )
638 ELSE IF( r .EQ. m-p )
THEN 644 CALL zunbdb3( m, p, q, x11, ldx11, x21, ldx21, theta,
645 $ rwork(iphi), work(itaup1), work(itaup2),
646 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
650 IF( wantu1 .AND. p .GT. 0 )
THEN 651 CALL zlacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
652 CALL zungqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
653 $ lorgqr, childinfo )
655 IF( wantu2 .AND. m-p .GT. 0 )
THEN 661 CALL zlacpy(
'L', m-p-1, m-p-1, x21(2,1), ldx21, u2(2,2),
663 CALL zungqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2,
664 $ work(itaup2), work(iorgqr), lorgqr, childinfo )
666 IF( wantv1t .AND. q .GT. 0 )
THEN 667 CALL zlacpy(
'U', m-p, q, x21, ldx21, v1t, ldv1t )
668 CALL zunglq( q, q, r, v1t, ldv1t, work(itauq1),
669 $ work(iorglq), lorglq, childinfo )
674 CALL zbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
675 $ theta, rwork(iphi), cdum, 1, v1t, ldv1t, u2, ldu2,
676 $ u1, ldu1, rwork(ib11d), rwork(ib11e),
677 $ rwork(ib12d), rwork(ib12e), rwork(ib21d),
678 $ rwork(ib21e), rwork(ib22d), rwork(ib22e),
679 $ rwork(ibbcsd), lbbcsd, childinfo )
692 CALL zlapmt( .false., p, q, u1, ldu1, iwork )
695 CALL zlapmr( .false., q, q, v1t, ldv1t, iwork )
704 CALL zunbdb4( m, p, q, x11, ldx11, x21, ldx21, theta,
705 $ rwork(iphi), work(itaup1), work(itaup2),
706 $ work(itauq1), work(iorbdb), work(iorbdb+m),
707 $ lorbdb-m, childinfo )
711 IF( wantu2 .AND. m-p .GT. 0 )
THEN 712 CALL zcopy( m-p, work(iorbdb+p), 1, u2, 1 )
714 IF( wantu1 .AND. p .GT. 0 )
THEN 715 CALL zcopy( p, work(iorbdb), 1, u1, 1 )
719 CALL zlacpy(
'L', p-1, m-q-1, x11(2,1), ldx11, u1(2,2),
721 CALL zungqr( p, p, m-q, u1, ldu1, work(itaup1),
722 $ work(iorgqr), lorgqr, childinfo )
724 IF( wantu2 .AND. m-p .GT. 0 )
THEN 728 CALL zlacpy(
'L', m-p-1, m-q-1, x21(2,1), ldx21, u2(2,2),
730 CALL zungqr( m-p, m-p, m-q, u2, ldu2, work(itaup2),
731 $ work(iorgqr), lorgqr, childinfo )
733 IF( wantv1t .AND. q .GT. 0 )
THEN 734 CALL zlacpy(
'U', m-q, q, x21, ldx21, v1t, ldv1t )
735 CALL zlacpy(
'U', p-(m-q), q-(m-q), x11(m-q+1,m-q+1), ldx11,
736 $ v1t(m-q+1,m-q+1), ldv1t )
737 CALL zlacpy(
'U', -p+q, q-p, x21(m-q+1,p+1), ldx21,
738 $ v1t(p+1,p+1), ldv1t )
739 CALL zunglq( q, q, q, v1t, ldv1t, work(itauq1),
740 $ work(iorglq), lorglq, childinfo )
745 CALL zbbcsd( jobu2, jobu1,
'N', jobv1t,
'N', m, m-p, m-q,
746 $ theta, rwork(iphi), u2, ldu2, u1, ldu1, cdum, 1,
747 $ v1t, ldv1t, rwork(ib11d), rwork(ib11e),
748 $ rwork(ib12d), rwork(ib12e), rwork(ib21d),
749 $ rwork(ib21e), rwork(ib22d), rwork(ib22e),
750 $ rwork(ibbcsd), lbbcsd, childinfo )
763 CALL zlapmt( .false., p, p, u1, ldu1, iwork )
766 CALL zlapmr( .false., p, q, v1t, ldv1t, iwork )
subroutine zlapmr(FORWRD, M, N, X, LDX, K)
ZLAPMR rearranges rows of a matrix as specified by a permutation vector.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zbbcsd(JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E, B22D, B22E, RWORK, LRWORK, INFO)
ZBBCSD
subroutine zuncsd2by1(JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK, INFO)
ZUNCSD2BY1
subroutine zunbdb1(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB1
subroutine zunbdb3(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB3
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlapmt(FORWRD, M, N, X, LDX, K)
ZLAPMT performs a forward or backward permutation of the columns of a matrix.
subroutine zunbdb2(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB2
subroutine zunglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGLQ
subroutine zunbdb4(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, INFO)
ZUNBDB4
subroutine zungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGQR