241 CHARACTER jobu1, jobu2, jobv1t
242 INTEGER info, ldu1, ldu2, ldv1t, lwork, ldx11, ldx21,
247 REAL u1(ldu1,*), u2(ldu2,*), v1t(ldv1t,*), work(*),
248 $ x11(ldx11,*), x21(ldx21,*)
256 parameter ( one = 1.0e0, zero = 0.0e0 )
259 INTEGER childinfo, i, ib11d, ib11e, ib12d, ib12e,
260 $ ib21d, ib21e, ib22d, ib22e, ibbcsd, iorbdb,
261 $ iorglq, iorgqr, iphi, itaup1, itaup2, itauq1,
262 $ j, lbbcsd, lorbdb, lorglq, lorglqmin,
263 $ lorglqopt, lorgqr, lorgqrmin, lorgqropt,
264 $ lworkmin, lworkopt, r
265 LOGICAL lquery, wantu1, wantu2, wantv1t
268 REAL dum1(1), dum2(1,1)
280 INTRINSIC int, max, min
287 wantu1 =
lsame( jobu1,
'Y' )
288 wantu2 =
lsame( jobu2,
'Y' )
289 wantv1t =
lsame( jobv1t,
'Y' )
290 lquery = lwork .EQ. -1
294 ELSE IF( p .LT. 0 .OR. p .GT. m )
THEN
296 ELSE IF( q .LT. 0 .OR. q .GT. m )
THEN
298 ELSE IF( ldx11 .LT. max( 1, p ) )
THEN
300 ELSE IF( ldx21 .LT. max( 1, m-p ) )
THEN
302 ELSE IF( wantu1 .AND. ldu1 .LT. max( 1, p ) )
THEN
304 ELSE IF( wantu2 .AND. ldu2 .LT. max( 1, m - p ) )
THEN
306 ELSE IF( wantv1t .AND. ldv1t .LT. max( 1, q ) )
THEN
310 r = min( p, m-p, q, m-q )
331 IF( info .EQ. 0 )
THEN
333 ib11d = iphi + max( 1, r-1 )
334 ib11e = ib11d + max( 1, r )
335 ib12d = ib11e + max( 1, r - 1 )
336 ib12e = ib12d + max( 1, r )
337 ib21d = ib12e + max( 1, r - 1 )
338 ib21e = ib21d + max( 1, r )
339 ib22d = ib21e + max( 1, r - 1 )
340 ib22e = ib22d + max( 1, r )
341 ibbcsd = ib22e + max( 1, r - 1 )
342 itaup1 = iphi + max( 1, r-1 )
343 itaup2 = itaup1 + max( 1, p )
344 itauq1 = itaup2 + max( 1, m-p )
345 iorbdb = itauq1 + max( 1, q )
346 iorgqr = itauq1 + max( 1, q )
347 iorglq = itauq1 + max( 1, q )
353 CALL sorbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
354 $ dum1, dum1, dum1, dum1, work, -1,
356 lorbdb = int( work(1) )
357 IF( wantu1 .AND. p .GT. 0 )
THEN
358 CALL sorgqr( p, p, q, u1, ldu1, dum1, work(1), -1,
360 lorgqrmin = max( lorgqrmin, p )
361 lorgqropt = max( lorgqropt, int( work(1) ) )
363 IF( wantu2 .AND. m-p .GT. 0 )
THEN
364 CALL sorgqr( m-p, m-p, q, u2, ldu2, dum1, work(1), -1,
366 lorgqrmin = max( lorgqrmin, m-p )
367 lorgqropt = max( lorgqropt, int( work(1) ) )
369 IF( wantv1t .AND. q .GT. 0 )
THEN
370 CALL sorglq( q-1, q-1, q-1, v1t, ldv1t,
371 $ dum1, work(1), -1, childinfo )
372 lorglqmin = max( lorglqmin, q-1 )
373 lorglqopt = max( lorglqopt, int( work(1) ) )
375 CALL sbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
376 $ dum1, u1, ldu1, u2, ldu2, v1t, ldv1t, dum2,
377 $ 1, dum1, dum1, dum1, dum1, dum1,
378 $ dum1, dum1, dum1, work(1), -1, childinfo
380 lbbcsd = int( work(1) )
381 ELSE IF( r .EQ. p )
THEN
382 CALL sorbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
383 $ dum1, dum1, dum1, dum1, work(1), -1,
385 lorbdb = int( work(1) )
386 IF( wantu1 .AND. p .GT. 0 )
THEN
387 CALL sorgqr( p-1, p-1, p-1, u1(2,2), ldu1, dum1,
388 $ work(1), -1, childinfo )
389 lorgqrmin = max( lorgqrmin, p-1 )
390 lorgqropt = max( lorgqropt, int( work(1) ) )
392 IF( wantu2 .AND. m-p .GT. 0 )
THEN
393 CALL sorgqr( m-p, m-p, q, u2, ldu2, dum1, work(1), -1,
395 lorgqrmin = max( lorgqrmin, m-p )
396 lorgqropt = max( lorgqropt, int( work(1) ) )
398 IF( wantv1t .AND. q .GT. 0 )
THEN
399 CALL sorglq( q, q, r, v1t, ldv1t, dum1, work(1), -1,
401 lorglqmin = max( lorglqmin, q )
402 lorglqopt = max( lorglqopt, int( work(1) ) )
404 CALL sbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
405 $ dum1, v1t, ldv1t, dum2, 1, u1, ldu1, u2,
406 $ ldu2, dum1, dum1, dum1, dum1, dum1,
407 $ dum1, dum1, dum1, work(1), -1, childinfo
409 lbbcsd = int( work(1) )
410 ELSE IF( r .EQ. m-p )
THEN
411 CALL sorbdb3( m, p, q, x11, ldx11, x21, ldx21, theta,
412 $ dum1, dum1, dum1, dum1, work(1), -1,
414 lorbdb = int( work(1) )
415 IF( wantu1 .AND. p .GT. 0 )
THEN
416 CALL sorgqr( p, p, q, u1, ldu1, dum1, work(1), -1,
418 lorgqrmin = max( lorgqrmin, p )
419 lorgqropt = max( lorgqropt, int( work(1) ) )
421 IF( wantu2 .AND. m-p .GT. 0 )
THEN
422 CALL sorgqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2, dum1,
423 $ work(1), -1, childinfo )
424 lorgqrmin = max( lorgqrmin, m-p-1 )
425 lorgqropt = max( lorgqropt, int( work(1) ) )
427 IF( wantv1t .AND. q .GT. 0 )
THEN
428 CALL sorglq( q, q, r, v1t, ldv1t, dum1, work(1), -1,
430 lorglqmin = max( lorglqmin, q )
431 lorglqopt = max( lorglqopt, int( work(1) ) )
433 CALL sbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
434 $ theta, dum1, dum2, 1, v1t, ldv1t, u2, ldu2,
435 $ u1, ldu1, dum1, dum1, dum1, dum1,
436 $ dum1, dum1, dum1, dum1, work(1), -1,
438 lbbcsd = int( work(1) )
440 CALL sorbdb4( m, p, q, x11, ldx11, x21, ldx21, theta,
441 $ dum1, dum1, dum1, dum1, dum1,
442 $ work(1), -1, childinfo )
443 lorbdb = m + int( work(1) )
444 IF( wantu1 .AND. p .GT. 0 )
THEN
445 CALL sorgqr( p, p, m-q, u1, ldu1, dum1, work(1), -1,
447 lorgqrmin = max( lorgqrmin, p )
448 lorgqropt = max( lorgqropt, int( work(1) ) )
450 IF( wantu2 .AND. m-p .GT. 0 )
THEN
451 CALL sorgqr( m-p, m-p, m-q, u2, ldu2, dum1, work(1),
453 lorgqrmin = max( lorgqrmin, m-p )
454 lorgqropt = max( lorgqropt, int( work(1) ) )
456 IF( wantv1t .AND. q .GT. 0 )
THEN
457 CALL sorglq( q, q, q, v1t, ldv1t, dum1, work(1), -1,
459 lorglqmin = max( lorglqmin, q )
460 lorglqopt = max( lorglqopt, int( work(1) ) )
462 CALL sbbcsd( jobu2, jobu1,
'N', jobv1t,
'N', m, m-p, m-q,
463 $ theta, dum1, u2, ldu2, u1, ldu1, dum2, 1,
464 $ v1t, ldv1t, dum1, dum1, dum1, dum1,
465 $ dum1, dum1, dum1, dum1, work(1), -1,
467 lbbcsd = int( work(1) )
469 lworkmin = max( iorbdb+lorbdb-1,
470 $ iorgqr+lorgqrmin-1,
471 $ iorglq+lorglqmin-1,
473 lworkopt = max( iorbdb+lorbdb-1,
474 $ iorgqr+lorgqropt-1,
475 $ iorglq+lorglqopt-1,
478 IF( lwork .LT. lworkmin .AND. .NOT.lquery )
THEN
482 IF( info .NE. 0 )
THEN
483 CALL xerbla(
'SORCSD2BY1', -info )
485 ELSE IF( lquery )
THEN
488 lorgqr = lwork-iorgqr+1
489 lorglq = lwork-iorglq+1
500 CALL sorbdb1( m, p, q, x11, ldx11, x21, ldx21, theta,
501 $ work(iphi), work(itaup1), work(itaup2),
502 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
506 IF( wantu1 .AND. p .GT. 0 )
THEN
507 CALL slacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
508 CALL sorgqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
509 $ lorgqr, childinfo )
511 IF( wantu2 .AND. m-p .GT. 0 )
THEN
512 CALL slacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
513 CALL sorgqr( m-p, m-p, q, u2, ldu2, work(itaup2),
514 $ work(iorgqr), lorgqr, childinfo )
516 IF( wantv1t .AND. q .GT. 0 )
THEN
522 CALL slacpy(
'U', q-1, q-1, x21(1,2), ldx21, v1t(2,2),
524 CALL sorglq( q-1, q-1, q-1, v1t(2,2), ldv1t, work(itauq1),
525 $ work(iorglq), lorglq, childinfo )
530 CALL sbbcsd( jobu1, jobu2, jobv1t,
'N',
'N', m, p, q, theta,
531 $ work(iphi), u1, ldu1, u2, ldu2, v1t, ldv1t,
532 $ dum2, 1, work(ib11d), work(ib11e), work(ib12d),
533 $ work(ib12e), work(ib21d), work(ib21e),
534 $ work(ib22d), work(ib22e), work(ibbcsd), lbbcsd,
540 IF( q .GT. 0 .AND. wantu2 )
THEN
542 iwork(i) = m - p - q + i
547 CALL slapmt( .false., m-p, m-p, u2, ldu2, iwork )
549 ELSE IF( r .EQ. p )
THEN
555 CALL sorbdb2( m, p, q, x11, ldx11, x21, ldx21, theta,
556 $ work(iphi), work(itaup1), work(itaup2),
557 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
561 IF( wantu1 .AND. p .GT. 0 )
THEN
567 CALL slacpy(
'L', p-1, p-1, x11(2,1), ldx11, u1(2,2), ldu1 )
568 CALL sorgqr( p-1, p-1, p-1, u1(2,2), ldu1, work(itaup1),
569 $ work(iorgqr), lorgqr, childinfo )
571 IF( wantu2 .AND. m-p .GT. 0 )
THEN
572 CALL slacpy(
'L', m-p, q, x21, ldx21, u2, ldu2 )
573 CALL sorgqr( m-p, m-p, q, u2, ldu2, work(itaup2),
574 $ work(iorgqr), lorgqr, childinfo )
576 IF( wantv1t .AND. q .GT. 0 )
THEN
577 CALL slacpy(
'U', p, q, x11, ldx11, v1t, ldv1t )
578 CALL sorglq( q, q, r, v1t, ldv1t, work(itauq1),
579 $ work(iorglq), lorglq, childinfo )
584 CALL sbbcsd( jobv1t,
'N', jobu1, jobu2,
'T', m, q, p, theta,
585 $ work(iphi), v1t, ldv1t, dum1, 1, u1, ldu1, u2,
586 $ ldu2, work(ib11d), work(ib11e), work(ib12d),
587 $ work(ib12e), work(ib21d), work(ib21e),
588 $ work(ib22d), work(ib22e), work(ibbcsd), lbbcsd,
594 IF( q .GT. 0 .AND. wantu2 )
THEN
596 iwork(i) = m - p - q + i
601 CALL slapmt( .false., m-p, m-p, u2, ldu2, iwork )
603 ELSE IF( r .EQ. m-p )
THEN
609 CALL sorbdb3( m, p, q, x11, ldx11, x21, ldx21, theta,
610 $ work(iphi), work(itaup1), work(itaup2),
611 $ work(itauq1), work(iorbdb), lorbdb, childinfo )
615 IF( wantu1 .AND. p .GT. 0 )
THEN
616 CALL slacpy(
'L', p, q, x11, ldx11, u1, ldu1 )
617 CALL sorgqr( p, p, q, u1, ldu1, work(itaup1), work(iorgqr),
618 $ lorgqr, childinfo )
620 IF( wantu2 .AND. m-p .GT. 0 )
THEN
626 CALL slacpy(
'L', m-p-1, m-p-1, x21(2,1), ldx21, u2(2,2),
628 CALL sorgqr( m-p-1, m-p-1, m-p-1, u2(2,2), ldu2,
629 $ work(itaup2), work(iorgqr), lorgqr, childinfo )
631 IF( wantv1t .AND. q .GT. 0 )
THEN
632 CALL slacpy(
'U', m-p, q, x21, ldx21, v1t, ldv1t )
633 CALL sorglq( q, q, r, v1t, ldv1t, work(itauq1),
634 $ work(iorglq), lorglq, childinfo )
639 CALL sbbcsd(
'N', jobv1t, jobu2, jobu1,
'T', m, m-q, m-p,
640 $ theta, work(iphi), dum1, 1, v1t, ldv1t, u2,
641 $ ldu2, u1, ldu1, work(ib11d), work(ib11e),
642 $ work(ib12d), work(ib12e), work(ib21d),
643 $ work(ib21e), work(ib22d), work(ib22e),
644 $ work(ibbcsd), lbbcsd, childinfo )
657 CALL slapmt( .false., p, q, u1, ldu1, iwork )
660 CALL slapmr( .false., q, q, v1t, ldv1t, iwork )
669 CALL sorbdb4( m, p, q, x11, ldx11, x21, ldx21, theta,
670 $ work(iphi), work(itaup1), work(itaup2),
671 $ work(itauq1), work(iorbdb), work(iorbdb+m),
672 $ lorbdb-m, childinfo )
676 IF( wantu1 .AND. p .GT. 0 )
THEN
677 CALL scopy( p, work(iorbdb), 1, u1, 1 )
681 CALL slacpy(
'L', p-1, m-q-1, x11(2,1), ldx11, u1(2,2),
683 CALL sorgqr( p, p, m-q, u1, ldu1, work(itaup1),
684 $ work(iorgqr), lorgqr, childinfo )
686 IF( wantu2 .AND. m-p .GT. 0 )
THEN
687 CALL scopy( m-p, work(iorbdb+p), 1, u2, 1 )
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 IF( wantv1t .AND. q .GT. 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 )
subroutine sorglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGLQ
subroutine slapmt(FORWRD, M, N, X, LDX, K)
SLAPMT performs a forward or backward permutation of the columns of a matrix.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine sorbdb4(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, INFO)
SORBDB4
subroutine slapmr(FORWRD, M, N, X, LDX, K)
SLAPMR rearranges rows of a matrix as specified by a permutation vector.
subroutine sorbdb2(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
SORBDB2
subroutine sorbdb1(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
SORBDB1
subroutine sorbdb3(M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)
SORBDB3
subroutine sbbcsd(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, WORK, LWORK, INFO)
SBBCSD
subroutine sorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGQR
logical function lsame(CA, CB)
LSAME
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY