Skip to content

Commit 8151076

Browse files
authored
Merge pull request #48 from fortran-lang/add-rfft-example
Add example of the transform of a closed-form real function
2 parents 02e7e57 + 7fe21d1 commit 8151076

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

example/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
add_executable(bench1 bench1.f90)
2-
target_link_libraries(bench1 fftpack)
1+
add_executable(bench1 bench01_zfft.f90)
2+
target_link_libraries(bench1 fftpack)
3+
4+
add_executable(bench2 bench02_zfft.f90)
5+
target_link_libraries(bench2 fftpack)
6+
7+
add_executable(bench3 bench03_dfft.f90)
8+
target_link_libraries(bench3 fftpack)
9+
10+
add_executable(rfft_example)
11+
target_link_libraries(rfft_example fftpack)

example/real-forward-transform.f90

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,51 @@
11
program forward_transform_of_real_function
2-
!! This program computes the forward transform of a real function and constructs
3-
!! the complex result (re)organized to match the array subscripting to the common
4-
!! analytical form [1]. Which form one uses in practice requires balancing the
5-
!! need for speed versus clarity.
2+
!! This program invokes fftpack's rrft function to compute the forward transform of a real function
3+
!! and constructs the resulting complex Fourier coefficients by (re)organizing and normalizing the
4+
!! rfft result according to array element layout described at [1]. The program also demonstrates
5+
!! the inverse transform of the raw rrft result to recover the original function.
66
!!
77
!! [1] https://docs.scipy.org/doc/scipy/reference/generated/scipy.fftpack.rfft.html#scipy.fftpack.rfft
88
use fftpack, only: rfft, irfft
99
implicit none
1010
integer j, k
1111
integer, parameter :: N = 8
1212
double precision, parameter :: two_pi = 2.D0*acos(-1.D0), tolerance = 1.0D-06, f_avg = 3.D0, zero=0.D0
13-
double precision, parameter :: f(0:N-1) = f_avg + [(cos(two_pi*dble(j)/dble(N)), j=0,N-1)]
13+
double precision, parameter :: x(0:N-1) = [(two_pi*dble(j)/dble(N), j=0,N-1)]
14+
double precision, parameter :: f(0:N-1) = f_avg + cos(x)
15+
!! sample f(x) = 3 + cos(x) uniformly on [0,2*pi)
16+
!! = 3 + (exp(i*x) - exp(-i*x))/2
17+
!! which yields the Fourier coefficients
18+
!! { 3, k = 0
19+
!! f_hat = { 1/2, k = 1
20+
!! { 0, otherwise
1421
double precision, dimension(0:N-1) :: f_round_trip, rfft_f
1522
integer, parameter :: rk = kind(two_pi)
1623
complex(rk) f_hat(0:N/2)
24+
character(len=*), parameter :: real_format = "(a,*(g10.4,:,1x))" !! space-separated values
25+
character(len=*), parameter :: complex_format= "(a,*('(',g10.4,',',g10.4,')',:,1x)))" !! space-separated complex values
1726

1827
call assert(mod(N,2)==0, "the algorithm below requires even N")
1928

2029
rfft_f(:) = rfft(f)/dble(N)
21-
f_hat(:) = [ cmplx(rfft_f(0),zero), [( cmplx(k,k+1), k=lbound(rfft_f,1)+1,ubound(rfft_f,1)-1,2)], cmplx(zero,rfft_f(N-1)) ]
22-
f_round_trip(:) = dble(irfft(rfft_f))
23-
!call assert(any(abs(f_round_trip - f) < tolerance), "inverse of forward FFT must yield the original function")
30+
f_hat(:) = [ &
31+
cmplx(rfft_f(0),zero), &
32+
[( cmplx(rfft_f(k),rfft_f(k+1)), k=lbound(rfft_f,1)+1,ubound(rfft_f,1)-1,2)], &
33+
cmplx(zero,rfft_f(N-1)) &
34+
]
35+
f_round_trip(:) = irfft(rfft_f)
2436

25-
print *, "f = ", f
26-
print *, "f_hat = ", f_hat
27-
print *, "f_round_trip = ", f_round_trip
37+
print real_format, "f = ", f
38+
print complex_format, "f_hat = ", f_hat
39+
print real_format, "f_round_trip = ",f_round_trip
2840

29-
!print '(3(10x,a,10x))',"f", "f_round_trip", "rfft_f"
30-
!do m = 1, size(f)
31-
! print *, f(m), f_round_trip(m), rfft_f(m)
32-
!end do
33-
!print *
41+
call assert(all(abs(f_round_trip - f) < tolerance), "inverse of forward FFT must yield the original function")
3442

3543
contains
44+
3645
pure subroutine assert(assertion, description)
3746
logical, intent(in) :: assertion
3847
character(len=*), intent(in) :: description
3948
if (.not. assertion) error stop description
4049
end subroutine
50+
4151
end program

fpm.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
name = "fftpack"
32
description = "A package of fortran subprograms for the fast fourier transform of periodic and other symmetric sequences"
43
homepage = "http://www.netlib.org/fftpack/"
@@ -15,6 +14,11 @@ implicit-typing=true
1514
implicit-external=true
1615
source-form="default"
1716

17+
[build]
18+
auto-executables = false
19+
auto-tests = true
20+
auto-examples = true
21+
1822
[dev-dependencies]
1923
test-drive = { git = "https://github.com/fortran-lang/test-drive", tag = "v0.4.0" }
2024

0 commit comments

Comments
 (0)