-
Notifications
You must be signed in to change notification settings - Fork 19
Open
Description
In many codes that use FFTs and the Fourier domain one need to alternatively work on the same array as real or as complex numbers. Different tricks have to used, none being really satisfactory, e.g.:
real, allocatable :: r(:)
! ...
! some computations on r(:)...
call rfft(r) ! real to complex in-place transform
call compute_complex(r,size(r)) ! this routine MUST NOT have any interface !!!
call irfft(r) ! complex to real in-place inverse transform
! ...
subroutine compute_complex(c,n)
complex :: c(n/2)
! some computations on c(:)
end subroutine
Instead, the standard should provide a way to have a complex pointer to a real array:
real, allocatable, target :: r(:)
complex, pointer :: c(:)
! ...
! some computations on r(:)...
call rfft(r) ! real to complex in-place transform
c => cmplx_pointer(r)
! some computations on c(:)...
call irfft(r) ! complex to real in-place inverse transform
! ...
And vice-versa
complex, allocatable, target :: c(:)
real, pointer :: r(:)
! ...
r => real_pointer(c)
! some computations on r(:)...
call rfft(r) ! real to complex in-place transform
! some computations on c(:)...
call irfft(r) ! complex to real in-place inverse transform
! ...
Of course some constraints would be needed:
- the size of the real array in the first dimension shall be even
- the real or complex array shall have a unit stride along the first dimension (forcing the whole array to be contiguous could be desirable, so that the compiler could catch the error at compile-time)
c(:)%re
shall be equivalent tor(1::2)
andc(:)%im
shall be equivalent tor(2::2)
, which enforces the real component to be stored first (de-facto standard in all compilers that I know).
certik and Fravadona
Metadata
Metadata
Assignees
Labels
No labels