571SUBROUTINE dgedmdq( 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 = real64
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. &
661 lsame(jobs,
'N')) )
THEN
663 ELSE IF ( .NOT. (wntvec .OR. wntvcf .OR. wntvcq &
664 .OR. lsame(jobz,
'N')) )
THEN
666 ELSE IF ( .NOT. (wntres .OR. lsame(jobr,
'N')) .OR. &
667 ( wntres .AND. lsame(jobz,
'N') ) )
THEN
669 ELSE IF ( .NOT. (wantq .OR. lsame(jobq,
'N')) )
THEN
671 ELSE IF ( .NOT. ( wnttrf .OR. lsame(jobt,
'N') ) )
THEN
673 ELSE IF ( .NOT. (wntref .OR. wntex .OR. &
674 lsame(jobf,
'N') ) )
THEN
676 ELSE IF ( .NOT. ((whtsvd == 1).OR.(whtsvd == 2).OR. &
677 (whtsvd == 3).OR.(whtsvd == 4)) )
THEN
679 ELSE IF ( m < 0 )
THEN
681 ELSE IF ( ( n < 0 ) .OR. ( n > m+1 ) )
THEN
683 ELSE IF ( ldf < m )
THEN
685 ELSE IF ( ldx < minmn )
THEN
687 ELSE IF ( ldy < minmn )
THEN
689 ELSE IF ( .NOT. (( nrnk == -2).OR.(nrnk == -1).OR. &
690 ((nrnk >= 1).AND.(nrnk <=n ))) )
THEN
692 ELSE IF ( ( tol < zero ) .OR. ( tol >= one ) )
THEN
694 ELSE IF ( ldz < m )
THEN
696 ELSE IF ( (wntref.OR.wntex ).AND.( ldb < minmn ) )
THEN
698 ELSE IF ( ldv < n-1 )
THEN
700 ELSE IF ( lds < n-1 )
THEN
704 IF ( wntvec .OR. wntvcf .OR. wntvcq )
THEN
709 IF ( info == 0 )
THEN
714 IF ( ( n == 0 ) .OR. ( n == 1 ) )
THEN
729 mlwork = minmn + mlwqr
731 CALL dgeqrf( m, n, f, ldf, work, rdummy, -1, &
733 olwqr = int(rdummy(1))
734 olwork = min(m,n) + olwqr
736 CALL dgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn,&
737 n-1, x, ldx, y, ldy, nrnk, tol, k, &
738 reig, imeig, z, ldz, res, b, ldb, &
739 v, ldv, s, lds, work, -1, iwork, &
741 mlwdmd = int(work(1))
742 mlwork = max(mlwork, minmn + mlwdmd)
745 olwdmd = int(work(2))
746 olwork = max(olwork, minmn+olwdmd)
748 IF ( wntvec .OR. wntvcf )
THEN
750 mlwork = max(mlwork,minmn+n-1+mlwmqr)
752 CALL dormqr(
'L',
'N', m, n, minmn, f, ldf, &
753 work, z, ldz, work, -1, info1 )
754 olwmqr = int(work(1))
755 olwork = max(olwork,minmn+n-1+olwmqr)
760 mlwork = max(mlwork,minmn+n-1+mlwgqr)
762 CALL dorgqr( m, minmn, minmn, f, ldf, work, &
764 olwgqr = int(work(1))
765 olwork = max(olwork,minmn+n-1+olwgqr)
768 iminwr = max( 1, iminwr )
769 mlwork = max( 2, mlwork )
770 IF ( lwork < mlwork .AND. (.NOT.lquery) ) info = -31
771 IF ( liwork < iminwr .AND. (.NOT.lquery) ) info = -33
774 CALL xerbla(
'DGEDMDQ', -info )
776 ELSE IF ( lquery )
THEN
789 CALL dgeqrf( m, n, f, ldf, work, &
790 work(minmn+1), lwork-minmn, info1 )
796 CALL dlaset(
'L', minmn, n-1, zero, zero, x, ldx )
797 CALL dlacpy(
'U', minmn, n-1, f, ldf, x, ldx )
798 CALL dlacpy(
'A', minmn, n-1, f(1,2), ldf, y, ldy )
800 CALL dlaset(
'L', minmn-2, n-2, zero, zero, &
805 CALL dgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn, &
806 n-1, x, ldx, y, ldy, nrnk, tol, k, &
807 reig, imeig, z, ldz, res, b, ldb, v, &
808 ldv, s, lds, work(minmn+1), lwork-minmn, &
809 iwork, liwork, info1 )
810 IF ( info1 == 2 .OR. info1 == 3 )
THEN
822 IF ( m > minmn )
CALL dlaset(
'A', m-minmn, k, zero, &
823 zero, z(minmn+1,1), ldz )
824 CALL dormqr(
'L',
'N', m, k, minmn, f, ldf, work, z, &
825 ldz, work(minmn+n), lwork-(minmn+n-1), info1 )
826 ELSE IF ( wntvcf )
THEN
833 CALL dlacpy(
'A', n, k, x, ldx, z, ldz )
834 IF ( m > n )
CALL dlaset(
'A', m-n, k, zero, zero, &
836 CALL dormqr(
'L',
'N', m, k, minmn, f, ldf, work, z, &
837 ldz, work(minmn+n), lwork-(minmn+n-1), info1 )
848 CALL dlaset(
'A', minmn, n, zero, zero, y, ldy )
849 CALL dlacpy(
'U', minmn, n, f, ldf, y, ldy )
857 CALL dorgqr( m, minmn, minmn, f, ldf, work, &
858 work(minmn+n), lwork-(minmn+n-1), info1 )
subroutine xerbla(srname, info)
subroutine dgedmdq(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)
DGEDMDQ computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine dgedmd(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)
DGEDMD computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR