LAPACK 3.12.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
cchkdmd.f90
Go to the documentation of this file.
1! This is a test program for checking the implementations of
2! the implementations of the following subroutines
3!
4! CGEDMD, for computation of the
5! Dynamic Mode Decomposition (DMD)
6! CGEDMDQ, for computation of a
7! QR factorization based compressed DMD
8!
9! Developed and supported by:
10! ===========================
11! Developed and coded by Zlatko Drmac, Faculty of Science,
12! University of Zagreb; drmac@math.hr
13! In cooperation with
14! AIMdyn Inc., Santa Barbara, CA.
15! ========================================================
16! How to run the code (compiler, link info)
17! ========================================================
18! Compile as FORTRAN 90 (or later) and link with BLAS and
19! LAPACK libraries.
20! NOTE: The code is developed and tested on top of the
21! Intel MKL library (versions 2022.0.3 and 2022.2.0),
22! using the Intel Fortran compiler.
23!
24! For developers of the C++ implementation
25! ========================================================
26! See the LAPACK++ and Template Numerical Toolkit (TNT)
27!
28! Note on a development of the GPU HP implementation
29! ========================================================
30! Work in progress. See CUDA, MAGMA, SLATE.
31! NOTE: The four SVD subroutines used in this code are
32! included as a part of R&D and for the completeness.
33! This was also an opportunity to test those SVD codes.
34! If the scaling option is used all four are essentially
35! equally good. For implementations on HP platforms,
36! one can use whichever SVD is available.
37!............................................................
38
39!............................................................
40!............................................................
41!
42 PROGRAM dmd_test
43
44 use iso_fortran_env
45 IMPLICIT NONE
46 integer, parameter :: WP = real32
47!............................................................
48 REAL(KIND=wp), PARAMETER :: one = 1.0_wp
49 REAL(KIND=wp), PARAMETER :: zero = 0.0_wp
50
51 COMPLEX(KIND=WP), PARAMETER :: CONE = ( 1.0_wp, 0.0_wp )
52 COMPLEX(KIND=WP), PARAMETER :: CZERO = ( 0.0_wp, 0.0_wp )
53!............................................................
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, &
62 tmp_ex
63!............................................................
64 COMPLEX(KIND=WP) :: CMAX
65 INTEGER :: LCWORK
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)
72!............................................................
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
82 LOGICAL :: TEST_QRDMD
83
84!..... external subroutines (BLAS and LAPACK)
85 EXTERNAL caxpy, cgeev, cgemm, cgemv, clascl
86!.....external subroutines DMD package
87! subroutines under test
88 EXTERNAL cgedmd, cgedmdq
89!..... external functions (BLAS and LAPACK)
90 EXTERNAL scnrm2, slamch
91 REAL(KIND=wp) :: scnrm2, slamch
92 EXTERNAL clange
93 REAL(KIND=wp) :: clange
94 EXTERNAL icamax
95 INTEGER ICAMAX
96 EXTERNAL lsame
97 LOGICAL LSAME
98
99 INTRINSIC abs, int, min, max, sign
100!............................................................
101
102
103 WRITE(*,*) 'COMPLEX CODE TESTING'
104
105 ! The test is always in pairs : ( CGEDMD and CGEDMDQ)
106 ! because the test includes comparing the results (in pairs).
107!.....................................................................................
108 ! This code by default performs tests on CGEDMDQ
109 ! Since the QR factorizations based algorithm is designed for
110 ! single trajectory data, only single trajectory tests will
111 ! be performed with xGEDMDQ.
112
113 wantq = 'Q'
114 wantr = 'R'
115!.................................................................................
116
117 eps = slamch( 'P' ) ! machine precision WP
118
119 ! Global counters of failures of some particular tests
120 nfail = 0
121 nfail_rez = 0
122 nfail_rezq = 0
123 nfail_z_xv = 0
124 nfail_f_qr = 0
125 nfail_au = 0
126 nfail_svdiff = 0
127 nfail_total = 0
128 nfailq_total = 0
129
130 DO lloop = 1, 4
131
132 WRITE(*,*) 'L Loop Index = ', lloop
133
134 ! Set the dimensions of the problem ...
135 READ(*,*) m
136 WRITE(*,*) 'M = ', m
137 ! ... and the number of snapshots.
138 READ(*,*) n
139 WRITE(*,*) 'N = ', n
140
141 ! Test the dimensions
142 IF ( ( min(m,n) == 0 ) .OR. ( m < n ) ) THEN
143 WRITE(*,*) 'Bad dimensions. Required: M >= N > 0.'
144 stop
145 END IF
146!.............
147 ! The seed inside the LLOOP so that each pass can be reproduced easily.
148 iseed(1) = 4
149 iseed(2) = 3
150 iseed(3) = 2
151 iseed(4) = 1
152
153 lda = m
154 ldf = m
155 ldx = m
156 ldy = m
157 ldw = n
158 ldz = m
159 ldau = m
160 lds = n
161
162 tmp_xw = zero
163 tmp_au = zero
164 tmp_rez = zero
165 tmp_rezq = zero
166 svdiff = zero
167 tmp_ex = zero
168
169 ALLOCATE( a(lda,m) )
170 ALLOCATE( ac(lda,m) )
171 ALLOCATE( f(ldf,n+1) )
172 ALLOCATE( f0(ldf,n+1) )
173 ALLOCATE( f1(ldf,n+1) )
174 ALLOCATE( x(ldx,n) )
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) )
180 ALLOCATE( w(ldw,n) )
181 ALLOCATE( s(lds,n) )
182 ALLOCATE( z(ldz,n) )
183 ALLOCATE( z1(ldz,n) )
184 ALLOCATE( res(n) )
185 ALLOCATE( res1(n) )
186 ALLOCATE( resex(n) )
187 ALLOCATE( ceigs(n) )
188 ALLOCATE( singvx(n) )
189 ALLOCATE( singvqx(n) )
190
191 tol = 10*m*eps
192 tol2 = 10*m*n*eps
193
194!.............
195
196 DO k_traj = 1, 2
197 ! Number of intial conditions in the simulation/trajectories (1 or 2)
198
199 cond = 1.0d4
200 cmax = (1.0d1,1.0d1)
201 rsign = 'F'
202 grade = 'N'
203 model = 6
204 condl = 1.0d1
205 moder = 6
206 condr = 1.0d1
207 pivtng = 'N'
208 ! Loop over all parameter MODE values for CLATMR (+-1,..,+-6)
209
210 DO mode = 1, 6
211
212 ALLOCATE( iwork(2*m) )
213 ALLOCATE( cda(m) )
214 ALLOCATE( cdl(m) )
215 ALLOCATE( cdr(m) )
216
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 )
221 DEALLOCATE( cdr )
222 DEALLOCATE( cdl )
223 DEALLOCATE( cda )
224 DEALLOCATE( iwork )
225
226 lcwork = max(1,2*m)
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 ) ! LAPACK CALL
233 DEALLOCATE(work)
234 DEALLOCATE(cwork)
235
236 tmp = abs(ceigsa(icamax(m, ceigsa, 1))) ! The spectral radius of A
237 ! Scale the matrix A to have unit spectral radius.
238 CALL clascl( 'G',0, 0, tmp, one, m, m, &
239 a, lda, info )
240 CALL clascl( 'G',0, 0, tmp, one, m, 1, &
241 ceigsa, m, info )
242 anorm = clange( 'F', m, m, a, lda, wdummy )
243
244 IF ( k_traj == 2 ) THEN
245 ! generate data as two trajectories
246 ! with two inital conditions
247 CALL clarnv(2, iseed, m, f(1,1) )
248 DO i = 1, n/2
249 CALL cgemv( 'N', m, m, cone, a, lda, f(1,i), 1, &
250 czero, f(1,i+1), 1 )
251 END DO
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)
254
255 CALL clarnv(2, iseed, m, f(1,1) )
256 DO i = 1, n-n/2
257 CALL cgemv( 'N', m, m, cone, a, lda, f(1,i), 1, &
258 czero, f(1,i+1), 1 )
259 END DO
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)
262 ELSE
263 CALL clarnv(2, iseed, m, f(1,1) )
264 DO i = 1, n
265 CALL cgemv( 'N', m, m, cone, a, m, f(1,i), 1, &
266 czero, f(1,i+1), 1 )
267 END DO
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)
271 END IF
272
273 DEALLOCATE( ceigsa )
274!........................................................................
275
276 DO ijobz = 1, 4
277
278 SELECT CASE ( ijobz )
279 CASE(1)
280 jobz = 'V'
281 resids = 'R'
282 CASE(2)
283 jobz = 'V'
284 resids = 'N'
285 CASE(3)
286 jobz = 'F'
287 resids = 'N'
288 CASE(4)
289 jobz = 'N'
290 resids = 'N'
291 END SELECT
292
293 DO ijobref = 1, 3
294
295 SELECT CASE ( ijobref )
296 CASE(1)
297 jobref = 'R'
298 CASE(2)
299 jobref = 'E'
300 CASE(3)
301 jobref = 'N'
302 END SELECT
303
304 DO iscale = 1, 4
305
306 SELECT CASE ( iscale )
307 CASE(1)
308 scale = 'S'
309 CASE(2)
310 scale = 'C'
311 CASE(3)
312 scale = 'Y'
313 CASE(4)
314 scale = 'N'
315 END SELECT
316
317 DO inrnk = -1, -2, -1
318 nrnk = inrnk
319
320 DO iwhtsvd = 1, 3
321 ! Check all four options to compute the POD basis
322 ! via the SVD.
323 whtsvd = iwhtsvd
324
325 DO lwminopt = 1, 2
326 ! Workspace query for the minimal (1) and for the optimal
327 ! (2) workspace lengths determined by workspace query.
328
329 ! CGEDMD is always tested and its results are also used for
330 ! comparisons with CGEDMDQ.
331
332 x(1:m,1:n) = x0(1:m,1:n)
333 y(1:m,1:n) = y0(1:m,1:n)
334
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 )
340
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
349 stop
350 ELSE
351 !WRITE(*,*) '... done. Workspace length computed.'
352 END IF
353
354 lcwork = int(cdummy(lwminopt))
355 ALLOCATE(cwork(lcwork))
356 liwork = idummy(1)
357 ALLOCATE(iwork(liwork))
358 lwork = int(wdummy(1))
359 ALLOCATE(work(lwork))
360
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
373 stop
374 END IF
375 singvx(1:n) = work(1:n)
376
377 !...... CGEDMD check point
378 IF ( lsame(jobz,'V') ) THEN
379 ! Check that Z = X*W, on return from CGEDMD
380 ! This checks that the returned eigenvectors in Z are
381 ! the product of the SVD'POD basis returned in X
382 ! and the eigenvectors of the Rayleigh quotient
383 ! returned in W
384 CALL cgemm( 'N', 'N', m, k, k, cone, x, ldx, w, ldw, &
385 czero, z1, ldz )
386 tmp = zero
387 DO i = 1, k
388 CALL caxpy( m, -cone, z(1,i), 1, z1(1,i), 1)
389 tmp = max(tmp, scnrm2( m, z1(1,i), 1 ) )
390 END DO
391 tmp_xw = max(tmp_xw, tmp )
392 IF ( tmp_xw <= tol ) THEN
393 !WRITE(*,*) ' :) .... OK .........CGEDMD PASSED.'
394 ELSE
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
401 END IF
402 END IF
403 !...... CGEDMD check point
404
405 IF ( lsame(jobref,'R') ) THEN
406 ! The matrix A*U is returned for computing refined Ritz vectors.
407 ! Check that A*U is computed correctly using the formula
408 ! A*U = Y * V * inv(SIGMA). This depends on the
409 ! accuracy in the computed singular values and vectors of X.
410 ! See the paper for an error analysis.
411 ! Note that the left singular vectors of the input matrix X
412 ! are returned in the array X.
413 CALL cgemm( 'N', 'N', m, k, m, cone, a, lda, x, ldx, &
414 czero, z1, ldz )
415 tmp = zero
416 DO i = 1, k
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)) )
420 END DO
421 tmp_au = max( tmp_au, tmp )
422 IF ( tmp <= tol2 ) THEN
423 !WRITE(*,*) ':) .... OK .........CGEDMD PASSED.'
424 ELSE
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
431 END IF
432 ELSEIF ( lsame(jobref,'E') ) THEN
433 ! The unscaled vectors of the Exact DMD are computed.
434 ! This option is included for the sake of completeness,
435 ! for users who prefer the Exact DMD vectors. The
436 ! returned vectors are in the real form, in the same way
437 ! as the Ritz vectors. Here we just save the vectors
438 ! and test them separately using a Matlab script.
439 CALL cgemm( 'N', 'N', m, k, m, cone, a, lda, au, ldau, czero, y1, ldy )
440
441 DO i=1, k
442 CALL caxpy( m, -ceigs(i), au(1,i), 1, y1(1,i), 1 )
443 resex(i) = scnrm2( m, y1(1,i), 1) / scnrm2(m,au(1,i),1)
444 END DO
445 END IF
446 !...... CGEDMD check point
447
448 IF ( lsame(resids, 'R') ) THEN
449 ! Compare the residuals returned by CGEDMD with the
450 ! explicitly computed residuals using the matrix A.
451 ! Compute explicitly Y1 = A*Z
452 CALL cgemm( 'N', 'N', m, k, m, cone, a, lda, z, ldz, czero, y1, ldy )
453 ! ... and then A*Z(:,i) - LAMBDA(i)*Z(:,i), using the real forms
454 ! of the invariant subspaces that correspond to complex conjugate
455 ! pairs of eigencalues. (See the description of Z in CGEDMD,)
456
457 DO i=1, k
458 ! have a real eigenvalue with real eigenvector
459 CALL caxpy( m, -ceigs(i), z(1,i), 1, y1(1,i), 1 )
460 res1(i) = scnrm2( m, y1(1,i), 1)
461 END DO
462 tmp = zero
463 DO i = 1, k
464 tmp = max( tmp, abs(res(i) - res1(i)) * &
465 singvx(k)/(anorm*singvx(1)) )
466 END DO
467 tmp_rez = max( tmp_rez, tmp )
468 IF ( tmp <= tol2 ) THEN
469 !WRITE(*,*) ':) .... OK ..........CGEDMD PASSED.'
470 ELSE
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
477 END IF
478
479
480 IF ( lsame(jobref,'E') ) THEN
481 tmp = zero
482 DO i = 1, k
483 tmp = max( tmp, abs(res1(i) - resex(i))/(res1(i)+resex(i)) )
484 END DO
485 tmp_ex = max(tmp_ex,tmp)
486 END IF
487
488 END IF
489
490 DEALLOCATE(cwork)
491 DEALLOCATE(work)
492 DEALLOCATE(iwork)
493
494!.......................................................................................................
495
496 IF ( k_traj == 1 ) THEN
497
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 )
504
505 lcwork = int(cdummy(lwminopt))
506 ALLOCATE(cwork(lcwork))
507 liwork = idummy(1)
508 ALLOCATE(iwork(liwork))
509 lwork = int(wdummy(1))
510 ALLOCATE(work(lwork))
511
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
524 stop
525 END IF
526 singvqx(1:n) =work(1:n)
527
528 !..... ZGEDMDQ check point
529
530 tmp = zero
531 DO i = 1, min(k, kq)
532 tmp = max(tmp, abs(singvx(i)-singvqx(i)) / &
533 singvx(1) )
534 END DO
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
539 END IF
540 !..... CGEDMDQ check point
541
542 !..... CGEDMDQ check point
543 IF ( lsame(wantq,'Q') .AND. lsame(wantr,'R') ) THEN
544 ! Check that the QR factors are computed and returned
545 ! as requested. The residual ||F-Q*R||_F / ||F||_F
546 ! is compared to M*N*EPS.
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
553 !WRITE(*,*) ':) CGEDMDQ ........ PASSED.'
554 ELSE
555 WRITE(*,*) ':( CGEDMDQ ........ FAILED.'
556 nfail_f_qr = nfail_f_qr + 1
557 END IF
558 END IF
559 !..... ZGEDMDQ checkpoint
560 !..... ZGEDMDQ checkpoint
561 IF ( lsame(resids, 'R') ) THEN
562 ! Compare the residuals returned by ZGEDMDQ with the
563 ! explicitly computed residuals using the matrix A.
564 ! Compute explicitly Y1 = A*Z
565 CALL cgemm( 'N', 'N', m, kq, m, cone, a, lda, z, ldz, czero, y1, ldy )
566 ! ... and then A*Z(:,i) - LAMBDA(i)*Z(:,i), using the real forms
567 ! of the invariant subspaces that correspond to complex conjugate
568 ! pairs of eigencalues. (See the description of Z in ZGEDMDQ)
569 DO i = 1, kq
570 ! have a real eigenvalue with real eigenvector
571 CALL caxpy( m, -ceigs(i), z(1,i), 1, y1(1,i), 1 )
572 ! Y(1:M,i) = Y(1:M,i) - REIG(i)*Z(1:M,i)
573 res1(i) = scnrm2( m, y1(1,i), 1)
574 END DO
575 tmp = zero
576 DO i = 1, kq
577 tmp = max( tmp, abs(res(i) - res1(i)) * &
578 singvqx(kq)/(anorm*singvqx(1)) )
579 END DO
580 tmp_rezq = max( tmp_rezq, tmp )
581 IF ( tmp <= tol2 ) THEN
582 !WRITE(*,*) '.... OK ........ CGEDMDQ PASSED.'
583 ELSE
584 nfail_rezq = nfail_rezq + 1
585 WRITE(*,*) '................ CGEDMDQ FAILED!', &
586 'Check the code for implementation errors.'
587 END IF
588 END IF
589
590 DEALLOCATE(cwork)
591 DEALLOCATE(work)
592 DEALLOCATE(iwork)
593
594 END IF
595
596 END DO ! LWMINOPT
597 !write(*,*) 'LWMINOPT loop completed'
598 END DO ! iWHTSVD
599 !write(*,*) 'WHTSVD loop completed'
600 END DO ! iNRNK -2:-1
601 !write(*,*) 'NRNK loop completed'
602 END DO ! iSCALE 1:4
603 !write(*,*) 'SCALE loop completed'
604 END DO
605 !write(*,*) 'JOBREF loop completed'
606 END DO ! iJOBZ
607 !write(*,*) 'JOBZ loop completed'
608
609 END DO ! MODE -6:6
610 !write(*,*) 'MODE loop completed'
611 END DO ! 1 or 2 trajectories
612 !write(*,*) 'trajectories loop completed'
613
614 DEALLOCATE( a )
615 DEALLOCATE( ac )
616 DEALLOCATE( z )
617 DEALLOCATE( f )
618 DEALLOCATE( f0 )
619 DEALLOCATE( f1 )
620 DEALLOCATE( x )
621 DEALLOCATE( x0 )
622 DEALLOCATE( y )
623 DEALLOCATE( y0 )
624 DEALLOCATE( y1 )
625 DEALLOCATE( au )
626 DEALLOCATE( w )
627 DEALLOCATE( s )
628 DEALLOCATE( z1 )
629 DEALLOCATE( res )
630 DEALLOCATE( res1 )
631 DEALLOCATE( resex )
632 DEALLOCATE( ceigs )
633 DEALLOCATE( singvx )
634 DEALLOCATE( singvqx )
635
636 END DO ! LLOOP
637
638 WRITE(*,*)
639 WRITE(*,*) '>>>>>>>>>>>>>>>>>>>>>>>>>>'
640 WRITE(*,*) ' Test summary for CGEDMD :'
641 WRITE(*,*) '>>>>>>>>>>>>>>>>>>>>>>>>>>'
642 WRITE(*,*)
643 IF ( nfail_z_xv == 0 ) THEN
644 WRITE(*,*) '>>>> Z - U*V test PASSED.'
645 ELSE
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
649 END IF
650
651 IF ( nfail_au == 0 ) THEN
652 WRITE(*,*) '>>>> A*U test PASSED. '
653 ELSE
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
658 END IF
659
660
661 IF ( nfail_rez == 0 ) THEN
662 WRITE(*,*) '>>>> Rezidual computation test PASSED.'
663 ELSE
664 WRITE(*,*) 'Rezidual computation test FAILED ', nfail_rez, 'time(s)'
665 WRITE(*,*) 'Max residual computing test adjusted error measure was ', tmp_rez
666 WRITE(*,*) 'It should be up to O(M*N) times EPS, EPS = ', eps
667 nfail_total = nfail_total + nfail_rez
668 END IF
669 IF ( nfail_total == 0 ) THEN
670 WRITE(*,*) '>>>> CGEDMD :: ALL TESTS PASSED.'
671 ELSE
672 WRITE(*,*) nfail_total, 'FAILURES!'
673 WRITE(*,*) '>>>>>>>>>>>>>> CGEDMD :: TESTS FAILED. CHECK THE IMPLEMENTATION.'
674 END IF
675
676 WRITE(*,*)
677 WRITE(*,*) '>>>>>>>>>>>>>>>>>>>>>>>>>>'
678 WRITE(*,*) ' Test summary for CGEDMDQ :'
679 WRITE(*,*) '>>>>>>>>>>>>>>>>>>>>>>>>>>'
680 WRITE(*,*)
681
682 IF ( nfail_svdiff == 0 ) THEN
683 WRITE(*,*) '>>>> CGEDMD and CGEDMDQ computed singular &
684 &values test PASSED.'
685 ELSE
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 ', svdiff
690 WRITE(*,*) 'It should be up to O(M*N) times EPS, EPS = ', eps
691 nfailq_total = nfailq_total + nfail_svdiff
692 END IF
693 IF ( nfail_f_qr == 0 ) THEN
694 WRITE(*,*) '>>>> F - Q*R test PASSED.'
695 ELSE
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
700 END IF
701
702 IF ( nfail_rezq == 0 ) THEN
703 WRITE(*,*) '>>>> Rezidual computation test PASSED.'
704 ELSE
705 WRITE(*,*) 'Rezidual computation test FAILED ', nfail_rezq, 'time(s)'
706 WRITE(*,*) 'Max residual computing test adjusted error measure was ', tmp_rezq
707 WRITE(*,*) 'It should be up to O(M*N) times EPS, EPS = ', eps
708 nfailq_total = nfailq_total + nfail_rezq
709 END IF
710
711 IF ( nfailq_total == 0 ) THEN
712 WRITE(*,*) '>>>>>>> CGEDMDQ :: ALL TESTS PASSED.'
713 ELSE
714 WRITE(*,*) nfailq_total, 'FAILURES!'
715 WRITE(*,*) '>>>>>>> CGEDMDQ :: TESTS FAILED. CHECK THE IMPLEMENTATION.'
716 END IF
717
718 WRITE(*,*)
719 WRITE(*,*) 'Test completed.'
720 stop
721 END
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
Definition clatmr.f:490
subroutine caxpy(n, ca, cx, incx, cy, incy)
CAXPY
Definition caxpy.f:88
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.
Definition cgedmdq.f90:558
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.
Definition cgedmd.f90:501
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
Definition cgeev.f:180
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
Definition cgemm.f:188
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
Definition cgemv.f:160
integer function icamax(n, cx, incx)
ICAMAX
Definition icamax.f:71
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
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 ...
Definition clange.f:115
subroutine clarnv(idist, iseed, n, x)
CLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition clarnv.f:99
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.
Definition clascl.f:143
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
real(wp) function scnrm2(n, x, incx)
SCNRM2
Definition scnrm2.f90:90