211 implicit none
212
213
214
215
216
217
218 CHARACTER JOBZ
219 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
220
221
222 INTEGER IWORK( * )
223 DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),
224 $ VT( LDVT, * ), WORK( * )
225
226
227
228
229
230 DOUBLE PRECISION ZERO, ONE
231 parameter( zero = 0.0d0, one = 1.0d0 )
232
233
234 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
235 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
236 $ IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
237 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
238 $ MNTHR, NWORK, WRKBL
239 INTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,
240 $ LWORK_DGEBRD_NN, LWORK_DGELQF_MN,
241 $ LWORK_DGEQRF_MN,
242 $ LWORK_DORGBR_P_MM, LWORK_DORGBR_Q_NN,
243 $ LWORK_DORGLQ_MN, LWORK_DORGLQ_NN,
244 $ LWORK_DORGQR_MM, LWORK_DORGQR_MN,
245 $ LWORK_DORMBR_PRT_MM, LWORK_DORMBR_QLN_MM,
246 $ LWORK_DORMBR_PRT_MN, LWORK_DORMBR_QLN_MN,
247 $ LWORK_DORMBR_PRT_NN, LWORK_DORMBR_QLN_NN
248 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
249
250
251 INTEGER IDUM( 1 )
252 DOUBLE PRECISION DUM( 1 )
253
254
259
260
261 LOGICAL LSAME, DISNAN
262 DOUBLE PRECISION DLAMCH, DLANGE, DROUNDUP_LWORK
265
266
267 INTRINSIC int, max, min, sqrt
268
269
270
271
272
273 info = 0
274 minmn = min( m, n )
275 wntqa =
lsame( jobz,
'A' )
276 wntqs =
lsame( jobz,
'S' )
277 wntqas = wntqa .OR. wntqs
278 wntqo =
lsame( jobz,
'O' )
279 wntqn =
lsame( jobz,
'N' )
280 lquery = ( lwork.EQ.-1 )
281
282 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) ) THEN
283 info = -1
284 ELSE IF( m.LT.0 ) THEN
285 info = -2
286 ELSE IF( n.LT.0 ) THEN
287 info = -3
288 ELSE IF( lda.LT.max( 1, m ) ) THEN
289 info = -5
290 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
291 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) ) THEN
292 info = -8
293 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
294 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
295 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) ) THEN
296 info = -10
297 END IF
298
299
300
301
302
303
304
305
306 IF( info.EQ.0 ) THEN
307 minwrk = 1
308 maxwrk = 1
309 bdspac = 0
310 mnthr = int( minmn*11.0d0 / 6.0d0 )
311 IF( m.GE.n .AND. minmn.GT.0 ) THEN
312
313
314
315 IF( wntqn ) THEN
316
317
318 bdspac = 7*n
319 ELSE
320 bdspac = 3*n*n + 4*n
321 END IF
322
323
324 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
325 $ dum(1), dum(1), -1, ierr )
326 lwork_dgebrd_mn = int( dum(1) )
327
328 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
329 $ dum(1), dum(1), -1, ierr )
330 lwork_dgebrd_nn = int( dum(1) )
331
332 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
333 lwork_dgeqrf_mn = int( dum(1) )
334
335 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
336 $ ierr )
337 lwork_dorgbr_q_nn = int( dum(1) )
338
339 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1,
340 $ ierr )
341 lwork_dorgqr_mm = int( dum(1) )
342
343 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1,
344 $ ierr )
345 lwork_dorgqr_mn = int( dum(1) )
346
347 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
348 $ dum(1), dum(1), n, dum(1), -1, ierr )
349 lwork_dormbr_prt_nn = int( dum(1) )
350
351 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
352 $ dum(1), dum(1), n, dum(1), -1, ierr )
353 lwork_dormbr_qln_nn = int( dum(1) )
354
355 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
356 $ dum(1), dum(1), m, dum(1), -1, ierr )
357 lwork_dormbr_qln_mn = int( dum(1) )
358
359 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
360 $ dum(1), dum(1), m, dum(1), -1, ierr )
361 lwork_dormbr_qln_mm = int( dum(1) )
362
363 IF( m.GE.mnthr ) THEN
364 IF( wntqn ) THEN
365
366
367
368 wrkbl = n + lwork_dgeqrf_mn
369 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
370 maxwrk = max( wrkbl, bdspac + n )
371 minwrk = bdspac + n
372 ELSE IF( wntqo ) THEN
373
374
375
376 wrkbl = n + lwork_dgeqrf_mn
377 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
378 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
379 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
380 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
381 wrkbl = max( wrkbl, 3*n + bdspac )
382 maxwrk = wrkbl + 2*n*n
383 minwrk = bdspac + 2*n*n + 3*n
384 ELSE IF( wntqs ) THEN
385
386
387
388 wrkbl = n + lwork_dgeqrf_mn
389 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
390 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
391 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
392 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
393 wrkbl = max( wrkbl, 3*n + bdspac )
394 maxwrk = wrkbl + n*n
395 minwrk = bdspac + n*n + 3*n
396 ELSE IF( wntqa ) THEN
397
398
399
400 wrkbl = n + lwork_dgeqrf_mn
401 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
402 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
403 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
404 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
405 wrkbl = max( wrkbl, 3*n + bdspac )
406 maxwrk = wrkbl + n*n
407 minwrk = n*n + max( 3*n + bdspac, n + m )
408 END IF
409 ELSE
410
411
412
413 wrkbl = 3*n + lwork_dgebrd_mn
414 IF( wntqn ) THEN
415
416 maxwrk = max( wrkbl, 3*n + bdspac )
417 minwrk = 3*n + max( m, bdspac )
418 ELSE IF( wntqo ) THEN
419
420 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
421 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
422 wrkbl = max( wrkbl, 3*n + bdspac )
423 maxwrk = wrkbl + m*n
424 minwrk = 3*n + max( m, n*n + bdspac )
425 ELSE IF( wntqs ) THEN
426
427 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
428 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
429 maxwrk = max( wrkbl, 3*n + bdspac )
430 minwrk = 3*n + max( m, bdspac )
431 ELSE IF( wntqa ) THEN
432
433 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
434 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
435 maxwrk = max( wrkbl, 3*n + bdspac )
436 minwrk = 3*n + max( m, bdspac )
437 END IF
438 END IF
439 ELSE IF( minmn.GT.0 ) THEN
440
441
442
443 IF( wntqn ) THEN
444
445
446 bdspac = 7*m
447 ELSE
448 bdspac = 3*m*m + 4*m
449 END IF
450
451
452 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
453 $ dum(1), dum(1), -1, ierr )
454 lwork_dgebrd_mn = int( dum(1) )
455
456 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
457 $ dum(1), dum(1), -1, ierr )
458 lwork_dgebrd_mm = int( dum(1) )
459
460 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
461 lwork_dgelqf_mn = int( dum(1) )
462
463 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1,
464 $ ierr )
465 lwork_dorglq_nn = int( dum(1) )
466
467 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
468 lwork_dorglq_mn = int( dum(1) )
469
470 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1,
471 $ ierr )
472 lwork_dorgbr_p_mm = int( dum(1) )
473
474 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
475 $ dum(1), dum(1), m, dum(1), -1, ierr )
476 lwork_dormbr_prt_mm = int( dum(1) )
477
478 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
479 $ dum(1), dum(1), m, dum(1), -1, ierr )
480 lwork_dormbr_prt_mn = int( dum(1) )
481
482 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
483 $ dum(1), dum(1), n, dum(1), -1, ierr )
484 lwork_dormbr_prt_nn = int( dum(1) )
485
486 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
487 $ dum(1), dum(1), m, dum(1), -1, ierr )
488 lwork_dormbr_qln_mm = int( dum(1) )
489
490 IF( n.GE.mnthr ) THEN
491 IF( wntqn ) THEN
492
493
494
495 wrkbl = m + lwork_dgelqf_mn
496 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
497 maxwrk = max( wrkbl, bdspac + m )
498 minwrk = bdspac + m
499 ELSE IF( wntqo ) THEN
500
501
502
503 wrkbl = m + lwork_dgelqf_mn
504 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
505 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
506 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
507 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
508 wrkbl = max( wrkbl, 3*m + bdspac )
509 maxwrk = wrkbl + 2*m*m
510 minwrk = bdspac + 2*m*m + 3*m
511 ELSE IF( wntqs ) THEN
512
513
514
515 wrkbl = m + lwork_dgelqf_mn
516 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
517 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
518 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
519 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
520 wrkbl = max( wrkbl, 3*m + bdspac )
521 maxwrk = wrkbl + m*m
522 minwrk = bdspac + m*m + 3*m
523 ELSE IF( wntqa ) THEN
524
525
526
527 wrkbl = m + lwork_dgelqf_mn
528 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
529 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
530 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
531 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
532 wrkbl = max( wrkbl, 3*m + bdspac )
533 maxwrk = wrkbl + m*m
534 minwrk = m*m + max( 3*m + bdspac, m + n )
535 END IF
536 ELSE
537
538
539
540 wrkbl = 3*m + lwork_dgebrd_mn
541 IF( wntqn ) THEN
542
543 maxwrk = max( wrkbl, 3*m + bdspac )
544 minwrk = 3*m + max( n, bdspac )
545 ELSE IF( wntqo ) THEN
546
547 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
548 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
549 wrkbl = max( wrkbl, 3*m + bdspac )
550 maxwrk = wrkbl + m*n
551 minwrk = 3*m + max( n, m*m + bdspac )
552 ELSE IF( wntqs ) THEN
553
554 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
555 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
556 maxwrk = max( wrkbl, 3*m + bdspac )
557 minwrk = 3*m + max( n, bdspac )
558 ELSE IF( wntqa ) THEN
559
560 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
561 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
562 maxwrk = max( wrkbl, 3*m + bdspac )
563 minwrk = 3*m + max( n, bdspac )
564 END IF
565 END IF
566 END IF
567
568 maxwrk = max( maxwrk, minwrk )
570
571 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
572 info = -12
573 END IF
574 END IF
575
576 IF( info.NE.0 ) THEN
577 CALL xerbla(
'DGESDD', -info )
578 RETURN
579 ELSE IF( lquery ) THEN
580 RETURN
581 END IF
582
583
584
585 IF( m.EQ.0 .OR. n.EQ.0 ) THEN
586 RETURN
587 END IF
588
589
590
592 smlnum = sqrt(
dlamch(
'S' ) ) / eps
593 bignum = one / smlnum
594
595
596
597 anrm =
dlange(
'M', m, n, a, lda, dum )
599 info = -4
600 RETURN
601 END IF
602 iscl = 0
603 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
604 iscl = 1
605 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
606 ELSE IF( anrm.GT.bignum ) THEN
607 iscl = 1
608 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
609 END IF
610
611 IF( m.GE.n ) THEN
612
613
614
615
616
617 IF( m.GE.mnthr ) THEN
618
619 IF( wntqn ) THEN
620
621
622
623
624 itau = 1
625 nwork = itau + n
626
627
628
629
630
631 CALL dgeqrf( m, n, a, lda, work( itau ),
632 $ work( nwork ),
633 $ lwork - nwork + 1, ierr )
634
635
636
637 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ),
638 $ lda )
639 ie = 1
640 itauq = ie + n
641 itaup = itauq + n
642 nwork = itaup + n
643
644
645
646
647
648 CALL dgebrd( n, n, a, lda, s, work( ie ),
649 $ work( itauq ),
650 $ work( itaup ), work( nwork ), lwork-nwork+1,
651 $ ierr )
652 nwork = ie + n
653
654
655
656
657 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum,
658 $ 1,
659 $ dum, idum, work( nwork ), iwork, info )
660
661 ELSE IF( wntqo ) THEN
662
663
664
665
666
667 ir = 1
668
669
670
671 IF( lwork .GE. lda*n + n*n + 3*n + bdspac ) THEN
672 ldwrkr = lda
673 ELSE
674 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
675 END IF
676 itau = ir + ldwrkr*n
677 nwork = itau + n
678
679
680
681
682
683 CALL dgeqrf( m, n, a, lda, work( itau ),
684 $ work( nwork ),
685 $ lwork - nwork + 1, ierr )
686
687
688
689 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
690 CALL dlaset(
'L', n - 1, n - 1, zero, zero,
691 $ work(ir+1),
692 $ ldwrkr )
693
694
695
696
697
698 CALL dorgqr( m, n, n, a, lda, work( itau ),
699 $ work( nwork ), lwork - nwork + 1, ierr )
700 ie = itau
701 itauq = ie + n
702 itaup = itauq + n
703 nwork = itaup + n
704
705
706
707
708
709 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
710 $ work( itauq ), work( itaup ), work( nwork ),
711 $ lwork - nwork + 1, ierr )
712
713
714
715 iu = nwork
716 nwork = iu + n*n
717
718
719
720
721
722
723 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
724 $ n,
725 $ vt, ldvt, dum, idum, work( nwork ), iwork,
726 $ info )
727
728
729
730
731
732
733 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ),
734 $ ldwrkr,
735 $ work( itauq ), work( iu ), n, work( nwork ),
736 $ lwork - nwork + 1, ierr )
737 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ),
738 $ ldwrkr,
739 $ work( itaup ), vt, ldvt, work( nwork ),
740 $ lwork - nwork + 1, ierr )
741
742
743
744
745
746
747 DO 10 i = 1, m, ldwrkr
748 chunk = min( m - i + 1, ldwrkr )
749 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
750 $ lda, work( iu ), n, zero, work( ir ),
751 $ ldwrkr )
752 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
753 $ a( i, 1 ), lda )
754 10 CONTINUE
755
756 ELSE IF( wntqs ) THEN
757
758
759
760
761
762 ir = 1
763
764
765
766 ldwrkr = n
767 itau = ir + ldwrkr*n
768 nwork = itau + n
769
770
771
772
773
774 CALL dgeqrf( m, n, a, lda, work( itau ),
775 $ work( nwork ),
776 $ lwork - nwork + 1, ierr )
777
778
779
780 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
781 CALL dlaset(
'L', n - 1, n - 1, zero, zero,
782 $ work(ir+1),
783 $ ldwrkr )
784
785
786
787
788
789 CALL dorgqr( m, n, n, a, lda, work( itau ),
790 $ work( nwork ), lwork - nwork + 1, ierr )
791 ie = itau
792 itauq = ie + n
793 itaup = itauq + n
794 nwork = itaup + n
795
796
797
798
799
800 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
801 $ work( itauq ), work( itaup ), work( nwork ),
802 $ lwork - nwork + 1, ierr )
803
804
805
806
807
808
809 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
810 $ ldvt, dum, idum, work( nwork ), iwork,
811 $ info )
812
813
814
815
816
817
818 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ),
819 $ ldwrkr,
820 $ work( itauq ), u, ldu, work( nwork ),
821 $ lwork - nwork + 1, ierr )
822
823 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ),
824 $ ldwrkr,
825 $ work( itaup ), vt, ldvt, work( nwork ),
826 $ lwork - nwork + 1, ierr )
827
828
829
830
831
832 CALL dlacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
833 CALL dgemm(
'N',
'N', m, n, n, one, a, lda,
834 $ work( ir ),
835 $ ldwrkr, zero, u, ldu )
836
837 ELSE IF( wntqa ) THEN
838
839
840
841
842
843 iu = 1
844
845
846
847 ldwrku = n
848 itau = iu + ldwrku*n
849 nwork = itau + n
850
851
852
853
854
855 CALL dgeqrf( m, n, a, lda, work( itau ),
856 $ work( nwork ),
857 $ lwork - nwork + 1, ierr )
858 CALL dlacpy(
'L', m, n, a, lda, u, ldu )
859
860
861
862
863 CALL dorgqr( m, m, n, u, ldu, work( itau ),
864 $ work( nwork ), lwork - nwork + 1, ierr )
865
866
867
868 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ),
869 $ lda )
870 ie = itau
871 itauq = ie + n
872 itaup = itauq + n
873 nwork = itaup + n
874
875
876
877
878
879 CALL dgebrd( n, n, a, lda, s, work( ie ),
880 $ work( itauq ),
881 $ work( itaup ), work( nwork ), lwork-nwork+1,
882 $ ierr )
883
884
885
886
887
888
889 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
890 $ n,
891 $ vt, ldvt, dum, idum, work( nwork ), iwork,
892 $ info )
893
894
895
896
897
898
899 CALL dormbr(
'Q',
'L',
'N', n, n, n, a, lda,
900 $ work( itauq ), work( iu ), ldwrku,
901 $ work( nwork ), lwork - nwork + 1, ierr )
902 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
903 $ work( itaup ), vt, ldvt, work( nwork ),
904 $ lwork - nwork + 1, ierr )
905
906
907
908
909
910 CALL dgemm(
'N',
'N', m, n, n, one, u, ldu,
911 $ work( iu ),
912 $ ldwrku, zero, a, lda )
913
914
915
916 CALL dlacpy(
'F', m, n, a, lda, u, ldu )
917
918 END IF
919
920 ELSE
921
922
923
924
925
926
927 ie = 1
928 itauq = ie + n
929 itaup = itauq + n
930 nwork = itaup + n
931
932
933
934
935
936 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
937 $ work( itaup ), work( nwork ), lwork-nwork+1,
938 $ ierr )
939 IF( wntqn ) THEN
940
941
942
943
944
945 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum,
946 $ 1,
947 $ dum, idum, work( nwork ), iwork, info )
948 ELSE IF( wntqo ) THEN
949
950 iu = nwork
951 IF( lwork .GE. m*n + 3*n + bdspac ) THEN
952
953
954
955 ldwrku = m
956 nwork = iu + ldwrku*n
957 CALL dlaset(
'F', m, n, zero, zero, work( iu ),
958 $ ldwrku )
959
960 ir = -1
961 ELSE
962
963
964
965 ldwrku = n
966 nwork = iu + ldwrku*n
967
968
969
970 ir = nwork
971 ldwrkr = ( lwork - n*n - 3*n ) / n
972 END IF
973 nwork = iu + ldwrku*n
974
975
976
977
978
979
980 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
981 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
982 $ iwork, info )
983
984
985
986
987
988 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
989 $ work( itaup ), vt, ldvt, work( nwork ),
990 $ lwork - nwork + 1, ierr )
991
992 IF( lwork .GE. m*n + 3*n + bdspac ) THEN
993
994
995
996
997
998
999 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1000 $ work( itauq ), work( iu ), ldwrku,
1001 $ work( nwork ), lwork - nwork + 1, ierr )
1002
1003
1004
1005 CALL dlacpy(
'F', m, n, work( iu ), ldwrku, a,
1006 $ lda )
1007 ELSE
1008
1009
1010
1011
1012
1013
1014 CALL dorgbr(
'Q', m, n, n, a, lda, work( itauq ),
1015 $ work( nwork ), lwork - nwork + 1, ierr )
1016
1017
1018
1019
1020
1021
1022
1023 DO 20 i = 1, m, ldwrkr
1024 chunk = min( m - i + 1, ldwrkr )
1025 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i,
1026 $ 1 ),
1027 $ lda, work( iu ), ldwrku, zero,
1028 $ work( ir ), ldwrkr )
1029 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
1030 $ a( i, 1 ), lda )
1031 20 CONTINUE
1032 END IF
1033
1034 ELSE IF( wntqs ) THEN
1035
1036
1037
1038
1039
1040
1041
1042 CALL dlaset(
'F', m, n, zero, zero, u, ldu )
1043 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1044 $ ldvt, dum, idum, work( nwork ), iwork,
1045 $ info )
1046
1047
1048
1049
1050
1051
1052 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1053 $ work( itauq ), u, ldu, work( nwork ),
1054 $ lwork - nwork + 1, ierr )
1055 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
1056 $ work( itaup ), vt, ldvt, work( nwork ),
1057 $ lwork - nwork + 1, ierr )
1058 ELSE IF( wntqa ) THEN
1059
1060
1061
1062
1063
1064
1065
1066 CALL dlaset(
'F', m, m, zero, zero, u, ldu )
1067 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1068 $ ldvt, dum, idum, work( nwork ), iwork,
1069 $ info )
1070
1071
1072
1073 IF( m.GT.n ) THEN
1074 CALL dlaset(
'F', m - n, m - n, zero, one, u(n+1,
1075 $ n+1),
1076 $ ldu )
1077 END IF
1078
1079
1080
1081
1082
1083
1084 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1085 $ work( itauq ), u, ldu, work( nwork ),
1086 $ lwork - nwork + 1, ierr )
1087 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1088 $ work( itaup ), vt, ldvt, work( nwork ),
1089 $ lwork - nwork + 1, ierr )
1090 END IF
1091
1092 END IF
1093
1094 ELSE
1095
1096
1097
1098
1099
1100 IF( n.GE.mnthr ) THEN
1101
1102 IF( wntqn ) THEN
1103
1104
1105
1106
1107 itau = 1
1108 nwork = itau + m
1109
1110
1111
1112
1113
1114 CALL dgelqf( m, n, a, lda, work( itau ),
1115 $ work( nwork ),
1116 $ lwork - nwork + 1, ierr )
1117
1118
1119
1120 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ),
1121 $ lda )
1122 ie = 1
1123 itauq = ie + m
1124 itaup = itauq + m
1125 nwork = itaup + m
1126
1127
1128
1129
1130
1131 CALL dgebrd( m, m, a, lda, s, work( ie ),
1132 $ work( itauq ),
1133 $ work( itaup ), work( nwork ), lwork-nwork+1,
1134 $ ierr )
1135 nwork = ie + m
1136
1137
1138
1139
1140 CALL dbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum,
1141 $ 1,
1142 $ dum, idum, work( nwork ), iwork, info )
1143
1144 ELSE IF( wntqo ) THEN
1145
1146
1147
1148
1149
1150 ivt = 1
1151
1152
1153
1154
1155 il = ivt + m*m
1156 IF( lwork .GE. m*n + m*m + 3*m + bdspac ) THEN
1157 ldwrkl = m
1158 chunk = n
1159 ELSE
1160 ldwrkl = m
1161 chunk = ( lwork - m*m ) / m
1162 END IF
1163 itau = il + ldwrkl*m
1164 nwork = itau + m
1165
1166
1167
1168
1169
1170 CALL dgelqf( m, n, a, lda, work( itau ),
1171 $ work( nwork ),
1172 $ lwork - nwork + 1, ierr )
1173
1174
1175
1176 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1177 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1178 $ work( il + ldwrkl ), ldwrkl )
1179
1180
1181
1182
1183
1184 CALL dorglq( m, n, m, a, lda, work( itau ),
1185 $ work( nwork ), lwork - nwork + 1, ierr )
1186 ie = itau
1187 itauq = ie + m
1188 itaup = itauq + m
1189 nwork = itaup + m
1190
1191
1192
1193
1194
1195 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1196 $ work( itauq ), work( itaup ), work( nwork ),
1197 $ lwork - nwork + 1, ierr )
1198
1199
1200
1201
1202
1203
1204 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1205 $ work( ivt ), m, dum, idum, work( nwork ),
1206 $ iwork, info )
1207
1208
1209
1210
1211
1212
1213 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ),
1214 $ ldwrkl,
1215 $ work( itauq ), u, ldu, work( nwork ),
1216 $ lwork - nwork + 1, ierr )
1217 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ),
1218 $ ldwrkl,
1219 $ work( itaup ), work( ivt ), m,
1220 $ work( nwork ), lwork - nwork + 1, ierr )
1221
1222
1223
1224
1225
1226
1227
1228 DO 30 i = 1, n, chunk
1229 blk = min( n - i + 1, chunk )
1230 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1231 $ m,
1232 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1233 CALL dlacpy(
'F', m, blk, work( il ), ldwrkl,
1234 $ a( 1, i ), lda )
1235 30 CONTINUE
1236
1237 ELSE IF( wntqs ) THEN
1238
1239
1240
1241
1242
1243 il = 1
1244
1245
1246
1247 ldwrkl = m
1248 itau = il + ldwrkl*m
1249 nwork = itau + m
1250
1251
1252
1253
1254
1255 CALL dgelqf( m, n, a, lda, work( itau ),
1256 $ work( nwork ),
1257 $ lwork - nwork + 1, ierr )
1258
1259
1260
1261 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1262 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1263 $ work( il + ldwrkl ), ldwrkl )
1264
1265
1266
1267
1268
1269 CALL dorglq( m, n, m, a, lda, work( itau ),
1270 $ work( nwork ), lwork - nwork + 1, ierr )
1271 ie = itau
1272 itauq = ie + m
1273 itaup = itauq + m
1274 nwork = itaup + m
1275
1276
1277
1278
1279
1280 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1281 $ work( itauq ), work( itaup ), work( nwork ),
1282 $ lwork - nwork + 1, ierr )
1283
1284
1285
1286
1287
1288
1289 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1290 $ ldvt, dum, idum, work( nwork ), iwork,
1291 $ info )
1292
1293
1294
1295
1296
1297
1298 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ),
1299 $ ldwrkl,
1300 $ work( itauq ), u, ldu, work( nwork ),
1301 $ lwork - nwork + 1, ierr )
1302 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ),
1303 $ ldwrkl,
1304 $ work( itaup ), vt, ldvt, work( nwork ),
1305 $ lwork - nwork + 1, ierr )
1306
1307
1308
1309
1310
1311 CALL dlacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1312 CALL dgemm(
'N',
'N', m, n, m, one, work( il ),
1313 $ ldwrkl,
1314 $ a, lda, zero, vt, ldvt )
1315
1316 ELSE IF( wntqa ) THEN
1317
1318
1319
1320
1321
1322 ivt = 1
1323
1324
1325
1326 ldwkvt = m
1327 itau = ivt + ldwkvt*m
1328 nwork = itau + m
1329
1330
1331
1332
1333
1334 CALL dgelqf( m, n, a, lda, work( itau ),
1335 $ work( nwork ),
1336 $ lwork - nwork + 1, ierr )
1337 CALL dlacpy(
'U', m, n, a, lda, vt, ldvt )
1338
1339
1340
1341
1342
1343 CALL dorglq( n, n, m, vt, ldvt, work( itau ),
1344 $ work( nwork ), lwork - nwork + 1, ierr )
1345
1346
1347
1348 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ),
1349 $ lda )
1350 ie = itau
1351 itauq = ie + m
1352 itaup = itauq + m
1353 nwork = itaup + m
1354
1355
1356
1357
1358
1359 CALL dgebrd( m, m, a, lda, s, work( ie ),
1360 $ work( itauq ),
1361 $ work( itaup ), work( nwork ), lwork-nwork+1,
1362 $ ierr )
1363
1364
1365
1366
1367
1368
1369 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1370 $ work( ivt ), ldwkvt, dum, idum,
1371 $ work( nwork ), iwork, info )
1372
1373
1374
1375
1376
1377
1378 CALL dormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1379 $ work( itauq ), u, ldu, work( nwork ),
1380 $ lwork - nwork + 1, ierr )
1381 CALL dormbr(
'P',
'R',
'T', m, m, m, a, lda,
1382 $ work( itaup ), work( ivt ), ldwkvt,
1383 $ work( nwork ), lwork - nwork + 1, ierr )
1384
1385
1386
1387
1388
1389 CALL dgemm(
'N',
'N', m, n, m, one, work( ivt ),
1390 $ ldwkvt,
1391 $ vt, ldvt, zero, a, lda )
1392
1393
1394
1395 CALL dlacpy(
'F', m, n, a, lda, vt, ldvt )
1396
1397 END IF
1398
1399 ELSE
1400
1401
1402
1403
1404
1405
1406 ie = 1
1407 itauq = ie + m
1408 itaup = itauq + m
1409 nwork = itaup + m
1410
1411
1412
1413
1414
1415 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1416 $ work( itaup ), work( nwork ), lwork-nwork+1,
1417 $ ierr )
1418 IF( wntqn ) THEN
1419
1420
1421
1422
1423
1424 CALL dbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum,
1425 $ 1,
1426 $ dum, idum, work( nwork ), iwork, info )
1427 ELSE IF( wntqo ) THEN
1428
1429 ldwkvt = m
1430 ivt = nwork
1431 IF( lwork .GE. m*n + 3*m + bdspac ) THEN
1432
1433
1434
1435 CALL dlaset(
'F', m, n, zero, zero, work( ivt ),
1436 $ ldwkvt )
1437 nwork = ivt + ldwkvt*n
1438
1439 il = -1
1440 ELSE
1441
1442
1443
1444 nwork = ivt + ldwkvt*m
1445 il = nwork
1446
1447
1448
1449 chunk = ( lwork - m*m - 3*m ) / m
1450 END IF
1451
1452
1453
1454
1455
1456
1457 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1458 $ work( ivt ), ldwkvt, dum, idum,
1459 $ work( nwork ), iwork, info )
1460
1461
1462
1463
1464
1465 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1466 $ work( itauq ), u, ldu, work( nwork ),
1467 $ lwork - nwork + 1, ierr )
1468
1469 IF( lwork .GE. m*n + 3*m + bdspac ) THEN
1470
1471
1472
1473
1474
1475
1476 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1477 $ work( itaup ), work( ivt ), ldwkvt,
1478 $ work( nwork ), lwork - nwork + 1, ierr )
1479
1480
1481
1482 CALL dlacpy(
'F', m, n, work( ivt ), ldwkvt, a,
1483 $ lda )
1484 ELSE
1485
1486
1487
1488
1489
1490
1491 CALL dorgbr(
'P', m, n, m, a, lda, work( itaup ),
1492 $ work( nwork ), lwork - nwork + 1, ierr )
1493
1494
1495
1496
1497
1498
1499
1500 DO 40 i = 1, n, chunk
1501 blk = min( n - i + 1, chunk )
1502 CALL dgemm(
'N',
'N', m, blk, m, one,
1503 $ work( ivt ),
1504 $ ldwkvt, a( 1, i ), lda, zero,
1505 $ work( il ), m )
1506 CALL dlacpy(
'F', m, blk, work( il ), m, a( 1,
1507 $ i ),
1508 $ lda )
1509 40 CONTINUE
1510 END IF
1511 ELSE IF( wntqs ) THEN
1512
1513
1514
1515
1516
1517
1518
1519 CALL dlaset(
'F', m, n, zero, zero, vt, ldvt )
1520 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1521 $ ldvt, dum, idum, work( nwork ), iwork,
1522 $ info )
1523
1524
1525
1526
1527
1528
1529 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1530 $ work( itauq ), u, ldu, work( nwork ),
1531 $ lwork - nwork + 1, ierr )
1532 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1533 $ work( itaup ), vt, ldvt, work( nwork ),
1534 $ lwork - nwork + 1, ierr )
1535 ELSE IF( wntqa ) THEN
1536
1537
1538
1539
1540
1541
1542
1543 CALL dlaset(
'F', n, n, zero, zero, vt, ldvt )
1544 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1545 $ ldvt, dum, idum, work( nwork ), iwork,
1546 $ info )
1547
1548
1549
1550 IF( n.GT.m ) THEN
1551 CALL dlaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1552 $ ldvt )
1553 END IF
1554
1555
1556
1557
1558
1559
1560 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1561 $ work( itauq ), u, ldu, work( nwork ),
1562 $ lwork - nwork + 1, ierr )
1563 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1564 $ work( itaup ), vt, ldvt, work( nwork ),
1565 $ lwork - nwork + 1, ierr )
1566 END IF
1567
1568 END IF
1569
1570 END IF
1571
1572
1573
1574 IF( iscl.EQ.1 ) THEN
1575 IF( anrm.GT.bignum )
1576 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1577 $ ierr )
1578 IF( anrm.LT.smlnum )
1579 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
1580 $ ierr )
1581 END IF
1582
1583
1584
1586
1587 RETURN
1588
1589
1590
subroutine xerbla(srname, info)
subroutine dbdsdc(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info)
DBDSDC
subroutine dgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
DGEBRD
subroutine dgelqf(m, n, a, lda, tau, work, lwork, info)
DGELQF
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
logical function disnan(din)
DISNAN tests input for NaN.
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
double precision function dlamch(cmach)
DLAMCH
double precision function dlange(norm, m, n, a, lda, work)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
double precision function droundup_lwork(lwork)
DROUNDUP_LWORK
subroutine dorgbr(vect, m, n, k, a, lda, tau, work, lwork, info)
DORGBR
subroutine dorglq(m, n, k, a, lda, tau, work, lwork, info)
DORGLQ
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMBR