lilsalsa74
Programmer
I am a complete beginner at programming and using Fortran. I am actually a Physics major and I am trying to learn more about Fourier Transforms. I have been looking at Ooura's 1-D DFT program and it compiles but does not give an output of the Fourier Transform. How would I do this?
(Also, Dr. Ooura said on his site that it was OK to copy and use his program. Besides, I am merely using this as an educational tool.)
Here is the program:
! Fast Fourier/Cosine/Sine Transform
! dimension ne
! data length ower of 2
! decimation :frequency
! radix :2
! data :inplace
! table :not use
! -------- Complex DFT (Discrete Fourier Transform) --------
! [definition]
! <case1>
! X(k) = sum_j=0^n-1 x(j)*exp(2*pi*i*j*k/n), 0<=k<n
! <case2>
! X(k) = sum_j=0^n-1 x(j)*exp(-2*pi*i*j*k/n), 0<=k<n
! (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
! [usage]
! <case1>
! call cdft(2*n, cos(pi/n), sin(pi/n), a)
! <case2>
! call cdft(2*n, cos(pi/n), -sin(pi/n), a)
! [parameters]
! 2*n :data length (integer)
! n >= 1, n = power of 2
! a(0:2*n-1) :input/output data (real*8)
! input data
! a(2*j) = Re(x(j)), a(2*j+1) = Im(x(j)), 0<=j<n
! output data
! a(2*k) = Re(X(k)), a(2*k+1) = Im(X(k)), 0<=k<n
! [remark]
! Inverse of
! call cdft(2*n, cos(pi/n), -sin(pi/n), a)
! is
! call cdft(2*n, cos(pi/n), sin(pi/n), a)
! do j = 0, 2 * n - 1
! a(j) = a(j) / n
! end do
subroutine cdft(n, wr, wi, a)
integer n, i, j, k, l, m
real*8 wr, wi, a(0 : n - 1), wmr, wmi, wkr, wki, wdr, wdi,
& ss, xr, xi
wmr = wr
wmi = wi
m = n
do while (m .gt. 4)
l = m / 2
wkr = 1
wki = 0
wdr = 1 - 2 * wmi * wmi
wdi = 2 * wmi * wmr
ss = 2 * wdi
wmr = wdr
wmi = wdi
do j = 0, n - m, m
i = j + l
xr = a(j) - a(i)
xi = a(j + 1) - a(i + 1)
a(j) = a(j) + a(i)
a(j + 1) = a(j + 1) + a(i + 1)
a(i) = xr
a(i + 1) = xi
xr = a(j + 2) - a(i + 2)
xi = a(j + 3) - a(i + 3)
a(j + 2) = a(j + 2) + a(i + 2)
a(j + 3) = a(j + 3) + a(i + 3)
a(i + 2) = wdr * xr - wdi * xi
a(i + 3) = wdr * xi + wdi * xr
end do
do k = 4, l - 4, 4
wkr = wkr - ss * wdi
wki = wki + ss * wdr
wdr = wdr - ss * wki
wdi = wdi + ss * wkr
do j = k, n - m + k, m
i = j + l
xr = a(j) - a(i)
xi = a(j + 1) - a(i + 1)
a(j) = a(j) + a(i)
a(j + 1) = a(j + 1) + a(i + 1)
a(i) = wkr * xr - wki * xi
a(i + 1) = wkr * xi + wki * xr
xr = a(j + 2) - a(i + 2)
xi = a(j + 3) - a(i + 3)
a(j + 2) = a(j + 2) + a(i + 2)
a(j + 3) = a(j + 3) + a(i + 3)
a(i + 2) = wdr * xr - wdi * xi
a(i + 3) = wdr * xi + wdi * xr
end do
end do
m = l
end do
if (m .gt. 2) then
do j = 0, n - 4, 4
xr = a(j) - a(j + 2)
xi = a(j + 1) - a(j + 3)
a(j) = a(j) + a(j + 2)
a(j + 1) = a(j + 1) + a(j + 3)
a(j + 2) = xr
a(j + 3) = xi
end do
end if
if (n .gt. 4) call bitrv2(n, a)
end
subroutine bitrv2(n, a)
integer n, j, j1, k, k1, l, m, m2, n2
real*8 a(0 : n - 1), xr, xi
m = n / 4
m2 = 2 * m
n2 = n - 2
k = 0
do j = 0, m2 - 4, 4
if (j .lt. k) then
xr = a(j)
xi = a(j + 1)
a(j) = a(k)
a(j + 1) = a(k + 1)
a(k) = xr
a(k + 1) = xi
else if (j .gt. k) then
j1 = n2 - j
k1 = n2 - k
xr = a(j1)
xi = a(j1 + 1)
a(j1) = a(k1)
a(j1 + 1) = a(k1 + 1)
a(k1) = xr
a(k1 + 1) = xi
end if
k1 = m2 + k
xr = a(j + 2)
xi = a(j + 3)
a(j + 2) = a(k1)
a(j + 3) = a(k1 + 1)
a(k1) = xr
a(k1 + 1) = xi
l = m
do while (k .ge. l)
k = k - l
l = l / 2
end do
k = k + l
end do
end
(Also, Dr. Ooura said on his site that it was OK to copy and use his program. Besides, I am merely using this as an educational tool.)
Here is the program:
! Fast Fourier/Cosine/Sine Transform
! dimension ne
! data length ower of 2
! decimation :frequency
! radix :2
! data :inplace
! table :not use
! -------- Complex DFT (Discrete Fourier Transform) --------
! [definition]
! <case1>
! X(k) = sum_j=0^n-1 x(j)*exp(2*pi*i*j*k/n), 0<=k<n
! <case2>
! X(k) = sum_j=0^n-1 x(j)*exp(-2*pi*i*j*k/n), 0<=k<n
! (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
! [usage]
! <case1>
! call cdft(2*n, cos(pi/n), sin(pi/n), a)
! <case2>
! call cdft(2*n, cos(pi/n), -sin(pi/n), a)
! [parameters]
! 2*n :data length (integer)
! n >= 1, n = power of 2
! a(0:2*n-1) :input/output data (real*8)
! input data
! a(2*j) = Re(x(j)), a(2*j+1) = Im(x(j)), 0<=j<n
! output data
! a(2*k) = Re(X(k)), a(2*k+1) = Im(X(k)), 0<=k<n
! [remark]
! Inverse of
! call cdft(2*n, cos(pi/n), -sin(pi/n), a)
! is
! call cdft(2*n, cos(pi/n), sin(pi/n), a)
! do j = 0, 2 * n - 1
! a(j) = a(j) / n
! end do
subroutine cdft(n, wr, wi, a)
integer n, i, j, k, l, m
real*8 wr, wi, a(0 : n - 1), wmr, wmi, wkr, wki, wdr, wdi,
& ss, xr, xi
wmr = wr
wmi = wi
m = n
do while (m .gt. 4)
l = m / 2
wkr = 1
wki = 0
wdr = 1 - 2 * wmi * wmi
wdi = 2 * wmi * wmr
ss = 2 * wdi
wmr = wdr
wmi = wdi
do j = 0, n - m, m
i = j + l
xr = a(j) - a(i)
xi = a(j + 1) - a(i + 1)
a(j) = a(j) + a(i)
a(j + 1) = a(j + 1) + a(i + 1)
a(i) = xr
a(i + 1) = xi
xr = a(j + 2) - a(i + 2)
xi = a(j + 3) - a(i + 3)
a(j + 2) = a(j + 2) + a(i + 2)
a(j + 3) = a(j + 3) + a(i + 3)
a(i + 2) = wdr * xr - wdi * xi
a(i + 3) = wdr * xi + wdi * xr
end do
do k = 4, l - 4, 4
wkr = wkr - ss * wdi
wki = wki + ss * wdr
wdr = wdr - ss * wki
wdi = wdi + ss * wkr
do j = k, n - m + k, m
i = j + l
xr = a(j) - a(i)
xi = a(j + 1) - a(i + 1)
a(j) = a(j) + a(i)
a(j + 1) = a(j + 1) + a(i + 1)
a(i) = wkr * xr - wki * xi
a(i + 1) = wkr * xi + wki * xr
xr = a(j + 2) - a(i + 2)
xi = a(j + 3) - a(i + 3)
a(j + 2) = a(j + 2) + a(i + 2)
a(j + 3) = a(j + 3) + a(i + 3)
a(i + 2) = wdr * xr - wdi * xi
a(i + 3) = wdr * xi + wdi * xr
end do
end do
m = l
end do
if (m .gt. 2) then
do j = 0, n - 4, 4
xr = a(j) - a(j + 2)
xi = a(j + 1) - a(j + 3)
a(j) = a(j) + a(j + 2)
a(j + 1) = a(j + 1) + a(j + 3)
a(j + 2) = xr
a(j + 3) = xi
end do
end if
if (n .gt. 4) call bitrv2(n, a)
end
subroutine bitrv2(n, a)
integer n, j, j1, k, k1, l, m, m2, n2
real*8 a(0 : n - 1), xr, xi
m = n / 4
m2 = 2 * m
n2 = n - 2
k = 0
do j = 0, m2 - 4, 4
if (j .lt. k) then
xr = a(j)
xi = a(j + 1)
a(j) = a(k)
a(j + 1) = a(k + 1)
a(k) = xr
a(k + 1) = xi
else if (j .gt. k) then
j1 = n2 - j
k1 = n2 - k
xr = a(j1)
xi = a(j1 + 1)
a(j1) = a(k1)
a(j1 + 1) = a(k1 + 1)
a(k1) = xr
a(k1 + 1) = xi
end if
k1 = m2 + k
xr = a(j + 2)
xi = a(j + 3)
a(j + 2) = a(k1)
a(j + 3) = a(k1 + 1)
a(k1) = xr
a(k1 + 1) = xi
l = m
do while (k .ge. l)
k = k - l
l = l / 2
end do
k = k + l
end do
end