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
269 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
270 EXTERNAL slamch, slange, lsame, sisnan,
274 INTRINSIC int, max, min, sqrt
282 wntqa = lsame( jobz,
'A' )
283 wntqs = lsame( jobz,
'S' )
284 wntqas = wntqa .OR. wntqs
285 wntqo = lsame( jobz,
'O' )
286 wntqn = lsame( jobz,
'N' )
287 lquery = ( lwork.EQ.-1 )
289 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
291 ELSE IF( m.LT.0 )
THEN
293 ELSE IF( n.LT.0 )
THEN
295 ELSE IF( lda.LT.max( 1, m ) )
THEN
297 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
298 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
300 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
301 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
302 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
317 mnthr = int( minmn*11.0e0 / 6.0e0 )
318 IF( m.GE.n .AND. minmn.GT.0 )
THEN
331 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
332 $ dum(1), dum(1), -1, ierr )
333 lwork_sgebrd_mn = int( dum(1) )
335 CALL sgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
336 $ dum(1), dum(1), -1, ierr )
337 lwork_sgebrd_nn = int( dum(1) )
339 CALL sgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
340 lwork_sgeqrf_mn = int( dum(1) )
342 CALL sorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
344 lwork_sorgbr_q_nn = int( dum(1) )
346 CALL sorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
347 lwork_sorgqr_mm = int( dum(1) )
349 CALL sorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
350 lwork_sorgqr_mn = int( dum(1) )
352 CALL sormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
353 $ dum(1), dum(1), n, dum(1), -1, ierr )
354 lwork_sormbr_prt_nn = int( dum(1) )
356 CALL sormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
357 $ dum(1), dum(1), n, dum(1), -1, ierr )
358 lwork_sormbr_qln_nn = int( dum(1) )
360 CALL sormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
361 $ dum(1), dum(1), m, dum(1), -1, ierr )
362 lwork_sormbr_qln_mn = int( dum(1) )
364 CALL sormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
365 $ dum(1), dum(1), m, dum(1), -1, ierr )
366 lwork_sormbr_qln_mm = int( dum(1) )
368 IF( m.GE.mnthr )
THEN
373 wrkbl = n + lwork_sgeqrf_mn
374 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
375 maxwrk = max( wrkbl, bdspac + n )
377 ELSE IF( wntqo )
THEN
381 wrkbl = n + lwork_sgeqrf_mn
382 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
383 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
384 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
385 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
386 wrkbl = max( wrkbl, 3*n + bdspac )
387 maxwrk = wrkbl + 2*n*n
388 minwrk = bdspac + 2*n*n + 3*n
389 ELSE IF( wntqs )
THEN
393 wrkbl = n + lwork_sgeqrf_mn
394 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
395 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
396 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
397 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
398 wrkbl = max( wrkbl, 3*n + bdspac )
400 minwrk = bdspac + n*n + 3*n
401 ELSE IF( wntqa )
THEN
405 wrkbl = n + lwork_sgeqrf_mn
406 wrkbl = max( wrkbl, n + lwork_sorgqr_mm )
407 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
408 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
409 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
410 wrkbl = max( wrkbl, 3*n + bdspac )
412 minwrk = n*n + max( 3*n + bdspac, n + m )
418 wrkbl = 3*n + lwork_sgebrd_mn
421 maxwrk = max( wrkbl, 3*n + bdspac )
422 minwrk = 3*n + max( m, bdspac )
423 ELSE IF( wntqo )
THEN
425 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
426 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
427 wrkbl = max( wrkbl, 3*n + bdspac )
429 minwrk = 3*n + max( m, n*n + bdspac )
430 ELSE IF( wntqs )
THEN
432 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
433 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
434 maxwrk = max( wrkbl, 3*n + bdspac )
435 minwrk = 3*n + max( m, bdspac )
436 ELSE IF( wntqa )
THEN
438 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mm )
439 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
440 maxwrk = max( wrkbl, 3*n + bdspac )
441 minwrk = 3*n + max( m, bdspac )
444 ELSE IF( minmn.GT.0 )
THEN
457 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
458 $ dum(1), dum(1), -1, ierr )
459 lwork_sgebrd_mn = int( dum(1) )
461 CALL sgebrd( m, m, a, m, s, dum(1), dum(1),
462 $ dum(1), dum(1), -1, ierr )
463 lwork_sgebrd_mm = int( dum(1) )
465 CALL sgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
466 lwork_sgelqf_mn = int( dum(1) )
468 CALL sorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
469 lwork_sorglq_nn = int( dum(1) )
471 CALL sorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
472 lwork_sorglq_mn = int( dum(1) )
474 CALL sorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
475 lwork_sorgbr_p_mm = int( dum(1) )
477 CALL sormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
478 $ dum(1), dum(1), m, dum(1), -1, ierr )
479 lwork_sormbr_prt_mm = int( dum(1) )
481 CALL sormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
482 $ dum(1), dum(1), m, dum(1), -1, ierr )
483 lwork_sormbr_prt_mn = int( dum(1) )
485 CALL sormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
486 $ dum(1), dum(1), n, dum(1), -1, ierr )
487 lwork_sormbr_prt_nn = int( dum(1) )
489 CALL sormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
490 $ dum(1), dum(1), m, dum(1), -1, ierr )
491 lwork_sormbr_qln_mm = int( dum(1) )
493 IF( n.GE.mnthr )
THEN
498 wrkbl = m + lwork_sgelqf_mn
499 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
500 maxwrk = max( wrkbl, bdspac + m )
502 ELSE IF( wntqo )
THEN
506 wrkbl = m + lwork_sgelqf_mn
507 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
508 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
509 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
510 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
511 wrkbl = max( wrkbl, 3*m + bdspac )
512 maxwrk = wrkbl + 2*m*m
513 minwrk = bdspac + 2*m*m + 3*m
514 ELSE IF( wntqs )
THEN
518 wrkbl = m + lwork_sgelqf_mn
519 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
520 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
521 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
522 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
523 wrkbl = max( wrkbl, 3*m + bdspac )
525 minwrk = bdspac + m*m + 3*m
526 ELSE IF( wntqa )
THEN
530 wrkbl = m + lwork_sgelqf_mn
531 wrkbl = max( wrkbl, m + lwork_sorglq_nn )
532 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
533 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
534 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
535 wrkbl = max( wrkbl, 3*m + bdspac )
537 minwrk = m*m + max( 3*m + bdspac, m + n )
543 wrkbl = 3*m + lwork_sgebrd_mn
546 maxwrk = max( wrkbl, 3*m + bdspac )
547 minwrk = 3*m + max( n, bdspac )
548 ELSE IF( wntqo )
THEN
550 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
551 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
552 wrkbl = max( wrkbl, 3*m + bdspac )
554 minwrk = 3*m + max( n, m*m + bdspac )
555 ELSE IF( wntqs )
THEN
557 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
558 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
559 maxwrk = max( wrkbl, 3*m + bdspac )
560 minwrk = 3*m + max( n, bdspac )
561 ELSE IF( wntqa )
THEN
563 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
564 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_nn )
565 maxwrk = max( wrkbl, 3*m + bdspac )
566 minwrk = 3*m + max( n, bdspac )
571 maxwrk = max( maxwrk, minwrk )
572 work( 1 ) = sroundup_lwork( maxwrk )
574 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
580 CALL xerbla(
'SGESDD', -info )
582 ELSE IF( lquery )
THEN
588 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
595 smlnum = sqrt( slamch(
'S' ) ) / eps
596 bignum = one / smlnum
600 anrm = slange(
'M', m, n, a, lda, dum )
601 IF( sisnan( anrm ) )
THEN
606 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
608 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
609 ELSE IF( anrm.GT.bignum )
THEN
611 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
620 IF( m.GE.mnthr )
THEN
634 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
635 $ lwork - nwork + 1, ierr )
639 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
649 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
650 $ work( itaup ), work( nwork ), lwork-nwork+1,
657 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
658 $ dum, idum, work( nwork ), iwork, info )
660 ELSE IF( wntqo )
THEN
670 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
673 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
682 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
683 $ lwork - nwork + 1, ierr )
687 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
688 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
695 CALL sorgqr( m, n, n, a, lda, work( itau ),
696 $ work( nwork ), lwork - nwork + 1, ierr )
706 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
707 $ work( itauq ), work( itaup ), work( nwork ),
708 $ lwork - nwork + 1, ierr )
720 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
721 $ vt, ldvt, dum, idum, work( nwork ), iwork,
729 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
730 $ work( itauq ), work( iu ), n, work( nwork ),
731 $ lwork - nwork + 1, ierr )
732 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
733 $ work( itaup ), vt, ldvt, work( nwork ),
734 $ lwork - nwork + 1, ierr )
741 DO 10 i = 1, m, ldwrkr
742 chunk = min( m - i + 1, ldwrkr )
743 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
744 $ lda, work( iu ), n, zero, work( ir ),
746 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
750 ELSE IF( wntqs )
THEN
768 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
769 $ lwork - nwork + 1, ierr )
773 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
774 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
781 CALL sorgqr( m, n, n, a, lda, work( itau ),
782 $ work( nwork ), lwork - nwork + 1, ierr )
792 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
793 $ work( itauq ), work( itaup ), work( nwork ),
794 $ lwork - nwork + 1, ierr )
801 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
802 $ ldvt, dum, idum, work( nwork ), iwork,
810 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
811 $ work( itauq ), u, ldu, work( nwork ),
812 $ lwork - nwork + 1, ierr )
814 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
815 $ work( itaup ), vt, ldvt, work( nwork ),
816 $ lwork - nwork + 1, ierr )
822 CALL slacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
823 CALL sgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
824 $ ldwrkr, zero, u, ldu )
826 ELSE IF( wntqa )
THEN
844 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
845 $ lwork - nwork + 1, ierr )
846 CALL slacpy(
'L', m, n, a, lda, u, ldu )
851 CALL sorgqr( m, m, n, u, ldu, work( itau ),
852 $ work( nwork ), lwork - nwork + 1, ierr )
856 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
866 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
867 $ work( itaup ), work( nwork ), lwork-nwork+1,
875 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
876 $ vt, ldvt, dum, idum, work( nwork ), iwork,
884 CALL sormbr(
'Q',
'L',
'N', n, n, n, a, lda,
885 $ work( itauq ), work( iu ), ldwrku,
886 $ work( nwork ), lwork - nwork + 1, ierr )
887 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
888 $ work( itaup ), vt, ldvt, work( nwork ),
889 $ lwork - nwork + 1, ierr )
895 CALL sgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
896 $ ldwrku, zero, a, lda )
900 CALL slacpy(
'F', m, n, a, lda, u, ldu )
920 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
921 $ work( itaup ), work( nwork ), lwork-nwork+1,
929 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
930 $ dum, idum, work( nwork ), iwork, info )
931 ELSE IF( wntqo )
THEN
934 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
939 nwork = iu + ldwrku*n
940 CALL slaset(
'F', m, n, zero, zero, work( iu ),
949 nwork = iu + ldwrku*n
954 ldwrkr = ( lwork - n*n - 3*n ) / n
956 nwork = iu + ldwrku*n
963 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
964 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
971 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
972 $ work( itaup ), vt, ldvt, work( nwork ),
973 $ lwork - nwork + 1, ierr )
975 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
982 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
983 $ work( itauq ), work( iu ), ldwrku,
984 $ work( nwork ), lwork - nwork + 1, ierr )
988 CALL slacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
996 CALL sorgbr(
'Q', m, n, n, a, lda, work( itauq ),
997 $ work( nwork ), lwork - nwork + 1, ierr )
1005 DO 20 i = 1, m, ldwrkr
1006 chunk = min( m - i + 1, ldwrkr )
1007 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1008 $ lda, work( iu ), ldwrku, zero,
1009 $ work( ir ), ldwrkr )
1010 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
1015 ELSE IF( wntqs )
THEN
1023 CALL slaset(
'F', m, n, zero, zero, u, ldu )
1024 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1025 $ ldvt, dum, idum, work( nwork ), iwork,
1033 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1034 $ work( itauq ), u, ldu, work( nwork ),
1035 $ lwork - nwork + 1, ierr )
1036 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
1037 $ work( itaup ), vt, ldvt, work( nwork ),
1038 $ lwork - nwork + 1, ierr )
1039 ELSE IF( wntqa )
THEN
1047 CALL slaset(
'F', m, m, zero, zero, u, ldu )
1048 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1049 $ ldvt, dum, idum, work( nwork ), iwork,
1055 CALL slaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1064 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1065 $ work( itauq ), u, ldu, work( nwork ),
1066 $ lwork - nwork + 1, ierr )
1067 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1068 $ work( itaup ), vt, ldvt, work( nwork ),
1069 $ lwork - nwork + 1, ierr )
1080 IF( n.GE.mnthr )
THEN
1094 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1095 $ lwork - nwork + 1, ierr )
1099 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1109 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1110 $ work( itaup ), work( nwork ), lwork-nwork+1,
1117 CALL sbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1118 $ dum, idum, work( nwork ), iwork, info )
1120 ELSE IF( wntqo )
THEN
1132 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1137 chunk = ( lwork - m*m ) / m
1139 itau = il + ldwrkl*m
1146 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1147 $ lwork - nwork + 1, ierr )
1151 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1152 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1153 $ work( il + ldwrkl ), ldwrkl )
1159 CALL sorglq( m, n, m, a, lda, work( itau ),
1160 $ work( nwork ), lwork - nwork + 1, ierr )
1170 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1171 $ work( itauq ), work( itaup ), work( nwork ),
1172 $ lwork - nwork + 1, ierr )
1179 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1180 $ work( ivt ), m, dum, idum, work( nwork ),
1188 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1189 $ work( itauq ), u, ldu, work( nwork ),
1190 $ lwork - nwork + 1, ierr )
1191 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1192 $ work( itaup ), work( ivt ), m,
1193 $ work( nwork ), lwork - nwork + 1, ierr )
1201 DO 30 i = 1, n, chunk
1202 blk = min( n - i + 1, chunk )
1203 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1204 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1205 CALL slacpy(
'F', m, blk, work( il ), ldwrkl,
1209 ELSE IF( wntqs )
THEN
1220 itau = il + ldwrkl*m
1227 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1228 $ lwork - nwork + 1, ierr )
1232 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1233 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1234 $ work( il + ldwrkl ), ldwrkl )
1240 CALL sorglq( m, n, m, a, lda, work( itau ),
1241 $ work( nwork ), lwork - nwork + 1, ierr )
1251 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1252 $ work( itauq ), work( itaup ), work( nwork ),
1253 $ lwork - nwork + 1, ierr )
1260 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1261 $ ldvt, dum, idum, work( nwork ), iwork,
1269 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1270 $ work( itauq ), u, ldu, work( nwork ),
1271 $ lwork - nwork + 1, ierr )
1272 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1273 $ work( itaup ), vt, ldvt, work( nwork ),
1274 $ lwork - nwork + 1, ierr )
1280 CALL slacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1281 CALL sgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1282 $ a, lda, zero, vt, ldvt )
1284 ELSE IF( wntqa )
THEN
1295 itau = ivt + ldwkvt*m
1302 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1303 $ lwork - nwork + 1, ierr )
1304 CALL slacpy(
'U', m, n, a, lda, vt, ldvt )
1310 CALL sorglq( n, n, m, vt, ldvt, work( itau ),
1311 $ work( nwork ), lwork - nwork + 1, ierr )
1315 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1325 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1326 $ work( itaup ), work( nwork ), lwork-nwork+1,
1334 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1335 $ work( ivt ), ldwkvt, dum, idum,
1336 $ work( nwork ), iwork, info )
1343 CALL sormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1344 $ work( itauq ), u, ldu, work( nwork ),
1345 $ lwork - nwork + 1, ierr )
1346 CALL sormbr(
'P',
'R',
'T', m, m, m, a, lda,
1347 $ work( itaup ), work( ivt ), ldwkvt,
1348 $ work( nwork ), lwork - nwork + 1, ierr )
1354 CALL sgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1355 $ vt, ldvt, zero, a, lda )
1359 CALL slacpy(
'F', m, n, a, lda, vt, ldvt )
1379 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1380 $ work( itaup ), work( nwork ), lwork-nwork+1,
1388 CALL sbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1389 $ dum, idum, work( nwork ), iwork, info )
1390 ELSE IF( wntqo )
THEN
1394 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1398 CALL slaset(
'F', m, n, zero, zero, work( ivt ),
1400 nwork = ivt + ldwkvt*n
1407 nwork = ivt + ldwkvt*m
1412 chunk = ( lwork - m*m - 3*m ) / m
1420 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1421 $ work( ivt ), ldwkvt, dum, idum,
1422 $ work( nwork ), iwork, info )
1428 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1429 $ work( itauq ), u, ldu, work( nwork ),
1430 $ lwork - nwork + 1, ierr )
1432 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1439 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1440 $ work( itaup ), work( ivt ), ldwkvt,
1441 $ work( nwork ), lwork - nwork + 1, ierr )
1445 CALL slacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1453 CALL sorgbr(
'P', m, n, m, a, lda, work( itaup ),
1454 $ work( nwork ), lwork - nwork + 1, ierr )
1462 DO 40 i = 1, n, chunk
1463 blk = min( n - i + 1, chunk )
1464 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1465 $ ldwkvt, a( 1, i ), lda, zero,
1467 CALL slacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1471 ELSE IF( wntqs )
THEN
1479 CALL slaset(
'F', m, n, zero, zero, vt, ldvt )
1480 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1481 $ ldvt, dum, idum, work( nwork ), iwork,
1489 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1490 $ work( itauq ), u, ldu, work( nwork ),
1491 $ lwork - nwork + 1, ierr )
1492 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1493 $ work( itaup ), vt, ldvt, work( nwork ),
1494 $ lwork - nwork + 1, ierr )
1495 ELSE IF( wntqa )
THEN
1503 CALL slaset(
'F', n, n, zero, zero, vt, ldvt )
1504 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1505 $ ldvt, dum, idum, work( nwork ), iwork,
1511 CALL slaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1520 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1521 $ work( itauq ), u, ldu, work( nwork ),
1522 $ lwork - nwork + 1, ierr )
1523 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1524 $ work( itaup ), vt, ldvt, work( nwork ),
1525 $ lwork - nwork + 1, ierr )
1534 IF( iscl.EQ.1 )
THEN
1535 IF( anrm.GT.bignum )
1536 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1538 IF( anrm.LT.smlnum )
1539 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
1545 work( 1 ) = sroundup_lwork( maxwrk )
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