230 SUBROUTINE sorcsd2by1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11,
231 $ X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T,
232 $ LDV1T, WORK, LWORK, IWORK, INFO )
239 CHARACTER JOBU1, JOBU2, JOBV1T
240 INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21,
245 REAL U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*),
246 $ x11(ldx11,*), x21(ldx21,*)
254 PARAMETER ( ONE = 1.0e0, zero = 0.0e0 )
257 INTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E,
258 $ IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB,
259 $ iorglq, iorgqr, iphi, itaup1, itaup2, itauq1,
260 $ j, lbbcsd, lorbdb, lorglq, lorglqmin,
261 $ lorglqopt, lorgqr, lorgqrmin, lorgqropt,
262 $ lworkmin, lworkopt, r
263 LOGICAL LQUERY, WANTU1, WANTU2, WANTV1T
266 REAL DUM1(1), DUM2(1,1)
285 wantu1 = lsame( jobu1,
'Y' )
286 wantu2 = lsame( jobu2,
'Y' )
287 wantv1t = lsame( jobv1t,
'Y' )
288 lquery = lwork .EQ. -1
292 ELSE IF( p .LT. 0 .OR. p .GT. m )
THEN
294 ELSE IF( q .LT. 0 .OR. q .GT. m )
THEN
296 ELSE IF( ldx11 .LT.
max( 1, p ) )
THEN
298 ELSE IF( ldx21 .LT.
max( 1, m-p ) )
THEN
300 ELSE IF( wantu1 .AND. ldu1 .LT.
max( 1, p ) )
THEN
302 ELSE IF( wantu2 .AND. ldu2 .LT.
max( 1, m - p ) )
THEN
304 ELSE IF( wantv1t .AND. ldv1t .LT.
max( 1, q ) )
THEN
308 r =
min( p, m-p, q, m-q )
329 IF( info .EQ. 0 )
THEN
331 ib11d = iphi +
max( 1, r-1 )
332 ib11e = ib11d +
max( 1, r )
333 ib12d = ib11e +
max( 1, r - 1 )
334 ib12e = ib12d +
max( 1, r )
335 ib21d = ib12e +
max( 1, r - 1 )
336 ib21e = ib21d +
max( 1, r )
337 ib22d = ib21e +
max( 1, r - 1 )
338 ib22e = ib22d +
max( 1, r )
339 ibbcsd = ib22e +
max( 1, r - 1 )
340 itaup1 = iphi +
max( 1, r-1 )
341 itaup2 = itaup1 +
max( 1, p )
342 itauq1 = itaup2 +
max( 1, m-p )
343 iorbdb = itauq1 +
max( 1, q )
344 iorgqr = itauq1 +
max( 1, q )
345 iorglq = itauq1 +
max( 1, q )
351 CALL sorbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
352 $ dum1, dum1, dum1, dum1, work, -1,
354 lorbdb = int( work(1) )
355 IF( wantu1 .AND. p .GT. 0 )
THEN
356 CALL sorgqr( p, p, q, u1, ldu1, dum1, work(1), -1,
358 lorgqrmin =
max( lorgqrmin, p )
359 lorgqropt =
max( lorgqropt, int( work(1) ) )
361 IF( wantu2 .AND. m-p .GT. 0 )
THEN
362 CALL sorgqr( m-p, m-p, q, u2, ldu2, dum1, work(1), -1,
364 lorgqrmin =
max( lorgqrmin, m-p )
365 lorgqropt =
max( lorgqropt, int( work(1) ) )
367 IF( wantv1t .AND. q .GT. 0 )
THEN
368 CALL sorglq( q-1, q-1, q-1, v1t, ldv1t,
369 $ dum1, work(1), -1, childinfo )
370 lorglqmin =
max( lorglqmin, q-1 )
371 lorglqopt =
max( lorglqopt, int( work(1) ) )
373 CALL sbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
374 $ dum1, u1, ldu1, u2, ldu2, v1t, ldv1t, dum2,
375 $ 1, dum1, dum1, dum1, dum1, dum1,
376 $ dum1, dum1, dum1, work(1), -1, childinfo
378 lbbcsd = int( work(1) )
379 ELSE IF( r .EQ. p )
THEN
380 CALL sorbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
381 $ dum1, dum1, dum1, dum1, work(1), -1,
383 lorbdb = int( work(1) )
384 IF( wantu1 .AND. p .GT. 0 )
THEN
385 CALL sorgqr( p-1, p-1, p-1, u1(2,2), ldu1, dum1,
386 $ work(1), -1, childinfo )
387 lorgqrmin =
max( lorgqrmin, p-1 )
388 lorgqropt =
max( lorgqropt, int( work(1) ) )
390 IF( wantu2 .AND. m-p .GT. 0 )
THEN
391 CALL sorgqr( m-p, m-p, q, u2, ldu2, dum1, work(1), -1,
393 lorgqrmin =
max( lorgqrmin, m-p )
394 lorgqropt =
max( lorgqropt, int( work(1) ) )
396 IF( wantv1t .AND. q .GT. 0 )
THEN
397 CALL sorglq( q, q, r, v1t, ldv1t, dum1, work(1), -1,
399 lorglqmin =
max( lorglqmin, q )
400 lorglqopt =
max( lorglqopt, int( work(1) ) )
402 CALL sbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
403 $ dum1, v1t, ldv1t, dum2, 1, u1, ldu1, u2,
404 $ ldu2, dum1, dum1, dum1, dum1, dum1,
405 $ dum1, dum1, dum1, work(1), -1, childinfo
407 lbbcsd = int( work(1) )
408 ELSE IF( r .EQ. m-p )
THEN
409 CALL sorbdb3( m, p, q, x11, ldx11, x21, ldx21, theta,
410 $ dum1, dum1, dum1, dum1, work(1), -1,
412 lorbdb = int( work(1) )
413 IF( wantu1 .AND. p .GT. 0 )
THEN
414 CALL sorgqr( p, p, q, u1, ldu1, dum1, work(1), -1,
416 lorgqrmin =
max( lorgqrmin, p )
417 lorgqropt =
max( lorgqropt, int( work(1) ) )
419 IF( wantu2 .AND. m-p .GT. 0 )
THEN
420 CALL sorgqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2, dum1,
421 $ work(1), -1, childinfo )
422 lorgqrmin =
max( lorgqrmin, m-p-1 )
423 lorgqropt =
max( lorgqropt, int( work(1) ) )
425 IF( wantv1t .AND. q .GT. 0 )
THEN
426 CALL sorglq( q, q, r, v1t, ldv1t, dum1, work(1), -1,
428 lorglqmin =
max( lorglqmin, q )
429 lorglqopt =
max( lorglqopt, int( work(1) ) )
431 CALL sbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
432 $ theta, dum1, dum2, 1, v1t, ldv1t, u2, ldu2,
433 $ u1, ldu1, dum1, dum1, dum1, dum1,
434 $ dum1, dum1, dum1, dum1, work(1), -1,
436 lbbcsd = int( work(1) )
438 CALL sorbdb4( m, p, q, x11, ldx11, x21, ldx21, theta,
439 $ dum1, dum1, dum1, dum1, dum1,
440 $ work(1), -1, childinfo )
441 lorbdb = m + int( work(1) )
442 IF( wantu1 .AND. p .GT. 0 )
THEN
443 CALL sorgqr( p, p, m-q, u1, ldu1, dum1, work(1), -1,
445 lorgqrmin =
max( lorgqrmin, p )
446 lorgqropt =
max( lorgqropt, int( work(1) ) )
448 IF( wantu2 .AND. m-p .GT. 0 )
THEN
449 CALL sorgqr( m-p, m-p, m-q, u2, ldu2, dum1, work(1),
451 lorgqrmin =
max( lorgqrmin, m-p )
452 lorgqropt =
max( lorgqropt, int( work(1) ) )
454 IF( wantv1t .AND. q .GT. 0 )
THEN
455 CALL sorglq( q, q, q, v1t, ldv1t, dum1, work(1), -1,
457 lorglqmin =
max( lorglqmin, q )
458 lorglqopt =
max( lorglqopt, int( work(1) ) )
460 CALL sbbcsd( jobu2, jobu1
'N', jobv1t,
'N', m, m-p, m-q,
461 $ theta, dum1, u2, ldu2, u1, ldu1, dum2, 1,
462 $ v1t, ldv1t, dum1, dum1, dum1, dum1,
463 $ dum1, dum1, dum1, dum1, work(1), -1,
465 lbbcsd = int( work(1) )
467 lworkmin =
max( iorbdb+lorbdb-1,
468 $ iorgqr+lorgqrmin-1,
469 $ iorglq+lorglqmin-1,
471 lworkopt =
max( iorbdb+lorbdb-1,
472 $ iorgqr+lorgqropt-1,
476 IF( lwork .LT. lworkmin .AND. .NOT.lquery )
THEN
480 IF( info .NE. 0 )
THEN
481 CALL xerbla(
'SORCSD2BY1', -info )
483 ELSE IF( lquery )
THEN
486 lorgqr = lwork-iorgqr+1
487 lorglq = lwork-iorglq+1
498 CALL sorbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
499 $ work(iphi), work(itaup1), work(itaup2),
500 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
504 IF( wantu1 .AND. p .GT. 0 )
THEN
505 CALL slacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
506 CALL sorgqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
507 $ lorgqr, childinfo )
509 IF( wantu2 .AND. m-p .GT. 0 )
THEN
510 CALL slacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
511 CALL sorgqr( m-p, m-p, q, u2, ldu2, work(itaup2),
512 $ work(iorgqr), lorgqr, childinfo )
514 IF( wantv1t .AND. q .GT. 0 )
THEN
520 CALL slacpy(
'U', q-1, q-1, x21(1,2), ldx21, v1t(2,2),
522 CALL sorglq( q-1, q-1, q-1, v1t(2,2), ldv1t, work(itauq1),
523 $ work(iorglq), lorglq, childinfo )
528 CALL sbbcsd( jobu1, jobu2, jobv1t, 'n
', 'n
', M, P, Q, THETA,
529 $ WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T,
530 $ DUM2, 1, WORK(IB11D), WORK(IB11E), WORK(IB12D),
531 $ WORK(IB12E), WORK(IB21D), WORK(IB21E),
532 $ WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
538.GT..AND.
IF( Q 0 WANTU2 ) THEN
540 IWORK(I) = M - P - Q + I
545 CALL SLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK )
547.EQ.
ELSE IF( R P ) THEN
553 CALL SORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA,
554 $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2),
555 $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO )
559.AND..GT.
IF( WANTU1 P 0 ) THEN
565 CALL SLACPY( 'l
', P-1, P-1, X11(2,1), LDX11, U1(2,2), LDU1 )
566 CALL SORGQR( P-1, P-1, P-1, U1(2,2), LDU1, WORK(ITAUP1),
567 $ WORK(IORGQR), LORGQR, CHILDINFO )
569.AND..GT.
IF( WANTU2 M-P 0 ) THEN
570 CALL SLACPY( 'l
', M-P, Q, X21, LDX21, U2, LDU2 )
571 CALL SORGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),
572 $ WORK(IORGQR), LORGQR, CHILDINFO )
574.AND..GT.
IF( WANTV1T Q 0 ) THEN
575 CALL SLACPY( 'u
', P, Q, X11, LDX11, V1T, LDV1T )
576 CALL SORGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1),
577 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
582 CALL SBBCSD( JOBV1T, 'n
', JOBU1, JOBU2, 't
', M, Q, P, THETA,
583 $ WORK(IPHI), V1T, LDV1T, DUM1, 1, U1, LDU1, U2,
584 $ LDU2, WORK(IB11D), WORK(IB11E), WORK(IB12D),
585 $ WORK(IB12E), WORK(IB21D), WORK(IB21E),
586 $ WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
592.GT..AND.
IF( Q 0 WANTU2 ) THEN
594 IWORK(I) = M - P - Q + I
599 CALL SLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK )
601.EQ.
ELSE IF( R M-P ) THEN
607 CALL SORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA,
608 $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2),
609 $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO )
613.AND..GT.
IF( WANTU1 P 0 ) THEN
614 CALL SLACPY( 'l
', P, Q, X11, LDX11, U1, LDU1 )
615 CALL SORGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR),
616 $ LORGQR, CHILDINFO )
618.AND..GT.
IF( WANTU2 M-P 0 ) THEN
624 CALL SLACPY( 'l
', M-P-1, M-P-1, X21(2,1), LDX21, U2(2,2),
626 CALL SORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2,
627 $ WORK(ITAUP2), WORK(IORGQR), LORGQR, CHILDINFO )
629.AND..GT.
IF( WANTV1T Q 0 ) THEN
630 CALL SLACPY( 'u
', M-P, Q, X21, LDX21, V1T, LDV1T )
631 CALL SORGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1),
632 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
637 CALL SBBCSD( 'n
', JOBV1T, JOBU2, JOBU1, 't
', M, M-Q, M-P,
638 $ THETA, WORK(IPHI), DUM1, 1, V1T, LDV1T, U2,
639 $ LDU2, U1, LDU1, WORK(IB11D), WORK(IB11E),
640 $ WORK(IB12D), WORK(IB12E), WORK(IB21D),
641 $ WORK(IB21E), WORK(IB22D), WORK(IB22E),
642 $ WORK(IBBCSD), LBBCSD, CHILDINFO )
655 CALL SLAPMT( .FALSE., P, Q, U1, LDU1, IWORK )
658 CALL SLAPMR( .FALSE., Q, Q, V1T, LDV1T, IWORK )
667 CALL SORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA,
668 $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2),
669 $ WORK(ITAUQ1), WORK(IORBDB), WORK(IORBDB+M),
670 $ LORBDB-M, CHILDINFO )
674.AND..GT.
IF( WANTU2 M-P 0 ) THEN
675 CALL SCOPY( M-P, WORK(IORBDB+P), 1, U2, 1 )
677.AND..GT.
IF( WANTU1 P 0 ) THEN
678 CALL SCOPY( P, WORK(IORBDB), 1, U1, 1 )
682 CALL SLACPY( 'l
', P-1, M-Q-1, X11(2,1), LDX11, U1(2,2),
684 CALL SORGQR( P, P, M-Q, U1, LDU1, WORK(ITAUP1),
685 $ WORK(IORGQR), LORGQR, CHILDINFO )
687.AND..GT.
IF( WANTU2 M-P 0 ) THEN
691 CALL SLACPY( 'l
', M-P-1, M-Q-1, X21(2,1), LDX21, U2(2,2),
693 CALL SORGQR( M-P, M-P, M-Q, U2, LDU2, WORK(ITAUP2),
694 $ WORK(IORGQR), LORGQR, CHILDINFO )
696.AND..GT.
IF( WANTV1T Q 0 ) THEN
697 CALL SLACPY( 'u
', M-Q, Q, X21, LDX21, V1T, LDV1T )
698 CALL SLACPY( 'u
', P-(M-Q), Q-(M-Q), X11(M-Q+1,M-Q+1), LDX11,
699 $ V1T(M-Q+1,M-Q+1), LDV1T )
700 CALL SLACPY( 'u
', -P+Q, Q-P, X21(M-Q+1,P+1), LDX21,
701 $ V1T(P+1,P+1), LDV1T )
702 CALL SORGLQ( Q, Q, Q, V1T, LDV1T, WORK(ITAUQ1),
703 $ WORK(IORGLQ), LORGLQ, CHILDINFO )
708 CALL SBBCSD( JOBU2, JOBU1, 'n
', JOBV1T, 'n
', M, M-P, M-Q,
709 $ THETA, WORK(IPHI), U2, LDU2, U1, LDU1, DUM1, 1,
710 $ V1T, LDV1T, WORK(IB11D), WORK(IB11E), WORK(IB12D),
711 $ WORK(IB12E), WORK(IB21D), WORK(IB21E),
712 $ WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
726 CALL SLAPMT( .FALSE., P, P, U1, LDU1, IWORK )
729 CALL SLAPMR( .FALSE., P, Q, V1T, LDV1T, IWORK )