268
269
270
271
272
273
274 CHARACTER JOBU, JOBVT, RANGE
275 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
276 REAL VL, VU
277
278
279 INTEGER IWORK( * )
280 REAL S( * ), RWORK( * )
281 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
282 $ WORK( * )
283
284
285
286
287
288 COMPLEX CZERO, CONE
289 parameter( czero = ( 0.0e0, 0.0e0 ),
290 $ cone = ( 1.0e0, 0.0e0 ) )
291 REAL ZERO, ONE
292 parameter( zero = 0.0e0, one = 1.0e0 )
293
294
295 CHARACTER JOBZ, RNGTGK
296 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
297 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
298 $ ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ,
299 $ IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
300 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
301
302
303 REAL DUM( 1 )
304
305
310
311
312 LOGICAL LSAME
313 INTEGER ILAENV
314 REAL SLAMCH, CLANGE, SROUNDUP_LWORK
317
318
319 INTRINSIC max, min, sqrt
320
321
322
323
324
325 ns = 0
326 info = 0
328 lquery = ( lwork.EQ.-1 )
329 minmn = min( m, n )
330
331 wantu =
lsame( jobu,
'V' )
332 wantvt =
lsame( jobvt,
'V' )
333 IF( wantu .OR. wantvt ) THEN
334 jobz = 'V'
335 ELSE
336 jobz = 'N'
337 END IF
338 alls =
lsame( range,
'A' )
339 vals =
lsame( range,
'V' )
340 inds =
lsame( range,
'I' )
341
342 info = 0
343 IF( .NOT.
lsame( jobu,
'V' ) .AND.
344 $ .NOT.
lsame( jobu,
'N' ) )
THEN
345 info = -1
346 ELSE IF( .NOT.
lsame( jobvt,
'V' ) .AND.
347 $ .NOT.
lsame( jobvt,
'N' ) )
THEN
348 info = -2
349 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) ) THEN
350 info = -3
351 ELSE IF( m.LT.0 ) THEN
352 info = -4
353 ELSE IF( n.LT.0 ) THEN
354 info = -5
355 ELSE IF( m.GT.lda ) THEN
356 info = -7
357 ELSE IF( minmn.GT.0 ) THEN
358 IF( vals ) THEN
359 IF( vl.LT.zero ) THEN
360 info = -8
361 ELSE IF( vu.LE.vl ) THEN
362 info = -9
363 END IF
364 ELSE IF( inds ) THEN
365 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) ) THEN
366 info = -10
367 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn ) THEN
368 info = -11
369 END IF
370 END IF
371 IF( info.EQ.0 ) THEN
372 IF( wantu .AND. ldu.LT.m ) THEN
373 info = -15
374 ELSE IF( wantvt ) THEN
375 IF( inds ) THEN
376 IF( ldvt.LT.iu-il+1 ) THEN
377 info = -17
378 END IF
379 ELSE IF( ldvt.LT.minmn ) THEN
380 info = -17
381 END IF
382 END IF
383 END IF
384 END IF
385
386
387
388
389
390
391
392
393 IF( info.EQ.0 ) THEN
394 minwrk = 1
395 maxwrk = 1
396 IF( minmn.GT.0 ) THEN
397 IF( m.GE.n ) THEN
398 mnthr =
ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0,
399 $ 0 )
400 IF( m.GE.mnthr ) THEN
401
402
403
404 minwrk = n*(n+5)
405 maxwrk = n + n*
ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
406 maxwrk = max(maxwrk,
407 $ n*n+2*n+2*n*
ilaenv(1,
'CGEBRD',
' ',n,n,-1,
408 $ -1))
409 IF (wantu .OR. wantvt) THEN
410 maxwrk = max(maxwrk,
411 $ n*n+2*n+n*
ilaenv(1,
'CUNMQR',
'LN',n,n,n,
412 $ -1))
413 END IF
414 ELSE
415
416
417
418 minwrk = 3*n + m
419 maxwrk = 2*n + (m+n)*
ilaenv(1,
'CGEBRD',
' ',m,n,-1,
420 $ -1)
421 IF (wantu .OR. wantvt) THEN
422 maxwrk = max(maxwrk,
423 $ 2*n+n*
ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
424 END IF
425 END IF
426 ELSE
427 mnthr =
ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0,
428 $ 0 )
429 IF( n.GE.mnthr ) THEN
430
431
432
433 minwrk = m*(m+5)
434 maxwrk = m + m*
ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
435 maxwrk = max(maxwrk,
436 $ m*m+2*m+2*m*
ilaenv(1,
'CGEBRD',
' ',m,m,-1,
437 $ -1))
438 IF (wantu .OR. wantvt) THEN
439 maxwrk = max(maxwrk,
440 $ m*m+2*m+m*
ilaenv(1,
'CUNMQR',
'LN',m,m,m,
441 $ -1))
442 END IF
443 ELSE
444
445
446
447
448 minwrk = 3*m + n
449 maxwrk = 2*m + (m+n)*
ilaenv(1,
'CGEBRD',
' ',m,n,-1,
450 $ -1)
451 IF (wantu .OR. wantvt) THEN
452 maxwrk = max(maxwrk,
453 $ 2*m+m*
ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
454 END IF
455 END IF
456 END IF
457 END IF
458 maxwrk = max( maxwrk, minwrk )
460
461 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
462 info = -19
463 END IF
464 END IF
465
466 IF( info.NE.0 ) THEN
467 CALL xerbla(
'CGESVDX', -info )
468 RETURN
469 ELSE IF( lquery ) THEN
470 RETURN
471 END IF
472
473
474
475 IF( minmn.EQ.0 ) THEN
476 RETURN
477 END IF
478
479
480
481 IF( alls ) THEN
482 rngtgk = 'I'
483 iltgk = 1
484 iutgk = min( m, n )
485 ELSE IF( inds ) THEN
486 rngtgk = 'I'
487 iltgk = il
488 iutgk = iu
489 ELSE
490 rngtgk = 'V'
491 iltgk = 0
492 iutgk = 0
493 END IF
494
495
496
498 smlnum = sqrt(
slamch(
'S' ) ) / eps
499 bignum = one / smlnum
500
501
502
503 anrm =
clange(
'M', m, n, a, lda, dum )
504 iscl = 0
505 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
506 iscl = 1
507 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
508 ELSE IF( anrm.GT.bignum ) THEN
509 iscl = 1
510 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
511 END IF
512
513 IF( m.GE.n ) THEN
514
515
516
517
518
519 IF( m.GE.mnthr ) THEN
520
521
522
523
524
525
526
527
528
529 itau = 1
530 itemp = itau + n
531 CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
532 $ lwork-itemp+1, info )
533
534
535
536
537 iqrf = itemp
538 itauq = itemp + n*n
539 itaup = itauq + n
540 itemp = itaup + n
541 id = 1
542 ie = id + n
543 itgkz = ie + n
544 CALL clacpy(
'U', n, n, a, lda, work( iqrf ), n )
545 CALL claset(
'L', n-1, n-1, czero, czero,
546 $ work( iqrf+1 ), n )
547 CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
548 $ rwork( ie ), work( itauq ), work( itaup ),
549 $ work( itemp ), lwork-itemp+1, info )
550 itempr = itgkz + n*(n*2+1)
551
552
553
554
555 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
556 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
557 $ rwork( itgkz ), n*2, rwork( itempr ),
558 $ iwork, info)
559
560
561
562 IF( wantu ) THEN
563 k = itgkz
564 DO i = 1, ns
565 DO j = 1, n
566 u( j, i ) = cmplx( rwork( k ), zero )
567 k = k + 1
568 END DO
569 k = k + n
570 END DO
571 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
572 $ ldu)
573
574
575
576
577 CALL cunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
578 $ work( itauq ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
580
581
582
583
584 CALL cunmqr(
'L',
'N', m, ns, n, a, lda,
585 $ work( itau ), u, ldu, work( itemp ),
586 $ lwork-itemp+1, info )
587 END IF
588
589
590
591 IF( wantvt) THEN
592 k = itgkz + n
593 DO i = 1, ns
594 DO j = 1, n
595 vt( i, j ) = cmplx( rwork( k ), zero )
596 k = k + 1
597 END DO
598 k = k + n
599 END DO
600
601
602
603
604 CALL cunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
605 $ work( itaup ), vt, ldvt, work( itemp ),
606 $ lwork-itemp+1, info )
607 END IF
608 ELSE
609
610
611
612
613
614
615
616
617
618 itauq = 1
619 itaup = itauq + n
620 itemp = itaup + n
621 id = 1
622 ie = id + n
623 itgkz = ie + n
624 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
625 $ work( itauq ), work( itaup ), work( itemp ),
626 $ lwork-itemp+1, info )
627 itempr = itgkz + n*(n*2+1)
628
629
630
631
632 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
633 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
634 $ rwork( itgkz ), n*2, rwork( itempr ),
635 $ iwork, info)
636
637
638
639 IF( wantu ) THEN
640 k = itgkz
641 DO i = 1, ns
642 DO j = 1, n
643 u( j, i ) = cmplx( rwork( k ), zero )
644 k = k + 1
645 END DO
646 k = k + n
647 END DO
648 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
649 $ ldu)
650
651
652
653
654 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
655 $ work( itauq ), u, ldu, work( itemp ),
656 $ lwork-itemp+1, ierr )
657 END IF
658
659
660
661 IF( wantvt) THEN
662 k = itgkz + n
663 DO i = 1, ns
664 DO j = 1, n
665 vt( i, j ) = cmplx( rwork( k ), zero )
666 k = k + 1
667 END DO
668 k = k + n
669 END DO
670
671
672
673
674 CALL cunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
675 $ work( itaup ), vt, ldvt, work( itemp ),
676 $ lwork-itemp+1, ierr )
677 END IF
678 END IF
679 ELSE
680
681
682
683
684 IF( n.GE.mnthr ) THEN
685
686
687
688
689
690
691
692
693
694 itau = 1
695 itemp = itau + m
696 CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
697 $ lwork-itemp+1, info )
698
699
700
701
702 ilqf = itemp
703 itauq = ilqf + m*m
704 itaup = itauq + m
705 itemp = itaup + m
706 id = 1
707 ie = id + m
708 itgkz = ie + m
709 CALL clacpy(
'L', m, m, a, lda, work( ilqf ), m )
710 CALL claset(
'U', m-1, m-1, czero, czero,
711 $ work( ilqf+m ), m )
712 CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
713 $ rwork( ie ), work( itauq ), work( itaup ),
714 $ work( itemp ), lwork-itemp+1, info )
715 itempr = itgkz + m*(m*2+1)
716
717
718
719
720 CALL sbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
721 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
722 $ rwork( itgkz ), m*2, rwork( itempr ),
723 $ iwork, info)
724
725
726
727 IF( wantu ) THEN
728 k = itgkz
729 DO i = 1, ns
730 DO j = 1, m
731 u( j, i ) = cmplx( rwork( k ), zero )
732 k = k + 1
733 END DO
734 k = k + m
735 END DO
736
737
738
739
740 CALL cunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
741 $ work( itauq ), u, ldu, work( itemp ),
742 $ lwork-itemp+1, info )
743 END IF
744
745
746
747 IF( wantvt) THEN
748 k = itgkz + m
749 DO i = 1, ns
750 DO j = 1, m
751 vt( i, j ) = cmplx( rwork( k ), zero )
752 k = k + 1
753 END DO
754 k = k + m
755 END DO
756 CALL claset(
'A', ns, n-m, czero, czero,
757 $ vt( 1,m+1 ), ldvt )
758
759
760
761
762 CALL cunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
763 $ work( itaup ), vt, ldvt, work( itemp ),
764 $ lwork-itemp+1, info )
765
766
767
768
769 CALL cunmlq(
'R',
'N', ns, n, m, a, lda,
770 $ work( itau ), vt, ldvt, work( itemp ),
771 $ lwork-itemp+1, info )
772 END IF
773 ELSE
774
775
776
777
778
779
780
781
782
783 itauq = 1
784 itaup = itauq + m
785 itemp = itaup + m
786 id = 1
787 ie = id + m
788 itgkz = ie + m
789 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
790 $ work( itauq ), work( itaup ), work( itemp ),
791 $ lwork-itemp+1, info )
792 itempr = itgkz + m*(m*2+1)
793
794
795
796
797 CALL sbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
798 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
799 $ rwork( itgkz ), m*2, rwork( itempr ),
800 $ iwork, info)
801
802
803
804 IF( wantu ) THEN
805 k = itgkz
806 DO i = 1, ns
807 DO j = 1, m
808 u( j, i ) = cmplx( rwork( k ), zero )
809 k = k + 1
810 END DO
811 k = k + m
812 END DO
813
814
815
816
817 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
818 $ work( itauq ), u, ldu, work( itemp ),
819 $ lwork-itemp+1, info )
820 END IF
821
822
823
824 IF( wantvt) THEN
825 k = itgkz + m
826 DO i = 1, ns
827 DO j = 1, m
828 vt( i, j ) = cmplx( rwork( k ), zero )
829 k = k + 1
830 END DO
831 k = k + m
832 END DO
833 CALL claset(
'A', ns, n-m, czero, czero,
834 $ vt( 1,m+1 ), ldvt )
835
836
837
838
839 CALL cunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
840 $ work( itaup ), vt, ldvt, work( itemp ),
841 $ lwork-itemp+1, info )
842 END IF
843 END IF
844 END IF
845
846
847
848 IF( iscl.EQ.1 ) THEN
849 IF( anrm.GT.bignum )
850 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
851 $ s, minmn, info )
852 IF( anrm.LT.smlnum )
853 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
854 $ s, minmn, info )
855 END IF
856
857
858
860
861 RETURN
862
863
864
subroutine xerbla(srname, info)
subroutine sbdsvdx(uplo, jobz, range, n, d, e, vl, vu, il, iu, ns, s, z, ldz, work, iwork, info)
SBDSVDX
subroutine cgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
CGEBRD
subroutine cgelqf(m, n, a, lda, tau, work, lwork, info)
CGELQF
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR