Note
Function that returns the acf of an array.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=R8), | intent(in), | dimension(1:w, 1:h) | :: | tab_in |
input array |
|
real(kind=R8), | intent(out), | dimension(1:w, 1:h) | :: | tab_out |
acf of the input array |
|
integer(kind=I4), | intent(in) | :: | w |
2D array length |
||
integer(kind=I4), | intent(in) | :: | h |
2D array width |
||
logical(kind=I4), | intent(in), | optional | :: | multi_fft |
run parallel acfs? |
subroutine acf_wiener(tab_in, tab_out, w, h, multi_fft) !================================================================================================ !<@note Function that returns the *acf* of an array. !< \[ !< \begin{align*} !< acf(i,j) &= (z \ast z)(i,j) = \sum_{k,l}^{n,n} z(k+1-i,l+1-j)z(k,l) \\ !< TF(acf) &= ACF = Z \cdot Z \\ !< acf &= TF^{-1}(ACF) = TF^{-1}(Z^2) !< \end{align*} !< \] !< !<@endnote !------------------------------------------------------------------------------------------------ implicit none integer(kind=I4), intent(in ) :: w !! *2D array length* integer(kind=I4), intent(in ) :: h !! *2D array width* real (kind=R8), intent(in ), dimension(1:w, 1:h) :: tab_in !! *input array* real (kind=R8), intent(out), dimension(1:w, 1:h) :: tab_out !! *acf of the input array* logical(kind=I4), intent(in ), optional :: multi_fft !! *run parallel acfs?* integer(kind=I4) :: lo2, la2 real (kind=R8) :: tmp logical(kind=I4) :: parallel_fft integer(kind=I4), dimension(1:2) :: loc_max complex(kind=R8), dimension(:,:), allocatable :: tab_cmpl real (kind=R8), dimension(:,:), allocatable :: tab_real allocate( tab_cmpl(1:w, 1:h) ) allocate( tab_real(1:w, 1:h) ) ! check for simultaneous fftw calculations !......................................... parallel_fft = .false. if ( present(multi_fft) ) parallel_fft = multi_fft !......................................... ! DFFT real -> complex !......................................... if ( parallel_fft ) then call tab_calc_fftw3_real_fwd( tab_in = tab_in (1:w, 1:h), & ! IN tab_ou = tab_cmpl(1:w, 1:h), & ! OUT long = w, & ! IN larg = h ) ! IN else call calc_fftw3_real_fwd( tab_in = tab_in (1:w, 1:h), & ! IN tab_ou = tab_cmpl(1:w, 1:h), & ! OUT long = w, & ! IN larg = h, & ! IN planner_flag = FFTW_MEASURE ) ! IN endif !......................................... tab_cmpl(1:w, 1:h) = cmplx( abs( tab_cmpl(1:w, 1:h) )**2, 0, kind = R8 ) ! IFFT complex -> real !......................................... if ( parallel_fft ) then call tab_calc_fftw3_real_bwd( tab_in = tab_cmpl(1:w, 1:h), & ! IN tab_ou = tab_real(1:w, 1:h), & ! OUT long = w, & ! IN larg = h ) ! IN else call calc_fftw3_real_bwd( tab_in = tab_cmpl(1:w, 1:h), & ! IN tab_ou = tab_real(1:w, 1:h), & ! OUT long = w, & ! IN larg = h, & ! IN planner_flag = FFTW_MEASURE ) ! IN endif !......................................... ! the maximum is placed in the array center !......................................... call trans_corner2center( tab_in = tab_real(1:w, 1:h), & ! IN tab_out = tab_out (1:w, 1:h), & ! OUT long = w, & ! IN larg = h ) ! IN !......................................... ! the maximum is 1 !......................................... loc_max(1:2) = maxloc( tab_out(1:w, 1:h) ) lo2 = loc_max(1) la2 = loc_max(2) tmp = tab_out(lo2, la2) tab_out(1:w, 1:h) = tab_out(1:w, 1:h) / tmp !......................................... deallocate(tab_cmpl) deallocate(tab_real) return endsubroutine acf_wiener