251 SUBROUTINE zuncsd2by1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11,
252 $ x21, ldx21, theta, u1, ldu1, u2, ldu2, v1t,
253 $ 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
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
514 IF( info .NE. 0 )
THEN
515 CALL xerbla(
'ZUNCSD2BY1', -info )
517 ELSE IF( lquery )
THEN
520 lorgqr = lwork-iorgqr+1
521 lorglq = lwork-iorglq+1
532 CALL zunbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
533 $ rwork(iphi), work(itaup1), work(itaup2),
534 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
538 IF( wantu1 .AND. p .GT. 0 )
THEN
539 CALL zlacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
540 CALL zungqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
541 $ lorgqr, childinfo )
543 IF( wantu2 .AND. m-p .GT. 0 )
THEN
544 CALL zlacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
545 CALL zungqr( m-p, m-p, q, u2, ldu2, work(itaup2),
546 $ work(iorgqr), lorgqr, childinfo )
548 IF( wantv1t .AND. q .GT. 0 )
THEN
554 CALL zlacpy(
'U', q-1, q-1, x21(1,2), ldx21, v1t(2,2),
556 CALL zunglq( q-1, q-1, q-1, v1t(2,2), ldv1t, work(itauq1),
557 $ work(iorglq), lorglq, childinfo )
562 CALL zbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
563 $ rwork(iphi), u1, ldu1, u2, ldu2, v1t, ldv1t, cdum,
564 $ 1, rwork(ib11d), rwork(ib11e), rwork(ib12d),
565 $ rwork(ib12e), rwork(ib21d), rwork(ib21e),
566 $ rwork(ib22d), rwork(ib22e), rwork(ibbcsd), lbbcsd,
572 IF( q .GT. 0 .AND. wantu2 )
THEN
574 iwork(i) = m - p - q + i
579 CALL zlapmt( .false., m-p, m-p, u2, ldu2, iwork )
581 ELSE IF( r .EQ. p )
THEN
587 CALL zunbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
588 $ rwork(iphi), work(itaup1), work(itaup2),
589 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
593 IF( wantu1 .AND. p .GT. 0 )
THEN
599 CALL zlacpy(
'L', p-1, p-1, x11(2,1), ldx11, u1(2,2), ldu1 )
600 CALL zungqr( p-1, p-1, p-1, u1(2,2), ldu1, work(itaup1),
601 $ work(iorgqr), lorgqr, childinfo )
603 IF( wantu2 .AND. m-p .GT. 0 )
THEN
604 CALL zlacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
605 CALL zungqr( m-p, m-p, q, u2, ldu2, work(itaup2),
606 $ work(iorgqr), lorgqr, childinfo )
608 IF( wantv1t .AND. q .GT. 0 )
THEN
609 CALL zlacpy(
'U', p, q, x11, ldx11, v1t, ldv1t )
610 CALL zunglq( q, q, r, v1t, ldv1t, work(itauq1),
611 $ work(iorglq), lorglq, childinfo )
616 CALL zbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
617 $ rwork(iphi), v1t, ldv1t, cdum, 1, u1, ldu1, u2,
618 $ ldu2, rwork(ib11d), rwork(ib11e), rwork(ib12d),
619 $ rwork(ib12e), rwork(ib21d), rwork(ib21e),
620 $ rwork(ib22d), rwork(ib22e), rwork(ibbcsd), lbbcsd,
626 IF( q .GT. 0 .AND. wantu2 )
THEN
628 iwork(i) = m - p - q + i
633 CALL zlapmt( .false., m-p, m-p, u2, ldu2, iwork )
635 ELSE IF( r .EQ. m-p )
THEN
641 CALL zunbdb3( m, p, q, x11, ldx11, x21, ldx21, theta,
642 $ rwork(iphi), work(itaup1), work(itaup2),
643 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
647 IF( wantu1 .AND. p .GT. 0 )
THEN
648 CALL zlacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
649 CALL zungqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
650 $ lorgqr, childinfo )
652 IF( wantu2 .AND. m-p .GT. 0 )
THEN
658 CALL zlacpy(
'L', m-p-1, m-p-1, x21(2,1), ldx21, u2(2,2),
660 CALL zungqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2,
661 $ work(itaup2), work(iorgqr), lorgqr, childinfo )
663 IF( wantv1t .AND. q .GT. 0 )
THEN
664 CALL zlacpy(
'U', m-p, q, x21, ldx21, v1t, ldv1t )
665 CALL zunglq( q, q, r, v1t, ldv1t, work(itauq1),
666 $ work(iorglq), lorglq, childinfo )
671 CALL zbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
672 $ theta, rwork(iphi), cdum, 1, v1t, ldv1t, u2, ldu2,
673 $ u1, ldu1, rwork(ib11d), rwork(ib11e),
674 $ rwork(ib12d), rwork(ib12e), rwork(ib21d),
675 $ rwork(ib21e), rwork(ib22d), rwork(ib22e),
676 $ rwork(ibbcsd), lbbcsd, childinfo )
689 CALL zlapmt( .false., p, q, u1, ldu1, iwork )
692 CALL zlapmr( .false., q, q, v1t, ldv1t, iwork )
701 CALL zunbdb4( m, p, q, x11, ldx11, x21, ldx21, theta,
702 $ rwork(iphi), work(itaup1), work(itaup2),
703 $ work(itauq1), work(iorbdb), work(iorbdb+m),
704 $ lorbdb-m, childinfo )
708 IF( wantu1 .AND. p .GT. 0 )
THEN
709 CALL zcopy( p, work(iorbdb), 1, u1, 1 )
713 CALL zlacpy(
'L', p-1, m-q-1, x11(2,1), ldx11, u1(2,2),
715 CALL zungqr( p, p, m-q, u1, ldu1, work(itaup1),
716 $ work(iorgqr), lorgqr, childinfo )
718 IF( wantu2 .AND. m-p .GT. 0 )
THEN
719 CALL zcopy( m-p, work(iorbdb+p), 1, u2, 1 )
723 CALL zlacpy(
'L', m-p-1, m-q-1, x21(2,1), ldx21, u2(2,2),
725 CALL zungqr( m-p, m-p, m-q, u2, ldu2, work(itaup2),
726 $ work(iorgqr), lorgqr, childinfo )
728 IF( wantv1t .AND. q .GT. 0 )
THEN
729 CALL zlacpy(
'U', m-q, q, x21, ldx21, v1t, ldv1t )
730 CALL zlacpy(
'U', p-(m-q), q-(m-q), x11(m-q+1,m-q+1), ldx11,
731 $ v1t(m-q+1,m-q+1), ldv1t )
732 CALL zlacpy(
'U', -p+q, q-p, x21(m-q+1,p+1), ldx21,
733 $ v1t(p+1,p+1), ldv1t )
734 CALL zunglq( q, q, q, v1t, ldv1t, work(itauq1),
735 $ work(iorglq), lorglq, childinfo )
740 CALL zbbcsd( jobu2, jobu1,
'N', jobv1t,
'N', m, m-p, m-q,
741 $ theta, rwork(iphi), u2, ldu2, u1, ldu1, cdum, 1,
742 $ v1t, ldv1t, rwork(ib11d), rwork(ib11e),
743 $ rwork(ib12d), rwork(ib12e), rwork(ib21d),
744 $ rwork(ib21e), rwork(ib22d), rwork(ib22e),
745 $ rwork(ibbcsd), lbbcsd, childinfo )
758 CALL zlapmt( .false., p, p, u1, ldu1, iwork )
761 CALL zlapmr( .false., p, q, v1t, ldv1t, iwork )
subroutine zunglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGLQ
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zunbdb2(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB2
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
subroutine zlapmt(FORWRD, M, N, X, LDX, K)
ZLAPMT performs a forward or backward permutation of the columns of a matrix.
subroutine zunbdb4(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, INFO)
ZUNBDB4
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zunbdb1(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB1
subroutine zungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
ZUNGQR
subroutine zlapmr(FORWRD, M, N, X, LDX, K)
ZLAPMR rearranges rows of a matrix as specified by a permutation vector.
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 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 zunbdb3(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
ZUNBDB3