46 integer,
parameter :: WP = real32
48 REAL(KIND=wp),
PARAMETER :: one = 1.0_wp
49 REAL(KIND=wp),
PARAMETER :: zero = 0.0_wp
51 COMPLEX(KIND=WP),
PARAMETER :: CONE = ( 1.0_wp, 0.0_wp )
52 COMPLEX(KIND=WP),
PARAMETER :: CZERO = ( 0.0_wp, 0.0_wp )
54 REAL(KIND=wp),
ALLOCATABLE,
DIMENSION(:) :: res, &
55 res1, resex, singvx, singvqx, work
56 INTEGER ,
ALLOCATABLE,
DIMENSION(:) :: IWORK
57 REAL(KIND=wp) :: wdummy(2)
58 INTEGER :: IDUMMY(4), ISEED(4)
59 REAL(KIND=wp) :: anorm, cond, condl, condr, eps, &
60 tol, tol2, svdiff, tmp, tmp_au, &
61 tmp_fqr, tmp_rez, tmp_rezq, tmp_xw, &
64 COMPLEX(KIND=WP) :: CMAX
66 COMPLEX(KIND=WP),
ALLOCATABLE,
DIMENSION(:,:) :: A, AC, &
67 au, f, f0, f1, s, w, &
68 x, x0, y, y0, y1, z, z1
69 COMPLEX(KIND=WP),
ALLOCATABLE,
DIMENSION(:) :: CDA, CDR, &
70 cdl, ceigs, ceigsa, cwork
71 COMPLEX(KIND=WP) :: CDUMMY(22), CDUM2X2(2,2)
73 INTEGER :: K, KQ, LDF, LDS, LDA, LDAU, LDW, LDX, LDY, &
74 ldz, liwork, lwork, m, n, lloop, nrnk
75 INTEGER :: i, iJOBREF, iJOBZ, iSCALE, INFO, j, &
76 nfail, nfail_au, nfail_f_qr, nfail_rez, &
77 nfail_rezq, nfail_svdiff, nfail_total, nfailq_total, &
78 nfail_z_xv, mode, model, moder, whtsvd
79 INTEGER :: iNRNK, iWHTSVD, K_traj, LWMINOPT
80 CHARACTER :: GRADE, JOBREF, JOBZ, PIVTNG, RSIGN, &
81 scale, resids, wantq, wantr
99 INTRINSIC abs, int, min, max, sign
103 WRITE(*,*)
'COMPLEX CODE TESTING'
132 WRITE(*,*)
'L Loop Index = ', lloop
142 IF ( ( min(m,n) == 0 ) .OR. ( m < n ) )
THEN
143 WRITE(*,*)
'Bad dimensions. Required: M >= N > 0.'
170 ALLOCATE( ac(lda,m) )
171 ALLOCATE( f(ldf,n+1) )
172 ALLOCATE( f0(ldf,n+1) )
173 ALLOCATE( f1(ldf,n+1) )
175 ALLOCATE( x0(ldx,n) )
176 ALLOCATE( y(ldy,n+1) )
177 ALLOCATE( y0(ldy,n+1) )
178 ALLOCATE( y1(ldy,n+1) )
179 ALLOCATE( au(ldau,n) )
183 ALLOCATE( z1(ldz,n) )
188 ALLOCATE( singvx(n) )
189 ALLOCATE( singvqx(n) )
212 ALLOCATE( iwork(2*m) )
217 CALL clatmr( m, m,
'N', iseed,
'N', cda, mode, cond, &
218 cmax, rsign, grade, cdl, model, condl, &
219 cdr, moder, condr, pivtng, iwork, m, m, &
220 zero, -one,
'N', a, lda, iwork(m+1), info )
227 ALLOCATE( ceigsa(m) )
228 ALLOCATE( cwork(lcwork) )
229 ALLOCATE( work(2*m) )
230 ac(1:m,1:m) = a(1:m,1:m)
231 CALL cgeev(
'N',
'N', m, ac, lda, ceigsa, cdum2x2, 2, &
232 cdum2x2, 2, cwork, lcwork, work, info )
236 tmp = abs(ceigsa(icamax(m, ceigsa, 1)))
238 CALL clascl(
'G',0, 0, tmp, one, m, m, &
240 CALL clascl(
'G',0, 0, tmp, one, m, 1, &
242 anorm =
clange(
'F', m, m, a, lda, wdummy )
244 IF ( k_traj == 2 )
THEN
247 CALL clarnv(2, iseed, m, f(1,1) )
249 CALL cgemv(
'N', m, m, cone, a, lda, f(1,i), 1, &
252 x0(1:m,1:n/2) = f(1:m,1:n/2)
253 y0(1:m,1:n/2) = f(1:m,2:n/2+1)
255 CALL clarnv(2, iseed, m, f(1,1) )
257 CALL cgemv(
'N', m, m, cone, a, lda, f(1,i), 1, &
260 x0(1:m,n/2+1:n) = f(1:m,1:n-n/2)
261 y0(1:m,n/2+1:n) = f(1:m,2:n-n/2+1)
263 CALL clarnv(2, iseed, m, f(1,1) )
265 CALL cgemv(
'N', m, m, cone, a, m, f(1,i), 1, &
268 f0(1:m,1:n+1) = f(1:m,1:n+1)
269 x0(1:m,1:n) = f0(1:m,1:n)
270 y0(1:m,1:n) = f0(1:m,2:n+1)
278 SELECT CASE ( ijobz )
295 SELECT CASE ( ijobref )
306 SELECT CASE ( iscale )
317 DO inrnk = -1, -2, -1
332 x(1:m,1:n) = x0(1:m,1:n)
333 y(1:m,1:n) = y0(1:m,1:n)
335 CALL cgedmd( scale, jobz, resids, jobref, whtsvd, &
336 m, n, x, ldx, y, ldy, nrnk, tol, &
337 k, ceigs, z, ldz, res, &
338 au, ldau, w, ldw, s, lds, &
339 cdummy, -1, wdummy, -1, idummy, -1, info )
341 IF ( (info .EQ. 2) .OR. ( info .EQ. 3 ) &
342 .OR. ( info < 0 ) )
THEN
343 WRITE(*,*)
'Call to CGEDMD workspace query failed. &
344 &Check the calling sequence and the code.'
345 WRITE(*,*)
'The error code is ', info
346 WRITE(*,*)
'The input parameters were ', &
347 scale, jobz, resids, jobref, whtsvd, &
348 m, n, ldx, ldy, nrnk, tol, ldz, ldau, ldw, lds
354 lcwork = int(cdummy(lwminopt))
355 ALLOCATE(cwork(lcwork))
357 ALLOCATE(iwork(liwork))
358 lwork = int(wdummy(1))
359 ALLOCATE(work(lwork))
361 CALL cgedmd( scale, jobz, resids, jobref, whtsvd, &
362 m, n, x, ldx, y, ldy, nrnk, tol, &
363 k, ceigs, z, ldz, res, &
364 au, ldau, w, ldw, s, lds, &
365 cwork, lcwork, work, lwork, iwork, liwork, info )
366 IF ( info /= 0 )
THEN
367 WRITE(*,*)
'Call to CGEDMD failed. &
368 &Check the calling sequence and the code.'
369 WRITE(*,*)
'The error code is ', info
370 WRITE(*,*)
'The input parameters were ',&
371 scale, jobz, resids, jobref, whtsvd, &
372 m, n, ldx, ldy, nrnk, tol
375 singvx(1:n) = work(1:n)
378 IF ( lsame(jobz,
'V') )
THEN
384 CALL cgemm(
'N',
'N', m, k, k, cone, x, ldx, w, ldw, &
388 CALL caxpy( m, -cone, z(1,i), 1, z1(1,i), 1)
389 tmp = max(tmp,
scnrm2( m, z1(1,i), 1 ) )
391 tmp_xw = max(tmp_xw, tmp )
392 IF ( tmp_xw <= tol )
THEN
395 nfail_z_xv = nfail_z_xv + 1
396 WRITE(*,*)
':( .................CGEDMD FAILED!', &
397 'Check the code for implementation errors.'
398 WRITE(*,*)
'The input parameters were ',&
399 scale, jobz, resids, jobref, whtsvd, &
400 m, n, ldx, ldy, nrnk, tol
405 IF ( lsame(jobref,
'R') )
THEN
413 CALL cgemm(
'N',
'N', m, k, m, cone, a, lda, x, ldx, &
417 CALL caxpy( m, -cone, au(1,i), 1, z1(1,i), 1)
418 tmp = max( tmp,
scnrm2( m, z1(1,i),1 ) * &
419 singvx(k)/(anorm*singvx(1)) )
421 tmp_au = max( tmp_au, tmp )
422 IF ( tmp <= tol2 )
THEN
425 nfail_au = nfail_au + 1
426 WRITE(*,*)
':( .................CGEDMD FAILED!', &
427 'Check the code for implementation errors.'
428 WRITE(*,*)
'The input parameters were ',&
429 scale, jobz, resids, jobref, whtsvd, &
430 m, n, ldx, ldy, nrnk, tol2
432 ELSEIF ( lsame(jobref,
'E') )
THEN
439 CALL cgemm(
'N',
'N', m, k, m, cone, a, lda, au, ldau, czero, y1
442 CALL caxpy( m, -ceigs(i), au(1,i), 1, y1(1,i), 1 )
448 IF ( lsame(resids,
'R') )
THEN
452 CALL cgemm(
'N',
'N', m, k, m, cone, a, lda, z, ldz, czero, y1
459 CALL caxpy( m, -ceigs(i), z(1,i), 1, y1(1,i), 1 )
460 res1(i) =
scnrm2( m, y1(1,i), 1)
464 tmp = max( tmp, abs(res(i) - res1(i)) * &
465 singvx(k)/(anorm*singvx(1)) )
467 tmp_rez = max( tmp_rez, tmp )
468 IF ( tmp <= tol2 )
THEN
471 nfail_rez = nfail_rez + 1
472 WRITE(*,*)
':( ..................CGEDMD FAILED!', &
473 'Check the code for implementation errors.'
474 WRITE(*,*)
'The input parameters were ',&
475 scale, jobz, resids, jobref, whtsvd, &
476 m, n, ldx, ldy, nrnk, tol
480 IF ( lsame(jobref,
'E') )
THEN
483 tmp = max( tmp, abs(res1(i) - resex(i))/(res1(i)+resex(i)) )
485 tmp_ex = max(tmp_ex,tmp)
496 IF ( k_traj == 1 )
THEN
498 f(1:m,1:n+1) = f0(1:m,1:n+1)
499 CALL cgedmdq( scale, jobz, resids, wantq, wantr, jobref, &
500 whtsvd, m, n+1, f, ldf, x, ldx, y, ldy, &
501 nrnk, tol, k, ceigs, z, ldz, res, au, &
502 ldau, w, ldw, s, lds, cdummy, -1, &
503 wdummy, -1, idummy, -1, info )
505 lcwork = int(cdummy(lwminopt))
506 ALLOCATE(cwork(lcwork))
508 ALLOCATE(iwork(liwork))
509 lwork = int(wdummy(1))
510 ALLOCATE(work(lwork))
512 CALL cgedmdq( scale, jobz, resids, wantq, wantr, jobref, &
513 whtsvd, m, n+1, f, ldf, x, ldx, y, ldy, &
514 nrnk, tol, kq, ceigs, z, ldz, res, au, &
515 ldau, w, ldw, s, lds, cwork, lcwork, &
516 work, lwork, iwork, liwork, info )
517 IF ( info /= 0 )
THEN
518 WRITE(*,*)
'Call to CGEDMDQ failed. &
519 &Check the calling sequence and the code.'
520 WRITE(*,*)
'The error code is ', info
521 WRITE(*,*)
'The input parameters were ',&
522 scale, jobz, resids, wantq, wantr, whtsvd, &
523 m, n, ldx, ldy, nrnk, tol
526 singvqx(1:n) =work(1:n)
532 tmp = max(tmp, abs(singvx(i)-singvqx(i)) / &
535 svdiff = max( svdiff, tmp )
536 IF ( tmp > tol2 )
THEN
537 WRITE(*,*)
'FAILED! Something was wrong with the run.'
538 nfail_svdiff = nfail_svdiff + 1
543 IF ( lsame(wantq,
'Q') .AND. lsame(wantr,
'R') )
THEN
547 f1(1:m,1:n+1) = f0(1:m,1:n+1)
548 CALL cgemm(
'N',
'N', m, n+1, min(m,n+1), -cone, f, &
549 ldf, y, ldy, cone, f1, ldf )
550 tmp_fqr =
clange(
'F', m, n+1, f1, ldf, work ) / &
551 clange(
'F', m, n+1, f0, ldf, work )
552 IF ( tmp_fqr <= tol2 )
THEN
555 WRITE(*,*)
':( CGEDMDQ ........ FAILED.'
556 nfail_f_qr = nfail_f_qr + 1
561 IF ( lsame(resids,
'R') )
THEN
565 CALL cgemm(
'N',
'N', m, kq, m, cone, a, lda, z, ldz, czero
571 CALL caxpy( m, -ceigs(i), z(1,i), 1, y1(1,i), 1 )
573 res1(i) =
scnrm2( m, y1(1,i), 1)
577 tmp = max( tmp, abs(res(i) - res1(i)) * &
578 singvqx(kq)/(anorm*singvqx(1)) )
580 tmp_rezq = max( tmp_rezq, tmp )
581 IF ( tmp <= tol2 )
THEN
584 nfail_rezq = nfail_rezq + 1
585 WRITE(*,*)
'................ CGEDMDQ FAILED!', &
586 'Check the code for implementation errors.'
634 DEALLOCATE( singvqx )
639 WRITE(*,*)
'>>>>>>>>>>>>>>>>>>>>>>>>>>'
640 WRITE(*,*)
' Test summary for CGEDMD :'
641 WRITE(*,*)
'>>>>>>>>>>>>>>>>>>>>>>>>>>'
643 IF ( nfail_z_xv == 0 )
THEN
644 WRITE(*,*)
'>>>> Z - U*V test PASSED.'
646 WRITE(*,*)
'Z - U*V test FAILED ', nfail_z_xv,
' time(s)'
647 WRITE(*,*)
'Max error ||Z-U*V||_F was ', tmp_xw
648 nfail_total = nfail_total + nfail_z_xv
651 IF ( nfail_au == 0 )
THEN
652 WRITE(*,*)
'>>>> A*U test PASSED. '
654 WRITE(*,*)
'A*U test FAILED ', nfail_au,
' time(s)'
655 WRITE(*,*)
'Max A*U test adjusted error measure was ', tmp_au
656 WRITE(*,*)
'It should be up to O(M*N) times EPS, EPS = ', eps
657 nfail_total = nfail_total + nfail_au
661 IF ( nfail_rez == 0 )
THEN
662 WRITE(*,*)
'>>>> Rezidual computation test PASSED.'
664 WRITE(*,*)
'Rezidual computation test FAILED ', nfail_rez,
'time(s)'
665 WRITE(*,*)
'Max residual computing test adjusted error measure was '
666 WRITE(*,*)
'It should be up to O(M*N) times EPS, EPS = ', eps
667 nfail_total = nfail_total + nfail_rez
669 IF ( nfail_total == 0 )
THEN
670 WRITE(*,*)
'>>>> CGEDMD :: ALL TESTS PASSED.'
672 WRITE(*,*) nfail_total,
'FAILURES!'
673 WRITE(*,*)
'>>>>>>>>>>>>>> CGEDMD :: TESTS FAILED. CHECK THE IMPLEMENTATION.'
677 WRITE(*,*)
'>>>>>>>>>>>>>>>>>>>>>>>>>>'
678 WRITE(*,*)
' Test summary for CGEDMDQ :'
679 WRITE(*,*)
'>>>>>>>>>>>>>>>>>>>>>>>>>>'
682 IF ( nfail_svdiff == 0 )
THEN
683 WRITE(*,*)
'>>>> CGEDMD and CGEDMDQ computed singular &
684 &values test PASSED.'
686 WRITE(*,*)
'ZGEDMD and ZGEDMDQ discrepancies in &
687 &the singular values unacceptable ', &
688 nfail_svdiff,
' times. Test FAILED.'
689 WRITE(*,*)
'The maximal discrepancy in the singular values (relative to the norm) was '
690 WRITE(*,*)
'It should be up to O(M*N) times EPS, EPS = ', eps
691 nfailq_total = nfailq_total + nfail_svdiff
693 IF ( nfail_f_qr == 0 )
THEN
694 WRITE(*,*)
'>>>> F - Q*R test PASSED.'
696 WRITE(*,*)
'F - Q*R test FAILED ', nfail_f_qr,
' time(s)'
697 WRITE(*,*)
'The largest relative residual was ', tmp_fqr
698 WRITE(*,*)
'It should be up to O(M*N) times EPS, EPS = ', eps
699 nfailq_total = nfailq_total + nfail_f_qr
702 IF ( nfail_rezq == 0 )
THEN
703 WRITE(*,*)
'>>>> Rezidual computation test PASSED.'
705 WRITE(*,*)
'Rezidual computation test FAILED ', nfail_rezq,
'time(s)'
706 WRITE(*,*)
'Max residual computing test adjusted error measure was '
707 WRITE(*,*)
'It should be up to O(M*N) times EPS, EPS = ', eps
708 nfailq_total = nfailq_total + nfail_rezq
711 IF ( nfailq_total == 0 )
THEN
712 WRITE(*,*)
'>>>>>>> CGEDMDQ :: ALL TESTS PASSED.'
714 WRITE(*,*) nfailq_total,
'FAILURES!'
715 WRITE(*,*)
'>>>>>>> CGEDMDQ :: TESTS FAILED. CHECK THE IMPLEMENTATION.'
719 WRITE(*,*)
'Test completed.'
subroutine clatmr(m, n, dist, iseed, sym, d, mode, cond, dmax, rsign, grade, dl, model, condl, dr, moder, condr, pivtng, ipivot, kl, ku, sparse, anorm, pack, a, lda, iwork, info)
CLATMR
subroutine caxpy(n, ca, cx, incx, cy, incy)
CAXPY
subroutine cgedmdq(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)
CGEDMDQ computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine cgedmd(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)
CGEDMD computes the Dynamic Mode Decomposition (DMD) for a pair of data snapshot matrices.
subroutine cgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
CGEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
integer function icamax(n, cx, incx)
ICAMAX
real function slamch(cmach)
SLAMCH
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine clarnv(idist, iseed, n, x)
CLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
logical function lsame(ca, cb)
LSAME
real(wp) function scnrm2(n, x, incx)
SCNRM2