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 REAL A( LDA, * ), S( * ), U( LDU, * ),
224 $ VT( LDVT, * ), WORK( * )
225
226
227
228
229
230 REAL ZERO, ONE
231 parameter( zero = 0.0e0, one = 1.0e0 )
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_SGEBRD_MN, LWORK_SGEBRD_MM,
240 $ LWORK_SGEBRD_NN, LWORK_SGELQF_MN,
241 $ LWORK_SGEQRF_MN,
242 $ LWORK_SORGBR_P_MM, LWORK_SORGBR_Q_NN,
243 $ LWORK_SORGLQ_MN, LWORK_SORGLQ_NN,
244 $ LWORK_SORGQR_MM, LWORK_SORGQR_MN,
245 $ LWORK_SORMBR_PRT_MM, LWORK_SORMBR_QLN_MM,
246 $ LWORK_SORMBR_PRT_MN, LWORK_SORMBR_QLN_MN,
247 $ LWORK_SORMBR_PRT_NN, LWORK_SORMBR_QLN_NN
248 REAL ANRM, BIGNUM, EPS, SMLNUM
249
250
251 INTEGER IDUM( 1 )
252 REAL DUM( 1 )
253
254
259
260
261 LOGICAL LSAME, SISNAN
262 REAL SLAMCH, SLANGE, SROUNDUP_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( real( minmn )*11.0e0 / 6.0e0 )
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 sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
325 $ dum(1), dum(1), -1, ierr )
326 lwork_sgebrd_mn = int( dum(1) )
327
328 CALL sgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
329 $ dum(1), dum(1), -1, ierr )
330 lwork_sgebrd_nn = int( dum(1) )
331
332 CALL sgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
333 lwork_sgeqrf_mn = int( dum(1) )
334
335 CALL sorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
336 $ ierr )
337 lwork_sorgbr_q_nn = int( dum(1) )
338
339 CALL sorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1,
340 $ ierr )
341 lwork_sorgqr_mm = int( dum(1) )
342
343 CALL sorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1,
344 $ ierr )
345 lwork_sorgqr_mn = int( dum(1) )
346
347 CALL sormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
348 $ dum(1), dum(1), n, dum(1), -1, ierr )
349 lwork_sormbr_prt_nn = int( dum(1) )
350
351 CALL sormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
352 $ dum(1), dum(1), n, dum(1), -1, ierr )
353 lwork_sormbr_qln_nn = int( dum(1) )
354
355 CALL sormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
356 $ dum(1), dum(1), m, dum(1), -1, ierr )
357 lwork_sormbr_qln_mn = int( dum(1) )
358
359 CALL sormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
360 $ dum(1), dum(1), m, dum(1), -1, ierr )
361 lwork_sormbr_qln_mm = int( dum(1) )
362
363 IF( m.GE.mnthr ) THEN
364 IF( wntqn ) THEN
365
366
367
368 wrkbl = n + lwork_sgeqrf_mn
369 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
370 maxwrk = max( wrkbl, bdspac + n )
371 minwrk = bdspac + n
372 ELSE IF( wntqo ) THEN
373
374
375
376 wrkbl = n + lwork_sgeqrf_mn
377 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
378 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
379 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
380 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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_sgeqrf_mn
389 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
390 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
391 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
392 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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_sgeqrf_mn
401 wrkbl = max( wrkbl, n + lwork_sorgqr_mm )
402 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
403 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
404 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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_sgebrd_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_sormbr_prt_nn )
421 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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_sormbr_qln_mn )
428 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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_sormbr_qln_mm )
434 wrkbl = max( wrkbl, 3*n + lwork_sormbr_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 sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
453 $ dum(1), dum(1), -1, ierr )
454 lwork_sgebrd_mn = int( dum(1) )
455
456 CALL sgebrd( m, m, a, m, s, dum(1), dum(1),
457 $ dum(1), dum(1), -1, ierr )
458 lwork_sgebrd_mm = int( dum(1) )
459
460 CALL sgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
461 lwork_sgelqf_mn = int( dum(1) )
462
463 CALL sorglq( n, n, m, dum(1), n, dum(1), dum(1), -1,
464 $ ierr )
465 lwork_sorglq_nn = int( dum(1) )
466
467 CALL sorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
468 lwork_sorglq_mn = int( dum(1) )
469
470 CALL sorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1,
471 $ ierr )
472 lwork_sorgbr_p_mm = int( dum(1) )
473
474 CALL sormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
475 $ dum(1), dum(1), m, dum(1), -1, ierr )
476 lwork_sormbr_prt_mm = int( dum(1) )
477
478 CALL sormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
479 $ dum(1), dum(1), m, dum(1), -1, ierr )
480 lwork_sormbr_prt_mn = int( dum(1) )
481
482 CALL sormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
483 $ dum(1), dum(1), n, dum(1), -1, ierr )
484 lwork_sormbr_prt_nn = int( dum(1) )
485
486 CALL sormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
487 $ dum(1), dum(1), m, dum(1), -1, ierr )
488 lwork_sormbr_qln_mm = int( dum(1) )
489
490 IF( n.GE.mnthr ) THEN
491 IF( wntqn ) THEN
492
493
494
495 wrkbl = m + lwork_sgelqf_mn
496 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
497 maxwrk = max( wrkbl, bdspac + m )
498 minwrk = bdspac + m
499 ELSE IF( wntqo ) THEN
500
501
502
503 wrkbl = m + lwork_sgelqf_mn
504 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
505 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
506 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
507 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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_sgelqf_mn
516 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
517 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
518 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
519 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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_sgelqf_mn
528 wrkbl = max( wrkbl, m + lwork_sorglq_nn )
529 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
530 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
531 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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_sgebrd_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_sormbr_qln_mm )
548 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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_sormbr_qln_mm )
555 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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_sormbr_qln_mm )
561 wrkbl = max( wrkbl, 3*m + lwork_sormbr_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(
'SGESDD', -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(
slamch(
'S' ) ) / eps
593 bignum = one / smlnum
594
595
596
597 anrm =
slange(
'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 slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
606 ELSE IF( anrm.GT.bignum ) THEN
607 iscl = 1
608 CALL slascl(
'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 sgeqrf( m, n, a, lda, work( itau ),
632 $ work( nwork ),
633 $ lwork - nwork + 1, ierr )
634
635
636
637 CALL slaset(
'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 sgebrd( 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 sbdsdc(
'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 sgeqrf( m, n, a, lda, work( itau ),
684 $ work( nwork ),
685 $ lwork - nwork + 1, ierr )
686
687
688
689 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
690 CALL slaset(
'L', n - 1, n - 1, zero, zero,
691 $ work(ir+1),
692 $ ldwrkr )
693
694
695
696
697
698 CALL sorgqr( 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 sgebrd( 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 sbdsdc(
'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 sormbr(
'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 sormbr(
'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 sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
750 $ lda, work( iu ), n, zero, work( ir ),
751 $ ldwrkr )
752 CALL slacpy(
'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 sgeqrf( m, n, a, lda, work( itau ),
775 $ work( nwork ),
776 $ lwork - nwork + 1, ierr )
777
778
779
780 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
781 CALL slaset(
'L', n - 1, n - 1, zero, zero,
782 $ work(ir+1),
783 $ ldwrkr )
784
785
786
787
788
789 CALL sorgqr( 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 sgebrd( 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 sbdsdc(
'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 sormbr(
'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 sormbr(
'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 slacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
833 CALL sgemm(
'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 sgeqrf( m, n, a, lda, work( itau ),
856 $ work( nwork ),
857 $ lwork - nwork + 1, ierr )
858 CALL slacpy(
'L', m, n, a, lda, u, ldu )
859
860
861
862
863 CALL sorgqr( m, m, n, u, ldu, work( itau ),
864 $ work( nwork ), lwork - nwork + 1, ierr )
865
866
867
868 CALL slaset(
'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 sgebrd( 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 sbdsdc(
'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 sormbr(
'Q',
'L',
'N', n, n, n, a, lda,
900 $ work( itauq ), work( iu ), ldwrku,
901 $ work( nwork ), lwork - nwork + 1, ierr )
902 CALL sormbr(
'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 sgemm(
'N',
'N', m, n, n, one, u, ldu,
911 $ work( iu ),
912 $ ldwrku, zero, a, lda )
913
914
915
916 CALL slacpy(
'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 sgebrd( 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 sbdsdc(
'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 slaset(
'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 sbdsdc(
'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 sormbr(
'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 sormbr(
'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 slacpy(
'F', m, n, work( iu ), ldwrku, a,
1006 $ lda )
1007 ELSE
1008
1009
1010
1011
1012
1013
1014 CALL sorgbr(
'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 sgemm(
'N',
'N', chunk, n, n, one, a( i,
1026 $ 1 ),
1027 $ lda, work( iu ), ldwrku, zero,
1028 $ work( ir ), ldwrkr )
1029 CALL slacpy(
'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 slaset(
'F', m, n, zero, zero, u, ldu )
1043 CALL sbdsdc(
'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 sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1053 $ work( itauq ), u, ldu, work( nwork ),
1054 $ lwork - nwork + 1, ierr )
1055 CALL sormbr(
'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 slaset(
'F', m, m, zero, zero, u, ldu )
1067 CALL sbdsdc(
'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 slaset(
'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 sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1085 $ work( itauq ), u, ldu, work( nwork ),
1086 $ lwork - nwork + 1, ierr )
1087 CALL sormbr(
'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 sgelqf( m, n, a, lda, work( itau ),
1115 $ work( nwork ),
1116 $ lwork - nwork + 1, ierr )
1117
1118
1119
1120 CALL slaset(
'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 sgebrd( 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 sbdsdc(
'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 sgelqf( m, n, a, lda, work( itau ),
1171 $ work( nwork ),
1172 $ lwork - nwork + 1, ierr )
1173
1174
1175
1176 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1177 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1178 $ work( il + ldwrkl ), ldwrkl )
1179
1180
1181
1182
1183
1184 CALL sorglq( 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 sgebrd( 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 sbdsdc(
'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 sormbr(
'Q',
'L',
'N', m, m, m, work( il ),
1214 $ ldwrkl,
1215 $ work( itauq ), u, ldu, work( nwork ),
1216 $ lwork - nwork + 1, ierr )
1217 CALL sormbr(
'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 sgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1231 $ m,
1232 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1233 CALL slacpy(
'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 sgelqf( m, n, a, lda, work( itau ),
1256 $ work( nwork ),
1257 $ lwork - nwork + 1, ierr )
1258
1259
1260
1261 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1262 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1263 $ work( il + ldwrkl ), ldwrkl )
1264
1265
1266
1267
1268
1269 CALL sorglq( 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 sgebrd( 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 sbdsdc(
'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 sormbr(
'Q',
'L',
'N', m, m, m, work( il ),
1299 $ ldwrkl,
1300 $ work( itauq ), u, ldu, work( nwork ),
1301 $ lwork - nwork + 1, ierr )
1302 CALL sormbr(
'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 slacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1312 CALL sgemm(
'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 sgelqf( m, n, a, lda, work( itau ),
1335 $ work( nwork ),
1336 $ lwork - nwork + 1, ierr )
1337 CALL slacpy(
'U', m, n, a, lda, vt, ldvt )
1338
1339
1340
1341
1342
1343 CALL sorglq( n, n, m, vt, ldvt, work( itau ),
1344 $ work( nwork ), lwork - nwork + 1, ierr )
1345
1346
1347
1348 CALL slaset(
'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 sgebrd( 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 sbdsdc(
'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 sormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1379 $ work( itauq ), u, ldu, work( nwork ),
1380 $ lwork - nwork + 1, ierr )
1381 CALL sormbr(
'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 sgemm(
'N',
'N', m, n, m, one, work( ivt ),
1390 $ ldwkvt,
1391 $ vt, ldvt, zero, a, lda )
1392
1393
1394
1395 CALL slacpy(
'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 sgebrd( 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 sbdsdc(
'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 slaset(
'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 sbdsdc(
'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 sormbr(
'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 sormbr(
'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 slacpy(
'F', m, n, work( ivt ), ldwkvt, a,
1483 $ lda )
1484 ELSE
1485
1486
1487
1488
1489
1490
1491 CALL sorgbr(
'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 sgemm(
'N',
'N', m, blk, m, one,
1503 $ work( ivt ),
1504 $ ldwkvt, a( 1, i ), lda, zero,
1505 $ work( il ), m )
1506 CALL slacpy(
'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 slaset(
'F', m, n, zero, zero, vt, ldvt )
1520 CALL sbdsdc(
'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 sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1530 $ work( itauq ), u, ldu, work( nwork ),
1531 $ lwork - nwork + 1, ierr )
1532 CALL sormbr(
'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 slaset(
'F', n, n, zero, zero, vt, ldvt )
1544 CALL sbdsdc(
'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 slaset(
'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 sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1561 $ work( itauq ), u, ldu, work( nwork ),
1562 $ lwork - nwork + 1, ierr )
1563 CALL sormbr(
'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 slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1577 $ ierr )
1578 IF( anrm.LT.smlnum )
1579 $
CALL slascl(
'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 sbdsdc(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info)
SBDSDC
subroutine sgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
SGEBRD
subroutine sgelqf(m, n, a, lda, tau, work, lwork, info)
SGELQF
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
logical function sisnan(sin)
SISNAN tests input for NaN.
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function slange(norm, m, n, a, lda, work)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
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 slaset(uplo, m, n, alpha, beta, a, lda)
SLASET 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 sorgbr(vect, m, n, k, a, lda, tau, work, lwork, info)
SORGBR
subroutine sorglq(m, n, k, a, lda, tau, work, lwork, info)
SORGLQ
subroutine sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMBR