331
332
333
334
335
336
337 CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
338 INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LRWORK, M, P, Q
339
340
341 REAL B11D( * ), B11E( * ), B12D( * ), B12E( * ),
342 $ B21D( * ), B21E( * ), B22D( * ), B22E( * ),
343 $ PHI( * ), THETA( * ), RWORK( * )
344 COMPLEX U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
345 $ V2T( LDV2T, * )
346
347
348
349
350
351 INTEGER MAXITR
352 parameter( maxitr = 6 )
353 REAL HUNDRED, MEIGHTH, ONE, TEN, ZERO
354 parameter( hundred = 100.0e0, meighth = -0.125e0,
355 $ one = 1.0e0, ten = 10.0e0, zero = 0.0e0 )
356 COMPLEX NEGONECOMPLEX
357 parameter( negonecomplex = (-1.0e0,0.0e0) )
358 REAL PIOVER2
359 parameter( piover2 = 1.57079632679489661923132169163975144210e0 )
360
361
362 LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12,
363 $ RESTART21, RESTART22, WANTU1, WANTU2, WANTV1T,
364 $ WANTV2T
365 INTEGER I, IMIN, IMAX, ITER, IU1CS, IU1SN, IU2CS,
366 $ IU2SN, IV1TCS, IV1TSN, IV2TCS, IV2TSN, J,
367 $ LRWORKMIN, LRWORKOPT, MAXIT, MINI
368 REAL B11BULGE, B12BULGE, B21BULGE, B22BULGE, DUMMY,
369 $ EPS, MU, NU, R, SIGMA11, SIGMA21,
370 $ TEMP, THETAMAX, THETAMIN, THRESH, TOL, TOLMUL,
371 $ UNFL, X1, X2, Y1, Y2
372
373
377
378
379 REAL SLAMCH
380 LOGICAL LSAME
382
383
384 INTRINSIC abs, atan2, cos, max, min, sin, sqrt
385
386
387
388
389
390 info = 0
391 lquery = lrwork .EQ. -1
392 wantu1 =
lsame( jobu1,
'Y' )
393 wantu2 =
lsame( jobu2,
'Y' )
394 wantv1t =
lsame( jobv1t,
'Y' )
395 wantv2t =
lsame( jobv2t,
'Y' )
396 colmajor = .NOT.
lsame( trans,
'T' )
397
398 IF( m .LT. 0 ) THEN
399 info = -6
400 ELSE IF( p .LT. 0 .OR. p .GT. m ) THEN
401 info = -7
402 ELSE IF( q .LT. 0 .OR. q .GT. m ) THEN
403 info = -8
404 ELSE IF( q .GT. p .OR. q .GT. m-p .OR. q .GT. m-q ) THEN
405 info = -8
406 ELSE IF( wantu1 .AND. ldu1 .LT. p ) THEN
407 info = -12
408 ELSE IF( wantu2 .AND. ldu2 .LT. m-p ) THEN
409 info = -14
410 ELSE IF( wantv1t .AND. ldv1t .LT. q ) THEN
411 info = -16
412 ELSE IF( wantv2t .AND. ldv2t .LT. m-q ) THEN
413 info = -18
414 END IF
415
416
417
418 IF( info .EQ. 0 .AND. q .EQ. 0 ) THEN
419 lrworkmin = 1
420 rwork(1) = real( lrworkmin )
421 RETURN
422 END IF
423
424
425
426 IF( info .EQ. 0 ) THEN
427 iu1cs = 1
428 iu1sn = iu1cs + q
429 iu2cs = iu1sn + q
430 iu2sn = iu2cs + q
431 iv1tcs = iu2sn + q
432 iv1tsn = iv1tcs + q
433 iv2tcs = iv1tsn + q
434 iv2tsn = iv2tcs + q
435 lrworkopt = iv2tsn + q - 1
436 lrworkmin = lrworkopt
437 rwork(1) = real( lrworkopt )
438 IF( lrwork .LT. lrworkmin .AND. .NOT. lquery ) THEN
439 info = -28
440 END IF
441 END IF
442
443 IF( info .NE. 0 ) THEN
444 CALL xerbla(
'CBBCSD', -info )
445 RETURN
446 ELSE IF( lquery ) THEN
447 RETURN
448 END IF
449
450
451
453 unfl =
slamch(
'Safe minimum' )
454 tolmul = max( ten, min( hundred, eps**meighth ) )
455 tol = tolmul*eps
456 thresh = max( tol, real( maxitr*q*q )*unfl )
457
458
459
460 DO i = 1, q
461 IF( theta(i) .LT. thresh ) THEN
462 theta(i) = zero
463 ELSE IF( theta(i) .GT. piover2-thresh ) THEN
464 theta(i) = piover2
465 END IF
466 END DO
467 DO i = 1, q-1
468 IF( phi(i) .LT. thresh ) THEN
469 phi(i) = zero
470 ELSE IF( phi(i) .GT. piover2-thresh ) THEN
471 phi(i) = piover2
472 END IF
473 END DO
474
475
476
477 imax = q
478 DO WHILE( imax .GT. 1 )
479 IF( phi(imax-1) .NE. zero ) THEN
480 EXIT
481 END IF
482 imax = imax - 1
483 END DO
484 imin = imax - 1
485 IF ( imin .GT. 1 ) THEN
486 DO WHILE( phi(imin-1) .NE. zero )
487 imin = imin - 1
488 IF ( imin .LE. 1 ) EXIT
489 END DO
490 END IF
491
492
493
494 maxit = maxitr*q*q
495 iter = 0
496
497
498
499 DO WHILE( imax .GT. 1 )
500
501
502
503 b11d(imin) = cos( theta(imin) )
504 b21d(imin) = -sin( theta(imin) )
505 DO i = imin, imax - 1
506 b11e(i) = -sin( theta(i) ) * sin( phi(i) )
507 b11d(i+1) = cos( theta(i+1) ) * cos( phi(i) )
508 b12d(i) = sin( theta(i) ) * cos( phi(i) )
509 b12e(i) = cos( theta(i+1) ) * sin( phi(i) )
510 b21e(i) = -cos( theta(i) ) * sin( phi(i) )
511 b21d(i+1) = -sin( theta(i+1) ) * cos( phi(i) )
512 b22d(i) = cos( theta(i) ) * cos( phi(i) )
513 b22e(i) = -sin( theta(i+1) ) * sin( phi(i) )
514 END DO
515 b12d(imax) = sin( theta(imax) )
516 b22d(imax) = cos( theta(imax) )
517
518
519
520 IF( iter .GT. maxit ) THEN
521 info = 0
522 DO i = 1, q
523 IF( phi(i) .NE. zero )
524 $ info = info + 1
525 END DO
526 RETURN
527 END IF
528
529 iter = iter + imax - imin
530
531
532
533 thetamax = theta(imin)
534 thetamin = theta(imin)
535 DO i = imin+1, imax
536 IF( theta(i) > thetamax )
537 $ thetamax = theta(i)
538 IF( theta(i) < thetamin )
539 $ thetamin = theta(i)
540 END DO
541
542 IF( thetamax .GT. piover2 - thresh ) THEN
543
544
545
546
547 mu = zero
548 nu = one
549
550 ELSE IF( thetamin .LT. thresh ) THEN
551
552
553
554
555 mu = one
556 nu = zero
557
558 ELSE
559
560
561
562 CALL slas2( b11d(imax-1), b11e(imax-1), b11d(imax),
563 $ sigma11,
564 $ dummy )
565 CALL slas2( b21d(imax-1), b21e(imax-1), b21d(imax),
566 $ sigma21,
567 $ dummy )
568
569 IF( sigma11 .LE. sigma21 ) THEN
570 mu = sigma11
571 nu = sqrt( one - mu**2 )
572 IF( mu .LT. thresh ) THEN
573 mu = zero
574 nu = one
575 END IF
576 ELSE
577 nu = sigma21
578 mu = sqrt( 1.0 - nu**2 )
579 IF( nu .LT. thresh ) THEN
580 mu = one
581 nu = zero
582 END IF
583 END IF
584 END IF
585
586
587
588 IF( mu .LE. nu ) THEN
589 CALL slartgs( b11d(imin), b11e(imin), mu,
590 $ rwork(iv1tcs+imin-1), rwork(iv1tsn+imin-1) )
591 ELSE
592 CALL slartgs( b21d(imin), b21e(imin), nu,
593 $ rwork(iv1tcs+imin-1), rwork(iv1tsn+imin-1) )
594 END IF
595
596 temp = rwork(iv1tcs+imin-1)*b11d(imin) +
597 $ rwork(iv1tsn+imin-1)*b11e(imin)
598 b11e(imin) = rwork(iv1tcs+imin-1)*b11e(imin) -
599 $ rwork(iv1tsn+imin-1)*b11d(imin)
600 b11d(imin) = temp
601 b11bulge = rwork(iv1tsn+imin-1)*b11d(imin+1)
602 b11d(imin+1) = rwork(iv1tcs+imin-1)*b11d(imin+1)
603 temp = rwork(iv1tcs+imin-1)*b21d(imin) +
604 $ rwork(iv1tsn+imin-1)*b21e(imin)
605 b21e(imin) = rwork(iv1tcs+imin-1)*b21e(imin) -
606 $ rwork(iv1tsn+imin-1)*b21d(imin)
607 b21d(imin) = temp
608 b21bulge = rwork(iv1tsn+imin-1)*b21d(imin+1)
609 b21d(imin+1) = rwork(iv1tcs+imin-1)*b21d(imin+1)
610
611
612
613 theta( imin ) = atan2( sqrt( b21d(imin)**2+b21bulge**2 ),
614 $ sqrt( b11d(imin)**2+b11bulge**2 ) )
615
616
617
618 IF( b11d(imin)**2+b11bulge**2 .GT. thresh**2 ) THEN
619 CALL slartgp( b11bulge, b11d(imin), rwork(iu1sn+imin-1),
620 $ rwork(iu1cs+imin-1), r )
621 ELSE IF( mu .LE. nu ) THEN
622 CALL slartgs( b11e( imin ), b11d( imin + 1 ), mu,
623 $ rwork(iu1cs+imin-1), rwork(iu1sn+imin-1) )
624 ELSE
625 CALL slartgs( b12d( imin ), b12e( imin ), nu,
626 $ rwork(iu1cs+imin-1), rwork(iu1sn+imin-1) )
627 END IF
628 IF( b21d(imin)**2+b21bulge**2 .GT. thresh**2 ) THEN
629 CALL slartgp( b21bulge, b21d(imin), rwork(iu2sn+imin-1),
630 $ rwork(iu2cs+imin-1), r )
631 ELSE IF( nu .LT. mu ) THEN
632 CALL slartgs( b21e( imin ), b21d( imin + 1 ), nu,
633 $ rwork(iu2cs+imin-1), rwork(iu2sn+imin-1) )
634 ELSE
635 CALL slartgs( b22d(imin), b22e(imin), mu,
636 $ rwork(iu2cs+imin-1), rwork(iu2sn+imin-1) )
637 END IF
638 rwork(iu2cs+imin-1) = -rwork(iu2cs+imin-1)
639 rwork(iu2sn+imin-1) = -rwork(iu2sn+imin-1)
640
641 temp = rwork(iu1cs+imin-1)*b11e(imin) +
642 $ rwork(iu1sn+imin-1)*b11d(imin+1)
643 b11d(imin+1) = rwork(iu1cs+imin-1)*b11d(imin+1) -
644 $ rwork(iu1sn+imin-1)*b11e(imin)
645 b11e(imin) = temp
646 IF( imax .GT. imin+1 ) THEN
647 b11bulge = rwork(iu1sn+imin-1)*b11e(imin+1)
648 b11e(imin+1) = rwork(iu1cs+imin-1)*b11e(imin+1)
649 END IF
650 temp = rwork(iu1cs+imin-1)*b12d(imin) +
651 $ rwork(iu1sn+imin-1)*b12e(imin)
652 b12e(imin) = rwork(iu1cs+imin-1)*b12e(imin) -
653 $ rwork(iu1sn+imin-1)*b12d(imin)
654 b12d(imin) = temp
655 b12bulge = rwork(iu1sn+imin-1)*b12d(imin+1)
656 b12d(imin+1) = rwork(iu1cs+imin-1)*b12d(imin+1)
657 temp = rwork(iu2cs+imin-1)*b21e(imin) +
658 $ rwork(iu2sn+imin-1)*b21d(imin+1)
659 b21d(imin+1) = rwork(iu2cs+imin-1)*b21d(imin+1) -
660 $ rwork(iu2sn+imin-1)*b21e(imin)
661 b21e(imin) = temp
662 IF( imax .GT. imin+1 ) THEN
663 b21bulge = rwork(iu2sn+imin-1)*b21e(imin+1)
664 b21e(imin+1) = rwork(iu2cs+imin-1)*b21e(imin+1)
665 END IF
666 temp = rwork(iu2cs+imin-1)*b22d(imin) +
667 $ rwork(iu2sn+imin-1)*b22e(imin)
668 b22e(imin) = rwork(iu2cs+imin-1)*b22e(imin) -
669 $ rwork(iu2sn+imin-1)*b22d(imin)
670 b22d(imin) = temp
671 b22bulge = rwork(iu2sn+imin-1)*b22d(imin+1)
672 b22d(imin+1) = rwork(iu2cs+imin-1)*b22d(imin+1)
673
674
675
676
677
678 DO i = imin+1, imax-1
679
680
681
682 x1 = sin(theta(i-1))*b11e(i-1) + cos(theta(i-1))*b21e(i-1)
683 x2 = sin(theta(i-1))*b11bulge + cos(theta(i-1))*b21bulge
684 y1 = sin(theta(i-1))*b12d(i-1) + cos(theta(i-1))*b22d(i-1)
685 y2 = sin(theta(i-1))*b12bulge + cos(theta(i-1))*b22bulge
686
687 phi(i-1) = atan2( sqrt(x1**2+x2**2), sqrt(y1**2+y2**2) )
688
689
690
691
692 restart11 = b11e(i-1)**2 + b11bulge**2 .LE. thresh**2
693 restart21 = b21e(i-1)**2 + b21bulge**2 .LE. thresh**2
694 restart12 = b12d(i-1)**2 + b12bulge**2 .LE. thresh**2
695 restart22 = b22d(i-1)**2 + b22bulge**2 .LE. thresh**2
696
697
698
699
700
701 IF( .NOT. restart11 .AND. .NOT. restart21 ) THEN
702 CALL slartgp( x2, x1, rwork(iv1tsn+i-1),
703 $ rwork(iv1tcs+i-1), r )
704 ELSE IF( .NOT. restart11 .AND. restart21 ) THEN
705 CALL slartgp( b11bulge, b11e(i-1), rwork(iv1tsn+i-1),
706 $ rwork(iv1tcs+i-1), r )
707 ELSE IF( restart11 .AND. .NOT. restart21 ) THEN
708 CALL slartgp( b21bulge, b21e(i-1), rwork(iv1tsn+i-1),
709 $ rwork(iv1tcs+i-1), r )
710 ELSE IF( mu .LE. nu ) THEN
711 CALL slartgs( b11d(i), b11e(i), mu, rwork(iv1tcs+i-1),
712 $ rwork(iv1tsn+i-1) )
713 ELSE
714 CALL slartgs( b21d(i), b21e(i), nu, rwork(iv1tcs+i-1),
715 $ rwork(iv1tsn+i-1) )
716 END IF
717 rwork(iv1tcs+i-1) = -rwork(iv1tcs+i-1)
718 rwork(iv1tsn+i-1) = -rwork(iv1tsn+i-1)
719 IF( .NOT. restart12 .AND. .NOT. restart22 ) THEN
720 CALL slartgp( y2, y1, rwork(iv2tsn+i-1-1),
721 $ rwork(iv2tcs+i-1-1), r )
722 ELSE IF( .NOT. restart12 .AND. restart22 ) THEN
723 CALL slartgp( b12bulge, b12d(i-1),
724 $ rwork(iv2tsn+i-1-1),
725 $ rwork(iv2tcs+i-1-1), r )
726 ELSE IF( restart12 .AND. .NOT. restart22 ) THEN
727 CALL slartgp( b22bulge, b22d(i-1),
728 $ rwork(iv2tsn+i-1-1),
729 $ rwork(iv2tcs+i-1-1), r )
730 ELSE IF( nu .LT. mu ) THEN
731 CALL slartgs( b12e(i-1), b12d(i), nu,
732 $ rwork(iv2tcs+i-1-1), rwork(iv2tsn+i-1-1) )
733 ELSE
734 CALL slartgs( b22e(i-1), b22d(i), mu,
735 $ rwork(iv2tcs+i-1-1), rwork(iv2tsn+i-1-1) )
736 END IF
737
738 temp = rwork(iv1tcs+i-1)*b11d(i) + rwork(iv1tsn+i-1)*b11e(i)
739 b11e(i) = rwork(iv1tcs+i-1)*b11e(i) -
740 $ rwork(iv1tsn+i-1)*b11d(i)
741 b11d(i) = temp
742 b11bulge = rwork(iv1tsn+i-1)*b11d(i+1)
743 b11d(i+1) = rwork(iv1tcs+i-1)*b11d(i+1)
744 temp = rwork(iv1tcs+i-1)*b21d(i) + rwork(iv1tsn+i-1)*b21e(i)
745 b21e(i) = rwork(iv1tcs+i-1)*b21e(i) -
746 $ rwork(iv1tsn+i-1)*b21d(i)
747 b21d(i) = temp
748 b21bulge = rwork(iv1tsn+i-1)*b21d(i+1)
749 b21d(i+1) = rwork(iv1tcs+i-1)*b21d(i+1)
750 temp = rwork(iv2tcs+i-1-1)*b12e(i-1) +
751 $ rwork(iv2tsn+i-1-1)*b12d(i)
752 b12d(i) = rwork(iv2tcs+i-1-1)*b12d(i) -
753 $ rwork(iv2tsn+i-1-1)*b12e(i-1)
754 b12e(i-1) = temp
755 b12bulge = rwork(iv2tsn+i-1-1)*b12e(i)
756 b12e(i) = rwork(iv2tcs+i-1-1)*b12e(i)
757 temp = rwork(iv2tcs+i-1-1)*b22e(i-1) +
758 $ rwork(iv2tsn+i-1-1)*b22d(i)
759 b22d(i) = rwork(iv2tcs+i-1-1)*b22d(i) -
760 $ rwork(iv2tsn+i-1-1)*b22e(i-1)
761 b22e(i-1) = temp
762 b22bulge = rwork(iv2tsn+i-1-1)*b22e(i)
763 b22e(i) = rwork(iv2tcs+i-1-1)*b22e(i)
764
765
766
767 x1 = cos(phi(i-1))*b11d(i) + sin(phi(i-1))*b12e(i-1)
768 x2 = cos(phi(i-1))*b11bulge + sin(phi(i-1))*b12bulge
769 y1 = cos(phi(i-1))*b21d(i) + sin(phi(i-1))*b22e(i-1)
770 y2 = cos(phi(i-1))*b21bulge + sin(phi(i-1))*b22bulge
771
772 theta(i) = atan2( sqrt(y1**2+y2**2), sqrt(x1**2+x2**2) )
773
774
775
776
777 restart11 = b11d(i)**2 + b11bulge**2 .LE. thresh**2
778 restart12 = b12e(i-1)**2 + b12bulge**2 .LE. thresh**2
779 restart21 = b21d(i)**2 + b21bulge**2 .LE. thresh**2
780 restart22 = b22e(i-1)**2 + b22bulge**2 .LE. thresh**2
781
782
783
784
785
786 IF( .NOT. restart11 .AND. .NOT. restart12 ) THEN
787 CALL slartgp( x2, x1, rwork(iu1sn+i-1),
788 $ rwork(iu1cs+i-1),
789 $ r )
790 ELSE IF( .NOT. restart11 .AND. restart12 ) THEN
791 CALL slartgp( b11bulge, b11d(i), rwork(iu1sn+i-1),
792 $ rwork(iu1cs+i-1), r )
793 ELSE IF( restart11 .AND. .NOT. restart12 ) THEN
794 CALL slartgp( b12bulge, b12e(i-1), rwork(iu1sn+i-1),
795 $ rwork(iu1cs+i-1), r )
796 ELSE IF( mu .LE. nu ) THEN
797 CALL slartgs( b11e(i), b11d(i+1), mu,
798 $ rwork(iu1cs+i-1),
799 $ rwork(iu1sn+i-1) )
800 ELSE
801 CALL slartgs( b12d(i), b12e(i), nu, rwork(iu1cs+i-1),
802 $ rwork(iu1sn+i-1) )
803 END IF
804 IF( .NOT. restart21 .AND. .NOT. restart22 ) THEN
805 CALL slartgp( y2, y1, rwork(iu2sn+i-1),
806 $ rwork(iu2cs+i-1),
807 $ r )
808 ELSE IF( .NOT. restart21 .AND. restart22 ) THEN
809 CALL slartgp( b21bulge, b21d(i), rwork(iu2sn+i-1),
810 $ rwork(iu2cs+i-1), r )
811 ELSE IF( restart21 .AND. .NOT. restart22 ) THEN
812 CALL slartgp( b22bulge, b22e(i-1), rwork(iu2sn+i-1),
813 $ rwork(iu2cs+i-1), r )
814 ELSE IF( nu .LT. mu ) THEN
815 CALL slartgs( b21e(i), b21e(i+1), nu,
816 $ rwork(iu2cs+i-1),
817 $ rwork(iu2sn+i-1) )
818 ELSE
819 CALL slartgs( b22d(i), b22e(i), mu, rwork(iu2cs+i-1),
820 $ rwork(iu2sn+i-1) )
821 END IF
822 rwork(iu2cs+i-1) = -rwork(iu2cs+i-1)
823 rwork(iu2sn+i-1) = -rwork(iu2sn+i-1)
824
825 temp = rwork(iu1cs+i-1)*b11e(i) + rwork(iu1sn+i-1)*b11d(i+1)
826 b11d(i+1) = rwork(iu1cs+i-1)*b11d(i+1) -
827 $ rwork(iu1sn+i-1)*b11e(i)
828 b11e(i) = temp
829 IF( i .LT. imax - 1 ) THEN
830 b11bulge = rwork(iu1sn+i-1)*b11e(i+1)
831 b11e(i+1) = rwork(iu1cs+i-1)*b11e(i+1)
832 END IF
833 temp = rwork(iu2cs+i-1)*b21e(i) + rwork(iu2sn+i-1)*b21d(i+1)
834 b21d(i+1) = rwork(iu2cs+i-1)*b21d(i+1) -
835 $ rwork(iu2sn+i-1)*b21e(i)
836 b21e(i) = temp
837 IF( i .LT. imax - 1 ) THEN
838 b21bulge = rwork(iu2sn+i-1)*b21e(i+1)
839 b21e(i+1) = rwork(iu2cs+i-1)*b21e(i+1)
840 END IF
841 temp = rwork(iu1cs+i-1)*b12d(i) + rwork(iu1sn+i-1)*b12e(i)
842 b12e(i) = rwork(iu1cs+i-1)*b12e(i) -
843 $ rwork(iu1sn+i-1)*b12d(i)
844 b12d(i) = temp
845 b12bulge = rwork(iu1sn+i-1)*b12d(i+1)
846 b12d(i+1) = rwork(iu1cs+i-1)*b12d(i+1)
847 temp = rwork(iu2cs+i-1)*b22d(i) + rwork(iu2sn+i-1)*b22e(i)
848 b22e(i) = rwork(iu2cs+i-1)*b22e(i) -
849 $ rwork(iu2sn+i-1)*b22d(i)
850 b22d(i) = temp
851 b22bulge = rwork(iu2sn+i-1)*b22d(i+1)
852 b22d(i+1) = rwork(iu2cs+i-1)*b22d(i+1)
853
854 END DO
855
856
857
858 x1 = sin(theta(imax-1))*b11e(imax-1) +
859 $ cos(theta(imax-1))*b21e(imax-1)
860 y1 = sin(theta(imax-1))*b12d(imax-1) +
861 $ cos(theta(imax-1))*b22d(imax-1)
862 y2 = sin(theta(imax-1))*b12bulge + cos(theta(imax-1))*b22bulge
863
864 phi(imax-1) = atan2( abs(x1), sqrt(y1**2+y2**2) )
865
866
867
868 restart12 = b12d(imax-1)**2 + b12bulge**2 .LE. thresh**2
869 restart22 = b22d(imax-1)**2 + b22bulge**2 .LE. thresh**2
870
871 IF( .NOT. restart12 .AND. .NOT. restart22 ) THEN
872 CALL slartgp( y2, y1, rwork(iv2tsn+imax-1-1),
873 $ rwork(iv2tcs+imax-1-1), r )
874 ELSE IF( .NOT. restart12 .AND. restart22 ) THEN
875 CALL slartgp( b12bulge, b12d(imax-1),
876 $ rwork(iv2tsn+imax-1-1),
877 $ rwork(iv2tcs+imax-1-1), r )
878 ELSE IF( restart12 .AND. .NOT. restart22 ) THEN
879 CALL slartgp( b22bulge, b22d(imax-1),
880 $ rwork(iv2tsn+imax-1-1),
881 $ rwork(iv2tcs+imax-1-1), r )
882 ELSE IF( nu .LT. mu ) THEN
883 CALL slartgs( b12e(imax-1), b12d(imax), nu,
884 $ rwork(iv2tcs+imax-1-1),
885 $ rwork(iv2tsn+imax-1-1) )
886 ELSE
887 CALL slartgs( b22e(imax-1), b22d(imax), mu,
888 $ rwork(iv2tcs+imax-1-1),
889 $ rwork(iv2tsn+imax-1-1) )
890 END IF
891
892 temp = rwork(iv2tcs+imax-1-1)*b12e(imax-1) +
893 $ rwork(iv2tsn+imax-1-1)*b12d(imax)
894 b12d(imax) = rwork(iv2tcs+imax-1-1)*b12d(imax) -
895 $ rwork(iv2tsn+imax-1-1)*b12e(imax-1)
896 b12e(imax-1) = temp
897 temp = rwork(iv2tcs+imax-1-1)*b22e(imax-1) +
898 $ rwork(iv2tsn+imax-1-1)*b22d(imax)
899 b22d(imax) = rwork(iv2tcs+imax-1-1)*b22d(imax) -
900 $ rwork(iv2tsn+imax-1-1)*b22e(imax-1)
901 b22e(imax-1) = temp
902
903
904
905 IF( wantu1 ) THEN
906 IF( colmajor ) THEN
907 CALL clasr(
'R',
'V',
'F', p, imax-imin+1,
908 $ rwork(iu1cs+imin-1), rwork(iu1sn+imin-1),
909 $ u1(1,imin), ldu1 )
910 ELSE
911 CALL clasr(
'L',
'V',
'F', imax-imin+1, p,
912 $ rwork(iu1cs+imin-1), rwork(iu1sn+imin-1),
913 $ u1(imin,1), ldu1 )
914 END IF
915 END IF
916 IF( wantu2 ) THEN
917 IF( colmajor ) THEN
918 CALL clasr(
'R',
'V',
'F', m-p, imax-imin+1,
919 $ rwork(iu2cs+imin-1), rwork(iu2sn+imin-1),
920 $ u2(1,imin), ldu2 )
921 ELSE
922 CALL clasr(
'L',
'V',
'F', imax-imin+1, m-p,
923 $ rwork(iu2cs+imin-1), rwork(iu2sn+imin-1),
924 $ u2(imin,1), ldu2 )
925 END IF
926 END IF
927 IF( wantv1t ) THEN
928 IF( colmajor ) THEN
929 CALL clasr(
'L',
'V',
'F', imax-imin+1, q,
930 $ rwork(iv1tcs+imin-1), rwork(iv1tsn+imin-1),
931 $ v1t(imin,1), ldv1t )
932 ELSE
933 CALL clasr(
'R',
'V',
'F', q, imax-imin+1,
934 $ rwork(iv1tcs+imin-1), rwork(iv1tsn+imin-1),
935 $ v1t(1,imin), ldv1t )
936 END IF
937 END IF
938 IF( wantv2t ) THEN
939 IF( colmajor ) THEN
940 CALL clasr(
'L',
'V',
'F', imax-imin+1, m-q,
941 $ rwork(iv2tcs+imin-1), rwork(iv2tsn+imin-1),
942 $ v2t(imin,1), ldv2t )
943 ELSE
944 CALL clasr(
'R',
'V',
'F', m-q, imax-imin+1,
945 $ rwork(iv2tcs+imin-1), rwork(iv2tsn+imin-1),
946 $ v2t(1,imin), ldv2t )
947 END IF
948 END IF
949
950
951
952 IF( b11e(imax-1)+b21e(imax-1) .GT. 0 ) THEN
953 b11d(imax) = -b11d(imax)
954 b21d(imax) = -b21d(imax)
955 IF( wantv1t ) THEN
956 IF( colmajor ) THEN
957 CALL cscal( q, negonecomplex, v1t(imax,1), ldv1t )
958 ELSE
959 CALL cscal( q, negonecomplex, v1t(1,imax), 1 )
960 END IF
961 END IF
962 END IF
963
964
965
966 x1 = cos(phi(imax-1))*b11d(imax) +
967 $ sin(phi(imax-1))*b12e(imax-1)
968 y1 = cos(phi(imax-1))*b21d(imax) +
969 $ sin(phi(imax-1))*b22e(imax-1)
970
971 theta(imax) = atan2( abs(y1), abs(x1) )
972
973
974
975
976 IF( b11d(imax)+b12e(imax-1) .LT. 0 ) THEN
977 b12d(imax) = -b12d(imax)
978 IF( wantu1 ) THEN
979 IF( colmajor ) THEN
980 CALL cscal( p, negonecomplex, u1(1,imax), 1 )
981 ELSE
982 CALL cscal( p, negonecomplex, u1(imax,1), ldu1 )
983 END IF
984 END IF
985 END IF
986 IF( b21d(imax)+b22e(imax-1) .GT. 0 ) THEN
987 b22d(imax) = -b22d(imax)
988 IF( wantu2 ) THEN
989 IF( colmajor ) THEN
990 CALL cscal( m-p, negonecomplex, u2(1,imax), 1 )
991 ELSE
992 CALL cscal( m-p, negonecomplex, u2(imax,1), ldu2 )
993 END IF
994 END IF
995 END IF
996
997
998
999 IF( b12d(imax)+b22d(imax) .LT. 0 ) THEN
1000 IF( wantv2t ) THEN
1001 IF( colmajor ) THEN
1002 CALL cscal( m-q, negonecomplex, v2t(imax,1),
1003 $ ldv2t )
1004 ELSE
1005 CALL cscal( m-q, negonecomplex, v2t(1,imax), 1 )
1006 END IF
1007 END IF
1008 END IF
1009
1010
1011
1012 DO i = imin, imax
1013 IF( theta(i) .LT. thresh ) THEN
1014 theta(i) = zero
1015 ELSE IF( theta(i) .GT. piover2-thresh ) THEN
1016 theta(i) = piover2
1017 END IF
1018 END DO
1019 DO i = imin, imax-1
1020 IF( phi(i) .LT. thresh ) THEN
1021 phi(i) = zero
1022 ELSE IF( phi(i) .GT. piover2-thresh ) THEN
1023 phi(i) = piover2
1024 END IF
1025 END DO
1026
1027
1028
1029 IF (imax .GT. 1) THEN
1030 DO WHILE( phi(imax-1) .EQ. zero )
1031 imax = imax - 1
1032 IF (imax .LE. 1) EXIT
1033 END DO
1034 END IF
1035 IF( imin .GT. imax - 1 )
1036 $ imin = imax - 1
1037 IF (imin .GT. 1) THEN
1038 DO WHILE (phi(imin-1) .NE. zero)
1039 imin = imin - 1
1040 IF (imin .LE. 1) EXIT
1041 END DO
1042 END IF
1043
1044
1045
1046 END DO
1047
1048
1049
1050 DO i = 1, q
1051
1052 mini = i
1053 thetamin = theta(i)
1054 DO j = i+1, q
1055 IF( theta(j) .LT. thetamin ) THEN
1056 mini = j
1057 thetamin = theta(j)
1058 END IF
1059 END DO
1060
1061 IF( mini .NE. i ) THEN
1062 theta(mini) = theta(i)
1063 theta(i) = thetamin
1064 IF( colmajor ) THEN
1065 IF( wantu1 )
1066 $
CALL cswap( p, u1(1,i), 1, u1(1,mini), 1 )
1067 IF( wantu2 )
1068 $
CALL cswap( m-p, u2(1,i), 1, u2(1,mini), 1 )
1069 IF( wantv1t )
1070 $
CALL cswap( q, v1t(i,1), ldv1t, v1t(mini,1),
1071 $ ldv1t )
1072 IF( wantv2t )
1073 $
CALL cswap( m-q, v2t(i,1), ldv2t, v2t(mini,1),
1074 $ ldv2t )
1075 ELSE
1076 IF( wantu1 )
1077 $
CALL cswap( p, u1(i,1), ldu1, u1(mini,1), ldu1 )
1078 IF( wantu2 )
1079 $
CALL cswap( m-p, u2(i,1), ldu2, u2(mini,1), ldu2 )
1080 IF( wantv1t )
1081 $
CALL cswap( q, v1t(1,i), 1, v1t(1,mini), 1 )
1082 IF( wantv2t )
1083 $
CALL cswap( m-q, v2t(1,i), 1, v2t(1,mini), 1 )
1084 END IF
1085 END IF
1086
1087 END DO
1088
1089 RETURN
1090
1091
1092
subroutine xerbla(srname, info)
real function slamch(cmach)
SLAMCH
subroutine slartgp(f, g, cs, sn, r)
SLARTGP generates a plane rotation so that the diagonal is nonnegative.
subroutine slartgs(x, y, sigma, cs, sn)
SLARTGS generates a plane rotation designed to introduce a bulge in implicit QR iteration for the bid...
subroutine slas2(f, g, h, ssmin, ssmax)
SLAS2 computes singular values of a 2-by-2 triangular matrix.
subroutine clasr(side, pivot, direct, m, n, c, s, a, lda)
CLASR applies a sequence of plane rotations to a general rectangular matrix.
logical function lsame(ca, cb)
LSAME
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP