| ! Fast Fourier/Cosine/Sine Transform | |
| ! dimension :two | |
| ! data length :power of 2 | |
| ! decimation :frequency | |
| ! radix :split-radix, row-column | |
| ! data :inplace | |
| ! table :use | |
| ! subroutines | |
| ! cdft2d: Complex Discrete Fourier Transform | |
| ! rdft2d: Real Discrete Fourier Transform | |
| ! ddct2d: Discrete Cosine Transform | |
| ! ddst2d: Discrete Sine Transform | |
| ! necessary package | |
| ! fftsg.f : 1D-FFT package | |
| ! | |
| ! | |
| ! -------- Complex DFT (Discrete Fourier Transform) -------- | |
| ! [definition] | |
| ! <case1> | |
| ! X(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 x(j1,j2) * | |
| ! exp(2*pi*i*j1*k1/n1) * | |
| ! exp(2*pi*i*j2*k2/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! <case2> | |
| ! X(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 x(j1,j2) * | |
| ! exp(-2*pi*i*j1*k1/n1) * | |
| ! exp(-2*pi*i*j2*k2/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! (notes: sum_j=0^n-1 is a summation from j=0 to n-1) | |
| ! [usage] | |
| ! <case1> | |
| ! ip(0) = 0 ! first time only | |
| ! call cdft2d(n1max, 2*n1, n2, 1, a, t, ip, w) | |
| ! <case2> | |
| ! ip(0) = 0 ! first time only | |
| ! call cdft2d(n1max, 2*n1, n2, -1, a, t, ip, w) | |
| ! [parameters] | |
| ! n1max :row size of the 2D array (integer) | |
| ! 2*n1 :data length (integer) | |
| ! n1 >= 1, n1 = power of 2 | |
| ! n2 :data length (integer) | |
| ! n2 >= 1, n2 = power of 2 | |
| ! a(0:2*n1-1,0:n2-1) | |
| ! :input/output data (real*8) | |
| ! input data | |
| ! a(2*j1,j2) = Re(x(j1,j2)), | |
| ! a(2*j1+1,j2) = Im(x(j1,j2)), | |
| ! 0<=j1<n1, 0<=j2<n2 | |
| ! output data | |
| ! a(2*k1,k2) = Re(X(k1,k2)), | |
| ! a(2*k1+1,k2) = Im(X(k1,k2)), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! t(0:8*n2-1) | |
| ! :work area (real*8) | |
| ! length of t >= 8*n2 | |
| ! ip(0:*):work area for bit reversal (integer) | |
| ! length of ip >= 2+sqrt(n) | |
| ! (n = max(n1, n2)) | |
| ! 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) | |
| ! w(),ip() are initialized if ip(0) = 0. | |
| ! [remark] | |
| ! Inverse of | |
| ! call cdft2d(n1max, 2*n1, n2, -1, a, t, ip, w) | |
| ! is | |
| ! call cdft2d(n1max, 2*n1, n2, 1, a, t, ip, w) | |
| ! do j2 = 0, n2 - 1 | |
| ! do j1 = 0, 2 * n1 - 1 | |
| ! a(j1, j2) = a(j1, j2) * (1.0d0 / n1 / n2) | |
| ! end do | |
| ! end do | |
| ! . | |
| ! | |
| ! | |
| ! -------- Real DFT / Inverse of Real DFT -------- | |
| ! [definition] | |
| ! <case1> RDFT | |
| ! R(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 a(j1,j2) * | |
| ! cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! I(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 a(j1,j2) * | |
| ! sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! <case2> IRDFT (excluding scale) | |
| ! a(k1,k2) = (1/2) * sum_j1=0^n1-1 sum_j2=0^n2-1 | |
| ! (R(j1,j2) * | |
| ! cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2) + | |
| ! I(j1,j2) * | |
| ! sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2)), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! (notes: R(n1-k1,n2-k2) = R(k1,k2), | |
| ! I(n1-k1,n2-k2) = -I(k1,k2), | |
| ! R(n1-k1,0) = R(k1,0), | |
| ! I(n1-k1,0) = -I(k1,0), | |
| ! R(0,n2-k2) = R(0,k2), | |
| ! I(0,n2-k2) = -I(0,k2), | |
| ! 0<k1<n1, 0<k2<n2) | |
| ! [usage] | |
| ! <case1> | |
| ! ip(0) = 0 ! first time only | |
| ! call rdft2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! <case2> | |
| ! ip(0) = 0 ! first time only | |
| ! call rdft2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! [parameters] | |
| ! n1max :row size of the 2D array (integer) | |
| ! n1 :data length (integer) | |
| ! n1 >= 2, n1 = power of 2 | |
| ! n2 :data length (integer) | |
| ! n2 >= 2, n2 = power of 2 | |
| ! a(0:n1-1,0:n2-1) | |
| ! :input/output data (real*8) | |
| ! <case1> | |
| ! output data | |
| ! a(2*k1,k2) = R(k1,k2) = R(n1-k1,n2-k2), | |
| ! a(2*k1+1,k2) = I(k1,k2) = -I(n1-k1,n2-k2), | |
| ! 0<k1<n1/2, 0<k2<n2, | |
| ! a(2*k1,0) = R(k1,0) = R(n1-k1,0), | |
| ! a(2*k1+1,0) = I(k1,0) = -I(n1-k1,0), | |
| ! 0<k1<n1/2, | |
| ! a(0,k2) = R(0,k2) = R(0,n2-k2), | |
| ! a(1,k2) = I(0,k2) = -I(0,n2-k2), | |
| ! a(1,n2-k2) = R(n1/2,k2) = R(n1/2,n2-k2), | |
| ! a(0,n2-k2) = -I(n1/2,k2) = I(n1/2,n2-k2), | |
| ! 0<k2<n2/2, | |
| ! a(0,0) = R(0,0), | |
| ! a(1,0) = R(n1/2,0), | |
| ! a(0,n2/2) = R(0,n2/2), | |
| ! a(1,n2/2) = R(n1/2,n2/2) | |
| ! <case2> | |
| ! input data | |
| ! a(2*j1,j2) = R(j1,j2) = R(n1-j1,n2-j2), | |
| ! a(2*j1+1,j2) = I(j1,j2) = -I(n1-j1,n2-j2), | |
| ! 0<j1<n1/2, 0<j2<n2, | |
| ! a(2*j1,0) = R(j1,0) = R(n1-j1,0), | |
| ! a(2*j1+1,0) = I(j1,0) = -I(n1-j1,0), | |
| ! 0<j1<n1/2, | |
| ! a(0,j2) = R(0,j2) = R(0,n2-j2), | |
| ! a(1,j2) = I(0,j2) = -I(0,n2-j2), | |
| ! a(1,n2-j2) = R(n1/2,j2) = R(n1/2,n2-j2), | |
| ! a(0,n2-j2) = -I(n1/2,j2) = I(n1/2,n2-j2), | |
| ! 0<j2<n2/2, | |
| ! a(0,0) = R(0,0), | |
| ! a(1,0) = R(n1/2,0), | |
| ! a(0,n2/2) = R(0,n2/2), | |
| ! a(1,n2/2) = R(n1/2,n2/2) | |
| ! ---- output ordering ---- | |
| ! call rdft2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! call rdft2dsort(n1max, n1, n2, 1, a) | |
| ! ! stored data is a(0:n1-1,0:n2+1): | |
| ! ! a(2*k1,k2) = R(k1,k2), | |
| ! ! a(2*k1+1,k2) = I(k1,k2), | |
| ! ! 0<=k1<=n1/2, 0<=k2<n2. | |
| ! ! the stored data is larger than the input data! | |
| ! ---- input ordering ---- | |
| ! call rdft2dsort(n1max, n1, n2, -1, a) | |
| ! call rdft2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! t(0:8*n2-1) | |
| ! :work area (real*8) | |
| ! length of t >= 8*n2 | |
| ! ip(0:*):work area for bit reversal (integer) | |
| ! length of ip >= 2+sqrt(n) | |
| ! (n = max(n1/2, n2)) | |
| ! 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) + n1/4 | |
| ! w(),ip() are initialized if ip(0) = 0. | |
| ! [remark] | |
| ! Inverse of | |
| ! call rdft2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! is | |
| ! call rdft2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! do j2 = 0, n2 - 1 | |
| ! do j1 = 0, n1 - 1 | |
| ! a(j1, j2) = a(j1, j2) * (2.0d0 / n1 / n2) | |
| ! end do | |
| ! end do | |
| ! . | |
| ! | |
| ! | |
| ! -------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- | |
| ! [definition] | |
| ! <case1> IDCT (excluding scale) | |
| ! C(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 a(j1,j2) * | |
| ! cos(pi*j1*(k1+1/2)/n1) * | |
| ! cos(pi*j2*(k2+1/2)/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! <case2> DCT | |
| ! C(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 a(j1,j2) * | |
| ! cos(pi*(j1+1/2)*k1/n1) * | |
| ! cos(pi*(j2+1/2)*k2/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! [usage] | |
| ! <case1> | |
| ! ip(0) = 0 ! first time only | |
| ! call ddct2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! <case2> | |
| ! ip(0) = 0 ! first time only | |
| ! call ddct2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! [parameters] | |
| ! n1max :row size of the 2D array (integer) | |
| ! n1 :data length (integer) | |
| ! n1 >= 2, n1 = power of 2 | |
| ! n2 :data length (integer) | |
| ! n2 >= 2, n2 = power of 2 | |
| ! a(0:n1-1,0:n2-1) | |
| ! :input/output data (real*8) | |
| ! output data | |
| ! a(k1,k2) = C(k1,k2), 0<=k1<n1, 0<=k2<n2 | |
| ! t(0:4*n2-1) | |
| ! :work area (real*8) | |
| ! length of t >= 4*n2 | |
| ! ip(0:*):work area for bit reversal (integer) | |
| ! length of ip >= 2+sqrt(n) | |
| ! (n = max(n1/2, n2/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) | |
| ! w(),ip() are initialized if ip(0) = 0. | |
| ! [remark] | |
| ! Inverse of | |
| ! call ddct2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! is | |
| ! do j1 = 0, n1 - 1 | |
| ! a(j1, 0) = a(j1, 0) * 0.5d0 | |
| ! end do | |
| ! do j2 = 0, n2 - 1 | |
| ! a(0, j2) = a(0, j2) * 0.5d0 | |
| ! end do | |
| ! call ddct2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! do j2 = 0, n2 - 1 | |
| ! do j1 = 0, n1 - 1 | |
| ! a(j1, j2) = a(j1, j2) * (4.0d0 / n1 / n2) | |
| ! end do | |
| ! end do | |
| ! . | |
| ! | |
| ! | |
| ! -------- DST (Discrete Sine Transform) / Inverse of DST -------- | |
| ! [definition] | |
| ! <case1> IDST (excluding scale) | |
| ! S(k1,k2) = sum_j1=1^n1 sum_j2=1^n2 A(j1,j2) * | |
| ! sin(pi*j1*(k1+1/2)/n1) * | |
| ! sin(pi*j2*(k2+1/2)/n2), | |
| ! 0<=k1<n1, 0<=k2<n2 | |
| ! <case2> DST | |
| ! S(k1,k2) = sum_j1=0^n1-1 sum_j2=0^n2-1 a(j1,j2) * | |
| ! sin(pi*(j1+1/2)*k1/n1) * | |
| ! sin(pi*(j2+1/2)*k2/n2), | |
| ! 0<k1<=n1, 0<k2<=n2 | |
| ! [usage] | |
| ! <case1> | |
| ! ip(0) = 0 ! first time only | |
| ! call ddst2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! <case2> | |
| ! ip(0) = 0 ! first time only | |
| ! call ddst2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! [parameters] | |
| ! n1max :row size of the 2D array (integer) | |
| ! n1 :data length (integer) | |
| ! n1 >= 2, n1 = power of 2 | |
| ! n2 :data length (integer) | |
| ! n2 >= 2, n2 = power of 2 | |
| ! a(0:n1-1,0:n2-1) | |
| ! :input/output data (real*8) | |
| ! <case1> | |
| ! input data | |
| ! a(j1,j2) = A(j1,j2), 0<j1<n1, 0<j2<n2, | |
| ! a(j1,0) = A(j1,n2), 0<j1<n1, | |
| ! a(0,j2) = A(n1,j2), 0<j2<n2, | |
| ! a(0,0) = A(n1,n2) | |
| ! (i.e. A(j1,j2) = a(mod(j1,n1),mod(j2,n2))) | |
| ! output data | |
| ! a(k1,k2) = S(k1,k2), 0<=k1<n1, 0<=k2<n2 | |
| ! <case2> | |
| ! output data | |
| ! a(k1,k2) = S(k1,k2), 0<k1<n1, 0<k2<n2, | |
| ! a(k1,0) = S(k1,n2), 0<k1<n1, | |
| ! a(0,k2) = S(n1,k2), 0<k2<n2, | |
| ! a(0,0) = S(n1,n2) | |
| ! (i.e. S(k1,k2) = a(mod(k1,n1),mod(k2,n2))) | |
| ! t(0:4*n2-1) | |
| ! :work area (real*8) | |
| ! length of t >= 4*n2 | |
| ! ip(0:*):work area for bit reversal (integer) | |
| ! length of ip >= 2+sqrt(n) | |
| ! (n = max(n1/2, n2/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) | |
| ! w(),ip() are initialized if ip(0) = 0. | |
| ! [remark] | |
| ! Inverse of | |
| ! call ddst2d(n1max, n1, n2, -1, a, t, ip, w) | |
| ! is | |
| ! do j1 = 0, n1 - 1 | |
| ! a(j1, 0) = a(j1, 0) * 0.5d0 | |
| ! end do | |
| ! do j2 = 0, n2 - 1 | |
| ! a(0, j2) = a(0, j2) * 0.5d0 | |
| ! end do | |
| ! call ddst2d(n1max, n1, n2, 1, a, t, ip, w) | |
| ! do j2 = 0, n2 - 1 | |
| ! do j1 = 0, n1 - 1 | |
| ! a(j1, j2) = a(j1, j2) * (4.0d0 / n1 / n2) | |
| ! end do | |
| ! end do | |
| ! . | |
| ! | |
| ! | |
| subroutine cdft2d(n1max, n1, n2, isgn, a, t, ip, w) | |
| integer n1max, n1, n2, isgn, ip(0 : *), n, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 8 * n2 - 1), | |
| & w(0 : *) | |
| n = max(n1, 2 * n2) | |
| if (n .gt. 4 * ip(0)) then | |
| call makewt(n / 4, ip, w) | |
| end if | |
| do j = 0, n2 - 1 | |
| call cdft(n1, isgn, a(0, j), ip, w) | |
| end do | |
| call cdft2d_sub(n1max, n1, n2, isgn, a, t, ip, w) | |
| end | |
| ! | |
| subroutine rdft2d(n1max, n1, n2, isgn, a, t, ip, w) | |
| integer n1max, n1, n2, isgn, ip(0 : *), n, nw, nc, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 8 * n2 - 1), | |
| & w(0 : *) | |
| n = max(n1, 2 * n2) | |
| 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 rdft2d_sub(n1max, n1, n2, isgn, a) | |
| call cdft2d_sub(n1max, n1, n2, isgn, a, t, ip, w) | |
| end if | |
| do j = 0, n2 - 1 | |
| call rdft(n1, isgn, a(0, j), ip, w) | |
| end do | |
| if (isgn .ge. 0) then | |
| call cdft2d_sub(n1max, n1, n2, isgn, a, t, ip, w) | |
| call rdft2d_sub(n1max, n1, n2, isgn, a) | |
| end if | |
| end | |
| ! | |
| subroutine rdft2dsort(n1max, n1, n2, isgn, a) | |
| integer n1max, n1, n2, isgn, n2h, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), x, y | |
| n2h = n2 / 2 | |
| if (isgn .lt. 0) then | |
| do j = n2h + 1, n2 - 1 | |
| a(0, j) = a(n1 + 1, j) | |
| a(1, j) = a(n1, j) | |
| end do | |
| a(1, 0) = a(n1, 0) | |
| a(1, n2h) = a(n1, n2h) | |
| else | |
| do j = n2h + 1, n2 - 1 | |
| y = a(0, j) | |
| x = a(1, j) | |
| a(n1, j) = x | |
| a(n1 + 1, j) = y | |
| a(n1, n2 - j) = x | |
| a(n1 + 1, n2 - j) = -y | |
| a(0, j) = a(0, n2 - j) | |
| a(1, j) = -a(1, n2 - j) | |
| end do | |
| a(n1, 0) = a(1, 0) | |
| a(n1 + 1, 0) = 0 | |
| a(1, 0) = 0 | |
| a(n1, n2h) = a(1, n2h) | |
| a(n1 + 1, n2h) = 0 | |
| a(1, n2h) = 0 | |
| end if | |
| end | |
| ! | |
| subroutine ddct2d(n1max, n1, n2, isgn, a, t, ip, w) | |
| integer n1max, n1, n2, isgn, ip(0 : *), n, nw, nc, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 4 * n2 - 1), | |
| & w(0 : *) | |
| n = max(n1, n2) | |
| 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 | |
| do j = 0, n2 - 1 | |
| call ddct(n1, isgn, a(0, j), ip, w) | |
| end do | |
| call ddxt2d_sub(n1max, n1, n2, 0, isgn, a, t, ip, w) | |
| end | |
| ! | |
| subroutine ddst2d(n1max, n1, n2, isgn, a, t, ip, w) | |
| integer n1max, n1, n2, isgn, ip(0 : *), n, nw, nc, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 4 * n2 - 1), | |
| & w(0 : *) | |
| n = max(n1, n2) | |
| 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 | |
| do j = 0, n2 - 1 | |
| call ddst(n1, isgn, a(0, j), ip, w) | |
| end do | |
| call ddxt2d_sub(n1max, n1, n2, 1, isgn, a, t, ip, w) | |
| end | |
| ! | |
| ! -------- child routines -------- | |
| ! | |
| subroutine cdft2d_sub(n1max, n1, n2, isgn, a, t, ip, w) | |
| integer n1max, n1, n2, isgn, ip(0 : *), i, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 8 * n2 - 1), | |
| & w(0 : *) | |
| if (n1 .gt. 4) then | |
| do i = 0, n1 - 8, 8 | |
| do j = 0, n2 - 1 | |
| t(2 * j) = a(i, j) | |
| t(2 * j + 1) = a(i + 1, j) | |
| t(2 * n2 + 2 * j) = a(i + 2, j) | |
| t(2 * n2 + 2 * j + 1) = a(i + 3, j) | |
| t(4 * n2 + 2 * j) = a(i + 4, j) | |
| t(4 * n2 + 2 * j + 1) = a(i + 5, j) | |
| t(6 * n2 + 2 * j) = a(i + 6, j) | |
| t(6 * n2 + 2 * j + 1) = a(i + 7, j) | |
| 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) = t(2 * j) | |
| a(i + 1, j) = t(2 * j + 1) | |
| a(i + 2, j) = t(2 * n2 + 2 * j) | |
| a(i + 3, j) = t(2 * n2 + 2 * j + 1) | |
| a(i + 4, j) = t(4 * n2 + 2 * j) | |
| a(i + 5, j) = t(4 * n2 + 2 * j + 1) | |
| a(i + 6, j) = t(6 * n2 + 2 * j) | |
| a(i + 7, j) = 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) | |
| t(2 * j + 1) = a(1, j) | |
| t(2 * n2 + 2 * j) = a(2, j) | |
| t(2 * n2 + 2 * j + 1) = a(3, j) | |
| 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) = t(2 * j) | |
| a(1, j) = t(2 * j + 1) | |
| a(2, j) = t(2 * n2 + 2 * j) | |
| a(3, j) = 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) | |
| t(2 * j + 1) = a(1, j) | |
| end do | |
| call cdft(2 * n2, isgn, t, ip, w) | |
| do j = 0, n2 - 1 | |
| a(0, j) = t(2 * j) | |
| a(1, j) = t(2 * j + 1) | |
| end do | |
| end if | |
| end | |
| ! | |
| subroutine rdft2d_sub(n1max, n1, n2, isgn, a) | |
| integer n1max, n1, n2, isgn, n2h, i, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), xi | |
| n2h = n2 / 2 | |
| if (isgn .lt. 0) then | |
| do i = 1, n2h - 1 | |
| j = n2 - i | |
| xi = a(0, i) - a(0, j) | |
| a(0, i) = a(0, i) + a(0, j) | |
| a(0, j) = xi | |
| xi = a(1, j) - a(1, i) | |
| a(1, i) = a(1, i) + a(1, j) | |
| a(1, j) = xi | |
| end do | |
| else | |
| do i = 1, n2h - 1 | |
| j = n2 - i | |
| a(0, j) = 0.5d0 * (a(0, i) - a(0, j)) | |
| a(0, i) = a(0, i) - a(0, j) | |
| a(1, j) = 0.5d0 * (a(1, i) + a(1, j)) | |
| a(1, i) = a(1, i) - a(1, j) | |
| end do | |
| end if | |
| end | |
| ! | |
| subroutine ddxt2d_sub(n1max, n1, n2, ics, isgn, a, t, | |
| & ip, w) | |
| integer n1max, n1, n2, ics, isgn, ip(0 : *), i, j | |
| real*8 a(0 : n1max - 1, 0 : n2 - 1), t(0 : 4 * n2 - 1), | |
| & w(0 : *) | |
| if (n1 .gt. 2) then | |
| do i = 0, n1 - 4, 4 | |
| do j = 0, n2 - 1 | |
| t(j) = a(i, j) | |
| t(n2 + j) = a(i + 1, j) | |
| t(2 * n2 + j) = a(i + 2, j) | |
| t(3 * n2 + j) = a(i + 3, j) | |
| 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) = t(j) | |
| a(i + 1, j) = t(n2 + j) | |
| a(i + 2, j) = t(2 * n2 + j) | |
| a(i + 3, j) = t(3 * n2 + j) | |
| end do | |
| end do | |
| else if (n1 .eq. 2) then | |
| do j = 0, n2 - 1 | |
| t(j) = a(0, j) | |
| t(n2 + j) = a(1, j) | |
| 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) = t(j) | |
| a(1, j) = t(n2 + j) | |
| end do | |
| end if | |
| end | |
| ! |