grid_singleton.F90 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. MODULE grid_singleton
  2. !-----------------------------------------------------------------------------
  3. ! Multivariate Fast Fourier Transform
  4. !
  5. ! Fortran 90 Implementation of Singleton's mixed-radix algorithm,
  6. ! RC Singleton, Stanford Research Institute, Sept. 1968.
  7. !
  8. ! Adapted from fftn.c, translated from Fortran 66 to C by Mark Olesen and
  9. ! John Beale.
  10. !
  11. ! Fourier transforms can be computed either in place, using assumed size
  12. ! arguments, or by generic function, using assumed shape arguments.
  13. !
  14. !
  15. ! Public:
  16. !
  17. ! fftkind kind parameter of complex arguments
  18. ! and function results.
  19. !
  20. ! fft(array, dim, inv, stat) generic transform function
  21. ! COMPLEX(fftkind), DIMENSION(:,...,:), INTENT(IN) :: array
  22. ! INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  23. ! LOGICAL, INTENT(IN), OPTIONAL:: inv
  24. ! INTEGER, INTENT(OUT), OPTIONAL:: stat
  25. !
  26. ! fftn(array, shape, dim, inv, stat) in place transform subroutine
  27. ! COMPLEX(fftkind), DIMENSION(*), INTENT(INOUT) :: array
  28. ! INTEGER, DIMENSION(:), INTENT(IN) :: shape
  29. ! INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  30. ! LOGICAL, INTENT(IN), OPTIONAL:: inv
  31. ! INTEGER, INTENT(OUT), OPTIONAL:: stat
  32. !
  33. !
  34. ! Formal Parameters:
  35. !
  36. ! array The complex array to be transformed. array can be of arbitrary
  37. ! rank (i.e. up to seven).
  38. !
  39. ! shape With subroutine fftn, the shape of the array to be transformed
  40. ! has to be passed separately, since fftradix - the internal trans-
  41. ! formation routine - will treat array always as one dimensional.
  42. ! The product of elements in shape must be the number of
  43. ! elements in array.
  44. ! Although passing array with assumed shape would have been nicer,
  45. ! I prefered assumed size in order to prevent the compiler from
  46. ! using a copy-in-copy-out mechanism. That would generally be
  47. ! necessary with fftn passing array to fftradix and with fftn
  48. ! being prepared for accepting non consecutive array sections.
  49. ! Using assumed size, it's up to the user to pass an array argu-
  50. ! ment, that can be addressed as continous one dimensional array
  51. ! without copying. Otherwise, transformation will not really be
  52. ! performed in place.
  53. ! On the other hand, since the rank of array and the size of
  54. ! shape needn't match, fftn is appropriate for handling more than
  55. ! seven dimensions.
  56. ! As far as function fft is concerned all this doesn't matter,
  57. ! because the argument will be copied anyway. Thus no extra
  58. ! shape argument is needed for fft.
  59. !
  60. ! Optional Parameters:
  61. !
  62. ! dim One dimensional integer array, containing the dimensions to be
  63. ! transformed. Default is (/1,...,N/) with N being the rank of
  64. ! array, i.e. complete transform. dim can restrict transformation
  65. ! to a subset of available dimensions. Its size must not exceed the
  66. ! rank of array or the size of shape respectivly.
  67. !
  68. ! inv If .true., inverse transformation will be performed. Default is
  69. ! .false., i.e. forward transformation.
  70. !
  71. ! stat If present, a system dependent nonzero status value will be
  72. ! returned in stat, if allocation of temporary storage failed.
  73. !
  74. !
  75. ! Scaling:
  76. !
  77. ! Transformation results will always be scaled by the square root of the
  78. ! product of sizes of each dimension in dim. (See examples below)
  79. !
  80. !
  81. ! Examples:
  82. !
  83. ! Let A be a L*M*N three dimensional complex array. Then
  84. !
  85. ! result = fft(A)
  86. !
  87. ! will produce a three dimensional transform, scaled by sqrt(L*M*N), while
  88. !
  89. ! call fftn(A, SHAPE(A))
  90. !
  91. ! will do the same in place.
  92. !
  93. ! result = fft(A, dim=(/1,3/))
  94. !
  95. ! will transform with respect to the first and the third dimension, scaled
  96. ! by sqrt(L*N).
  97. !
  98. ! result = fft(fft(A), inv=.true.)
  99. !
  100. ! should (approximately) reproduce A.
  101. ! With B having the same shape as A
  102. !
  103. ! result = fft(fft(A) * CONJG(fft(B)), inv=.true.)
  104. !
  105. ! will correlate A and B.
  106. !
  107. !
  108. ! Remarks:
  109. !
  110. ! Following changes have been introduced with respect to fftn.c:
  111. ! - complex arguments and results are of type complex, rather than
  112. ! real an imaginary part separately.
  113. ! - increment parameter (magnitude of isign) has been dropped,
  114. ! inc is always one, direction of transform is given by inv.
  115. ! - maxf and maxp have been dropped. The amount of temporary storage
  116. ! needed is determined by the fftradix routine. Both fftn and fft
  117. ! can handle any size of array. (Maybe they take a lot of time and
  118. ! memory, but they will do it)
  119. !
  120. ! Redesigning fftradix in a way, that it handles assumed shape arrays
  121. ! would have been desirable. However, I found it rather hard to do this
  122. ! in an efficient way. Problems were:
  123. ! - to prevent stride multiplications when indexing arrays. At least our
  124. ! compiler was not clever enough to discover that in fact additions
  125. ! would do the job as well. On the other hand, I haven't been clever
  126. ! enough to find an implementation using array operations.
  127. ! - fftradix is rather large and different versions would be necessaray
  128. ! for each possible rank of array.
  129. ! Consequently, in place transformation still needs the argument stored
  130. ! in a consecutive bunch of memory and can't be performed on array
  131. ! sections like A(100:199:-3, 50:1020). Calling fftn with such sections
  132. ! will most probably imply copy-in-copy-out. However, the function fft
  133. ! works with everything it gets and should be convenient to use.
  134. !
  135. ! Michael Steffens, 09.12.96, <Michael.Steffens@mbox.muk.uni-hannover.de>
  136. !-----------------------------------------------------------------------------
  137. IMPLICIT NONE
  138. PRIVATE
  139. PUBLIC:: fft, fftn, fftkind
  140. INTEGER, PARAMETER:: fftkind = KIND(0.0) !--- adjust here for other precisions
  141. REAL(fftkind), PARAMETER:: sin60 = 0.86602540378443865_fftkind
  142. REAL(fftkind), PARAMETER:: cos72 = 0.30901699437494742_fftkind
  143. REAL(fftkind), PARAMETER:: sin72 = 0.95105651629515357_fftkind
  144. REAL(fftkind), PARAMETER:: pi = 3.14159265358979323_fftkind
  145. INTERFACE fft
  146. MODULE PROCEDURE fft1d
  147. MODULE PROCEDURE fft2d
  148. MODULE PROCEDURE fft3d
  149. MODULE PROCEDURE fft4d
  150. MODULE PROCEDURE fft5d
  151. MODULE PROCEDURE fft6d
  152. MODULE PROCEDURE fft7d
  153. END INTERFACE
  154. CONTAINS
  155. FUNCTION fft1d(array, dim, inv, stat) RESULT(ft)
  156. !--- formal parameters
  157. COMPLEX(fftkind), DIMENSION(:), INTENT(IN) :: array
  158. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  159. LOGICAL, INTENT(IN), OPTIONAL:: inv
  160. INTEGER, INTENT(OUT), OPTIONAL:: stat
  161. !--- function result
  162. COMPLEX(fftkind), DIMENSION(SIZE(array, 1)):: ft
  163. !--- intrinsics used
  164. INTRINSIC SIZE, SHAPE
  165. ft = array
  166. CALL fftn(ft, SHAPE(array), inv = inv, stat = stat)
  167. END FUNCTION fft1d
  168. FUNCTION fft2d(array, dim, inv, stat) RESULT(ft)
  169. !--- formal parameters
  170. COMPLEX(fftkind), DIMENSION(:,:), INTENT(IN) :: array
  171. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  172. LOGICAL, INTENT(IN), OPTIONAL:: inv
  173. INTEGER, INTENT(OUT), OPTIONAL:: stat
  174. !--- function result
  175. COMPLEX(fftkind), DIMENSION(SIZE(array, 1), SIZE(array, 2)):: ft
  176. !--- intrinsics used
  177. INTRINSIC SIZE, SHAPE
  178. ft = array
  179. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  180. END FUNCTION fft2d
  181. FUNCTION fft3d(array, dim, inv, stat) RESULT(ft)
  182. !--- formal parameters
  183. COMPLEX(fftkind), DIMENSION(:,:,:), INTENT(IN) :: array
  184. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  185. LOGICAL, INTENT(IN), OPTIONAL:: inv
  186. INTEGER, INTENT(OUT), OPTIONAL:: stat
  187. !--- function result
  188. COMPLEX(fftkind), &
  189. DIMENSION(SIZE(array, 1), SIZE(array, 2), SIZE(array, 3)):: ft
  190. !--- intrinsics used
  191. INTRINSIC SIZE, SHAPE
  192. ft = array
  193. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  194. END FUNCTION fft3d
  195. FUNCTION fft4d(array, dim, inv, stat) RESULT(ft)
  196. !--- formal parameters
  197. COMPLEX(fftkind), DIMENSION(:,:,:,:), INTENT(IN) :: array
  198. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  199. LOGICAL, INTENT(IN), OPTIONAL:: inv
  200. INTEGER, INTENT(OUT), OPTIONAL:: stat
  201. !--- function result
  202. COMPLEX(fftkind), DIMENSION( &
  203. SIZE(array, 1), SIZE(array, 2), SIZE(array, 3), SIZE(array, 4)):: ft
  204. !--- intrinsics used
  205. INTRINSIC SIZE, SHAPE
  206. ft = array
  207. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  208. END FUNCTION fft4d
  209. FUNCTION fft5d(array, dim, inv, stat) RESULT(ft)
  210. !--- formal parameters
  211. COMPLEX(fftkind), DIMENSION(:,:,:,:,:), INTENT(IN) :: array
  212. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  213. LOGICAL, INTENT(IN), OPTIONAL:: inv
  214. INTEGER, INTENT(OUT), OPTIONAL:: stat
  215. !--- function result
  216. COMPLEX(fftkind), DIMENSION( &
  217. SIZE(array, 1), SIZE(array, 2), SIZE(array, 3), SIZE(array, 4), &
  218. SIZE(array, 5)):: ft
  219. !--- intrinsics used
  220. INTRINSIC SIZE, SHAPE
  221. ft = array
  222. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  223. END FUNCTION fft5d
  224. FUNCTION fft6d(array, dim, inv, stat) RESULT(ft)
  225. !--- formal parameters
  226. COMPLEX(fftkind), DIMENSION(:,:,:,:,:,:), INTENT(IN) :: array
  227. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  228. LOGICAL, INTENT(IN), OPTIONAL:: inv
  229. INTEGER, INTENT(OUT), OPTIONAL:: stat
  230. !--- function result
  231. COMPLEX(fftkind), DIMENSION( &
  232. SIZE(array, 1), SIZE(array, 2), SIZE(array, 3), SIZE(array, 4), &
  233. SIZE(array, 5), SIZE(array, 6)):: ft
  234. !--- intrinsics used
  235. INTRINSIC SIZE, SHAPE
  236. ft = array
  237. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  238. END FUNCTION fft6d
  239. FUNCTION fft7d(array, dim, inv, stat) RESULT(ft)
  240. !--- formal parameters
  241. COMPLEX(fftkind), DIMENSION(:,:,:,:,:,:,:), INTENT(IN) :: array
  242. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  243. LOGICAL, INTENT(IN), OPTIONAL:: inv
  244. INTEGER, INTENT(OUT), OPTIONAL:: stat
  245. !--- function result
  246. COMPLEX(fftkind), DIMENSION( &
  247. SIZE(array, 1), SIZE(array, 2), SIZE(array, 3), SIZE(array, 4), &
  248. SIZE(array, 5), SIZE(array, 6), SIZE(array, 7)):: ft
  249. !--- intrinsics used
  250. INTRINSIC SIZE, SHAPE
  251. ft = array
  252. CALL fftn(ft, SHAPE(array), dim, inv, stat)
  253. END FUNCTION fft7d
  254. SUBROUTINE fftn(array, shape, dim, inv, stat)
  255. !--- formal parameters
  256. COMPLEX(fftkind), DIMENSION(*), INTENT(INOUT) :: array
  257. INTEGER, DIMENSION(:), INTENT(IN) :: shape
  258. INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL:: dim
  259. LOGICAL, INTENT(IN), OPTIONAL:: inv
  260. INTEGER, INTENT(OUT), OPTIONAL:: stat
  261. !--- local arrays
  262. INTEGER, DIMENSION(SIZE(shape)):: d
  263. !--- local scalars
  264. LOGICAL :: inverse
  265. INTEGER :: i, ndim, ntotal
  266. REAL(fftkind):: scale
  267. !--- intrinsics used
  268. !>>> ecgate ibm fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  269. !INTRINSIC PRESENT, MIN, PRODUCT, SIZE, SQRT
  270. INTRINSIC PRESENT, MIN, PRODUCT, SIZE
  271. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  272. !--- optional parameter settings
  273. IF (PRESENT(inv)) THEN
  274. inverse = inv
  275. ELSE
  276. inverse = .FALSE.
  277. END IF
  278. IF (PRESENT(dim)) THEN
  279. ndim = MIN(SIZE(dim), SIZE(d))
  280. d(1:ndim) = dim(1:ndim)
  281. ELSE
  282. ndim = SIZE(d)
  283. d = (/(i, i = 1, SIZE(d))/)
  284. END IF
  285. ntotal = PRODUCT(shape)
  286. scale = SQRT(1.0_fftkind / PRODUCT(shape(d(1:ndim))))
  287. ! FORALL (i = 1: ntotal) array(i) = array(i) * scale
  288. DO i = 1, ntotal
  289. array(i) = array(i) * scale
  290. END DO
  291. DO i = 1, ndim
  292. CALL fftradix(array, ntotal, shape(d(i)), PRODUCT(shape(1:d(i))), &
  293. inverse, stat)
  294. IF (PRESENT(stat)) then
  295. IF (stat /=0) RETURN
  296. END IF
  297. END DO
  298. END SUBROUTINE fftn
  299. SUBROUTINE fftradix(array, ntotal, npass, nspan, inv, stat)
  300. !--- formal parameters
  301. INTEGER, INTENT(IN) :: ntotal, npass, nspan
  302. COMPLEX(fftkind), DIMENSION(*), INTENT(INOUT) :: array
  303. LOGICAL, INTENT(IN) :: inv
  304. INTEGER, INTENT(OUT), OPTIONAL:: stat
  305. !--- local arrays
  306. INTEGER, DIMENSION(BIT_SIZE(0)) :: factor
  307. COMPLEX(fftkind), DIMENSION(:), ALLOCATABLE :: ctmp
  308. REAL(fftkind), DIMENSION(:), ALLOCATABLE :: sine, cosine
  309. INTEGER, DIMENSION(:), ALLOCATABLE :: perm
  310. !--- local scalars
  311. INTEGER :: ii, kspan, ispan
  312. INTEGER :: j, jc, jf, jj, k, k1, k2, k3, k4, kk, kt, nn, ns, nt
  313. INTEGER :: maxfactor, nfactor, nperm
  314. REAL(fftkind) :: s60, c72, s72, pi2
  315. REAL(fftkind) :: radf
  316. REAL(fftkind) :: c1, c2, c3, cd, ak
  317. REAL(fftkind) :: s1, s2, s3, sd
  318. COMPLEX(fftkind):: cc, cj, ck, cjp, cjm, ckp, ckm
  319. !--- intrinsics used
  320. !>>> ecgate ibm fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  321. !INTRINSIC MAXVAL, MOD, PRESENT, ISHFT, BIT_SIZE, SIN, COS, &
  322. ! CMPLX, REAL, AIMAG
  323. INTRINSIC MAXVAL, MOD, PRESENT, ISHFT, BIT_SIZE, &
  324. CMPLX, REAL
  325. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  326. IF (npass <= 1) RETURN
  327. c72 = cos72
  328. IF (inv) THEN
  329. s72 = sin72
  330. s60 = sin60
  331. pi2 = pi
  332. ELSE
  333. s72 = -sin72
  334. s60 = -sin60
  335. pi2 = -pi
  336. END IF
  337. nt = ntotal
  338. ns = nspan
  339. kspan = ns
  340. nn = nt - 1
  341. jc = ns / npass
  342. radf = pi2 * jc
  343. pi2 = pi2 * 2.0_fftkind !-- use 2 PI from here on
  344. CALL factorize
  345. maxfactor = MAXVAL(factor (:nfactor))
  346. IF (nfactor - ISHFT(kt, 1) > 0) THEN
  347. nperm = MAX(nfactor + 1, PRODUCT(factor(kt+1: nfactor-kt)) - 1)
  348. ELSE
  349. nperm = nfactor + 1
  350. END IF
  351. IF (PRESENT(stat)) THEN
  352. ALLOCATE(ctmp(maxfactor), sine(maxfactor), cosine(maxfactor), STAT=stat)
  353. IF (stat /= 0) RETURN
  354. CALL transform
  355. DEALLOCATE(sine, cosine, STAT=stat)
  356. IF (stat /= 0) RETURN
  357. ALLOCATE(perm(nperm), STAT=stat)
  358. IF (stat /= 0) RETURN
  359. CALL permute
  360. DEALLOCATE(perm, ctmp, STAT=stat)
  361. IF (stat /= 0) RETURN
  362. ELSE
  363. ALLOCATE(ctmp(maxfactor), sine(maxfactor), cosine(maxfactor))
  364. CALL transform
  365. DEALLOCATE(sine, cosine)
  366. ALLOCATE(perm(nperm))
  367. CALL permute
  368. DEALLOCATE(perm, ctmp)
  369. END IF
  370. CONTAINS
  371. SUBROUTINE factorize
  372. nfactor = 0
  373. k = npass
  374. DO WHILE (MOD(k, 16) == 0)
  375. nfactor = nfactor + 1
  376. factor (nfactor) = 4
  377. k = k / 16
  378. END DO
  379. j = 3
  380. jj = 9
  381. DO
  382. DO WHILE (MOD(k, jj) == 0)
  383. nfactor=nfactor + 1
  384. factor (nfactor) = j
  385. k = k / jj
  386. END DO
  387. j = j + 2
  388. jj = j * j
  389. IF (jj > k) EXIT
  390. END DO
  391. IF (k <= 4) THEN
  392. kt = nfactor
  393. factor (nfactor + 1) = k
  394. IF (k /= 1) nfactor = nfactor + 1
  395. ELSE
  396. IF (k - ISHFT(k / 4, 2) == 0) THEN
  397. nfactor = nfactor + 1
  398. factor (nfactor) = 2
  399. k = k / 4
  400. END IF
  401. kt = nfactor
  402. j = 2
  403. DO
  404. IF (MOD(k, j) == 0) THEN
  405. nfactor = nfactor + 1
  406. factor (nfactor) = j
  407. k = k / j
  408. END IF
  409. j = ISHFT((j + 1)/2, 1) + 1
  410. IF (j > k) EXIT
  411. END DO
  412. END IF
  413. IF (kt > 0) THEN
  414. j = kt
  415. DO
  416. nfactor = nfactor + 1
  417. factor (nfactor) = factor (j)
  418. j = j - 1
  419. IF (j==0) EXIT
  420. END DO
  421. END IF
  422. END SUBROUTINE factorize
  423. SUBROUTINE transform !-- compute fourier transform
  424. ii = 0
  425. jf = 0
  426. DO
  427. sd = radf / kspan
  428. cd = SIN(sd)
  429. cd = 2.0_fftkind * cd * cd
  430. sd = SIN(sd + sd)
  431. kk = 1
  432. ii = ii + 1
  433. SELECT CASE (factor (ii))
  434. CASE (2)
  435. !-- transform for factor of 2 (including rotation factor)
  436. kspan = kspan / 2;
  437. k1 = kspan + 2
  438. DO
  439. DO
  440. k2 = kk + kspan
  441. ck = array(k2)
  442. array(k2) = array(kk)-ck
  443. array(kk) = array(kk) + ck
  444. kk = k2 + kspan;
  445. IF (kk > nn) EXIT
  446. END DO
  447. kk = kk - nn;
  448. IF (kk > jc) EXIT
  449. END DO
  450. IF (kk > kspan) RETURN
  451. DO
  452. c1 = 1.0_fftkind - cd
  453. s1 = sd
  454. DO
  455. DO
  456. DO
  457. k2 = kk + kspan
  458. ck = array(kk) - array(k2)
  459. array(kk) = array(kk) + array(k2)
  460. array(k2) = ck * CMPLX(c1, s1, kind=fftkind)
  461. kk = k2 + kspan
  462. IF (kk >= nt) EXIT
  463. END DO
  464. k2 = kk - nt
  465. c1 = -c1
  466. kk = k1 - k2
  467. IF (kk <= k2) EXIT
  468. END DO
  469. ak = c1 - (cd * c1 + sd * s1)
  470. s1 = sd * c1 - cd * s1 + s1
  471. c1 = 2.0_fftkind - (ak * ak + s1 * s1)
  472. s1 = s1 * c1
  473. c1 = c1 * ak
  474. kk = kk + jc
  475. IF (kk >= k2) EXIT
  476. END DO
  477. k1 = k1 + 1 + 1
  478. kk = (k1 - kspan) / 2 + jc
  479. IF (kk > jc + jc) EXIT
  480. END DO
  481. CASE (4) !-- transform for factor of 4
  482. ispan = kspan
  483. kspan = kspan / 4
  484. DO
  485. c1 = 1.0_fftkind
  486. s1 = 0.0_fftkind
  487. DO
  488. DO
  489. k1 = kk + kspan
  490. k2 = k1 + kspan
  491. k3 = k2 + kspan
  492. ckp = array(kk) + array(k2)
  493. ckm = array(kk) - array(k2)
  494. cjp = array(k1) + array(k3)
  495. cjm = array(k1) - array(k3)
  496. array(kk) = ckp + cjp
  497. cjp = ckp - cjp
  498. IF (inv) THEN
  499. ckp = ckm + CMPLX(-AIMAG(cjm), REAL(cjm), kind=fftkind)
  500. ckm = ckm + CMPLX(AIMAG(cjm), -REAL(cjm), kind=fftkind)
  501. ELSE
  502. ckp = ckm + CMPLX(AIMAG(cjm), -REAL(cjm), kind=fftkind)
  503. ckm = ckm + CMPLX(-AIMAG(cjm), REAL(cjm), kind=fftkind)
  504. END IF
  505. !-- avoid useless multiplies
  506. IF (s1 == 0.0_fftkind) THEN
  507. array(k1) = ckp
  508. array(k2) = cjp
  509. array(k3) = ckm
  510. ELSE
  511. array(k1) = ckp * CMPLX(c1, s1, kind=fftkind)
  512. array(k2) = cjp * CMPLX(c2, s2, kind=fftkind)
  513. array(k3) = ckm * CMPLX(c3, s3, kind=fftkind)
  514. END IF
  515. kk = k3 + kspan
  516. IF (kk > nt) EXIT
  517. END DO
  518. c2 = c1 - (cd * c1 + sd * s1)
  519. s1 = sd * c1 - cd * s1 + s1
  520. c1 = 2.0_fftkind - (c2 * c2 + s1 * s1)
  521. s1 = s1 * c1
  522. c1 = c1 * c2
  523. !-- values of c2, c3, s2, s3 that will get used next time
  524. c2 = c1 * c1 - s1 * s1
  525. s2 = 2.0_fftkind * c1 * s1
  526. c3 = c2 * c1 - s2 * s1
  527. s3 = c2 * s1 + s2 * c1
  528. kk = kk - nt + jc
  529. IF (kk > kspan) EXIT
  530. END DO
  531. kk = kk - kspan + 1
  532. IF (kk > jc) EXIT
  533. END DO
  534. IF (kspan == jc) RETURN
  535. CASE default
  536. !-- transform for odd factors
  537. k = factor (ii)
  538. ispan = kspan
  539. kspan = kspan / k
  540. SELECT CASE (k)
  541. CASE (3) !-- transform for factor of 3 (optional code)
  542. DO
  543. DO
  544. k1 = kk + kspan
  545. k2 = k1 + kspan
  546. ck = array(kk)
  547. cj = array(k1) + array(k2)
  548. array(kk) = ck + cj
  549. ck = ck - 0.5_fftkind * cj
  550. cj = (array(k1) - array(k2)) * s60
  551. array(k1) = ck + CMPLX(-AIMAG(cj), REAL(cj), kind=fftkind)
  552. array(k2) = ck + CMPLX(AIMAG(cj), -REAL(cj), kind=fftkind)
  553. kk = k2 + kspan
  554. IF (kk >= nn) EXIT
  555. END DO
  556. kk = kk - nn
  557. IF (kk > kspan) EXIT
  558. END DO
  559. CASE (5) !-- transform for factor of 5 (optional code)
  560. c2 = c72 * c72 - s72 * s72
  561. s2 = 2.0_fftkind * c72 * s72
  562. DO
  563. DO
  564. k1 = kk + kspan
  565. k2 = k1 + kspan
  566. k3 = k2 + kspan
  567. k4 = k3 + kspan
  568. ckp = array(k1) + array(k4)
  569. ckm = array(k1) - array(k4)
  570. cjp = array(k2) + array(k3)
  571. cjm = array(k2) - array(k3)
  572. cc = array(kk)
  573. array(kk) = cc + ckp + cjp
  574. ck = ckp * c72 + cjp * c2 + cc
  575. cj = ckm * s72 + cjm * s2
  576. array(k1) = ck + CMPLX(-AIMAG(cj), REAL(cj), kind=fftkind)
  577. array(k4) = ck + CMPLX(AIMAG(cj), -REAL(cj), kind=fftkind)
  578. ck = ckp * c2 + cjp * c72 + cc
  579. cj = ckm * s2 - cjm * s72
  580. array(k2) = ck + CMPLX(-AIMAG(cj), REAL(cj), kind=fftkind)
  581. array(k3) = ck + CMPLX(AIMAG(cj), -REAL(cj), kind=fftkind)
  582. kk = k4 + kspan
  583. IF (kk >= nn) EXIT
  584. END DO
  585. kk = kk - nn
  586. IF (kk > kspan) EXIT
  587. END DO
  588. CASE default
  589. IF (k /= jf) THEN
  590. jf = k
  591. s1 = pi2 / k
  592. c1 = COS(s1)
  593. s1 = SIN(s1)
  594. cosine (jf) = 1.0_fftkind
  595. sine (jf) = 0.0_fftkind
  596. j = 1
  597. DO
  598. cosine (j) = cosine (k) * c1 + sine (k) * s1
  599. sine (j) = cosine (k) * s1 - sine (k) * c1
  600. k = k-1
  601. cosine (k) = cosine (j)
  602. sine (k) = -sine (j)
  603. j = j + 1
  604. IF (j >= k) EXIT
  605. END DO
  606. END IF
  607. DO
  608. DO
  609. k1 = kk
  610. k2 = kk + ispan
  611. cc = array(kk)
  612. ck = cc
  613. j = 1
  614. k1 = k1 + kspan
  615. DO
  616. k2 = k2 - kspan
  617. j = j + 1
  618. ctmp(j) = array(k1) + array(k2)
  619. ck = ck + ctmp(j)
  620. j = j + 1
  621. ctmp(j) = array(k1) - array(k2)
  622. k1 = k1 + kspan
  623. IF (k1 >= k2) EXIT
  624. END DO
  625. array(kk) = ck
  626. k1 = kk
  627. k2 = kk + ispan
  628. j = 1
  629. DO
  630. k1 = k1 + kspan;
  631. k2 = k2 - kspan;
  632. jj = j
  633. ck = cc
  634. cj = (0.0_fftkind, 0.0_fftkind)
  635. k = 1
  636. DO
  637. k = k + 1
  638. ck = ck + ctmp(k) * cosine (jj)
  639. k = k + 1
  640. cj = cj + ctmp(k) * sine (jj)
  641. jj = jj + j
  642. IF (jj > jf) jj = jj - jf
  643. IF (k >= jf) EXIT
  644. END DO
  645. k = jf - j
  646. array(k1) = ck + CMPLX(-AIMAG(cj), REAL(cj), kind=fftkind)
  647. array(k2) = ck + CMPLX(AIMAG(cj), -REAL(cj), kind=fftkind)
  648. j = j + 1
  649. IF (j >= k) EXIT
  650. END DO
  651. kk = kk + ispan
  652. IF (kk > nn) EXIT
  653. END DO
  654. kk = kk - nn
  655. IF (kk > kspan) EXIT
  656. END DO
  657. END SELECT
  658. !-- multiply by rotation factor (except for factors of 2 and 4)
  659. IF (ii == nfactor) RETURN
  660. kk = jc + 1
  661. DO
  662. c2 = 1.0_fftkind - cd
  663. s1 = sd
  664. DO
  665. c1 = c2
  666. s2 = s1
  667. kk = kk + kspan
  668. DO
  669. DO
  670. array(kk) = CMPLX(c2, s2, kind=fftkind) * array(kk)
  671. kk = kk + ispan
  672. IF (kk > nt) EXIT
  673. END DO
  674. ak = s1 * s2
  675. s2 = s1 * c2 + c1 * s2
  676. c2 = c1 * c2 - ak
  677. kk = kk - nt + kspan
  678. IF (kk > ispan) EXIT
  679. END DO
  680. c2 = c1 - (cd * c1 + sd * s1)
  681. s1 = s1 + sd * c1 - cd * s1
  682. c1 = 2.0_fftkind - (c2 * c2 + s1 * s1)
  683. s1 = s1 * c1
  684. c2 = c2 * c1
  685. kk = kk - ispan + jc
  686. IF (kk > kspan) EXIT
  687. END DO
  688. kk = kk - kspan + jc + 1
  689. IF (kk > jc + jc) EXIT
  690. END DO
  691. END SELECT
  692. END DO
  693. END SUBROUTINE transform
  694. SUBROUTINE permute
  695. !-- permute the results to normal order---done in two stages
  696. !-- permutation for square factors of n
  697. perm (1) = ns
  698. IF (kt > 0) THEN
  699. k = kt + kt + 1
  700. IF (nfactor < k) k = k - 1
  701. j = 1
  702. perm (k + 1) = jc
  703. DO
  704. perm (j + 1) = perm (j) / factor (j)
  705. perm (k) = perm (k + 1) * factor (j)
  706. j = j + 1
  707. k = k - 1
  708. IF (j >= k) EXIT
  709. END DO
  710. k3 = perm (k + 1)
  711. kspan = perm (2)
  712. kk = jc + 1
  713. k2 = kspan + 1
  714. j = 1
  715. IF (npass /= ntotal) THEN
  716. permute_multi: DO
  717. DO
  718. DO
  719. k = kk + jc
  720. DO
  721. !-- swap array(kk) <> array(k2)
  722. ck = array(kk)
  723. array(kk) = array(k2)
  724. array(k2) = ck
  725. kk = kk + 1
  726. k2 = k2 + 1
  727. IF (kk >= k) EXIT
  728. END DO
  729. kk = kk + ns - jc
  730. k2 = k2 + ns - jc
  731. IF (kk >= nt) EXIT
  732. END DO
  733. kk = kk - nt + jc
  734. k2 = k2 - nt + kspan
  735. IF (k2 >= ns) EXIT
  736. END DO
  737. DO
  738. DO
  739. k2 = k2 - perm (j)
  740. j = j + 1
  741. k2 = perm (j + 1) + k2
  742. IF (k2 <= perm (j)) EXIT
  743. END DO
  744. j = 1
  745. DO
  746. IF (kk < k2) CYCLE permute_multi
  747. kk = kk + jc
  748. k2 = k2 + kspan
  749. IF (k2 >= ns) EXIT
  750. END DO
  751. IF (kk >= ns) EXIT
  752. END DO
  753. EXIT
  754. END DO permute_multi
  755. ELSE
  756. permute_single: DO
  757. DO
  758. !-- swap array(kk) <> array(k2)
  759. ck = array(kk)
  760. array(kk) = array(k2)
  761. array(k2) = ck
  762. kk = kk + 1
  763. k2 = k2 + kspan
  764. IF (k2 >= ns) EXIT
  765. END DO
  766. DO
  767. DO
  768. k2 = k2 - perm (j)
  769. j = j + 1
  770. k2 = perm (j + 1) + k2
  771. IF (k2 <= perm (j)) EXIT
  772. END DO
  773. j = 1
  774. DO
  775. IF (kk < k2) CYCLE permute_single
  776. kk = kk + 1
  777. k2 = k2 + kspan
  778. IF (k2 >= ns) EXIT
  779. END DO
  780. IF (kk >= ns) EXIT
  781. END DO
  782. EXIT
  783. END DO permute_single
  784. END IF
  785. jc = k3
  786. END IF
  787. IF (ISHFT(kt, 1) + 1 >= nfactor) RETURN
  788. ispan = perm (kt + 1)
  789. !-- permutation for square-free factors of n
  790. j = nfactor - kt
  791. factor (j + 1) = 1
  792. DO
  793. factor(j) = factor(j) * factor(j+1)
  794. j = j - 1
  795. IF (j == kt) EXIT
  796. END DO
  797. kt = kt + 1
  798. nn = factor(kt) - 1
  799. j = 0
  800. jj = 0
  801. DO
  802. k = kt + 1
  803. k2 = factor(kt)
  804. kk = factor(k)
  805. j = j + 1
  806. IF (j > nn) EXIT !-- exit infinite loop
  807. jj = jj + kk
  808. DO WHILE (jj >= k2)
  809. jj = jj - k2
  810. k2 = kk
  811. k = k + 1
  812. kk = factor(k)
  813. jj = jj + kk
  814. END DO
  815. perm (j) = jj
  816. END DO
  817. !-- determine the permutation cycles of length greater than 1
  818. j = 0
  819. DO
  820. DO
  821. j = j + 1
  822. kk = perm(j)
  823. IF (kk >= 0) EXIT
  824. END DO
  825. IF (kk /= j) THEN
  826. DO
  827. k = kk
  828. kk = perm (k)
  829. perm (k) = -kk
  830. IF (kk == j) EXIT
  831. END DO
  832. k3 = kk
  833. ELSE
  834. perm (j) = -j
  835. IF (j == nn) EXIT !-- exit infinite loop
  836. END IF
  837. END DO
  838. !-- reorder a and b, following the permutation cycles
  839. DO
  840. j = k3 + 1
  841. nt = nt - ispan
  842. ii = nt - 1 + 1
  843. IF (nt < 0) EXIT !-- exit infinite loop
  844. DO
  845. DO
  846. j = j-1
  847. IF (perm(j) >= 0) EXIT
  848. END DO
  849. jj = jc
  850. DO
  851. kspan = jj
  852. IF (jj > maxfactor) kspan = maxfactor
  853. jj = jj - kspan;
  854. k = perm(j)
  855. kk = jc * k + ii + jj
  856. k1 = kk + kspan
  857. k2 = 0
  858. DO
  859. k2 = k2 + 1
  860. ctmp(k2) = array(k1)
  861. k1 = k1 - 1;
  862. IF (k1 == kk) EXIT
  863. END DO
  864. DO
  865. k1 = kk + kspan
  866. k2 = k1 - jc * (k + perm(k))
  867. k = -perm(k)
  868. DO
  869. array(k1) = array(k2)
  870. k1 = k1 - 1
  871. k2 = k2 - 1
  872. IF (k1 == kk) EXIT
  873. END DO
  874. kk = k2
  875. IF (k == j) EXIT
  876. END DO
  877. k1 = kk + kspan
  878. k2 = 0
  879. DO
  880. k2 = k2 + 1
  881. array(k1) = ctmp(k2)
  882. k1 = k1 - 1;
  883. IF (k1 == kk) EXIT
  884. END DO
  885. IF (jj == 0) EXIT
  886. END DO
  887. IF (j == 1) EXIT
  888. END DO
  889. END DO
  890. END SUBROUTINE permute
  891. END SUBROUTINE fftradix
  892. END MODULE grid_singleton