253 SUBROUTINE cuncsd2by1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11,
254 $ X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T,
255 $ LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK,
263 CHARACTER JOBU1, JOBU2, JOBV1T
264 INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21,
266 INTEGER LRWORK, LRWORKMIN, LRWORKOPT
271 COMPLEX U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*),
272 $ x11(ldx11,*), x21(ldx21,*)
280 PARAMETER ( ONE = (1.0e0,0.0e0), zero = (0.0e0,0.0e0) )
283 INTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E,
284 $ IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB,
285 $ IORGLQ, IORGQR, IPHI, ITAUP1, ITAUP2, ITAUQ1,
286 $ j, lbbcsd, lorbdb, lorglq, lorglqmin,
287 $ lorglqopt, lorgqr, lorgqrmin, lorgqropt,
288 $ lworkmin, lworkopt, r
289 LOGICAL LQUERY, WANTU1, WANTU2, WANTV1T
312 wantu1 = lsame( jobu1,
'Y' )
313 wantu2 = lsame( jobu2,
'Y' )
314 wantv1t = lsame( jobv1t,
'Y' )
315 lquery = ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 )
319 ELSE IF( p .LT. 0 .OR. p .GT. m )
THEN
321 ELSE IF( q .LT. 0 .OR. q .GT. m )
THEN
323 ELSE IF( ldx11 .LT.
max( 1, p ) )
THEN
325 ELSE IF( ldx21 .LT.
max( 1, m-p ) )
THEN
327 ELSE IF( wantu1 .AND. ldu1 .LT.
max( 1, p ) )
THEN
329 ELSE IF( wantu2 .AND. ldu2 .LT.
max( 1, m - p ) )
THEN
331 ELSE IF( wantv1t .AND. ldv1t .LT.
max( 1, q ) )
THEN
335 r =
min( p, m-p, q, m-q )
370 IF( info .EQ. 0 )
THEN
372 ib11d = iphi +
max( 1, r-1 )
373 ib11e = ib11d +
max( 1, r )
374 ib12d = ib11e +
max( 1, r - 1 )
375 ib12e = ib12d +
max( 1, r )
376 ib21d = ib12e +
max( 1, r - 1 )
377 ib21e = ib21d +
max( 1, r )
378 ib22d = ib21e +
max( 1, r - 1 )
379 ib22e = ib22d +
max( 1, r )
380 ibbcsd = ib22e +
max( 1, r - 1 )
382 itaup2 = itaup1 +
max( 1, p )
383 itauq1 = itaup2 +
max( 1, m-p )
384 iorbdb = itauq1 +
max( 1, q )
385 iorgqr = itauq1 +
max( 1, q )
386 iorglq = itauq1 +
max( 1, q )
392 CALL cunbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
393 $ dum, cdum, cdum, cdum, work, -1,
395 lorbdb = int( work(1) )
396 IF( wantu1 .AND. p .GT. 0 )
THEN
397 CALL cungqr( p, p, q, u1, ldu1, cdum, work(1), -1,
399 lorgqrmin =
max( lorgqrmin, p )
400 lorgqropt =
max( lorgqropt, int( work(1) ) )
402 IF( wantu2 .AND. m-p .GT. 0 )
THEN
403 CALL cungqr( m-p, m-p, q, u2, ldu2, cdum, work(1), -1,
405 lorgqrmin =
max( lorgqrmin, m-p )
406 lorgqropt =
max( lorgqropt, int( work(1) ) )
408 IF( wantv1t .AND. q .GT. 0 )
THEN
409 CALL cunglq( q-1, q-1, q-1, v1t, ldv1t,
410 $ cdum, work(1), -1, childinfo )
411 lorglqmin =
max( lorglqmin, q-1 )
412 lorglqopt =
max( lorglqopt, int( work(1) ) )
414 CALL cbbcsd( jobu1,
'N',
'N', m, p, q, theta,
415 $ dum(1), u1, ldu1, u2, ldu2, v1t, ldv1t, cdum,
416 $ 1, dum, dum, dum, dum, dum, dum, dum, dum,
418 lbbcsd = int( rwork(1) )
419 ELSE IF( r .EQ. p )
THEN
420 CALL cunbdb2( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
421 $ cdum, cdum, cdum, work(1), -1, childinfo )
422 lorbdb = int( work(1) )
423 IF( wantu1 .AND. p .GT. 0 )
THEN
424 CALL cungqr( p-1, p-1, p-1, u1(2,2), ldu1, cdum, work(1),
426 lorgqrmin =
max( lorgqrmin, p-1 )
427 lorgqropt =
max( lorgqropt, int( work(1) ) )
429 IF( wantu2 .AND. m-p .GT. 0 )
THEN
430 CALL cungqr( m-p, m-p, q, u2, ldu2, cdum, work(1), -1,
432 lorgqrmin =
max( lorgqrmin, m-p )
433 lorgqropt =
max( lorgqropt, int( work(1) ) )
435 IF( wantv1t .AND. q .GT. 0 )
THEN
436 CALL cunglq( q, q, r, v1t, ldv1t, cdum, work(1), -1,
438 lorglqmin =
max( lorglqmin, q )
439 lorglqopt =
max( lorglqopt, int( work(1) ) )
441 CALL cbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
442 $ dum, v1t, ldv1t, cdum, 1, u1, ldu1, u2, ldu2,
443 $ dum, dum, dum, dum, dum, dum, dum, dum,
444 $ rwork(1), -1, childinfo )
445 lbbcsd = int( rwork(1) )
446 ELSE IF( r .EQ. m-p )
THEN
447 CALL cunbdb3( m, p, q, x11, ldx11, x21, ldx21, theta, dum,
448 $ cdum, cdum, cdum, work(1), -1, childinfo )
449 lorbdb = int( work(1) )
450 IF( wantu1 .AND. p .GT. 0 )
THEN
451 CALL cungqr( p, p, q, u1, ldu1, cdum, work(1), -1,
453 lorgqrmin =
max( lorgqrmin, p )
454 lorgqropt =
max( lorgqropt, int( work(1) ) )
456 IF( wantu2 .AND. m-p .GT. 0 )
THEN
457 CALL cungqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2, cdum,
458 $ work(1), -1, childinfo )
459 lorgqrmin =
max( lorgqrmin, m-p-1 )
460 lorgqropt =
max( lorgqropt, int( work(1) ) )
462 IF( wantv1t .AND. q .GT. 0 )
THEN
463 CALL cunglq( q, q, r, v1t, ldv1t, cdum, work(1), -1,
465 lorglqmin =
max( lorglqmin, q )
466 lorglqopt =
max( lorglqopt, int( work(1) ) )
468 CALL cbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
469 $ theta, dum, cdum, 1, v1t, ldv1t, u2, ldu2, u1,
470 $ ldu1, dum, dum, dum, dum, dum, dum, dum, dum,
471 $ rwork(1), -1, childinfo )
472 lbbcsd = int( rwork(1) )
474 CALL cunbdb4( m, p, q, x11, ldx11, x21, ldx21
475 $ cdum, cdum, cdum, cdum, work(1), -1, childinfo
477 lorbdb = m + int( work(1) )
478 IF( wantu1 .AND. p .GT. 0 )
THEN
479 CALL cungqr( p, p, m-q, u1, ldu1, cdum, work(1), -1,
481 lorgqrmin =
max( lorgqrmin, p )
482 lorgqropt =
max( lorgqropt, int( work(1) ) )
484 IF( wantu2 .AND. m-p .GT. 0 )
THEN
485 CALL cungqr( m-p, m-p, m-q, u2, ldu2, cdum, work(1), -1,
487 lorgqrmin =
max( lorgqrmin, m-p )
488 lorgqropt =
max( lorgqropt, int( work(1) ) )
490 IF( wantv1t .AND. q .GT. 0 )
THEN
491 CALL cunglq( q, q, q, v1t, ldv1t, cdum, work(1), -1,
493 lorglqmin =
max( lorglqmin, q )
494 lorglqopt =
max( lorglqopt, int( work(1) ) )
496 CALL cbbcsd( jobu2, jobu1,
'N', jobv1t,
'N', m, m-p, m-q,
497 $ theta, dum, u2, ldu2, u1, ldu1, cdum, 1, v1t,
498 $ ldv1t, dum, dum, dum, dum, dum, dum, dum, dum,
499 $ rwork(1), -1, childinfo )
500 lbbcsd = int( rwork(1) )
502 lrworkmin = ibbcsd+lbbcsd-1
503 lrworkopt = lrworkmin
505 lworkmin =
max( iorbdb+lorbdb-1,
506 $ iorgqr+lorgqrmin-1,
507 $ iorglq+lorglqmin-1 )
508 lworkopt =
max( iorbdb+lorbdb-1,
509 $ iorgqr+lorgqropt-1,
510 $ iorglq+lorglqopt-1 )
512 IF( lwork .LT. lworkmin .AND. .NOT.lquery )
THEN
515 IF( lrwork .LT. lrworkmin .AND. .NOT.lquery )
THEN
519 IF( info .NE. 0 )
THEN
520 CALL xerbla(
'CUNCSD2BY1', -info )
522 ELSE IF( lquery )
THEN
525 lorgqr = lwork-iorgqr+1
526 lorglq = lwork-iorglq+1
537 CALL cunbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
538 $ rwork(iphi), work(itaup1), work(itaup2),
539 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
543 IF( wantu1 .AND. p .GT. 0 )
THEN
544 CALL clacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
545 CALL cungqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
546 $ lorgqr, childinfo )
548 IF( wantu2 .AND. m-p .GT. 0 )
THEN
549 CALL clacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
550 CALL cungqr( m-p, m-p, q, u2, ldu2, work(itaup2),
551 $ work(iorgqr), lorgqr, childinfo )
553 IF( wantv1t .AND. q .GT. 0 )
THEN
559 CALL clacpy(
'U', q-1, q-1, x21(1,2), ldx21, v1t(2,2),
561 CALL cunglq( q-1, q-1, q-1, v1t(2,2), ldv1t, work(itauq1),
562 $ work(iorglq), lorglq, childinfo )
567 CALL cbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
568 $ rwork(iphi), u1, ldu1, u2, ldu2, v1t, ldv1t, cdum,
569 $ 1, rwork(ib11d), rwork(ib11e), rwork(ib12d),
570 $ rwork(ib12e), rwork(ib21d), rwork(ib21e),
571 $ rwork(ib22d), rwork(ib22e), rwork(ibbcsd),
572 $ lrwork-ibbcsd+1, childinfo )
577 IF( q .GT. 0 .AND. wantu2 )
THEN
579 iwork(i) = m - p - q + i
584 CALL clapmt( .false., m-p, m-p, u2, ldu2, iwork )
586 ELSE IF( r .EQ. p )
THEN
592 CALL cunbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
593 $ rwork(iphi), work(itaup1), work(itaup2),
594 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
598 IF( wantu1 .AND. p .GT. 0 )
THEN
604 CALL clacpy( 'l
', P-1, P-1, X11(2,1), LDX11, U1(2,2), LDU1 )
605 CALL CUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, WORK(ITAUP1),
606 $ WORK(IORGQR), LORGQR, CHILDINFO )
608.AND..GT.
IF( WANTU2 M-P 0 ) THEN
609 CALL CLACPY( 'l
', M-P, Q, X21, LDX21, U2, LDU2 )
610 CALL CUNGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),
611 $ WORK(IORGQR), LORGQR, CHILDINFO )
613.AND..GT.
IF( WANTV1T Q 0 ) THEN
614 CALL CLACPY( 'u
', P, Q, X11, LDX11, V1T, LDV1T )
615 CALL CUNGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1),
616 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
621 CALL CBBCSD( JOBV1T, 'n
', JOBU1, JOBU2, 't
', M, Q, P, THETA,
622 $ RWORK(IPHI), V1T, LDV1T, CDUM, 1, U1, LDU1, U2,
623 $ LDU2, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
624 $ RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
625 $ RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
631.GT..AND.
IF( Q 0 WANTU2 ) THEN
633 IWORK(I) = M - P - Q + I
638 CALL CLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK )
640.EQ.
ELSE IF( R M-P ) THEN
646 CALL CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA,
647 $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2),
648 $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO )
652.AND..GT.
IF( WANTU1 P 0 ) THEN
653 CALL CLACPY( 'l
', P, Q, X11, LDX11, U1, LDU1 )
654 CALL CUNGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR),
655 $ LORGQR, CHILDINFO )
657.AND..GT.
IF( WANTU2 M-P 0 ) THEN
663 CALL CLACPY( 'l
', M-P-1, M-P-1, X21(2,1), LDX21, U2(2,2),
665 CALL CUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2,
666 $ WORK(ITAUP2), WORK(IORGQR), LORGQR, CHILDINFO )
668.AND..GT.
IF( WANTV1T Q 0 ) THEN
669 CALL CLACPY( 'u
', M-P, Q, X21, LDX21, V1T, LDV1T )
670 CALL CUNGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1),
671 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
676 CALL CBBCSD( 'n
', JOBV1T, JOBU2, JOBU1, 't
', M, M-Q, M-P,
677 $ THETA, RWORK(IPHI), CDUM, 1, V1T, LDV1T, U2, LDU2,
678 $ U1, LDU1, RWORK(IB11D), RWORK(IB11E),
679 $ RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
680 $ RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
681 $ RWORK(IBBCSD), LBBCSD, CHILDINFO )
694 CALL CLAPMT( .FALSE., P, Q, U1, LDU1, IWORK )
697 CALL CLAPMR( .FALSE., Q, Q, V1T, LDV1T, IWORK )
706 CALL CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA,
707 $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2),
708 $ WORK(ITAUQ1), WORK(IORBDB), WORK(IORBDB+M),
709 $ LORBDB-M, CHILDINFO )
714.AND..GT.
IF( WANTU2 M-P 0 ) THEN
715 CALL CCOPY( M-P, WORK(IORBDB+P), 1, U2, 1 )
717.AND..GT.
IF( WANTU1 P 0 ) THEN
718 CALL CCOPY( P, WORK(IORBDB), 1, U1, 1 )
722 CALL CLACPY( 'l
', P-1, M-Q-1, X11(2,1), LDX11, U1(2,2),
724 CALL CUNGQR( P, P, M-Q, U1, LDU1, WORK(ITAUP1),
725 $ WORK(IORGQR), LORGQR, CHILDINFO )
727.AND..GT.
IF( WANTU2 M-P 0 ) THEN
731 CALL CLACPY( 'l
', M-P-1, M-Q-1, X21(2,1), LDX21, U2(2,2),
733 CALL CUNGQR( M-P, M-P, M-Q, U2, LDU2, WORK(ITAUP2),
734 $ WORK(IORGQR), LORGQR, CHILDINFO )
736.AND..GT.
IF( WANTV1T Q 0 ) THEN
737 CALL CLACPY( 'u
', M-Q, Q, X21, LDX21, V1T, LDV1T )
738 CALL CLACPY( 'u
', P-(M-Q), Q-(M-Q), X11(M-Q+1,M-Q+1), LDX11,
739 $ V1T(M-Q+1,M-Q+1), LDV1T )
740 CALL CLACPY( 'u
', -P+Q, Q-P, X21(M-Q+1,P+1), LDX21,
741 $ V1T(P+1,P+1), LDV1T )
742 CALL CUNGLQ( Q, Q, Q, V1T, LDV1T, WORK(ITAUQ1),
743 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
748 CALL CBBCSD( JOBU2, JOBU1, 'n
', JOBV1T, 'n
', M, M-P, M-Q,
749 $ THETA, RWORK(IPHI), U2, LDU2, U1, LDU1, CDUM, 1,
750 $ V1T, LDV1T, RWORK(IB11D), RWORK(IB11E),
751 $ RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
752 $ RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
753 $ RWORK(IBBCSD), LBBCSD, CHILDINFO )
766 CALL CLAPMT( .FALSE., P, P, U1, LDU1, IWORK )
769 CALL CLAPMR( .FALSE., P, Q, V1T, LDV1T, IWORK )