1 subroutine da_eof_decomposition_test (kz, bx, e, l)
3 !------------------------------------------------------------------------------
5 ! [1] Print eigenvalues:
6 ! [2] Test orthogonality of eigenvectors - sum_k (e_m(k) e_n(k)) = delta_mn:
7 ! [3] Test eigenvectors completeness - sum_m (e_m(k1) e_m(k2)) = delta_k1k2:
8 ! [4] Check B correctness: B = E*L*E^T
9 !------------------------------------------------------------------------------
13 integer, intent(in) :: kz ! Dimension of BE matrix
14 real, intent(in) :: bx(1:kz,1:kz) ! Global vert. background error.
15 real*8, intent(in) :: e(1:kz,1:kz) ! Eigenvectors of Bx.
16 real*8, intent(in) :: l(1:kz) ! Eigenvalues of Bx.
18 integer :: k, k1, k2, m ! Loop counters
19 real :: tot_variance ! Total variance.
20 real :: cum_variance ! Cumulative variance.
21 real :: max_off_diag ! Maximum off-diagonal.
23 real :: work(1:kz,1:kz) ! 2D Work matrix.
24 real :: bc(1:kz,1:kz) ! 2D Work matrix.
25 logical :: array_mask(1:kz) ! Array mask for MAXVAL.
27 if (trace_use) call da_trace_entry("da_eof_decomposition_test")
29 !-------------------------------------------------------------------------
30 ! [1] Print eigenvalues:
31 !-------------------------------------------------------------------------
33 tot_variance = sum(l(1:kz))
36 write(unit=stdout,fmt='(A)')' Mode Eigenvalue Cumulative Variance e(k,k)'
39 cum_variance = cum_variance + l(k)
40 write(unit=stdout,fmt='(I4,4x,e12.4,10x,f8.4,4x,e12.4)') &
41 k, l(k), cum_variance / tot_variance, e(k,k)
44 write(unit=stdout,fmt=*)
46 call da_array_print( 1, e, 'Global Eigenvectors' )
48 !-------------------------------------------------------------------------
49 ! [2] Test orthogonality of eigenvectors - sum_k (e_m(k) e_n(k)) = delta_mn:
50 !-------------------------------------------------------------------------
52 write(unit=stdout,fmt='(A)')' Eigenvector orthogonality check:'
53 write(unit=stdout,fmt='(A)')' Mode Diagonal Maximum off-diagonal'
57 work(k1,k2) = sum(e(1:kz,k1) * e(1:kz,k2))
60 array_mask(1:kz) =.true.
61 array_mask(k1) = .false.
62 max_off_diag = maxval(abs(work(k1,:)),mask=array_mask(:))
63 write(unit=stdout,fmt='(I4,4x,1pe12.4,10x,1pe12.4)')k1, work(k1,k1), max_off_diag
65 write(unit=stdout,fmt=*)
67 !-------------------------------------------------------------------------
68 ! [3] Test eigenvectors completeness - sum_m (e_m(k1) e_m(k2)) = delta_k1k2:
69 !-------------------------------------------------------------------------
71 write(unit=stdout,fmt='(A)')' Eigenvector completeness check:'
72 write(unit=stdout,fmt='(A)')' Level Diagonal Maximum off-diagonal'
76 work(k1,k2) = sum(e(k1,1:kz) * e(k2,1:kz))
79 array_mask(1:kz) =.true.
80 array_mask(k1) = .false.
81 max_off_diag = maxval(abs(work(k1,:)),mask=array_mask(:))
82 write(unit=stdout,fmt='(I4,4x,1pe12.4,10x,1pe12.4)')k1, work(k1,k1), max_off_diag
84 write(unit=stdout,fmt=*)
86 !-------------------------------------------------------------------------
87 ! [4] check B correctness: B = E*L*E^T
88 !-------------------------------------------------------------------------
90 write(unit=stdout,fmt='(a/a)') &
91 'real and Calculated B (diagonal)', &
92 'lvl real-B Calculated-B'
104 bc(k1,k2)=bc(k1,k2)+e(k1,m)*work(m,k2)
108 write(unit=stdout,fmt='(I5,2F20.5)') k1, bx(k1,k1), bc(k1,k1)
112 write(unit=stdout, fmt='(a,i4/a)') &
113 'real and Calculated B (off diagonal):', k2, &
114 'lvl real-B Calculated-B'
117 write(unit=stdout,fmt='(I5,2F20.5)') k1, bx(k1,k2), bc(k1,k2)
121 if (trace_use) call da_trace_exit("da_eof_decomposition_test")
123 end subroutine da_eof_decomposition_test