When using r2c and c2r FFTW in Fortran, are the forward and backward dimensions same?

删除回忆录丶 提交于 2019-12-02 07:50:10
roygvib

One issue may be that dfftw_execute_dft_c2r can destroy the content of the input array, as described in this page. The key excerpt is

FFTW_PRESERVE_INPUT specifies that an out-of-place transform must not change its input array. This is ordinarily the default, except for c2r and hc2r (i.e. complex-to-real) transforms for which FFTW_DESTROY_INPUTis the default...

We can verify this, for example, by modifying the sample code by @VladimirF such that it saves data_out to data_save right after the first FFT(r2c) call, and then calculating their difference after the second FFT (c2r) call. So, in the case of OP's code, it seems safer to save output1 and output2 to different arrays before entering the second FFT (c2r).

First, although you claim your example is minimal, it is still pretty large, I have no time to study it.

But I updated my gist code https://gist.github.com/LadaF/73eb430682ef527eea9972ceb96116c5 to show also the backward transform and to answer the title question about the transform dimensions.

The logical size of the transform is the size of the real array (Real-data DFT Array Format) but the complex part is smaller due to inherent symmetries.

But when you make first r2c transform from real array of size n to complex array of size n/2+1. and then an opposite transform back, the real array should be again of size n.

This is my minimal example from the gist:

module FFTW3
  use, intrinsic :: iso_c_binding
  include "fftw3.f03"
end module

    use FFTW3
    implicit none

    integer, parameter :: n = 100

    real(c_double), allocatable :: data_in(:)
    complex(c_double_complex), allocatable :: data_out(:)
    type(c_ptr) :: planf, planb

    allocate(data_in(n))
    allocate(data_out(n/2+1))

    call random_number(data_in)

    planf = fftw_plan_dft_r2c_1d(size(data_in), data_in, data_out, FFTW_ESTIMATE+FFTW_UNALIGNED)
    planb = fftw_plan_dft_c2r_1d(size(data_in), data_out, data_in, FFTW_ESTIMATE+FFTW_UNALIGNED)

    print *, "real input:", real(data_in)

    call fftw_execute_dft_r2c(planf, data_in, data_out)

    print *, "result real part:", real(data_out)

    print *, "result imaginary part:", aimag(data_out)

    call fftw_execute_dft_c2r(planb, data_out, data_in)

    print *, "real output:", real(data_in)/n

    call fftw_destroy_plan(planf)
    call fftw_destroy_plan(planb)
end

Note that I am using the modern Fortran interface. I don't like using the old one.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!