blob: f08b1dc547c957256a97c4021d45873dc96b9525 [file] [log] [blame]
! Fast Fourier/Cosine/Sine Transform
! dimension :three
! data length :power of 2
! decimation :frequency
! radix :split-radix, row-column
! data :inplace
! table :use
! subroutines
! cdft3d: Complex Discrete Fourier Transform
! rdft3d: Real Discrete Fourier Transform
! ddct3d: Discrete Cosine Transform
! ddst3d: Discrete Sine Transform
! necessary package
! fftsg.f : 1D-FFT package
!
!
! -------- Complex DFT (Discrete Fourier Transform) --------
! [definition]
! <case1>
! X(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! x(j1,j2,j3) *
! exp(2*pi*i*j1*k1/n1) *
! exp(2*pi*i*j2*k2/n2) *
! exp(2*pi*i*j3*k3/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! <case2>
! X(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! x(j1,j2,j3) *
! exp(-2*pi*i*j1*k1/n1) *
! exp(-2*pi*i*j2*k2/n2) *
! exp(-2*pi*i*j3*k3/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call cdft3d(n1max, n2max, 2*n1, n2, n3, 1, a, t, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call cdft3d(n1max, n2max, 2*n1, n2, n3, -1, a, t, ip, w)
! [parameters]
! n1max :row1 size of the 3D array (integer)
! n2max :row2 size of the 3D array (integer)
! 2*n1 :data length (integer)
! n1 >= 1, n1 = power of 2
! n2 :data length (integer)
! n2 >= 1, n2 = power of 2
! n3 :data length (integer)
! n3 >= 1, n3 = power of 2
! a(0:2*n1-1,0:n2-1,0:n3-1)
! :input/output data (real*8)
! input data
! a(2*j1,j2,j3) = Re(x(j1,j2,j3)),
! a(2*j1+1,j2,j3) = Im(x(j1,j2,j3)),
! 0<=j1<n1, 0<=j2<n2, 0<=j3<n3
! output data
! a(2*k1,k2,k3) = Re(X(k1,k2,k3)),
! a(2*k1+1,k2,k3) = Im(X(k1,k2,k3)),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! t(0:*) :work area (real*8)
! length of t >= max(8*n2, 8*n3)
! ip(0:*):work area for bit reversal (integer)
! length of ip >= 2+sqrt(n)
! (n = max(n1, n2, n3))
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:*) :cos/sin table (real*8)
! length of w >= max(n1/2, n2/2, n3/2)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call cdft3d(n1max, n2max, 2*n1, n2, n3, -1, a, t, ip, w)
! is
! call cdft3d(n1max, n2max, 2*n1, n2, n3, 1, a, t, ip, w)
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! do j1 = 0, 2 * n1 - 1
! a(j1,j2,j3) = a(j1,j2,j3) * (1.0d0/n1/n2/n3)
! end do
! end do
! end do
! .
!
!
! -------- Real DFT / Inverse of Real DFT --------
! [definition]
! <case1> RDFT
! R(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! a(j1,j2,j3) *
! cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2 +
! 2*pi*j3*k3/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! I(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! a(j1,j2,j3) *
! sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2 +
! 2*pi*j3*k3/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! <case2> IRDFT (excluding scale)
! a(k1,k2,k3) = (1/2) * sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! (R(j1,j2,j3) *
! cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2 +
! 2*pi*j3*k3/n3) +
! I(j1,j2,j3) *
! sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2 +
! 2*pi*j3*k3/n3)),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! (notes: R(mod(n1-k1,n1),mod(n2-k2,n2),mod(n3-k3,n3)) = R(k1,k2,k3),
! I(mod(n1-k1,n1),mod(n2-k2,n2),mod(n3-k3,n3)) = -I(k1,k2,k3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3)
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call rdft3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call rdft3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! [parameters]
! n1max :row1 size of the 3D array (integer)
! n2max :row2 size of the 3D array (integer)
! n1 :data length (integer)
! n1 >= 2, n1 = power of 2
! n2 :data length (integer)
! n2 >= 2, n2 = power of 2
! n3 :data length (integer)
! n3 >= 2, n3 = power of 2
! a(0:n1-1,0:n2-1,0:n3-1)
! :input/output data (real*8)
! <case1>
! output data
! a(2*k1,k2,k3) = R(k1,k2,k3)
! = R(n1-k1,mod(n2-k2,n2),mod(n3-k3,n3)),
! a(2*k1+1,k2,k3) = I(k1,k2,k3)
! = -I(n1-k1,mod(n2-k2,n2),mod(n3-k3,n3)),
! 0<k1<n1/2, 0<=k2<n2, 0<=k3<n3,
! a(0,k2,k3) = R(0,k2,k3)
! = R(0,n2-k2,mod(n3-k3,n3)),
! a(1,k2,k3) = I(0,k2,k3)
! = -I(0,n2-k2,mod(n3-k3,n3)),
! a(1,n2-k2,k3) = R(n1/2,k2,mod(n3-k3,n3))
! = R(n1/2,n2-k2,k3),
! a(0,n2-k2,k3) = -I(n1/2,k2,mod(n3-k3,n3))
! = I(n1/2,n2-k2,k3),
! 0<k2<n2/2, 0<=k3<n3,
! a(0,0,k3) = R(0,0,k3)
! = R(0,0,n3-k3),
! a(1,0,k3) = I(0,0,k3)
! = -I(0,0,n3-k3),
! a(0,n2/2,k3) = R(0,n2/2,k3)
! = R(0,n2/2,n3-k3),
! a(1,n2/2,k3) = I(0,n2/2,k3)
! = -I(0,n2/2,n3-k3),
! a(1,0,n3-k3) = R(n1/2,0,k3)
! = R(n1/2,0,n3-k3),
! a(0,0,n3-k3) = -I(n1/2,0,k3)
! = I(n1/2,0,n3-k3),
! a(1,n2/2,n3-k3) = R(n1/2,n2/2,k3)
! = R(n1/2,n2/2,n3-k3),
! a(0,n2/2,n3-k3) = -I(n1/2,n2/2,k3)
! = I(n1/2,n2/2,n3-k3),
! 0<k3<n3/2,
! a(0,0,0) = R(0,0,0),
! a(1,0,0) = R(n1/2,0,0),
! a(0,0,n3/2) = R(0,0,n3/2),
! a(1,0,n3/2) = R(n1/2,0,n3/2),
! a(0,n2/2,0) = R(0,n2/2,0),
! a(1,n2/2,0) = R(n1/2,n2/2,0),
! a(0,n2/2,n3/2) = R(0,n2/2,n3/2),
! a(1,n2/2,n3/2) = R(n1/2,n2/2,n3/2)
! <case2>
! input data
! a(2*j1,j2,j3) = R(j1,j2,j3)
! = R(n1-j1,mod(n2-j2,n2),mod(n3-j3,n3)),
! a(2*j1+1,j2,j3) = I(j1,j2,j3)
! = -I(n1-j1,mod(n2-j2,n2),mod(n3-j3,n3)),
! 0<j1<n1/2, 0<=j2<n2, 0<=j3<n3,
! a(0,j2,j3) = R(0,j2,j3)
! = R(0,n2-j2,mod(n3-j3,n3)),
! a(1,j2,j3) = I(0,j2,j3)
! = -I(0,n2-j2,mod(n3-j3,n3)),
! a(1,n2-j2,j3) = R(n1/2,j2,mod(n3-j3,n3))
! = R(n1/2,n2-j2,j3),
! a(0,n2-j2,j3) = -I(n1/2,j2,mod(n3-j3,n3))
! = I(n1/2,n2-j2,j3),
! 0<j2<n2/2, 0<=j3<n3,
! a(0,0,j3) = R(0,0,j3)
! = R(0,0,n3-j3),
! a(1,0,j3) = I(0,0,j3)
! = -I(0,0,n3-j3),
! a(0,n2/2,j3) = R(0,n2/2,j3)
! = R(0,n2/2,n3-j3),
! a(1,n2/2,j3) = I(0,n2/2,j3)
! = -I(0,n2/2,n3-j3),
! a(1,0,n3-j3) = R(n1/2,0,j3)
! = R(n1/2,0,n3-j3),
! a(0,0,n3-j3) = -I(n1/2,0,j3)
! = I(n1/2,0,n3-j3),
! a(1,n2/2,n3-j3) = R(n1/2,n2/2,j3)
! = R(n1/2,n2/2,n3-j3),
! a(0,n2/2,n3-j3) = -I(n1/2,n2/2,j3)
! = I(n1/2,n2/2,n3-j3),
! 0<j3<n3/2,
! a(0,0,0) = R(0,0,0),
! a(1,0,0) = R(n1/2,0,0),
! a(0,0,n3/2) = R(0,0,n3/2),
! a(1,0,n3/2) = R(n1/2,0,n3/2),
! a(0,n2/2,0) = R(0,n2/2,0),
! a(1,n2/2,0) = R(n1/2,n2/2,0),
! a(0,n2/2,n3/2) = R(0,n2/2,n3/2),
! a(1,n2/2,n3/2) = R(n1/2,n2/2,n3/2)
! ---- output ordering ----
! call rdft3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! call rdft3dsort(n1max, n2max, n1, n2, n3, 1, a)
! ! stored data is a(0:n1-1,0:n2-1,0:n3+1):
! ! a(2*k1,k2,k3) = R(k1,k2,k3),
! ! a(2*k1+1,k2,k3) = I(k1,k2,k3),
! ! 0<=k1<=n1/2, 0<=k2<n2, 0<=k3<n3.
! ! the stored data is larger than the input data!
! ---- input ordering ----
! call rdft3dsort(n1max, n2max, n1, n2, n3, -1, a)
! call rdft3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! t(0:*) :work area (real*8)
! length of t >= max(8*n2, 8*n3)
! ip(0:*):work area for bit reversal (integer)
! length of ip >= 2+sqrt(n)
! (n = max(n1/2, n2, n3))
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:*) :cos/sin table (real*8)
! length of w >= max(n1/4, n2/2, n3/2) + n1/4
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call rdft3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! is
! call rdft3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! do j1 = 0, n1 - 1
! a(j1,j2,j3) = a(j1,j2,j3) * (2.0d0/n1/n2/n3)
! end do
! end do
! end do
! .
!
!
! -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
! [definition]
! <case1> IDCT (excluding scale)
! C(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! a(j1,j2,j3) *
! cos(pi*j1*(k1+1/2)/n1) *
! cos(pi*j2*(k2+1/2)/n2) *
! cos(pi*j3*(k3+1/2)/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! <case2> DCT
! C(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! a(j1,j2,j3) *
! cos(pi*(j1+1/2)*k1/n1) *
! cos(pi*(j2+1/2)*k2/n2) *
! cos(pi*(j3+1/2)*k3/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call ddct3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call ddct3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! [parameters]
! n1max :row1 size of the 3D array (integer)
! n2max :row2 size of the 3D array (integer)
! n1 :data length (integer)
! n1 >= 2, n1 = power of 2
! n2 :data length (integer)
! n2 >= 2, n2 = power of 2
! n3 :data length (integer)
! n3 >= 2, n3 = power of 2
! a(0:n1-1,0:n2-1,0:n3-1)
! :input/output data (real*8)
! output data
! a(k1,k2,k3) = C(k1,k2,k3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! t(0:*) :work area (real*8)
! length of t >= max(4*n2, 4*n3)
! ip(0:*):work area for bit reversal (integer)
! length of ip >= 2+sqrt(n)
! (n = max(n1/2, n2/2, n3/2))
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:*) :cos/sin table (real*8)
! length of w >= max(n1*3/2, n2*3/2, n3*3/2)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call ddct3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! is
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! a(0, j2, j3) = a(0, j2, j3) * 0.5d0
! end do
! do j1 = 0, n1 - 1
! a(j1, 0, j3) = a(j1, 0, j3) * 0.5d0
! end do
! end do
! do j2 = 0, n2 - 1
! do j1 = 0, n1 - 1
! a(j1, j2, 0) = a(j1, j2, 0) * 0.5d0
! end do
! end do
! call ddct3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! do j1 = 0, n1 - 1
! a(j1,j2,j3) = a(j1,j2,j3) * (8.0d0/n1/n2/n3)
! end do
! end do
! end do
! .
!
!
! -------- DST (Discrete Sine Transform) / Inverse of DST --------
! [definition]
! <case1> IDST (excluding scale)
! S(k1,k2,k3) = sum_j1=1^n1 sum_j2=1^n2 sum_j3=1^n3
! A(j1,j2,j3) *
! sin(pi*j1*(k1+1/2)/n1) *
! sin(pi*j2*(k2+1/2)/n2) *
! sin(pi*j3*(k3+1/2)/n3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! <case2> DST
! S(k1,k2,k3) = sum_j1=0^n1-1 sum_j2=0^n2-1 sum_j3=0^n3-1
! a(j1,j2,j3) *
! sin(pi*(j1+1/2)*k1/n1) *
! sin(pi*(j2+1/2)*k2/n2) *
! sin(pi*(j3+1/2)*k3/n3),
! 0<k1<=n1, 0<k2<=n2, 0<k3<=n3
! [usage]
! <case1>
! ip(0) = 0 ! first time only
! call ddst3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! <case2>
! ip(0) = 0 ! first time only
! call ddst3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! [parameters]
! n1max :row1 size of the 3D array (integer)
! n2max :row2 size of the 3D array (integer)
! n1 :data length (integer)
! n1 >= 2, n1 = power of 2
! n2 :data length (integer)
! n2 >= 2, n2 = power of 2
! n3 :data length (integer)
! n3 >= 2, n3 = power of 2
! a(0:n1-1,0:n2-1,0:n3-1)
! :input/output data (real*8)
! <case1>
! input data
! a(mod(j1,n1),mod(j2,n2),mod(j3,n3)) = A(j1,j2,j3),
! 0<j1<=n1, 0<j2<=n2, 0<j3<=n3
! output data
! a(k1,k2,k3) = S(k1,k2,k3),
! 0<=k1<n1, 0<=k2<n2, 0<=k3<n3
! <case2>
! output data
! a(mod(k1,n1),mod(k2,n2),mod(k3,n3)) = S(k1,k2,k3),
! 0<k1<=n1, 0<k2<=n2, 0<k3<=n3
! t(0:*) :work area (real*8)
! length of t >= max(4*n2, 4*n3)
! ip(0:*):work area for bit reversal (integer)
! length of ip >= 2+sqrt(n)
! (n = max(n1/2, n2/2, n3/2))
! ip(0),ip(1) are pointers of the cos/sin table.
! w(0:*) :cos/sin table (real*8)
! length of w >= max(n1*3/2, n2*3/2, n3*3/2)
! w(),ip() are initialized if ip(0) = 0.
! [remark]
! Inverse of
! call ddst3d(n1max, n2max, n1, n2, n3, -1, a, t, ip, w)
! is
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! a(0, j2, j3) = a(0, j2, j3) * 0.5d0
! end do
! do j1 = 0, n1 - 1
! a(j1, 0, j3) = a(j1, 0, j3) * 0.5d0
! end do
! end do
! do j2 = 0, n2 - 1
! do j1 = 0, n1 - 1
! a(j1, j2, 0) = a(j1, j2, 0) * 0.5d0
! end do
! end do
! call ddst3d(n1max, n2max, n1, n2, n3, 1, a, t, ip, w)
! do j3 = 0, n3 - 1
! do j2 = 0, n2 - 1
! do j1 = 0, n1 - 1
! a(j1,j2,j3) = a(j1,j2,j3) * (8.0d0/n1/n2/n3)
! end do
! end do
! end do
! .
!
!
subroutine cdft3d(n1max, n2max, n1, n2, n3, isgn, a,
& t, ip, w)
integer n1max, n2max, n1, n2, n3, isgn, ip(0 : *), n
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
n = 2 * max(n2, n3)
n = max(n, n1)
if (n .gt. 4 * ip(0)) then
call makewt(n / 4, ip, w)
end if
call xdft3da_sub(n1max, n2max, n1, n2, n3, 0,
& isgn, a, t, ip, w)
call cdft3db_sub(n1max, n2max, n1, n2, n3,
& isgn, a, t, ip, w)
end
!
subroutine rdft3d(n1max, n2max, n1, n2, n3, isgn, a,
& t, ip, w)
integer n1max, n2max, n1, n2, n3, isgn, ip(0 : *),
& n, nw, nc
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
n = 2 * max(n2, n3)
n = max(n, n1)
nw = ip(0)
if (n .gt. 4 * nw) then
nw = n / 4
call makewt(nw, ip, w)
end if
nc = ip(1)
if (n1 .gt. 4 * nc) then
nc = n1 / 4
call makect(nc, ip, w(nw))
end if
if (isgn .lt. 0) then
call rdft3d_sub(n1max, n2max, n1, n2, n3, isgn, a)
call cdft3db_sub(n1max, n2max, n1, n2, n3,
& isgn, a, t, ip, w)
call xdft3da_sub(n1max, n2max, n1, n2, n3, 1,
& isgn, a, t, ip, w)
else
call xdft3da_sub(n1max, n2max, n1, n2, n3, 1,
& isgn, a, t, ip, w)
call cdft3db_sub(n1max, n2max, n1, n2, n3,
& isgn, a, t, ip, w)
call rdft3d_sub(n1max, n2max, n1, n2, n3, isgn, a)
end if
end
!
subroutine rdft3dsort(n1max, n2max, n1, n2, n3, isgn, a)
integer n1max, n2max, n1, n2, n3, isgn, n2h, n3h, j, k
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1), x, y
n2h = n2 / 2
n3h = n3 / 2
if (isgn .lt. 0) then
do k = 0, n3 - 1
do j = n2h + 1, n2 - 1
a(0, j, k) = a(n1 + 1, j, k)
a(1, j, k) = a(n1, j, k)
end do
end do
do k = n3h + 1, n3 - 1
a(0, 0, k) = a(n1 + 1, 0, k)
a(1, 0, k) = a(n1, 0, k)
a(0, n2h, k) = a(n1 + 1, n2h, k)
a(1, n2h, k) = a(n1, n2h, k)
end do
a(1, 0, 0) = a(n1, 0, 0)
a(1, n2h, 0) = a(n1, n2h, 0)
a(1, 0, n3h) = a(n1, 0, n3h)
a(1, n2h, n3h) = a(n1, n2h, n3h)
else
do j = n2h + 1, n2 - 1
y = a(0, j, 0)
x = a(1, j, 0)
a(n1, j, 0) = x
a(n1 + 1, j, 0) = y
a(n1, n2 - j, 0) = x
a(n1 + 1, n2 - j, 0) = -y
a(0, j, 0) = a(0, n2 - j, 0)
a(1, j, 0) = -a(1, n2 - j, 0)
end do
do k = 1, n3 - 1
do j = n2h + 1, n2 - 1
y = a(0, j, k)
x = a(1, j, k)
a(n1, j, k) = x
a(n1 + 1, j, k) = y
a(n1, n2 - j, n3 - k) = x
a(n1 + 1, n2 - j, n3 - k) = -y
a(0, j, k) = a(0, n2 - j, n3 - k)
a(1, j, k) = -a(1, n2 - j, n3 - k)
end do
end do
do k = n3h + 1, n3 - 1
y = a(0, 0, k)
x = a(1, 0, k)
a(n1, 0, k) = x
a(n1 + 1, 0, k) = y
a(n1, 0, n3 - k) = x
a(n1 + 1, 0, n3 - k) = -y
a(0, 0, k) = a(0, 0, n3 - k)
a(1, 0, k) = -a(1, 0, n3 - k)
y = a(0, n2h, k)
x = a(1, n2h, k)
a(n1, n2h, k) = x
a(n1 + 1, n2h, k) = y
a(n1, n2h, n3 - k) = x
a(n1 + 1, n2h, n3 - k) = -y
a(0, n2h, k) = a(0, n2h, n3 - k)
a(1, n2h, k) = -a(1, n2h, n3 - k)
end do
a(n1, 0, 0) = a(1, 0, 0)
a(n1 + 1, 0, 0) = 0
a(1, 0, 0) = 0
a(n1, n2h, 0) = a(1, n2h, 0)
a(n1 + 1, n2h, 0) = 0
a(1, n2h, 0) = 0
a(n1, 0, n3h) = a(1, 0, n3h)
a(n1 + 1, 0, n3h) = 0
a(1, 0, n3h) = 0
a(n1, n2h, n3h) = a(1, n2h, n3h)
a(n1 + 1, n2h, n3h) = 0
a(1, n2h, n3h) = 0
end if
end
!
subroutine ddct3d(n1max, n2max, n1, n2, n3, isgn, a,
& t, ip, w)
integer n1max, n2max, n1, n2, n3, isgn, ip(0 : *),
& n, nw, nc
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
n = max(n2, n3)
n = max(n, n1)
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
call ddxt3da_sub(n1max, n2max, n1, n2, n3, 0,
& isgn, a, t, ip, w)
call ddxt3db_sub(n1max, n2max, n1, n2, n3, 0,
& isgn, a, t, ip, w)
end
!
subroutine ddst3d(n1max, n2max, n1, n2, n3, isgn, a,
& t, ip, w)
integer n1max, n2max, n1, n2, n3, isgn, ip(0 : *),
& n, nw, nc
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
n = max(n2, n3)
n = max(n, n1)
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
call ddxt3da_sub(n1max, n2max, n1, n2, n3, 1,
& isgn, a, t, ip, w)
call ddxt3db_sub(n1max, n2max, n1, n2, n3, 1,
& isgn, a, t, ip, w)
end
!
! -------- child routines --------
!
subroutine xdft3da_sub(n1max, n2max, n1, n2, n3, icr,
& isgn, a, t, ip, w)
integer n1max, n2max, n1, n2, n3, icr, isgn,
& ip(0 : *), i, j, k
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
do k = 0, n3 - 1
if (icr .eq. 0) then
do j = 0, n2 - 1
call cdft(n1, isgn, a(0, j, k), ip, w)
end do
else if (isgn .ge. 0) then
do j = 0, n2 - 1
call rdft(n1, isgn, a(0, j, k), ip, w)
end do
end if
if (n1 .gt. 4) then
do i = 0, n1 - 8, 8
do j = 0, n2 - 1
t(2 * j) = a(i, j, k)
t(2 * j + 1) = a(i + 1, j, k)
t(2 * n2 + 2 * j) = a(i + 2, j, k)
t(2 * n2 + 2 * j + 1) = a(i + 3, j, k)
t(4 * n2 + 2 * j) = a(i + 4, j, k)
t(4 * n2 + 2 * j + 1) = a(i + 5, j, k)
t(6 * n2 + 2 * j) = a(i + 6, j, k)
t(6 * n2 + 2 * j + 1) = a(i + 7, j, k)
end do
call cdft(2 * n2, isgn, t, ip, w)
call cdft(2 * n2, isgn, t(2 * n2), ip, w)
call cdft(2 * n2, isgn, t(4 * n2), ip, w)
call cdft(2 * n2, isgn, t(6 * n2), ip, w)
do j = 0, n2 - 1
a(i, j, k) = t(2 * j)
a(i + 1, j, k) = t(2 * j + 1)
a(i + 2, j, k) = t(2 * n2 + 2 * j)
a(i + 3, j, k) = t(2 * n2 + 2 * j + 1)
a(i + 4, j, k) = t(4 * n2 + 2 * j)
a(i + 5, j, k) = t(4 * n2 + 2 * j + 1)
a(i + 6, j, k) = t(6 * n2 + 2 * j)
a(i + 7, j, k) = t(6 * n2 + 2 * j + 1)
end do
end do
else if (n1 .eq. 4) then
do j = 0, n2 - 1
t(2 * j) = a(0, j, k)
t(2 * j + 1) = a(1, j, k)
t(2 * n2 + 2 * j) = a(2, j, k)
t(2 * n2 + 2 * j + 1) = a(3, j, k)
end do
call cdft(2 * n2, isgn, t, ip, w)
call cdft(2 * n2, isgn, t(2 * n2), ip, w)
do j = 0, n2 - 1
a(0, j, k) = t(2 * j)
a(1, j, k) = t(2 * j + 1)
a(2, j, k) = t(2 * n2 + 2 * j)
a(3, j, k) = t(2 * n2 + 2 * j + 1)
end do
else if (n1 .eq. 2) then
do j = 0, n2 - 1
t(2 * j) = a(0, j, k)
t(2 * j + 1) = a(1, j, k)
end do
call cdft(2 * n2, isgn, t, ip, w)
do j = 0, n2 - 1
a(0, j, k) = t(2 * j)
a(1, j, k) = t(2 * j + 1)
end do
end if
if (icr .ne. 0 .and. isgn .lt. 0) then
do j = 0, n2 - 1
call rdft(n1, isgn, a(0, j, k), ip, w)
end do
end if
end do
end
!
subroutine cdft3db_sub(n1max, n2max, n1, n2, n3,
& isgn, a, t, ip, w)
integer n1max, n2max, n1, n2, n3, isgn, ip(0 : *),
& i, j, k
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
if (n1 .gt. 4) then
do j = 0, n2 - 1
do i = 0, n1 - 8, 8
do k = 0, n3 - 1
t(2 * k) = a(i, j, k)
t(2 * k + 1) = a(i + 1, j, k)
t(2 * n3 + 2 * k) = a(i + 2, j, k)
t(2 * n3 + 2 * k + 1) = a(i + 3, j, k)
t(4 * n3 + 2 * k) = a(i + 4, j, k)
t(4 * n3 + 2 * k + 1) = a(i + 5, j, k)
t(6 * n3 + 2 * k) = a(i + 6, j, k)
t(6 * n3 + 2 * k + 1) = a(i + 7, j, k)
end do
call cdft(2 * n3, isgn, t, ip, w)
call cdft(2 * n3, isgn, t(2 * n3), ip, w)
call cdft(2 * n3, isgn, t(4 * n3), ip, w)
call cdft(2 * n3, isgn, t(6 * n3), ip, w)
do k = 0, n3 - 1
a(i, j, k) = t(2 * k)
a(i + 1, j, k) = t(2 * k + 1)
a(i + 2, j, k) = t(2 * n3 + 2 * k)
a(i + 3, j, k) = t(2 * n3 + 2 * k + 1)
a(i + 4, j, k) = t(4 * n3 + 2 * k)
a(i + 5, j, k) = t(4 * n3 + 2 * k + 1)
a(i + 6, j, k) = t(6 * n3 + 2 * k)
a(i + 7, j, k) = t(6 * n3 + 2 * k + 1)
end do
end do
end do
else if (n1 .eq. 4) then
do j = 0, n2 - 1
do k = 0, n3 - 1
t(2 * k) = a(0, j, k)
t(2 * k + 1) = a(1, j, k)
t(2 * n3 + 2 * k) = a(2, j, k)
t(2 * n3 + 2 * k + 1) = a(3, j, k)
end do
call cdft(2 * n3, isgn, t, ip, w)
call cdft(2 * n3, isgn, t(2 * n3), ip, w)
do k = 0, n3 - 1
a(0, j, k) = t(2 * k)
a(1, j, k) = t(2 * k + 1)
a(2, j, k) = t(2 * n3 + 2 * k)
a(3, j, k) = t(2 * n3 + 2 * k + 1)
end do
end do
else if (n1 .eq. 2) then
do j = 0, n2 - 1
do k = 0, n3 - 1
t(2 * k) = a(0, j, k)
t(2 * k + 1) = a(1, j, k)
end do
call cdft(2 * n3, isgn, t, ip, w)
do k = 0, n3 - 1
a(0, j, k) = t(2 * k)
a(1, j, k) = t(2 * k + 1)
end do
end do
end if
end
!
subroutine rdft3d_sub(n1max, n2max, n1, n2, n3, isgn, a)
integer n1max, n2max, n1, n2, n3, isgn,
& n2h, n3h, i, j, k, l
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1), xi
n2h = n2 / 2
n3h = n3 / 2
if (isgn .lt. 0) then
do k = 1, n3h - 1
l = n3 - k
xi = a(0, 0, k) - a(0, 0, l)
a(0, 0, k) = a(0, 0, k) + a(0, 0, l)
a(0, 0, l) = xi
xi = a(1, 0, l) - a(1, 0, k)
a(1, 0, k) = a(1, 0, k) + a(1, 0, l)
a(1, 0, l) = xi
xi = a(0, n2h, k) - a(0, n2h, l)
a(0, n2h, k) = a(0, n2h, k) + a(0, n2h, l)
a(0, n2h, l) = xi
xi = a(1, n2h, l) - a(1, n2h, k)
a(1, n2h, k) = a(1, n2h, k) + a(1, n2h, l)
a(1, n2h, l) = xi
do i = 1, n2h - 1
j = n2 - i
xi = a(0, i, k) - a(0, j, l)
a(0, i, k) = a(0, i, k) + a(0, j, l)
a(0, j, l) = xi
xi = a(1, j, l) - a(1, i, k)
a(1, i, k) = a(1, i, k) + a(1, j, l)
a(1, j, l) = xi
xi = a(0, i, l) - a(0, j, k)
a(0, i, l) = a(0, i, l) + a(0, j, k)
a(0, j, k) = xi
xi = a(1, j, k) - a(1, i, l)
a(1, i, l) = a(1, i, l) + a(1, j, k)
a(1, j, k) = xi
end do
end do
do i = 1, n2h - 1
j = n2 - i
xi = a(0, i, 0) - a(0, j, 0)
a(0, i, 0) = a(0, i, 0) + a(0, j, 0)
a(0, j, 0) = xi
xi = a(1, j, 0) - a(1, i, 0)
a(1, i, 0) = a(1, i, 0) + a(1, j, 0)
a(1, j, 0) = xi
xi = a(0, i, n3h) - a(0, j, n3h)
a(0, i, n3h) = a(0, i, n3h) + a(0, j, n3h)
a(0, j, n3h) = xi
xi = a(1, j, n3h) - a(1, i, n3h)
a(1, i, n3h) = a(1, i, n3h) + a(1, j, n3h)
a(1, j, n3h) = xi
end do
else
do k = 1, n3h - 1
l = n3 - k
a(0, 0, l) = 0.5d0 * (a(0, 0, k) - a(0, 0, l))
a(0, 0, k) = a(0, 0, k) - a(0, 0, l)
a(1, 0, l) = 0.5d0 * (a(1, 0, k) + a(1, 0, l))
a(1, 0, k) = a(1, 0, k) - a(1, 0, l)
a(0, n2h, l) = 0.5d0 * (a(0, n2h, k) - a(0, n2h, l))
a(0, n2h, k) = a(0, n2h, k) - a(0, n2h, l)
a(1, n2h, l) = 0.5d0 * (a(1, n2h, k) + a(1, n2h, l))
a(1, n2h, k) = a(1, n2h, k) - a(1, n2h, l)
do i = 1, n2h - 1
j = n2 - i
a(0, j, l) = 0.5d0 * (a(0, i, k) - a(0, j, l))
a(0, i, k) = a(0, i, k) - a(0, j, l)
a(1, j, l) = 0.5d0 * (a(1, i, k) + a(1, j, l))
a(1, i, k) = a(1, i, k) - a(1, j, l)
a(0, j, k) = 0.5d0 * (a(0, i, l) - a(0, j, k))
a(0, i, l) = a(0, i, l) - a(0, j, k)
a(1, j, k) = 0.5d0 * (a(1, i, l) + a(1, j, k))
a(1, i, l) = a(1, i, l) - a(1, j, k)
end do
end do
do i = 1, n2h - 1
j = n2 - i
a(0, j, 0) = 0.5d0 * (a(0, i, 0) - a(0, j, 0))
a(0, i, 0) = a(0, i, 0) - a(0, j, 0)
a(1, j, 0) = 0.5d0 * (a(1, i, 0) + a(1, j, 0))
a(1, i, 0) = a(1, i, 0) - a(1, j, 0)
a(0, j, n3h) = 0.5d0 * (a(0, i, n3h) - a(0, j, n3h))
a(0, i, n3h) = a(0, i, n3h) - a(0, j, n3h)
a(1, j, n3h) = 0.5d0 * (a(1, i, n3h) + a(1, j, n3h))
a(1, i, n3h) = a(1, i, n3h) - a(1, j, n3h)
end do
end if
end
!
subroutine ddxt3da_sub(n1max, n2max, n1, n2, n3, ics,
& isgn, a, t, ip, w)
integer n1max, n2max, n1, n2, n3, ics, isgn,
& ip(0 : *), i, j, k
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
do k = 0, n3 - 1
if (ics .eq. 0) then
do j = 0, n2 - 1
call ddct(n1, isgn, a(0, j, k), ip, w)
end do
else
do j = 0, n2 - 1
call ddst(n1, isgn, a(0, j, k), ip, w)
end do
end if
if (n1 .gt. 2) then
do i = 0, n1 - 4, 4
do j = 0, n2 - 1
t(j) = a(i, j, k)
t(n2 + j) = a(i + 1, j, k)
t(2 * n2 + j) = a(i + 2, j, k)
t(3 * n2 + j) = a(i + 3, j, k)
end do
if (ics .eq. 0) then
call ddct(n2, isgn, t, ip, w)
call ddct(n2, isgn, t(n2), ip, w)
call ddct(n2, isgn, t(2 * n2), ip, w)
call ddct(n2, isgn, t(3 * n2), ip, w)
else
call ddst(n2, isgn, t, ip, w)
call ddst(n2, isgn, t(n2), ip, w)
call ddst(n2, isgn, t(2 * n2), ip, w)
call ddst(n2, isgn, t(3 * n2), ip, w)
end if
do j = 0, n2 - 1
a(i, j, k) = t(j)
a(i + 1, j, k) = t(n2 + j)
a(i + 2, j, k) = t(2 * n2 + j)
a(i + 3, j, k) = t(3 * n2 + j)
end do
end do
else if (n1 .eq. 2) then
do j = 0, n2 - 1
t(j) = a(0, j, k)
t(n2 + j) = a(1, j, k)
end do
if (ics .eq. 0) then
call ddct(n2, isgn, t, ip, w)
call ddct(n2, isgn, t(n2), ip, w)
else
call ddst(n2, isgn, t, ip, w)
call ddst(n2, isgn, t(n2), ip, w)
end if
do j = 0, n2 - 1
a(0, j, k) = t(j)
a(1, j, k) = t(n2 + j)
end do
end if
end do
end
!
subroutine ddxt3db_sub(n1max, n2max, n1, n2, n3, ics,
& isgn, a, t, ip, w)
integer n1max, n2max, n1, n2, n3, ics, isgn,
& ip(0 : *), i, j, k
real*8 a(0 : n1max - 1, 0 : n2max - 1, 0 : n3 - 1),
& t(0 : *), w(0 : *)
if (n1 .gt. 2) then
do j = 0, n2 - 1
do i = 0, n1 - 4, 4
do k = 0, n3 - 1
t(k) = a(i, j, k)
t(n3 + k) = a(i + 1, j, k)
t(2 * n3 + k) = a(i + 2, j, k)
t(3 * n3 + k) = a(i + 3, j, k)
end do
if (ics .eq. 0) then
call ddct(n3, isgn, t, ip, w)
call ddct(n3, isgn, t(n3), ip, w)
call ddct(n3, isgn, t(2 * n3), ip, w)
call ddct(n3, isgn, t(3 * n3), ip, w)
else
call ddst(n3, isgn, t, ip, w)
call ddst(n3, isgn, t(n3), ip, w)
call ddst(n3, isgn, t(2 * n3), ip, w)
call ddst(n3, isgn, t(3 * n3), ip, w)
end if
do k = 0, n3 - 1
a(i, j, k) = t(k)
a(i + 1, j, k) = t(n3 + k)
a(i + 2, j, k) = t(2 * n3 + k)
a(i + 3, j, k) = t(3 * n3 + k)
end do
end do
end do
else if (n1 .eq. 2) then
do j = 0, n2 - 1
do k = 0, n3 - 1
t(k) = a(0, j, k)
t(n3 + k) = a(1, j, k)
end do
if (ics .eq. 0) then
call ddct(n3, isgn, t, ip, w)
call ddct(n3, isgn, t(n3), ip, w)
else
call ddst(n3, isgn, t, ip, w)
call ddst(n3, isgn, t(n3), ip, w)
end if
do k = 0, n3 - 1
a(0, j, k) = t(k)
a(1, j, k) = t(n3 + k)
end do
end do
end if
end
!