217 SUBROUTINE sgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
218 $ WORK, LWORK, IWORK, INFO )
227 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
231 REAL A( LDA, * ), S( * ), U( LDU, * ),
232 $ vt( ldvt, * ), work( * )
239 parameter( zero = 0.0e0, one = 1.0e0 )
242 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
243 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
244 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
245 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
246 $ mnthr, nwork, wrkbl
247 INTEGER LWORK_SGEBRD_MN, LWORK_SGEBRD_MM,
248 $ lwork_sgebrd_nn, lwork_sgelqf_mn,
250 $ lwork_sorgbr_p_mm, lwork_sorgbr_q_nn,
251 $ lwork_sorglq_mn, lwork_sorglq_nn,
252 $ lwork_sorgqr_mm, lwork_sorgqr_mn,
253 $ lwork_sormbr_prt_mm, lwork_sormbr_qln_mm,
254 $ lwork_sormbr_prt_mn, lwork_sormbr_qln_mn,
255 $ lwork_sormbr_prt_nn, lwork_sormbr_qln_nn
256 REAL ANRM, BIGNUM, EPS, SMLNUM
268 LOGICAL LSAME, SISNAN
270 EXTERNAL slamch, slange, lsame, sisnan
273 INTRINSIC int, max, min, sqrt
281 wntqa = lsame( jobz,
'A' )
282 wntqs = lsame( jobz,
'S' )
283 wntqas = wntqa .OR. wntqs
284 wntqo = lsame( jobz,
'O' )
285 wntqn = lsame( jobz,
'N' )
286 lquery = ( lwork.EQ.-1 )
288 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
290 ELSE IF( m.LT.0 )
THEN
292 ELSE IF( n.LT.0 )
THEN
294 ELSE IF( lda.LT.max( 1, m ) )
THEN
296 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
297 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
299 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
300 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
301 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
316 mnthr = int( minmn*11.0e0 / 6.0e0 )
317 IF( m.GE.n .AND. minmn.GT.0 )
THEN
330 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
331 $ dum(1), dum(1), -1, ierr )
332 lwork_sgebrd_mn = int( dum(1) )
334 CALL sgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
335 $ dum(1), dum(1), -1, ierr )
336 lwork_sgebrd_nn = int( dum(1) )
338 CALL sgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
339 lwork_sgeqrf_mn = int( dum(1) )
341 CALL sorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
343 lwork_sorgbr_q_nn = int( dum(1) )
345 CALL sorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
346 lwork_sorgqr_mm = int( dum(1) )
348 CALL sorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
349 lwork_sorgqr_mn = int( dum(1) )
351 CALL sormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
352 $ dum(1), dum(1), n, dum(1), -1, ierr )
353 lwork_sormbr_prt_nn = int( dum(1) )
355 CALL sormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
356 $ dum(1), dum(1), n, dum(1), -1, ierr )
357 lwork_sormbr_qln_nn = int( dum(1) )
359 CALL sormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
360 $ dum(1), dum(1), m, dum(1), -1, ierr )
361 lwork_sormbr_qln_mn = int( dum(1) )
363 CALL sormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
364 $ dum(1), dum(1), m, dum(1), -1, ierr )
365 lwork_sormbr_qln_mm = int( dum(1) )
367 IF( m.GE.mnthr )
THEN
372 wrkbl = n + lwork_sgeqrf_mn
373 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
374 maxwrk = max( wrkbl, bdspac + n )
376 ELSE IF( wntqo )
THEN
380 wrkbl = n + lwork_sgeqrf_mn
381 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
382 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
383 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
384 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
385 wrkbl = max( wrkbl, 3*n + bdspac )
386 maxwrk = wrkbl + 2*n*n
387 minwrk = bdspac + 2*n*n + 3*n
388 ELSE IF( wntqs )
THEN
392 wrkbl = n + lwork_sgeqrf_mn
393 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
394 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
395 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
396 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
397 wrkbl = max( wrkbl, 3*n + bdspac )
399 minwrk = bdspac + n*n + 3*n
400 ELSE IF( wntqa )
THEN
404 wrkbl = n + lwork_sgeqrf_mn
405 wrkbl = max( wrkbl, n + lwork_sorgqr_mm )
406 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
407 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
408 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
409 wrkbl = max( wrkbl, 3*n + bdspac )
411 minwrk = n*n + max( 3*n + bdspac, n + m )
417 wrkbl = 3*n + lwork_sgebrd_mn
420 maxwrk = max( wrkbl, 3*n + bdspac )
421 minwrk = 3*n + max( m, bdspac )
422 ELSE IF( wntqo )
THEN
424 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
425 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
426 wrkbl = max( wrkbl, 3*n + bdspac )
428 minwrk = 3*n + max( m, n*n + bdspac )
429 ELSE IF( wntqs )
THEN
431 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
432 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
433 maxwrk = max( wrkbl, 3*n + bdspac )
434 minwrk = 3*n + max( m, bdspac )
435 ELSE IF( wntqa )
THEN
437 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mm )
438 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
439 maxwrk = max( wrkbl, 3*n + bdspac )
440 minwrk = 3*n + max( m, bdspac )
443 ELSE IF( minmn.GT.0 )
THEN
456 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
457 $ dum(1), dum(1), -1, ierr )
458 lwork_sgebrd_mn = int( dum(1) )
460 CALL sgebrd( m, m, a, m, s, dum(1), dum(1),
461 $ dum(1), dum(1), -1, ierr )
462 lwork_sgebrd_mm = int( dum(1) )
464 CALL sgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
465 lwork_sgelqf_mn = int( dum(1) )
467 CALL sorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
468 lwork_sorglq_nn = int( dum(1) )
470 CALL sorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
471 lwork_sorglq_mn = int( dum(1) )
473 CALL sorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
474 lwork_sorgbr_p_mm = int( dum(1) )
476 CALL sormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
477 $ dum(1), dum(1), m, dum(1), -1, ierr )
478 lwork_sormbr_prt_mm = int( dum(1) )
480 CALL sormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
481 $ dum(1), dum(1), m, dum(1), -1, ierr )
482 lwork_sormbr_prt_mn = int( dum(1) )
484 CALL sormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
485 $ dum(1), dum(1), n, dum(1), -1, ierr )
486 lwork_sormbr_prt_nn = int( dum(1) )
488 CALL sormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
489 $ dum(1), dum(1), m, dum(1), -1, ierr )
490 lwork_sormbr_qln_mm = int( dum(1) )
492 IF( n.GE.mnthr )
THEN
497 wrkbl = m + lwork_sgelqf_mn
498 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
499 maxwrk = max( wrkbl, bdspac + m )
501 ELSE IF( wntqo )
THEN
505 wrkbl = m + lwork_sgelqf_mn
506 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
507 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
508 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
509 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
510 wrkbl = max( wrkbl, 3*m + bdspac )
511 maxwrk = wrkbl + 2*m*m
512 minwrk = bdspac + 2*m*m + 3*m
513 ELSE IF( wntqs )
THEN
517 wrkbl = m + lwork_sgelqf_mn
518 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
519 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
520 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
521 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
522 wrkbl = max( wrkbl, 3*m + bdspac )
524 minwrk = bdspac + m*m + 3*m
525 ELSE IF( wntqa )
THEN
529 wrkbl = m + lwork_sgelqf_mn
530 wrkbl = max( wrkbl, m + lwork_sorglq_nn )
531 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
532 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
533 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
534 wrkbl = max( wrkbl, 3*m + bdspac )
536 minwrk = m*m + max( 3*m + bdspac, m + n )
542 wrkbl = 3*m + lwork_sgebrd_mn
545 maxwrk = max( wrkbl, 3*m + bdspac )
546 minwrk = 3*m + max( n, bdspac )
547 ELSE IF( wntqo )
THEN
549 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
550 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
551 wrkbl = max( wrkbl, 3*m + bdspac )
553 minwrk = 3*m + max( n, m*m + bdspac )
554 ELSE IF( wntqs )
THEN
556 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
557 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
558 maxwrk = max( wrkbl, 3*m + bdspac )
559 minwrk = 3*m + max( n, bdspac )
560 ELSE IF( wntqa )
THEN
562 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
563 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_nn )
564 maxwrk = max( wrkbl, 3*m + bdspac )
565 minwrk = 3*m + max( n, bdspac )
570 maxwrk = max( maxwrk, minwrk )
573 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
579 CALL xerbla(
'SGESDD', -info )
581 ELSE IF( lquery )
THEN
587 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
594 smlnum = sqrt( slamch(
'S' ) ) / eps
595 bignum = one / smlnum
599 anrm = slange(
'M', m, n, a, lda, dum )
600 IF( sisnan( anrm ) )
THEN
605 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
607 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
608 ELSE IF( anrm.GT.bignum )
THEN
610 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
619 IF( m.GE.mnthr )
THEN
633 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
634 $ lwork - nwork + 1, ierr )
638 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
648 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
649 $ work( itaup ), work( nwork ), lwork-nwork+1,
656 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
657 $ dum, idum, work( nwork ), iwork, info )
659 ELSE IF( wntqo )
THEN
669 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
672 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
681 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
682 $ lwork - nwork + 1, ierr )
686 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
687 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
694 CALL sorgqr( m, n, n, a, lda, work( itau ),
695 $ work( nwork ), lwork - nwork + 1, ierr )
705 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
706 $ work( itauq ), work( itaup ), work( nwork ),
707 $ lwork - nwork + 1, ierr )
719 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
720 $ vt, ldvt, dum, idum, work( nwork ), iwork,
728 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
729 $ work( itauq ), work( iu ), n, work( nwork ),
730 $ lwork - nwork + 1, ierr )
731 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
732 $ work( itaup ), vt, ldvt, work( nwork ),
733 $ lwork - nwork + 1, ierr )
740 DO 10 i = 1, m, ldwrkr
741 chunk = min( m - i + 1, ldwrkr )
742 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
743 $ lda, work( iu ), n, zero, work( ir ),
745 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
749 ELSE IF( wntqs )
THEN
767 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
768 $ lwork - nwork + 1, ierr )
772 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
773 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
780 CALL sorgqr( m, n, n, a, lda, work( itau ),
781 $ work( nwork ), lwork - nwork + 1, ierr )
791 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
792 $ work( itauq ), work( itaup ), work( nwork ),
793 $ lwork - nwork + 1, ierr )
800 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
801 $ ldvt, dum, idum, work( nwork ), iwork,
809 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
810 $ work( itauq ), u, ldu, work( nwork ),
811 $ lwork - nwork + 1, ierr )
813 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
814 $ work( itaup ), vt, ldvt, work( nwork ),
815 $ lwork - nwork + 1, ierr )
821 CALL slacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
822 CALL sgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
823 $ ldwrkr, zero, u, ldu )
825 ELSE IF( wntqa )
THEN
843 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
844 $ lwork - nwork + 1, ierr )
845 CALL slacpy(
'L', m, n, a, lda, u, ldu )
850 CALL sorgqr( m, m, n, u, ldu, work( itau ),
851 $ work( nwork ), lwork - nwork + 1, ierr )
855 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
865 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
866 $ work( itaup ), work( nwork ), lwork-nwork+1,
874 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
875 $ vt, ldvt, dum, idum, work( nwork ), iwork,
883 CALL sormbr(
'Q',
'L',
'N', n, n, n, a, lda,
884 $ work( itauq ), work( iu ), ldwrku,
885 $ work( nwork ), lwork - nwork + 1, ierr )
886 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
887 $ work( itaup ), vt, ldvt, work( nwork ),
888 $ lwork - nwork + 1, ierr )
894 CALL sgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
895 $ ldwrku, zero, a, lda )
899 CALL slacpy(
'F', m, n, a, lda, u, ldu )
919 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
920 $ work( itaup ), work( nwork ), lwork-nwork+1,
928 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
929 $ dum, idum, work( nwork ), iwork, info )
930 ELSE IF( wntqo )
THEN
933 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
938 nwork = iu + ldwrku*n
939 CALL slaset(
'F', m, n, zero, zero, work( iu ),
948 nwork = iu + ldwrku*n
953 ldwrkr = ( lwork - n*n - 3*n ) / n
955 nwork = iu + ldwrku*n
962 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
963 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
970 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
971 $ work( itaup ), vt, ldvt, work( nwork ),
972 $ lwork - nwork + 1, ierr )
974 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
981 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
982 $ work( itauq ), work( iu ), ldwrku,
983 $ work( nwork ), lwork - nwork + 1, ierr )
987 CALL slacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
995 CALL sorgbr(
'Q', m, n, n, a, lda, work( itauq ),
996 $ work( nwork ), lwork - nwork + 1, ierr )
1004 DO 20 i = 1, m, ldwrkr
1005 chunk = min( m - i + 1, ldwrkr )
1006 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1007 $ lda, work( iu ), ldwrku, zero,
1008 $ work( ir ), ldwrkr )
1009 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
1014 ELSE IF( wntqs )
THEN
1022 CALL slaset(
'F', m, n, zero, zero, u, ldu )
1023 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1024 $ ldvt, dum, idum, work( nwork ), iwork,
1032 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1033 $ work( itauq ), u, ldu, work( nwork ),
1034 $ lwork - nwork + 1, ierr )
1035 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
1036 $ work( itaup ), vt, ldvt, work( nwork ),
1037 $ lwork - nwork + 1, ierr )
1038 ELSE IF( wntqa )
THEN
1046 CALL slaset(
'F', m, m, zero, zero, u, ldu )
1047 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1048 $ ldvt, dum, idum, work( nwork ), iwork,
1054 CALL slaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1063 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1064 $ work( itauq ), u, ldu, work( nwork ),
1065 $ lwork - nwork + 1, ierr )
1066 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1067 $ work( itaup ), vt, ldvt, work( nwork ),
1068 $ lwork - nwork + 1, ierr )
1079 IF( n.GE.mnthr )
THEN
1093 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1094 $ lwork - nwork + 1, ierr )
1098 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1108 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1109 $ work( itaup ), work( nwork ), lwork-nwork+1,
1116 CALL sbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1117 $ dum, idum, work( nwork ), iwork, info )
1119 ELSE IF( wntqo )
THEN
1131 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1136 chunk = ( lwork - m*m ) / m
1138 itau = il + ldwrkl*m
1145 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1146 $ lwork - nwork + 1, ierr )
1150 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1151 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1152 $ work( il + ldwrkl ), ldwrkl )
1158 CALL sorglq( m, n, m, a, lda, work( itau ),
1159 $ work( nwork ), lwork - nwork + 1, ierr )
1169 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1170 $ work( itauq ), work( itaup ), work( nwork ),
1171 $ lwork - nwork + 1, ierr )
1178 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1179 $ work( ivt ), m, dum, idum, work( nwork ),
1187 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1188 $ work( itauq ), u, ldu, work( nwork ),
1189 $ lwork - nwork + 1, ierr )
1190 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1191 $ work( itaup ), work( ivt ), m,
1192 $ work( nwork ), lwork - nwork + 1, ierr )
1200 DO 30 i = 1, n, chunk
1201 blk = min( n - i + 1, chunk )
1202 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1203 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1204 CALL slacpy(
'F', m, blk, work( il ), ldwrkl,
1208 ELSE IF( wntqs )
THEN
1219 itau = il + ldwrkl*m
1226 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1227 $ lwork - nwork + 1, ierr )
1231 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1232 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1233 $ work( il + ldwrkl ), ldwrkl )
1239 CALL sorglq( m, n, m, a, lda, work( itau ),
1240 $ work( nwork ), lwork - nwork + 1, ierr )
1250 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1251 $ work( itauq ), work( itaup ), work( nwork ),
1252 $ lwork - nwork + 1, ierr )
1259 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1260 $ ldvt, dum, idum, work( nwork ), iwork,
1268 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1269 $ work( itauq ), u, ldu, work( nwork ),
1270 $ lwork - nwork + 1, ierr )
1271 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1272 $ work( itaup ), vt, ldvt, work( nwork ),
1273 $ lwork - nwork + 1, ierr )
1279 CALL slacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1280 CALL sgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1281 $ a, lda, zero, vt, ldvt )
1283 ELSE IF( wntqa )
THEN
1294 itau = ivt + ldwkvt*m
1301 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1302 $ lwork - nwork + 1, ierr )
1303 CALL slacpy(
'U', m, n, a, lda, vt, ldvt )
1309 CALL sorglq( n, n, m, vt, ldvt, work( itau ),
1310 $ work( nwork ), lwork - nwork + 1, ierr )
1314 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1324 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1325 $ work( itaup ), work( nwork ), lwork-nwork+1,
1333 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1334 $ work( ivt ), ldwkvt, dum, idum,
1335 $ work( nwork ), iwork, info )
1342 CALL sormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1343 $ work( itauq ), u, ldu, work( nwork ),
1344 $ lwork - nwork + 1, ierr )
1345 CALL sormbr(
'P',
'R',
'T', m, m, m, a, lda,
1346 $ work( itaup ), work( ivt ), ldwkvt,
1347 $ work( nwork ), lwork - nwork + 1, ierr )
1353 CALL sgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1354 $ vt, ldvt, zero, a, lda )
1358 CALL slacpy(
'F', m, n, a, lda, vt, ldvt )
1378 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1379 $ work( itaup ), work( nwork ), lwork-nwork+1,
1387 CALL sbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1388 $ dum, idum, work( nwork ), iwork, info )
1389 ELSE IF( wntqo )
THEN
1393 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1397 CALL slaset(
'F', m, n, zero, zero, work( ivt ),
1399 nwork = ivt + ldwkvt*n
1406 nwork = ivt + ldwkvt*m
1411 chunk = ( lwork - m*m - 3*m ) / m
1419 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1420 $ work( ivt ), ldwkvt, dum, idum,
1421 $ work( nwork ), iwork, info )
1427 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1428 $ work( itauq ), u, ldu, work( nwork ),
1429 $ lwork - nwork + 1, ierr )
1431 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1438 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1439 $ work( itaup ), work( ivt ), ldwkvt,
1440 $ work( nwork ), lwork - nwork + 1, ierr )
1444 CALL slacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1452 CALL sorgbr(
'P', m, n, m, a, lda, work( itaup ),
1453 $ work( nwork ), lwork - nwork + 1, ierr )
1461 DO 40 i = 1, n, chunk
1462 blk = min( n - i + 1, chunk )
1463 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1464 $ ldwkvt, a( 1, i ), lda, zero,
1466 CALL slacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1470 ELSE IF( wntqs )
THEN
1478 CALL slaset(
'F', m, n, zero, zero, vt, ldvt )
1479 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1480 $ ldvt, dum, idum, work( nwork ), iwork,
1488 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1489 $ work( itauq ), u, ldu, work( nwork ),
1490 $ lwork - nwork + 1, ierr )
1491 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1492 $ work( itaup ), vt, ldvt, work( nwork ),
1493 $ lwork - nwork + 1, ierr )
1494 ELSE IF( wntqa )
THEN
1502 CALL slaset(
'F', n, n, zero, zero, vt, ldvt )
1503 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1504 $ ldvt, dum, idum, work( nwork ), iwork,
1510 CALL slaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1519 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1520 $ work( itauq ), u, ldu, work( nwork ),
1521 $ lwork - nwork + 1, ierr )
1522 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1523 $ work( itaup ), vt, ldvt, work( nwork ),
1524 $ lwork - nwork + 1, ierr )
1533 IF( iscl.EQ.1 )
THEN
1534 IF( anrm.GT.bignum )
1535 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1537 IF( anrm.LT.smlnum )
1538 $
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