571SUBROUTINE sgedmdq( JOBS, JOBZ, JOBR, JOBQ, JOBT, JOBF, &
572 WHTSVD, M, N, F, LDF, X, LDX, Y, &
573 LDY, NRNK, TOL, K, REIG, IMEIG, &
574 Z, LDZ, RES, B, LDB, V, LDV, &
575 S, LDS, WORK, LWORK, IWORK, LIWORK, INFO )
586 INTEGER,
PARAMETER :: WP = real32
590 CHARACTER,
INTENT(IN) :: JOBS, JOBZ, JOBR, JOBQ, &
592 INTEGER,
INTENT(IN) :: WHTSVD, M, N, LDF, LDX, &
593 LDY, NRNK, LDZ, LDB, LDV, &
595 INTEGER,
INTENT(OUT) :: INFO, K
596 REAL(KIND=wp),
INTENT(IN) :: tol
600 REAL(KIND=wp),
INTENT(INOUT) :: f(ldf,*)
601 REAL(KIND=wp),
INTENT(OUT) :: x(ldx,*), y(ldy,*), &
602 z(ldz,*), b(ldb,*), &
604 REAL(KIND=wp),
INTENT(OUT) :: reig(*), imeig(*), &
606 REAL(KIND=wp),
INTENT(OUT) :: work(*)
607 INTEGER,
INTENT(OUT) :: IWORK(*)
611 REAL(KIND=wp),
PARAMETER :: one = 1.0_wp
612 REAL(KIND=wp),
PARAMETER :: zero = 0.0_wp
616 INTEGER :: IMINWR, INFO1, MLWDMD, MLWGQR, &
617 MLWMQR, MLWORK, MLWQR, MINMN, &
618 OLWDMD, OLWGQR, OLWMQR, OLWORK, &
620 LOGICAL :: LQUERY, SCCOLX, SCCOLY, WANTQ, &
621 WNTTRF, WNTRES, WNTVEC, WNTVCF, &
622 WNTVCQ, WNTREF, WNTEX
623 CHARACTER(LEN=1) :: JOBVL
627 REAL(KIND=wp) :: rdummy(2)
642 INTRINSIC max, min, int
646 wntres = lsame(jobr,
'R')
647 sccolx = lsame(jobs,
'S') .OR. lsame( jobs,
'C' )
648 sccoly = lsame(jobs,
'Y')
649 wntvec = lsame(jobz,
'V')
650 wntvcf = lsame(jobz,
'F')
651 wntvcq = lsame(jobz,
'Q')
652 wntref = lsame(jobf,
'R')
653 wntex = lsame(jobf,
'E')
654 wantq = lsame(jobq,
'Q')
655 wnttrf = lsame(jobt,
'R')
658 lquery = ( ( lwork == -1 ) .OR. ( liwork == -1 ) )
660 IF ( .NOT. (sccolx .OR. sccoly .OR. lsame(jobs,
'N')) )
THEN
662 ELSE IF ( .NOT. (wntvec .OR. wntvcf .OR. wntvcq &
663 .OR. lsame(jobz,
'N')) )
THEN
665 ELSE IF ( .NOT. (wntres .OR. lsame(jobr,
'N')) .OR. &
666 ( wntres .AND. lsame(jobz,
'N') ) )
THEN
668 ELSE IF ( .NOT. (wantq .OR. lsame(jobq,
'N')) )
THEN
670 ELSE IF ( .NOT. ( wnttrf .OR. lsame(jobt,
'N') ) )
THEN
672 ELSE IF ( .NOT. (wntref .OR. wntex .OR. &
673 lsame(jobf,
'N') ) )
THEN
675 ELSE IF ( .NOT. ((whtsvd == 1).OR.(whtsvd == 2).OR. &
676 (whtsvd == 3).OR.(whtsvd == 4)) )
THEN
678 ELSE IF ( m < 0 )
THEN
680 ELSE IF ( ( n < 0 ) .OR. ( n > m+1 ) )
THEN
682 ELSE IF ( ldf < m )
THEN
684 ELSE IF ( ldx < minmn )
THEN
686 ELSE IF ( ldy < minmn )
THEN
688 ELSE IF ( .NOT. (( nrnk == -2).OR.(nrnk == -1).OR. &
689 ((nrnk >= 1).AND.(nrnk <=n ))) )
THEN
691 ELSE IF ( ( tol < zero ) .OR. ( tol >= one ) )
THEN
693 ELSE IF ( ldz < m )
THEN
695 ELSE IF ( (wntref.OR.wntex ).AND.( ldb < minmn ) )
THEN
697 ELSE IF ( ldv < n-1 )
THEN
699 ELSE IF ( lds < n-1 )
THEN
703 IF ( wntvec .OR. wntvcf )
THEN
708 IF ( info == 0 )
THEN
713 IF ( ( n == 0 ) .OR. ( n == 1 ) )
THEN
728 mlwork = min(m,n) + mlwqr
730 CALL sgeqrf( m, n, f, ldf, work, rdummy, -1, &
732 olwqr = int(rdummy(1))
733 olwork = min(m,n) + olwqr
735 CALL sgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn,&
736 n-1, x, ldx, y, ldy, nrnk, tol, k, &
737 reig, imeig, z, ldz, res, b, ldb, &
738 v, ldv, s, lds, work, -1, iwork, &
740 mlwdmd = int(work(1))
741 mlwork = max(mlwork, minmn + mlwdmd)
744 olwdmd = int(work(2))
745 olwork = max(olwork, minmn+olwdmd)
747 IF ( wntvec .OR. wntvcf )
THEN
749 mlwork = max(mlwork,minmn+n-1+mlwmqr)
751 CALL sormqr(
'L',
'N', m, n, minmn, f, ldf, &
752 work, z, ldz, work, -1, info1 )
753 olwmqr = int(work(1))
754 olwork = max(olwork,minmn+n-1+olwmqr)
759 mlwork = max(mlwork,minmn+n-1+mlwgqr)
761 CALL sorgqr( m, minmn, minmn, f, ldf, work, &
763 olwgqr = int(work(1))
764 olwork = max(olwork,minmn+n-1+olwgqr)
767 iminwr = max( 1, iminwr )
768 mlwork = max( 2, mlwork )
769 IF ( lwork < mlwork .AND. (.NOT.lquery) ) info = -31
770 IF ( liwork < iminwr .AND. (.NOT.lquery) ) info = -33
773 CALL xerbla(
'SGEDMDQ', -info )
775 ELSE IF ( lquery )
THEN
788 CALL sgeqrf( m, n, f, ldf, work, &
789 work(minmn+1), lwork-minmn, info1 )
795 CALL slaset(
'L', minmn, n-1, zero, zero, x, ldx )
796 CALL slacpy(
'U', minmn, n-1, f, ldf, x, ldx )
797 CALL slacpy(
'A', minmn, n-1, f(1,2), ldf, y, ldy )
799 CALL slaset(
'L', minmn-2, n-2, zero, zero, &
804 CALL sgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn, &
805 n-1, x, ldx, y, ldy, nrnk, tol, k, &
806 reig, imeig, z, ldz, res, b, ldb, v, &
807 ldv, s, lds, work(minmn+1), lwork-minmn, iwork, &
809 IF ( info1 == 2 .OR. info1 == 3 )
THEN
821 IF ( m > minmn )
CALL slaset(
'A', m-minmn, k, zero, &
822 zero, z(minmn+1,1), ldz )
823 CALL sormqr(
'L',
'N', m, k, minmn, f, ldf, work, z, &
824 ldz, work(minmn+n), lwork-(minmn+n-1), info1 )
825 ELSE IF ( wntvcf )
THEN
832 CALL slacpy(
'A', n, k, x, ldx, z, ldz )
833 IF ( m > n )
CALL slaset(
'A', m-n, k, zero, zero, &
835 CALL sormqr(
'L',
'N', m, k, minmn, f, ldf, work, z, &
836 ldz, work(minmn+n), lwork-(minmn+n-1), info1 )
847 CALL slaset(
'A', minmn, n, zero, zero, y, ldy )
848 CALL slacpy(
'U', minmn, n, f, ldf, y, ldy )
856 CALL sorgqr( m, minmn, minmn, f, ldf, work, &
857 work(minmn+n), lwork-(minmn+n-1), info1 )
subroutine xerbla(srname, info)
subroutine sgedmd(jobs, jobz, jobr, jobf, whtsvd, m, n, x, ldx, y, ldy, nrnk, tol, k, reig, imeig, z, ldz, res, b, ldb, w, ldw, s, lds, work, lwork, iwork, liwork, info)
SGEDMD computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine sgedmdq(jobs, jobz, jobr, jobq, jobt, jobf, whtsvd, m, n, f, ldf, x, ldx, y, ldy, nrnk, tol, k, reig, imeig, z, ldz, res, b, ldb, v, ldv, s, lds, work, lwork, iwork, liwork, info)
SGEDMDQ computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
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
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
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 sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR