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