550SUBROUTINE zgedmdq( JOBS, JOBZ, JOBR, JOBQ, JOBT, JOBF, &
551 WHTSVD, M, N, F, LDF, X, LDX, Y, &
552 LDY, NRNK, TOL, K, EIGS, &
553 Z, LDZ, RES, B, LDB, V, LDV, &
554 S, LDS, ZWORK, LZWORK, WORK, LWORK, &
555 IWORK, LIWORK, INFO )
566 INTEGER,
PARAMETER :: WP = real64
570 CHARACTER,
INTENT(IN) :: JOBS, JOBZ, JOBR, JOBQ, &
572 INTEGER,
INTENT(IN) :: WHTSVD, M, N, LDF, LDX, &
573 LDY, NRNK, LDZ, LDB, LDV, &
574 LDS, LZWORK, LWORK, LIWORK
575 INTEGER,
INTENT(OUT) :: INFO, K
576 REAL(KIND=wp),
INTENT(IN) :: tol
580 COMPLEX(KIND=WP),
INTENT(INOUT) :: F(LDF,*)
581 COMPLEX(KIND=WP),
INTENT(OUT) :: X(LDX,*), Y(LDY,*), &
582 Z(LDZ,*), B(LDB,*), &
584 COMPLEX(KIND=WP),
INTENT(OUT) :: EIGS(*)
585 COMPLEX(KIND=WP),
INTENT(OUT) :: ZWORK(*)
586 REAL(KIND=wp),
INTENT(OUT) :: res(*)
587 REAL(KIND=wp),
INTENT(OUT) :: work(*)
588 INTEGER,
INTENT(OUT) :: IWORK(*)
592 REAL(KIND=wp),
PARAMETER :: one = 1.0_wp
593 REAL(KIND=wp),
PARAMETER :: zero = 0.0_wp
595 COMPLEX(KIND=WP),
PARAMETER :: ZZERO = ( 0.0_wp, 0.0_wp )
599 INTEGER :: IMINWR, INFO1, MINMN, MLRWRK, &
600 MLWDMD, MLWGQR, MLWMQR, MLWORK, &
601 MLWQR, OLWDMD, OLWGQR, OLWMQR, &
603 LOGICAL :: LQUERY, SCCOLX, SCCOLY, WANTQ, &
604 WNTTRF, WNTRES, WNTVEC, WNTVCF, &
605 WNTVCQ, WNTREF, WNTEX
606 CHARACTER(LEN=1) :: JOBVL
620 INTRINSIC max, min, int
624 wntres = lsame(jobr,
'R')
625 sccolx = lsame(jobs,
'S') .OR. lsame( jobs,
'C' )
626 sccoly = lsame(jobs,
'Y')
627 wntvec = lsame(jobz,
'V')
628 wntvcf = lsame(jobz,
'F')
629 wntvcq = lsame(jobz,
'Q')
630 wntref = lsame(jobf,
'R')
631 wntex = lsame(jobf,
'E')
632 wantq = lsame(jobq,
'Q')
633 wnttrf = lsame(jobt,
'R')
636 lquery = ( (lzwork == -1) .OR. (lwork == -1) .OR. (liwork == -1) )
638 IF ( .NOT. (sccolx .OR. sccoly .OR. &
639 lsame(jobs,
'N')) )
THEN
641 ELSE IF ( .NOT. (wntvec .OR. wntvcf .OR. wntvcq &
642 .OR. lsame(jobz,
'N')) )
THEN
644 ELSE IF ( .NOT. (wntres .OR. lsame(jobr,
'N')) .OR. &
645 ( wntres .AND. lsame(jobz,
'N') ) )
THEN
647 ELSE IF ( .NOT. (wantq .OR. lsame(jobq,
'N')) )
THEN
649 ELSE IF ( .NOT. ( wnttrf .OR. lsame(jobt,
'N') ) )
THEN
651 ELSE IF ( .NOT. (wntref .OR. wntex .OR. &
652 lsame(jobf,
'N') ) )
THEN
654 ELSE IF ( .NOT. ((whtsvd == 1).OR.(whtsvd == 2).OR. &
655 (whtsvd == 3).OR.(whtsvd == 4)) )
THEN
657 ELSE IF ( m < 0 )
THEN
659 ELSE IF ( ( n < 0 ) .OR. ( n > m+1 ) )
THEN
661 ELSE IF ( ldf < m )
THEN
663 ELSE IF ( ldx < minmn )
THEN
665 ELSE IF ( ldy < minmn )
THEN
667 ELSE IF ( .NOT. (( nrnk == -2).OR.(nrnk == -1).OR. &
668 ((nrnk >= 1).AND.(nrnk <=n ))) )
THEN
670 ELSE IF ( ( tol < zero ) .OR. ( tol >= one ) )
THEN
672 ELSE IF ( ldz < m )
THEN
674 ELSE IF ( (wntref.OR.wntex ).AND.( ldb < minmn ) )
THEN
676 ELSE IF ( ldv < n-1 )
THEN
678 ELSE IF ( lds < n-1 )
THEN
682 IF ( wntvec .OR. wntvcf .OR. wntvcq )
THEN
687 IF ( info == 0 )
THEN
692 IF ( ( n == 0 ) .OR. ( n == 1 ) )
THEN
714 mlwork = max(mlwork,minmn + mlwqr)
717 CALL zgeqrf( m, n, f, ldf, zwork, zwork, -1, &
719 olwqr = int(zwork(1))
720 olwork = max(olwork,minmn + olwqr)
722 CALL zgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn,&
723 n-1, x, ldx, y, ldy, nrnk, tol, k, &
724 eigs, z, ldz, res, b, ldb, v, ldv, &
725 s, lds, zwork, -1, work, -1, iwork,&
727 mlwdmd = int(zwork(1))
728 mlwork = max(mlwork, minmn + mlwdmd)
729 mlrwrk = max(mlrwrk, int(work(1)))
730 iminwr = max(iminwr, iwork(1))
732 olwdmd = int(zwork(2))
733 olwork = max(olwork, minmn+olwdmd)
735 IF ( wntvec .OR. wntvcf )
THEN
737 mlwork = max(mlwork,minmn+mlwmqr)
739 CALL zunmqr(
'L',
'N', m, n, minmn, f, ldf, &
740 zwork, z, ldz, zwork, -1, info1 )
741 olwmqr = int(zwork(1))
742 olwork = max(olwork,minmn+olwmqr)
747 mlwork = max(mlwork,minmn+mlwgqr)
749 CALL zungqr( m, minmn, minmn, f, ldf, zwork, &
751 olwgqr = int(zwork(1))
752 olwork = max(olwork,minmn+olwgqr)
755 IF ( liwork < iminwr .AND. (.NOT.lquery) ) info = -34
756 IF ( lwork < mlrwrk .AND. (.NOT.lquery) ) info = -32
757 IF ( lzwork < mlwork .AND. (.NOT.lquery) ) info = -30
760 CALL xerbla(
'ZGEDMDQ', -info )
762 ELSE IF ( lquery )
THEN
777 CALL zgeqrf( m, n, f, ldf, zwork, &
778 zwork(minmn+1), lzwork-minmn, info1 )
784 CALL zlaset(
'L', minmn, n-1, zzero, zzero, x, ldx )
785 CALL zlacpy(
'U', minmn, n-1, f, ldf, x, ldx )
786 CALL zlacpy(
'A', minmn, n-1, f(1,2), ldf, y, ldy )
788 CALL zlaset(
'L', minmn-2, n-2, zzero, zzero, &
793 CALL zgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn, &
794 n-1, x, ldx, y, ldy, nrnk, tol, k, &
795 eigs, z, ldz, res, b, ldb, v, ldv, &
796 s, lds, zwork(minmn+1), lzwork-minmn, &
797 work, lwork, iwork, liwork, info1 )
798 IF ( info1 == 2 .OR. info1 == 3 )
THEN
810 IF ( m > minmn )
CALL zlaset(
'A', m-minmn, k, zzero, &
811 zzero, z(minmn+1,1), ldz )
812 CALL zunmqr(
'L',
'N', m, k, minmn, f, ldf, zwork, z, &
813 ldz, zwork(minmn+1), lzwork-minmn, info1 )
814 ELSE IF ( wntvcf )
THEN
821 CALL zlacpy(
'A', n, k, x, ldx, z, ldz )
822 IF ( m > n )
CALL zlaset(
'A', m-n, k, zzero, zzero, &
824 CALL zunmqr(
'L',
'N', m, k, minmn, f, ldf, zwork, z, &
825 ldz, zwork(minmn+1), lzwork-minmn, info1 )
836 CALL zlaset(
'A', minmn, n, zzero, zzero, y, ldy )
837 CALL zlacpy(
'U', minmn, n, f, ldf, y, ldy )
845 CALL zungqr( m, minmn, minmn, f, ldf, zwork, &
846 zwork(minmn+1), lzwork-minmn, info1 )
subroutine xerbla(srname, info)
subroutine zgedmdq(jobs, jobz, jobr, jobq, jobt, jobf, whtsvd, m, n, f, ldf, x, ldx, y, ldy, nrnk, tol, k, eigs, z, ldz, res, b, ldb, v, ldv, s, lds, zwork, lzwork, work, lwork, iwork, liwork, info)
ZGEDMDQ computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine zgedmd(jobs, jobz, jobr, jobf, whtsvd, m, n, x, ldx, y, ldy, nrnk, tol, k, eigs, z, ldz, res, b, ldb, w, ldw, s, lds, zwork, lzwork, rwork, lrwork, iwork, liwork, info)
ZGEDMD computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine zgeqrf(m, n, a, lda, tau, work, lwork, info)
ZGEQRF
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zungqr(m, n, k, a, lda, tau, work, lwork, info)
ZUNGQR
subroutine zunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMQR