1 | ! Transformee de Fourier complexe-reelle multiple |
---|
2 | |
---|
3 | program tjmcsfft3d |
---|
4 | |
---|
5 | implicit none |
---|
6 | |
---|
7 | integer, parameter :: m = 1 |
---|
8 | integer, parameter :: n = 8 |
---|
9 | integer, parameter :: l = 8 |
---|
10 | complex, dimension(0:n/2,0:m-1,0:l-1) :: x, xx |
---|
11 | real, dimension(0:n/2,0:m-1,0:l-1,2) :: rx |
---|
12 | equivalence ( x, rx ) |
---|
13 | real, dimension(0:n-1+2,0:m-1,0:l-1) :: y |
---|
14 | |
---|
15 | ! Tableau temporaire pour forcer la symetrie hermitienne |
---|
16 | complex, dimension(0:m-1,0:l-1) :: z |
---|
17 | |
---|
18 | ! Pour stocker les cosinus et les sinus |
---|
19 | integer, parameter :: ntable = 100+2*(n+m+l) |
---|
20 | real, dimension(0:ntable-1) :: table |
---|
21 | |
---|
22 | ! Les routines jm ont besoin de 2*2*(n/2+1)*m*l. D'ou tronconnage. |
---|
23 | integer, parameter :: nwork = 512*max(n,m,l) |
---|
24 | real, dimension(0:nwork-1) :: work |
---|
25 | |
---|
26 | integer :: isign |
---|
27 | real :: scale |
---|
28 | integer :: isys |
---|
29 | integer :: i, j, k, iz, j1, k1 |
---|
30 | real :: twopi |
---|
31 | complex :: s |
---|
32 | integer :: j2, k2 |
---|
33 | |
---|
34 | ! On prepare deux tableaux d'entree |
---|
35 | ! x en forcant la symetrie hermitienne, sauf termes a parties reelles nulles |
---|
36 | ! xx en forcant la symetrie hermitienne, avec termes a parties reelles nulles |
---|
37 | call random_number( rx ) |
---|
38 | xx = x |
---|
39 | ! On force la symetrie hermitienne pour i=0 et i=n/2 |
---|
40 | do k = 0,l-1 |
---|
41 | k2 = l-k |
---|
42 | if (k == 0) k2 = 0 |
---|
43 | do j = 0,m-1 |
---|
44 | j2 = m-j |
---|
45 | if ( j== 0) j2 = 0 |
---|
46 | if ( ( j > j2 ) .or. ( j == j2 .and. k > k2 ) ) then |
---|
47 | x(0,j,k) = conjg( x( 0,j2,k2 ) ) |
---|
48 | xx(0,j,k) = conjg( xx( 0,j2,k2 ) ) |
---|
49 | end if |
---|
50 | ! Note : le test suivant engloble les cas 0 et moitie si parite |
---|
51 | !JMT- if ( (j==j2) .and. (k==k2) ) x(0,j,k) = real( x(0,j,k) ) |
---|
52 | if ( (j==j2) .and. (k==k2) ) xx(0,j,k) = real( xx(0,j,k), 8 ) |
---|
53 | end do |
---|
54 | end do |
---|
55 | if ( mod(n,2) == 0 ) then |
---|
56 | do k = 0,l-1 |
---|
57 | k2 = l-k |
---|
58 | if (k == 0) k2 = 0 |
---|
59 | do j = 0,m-1 |
---|
60 | j2 = m-j |
---|
61 | if ( j== 0) j2 = 0 |
---|
62 | if ( ( j > j2 ) .or. ( j == j2 .and. k > k2 ) ) then |
---|
63 | x(n/2,j,k) = conjg( x( n/2,j2,k2 ) ) |
---|
64 | xx(n/2,j,k) = conjg( xx( n/2,j2,k2 ) ) |
---|
65 | end if |
---|
66 | ! Note : le test suivant engloble les cas 0 et moitie si parite |
---|
67 | !JMT- if ( (j==j2) .and. (k==k2) ) x(n/2,j,k) = real( x(n/2,j,k) ) |
---|
68 | if ( (j==j2) .and. (k==k2) ) xx(n/2,j,k) = real( xx(n/2,j,k), 8 ) |
---|
69 | end do |
---|
70 | end do |
---|
71 | end if |
---|
72 | |
---|
73 | scale = 1. |
---|
74 | isys = 0 |
---|
75 | |
---|
76 | isign = 0 |
---|
77 | call csfft3d(isign,n,m,l,scale,x,n/2+1,m,y,n+2,m,table,work,isys) |
---|
78 | isign = 1 |
---|
79 | print *,'jmcsfft3d ',n,m,l,isign,scale |
---|
80 | call csfft3d(isign,n,m,l,scale,x,n/2+1,m,y,n+2,m,table,work,isys) |
---|
81 | |
---|
82 | ! On imprime le tableau de sortie |
---|
83 | open(10,file='temp1',status='unknown',form='formatted') |
---|
84 | write(10,'(e25.12)') y(0:n-1,0:m-1,0:l-1) |
---|
85 | close(10) |
---|
86 | |
---|
87 | ! Ce qu'il faut trouver |
---|
88 | x = xx |
---|
89 | open(11,file='temp2',status='unknown',form='formatted') |
---|
90 | twopi = 2 * acos(real(-1,8)) |
---|
91 | ! Et on calcule |
---|
92 | do k = 0,l-1 |
---|
93 | do j = 0,m-1 |
---|
94 | do i = 0,n-1 |
---|
95 | s = 0 |
---|
96 | do k1 = 0,l-1 |
---|
97 | do j1 = 0,m-1 |
---|
98 | do iz = 0,n/2 |
---|
99 | s = s+cmplx(cos(twopi*i*iz/real(n,8)),isign*sin(twopi*i*iz/real(n,8))) & |
---|
100 | & *cmplx(cos(twopi*j*j1/real(m,8)),isign*sin(twopi*j*j1/real(m,8))) & |
---|
101 | & *cmplx(cos(twopi*k*k1/real(l,8)),isign*sin(twopi*k*k1/real(l,8))) & |
---|
102 | & *x(iz,j1,k1) |
---|
103 | end do |
---|
104 | do iz = n/2+1,n-1 |
---|
105 | s = s+cmplx(cos(twopi*i*iz/real(n,8)),isign*sin(twopi*i*iz/real(n,8))) & |
---|
106 | & *cmplx(cos(twopi*j*j1/real(m,8)),isign*sin(twopi*j*j1/real(m,8))) & |
---|
107 | & *cmplx(cos(twopi*k*k1/real(l,8)),isign*sin(twopi*k*k1/real(l,8))) & |
---|
108 | & *conjg(x(n-iz,mod(m-j1,m),mod(l-k1,l))) |
---|
109 | end do |
---|
110 | end do |
---|
111 | end do |
---|
112 | write(11,'(2e25.12)') real(s*scale,8) |
---|
113 | end do |
---|
114 | end do |
---|
115 | end do |
---|
116 | close(11) |
---|
117 | |
---|
118 | end program tjmcsfft3d |
---|