| ! 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 |
| ! |