Create an exponential filter matrix that can be used to filter out high-frequency noise.
The filter matrix is defined as where the diagonal matrix, has the entries for and the filter function, has the form Here , where is the machine precision in working precision, is the order of the element, is a cutoff, below which the low modes are left untouched and (has to be even) is the order of the filter.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=ip), | intent(in) | :: | n | The order of the element. |
||
integer(kind=ip), | intent(in) | :: | nc | The cutoff, below which the low modes are left untouched. |
||
integer(kind=ip), | intent(in) | :: | s | The order of the filter. |
||
real(kind=wp), | intent(in), | dimension(:,:) | :: | v | The Vandermonde matrix, . |
|
real(kind=wp), | intent(in), | dimension(:,:) | :: | invv | The inverse of the Vandermonde matric, . |
The return value is the filter matrix, .
function Filter1D ( n, nc, s, v, invv )
!! Create an exponential filter matrix that can be used to filter out
!! high-frequency noise.
!!
!! The filter matrix \(\mathcal{F}\) is defined as \(\mathcal{F}=
!! \mathcal{V}\Lambda\mathcal{V}^{-1}\) where the diagonal matrix,
!! \(\Lambda\) has the entries \(\Lambda_{ii}=\sigma(i-1)\) for
!! \(i=1,\ldots,n+1\) and the filter function, \(\sigma(i)\) has the form
!! \[
!! \sigma(i) =
!! \begin{cases}
!! 1 & 0\le i\le n_c \\
!! e^{-\alpha\left (\frac{i-n_c}{n-n_c}\right )^s} & n_c<i\le n.
!! \end{cases}
!! \]
!! Here \(\alpha=-\log(\epsilon_M)\), where \(\epsilon_M\) is the machine
!! precision in working precision, \(n\) is the order of the element,
!! \(n_c\) is a cutoff, below which the low modes are left untouched and
!! \(s\) (has to be even) is the order of the filter.
integer(ip), intent(in) :: n
!! The order of the element.
integer(ip), intent(in) :: nc
!! The cutoff, below which the low modes are left untouched.
integer(ip), intent(in) :: s
!! The order of the filter.
real(wp), dimension(:,:), intent(in) :: v
!! The Vandermonde matrix, \(\mathcal{V}\).
real(wp), dimension(:,:), intent(in) :: invv
!! The inverse of the Vandermonde matric, \(\mathcal{V}^{-1}\).
real(wp), dimension(n+1,n+1) :: Filter1D
!! The return value is the filter matrix, \(\mathcal{F}\).
real(wp), dimension(n+1,n+1) :: tmp
real(wp) :: alpha
integer(ip) :: i
alpha = -log(epsilon(1.0_wp))
Filter1D = 0.0_wp
forall(i=1:nc) Filter1D(i,i) = 1.0_wp
forall(i=nc:n) Filter1D(i+1,i+1) = exp(-alpha*(real(i-nc,wp)/real(n-nc,wp))**s)
! Filter1D = matmul(Filter1D,invv)
! Filter1D = matmul(v,Filter1D)
tmp = matmul(Filter1D,invv)
Filter1D = matmul(v,tmp)
return
end function Filter1D