216 SUBROUTINE sgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
217 $ WORK, LWORK, IWORK, INFO )
226 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
230 REAL A( LDA, * ), S( * ), U( LDU, * ),
231 $ vt( ldvt, * ), work( * )
238 parameter( zero = 0.0e0, one = 1.0e0 )
241 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
242 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
243 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
244 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
245 $ mnthr, nwork, wrkbl
246 INTEGER LWORK_SGEBRD_MN, LWORK_SGEBRD_MM,
247 $ lwork_sgebrd_nn, lwork_sgelqf_mn,
249 $ lwork_sorgbr_p_mm, lwork_sorgbr_q_nn,
250 $ lwork_sorglq_mn, lwork_sorglq_nn,
251 $ lwork_sorgqr_mm, lwork_sorgqr_mn,
252 $ lwork_sormbr_prt_mm, lwork_sormbr_qln_mm,
253 $ lwork_sormbr_prt_mn, lwork_sormbr_qln_mn,
254 $ lwork_sormbr_prt_nn, lwork_sormbr_qln_nn
255 REAL ANRM, BIGNUM, EPS, SMLNUM
267 LOGICAL LSAME, SISNAN
269 EXTERNAL slamch, slange, lsame, sisnan
272 INTRINSIC int, max, min, sqrt
280 wntqa = lsame( jobz,
'A' )
281 wntqs = lsame( jobz,
'S' )
282 wntqas = wntqa .OR. wntqs
283 wntqo = lsame( jobz,
'O' )
284 wntqn = lsame( jobz,
'N' )
285 lquery = ( lwork.EQ.-1 )
287 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
289 ELSE IF( m.LT.0 )
THEN
291 ELSE IF( n.LT.0 )
THEN
293 ELSE IF( lda.LT.max( 1, m ) )
THEN
295 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
296 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
298 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
299 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
300 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
315 mnthr = int( minmn*11.0e0 / 6.0e0 )
316 IF( m.GE.n .AND. minmn.GT.0 )
THEN
329 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
330 $ dum(1), dum(1), -1, ierr )
331 lwork_sgebrd_mn = int( dum(1) )
333 CALL sgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
334 $ dum(1), dum(1), -1, ierr )
335 lwork_sgebrd_nn = int( dum(1) )
337 CALL sgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
338 lwork_sgeqrf_mn = int( dum(1) )
340 CALL sorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
342 lwork_sorgbr_q_nn = int( dum(1) )
344 CALL sorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
345 lwork_sorgqr_mm = int( dum(1) )
347 CALL sorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
348 lwork_sorgqr_mn = int( dum(1) )
350 CALL sormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
351 $ dum(1), dum(1), n, dum(1), -1, ierr )
352 lwork_sormbr_prt_nn = int( dum(1) )
354 CALL sormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
355 $ dum(1), dum(1), n, dum(1), -1, ierr )
356 lwork_sormbr_qln_nn = int( dum(1) )
358 CALL sormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
359 $ dum(1), dum(1), m, dum(1), -1, ierr )
360 lwork_sormbr_qln_mn = int( dum(1) )
362 CALL sormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
363 $ dum(1), dum(1), m, dum(1), -1, ierr )
364 lwork_sormbr_qln_mm = int( dum(1) )
366 IF( m.GE.mnthr )
THEN
371 wrkbl = n + lwork_sgeqrf_mn
372 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
373 maxwrk = max( wrkbl, bdspac + n )
375 ELSE IF( wntqo )
THEN
379 wrkbl = n + lwork_sgeqrf_mn
380 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
381 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
382 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
383 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
384 wrkbl = max( wrkbl, 3*n + bdspac )
385 maxwrk = wrkbl + 2*n*n
386 minwrk = bdspac + 2*n*n + 3*n
387 ELSE IF( wntqs )
THEN
391 wrkbl = n + lwork_sgeqrf_mn
392 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
393 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
394 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
395 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
396 wrkbl = max( wrkbl, 3*n + bdspac )
398 minwrk = bdspac + n*n + 3*n
399 ELSE IF( wntqa )
THEN
403 wrkbl = n + lwork_sgeqrf_mn
404 wrkbl = max( wrkbl, n + lwork_sorgqr_mm )
405 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
406 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
407 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
408 wrkbl = max( wrkbl, 3*n + bdspac )
410 minwrk = n*n + max( 3*n + bdspac, n + m )
416 wrkbl = 3*n + lwork_sgebrd_mn
419 maxwrk = max( wrkbl, 3*n + bdspac )
420 minwrk = 3*n + max( m, bdspac )
421 ELSE IF( wntqo )
THEN
423 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
424 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
425 wrkbl = max( wrkbl, 3*n + bdspac )
427 minwrk = 3*n + max( m, n*n + bdspac )
428 ELSE IF( wntqs )
THEN
430 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
431 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
432 maxwrk = max( wrkbl, 3*n + bdspac )
433 minwrk = 3*n + max( m, bdspac )
434 ELSE IF( wntqa )
THEN
436 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mm )
437 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
438 maxwrk = max( wrkbl, 3*n + bdspac )
439 minwrk = 3*n + max( m, bdspac )
442 ELSE IF( minmn.GT.0 )
THEN
455 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
456 $ dum(1), dum(1), -1, ierr )
457 lwork_sgebrd_mn = int( dum(1) )
459 CALL sgebrd( m, m, a, m, s, dum(1), dum(1),
460 $ dum(1), dum(1), -1, ierr )
461 lwork_sgebrd_mm = int( dum(1) )
463 CALL sgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
464 lwork_sgelqf_mn = int( dum(1) )
466 CALL sorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
467 lwork_sorglq_nn = int( dum(1) )
469 CALL sorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
470 lwork_sorglq_mn = int( dum(1) )
472 CALL sorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
473 lwork_sorgbr_p_mm = int( dum(1) )
475 CALL sormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
476 $ dum(1), dum(1), m, dum(1), -1, ierr )
477 lwork_sormbr_prt_mm = int( dum(1) )
479 CALL sormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
480 $ dum(1), dum(1), m, dum(1), -1, ierr )
481 lwork_sormbr_prt_mn = int( dum(1) )
483 CALL sormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
484 $ dum(1), dum(1), n, dum(1), -1, ierr )
485 lwork_sormbr_prt_nn = int( dum(1) )
487 CALL sormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
488 $ dum(1), dum(1), m, dum(1), -1, ierr )
489 lwork_sormbr_qln_mm = int( dum(1) )
491 IF( n.GE.mnthr )
THEN
496 wrkbl = m + lwork_sgelqf_mn
497 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
498 maxwrk = max( wrkbl, bdspac + m )
500 ELSE IF( wntqo )
THEN
504 wrkbl = m + lwork_sgelqf_mn
505 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
506 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
507 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
508 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
509 wrkbl = max( wrkbl, 3*m + bdspac )
510 maxwrk = wrkbl + 2*m*m
511 minwrk = bdspac + 2*m*m + 3*m
512 ELSE IF( wntqs )
THEN
516 wrkbl = m + lwork_sgelqf_mn
517 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
518 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
519 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
520 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
521 wrkbl = max( wrkbl, 3*m + bdspac )
523 minwrk = bdspac + m*m + 3*m
524 ELSE IF( wntqa )
THEN
528 wrkbl = m + lwork_sgelqf_mn
529 wrkbl = max( wrkbl, m + lwork_sorglq_nn )
530 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
531 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
532 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
533 wrkbl = max( wrkbl, 3*m + bdspac )
535 minwrk = m*m + max( 3*m + bdspac, m + n )
541 wrkbl = 3*m + lwork_sgebrd_mn
544 maxwrk = max( wrkbl, 3*m + bdspac )
545 minwrk = 3*m + max( n, bdspac )
546 ELSE IF( wntqo )
THEN
548 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
549 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
550 wrkbl = max( wrkbl, 3*m + bdspac )
552 minwrk = 3*m + max( n, m*m + bdspac )
553 ELSE IF( wntqs )
THEN
555 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
556 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
557 maxwrk = max( wrkbl, 3*m + bdspac )
558 minwrk = 3*m + max( n, bdspac )
559 ELSE IF( wntqa )
THEN
561 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
562 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_nn )
563 maxwrk = max( wrkbl, 3*m + bdspac )
564 minwrk = 3*m + max( n, bdspac )
569 maxwrk = max( maxwrk, minwrk )
572 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
578 CALL xerbla(
'SGESDD', -info )
580 ELSE IF( lquery )
THEN
586 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
593 smlnum = sqrt( slamch(
'S' ) ) / eps
594 bignum = one / smlnum
598 anrm = slange(
'M', m, n, a, lda, dum )
599 IF( sisnan( anrm ) )
THEN
604 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
606 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
607 ELSE IF( anrm.GT.bignum )
THEN
609 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
618 IF( m.GE.mnthr )
THEN
632 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
633 $ lwork - nwork + 1, ierr )
637 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
647 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
648 $ work( itaup ), work( nwork ), lwork-nwork+1,
655 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
656 $ dum, idum, work( nwork ), iwork, info )
658 ELSE IF( wntqo )
THEN
668 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
671 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
680 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
681 $ lwork - nwork + 1, ierr )
685 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
686 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
693 CALL sorgqr( m, n, n, a, lda, work( itau ),
694 $ work( nwork ), lwork - nwork + 1, ierr )
704 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
705 $ work( itauq ), work( itaup ), work( nwork ),
706 $ lwork - nwork + 1, ierr )
718 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
719 $ vt, ldvt, dum, idum, work( nwork ), iwork,
727 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
728 $ work( itauq ), work( iu ), n, work( nwork ),
729 $ lwork - nwork + 1, ierr )
730 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
731 $ work( itaup ), vt, ldvt, work( nwork ),
732 $ lwork - nwork + 1, ierr )
739 DO 10 i = 1, m, ldwrkr
740 chunk = min( m - i + 1, ldwrkr )
741 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
742 $ lda, work( iu ), n, zero, work( ir ),
744 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
748 ELSE IF( wntqs )
THEN
766 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
767 $ lwork - nwork + 1, ierr )
771 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
772 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
779 CALL sorgqr( m, n, n, a, lda, work( itau ),
780 $ work( nwork ), lwork - nwork + 1, ierr )
790 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
791 $ work( itauq ), work( itaup ), work( nwork ),
792 $ lwork - nwork + 1, ierr )
799 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
800 $ ldvt, dum, idum, work( nwork ), iwork,
808 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
809 $ work( itauq ), u, ldu, work( nwork ),
810 $ lwork - nwork + 1, ierr )
812 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
813 $ work( itaup ), vt, ldvt, work( nwork ),
814 $ lwork - nwork + 1, ierr )
820 CALL slacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
821 CALL sgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
822 $ ldwrkr, zero, u, ldu )
824 ELSE IF( wntqa )
THEN
842 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
843 $ lwork - nwork + 1, ierr )
844 CALL slacpy(
'L', m, n, a, lda, u, ldu )
849 CALL sorgqr( m, m, n, u, ldu, work( itau ),
850 $ work( nwork ), lwork - nwork + 1, ierr )
854 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
864 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
865 $ work( itaup ), work( nwork ), lwork-nwork+1,
873 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
874 $ vt, ldvt, dum, idum, work( nwork ), iwork,
882 CALL sormbr(
'Q',
'L',
'N', n, n, n, a, lda,
883 $ work( itauq ), work( iu ), ldwrku,
884 $ work( nwork ), lwork - nwork + 1, ierr )
885 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
886 $ work( itaup ), vt, ldvt, work( nwork ),
887 $ lwork - nwork + 1, ierr )
893 CALL sgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
894 $ ldwrku, zero, a, lda )
898 CALL slacpy(
'F', m, n, a, lda, u, ldu )
918 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
919 $ work( itaup ), work( nwork ), lwork-nwork+1,
927 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
928 $ dum, idum, work( nwork ), iwork, info )
929 ELSE IF( wntqo )
THEN
932 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
937 nwork = iu + ldwrku*n
938 CALL slaset(
'F', m, n, zero, zero, work( iu ),
947 nwork = iu + ldwrku*n
952 ldwrkr = ( lwork - n*n - 3*n ) / n
954 nwork = iu + ldwrku*n
961 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
962 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
969 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
970 $ work( itaup ), vt, ldvt, work( nwork ),
971 $ lwork - nwork + 1, ierr )
973 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
980 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
981 $ work( itauq ), work( iu ), ldwrku,
982 $ work( nwork ), lwork - nwork + 1, ierr )
986 CALL slacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
994 CALL sorgbr(
'Q', m, n, n, a, lda, work( itauq ),
995 $ work( nwork ), lwork - nwork + 1, ierr )
1003 DO 20 i = 1, m, ldwrkr
1004 chunk = min( m - i + 1, ldwrkr )
1005 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1006 $ lda, work( iu ), ldwrku, zero,
1007 $ work( ir ), ldwrkr )
1008 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
1013 ELSE IF( wntqs )
THEN
1021 CALL slaset(
'F', m, n, zero, zero, u, ldu )
1022 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1023 $ ldvt, dum, idum, work( nwork ), iwork,
1031 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1032 $ work( itauq ), u, ldu, work( nwork ),
1033 $ lwork - nwork + 1, ierr )
1034 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
1035 $ work( itaup ), vt, ldvt, work( nwork ),
1036 $ lwork - nwork + 1, ierr )
1037 ELSE IF( wntqa )
THEN
1045 CALL slaset(
'F', m, m, zero, zero, u, ldu )
1046 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1047 $ ldvt, dum, idum, work( nwork ), iwork,
1053 CALL slaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1062 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1063 $ work( itauq ), u, ldu, work( nwork ),
1064 $ lwork - nwork + 1, ierr )
1065 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1066 $ work( itaup ), vt, ldvt, work( nwork ),
1067 $ lwork - nwork + 1, ierr )
1078 IF( n.GE.mnthr )
THEN
1092 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1093 $ lwork - nwork + 1, ierr )
1097 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1107 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1108 $ work( itaup ), work( nwork ), lwork-nwork+1,
1115 CALL sbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1116 $ dum, idum, work( nwork ), iwork, info )
1118 ELSE IF( wntqo )
THEN
1130 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1135 chunk = ( lwork - m*m ) / m
1137 itau = il + ldwrkl*m
1144 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1145 $ lwork - nwork + 1, ierr )
1149 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1150 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1151 $ work( il + ldwrkl ), ldwrkl )
1157 CALL sorglq( m, n, m, a, lda, work( itau ),
1158 $ work( nwork ), lwork - nwork + 1, ierr )
1168 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1169 $ work( itauq ), work( itaup ), work( nwork ),
1170 $ lwork - nwork + 1, ierr )
1177 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1178 $ work( ivt ), m, dum, idum, work( nwork ),
1186 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1187 $ work( itauq ), u, ldu, work( nwork ),
1188 $ lwork - nwork + 1, ierr )
1189 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1190 $ work( itaup ), work( ivt ), m,
1191 $ work( nwork ), lwork - nwork + 1, ierr )
1199 DO 30 i = 1, n, chunk
1200 blk = min( n - i + 1, chunk )
1201 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1202 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1203 CALL slacpy(
'F', m, blk, work( il ), ldwrkl,
1207 ELSE IF( wntqs )
THEN
1218 itau = il + ldwrkl*m
1225 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1226 $ lwork - nwork + 1, ierr )
1230 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1231 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1232 $ work( il + ldwrkl ), ldwrkl )
1238 CALL sorglq( m, n, m, a, lda, work( itau ),
1239 $ work( nwork ), lwork - nwork + 1, ierr )
1249 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1250 $ work( itauq ), work( itaup ), work( nwork ),
1251 $ lwork - nwork + 1, ierr )
1258 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1259 $ ldvt, dum, idum, work( nwork ), iwork,
1267 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1268 $ work( itauq ), u, ldu, work( nwork ),
1269 $ lwork - nwork + 1, ierr )
1270 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1271 $ work( itaup ), vt, ldvt, work( nwork ),
1272 $ lwork - nwork + 1, ierr )
1278 CALL slacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1279 CALL sgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1280 $ a, lda, zero, vt, ldvt )
1282 ELSE IF( wntqa )
THEN
1293 itau = ivt + ldwkvt*m
1300 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1301 $ lwork - nwork + 1, ierr )
1302 CALL slacpy(
'U', m, n, a, lda, vt, ldvt )
1308 CALL sorglq( n, n, m, vt, ldvt, work( itau ),
1309 $ work( nwork ), lwork - nwork + 1, ierr )
1313 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1323 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1324 $ work( itaup ), work( nwork ), lwork-nwork+1,
1332 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1333 $ work( ivt ), ldwkvt, dum, idum,
1334 $ work( nwork ), iwork, info )
1341 CALL sormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1342 $ work( itauq ), u, ldu, work( nwork ),
1343 $ lwork - nwork + 1, ierr )
1344 CALL sormbr(
'P',
'R',
'T', m, m, m, a, lda,
1345 $ work( itaup ), work( ivt ), ldwkvt,
1346 $ work( nwork ), lwork - nwork + 1, ierr )
1352 CALL sgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1353 $ vt, ldvt, zero, a, lda )
1357 CALL slacpy(
'F', m, n, a, lda, vt, ldvt )
1377 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1378 $ work( itaup ), work( nwork ), lwork-nwork+1,
1386 CALL sbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1387 $ dum, idum, work( nwork ), iwork, info )
1388 ELSE IF( wntqo )
THEN
1392 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1396 CALL slaset(
'F', m, n, zero, zero, work( ivt ),
1398 nwork = ivt + ldwkvt*n
1405 nwork = ivt + ldwkvt*m
1410 chunk = ( lwork - m*m - 3*m ) / m
1418 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1419 $ work( ivt ), ldwkvt, dum, idum,
1420 $ work( nwork ), iwork, info )
1426 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1427 $ work( itauq ), u, ldu, work( nwork ),
1428 $ lwork - nwork + 1, ierr )
1430 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1437 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1438 $ work( itaup ), work( ivt ), ldwkvt,
1439 $ work( nwork ), lwork - nwork + 1, ierr )
1443 CALL slacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1451 CALL sorgbr(
'P', m, n, m, a, lda, work( itaup ),
1452 $ work( nwork ), lwork - nwork + 1, ierr )
1460 DO 40 i = 1, n, chunk
1461 blk = min( n - i + 1, chunk )
1462 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1463 $ ldwkvt, a( 1, i ), lda, zero,
1465 CALL slacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1469 ELSE IF( wntqs )
THEN
1477 CALL slaset(
'F', m, n, zero, zero, vt, ldvt )
1478 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1479 $ ldvt, dum, idum, work( nwork ), iwork,
1487 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1488 $ work( itauq ), u, ldu, work( nwork ),
1489 $ lwork - nwork + 1, ierr )
1490 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1491 $ work( itaup ), vt, ldvt, work( nwork ),
1492 $ lwork - nwork + 1, ierr )
1493 ELSE IF( wntqa )
THEN
1501 CALL slaset(
'F', n, n, zero, zero, vt, ldvt )
1502 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1503 $ ldvt, dum, idum, work( nwork ), iwork,
1509 CALL slaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1518 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1519 $ work( itauq ), u, ldu, work( nwork ),
1520 $ lwork - nwork + 1, ierr )
1521 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1522 $ work( itaup ), vt, ldvt, work( nwork ),
1523 $ lwork - nwork + 1, ierr )
1532 IF( iscl.EQ.1 )
THEN
1533 IF( anrm.GT.bignum )
1534 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1536 IF( anrm.LT.smlnum )
1537 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
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.
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine sbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
SBDSDC
subroutine sorgbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGBR
subroutine sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
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 sgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
SGESDD
subroutine sormbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMBR
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 sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM