blob: 6c52ff39ab4bb4831203f8b5525128900ee8a195 [file] [log] [blame]
! Fast Fourier/Cosine/Sine Transform
! dimension :one
! data length :power of 2
! decimation :frequency
! radix :4, 2
! data :inplace
! table :use
! subroutines
! cdft: Complex Discrete Fourier Transform
! rdft: Real Discrete Fourier Transform
! ddct: Discrete Cosine Transform
! ddst: Discrete Sine Transform
! dfct: Cosine Transform of RDFT (Real Symmetric DFT)
! dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
!
!
! -------- 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>
! ip(0) = 0 ! first time only
! call cdft(2*n, 1, a, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call cdft(2*n, -1, a, ip, w)
! [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
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n)
! strictly,
! length of ip >=
! 2+2**(int(log(n+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n/2-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call cdft(2*n, -1, a, ip, w)
! is
! call cdft(2*n, 1, a, ip, w)
! do j = 0, 2 * n - 1
! a(j) = a(j) / n
! end do
! .
!
!
! -------- Real DFT / Inverse of Real DFT --------
! [definition]
! <case1> RDFT
! R(k) = sum_j=0^n-1 a(j)*cos(2*pi*j*k/n), 0<=k<=n/2
! I(k) = sum_j=0^n-1 a(j)*sin(2*pi*j*k/n), 0<k<n/2
! <case2> IRDFT (excluding scale)
! a(k) = (R(0) + R(n/2)*cos(pi*k))/2 +
! sum_j=1^n/2-1 R(j)*cos(2*pi*j*k/n) +
! sum_j=1^n/2-1 I(j)*sin(2*pi*j*k/n), 0<=k<n
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call rdft(n, 1, a, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call rdft(n, -1, a, ip, w)
! [parameters]
! n :data length (integer)
! n >= 2, n = power of 2
! a(0:n-1) :input/output data (real*8)
! <case1>
! output data
! a(2*k) = R(k), 0<=k<n/2
! a(2*k+1) = I(k), 0<k<n/2
! a(1) = R(n/2)
! <case2>
! input data
! a(2*j) = R(j), 0<=j<n/2
! a(2*j+1) = I(j), 0<j<n/2
! a(1) = R(n/2)
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n/2)
! strictly,
! length of ip >=
! 2+2**(int(log(n/2+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n/2-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call rdft(n, 1, a, ip, w)
! is
! call rdft(n, -1, a, ip, w)
! do j = 0, n - 1
! a(j) = a(j) * 2 / n
! end do
! .
!
!
! -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
! [definition]
! <case1> IDCT (excluding scale)
! C(k) = sum_j=0^n-1 a(j)*cos(pi*j*(k+1/2)/n), 0<=k<n
! <case2> DCT
! C(k) = sum_j=0^n-1 a(j)*cos(pi*(j+1/2)*k/n), 0<=k<n
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call ddct(n, 1, a, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call ddct(n, -1, a, ip, w)
! [parameters]
! n :data length (integer)
! n >= 2, n = power of 2
! a(0:n-1) :input/output data (real*8)
! output data
! a(k) = C(k), 0<=k<n
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n/2)
! strictly,
! length of ip >=
! 2+2**(int(log(n/2+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n*5/4-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call ddct(n, -1, a, ip, w)
! is
! a(0) = a(0) / 2
! call ddct(n, 1, a, ip, w)
! do j = 0, n - 1
! a(j) = a(j) * 2 / n
! end do
! .
!
!
! -------- DST (Discrete Sine Transform) / Inverse of DST --------
! [definition]
! <case1> IDST (excluding scale)
! S(k) = sum_j=1^n A(j)*sin(pi*j*(k+1/2)/n), 0<=k<n
! <case2> DST
! S(k) = sum_j=0^n-1 a(j)*sin(pi*(j+1/2)*k/n), 0<k<=n
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call ddst(n, 1, a, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call ddst(n, -1, a, ip, w)
! [parameters]
! n :data length (integer)
! n >= 2, n = power of 2
! a(0:n-1) :input/output data (real*8)
! <case1>
! input data
! a(j) = A(j), 0<j<n
! a(0) = A(n)
! output data
! a(k) = S(k), 0<=k<n
! <case2>
! output data
! a(k) = S(k), 0<k<n
! a(0) = S(n)
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n/2)
! strictly,
! length of ip >=
! 2+2**(int(log(n/2+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n*5/4-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call ddst(n, -1, a, ip, w)
! is
! a(0) = a(0) / 2
! call ddst(n, 1, a, ip, w)
! do j = 0, n - 1
! a(j) = a(j) * 2 / n
! end do
! .
!
!
! -------- Cosine Transform of RDFT (Real Symmetric DFT) --------
! [definition]
! C(k) = sum_j=0^n a(j)*cos(pi*j*k/n), 0<=k<=n
! [usage]
! ip(0) = 0 ! first time only
! call dfct(n, a, t, ip, w)
! [parameters]
! n :data length - 1 (integer)
! n >= 2, n = power of 2
! a(0:n) :input/output data (real*8)
! output data
! a(k) = C(k), 0<=k<=n
! t(0:n/2) :work area (real*8)
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n/4)
! strictly,
! length of ip >=
! 2+2**(int(log(n/4+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n*5/8-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! a(0) = a(0) / 2
! a(n) = a(n) / 2
! call dfct(n, a, t, ip, w)
! is
! a(0) = a(0) / 2
! a(n) = a(n) / 2
! call dfct(n, a, t, ip, w)
! do j = 0, n
! a(j) = a(j) * 2 / n
! end do
! .
!
!
! -------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
! [definition]
! S(k) = sum_j=1^n-1 a(j)*sin(pi*j*k/n), 0<k<n
! [usage]
! ip(0) = 0 ! first time only
! call dfst(n, a, t, ip, w)
! [parameters]
! n :data length + 1 (integer)
! n >= 2, n = power of 2
! a(0:n-1) :input/output data (real*8)
! output data
! a(k) = S(k), 0<k<n
! (a(0) is used for work area)
! t(0:n/2-1) :work area (real*8)
! ip(0:*) :work area for bit reversal (integer)
! length of ip >= 2+sqrt(n/4)
! strictly,
! length of ip >=
! 2+2**(int(log(n/4+0.5)/log(2.0))/2).
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:n*5/8-1) :cos/sin table (real*8)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call dfst(n, a, t, ip, w)
! is
! call dfst(n, a, t, ip, w)
! do j = 1, n - 1
! a(j) = a(j) * 2 / n
! end do
! .
!
!
! Appendix :
! The cos/sin table is recalculated when the larger table required.
! w() and ip() are compatible with all routines.
!
!
subroutine cdft(n, isgn, a, ip, w)
integer n, isgn, ip(0 : *)
real*8 a(0 : n - 1), w(0 : *)
if (n .gt. 4 * ip(0)) then
call makewt(n / 4, ip, w)
end if
if (n .gt. 4) then
if (isgn .ge. 0) then
call bitrv2(n, ip(2), a)
call cftfsub(n, a, w)
else
call bitrv2conj(n, ip(2), a)
call cftbsub(n, a, w)
end if
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
end
!
subroutine rdft(n, isgn, a, ip, w)
integer n, isgn, ip(0 : *), nw, nc
real*8 a(0 : n - 1), w(0 : *), xi
nw = ip(0)
if (n .gt. 4 * nw) then
nw = n / 4
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n .gt. 4 * nc) then
nc = n / 4
call makect(nc, ip, w(nw))
end if
if (isgn .ge. 0) then
if (n .gt. 4) then
call bitrv2(n, ip(2), a)
call cftfsub(n, a, w)
call rftfsub(n, a, nc, w(nw))
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
xi = a(0) - a(1)
a(0) = a(0) + a(1)
a(1) = xi
else
a(1) = 0.5d0 * (a(0) - a(1))
a(0) = a(0) - a(1)
if (n .gt. 4) then
call rftbsub(n, a, nc, w(nw))
call bitrv2(n, ip(2), a)
call cftbsub(n, a, w)
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
end if
end
!
subroutine ddct(n, isgn, a, ip, w)
integer n, isgn, ip(0 : *), j, nw, nc
real*8 a(0 : n - 1), w(0 : *), xr
nw = ip(0)
if (n .gt. 4 * nw) then
nw = n / 4
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n .gt. nc) then
nc = n
call makect(nc, ip, w(nw))
end if
if (isgn .lt. 0) then
xr = a(n - 1)
do j = n - 2, 2, -2
a(j + 1) = a(j) - a(j - 1)
a(j) = a(j) + a(j - 1)
end do
a(1) = a(0) - xr
a(0) = a(0) + xr
if (n .gt. 4) then
call rftbsub(n, a, nc, w(nw))
call bitrv2(n, ip(2), a)
call cftbsub(n, a, w)
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
end if
call dctsub(n, a, nc, w(nw))
if (isgn .ge. 0) then
if (n .gt. 4) then
call bitrv2(n, ip(2), a)
call cftfsub(n, a, w)
call rftfsub(n, a, nc, w(nw))
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
xr = a(0) - a(1)
a(0) = a(0) + a(1)
do j = 2, n - 2, 2
a(j - 1) = a(j) - a(j + 1)
a(j) = a(j) + a(j + 1)
end do
a(n - 1) = xr
end if
end
!
subroutine ddst(n, isgn, a, ip, w)
integer n, isgn, ip(0 : *), j, nw, nc
real*8 a(0 : n - 1), w(0 : *), xr
nw = ip(0)
if (n .gt. 4 * nw) then
nw = n / 4
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n .gt. nc) then
nc = n
call makect(nc, ip, w(nw))
end if
if (isgn .lt. 0) then
xr = a(n - 1)
do j = n - 2, 2, -2
a(j + 1) = -a(j) - a(j - 1)
a(j) = a(j) - a(j - 1)
end do
a(1) = a(0) + xr
a(0) = a(0) - xr
if (n .gt. 4) then
call rftbsub(n, a, nc, w(nw))
call bitrv2(n, ip(2), a)
call cftbsub(n, a, w)
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
end if
call dstsub(n, a, nc, w(nw))
if (isgn .ge. 0) then
if (n .gt. 4) then
call bitrv2(n, ip(2), a)
call cftfsub(n, a, w)
call rftfsub(n, a, nc, w(nw))
else if (n .eq. 4) then
call cftfsub(n, a, w)
end if
xr = a(0) - a(1)
a(0) = a(0) + a(1)
do j = 2, n - 2, 2
a(j - 1) = -a(j) - a(j + 1)
a(j) = a(j) - a(j + 1)
end do
a(n - 1) = -xr
end if
end
!
subroutine dfct(n, a, t, ip, w)
integer n, ip(0 : *), j, k, l, m, mh, nw, nc
real*8 a(0 : n), t(0 : n / 2), w(0 : *), xr, xi, yr, yi
nw = ip(0)
if (n .gt. 8 * nw) then
nw = n / 8
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n .gt. 2 * nc) then
nc = n / 2
call makect(nc, ip, w(nw))
end if
m = n / 2
yi = a(m)
xi = a(0) + a(n)
a(0) = a(0) - a(n)
t(0) = xi - yi
t(m) = xi + yi
if (n .gt. 2) then
mh = m / 2
do j = 1, mh - 1
k = m - j
xr = a(j) - a(n - j)
xi = a(j) + a(n - j)
yr = a(k) - a(n - k)
yi = a(k) + a(n - k)
a(j) = xr
a(k) = yr
t(j) = xi - yi
t(k) = xi + yi
end do
t(mh) = a(mh) + a(n - mh)
a(mh) = a(mh) - a(n - mh)
call dctsub(m, a, nc, w(nw))
if (m .gt. 4) then
call bitrv2(m, ip(2), a)
call cftfsub(m, a, w)
call rftfsub(m, a, nc, w(nw))
else if (m .eq. 4) then
call cftfsub(m, a, w)
end if
a(n - 1) = a(0) - a(1)
a(1) = a(0) + a(1)
do j = m - 2, 2, -2
a(2 * j + 1) = a(j) + a(j + 1)
a(2 * j - 1) = a(j) - a(j + 1)
end do
l = 2
m = mh
do while (m .ge. 2)
call dctsub(m, t, nc, w(nw))
if (m .gt. 4) then
call bitrv2(m, ip(2), t)
call cftfsub(m, t, w)
call rftfsub(m, t, nc, w(nw))
else if (m .eq. 4) then
call cftfsub(m, t, w)
end if
a(n - l) = t(0) - t(1)
a(l) = t(0) + t(1)
k = 0
do j = 2, m - 2, 2
k = k + 4 * l
a(k - l) = t(j) - t(j + 1)
a(k + l) = t(j) + t(j + 1)
end do
l = 2 * l
mh = m / 2
do j = 0, mh - 1
k = m - j
t(j) = t(m + k) - t(m + j)
t(k) = t(m + k) + t(m + j)
end do
t(mh) = t(m + mh)
m = mh
end do
a(l) = t(0)
a(n) = t(2) - t(1)
a(0) = t(2) + t(1)
else
a(1) = a(0)
a(2) = t(0)
a(0) = t(1)
end if
end
!
subroutine dfst(n, a, t, ip, w)
integer n, ip(0 : *), j, k, l, m, mh, nw, nc
real*8 a(0 : n - 1), t(0 : n / 2 - 1), w(0 : *), xr, xi, yr, yi
nw = ip(0)
if (n .gt. 8 * nw) then
nw = n / 8
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n .gt. 2 * nc) then
nc = n / 2
call makect(nc, ip, w(nw))
end if
if (n .gt. 2) then
m = n / 2
mh = m / 2
do j = 1, mh - 1
k = m - j
xr = a(j) + a(n - j)
xi = a(j) - a(n - j)
yr = a(k) + a(n - k)
yi = a(k) - a(n - k)
a(j) = xr
a(k) = yr
t(j) = xi + yi
t(k) = xi - yi
end do
t(0) = a(mh) - a(n - mh)
a(mh) = a(mh) + a(n - mh)
a(0) = a(m)
call dstsub(m, a, nc, w(nw))
if (m .gt. 4) then
call bitrv2(m, ip(2), a)
call cftfsub(m, a, w)
call rftfsub(m, a, nc, w(nw))
else if (m .eq. 4) then
call cftfsub(m, a, w)
end if
a(n - 1) = a(1) - a(0)
a(1) = a(0) + a(1)
do j = m - 2, 2, -2
a(2 * j + 1) = a(j) - a(j + 1)
a(2 * j - 1) = -a(j) - a(j + 1)
end do
l = 2
m = mh
do while (m .ge. 2)
call dstsub(m, t, nc, w(nw))
if (m .gt. 4) then
call bitrv2(m, ip(2), t)
call cftfsub(m, t, w)
call rftfsub(m, t, nc, w(nw))
else if (m .eq. 4) then
call cftfsub(m, t, w)
end if
a(n - l) = t(1) - t(0)
a(l) = t(0) + t(1)
k = 0
do j = 2, m - 2, 2
k = k + 4 * l
a(k - l) = -t(j) - t(j + 1)
a(k + l) = t(j) - t(j + 1)
end do
l = 2 * l
mh = m / 2
do j = 1, mh - 1
k = m - j
t(j) = t(m + k) + t(m + j)
t(k) = t(m + k) - t(m + j)
end do
t(0) = t(m + mh)
m = mh
end do
a(l) = t(0)
end if
a(0) = 0
end
!
! -------- initializing routines --------
!
subroutine makewt(nw, ip, w)
integer nw, ip(0 : *), j, nwh
real*8 w(0 : nw - 1), delta, x, y
ip(0) = nw
ip(1) = 1
if (nw .gt. 2) then
nwh = nw / 2
delta = atan(1.0d0) / nwh
w(0) = 1
w(1) = 0
w(nwh) = cos(delta * nwh)
w(nwh + 1) = w(nwh)
if (nwh .gt. 2) then
do j = 2, nwh - 2, 2
x = cos(delta * j)
y = sin(delta * j)
w(j) = x
w(j + 1) = y
w(nw - j) = y
w(nw - j + 1) = x
end do
call bitrv2(nw, ip(2), w)
end if
end if
end
!
subroutine makect(nc, ip, c)
integer nc, ip(0 : *), j, nch
real*8 c(0 : nc - 1), delta
ip(1) = nc
if (nc .gt. 1) then
nch = nc / 2
delta = atan(1.0d0) / nch
c(0) = cos(delta * nch)
c(nch) = 0.5d0 * c(0)
do j = 1, nch - 1
c(j) = 0.5d0 * cos(delta * j)
c(nc - j) = 0.5d0 * sin(delta * j)
end do
end if
end
!
! -------- child routines --------
!
subroutine bitrv2(n, ip, a)
integer n, ip(0 : *), j, j1, k, k1, l, m, m2
real*8 a(0 : n - 1), xr, xi, yr, yi
ip(0) = 0
l = n
m = 1
do while (8 * m .lt. l)
l = l / 2
do j = 0, m - 1
ip(m + j) = ip(j) + l
end do
m = m * 2
end do
m2 = 2 * m
if (8 * m .eq. l) then
do k = 0, m - 1
do j = 0, k - 1
j1 = 2 * j + ip(k)
k1 = 2 * k + ip(j)
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + 2 * m2
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 - m2
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + 2 * m2
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
end do
j1 = 2 * k + m2 + ip(k)
k1 = j1 + m2
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
end do
else
do k = 1, m - 1
do j = 0, k - 1
j1 = 2 * j + ip(k)
k1 = 2 * k + ip(j)
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + m2
xr = a(j1)
xi = a(j1 + 1)
yr = a(k1)
yi = a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
end do
end do
end if
end
!
subroutine bitrv2conj(n, ip, a)
integer n, ip(0 : *), j, j1, k, k1, l, m, m2
real*8 a(0 : n - 1), xr, xi, yr, yi
ip(0) = 0
l = n
m = 1
do while (8 * m .lt. l)
l = l / 2
do j = 0, m - 1
ip(m + j) = ip(j) + l
end do
m = m * 2
end do
m2 = 2 * m
if (8 * m .eq. l) then
do k = 0, m - 1
do j = 0, k - 1
j1 = 2 * j + ip(k)
k1 = 2 * k + ip(j)
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + 2 * m2
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 - m2
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + 2 * m2
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
end do
k1 = 2 * k + ip(k)
a(k1 + 1) = -a(k1 + 1)
j1 = k1 + m2
k1 = j1 + m2
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
k1 = k1 + m2
a(k1 + 1) = -a(k1 + 1)
end do
else
a(1) = -a(1)
a(m2 + 1) = -a(m2 + 1)
do k = 1, m - 1
do j = 0, k - 1
j1 = 2 * j + ip(k)
k1 = 2 * k + ip(j)
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
j1 = j1 + m2
k1 = k1 + m2
xr = a(j1)
xi = -a(j1 + 1)
yr = a(k1)
yi = -a(k1 + 1)
a(j1) = yr
a(j1 + 1) = yi
a(k1) = xr
a(k1 + 1) = xi
end do
k1 = 2 * k + ip(k)
a(k1 + 1) = -a(k1 + 1)
a(k1 + m2 + 1) = -a(k1 + m2 + 1)
end do
end if
end
!
subroutine cftfsub(n, a, w)
integer n, j, j1, j2, j3, l
real*8 a(0 : n - 1), w(0 : *)
real*8 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i
l = 2
if (n .gt. 8) then
call cft1st(n, a, w)
l = 8
do while (4 * l .lt. n)
call cftmdl(n, l, a, w)
l = 4 * l
end do
end if
if (4 * l .eq. n) then
do j = 0, l - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = a(j + 1) + a(j1 + 1)
x1r = a(j) - a(j1)
x1i = a(j + 1) - a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
a(j2) = x0r - x2r
a(j2 + 1) = x0i - x2i
a(j1) = x1r - x3i
a(j1 + 1) = x1i + x3r
a(j3) = x1r + x3i
a(j3 + 1) = x1i - x3r
end do
else
do j = 0, l - 2, 2
j1 = j + l
x0r = a(j) - a(j1)
x0i = a(j + 1) - a(j1 + 1)
a(j) = a(j) + a(j1)
a(j + 1) = a(j + 1) + a(j1 + 1)
a(j1) = x0r
a(j1 + 1) = x0i
end do
end if
end
!
subroutine cftbsub(n, a, w)
integer n, j, j1, j2, j3, l
real*8 a(0 : n - 1), w(0 : *)
real*8 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i
l = 2
if (n .gt. 8) then
call cft1st(n, a, w)
l = 8
do while (4 * l .lt. n)
call cftmdl(n, l, a, w)
l = 4 * l
end do
end if
if (4 * l .eq. n) then
do j = 0, l - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = -a(j + 1) - a(j1 + 1)
x1r = a(j) - a(j1)
x1i = -a(j + 1) + a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i - x2i
a(j2) = x0r - x2r
a(j2 + 1) = x0i + x2i
a(j1) = x1r - x3i
a(j1 + 1) = x1i - x3r
a(j3) = x1r + x3i
a(j3 + 1) = x1i + x3r
end do
else
do j = 0, l - 2, 2
j1 = j + l
x0r = a(j) - a(j1)
x0i = -a(j + 1) + a(j1 + 1)
a(j) = a(j) + a(j1)
a(j + 1) = -a(j + 1) - a(j1 + 1)
a(j1) = x0r
a(j1 + 1) = x0i
end do
end if
end
!
subroutine cft1st(n, a, w)
integer n, j, k1, k2
real*8 a(0 : n - 1), w(0 : *)
real*8 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i
real*8 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i
x0r = a(0) + a(2)
x0i = a(1) + a(3)
x1r = a(0) - a(2)
x1i = a(1) - a(3)
x2r = a(4) + a(6)
x2i = a(5) + a(7)
x3r = a(4) - a(6)
x3i = a(5) - a(7)
a(0) = x0r + x2r
a(1) = x0i + x2i
a(4) = x0r - x2r
a(5) = x0i - x2i
a(2) = x1r - x3i
a(3) = x1i + x3r
a(6) = x1r + x3i
a(7) = x1i - x3r
wk1r = w(2)
x0r = a(8) + a(10)
x0i = a(9) + a(11)
x1r = a(8) - a(10)
x1i = a(9) - a(11)
x2r = a(12) + a(14)
x2i = a(13) + a(15)
x3r = a(12) - a(14)
x3i = a(13) - a(15)
a(8) = x0r + x2r
a(9) = x0i + x2i
a(12) = x2i - x0i
a(13) = x0r - x2r
x0r = x1r - x3i
x0i = x1i + x3r
a(10) = wk1r * (x0r - x0i)
a(11) = wk1r * (x0r + x0i)
x0r = x3i + x1r
x0i = x3r - x1i
a(14) = wk1r * (x0i - x0r)
a(15) = wk1r * (x0i + x0r)
k1 = 0
do j = 16, n - 16, 16
k1 = k1 + 2
k2 = 2 * k1
wk2r = w(k1)
wk2i = w(k1 + 1)
wk1r = w(k2)
wk1i = w(k2 + 1)
wk3r = wk1r - 2 * wk2i * wk1i
wk3i = 2 * wk2i * wk1r - wk1i
x0r = a(j) + a(j + 2)
x0i = a(j + 1) + a(j + 3)
x1r = a(j) - a(j + 2)
x1i = a(j + 1) - a(j + 3)
x2r = a(j + 4) + a(j + 6)
x2i = a(j + 5) + a(j + 7)
x3r = a(j + 4) - a(j + 6)
x3i = a(j + 5) - a(j + 7)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
x0r = x0r - x2r
x0i = x0i - x2i
a(j + 4) = wk2r * x0r - wk2i * x0i
a(j + 5) = wk2r * x0i + wk2i * x0r
x0r = x1r - x3i
x0i = x1i + x3r
a(j + 2) = wk1r * x0r - wk1i * x0i
a(j + 3) = wk1r * x0i + wk1i * x0r
x0r = x1r + x3i
x0i = x1i - x3r
a(j + 6) = wk3r * x0r - wk3i * x0i
a(j + 7) = wk3r * x0i + wk3i * x0r
wk1r = w(k2 + 2)
wk1i = w(k2 + 3)
wk3r = wk1r - 2 * wk2r * wk1i
wk3i = 2 * wk2r * wk1r - wk1i
x0r = a(j + 8) + a(j + 10)
x0i = a(j + 9) + a(j + 11)
x1r = a(j + 8) - a(j + 10)
x1i = a(j + 9) - a(j + 11)
x2r = a(j + 12) + a(j + 14)
x2i = a(j + 13) + a(j + 15)
x3r = a(j + 12) - a(j + 14)
x3i = a(j + 13) - a(j + 15)
a(j + 8) = x0r + x2r
a(j + 9) = x0i + x2i
x0r = x0r - x2r
x0i = x0i - x2i
a(j + 12) = -wk2i * x0r - wk2r * x0i
a(j + 13) = -wk2i * x0i + wk2r * x0r
x0r = x1r - x3i
x0i = x1i + x3r
a(j + 10) = wk1r * x0r - wk1i * x0i
a(j + 11) = wk1r * x0i + wk1i * x0r
x0r = x1r + x3i
x0i = x1i - x3r
a(j + 14) = wk3r * x0r - wk3i * x0i
a(j + 15) = wk3r * x0i + wk3i * x0r
end do
end
!
subroutine cftmdl(n, l, a, w)
integer n, l, j, j1, j2, j3, k, k1, k2, m, m2
real*8 a(0 : n - 1), w(0 : *)
real*8 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i
real*8 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i
m = 4 * l
do j = 0, l - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = a(j + 1) + a(j1 + 1)
x1r = a(j) - a(j1)
x1i = a(j + 1) - a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
a(j2) = x0r - x2r
a(j2 + 1) = x0i - x2i
a(j1) = x1r - x3i
a(j1 + 1) = x1i + x3r
a(j3) = x1r + x3i
a(j3 + 1) = x1i - x3r
end do
wk1r = w(2)
do j = m, l + m - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = a(j + 1) + a(j1 + 1)
x1r = a(j) - a(j1)
x1i = a(j + 1) - a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
a(j2) = x2i - x0i
a(j2 + 1) = x0r - x2r
x0r = x1r - x3i
x0i = x1i + x3r
a(j1) = wk1r * (x0r - x0i)
a(j1 + 1) = wk1r * (x0r + x0i)
x0r = x3i + x1r
x0i = x3r - x1i
a(j3) = wk1r * (x0i - x0r)
a(j3 + 1) = wk1r * (x0i + x0r)
end do
k1 = 0
m2 = 2 * m
do k = m2, n - m2, m2
k1 = k1 + 2
k2 = 2 * k1
wk2r = w(k1)
wk2i = w(k1 + 1)
wk1r = w(k2)
wk1i = w(k2 + 1)
wk3r = wk1r - 2 * wk2i * wk1i
wk3i = 2 * wk2i * wk1r - wk1i
do j = k, l + k - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = a(j + 1) + a(j1 + 1)
x1r = a(j) - a(j1)
x1i = a(j + 1) - a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
x0r = x0r - x2r
x0i = x0i - x2i
a(j2) = wk2r * x0r - wk2i * x0i
a(j2 + 1) = wk2r * x0i + wk2i * x0r
x0r = x1r - x3i
x0i = x1i + x3r
a(j1) = wk1r * x0r - wk1i * x0i
a(j1 + 1) = wk1r * x0i + wk1i * x0r
x0r = x1r + x3i
x0i = x1i - x3r
a(j3) = wk3r * x0r - wk3i * x0i
a(j3 + 1) = wk3r * x0i + wk3i * x0r
end do
wk1r = w(k2 + 2)
wk1i = w(k2 + 3)
wk3r = wk1r - 2 * wk2r * wk1i
wk3i = 2 * wk2r * wk1r - wk1i
do j = k + m, l + (k + m) - 2, 2
j1 = j + l
j2 = j1 + l
j3 = j2 + l
x0r = a(j) + a(j1)
x0i = a(j + 1) + a(j1 + 1)
x1r = a(j) - a(j1)
x1i = a(j + 1) - a(j1 + 1)
x2r = a(j2) + a(j3)
x2i = a(j2 + 1) + a(j3 + 1)
x3r = a(j2) - a(j3)
x3i = a(j2 + 1) - a(j3 + 1)
a(j) = x0r + x2r
a(j + 1) = x0i + x2i
x0r = x0r - x2r
x0i = x0i - x2i
a(j2) = -wk2i * x0r - wk2r * x0i
a(j2 + 1) = -wk2i * x0i + wk2r * x0r
x0r = x1r - x3i
x0i = x1i + x3r
a(j1) = wk1r * x0r - wk1i * x0i
a(j1 + 1) = wk1r * x0i + wk1i * x0r
x0r = x1r + x3i
x0i = x1i - x3r
a(j3) = wk3r * x0r - wk3i * x0i
a(j3 + 1) = wk3r * x0i + wk3i * x0r
end do
end do
end
!
subroutine rftfsub(n, a, nc, c)
integer n, nc, j, k, kk, ks, m
real*8 a(0 : n - 1), c(0 : nc - 1), wkr, wki, xr, xi, yr, yi
m = n / 2
ks = 2 * nc / m
kk = 0
do j = 2, m - 2, 2
k = n - j
kk = kk + ks
wkr = 0.5d0 - c(nc - kk)
wki = c(kk)
xr = a(j) - a(k)
xi = a(j + 1) + a(k + 1)
yr = wkr * xr - wki * xi
yi = wkr * xi + wki * xr
a(j) = a(j) - yr
a(j + 1) = a(j + 1) - yi
a(k) = a(k) + yr
a(k + 1) = a(k + 1) - yi
end do
end
!
subroutine rftbsub(n, a, nc, c)
integer n, nc, j, k, kk, ks, m
real*8 a(0 : n - 1), c(0 : nc - 1), wkr, wki, xr, xi, yr, yi
a(1) = -a(1)
m = n / 2
ks = 2 * nc / m
kk = 0
do j = 2, m - 2, 2
k = n - j
kk = kk + ks
wkr = 0.5d0 - c(nc - kk)
wki = c(kk)
xr = a(j) - a(k)
xi = a(j + 1) + a(k + 1)
yr = wkr * xr + wki * xi
yi = wkr * xi - wki * xr
a(j) = a(j) - yr
a(j + 1) = yi - a(j + 1)
a(k) = a(k) + yr
a(k + 1) = yi - a(k + 1)
end do
a(m + 1) = -a(m + 1)
end
!
subroutine dctsub(n, a, nc, c)
integer n, nc, j, k, kk, ks, m
real*8 a(0 : n - 1), c(0 : nc - 1), wkr, wki, xr
m = n / 2
ks = nc / n
kk = 0
do j = 1, m - 1
k = n - j
kk = kk + ks
wkr = c(kk) - c(nc - kk)
wki = c(kk) + c(nc - kk)
xr = wki * a(j) - wkr * a(k)
a(j) = wkr * a(j) + wki * a(k)
a(k) = xr
end do
a(m) = c(0) * a(m)
end
!
subroutine dstsub(n, a, nc, c)
integer n, nc, j, k, kk, ks, m
real*8 a(0 : n - 1), c(0 : nc - 1), wkr, wki, xr
m = n / 2
ks = nc / n
kk = 0
do j = 1, m - 1
k = n - j
kk = kk + ks
wkr = c(kk) - c(nc - kk)
wki = c(kk) + c(nc - kk)
xr = wki * a(k) - wkr * a(j)
a(k) = wkr * a(k) + wki * a(j)
a(j) = xr
end do
a(m) = c(0) * a(m)
end
!