551SUBROUTINE zgedmdq( JOBS, JOBZ, JOBR, JOBQ, JOBT, JOBF, &
552 WHTSVD, M, N, F, LDF, X, LDX, Y, &
553 LDY, NRNK, TOL, K, EIGS, &
554 Z, LDZ, RES, B, LDB, V, LDV, &
555 S, LDS, ZWORK, LZWORK, WORK, LWORK, &
556 IWORK, LIWORK, INFO )
565 use,
INTRINSIC :: iso_fortran_env, only: real64
567 INTEGER,
PARAMETER :: WP = real64
571 CHARACTER,
INTENT(IN) :: JOBS, JOBZ, JOBR, JOBQ, &
573 INTEGER,
INTENT(IN) :: WHTSVD, M, N, LDF, LDX, &
574 LDY, NRNK, LDZ, LDB, LDV, &
575 LDS, LZWORK, LWORK, LIWORK
576 INTEGER,
INTENT(OUT) :: INFO, K
577 REAL(KIND=wp),
INTENT(IN) :: tol
581 COMPLEX(KIND=WP),
INTENT(INOUT) :: F(LDF,*)
582 COMPLEX(KIND=WP),
INTENT(OUT) :: X(LDX,*), Y(LDY,*), &
583 Z(LDZ,*), B(LDB,*), &
585 COMPLEX(KIND=WP),
INTENT(OUT) :: EIGS(*)
586 COMPLEX(KIND=WP),
INTENT(OUT) :: ZWORK(*)
587 REAL(KIND=wp),
INTENT(OUT) :: res(*)
588 REAL(KIND=wp),
INTENT(OUT) :: work(*)
589 INTEGER,
INTENT(OUT) :: IWORK(*)
593 REAL(KIND=wp),
PARAMETER :: one = 1.0_wp
594 REAL(KIND=wp),
PARAMETER :: zero = 0.0_wp
596 COMPLEX(KIND=WP),
PARAMETER :: ZZERO = ( 0.0_wp, 0.0_wp )
600 INTEGER :: IMINWR, INFO1, MINMN, MLRWRK, &
601 MLWDMD, MLWGQR, MLWMQR, MLWORK, &
602 MLWQR, OLWDMD, OLWGQR, OLWMQR, &
604 LOGICAL :: LQUERY, SCCOLX, SCCOLY, WANTQ, &
605 WNTTRF, WNTRES, WNTVEC, WNTVCF, &
606 WNTVCQ, WNTREF, WNTEX
607 CHARACTER(LEN=1) :: JOBVL
621 INTRINSIC max, min, int
625 wntres = lsame(jobr,
'R')
626 sccolx = lsame(jobs,
'S') .OR. lsame( jobs,
'C' )
627 sccoly = lsame(jobs,
'Y')
628 wntvec = lsame(jobz,
'V')
629 wntvcf = lsame(jobz,
'F')
630 wntvcq = lsame(jobz,
'Q')
631 wntref = lsame(jobf,
'R')
632 wntex = lsame(jobf,
'E')
633 wantq = lsame(jobq,
'Q')
634 wnttrf = lsame(jobt,
'R')
637 lquery = ( (lzwork == -1) .OR. (lwork == -1) .OR. (liwork == -1) )
639 IF ( .NOT. (sccolx .OR. sccoly .OR. &
640 lsame(jobs,
'N')) )
THEN
642 ELSE IF ( .NOT. (wntvec .OR. wntvcf .OR. wntvcq &
643 .OR. lsame(jobz,
'N')) )
THEN
645 ELSE IF ( .NOT. (wntres .OR. lsame(jobr,
'N')) .OR. &
646 ( wntres .AND. lsame(jobz,
'N') ) )
THEN
648 ELSE IF ( .NOT. (wantq .OR. lsame(jobq,
'N')) )
THEN
650 ELSE IF ( .NOT. ( wnttrf .OR. lsame(jobt,
'N') ) )
THEN
652 ELSE IF ( .NOT. (wntref .OR. wntex .OR. &
653 lsame(jobf,
'N') ) )
THEN
655 ELSE IF ( .NOT. ((whtsvd == 1).OR.(whtsvd == 2).OR. &
656 (whtsvd == 3).OR.(whtsvd == 4)) )
THEN
658 ELSE IF ( m < 0 )
THEN
660 ELSE IF ( ( n < 0 ) .OR. ( n > m+1 ) )
THEN
662 ELSE IF ( ldf < m )
THEN
664 ELSE IF ( ldx < minmn )
THEN
666 ELSE IF ( ldy < minmn )
THEN
668 ELSE IF ( .NOT. (( nrnk == -2).OR.(nrnk == -1).OR. &
669 ((nrnk >= 1).AND.(nrnk <=n ))) )
THEN
671 ELSE IF ( ( tol < zero ) .OR. ( tol >= one ) )
THEN
673 ELSE IF ( ldz < m )
THEN
675 ELSE IF ( (wntref.OR.wntex ).AND.( ldb < minmn ) )
THEN
677 ELSE IF ( ldv < n-1 )
THEN
679 ELSE IF ( lds < n-1 )
THEN
683 IF ( wntvec .OR. wntvcf .OR. wntvcq )
THEN
688 IF ( info == 0 )
THEN
693 IF ( ( n == 0 ) .OR. ( n == 1 ) )
THEN
715 mlwork = max(mlwork,minmn + mlwqr)
718 CALL zgeqrf( m, n, f, ldf, zwork, zwork, -1, &
720 olwqr = int(zwork(1))
721 olwork = max(olwork,minmn + olwqr)
723 CALL zgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn,&
724 n-1, x, ldx, y, ldy, nrnk, tol, k, &
725 eigs, z, ldz, res, b, ldb, v, ldv, &
726 s, lds, zwork, -1, work, -1, iwork,&
728 mlwdmd = int(zwork(1))
729 mlwork = max(mlwork, minmn + mlwdmd)
730 mlrwrk = max(mlrwrk, int(work(1)))
731 iminwr = max(iminwr, iwork(1))
733 olwdmd = int(zwork(2))
734 olwork = max(olwork, minmn+olwdmd)
736 IF ( wntvec .OR. wntvcf )
THEN
738 mlwork = max(mlwork,minmn+mlwmqr)
740 CALL zunmqr(
'L',
'N', m, n, minmn, f, ldf, &
741 zwork, z, ldz, zwork, -1, info1 )
742 olwmqr = int(zwork(1))
743 olwork = max(olwork,minmn+olwmqr)
748 mlwork = max(mlwork,minmn+mlwgqr)
750 CALL zungqr( m, minmn, minmn, f, ldf, zwork, &
752 olwgqr = int(zwork(1))
753 olwork = max(olwork,minmn+olwgqr)
756 IF ( liwork < iminwr .AND. (.NOT.lquery) ) info = -34
757 IF ( lwork < mlrwrk .AND. (.NOT.lquery) ) info = -32
758 IF ( lzwork < mlwork .AND. (.NOT.lquery) ) info = -30
761 CALL xerbla(
'ZGEDMDQ', -info )
763 ELSE IF ( lquery )
THEN
778 CALL zgeqrf( m, n, f, ldf, zwork, &
779 zwork(minmn+1), lzwork-minmn, info1 )
785 CALL zlaset(
'L', minmn, n-1, zzero, zzero, x, ldx )
786 CALL zlacpy(
'U', minmn, n-1, f, ldf, x, ldx )
787 CALL zlacpy(
'A', minmn, n-1, f(1,2), ldf, y, ldy )
789 CALL zlaset(
'L', minmn-2, n-2, zzero, zzero, &
794 CALL zgedmd( jobs, jobvl, jobr, jobf, whtsvd, minmn, &
795 n-1, x, ldx, y, ldy, nrnk, tol, k, &
796 eigs, z, ldz, res, b, ldb, v, ldv, &
797 s, lds, zwork(minmn+1), lzwork-minmn, &
798 work, lwork, iwork, liwork, info1 )
799 IF ( info1 == 2 .OR. info1 == 3 )
THEN
811 IF ( m > minmn )
CALL zlaset(
'A', m-minmn, k, zzero, &
812 zzero, z(minmn+1,1), ldz )
813 CALL zunmqr(
'L',
'N', m, k, minmn, f, ldf, zwork, z, &
814 ldz, zwork(minmn+1), lzwork-minmn, info1 )
815 ELSE IF ( wntvcf )
THEN
822 CALL zlacpy(
'A', n, k, x, ldx, z, ldz )
823 IF ( m > n )
CALL zlaset(
'A', m-n, k, zzero, zzero, &
825 CALL zunmqr(
'L',
'N', m, k, minmn, f, ldf, zwork, z, &
826 ldz, zwork(minmn+1), lzwork-minmn, info1 )
837 CALL zlaset(
'A', minmn, n, zzero, zzero, y, ldy )
838 CALL zlacpy(
'U', minmn, n, f, ldf, y, ldy )
846 CALL zungqr( m, minmn, minmn, f, ldf, zwork, &
847 zwork(minmn+1), lzwork-minmn, info1 )
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.