227 implicit none
228
229
230
231
232
233
234 CHARACTER JOBZ
235 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
236
237
238 INTEGER IWORK( * )
239 REAL RWORK( * ), S( * )
240 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
241 $ WORK( * )
242
243
244
245
246
247 COMPLEX CZERO, CONE
248 parameter( czero = ( 0.0e+0, 0.0e+0 ),
249 $ cone = ( 1.0e+0, 0.0e+0 ) )
250 REAL ZERO, ONE
251 parameter( zero = 0.0e+0, one = 1.0e+0 )
252
253
254 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
255 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
256 $ ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
257 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
258 $ MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
259 INTEGER LWORK_CGEBRD_MN, LWORK_CGEBRD_MM,
260 $ LWORK_CGEBRD_NN, LWORK_CGELQF_MN,
261 $ LWORK_CGEQRF_MN,
262 $ LWORK_CUNGBR_P_MN, LWORK_CUNGBR_P_NN,
263 $ LWORK_CUNGBR_Q_MN, LWORK_CUNGBR_Q_MM,
264 $ LWORK_CUNGLQ_MN, LWORK_CUNGLQ_NN,
265 $ LWORK_CUNGQR_MM, LWORK_CUNGQR_MN,
266 $ LWORK_CUNMBR_PRC_MM, LWORK_CUNMBR_QLN_MM,
267 $ LWORK_CUNMBR_PRC_MN, LWORK_CUNMBR_QLN_MN,
268 $ LWORK_CUNMBR_PRC_NN, LWORK_CUNMBR_QLN_NN
269 REAL ANRM, BIGNUM, EPS, SMLNUM
270
271
272 INTEGER IDUM( 1 )
273 REAL DUM( 1 )
274 COMPLEX CDUM( 1 )
275
276
280
281
282 LOGICAL LSAME, SISNAN
283 REAL SLAMCH, CLANGE, SROUNDUP_LWORK
286
287
288 INTRINSIC int, max, min, sqrt
289
290
291
292
293
294 info = 0
295 minmn = min( m, n )
296 mnthr1 = int( minmn*17.0e0 / 9.0e0 )
297 mnthr2 = int( minmn*5.0e0 / 3.0e0 )
298 wntqa =
lsame( jobz,
'A' )
299 wntqs =
lsame( jobz,
'S' )
300 wntqas = wntqa .OR. wntqs
301 wntqo =
lsame( jobz,
'O' )
302 wntqn =
lsame( jobz,
'N' )
303 lquery = ( lwork.EQ.-1 )
304 minwrk = 1
305 maxwrk = 1
306
307 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) ) THEN
308 info = -1
309 ELSE IF( m.LT.0 ) THEN
310 info = -2
311 ELSE IF( n.LT.0 ) THEN
312 info = -3
313 ELSE IF( lda.LT.max( 1, m ) ) THEN
314 info = -5
315 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
316 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) ) THEN
317 info = -8
318 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
319 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
320 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) ) THEN
321 info = -10
322 END IF
323
324
325
326
327
328
329
330
331
332 IF( info.EQ.0 ) THEN
333 minwrk = 1
334 maxwrk = 1
335 IF( m.GE.n .AND. minmn.GT.0 ) THEN
336
337
338
339
340
341
342
343
344 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
345 $ cdum(1), cdum(1), -1, ierr )
346 lwork_cgebrd_mn = int( cdum(1) )
347
348 CALL cgebrd( n, n, cdum(1), n, dum(1), dum(1), cdum(1),
349 $ cdum(1), cdum(1), -1, ierr )
350 lwork_cgebrd_nn = int( cdum(1) )
351
352 CALL cgeqrf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
353 lwork_cgeqrf_mn = int( cdum(1) )
354
355 CALL cungbr(
'P', n, n, n, cdum(1), n, cdum(1), cdum(1),
356 $ -1, ierr )
357 lwork_cungbr_p_nn = int( cdum(1) )
358
359 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
360 $ -1, ierr )
361 lwork_cungbr_q_mm = int( cdum(1) )
362
363 CALL cungbr(
'Q', m, n, n, cdum(1), m, cdum(1), cdum(1),
364 $ -1, ierr )
365 lwork_cungbr_q_mn = int( cdum(1) )
366
367 CALL cungqr( m, m, n, cdum(1), m, cdum(1), cdum(1),
368 $ -1, ierr )
369 lwork_cungqr_mm = int( cdum(1) )
370
371 CALL cungqr( m, n, n, cdum(1), m, cdum(1), cdum(1),
372 $ -1, ierr )
373 lwork_cungqr_mn = int( cdum(1) )
374
375 CALL cunmbr(
'P',
'R',
'C', n, n, n, cdum(1), n, cdum(1),
376 $ cdum(1), n, cdum(1), -1, ierr )
377 lwork_cunmbr_prc_nn = int( cdum(1) )
378
379 CALL cunmbr(
'Q',
'L',
'N', m, m, n, cdum(1), m, cdum(1),
380 $ cdum(1), m, cdum(1), -1, ierr )
381 lwork_cunmbr_qln_mm = int( cdum(1) )
382
383 CALL cunmbr(
'Q',
'L',
'N', m, n, n, cdum(1), m, cdum(1),
384 $ cdum(1), m, cdum(1), -1, ierr )
385 lwork_cunmbr_qln_mn = int( cdum(1) )
386
387 CALL cunmbr(
'Q',
'L',
'N', n, n, n, cdum(1), n, cdum(1),
388 $ cdum(1), n, cdum(1), -1, ierr )
389 lwork_cunmbr_qln_nn = int( cdum(1) )
390
391 IF( m.GE.mnthr1 ) THEN
392 IF( wntqn ) THEN
393
394
395
396 maxwrk = n + lwork_cgeqrf_mn
397 maxwrk = max( maxwrk, 2*n + lwork_cgebrd_nn )
398 minwrk = 3*n
399 ELSE IF( wntqo ) THEN
400
401
402
403 wrkbl = n + lwork_cgeqrf_mn
404 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
405 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
406 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
407 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
408 maxwrk = m*n + n*n + wrkbl
409 minwrk = 2*n*n + 3*n
410 ELSE IF( wntqs ) THEN
411
412
413
414 wrkbl = n + lwork_cgeqrf_mn
415 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
416 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
417 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
418 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
419 maxwrk = n*n + wrkbl
420 minwrk = n*n + 3*n
421 ELSE IF( wntqa ) THEN
422
423
424
425 wrkbl = n + lwork_cgeqrf_mn
426 wrkbl = max( wrkbl, n + lwork_cungqr_mm )
427 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
428 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
429 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
430 maxwrk = n*n + wrkbl
431 minwrk = n*n + max( 3*n, n + m )
432 END IF
433 ELSE IF( m.GE.mnthr2 ) THEN
434
435
436
437 maxwrk = 2*n + lwork_cgebrd_mn
438 minwrk = 2*n + m
439 IF( wntqo ) THEN
440
441 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
442 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
443 maxwrk = maxwrk + m*n
444 minwrk = minwrk + n*n
445 ELSE IF( wntqs ) THEN
446
447 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
448 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
449 ELSE IF( wntqa ) THEN
450
451 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
452 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mm )
453 END IF
454 ELSE
455
456
457
458 maxwrk = 2*n + lwork_cgebrd_mn
459 minwrk = 2*n + m
460 IF( wntqo ) THEN
461
462 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
463 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
464 maxwrk = maxwrk + m*n
465 minwrk = minwrk + n*n
466 ELSE IF( wntqs ) THEN
467
468 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
469 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
470 ELSE IF( wntqa ) THEN
471
472 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mm )
473 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
474 END IF
475 END IF
476 ELSE IF( minmn.GT.0 ) THEN
477
478
479
480
481
482
483
484
485 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
486 $ cdum(1), cdum(1), -1, ierr )
487 lwork_cgebrd_mn = int( cdum(1) )
488
489 CALL cgebrd( m, m, cdum(1), m, dum(1), dum(1), cdum(1),
490 $ cdum(1), cdum(1), -1, ierr )
491 lwork_cgebrd_mm = int( cdum(1) )
492
493 CALL cgelqf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
494 lwork_cgelqf_mn = int( cdum(1) )
495
496 CALL cungbr(
'P', m, n, m, cdum(1), m, cdum(1), cdum(1),
497 $ -1, ierr )
498 lwork_cungbr_p_mn = int( cdum(1) )
499
500 CALL cungbr(
'P', n, n, m, cdum(1), n, cdum(1), cdum(1),
501 $ -1, ierr )
502 lwork_cungbr_p_nn = int( cdum(1) )
503
504 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
505 $ -1, ierr )
506 lwork_cungbr_q_mm = int( cdum(1) )
507
508 CALL cunglq( m, n, m, cdum(1), m, cdum(1), cdum(1),
509 $ -1, ierr )
510 lwork_cunglq_mn = int( cdum(1) )
511
512 CALL cunglq( n, n, m, cdum(1), n, cdum(1), cdum(1),
513 $ -1, ierr )
514 lwork_cunglq_nn = int( cdum(1) )
515
516 CALL cunmbr(
'P',
'R',
'C', m, m, m, cdum(1), m, cdum(1),
517 $ cdum(1), m, cdum(1), -1, ierr )
518 lwork_cunmbr_prc_mm = int( cdum(1) )
519
520 CALL cunmbr(
'P',
'R',
'C', m, n, m, cdum(1), m, cdum(1),
521 $ cdum(1), m, cdum(1), -1, ierr )
522 lwork_cunmbr_prc_mn = int( cdum(1) )
523
524 CALL cunmbr(
'P',
'R',
'C', n, n, m, cdum(1), n, cdum(1),
525 $ cdum(1), n, cdum(1), -1, ierr )
526 lwork_cunmbr_prc_nn = int( cdum(1) )
527
528 CALL cunmbr(
'Q',
'L',
'N', m, m, m, cdum(1), m, cdum(1),
529 $ cdum(1), m, cdum(1), -1, ierr )
530 lwork_cunmbr_qln_mm = int( cdum(1) )
531
532 IF( n.GE.mnthr1 ) THEN
533 IF( wntqn ) THEN
534
535
536
537 maxwrk = m + lwork_cgelqf_mn
538 maxwrk = max( maxwrk, 2*m + lwork_cgebrd_mm )
539 minwrk = 3*m
540 ELSE IF( wntqo ) THEN
541
542
543
544 wrkbl = m + lwork_cgelqf_mn
545 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
546 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
547 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
548 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
549 maxwrk = m*n + m*m + wrkbl
550 minwrk = 2*m*m + 3*m
551 ELSE IF( wntqs ) THEN
552
553
554
555 wrkbl = m + lwork_cgelqf_mn
556 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
557 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
558 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
559 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
560 maxwrk = m*m + wrkbl
561 minwrk = m*m + 3*m
562 ELSE IF( wntqa ) THEN
563
564
565
566 wrkbl = m + lwork_cgelqf_mn
567 wrkbl = max( wrkbl, m + lwork_cunglq_nn )
568 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
569 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
570 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
571 maxwrk = m*m + wrkbl
572 minwrk = m*m + max( 3*m, m + n )
573 END IF
574 ELSE IF( n.GE.mnthr2 ) THEN
575
576
577
578 maxwrk = 2*m + lwork_cgebrd_mn
579 minwrk = 2*m + n
580 IF( wntqo ) THEN
581
582 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
583 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
584 maxwrk = maxwrk + m*n
585 minwrk = minwrk + m*m
586 ELSE IF( wntqs ) THEN
587
588 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
589 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
590 ELSE IF( wntqa ) THEN
591
592 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
593 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_nn )
594 END IF
595 ELSE
596
597
598
599 maxwrk = 2*m + lwork_cgebrd_mn
600 minwrk = 2*m + n
601 IF( wntqo ) THEN
602
603 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
604 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
605 maxwrk = maxwrk + m*n
606 minwrk = minwrk + m*m
607 ELSE IF( wntqs ) THEN
608
609 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
610 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
611 ELSE IF( wntqa ) THEN
612
613 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
614 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_nn )
615 END IF
616 END IF
617 END IF
618 maxwrk = max( maxwrk, minwrk )
619 END IF
620 IF( info.EQ.0 ) THEN
622 IF( lwork.LT.minwrk .AND. .NOT. lquery ) THEN
623 info = -12
624 END IF
625 END IF
626
627 IF( info.NE.0 ) THEN
628 CALL xerbla(
'CGESDD', -info )
629 RETURN
630 ELSE IF( lquery ) THEN
631 RETURN
632 END IF
633
634
635
636 IF( m.EQ.0 .OR. n.EQ.0 ) THEN
637 RETURN
638 END IF
639
640
641
643 smlnum = sqrt(
slamch(
'S' ) ) / eps
644 bignum = one / smlnum
645
646
647
648 anrm =
clange(
'M', m, n, a, lda, dum )
650 info = -4
651 RETURN
652 END IF
653 iscl = 0
654 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
655 iscl = 1
656 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
657 ELSE IF( anrm.GT.bignum ) THEN
658 iscl = 1
659 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
660 END IF
661
662 IF( m.GE.n ) THEN
663
664
665
666
667
668 IF( m.GE.mnthr1 ) THEN
669
670 IF( wntqn ) THEN
671
672
673
674
675 itau = 1
676 nwork = itau + n
677
678
679
680
681
682
683 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
684 $ lwork-nwork+1, ierr )
685
686
687
688 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
689 $ lda )
690 ie = 1
691 itauq = 1
692 itaup = itauq + n
693 nwork = itaup + n
694
695
696
697
698
699
700 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
701 $ work( itaup ), work( nwork ), lwork-nwork+1,
702 $ ierr )
703 nrwork = ie + n
704
705
706
707
708
709 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
710 $ dum, idum, rwork( nrwork ), iwork, info )
711
712 ELSE IF( wntqo ) THEN
713
714
715
716
717
718 iu = 1
719
720
721
722 ldwrku = n
723 ir = iu + ldwrku*n
724 IF( lwork .GE. m*n + n*n + 3*n ) THEN
725
726
727
728 ldwrkr = m
729 ELSE
730 ldwrkr = ( lwork - n*n - 3*n ) / n
731 END IF
732 itau = ir + ldwrkr*n
733 nwork = itau + n
734
735
736
737
738
739
740 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
741 $ lwork-nwork+1, ierr )
742
743
744
745 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
746 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
747 $ ldwrkr )
748
749
750
751
752
753
754 CALL cungqr( m, n, n, a, lda, work( itau ),
755 $ work( nwork ), lwork-nwork+1, ierr )
756 ie = 1
757 itauq = itau
758 itaup = itauq + n
759 nwork = itaup + n
760
761
762
763
764
765
766 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
767 $ work( itauq ), work( itaup ), work( nwork ),
768 $ lwork-nwork+1, ierr )
769
770
771
772
773
774
775
776 iru = ie + n
777 irvt = iru + n*n
778 nrwork = irvt + n*n
779 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
780 $ n, rwork( irvt ), n, dum, idum,
781 $ rwork( nrwork ), iwork, info )
782
783
784
785
786
787
788
789 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
790 $ ldwrku )
791 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
792 $ work( itauq ), work( iu ), ldwrku,
793 $ work( nwork ), lwork-nwork+1, ierr )
794
795
796
797
798
799
800
801 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
802 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
803 $ work( itaup ), vt, ldvt, work( nwork ),
804 $ lwork-nwork+1, ierr )
805
806
807
808
809
810
811
812 DO 10 i = 1, m, ldwrkr
813 chunk = min( m-i+1, ldwrkr )
814 CALL cgemm(
'N',
'N', chunk, n, n, cone, a( i, 1 ),
815 $ lda, work( iu ), ldwrku, czero,
816 $ work( ir ), ldwrkr )
817 CALL clacpy(
'F', chunk, n, work( ir ), ldwrkr,
818 $ a( i, 1 ), lda )
819 10 CONTINUE
820
821 ELSE IF( wntqs ) THEN
822
823
824
825
826
827 ir = 1
828
829
830
831 ldwrkr = n
832 itau = ir + ldwrkr*n
833 nwork = itau + n
834
835
836
837
838
839
840 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
841 $ lwork-nwork+1, ierr )
842
843
844
845 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
846 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
847 $ ldwrkr )
848
849
850
851
852
853
854 CALL cungqr( m, n, n, a, lda, work( itau ),
855 $ work( nwork ), lwork-nwork+1, ierr )
856 ie = 1
857 itauq = itau
858 itaup = itauq + n
859 nwork = itaup + n
860
861
862
863
864
865
866 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
867 $ work( itauq ), work( itaup ), work( nwork ),
868 $ lwork-nwork+1, ierr )
869
870
871
872
873
874
875
876 iru = ie + n
877 irvt = iru + n*n
878 nrwork = irvt + n*n
879 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
880 $ n, rwork( irvt ), n, dum, idum,
881 $ rwork( nrwork ), iwork, info )
882
883
884
885
886
887
888
889 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
890 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
891 $ work( itauq ), u, ldu, work( nwork ),
892 $ lwork-nwork+1, ierr )
893
894
895
896
897
898
899
900 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
901 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
902 $ work( itaup ), vt, ldvt, work( nwork ),
903 $ lwork-nwork+1, ierr )
904
905
906
907
908
909
910 CALL clacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
911 CALL cgemm(
'N',
'N', m, n, n, cone, a, lda, work( ir ),
912 $ ldwrkr, czero, u, ldu )
913
914 ELSE IF( wntqa ) THEN
915
916
917
918
919
920 iu = 1
921
922
923
924 ldwrku = n
925 itau = iu + ldwrku*n
926 nwork = itau + n
927
928
929
930
931
932
933 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
934 $ lwork-nwork+1, ierr )
935 CALL clacpy(
'L', m, n, a, lda, u, ldu )
936
937
938
939
940
941
942 CALL cungqr( m, m, n, u, ldu, work( itau ),
943 $ work( nwork ), lwork-nwork+1, ierr )
944
945
946
947 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
948 $ lda )
949 ie = 1
950 itauq = itau
951 itaup = itauq + n
952 nwork = itaup + n
953
954
955
956
957
958
959 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
960 $ work( itaup ), work( nwork ), lwork-nwork+1,
961 $ ierr )
962 iru = ie + n
963 irvt = iru + n*n
964 nrwork = irvt + n*n
965
966
967
968
969
970
971
972 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
973 $ n, rwork( irvt ), n, dum, idum,
974 $ rwork( nrwork ), iwork, info )
975
976
977
978
979
980
981
982 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
983 $ ldwrku )
984 CALL cunmbr(
'Q',
'L',
'N', n, n, n, a, lda,
985 $ work( itauq ), work( iu ), ldwrku,
986 $ work( nwork ), lwork-nwork+1, ierr )
987
988
989
990
991
992
993
994 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
995 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
996 $ work( itaup ), vt, ldvt, work( nwork ),
997 $ lwork-nwork+1, ierr )
998
999
1000
1001
1002
1003
1004 CALL cgemm(
'N',
'N', m, n, n, cone, u, ldu, work( iu ),
1005 $ ldwrku, czero, a, lda )
1006
1007
1008
1009 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1010
1011 END IF
1012
1013 ELSE IF( m.GE.mnthr2 ) THEN
1014
1015
1016
1017
1018
1019
1020
1021 ie = 1
1022 nrwork = ie + n
1023 itauq = 1
1024 itaup = itauq + n
1025 nwork = itaup + n
1026
1027
1028
1029
1030
1031
1032 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1033 $ work( itaup ), work( nwork ), lwork-nwork+1,
1034 $ ierr )
1035 IF( wntqn ) THEN
1036
1037
1038
1039
1040
1041
1042 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum, 1,dum,1,
1043 $ dum, idum, rwork( nrwork ), iwork, info )
1044 ELSE IF( wntqo ) THEN
1045 iu = nwork
1046 iru = nrwork
1047 irvt = iru + n*n
1048 nrwork = irvt + n*n
1049
1050
1051
1052
1053
1054
1055
1056 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1057 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1058 $ work( nwork ), lwork-nwork+1, ierr )
1059
1060
1061
1062
1063
1064
1065 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1066 $ work( nwork ), lwork-nwork+1, ierr )
1067
1068 IF( lwork .GE. m*n + 3*n ) THEN
1069
1070
1071
1072 ldwrku = m
1073 ELSE
1074
1075
1076
1077 ldwrku = ( lwork - 3*n ) / n
1078 END IF
1079 nwork = iu + ldwrku*n
1080
1081
1082
1083
1084
1085
1086
1087 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1088 $ n, rwork( irvt ), n, dum, idum,
1089 $ rwork( nrwork ), iwork, info )
1090
1091
1092
1093
1094
1095
1096 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt,
1097 $ work( iu ), ldwrku, rwork( nrwork ) )
1098 CALL clacpy(
'F', n, n, work( iu ), ldwrku, vt, ldvt )
1099
1100
1101
1102
1103
1104
1105
1106
1107 nrwork = irvt
1108 DO 20 i = 1, m, ldwrku
1109 chunk = min( m-i+1, ldwrku )
1110 CALL clacrm( chunk, n, a( i, 1 ), lda, rwork( iru ),
1111 $ n, work( iu ), ldwrku, rwork( nrwork ) )
1112 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1113 $ a( i, 1 ), lda )
1114 20 CONTINUE
1115
1116 ELSE IF( wntqs ) THEN
1117
1118
1119
1120
1121
1122
1123
1124 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1125 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1126 $ work( nwork ), lwork-nwork+1, ierr )
1127
1128
1129
1130
1131
1132
1133 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1134 CALL cungbr(
'Q', m, n, n, u, ldu, work( itauq ),
1135 $ work( nwork ), lwork-nwork+1, ierr )
1136
1137
1138
1139
1140
1141
1142
1143 iru = nrwork
1144 irvt = iru + n*n
1145 nrwork = irvt + n*n
1146 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1147 $ n, rwork( irvt ), n, dum, idum,
1148 $ rwork( nrwork ), iwork, info )
1149
1150
1151
1152
1153
1154
1155 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1156 $ rwork( nrwork ) )
1157 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1158
1159
1160
1161
1162
1163
1164 nrwork = irvt
1165 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1166 $ rwork( nrwork ) )
1167 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1168 ELSE
1169
1170
1171
1172
1173
1174
1175
1176 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1177 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1178 $ work( nwork ), lwork-nwork+1, ierr )
1179
1180
1181
1182
1183
1184
1185 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1186 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1187 $ work( nwork ), lwork-nwork+1, ierr )
1188
1189
1190
1191
1192
1193
1194
1195 iru = nrwork
1196 irvt = iru + n*n
1197 nrwork = irvt + n*n
1198 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1199 $ n, rwork( irvt ), n, dum, idum,
1200 $ rwork( nrwork ), iwork, info )
1201
1202
1203
1204
1205
1206
1207 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1208 $ rwork( nrwork ) )
1209 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1210
1211
1212
1213
1214
1215
1216 nrwork = irvt
1217 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1218 $ rwork( nrwork ) )
1219 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1220 END IF
1221
1222 ELSE
1223
1224
1225
1226
1227
1228
1229
1230 ie = 1
1231 nrwork = ie + n
1232 itauq = 1
1233 itaup = itauq + n
1234 nwork = itaup + n
1235
1236
1237
1238
1239
1240
1241 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1242 $ work( itaup ), work( nwork ), lwork-nwork+1,
1243 $ ierr )
1244 IF( wntqn ) THEN
1245
1246
1247
1248
1249
1250
1251 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
1252 $ dum, idum, rwork( nrwork ), iwork, info )
1253 ELSE IF( wntqo ) THEN
1254 iu = nwork
1255 iru = nrwork
1256 irvt = iru + n*n
1257 nrwork = irvt + n*n
1258 IF( lwork .GE. m*n + 3*n ) THEN
1259
1260
1261
1262 ldwrku = m
1263 ELSE
1264
1265
1266
1267 ldwrku = ( lwork - 3*n ) / n
1268 END IF
1269 nwork = iu + ldwrku*n
1270
1271
1272
1273
1274
1275
1276
1277
1278 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1279 $ n, rwork( irvt ), n, dum, idum,
1280 $ rwork( nrwork ), iwork, info )
1281
1282
1283
1284
1285
1286
1287
1288 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1289 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1290 $ work( itaup ), vt, ldvt, work( nwork ),
1291 $ lwork-nwork+1, ierr )
1292
1293 IF( lwork .GE. m*n + 3*n ) THEN
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303 CALL claset(
'F', m, n, czero, czero, work( iu ),
1304 $ ldwrku )
1305 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
1306 $ ldwrku )
1307 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1308 $ work( itauq ), work( iu ), ldwrku,
1309 $ work( nwork ), lwork-nwork+1, ierr )
1310 CALL clacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
1311 ELSE
1312
1313
1314
1315
1316
1317
1318
1319 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1320 $ work( nwork ), lwork-nwork+1, ierr )
1321
1322
1323
1324
1325
1326
1327
1328
1329 nrwork = irvt
1330 DO 30 i = 1, m, ldwrku
1331 chunk = min( m-i+1, ldwrku )
1332 CALL clacrm( chunk, n, a( i, 1 ), lda,
1333 $ rwork( iru ), n, work( iu ), ldwrku,
1334 $ rwork( nrwork ) )
1335 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1336 $ a( i, 1 ), lda )
1337 30 CONTINUE
1338 END IF
1339
1340 ELSE IF( wntqs ) THEN
1341
1342
1343
1344
1345
1346
1347
1348
1349 iru = nrwork
1350 irvt = iru + n*n
1351 nrwork = irvt + n*n
1352 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1353 $ n, rwork( irvt ), n, dum, idum,
1354 $ rwork( nrwork ), iwork, info )
1355
1356
1357
1358
1359
1360
1361
1362 CALL claset(
'F', m, n, czero, czero, u, ldu )
1363 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1364 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1365 $ work( itauq ), u, ldu, work( nwork ),
1366 $ lwork-nwork+1, ierr )
1367
1368
1369
1370
1371
1372
1373
1374 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1375 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1376 $ work( itaup ), vt, ldvt, work( nwork ),
1377 $ lwork-nwork+1, ierr )
1378 ELSE
1379
1380
1381
1382
1383
1384
1385
1386
1387 iru = nrwork
1388 irvt = iru + n*n
1389 nrwork = irvt + n*n
1390 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1391 $ n, rwork( irvt ), n, dum, idum,
1392 $ rwork( nrwork ), iwork, info )
1393
1394
1395
1396 CALL claset(
'F', m, m, czero, czero, u, ldu )
1397 IF( m.GT.n ) THEN
1398 CALL claset(
'F', m-n, m-n, czero, cone,
1399 $ u( n+1, n+1 ), ldu )
1400 END IF
1401
1402
1403
1404
1405
1406
1407
1408 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1409 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
1410 $ work( itauq ), u, ldu, work( nwork ),
1411 $ lwork-nwork+1, ierr )
1412
1413
1414
1415
1416
1417
1418
1419 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1420 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1421 $ work( itaup ), vt, ldvt, work( nwork ),
1422 $ lwork-nwork+1, ierr )
1423 END IF
1424
1425 END IF
1426
1427 ELSE
1428
1429
1430
1431
1432
1433 IF( n.GE.mnthr1 ) THEN
1434
1435 IF( wntqn ) THEN
1436
1437
1438
1439
1440 itau = 1
1441 nwork = itau + m
1442
1443
1444
1445
1446
1447
1448 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1449 $ lwork-nwork+1, ierr )
1450
1451
1452
1453 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1454 $ lda )
1455 ie = 1
1456 itauq = 1
1457 itaup = itauq + m
1458 nwork = itaup + m
1459
1460
1461
1462
1463
1464
1465 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1466 $ work( itaup ), work( nwork ), lwork-nwork+1,
1467 $ ierr )
1468 nrwork = ie + m
1469
1470
1471
1472
1473
1474 CALL sbdsdc(
'U',
'N', m, s, rwork( ie ), dum,1,dum,1,
1475 $ dum, idum, rwork( nrwork ), iwork, info )
1476
1477 ELSE IF( wntqo ) THEN
1478
1479
1480
1481
1482
1483 ivt = 1
1484 ldwkvt = m
1485
1486
1487
1488 il = ivt + ldwkvt*m
1489 IF( lwork .GE. m*n + m*m + 3*m ) THEN
1490
1491
1492
1493 ldwrkl = m
1494 chunk = n
1495 ELSE
1496
1497
1498
1499 ldwrkl = m
1500 chunk = ( lwork - m*m - 3*m ) / m
1501 END IF
1502 itau = il + ldwrkl*chunk
1503 nwork = itau + m
1504
1505
1506
1507
1508
1509
1510 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1511 $ lwork-nwork+1, ierr )
1512
1513
1514
1515 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1516 CALL claset(
'U', m-1, m-1, czero, czero,
1517 $ work( il+ldwrkl ), ldwrkl )
1518
1519
1520
1521
1522
1523
1524 CALL cunglq( m, n, m, a, lda, work( itau ),
1525 $ work( nwork ), lwork-nwork+1, ierr )
1526 ie = 1
1527 itauq = itau
1528 itaup = itauq + m
1529 nwork = itaup + m
1530
1531
1532
1533
1534
1535
1536 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1537 $ work( itauq ), work( itaup ), work( nwork ),
1538 $ lwork-nwork+1, ierr )
1539
1540
1541
1542
1543
1544
1545
1546 iru = ie + m
1547 irvt = iru + m*m
1548 nrwork = irvt + m*m
1549 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1550 $ m, rwork( irvt ), m, dum, idum,
1551 $ rwork( nrwork ), iwork, info )
1552
1553
1554
1555
1556
1557
1558
1559 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1560 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1561 $ work( itauq ), u, ldu, work( nwork ),
1562 $ lwork-nwork+1, ierr )
1563
1564
1565
1566
1567
1568
1569
1570 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1571 $ ldwkvt )
1572 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1573 $ work( itaup ), work( ivt ), ldwkvt,
1574 $ work( nwork ), lwork-nwork+1, ierr )
1575
1576
1577
1578
1579
1580
1581
1582 DO 40 i = 1, n, chunk
1583 blk = min( n-i+1, chunk )
1584 CALL cgemm(
'N',
'N', m, blk, m, cone, work( ivt ), m,
1585 $ a( 1, i ), lda, czero, work( il ),
1586 $ ldwrkl )
1587 CALL clacpy(
'F', m, blk, work( il ), ldwrkl,
1588 $ a( 1, i ), lda )
1589 40 CONTINUE
1590
1591 ELSE IF( wntqs ) THEN
1592
1593
1594
1595
1596
1597 il = 1
1598
1599
1600
1601 ldwrkl = m
1602 itau = il + ldwrkl*m
1603 nwork = itau + m
1604
1605
1606
1607
1608
1609
1610 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1611 $ lwork-nwork+1, ierr )
1612
1613
1614
1615 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1616 CALL claset(
'U', m-1, m-1, czero, czero,
1617 $ work( il+ldwrkl ), ldwrkl )
1618
1619
1620
1621
1622
1623
1624 CALL cunglq( m, n, m, a, lda, work( itau ),
1625 $ work( nwork ), lwork-nwork+1, ierr )
1626 ie = 1
1627 itauq = itau
1628 itaup = itauq + m
1629 nwork = itaup + m
1630
1631
1632
1633
1634
1635
1636 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1637 $ work( itauq ), work( itaup ), work( nwork ),
1638 $ lwork-nwork+1, ierr )
1639
1640
1641
1642
1643
1644
1645
1646 iru = ie + m
1647 irvt = iru + m*m
1648 nrwork = irvt + m*m
1649 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1650 $ m, rwork( irvt ), m, dum, idum,
1651 $ rwork( nrwork ), iwork, info )
1652
1653
1654
1655
1656
1657
1658
1659 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1660 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1661 $ work( itauq ), u, ldu, work( nwork ),
1662 $ lwork-nwork+1, ierr )
1663
1664
1665
1666
1667
1668
1669
1670 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
1671 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1672 $ work( itaup ), vt, ldvt, work( nwork ),
1673 $ lwork-nwork+1, ierr )
1674
1675
1676
1677
1678
1679
1680 CALL clacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1681 CALL cgemm(
'N',
'N', m, n, m, cone, work( il ), ldwrkl,
1682 $ a, lda, czero, vt, ldvt )
1683
1684 ELSE IF( wntqa ) THEN
1685
1686
1687
1688
1689
1690 ivt = 1
1691
1692
1693
1694 ldwkvt = m
1695 itau = ivt + ldwkvt*m
1696 nwork = itau + m
1697
1698
1699
1700
1701
1702
1703 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1704 $ lwork-nwork+1, ierr )
1705 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1706
1707
1708
1709
1710
1711
1712 CALL cunglq( n, n, m, vt, ldvt, work( itau ),
1713 $ work( nwork ), lwork-nwork+1, ierr )
1714
1715
1716
1717 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1718 $ lda )
1719 ie = 1
1720 itauq = itau
1721 itaup = itauq + m
1722 nwork = itaup + m
1723
1724
1725
1726
1727
1728
1729 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1730 $ work( itaup ), work( nwork ), lwork-nwork+1,
1731 $ ierr )
1732
1733
1734
1735
1736
1737
1738
1739 iru = ie + m
1740 irvt = iru + m*m
1741 nrwork = irvt + m*m
1742 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1743 $ m, rwork( irvt ), m, dum, idum,
1744 $ rwork( nrwork ), iwork, info )
1745
1746
1747
1748
1749
1750
1751
1752 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1753 CALL cunmbr(
'Q',
'L',
'N', m, m, m, a, lda,
1754 $ work( itauq ), u, ldu, work( nwork ),
1755 $ lwork-nwork+1, ierr )
1756
1757
1758
1759
1760
1761
1762
1763 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1764 $ ldwkvt )
1765 CALL cunmbr(
'P',
'R',
'C', m, m, m, a, lda,
1766 $ work( itaup ), work( ivt ), ldwkvt,
1767 $ work( nwork ), lwork-nwork+1, ierr )
1768
1769
1770
1771
1772
1773
1774 CALL cgemm(
'N',
'N', m, n, m, cone, work( ivt ), ldwkvt,
1775 $ vt, ldvt, czero, a, lda )
1776
1777
1778
1779 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1780
1781 END IF
1782
1783 ELSE IF( n.GE.mnthr2 ) THEN
1784
1785
1786
1787
1788
1789
1790
1791 ie = 1
1792 nrwork = ie + m
1793 itauq = 1
1794 itaup = itauq + m
1795 nwork = itaup + m
1796
1797
1798
1799
1800
1801
1802 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1803 $ work( itaup ), work( nwork ), lwork-nwork+1,
1804 $ ierr )
1805
1806 IF( wntqn ) THEN
1807
1808
1809
1810
1811
1812
1813 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
1814 $ dum, idum, rwork( nrwork ), iwork, info )
1815 ELSE IF( wntqo ) THEN
1816 irvt = nrwork
1817 iru = irvt + m*m
1818 nrwork = iru + m*m
1819 ivt = nwork
1820
1821
1822
1823
1824
1825
1826
1827 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1828 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1829 $ work( nwork ), lwork-nwork+1, ierr )
1830
1831
1832
1833
1834
1835
1836 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
1837 $ work( nwork ), lwork-nwork+1, ierr )
1838
1839 ldwkvt = m
1840 IF( lwork .GE. m*n + 3*m ) THEN
1841
1842
1843
1844 nwork = ivt + ldwkvt*n
1845 chunk = n
1846 ELSE
1847
1848
1849
1850 chunk = ( lwork - 3*m ) / m
1851 nwork = ivt + ldwkvt*chunk
1852 END IF
1853
1854
1855
1856
1857
1858
1859
1860 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1861 $ m, rwork( irvt ), m, dum, idum,
1862 $ rwork( nrwork ), iwork, info )
1863
1864
1865
1866
1867
1868
1869 CALL clacrm( m, m, u, ldu, rwork( iru ), m, work( ivt ),
1870 $ ldwkvt, rwork( nrwork ) )
1871 CALL clacpy(
'F', m, m, work( ivt ), ldwkvt, u, ldu )
1872
1873
1874
1875
1876
1877
1878
1879
1880 nrwork = iru
1881 DO 50 i = 1, n, chunk
1882 blk = min( n-i+1, chunk )
1883 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ), lda,
1884 $ work( ivt ), ldwkvt, rwork( nrwork ) )
1885 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
1886 $ a( 1, i ), lda )
1887 50 CONTINUE
1888 ELSE IF( wntqs ) THEN
1889
1890
1891
1892
1893
1894
1895
1896 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1897 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1898 $ work( nwork ), lwork-nwork+1, ierr )
1899
1900
1901
1902
1903
1904
1905 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1906 CALL cungbr(
'P', m, n, m, vt, ldvt, work( itaup ),
1907 $ work( nwork ), lwork-nwork+1, ierr )
1908
1909
1910
1911
1912
1913
1914
1915 irvt = nrwork
1916 iru = irvt + m*m
1917 nrwork = iru + m*m
1918 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1919 $ m, rwork( irvt ), m, dum, idum,
1920 $ rwork( nrwork ), iwork, info )
1921
1922
1923
1924
1925
1926
1927 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1928 $ rwork( nrwork ) )
1929 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1930
1931
1932
1933
1934
1935
1936 nrwork = iru
1937 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1938 $ rwork( nrwork ) )
1939 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1940 ELSE
1941
1942
1943
1944
1945
1946
1947
1948 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1949 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1950 $ work( nwork ), lwork-nwork+1, ierr )
1951
1952
1953
1954
1955
1956
1957 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1958 CALL cungbr(
'P', n, n, m, vt, ldvt, work( itaup ),
1959 $ work( nwork ), lwork-nwork+1, ierr )
1960
1961
1962
1963
1964
1965
1966
1967 irvt = nrwork
1968 iru = irvt + m*m
1969 nrwork = iru + m*m
1970 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1971 $ m, rwork( irvt ), m, dum, idum,
1972 $ rwork( nrwork ), iwork, info )
1973
1974
1975
1976
1977
1978
1979 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1980 $ rwork( nrwork ) )
1981 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1982
1983
1984
1985
1986
1987
1988 nrwork = iru
1989 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1990 $ rwork( nrwork ) )
1991 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1992 END IF
1993
1994 ELSE
1995
1996
1997
1998
1999
2000
2001
2002 ie = 1
2003 nrwork = ie + m
2004 itauq = 1
2005 itaup = itauq + m
2006 nwork = itaup + m
2007
2008
2009
2010
2011
2012
2013 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
2014 $ work( itaup ), work( nwork ), lwork-nwork+1,
2015 $ ierr )
2016 IF( wntqn ) THEN
2017
2018
2019
2020
2021
2022
2023 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
2024 $ dum, idum, rwork( nrwork ), iwork, info )
2025 ELSE IF( wntqo ) THEN
2026
2027 ldwkvt = m
2028 ivt = nwork
2029 IF( lwork .GE. m*n + 3*m ) THEN
2030
2031
2032
2033 CALL claset(
'F', m, n, czero, czero, work( ivt ),
2034 $ ldwkvt )
2035 nwork = ivt + ldwkvt*n
2036 ELSE
2037
2038
2039
2040 chunk = ( lwork - 3*m ) / m
2041 nwork = ivt + ldwkvt*chunk
2042 END IF
2043
2044
2045
2046
2047
2048
2049
2050 irvt = nrwork
2051 iru = irvt + m*m
2052 nrwork = iru + m*m
2053 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2054 $ m, rwork( irvt ), m, dum, idum,
2055 $ rwork( nrwork ), iwork, info )
2056
2057
2058
2059
2060
2061
2062
2063 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2064 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2065 $ work( itauq ), u, ldu, work( nwork ),
2066 $ lwork-nwork+1, ierr )
2067
2068 IF( lwork .GE. m*n + 3*m ) THEN
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
2079 $ ldwkvt )
2080 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2081 $ work( itaup ), work( ivt ), ldwkvt,
2082 $ work( nwork ), lwork-nwork+1, ierr )
2083 CALL clacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
2084 ELSE
2085
2086
2087
2088
2089
2090
2091
2092 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
2093 $ work( nwork ), lwork-nwork+1, ierr )
2094
2095
2096
2097
2098
2099
2100
2101
2102 nrwork = iru
2103 DO 60 i = 1, n, chunk
2104 blk = min( n-i+1, chunk )
2105 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ),
2106 $ lda, work( ivt ), ldwkvt,
2107 $ rwork( nrwork ) )
2108 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
2109 $ a( 1, i ), lda )
2110 60 CONTINUE
2111 END IF
2112 ELSE IF( wntqs ) THEN
2113
2114
2115
2116
2117
2118
2119
2120
2121 irvt = nrwork
2122 iru = irvt + m*m
2123 nrwork = iru + m*m
2124 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2125 $ m, rwork( irvt ), m, dum, idum,
2126 $ rwork( nrwork ), iwork, info )
2127
2128
2129
2130
2131
2132
2133
2134 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2135 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2136 $ work( itauq ), u, ldu, work( nwork ),
2137 $ lwork-nwork+1, ierr )
2138
2139
2140
2141
2142
2143
2144
2145 CALL claset(
'F', m, n, czero, czero, vt, ldvt )
2146 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2147 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2148 $ work( itaup ), vt, ldvt, work( nwork ),
2149 $ lwork-nwork+1, ierr )
2150 ELSE
2151
2152
2153
2154
2155
2156
2157
2158
2159 irvt = nrwork
2160 iru = irvt + m*m
2161 nrwork = iru + m*m
2162
2163 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2164 $ m, rwork( irvt ), m, dum, idum,
2165 $ rwork( nrwork ), iwork, info )
2166
2167
2168
2169
2170
2171
2172
2173 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2174 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2175 $ work( itauq ), u, ldu, work( nwork ),
2176 $ lwork-nwork+1, ierr )
2177
2178
2179
2180 CALL claset(
'F', n, n, czero, cone, vt, ldvt )
2181
2182
2183
2184
2185
2186
2187
2188 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2189 CALL cunmbr(
'P',
'R',
'C', n, n, m, a, lda,
2190 $ work( itaup ), vt, ldvt, work( nwork ),
2191 $ lwork-nwork+1, ierr )
2192 END IF
2193
2194 END IF
2195
2196 END IF
2197
2198
2199
2200 IF( iscl.EQ.1 ) THEN
2201 IF( anrm.GT.bignum )
2202 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
2203 $ ierr )
2204 IF( info.NE.0 .AND. anrm.GT.bignum )
2205 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn-1, 1,
2206 $ rwork( ie ), minmn, ierr )
2207 IF( anrm.LT.smlnum )
2208 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
2209 $ ierr )
2210 IF( info.NE.0 .AND. anrm.LT.smlnum )
2211 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn-1, 1,
2212 $ rwork( ie ), minmn, ierr )
2213 END IF
2214
2215
2216
2218
2219 RETURN
2220
2221
2222
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.
logical function sisnan(SIN)
SISNAN tests input for NaN.
subroutine xerbla(SRNAME, INFO)
XERBLA
logical function lsame(CA, CB)
LSAME
subroutine sbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
SBDSDC
subroutine cgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
CGEMM
subroutine cungbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGBR
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 cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
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 clarcm(M, N, A, LDA, B, LDB, C, LDC, RWORK)
CLARCM copies all or part of a real two-dimensional array to a complex array.
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.
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 clacrm(M, N, A, LDA, B, LDB, C, LDC, RWORK)
CLACRM multiplies a complex matrix by a square real matrix.
subroutine clacp2(UPLO, M, N, A, LDA, B, LDB)
CLACP2 copies all or part of a real two-dimensional array to a complex array.
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cunglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGLQ
subroutine cunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMBR
subroutine cungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGQR
real function slamch(CMACH)
SLAMCH
real function sroundup_lwork(LWORK)
SROUNDUP_LWORK