PyFishPack 0.1.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. PyFishPack/__init__.py +86 -0
  2. PyFishPack/__pycache__/__init__.cpython-313.pyc +0 -0
  3. PyFishPack/__pycache__/apps.cpython-313.pyc +0 -0
  4. PyFishPack/_dummy.c +23 -0
  5. PyFishPack/_dummy.cp313-win_amd64.pyd +0 -0
  6. PyFishPack/apps.py +3640 -0
  7. PyFishPack/fishpack.cp313-win_amd64.dll.a +0 -0
  8. PyFishPack/fishpack.cp313-win_amd64.pyd +0 -0
  9. PyFishPack/meson.build +213 -0
  10. PyFishPack/src/archive/f77/Makefile +19 -0
  11. PyFishPack/src/archive/f77/blktri.f +1404 -0
  12. PyFishPack/src/archive/f77/cblktri.f +1414 -0
  13. PyFishPack/src/archive/f77/cmgnbn.f +1592 -0
  14. PyFishPack/src/archive/f77/comf.f +186 -0
  15. PyFishPack/src/archive/f77/fftpack.f +2968 -0
  16. PyFishPack/src/archive/f77/genbun.f +1335 -0
  17. PyFishPack/src/archive/f77/gnbnaux.f +314 -0
  18. PyFishPack/src/archive/f77/hstcrt.f +443 -0
  19. PyFishPack/src/archive/f77/hstcsp.f +683 -0
  20. PyFishPack/src/archive/f77/hstcyl.f +485 -0
  21. PyFishPack/src/archive/f77/hstplr.f +538 -0
  22. PyFishPack/src/archive/f77/hstssp.f +634 -0
  23. PyFishPack/src/archive/f77/hw3crt.f +687 -0
  24. PyFishPack/src/archive/f77/hwscrt.f +512 -0
  25. PyFishPack/src/archive/f77/hwscsp.f +728 -0
  26. PyFishPack/src/archive/f77/hwscyl.f +538 -0
  27. PyFishPack/src/archive/f77/hwsplr.f +602 -0
  28. PyFishPack/src/archive/f77/hwsssp.f +780 -0
  29. PyFishPack/src/archive/f77/pois3d.f +550 -0
  30. PyFishPack/src/archive/f77/poistg.f +875 -0
  31. PyFishPack/src/archive/f77/sepaux.f +361 -0
  32. PyFishPack/src/archive/f77/sepeli.f +1029 -0
  33. PyFishPack/src/archive/f77/sepx4.f +958 -0
  34. PyFishPack/src/centered_axisymmetric_spherical_solver.f90 +1002 -0
  35. PyFishPack/src/centered_cartesian_helmholtz_solver_3d.f90 +819 -0
  36. PyFishPack/src/centered_cartesian_solver.f90 +583 -0
  37. PyFishPack/src/centered_cylindrical_solver.f90 +634 -0
  38. PyFishPack/src/centered_helmholtz_solvers.f90 +156 -0
  39. PyFishPack/src/centered_polar_solver.f90 +746 -0
  40. PyFishPack/src/centered_real_linear_systems_solver.f90 +280 -0
  41. PyFishPack/src/centered_spherical_solver.f90 +928 -0
  42. PyFishPack/src/complex_block_tridiagonal_linear_systems_solver.f90 +1947 -0
  43. PyFishPack/src/complex_linear_systems_solver.f90 +1787 -0
  44. PyFishPack/src/fftpack_c_api.f90 +86 -0
  45. PyFishPack/src/fishpack.f90 +191 -0
  46. PyFishPack/src/fishpack.pyf +504 -0
  47. PyFishPack/src/fishpack_c_api.f90 +365 -0
  48. PyFishPack/src/fishpack_original.pyf +2119 -0
  49. PyFishPack/src/fishpack_precision.f90 +53 -0
  50. PyFishPack/src/general_linear_systems_solver_3d.f90 +296 -0
  51. PyFishPack/src/iterative_solvers.f90 +969 -0
  52. PyFishPack/src/main.f90 +10 -0
  53. PyFishPack/src/pyfishpack_module.c +1302 -0
  54. PyFishPack/src/real_block_tridiagonal_linear_systems_solver.f90 +319 -0
  55. PyFishPack/src/sepeli.f90 +1454 -0
  56. PyFishPack/src/sepx4.f90 +1338 -0
  57. PyFishPack/src/staggered_axisymmetric_spherical_solver.f90 +908 -0
  58. PyFishPack/src/staggered_cartesian_solver.f90 +553 -0
  59. PyFishPack/src/staggered_cylindrical_solver.f90 +630 -0
  60. PyFishPack/src/staggered_helmholtz_solvers.f90 +172 -0
  61. PyFishPack/src/staggered_polar_solver.f90 +651 -0
  62. PyFishPack/src/staggered_real_linear_systems_solver.f90 +258 -0
  63. PyFishPack/src/staggered_spherical_solver.f90 +758 -0
  64. PyFishPack/src/three_dimensional_solvers.f90 +602 -0
  65. PyFishPack/src/type_CenteredCyclicReductionUtility.f90 +1714 -0
  66. PyFishPack/src/type_CyclicReductionUtility.f90 +472 -0
  67. PyFishPack/src/type_FishpackWorkspace.f90 +290 -0
  68. PyFishPack/src/type_GeneralizedCyclicReductionUtility.f90 +1980 -0
  69. PyFishPack/src/type_PeriodicFastFourierTransform.f90 +3789 -0
  70. PyFishPack/src/type_SepAux.f90 +586 -0
  71. PyFishPack/src/type_StaggeredCyclicReductionUtility.f90 +893 -0
  72. pyfishpack-0.1.0.dist-info/DELVEWHEEL +2 -0
  73. pyfishpack-0.1.0.dist-info/METADATA +81 -0
  74. pyfishpack-0.1.0.dist-info/RECORD +81 -0
  75. pyfishpack-0.1.0.dist-info/WHEEL +5 -0
  76. pyfishpack-0.1.0.dist-info/licenses/LICENSE +21 -0
  77. pyfishpack-0.1.0.dist-info/top_level.txt +1 -0
  78. pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
  79. pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
  80. pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
  81. pyfishpack.libs/libwinpthread-1-83908d14abfafb8b3bfa38cf51ecee56.dll +0 -0
@@ -0,0 +1,3789 @@
1
+ !
2
+ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3
+ ! * *
4
+ ! * copyright (c) 2005 by UCAR *
5
+ ! * *
6
+ ! * University Corporation for Atmospheric Research *
7
+ ! * *
8
+ ! * all rights reserved *
9
+ ! * *
10
+ ! * Fishpack *
11
+ ! * *
12
+ ! * A Package of Fortran *
13
+ ! * *
14
+ ! * Subroutines and Example Programs *
15
+ ! * *
16
+ ! * for Modeling Geophysical Processes *
17
+ ! * *
18
+ ! * by *
19
+ ! * *
20
+ ! * John Adams, Paul Swarztrauber and Roland Sweet *
21
+ ! * *
22
+ ! * of *
23
+ ! * *
24
+ ! * the National Center for Atmospheric Research *
25
+ ! * *
26
+ ! * Boulder, Colorado (80307) U.S.A. *
27
+ ! * *
28
+ ! * which is sponsored by *
29
+ ! * *
30
+ ! * the National Science Foundation *
31
+ ! * *
32
+ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
33
+ !
34
+ ! PURPOSE
35
+ !
36
+ ! This module consists of procedures which perform fast Fourier
37
+ ! transforms for both complex and real periodic sequences and
38
+ ! certain other symmetric sequences that are listed below.
39
+ !
40
+ ! USAGE
41
+ !
42
+ ! 1. rffti initialize rfftf and rfftb
43
+ ! 2. rfftf forward transform of a real periodic sequence
44
+ ! 3. rfftb backward transform of a real coefficient array
45
+ !
46
+ ! 4. ezffti initialize ezfftf and ezfftb
47
+ ! 5. ezfftf a simplified real periodic forward transform
48
+ ! 6. ezfftb a simplified real periodic backward transform
49
+ !
50
+ ! 7. sinti initialize sint
51
+ ! 8. sint sine transform of a real odd sequence
52
+ !
53
+ ! 9. costi initialize cost
54
+ ! 10. cost cosine transform of a real even sequence
55
+ !
56
+ ! 11. sinqi initialize sinqf and sinqb
57
+ ! 12. sinqf forward sine transform with odd wave numbers
58
+ ! 13. sinqb unnormalized inverse of sinqf
59
+ !
60
+ ! 14. cosqi initialize cosqf and cosqb
61
+ ! 15. cosqf forward cosine transform with odd wave numbers
62
+ ! 16. cosqb unnormalized inverse of cosqf
63
+ !
64
+ ! 17. cffti initialize cfftf and cfftb
65
+ ! 18. cfftf forward transform of a complex periodic sequence
66
+ ! 19. cfftb unnormalized inverse of cfftf
67
+ !
68
+ ! SPECIAL CONDITIONS
69
+ !
70
+ ! Before calling routines ezfftb and ezfftf for the first time,
71
+ ! or before calling ezfftb and ezfftf with a different length,
72
+ ! users must initialize by calling routine ezffti.
73
+ !
74
+ ! HISTORY
75
+ !
76
+ ! * Developed at NCAR in boulder, colorado by paul n. swarztrauber
77
+ ! of the scientific computing division. Released on NCAR's public
78
+ ! software libraries in January 1980.
79
+ ! * Modified may 29, 1985 to increase efficiency.
80
+ ! * Updated in 2016 to incorporate features of Fortran 2008+
81
+ !
82
+ !
83
+ ! **********************************************************************
84
+ !
85
+ !
86
+ ! **********************************************************************
87
+ !
88
+ ! subroutine rfftf(n, r, wsave)
89
+ !
90
+ ! subroutine rfftf computes the fourier coefficients of a real
91
+ ! perodic sequence (fourier analysis). the transform is defined
92
+ ! below at output parameter r.
93
+ !
94
+ ! input parameters
95
+ !
96
+ ! n the length of the array r to be transformed. the method
97
+ ! is most efficient when n is a product of small primes.
98
+ ! n may change so long as different work arrays are provided
99
+ !
100
+ ! r a real array of length n which contains the sequence
101
+ ! to be transformed
102
+ !
103
+ ! wsave a work array which must be dimensioned at least 2*n+15.
104
+ ! in the program that calls rfftf. the wsave array must be
105
+ ! initialized by calling subroutine rffti(n, wsave) and a
106
+ ! different wsave array must be used for each different
107
+ ! value of n. this initialization does not have to be
108
+ ! repeated so long as n remains unchanged thus subsequent
109
+ ! transforms can be obtained faster than the first.
110
+ ! the same wsave array can be used by rfftf and rfftb.
111
+ !
112
+ !
113
+ ! output parameters
114
+ !
115
+ ! r r(1) = the sum from i=1 to i=n of r(i)
116
+ !
117
+ ! if n is even set l =n/2 , if n is odd set l =(n+1)/2
118
+ !
119
+ ! then for k = 2, ..., l
120
+ !
121
+ ! r(2*k-2) = the sum from i = 1 to i = n of
122
+ !
123
+ ! r(i)*cos((k-1)*(i-1)*2*pi/n)
124
+ !
125
+ ! r(2*k-1) = the sum from i = 1 to i = n of
126
+ !
127
+ ! -r(i)*sin((k-1)*(i-1)*2*pi/n)
128
+ !
129
+ ! if n is even
130
+ !
131
+ ! r(n) = the sum from i = 1 to i = n of
132
+ !
133
+ ! (-1)**(i-1)*r(i)
134
+ !
135
+ ! ***** note
136
+ ! this transform is unnormalized since a call of rfftf
137
+ ! followed by a call of rfftb will multiply the input
138
+ ! sequence by n.
139
+ !
140
+ ! wsave contains results which must not be destroyed between
141
+ ! calls of rfftf or rfftb.
142
+ !
143
+ !
144
+ ! **********************************************************************
145
+ !
146
+ ! subroutine rfftb(n, r, wsave)
147
+ !
148
+ ! subroutine rfftb computes the real perodic sequence from its
149
+ ! fourier coefficients (fourier synthesis). the transform is defined
150
+ ! below at output parameter r.
151
+ !
152
+ ! input parameters
153
+ !
154
+ ! n the length of the array r to be transformed. the method
155
+ ! is most efficient when n is a product of small primes.
156
+ ! n may change so long as different work arrays are provided
157
+ !
158
+ ! r a real array of length n which contains the sequence
159
+ ! to be transformed
160
+ !
161
+ ! wsave a work array which must be dimensioned at least 2*n+15.
162
+ ! in the program that calls rfftb. the wsave array must be
163
+ ! initialized by calling subroutine rffti(n, wsave) and a
164
+ ! different wsave array must be used for each different
165
+ ! value of n. this initialization does not have to be
166
+ ! repeated so long as n remains unchanged thus subsequent
167
+ ! transforms can be obtained faster than the first.
168
+ ! the same wsave array can be used by rfftf and rfftb.
169
+ !
170
+ !
171
+ ! output parameters
172
+ !
173
+ ! r for n even and for i = 1, ..., n
174
+ !
175
+ ! r(i) = r(1)+(-1)**(i-1)*r(n)
176
+ !
177
+ ! plus the sum from k=2 to k=n/2 of
178
+ !
179
+ ! TWO * r(2*k-2)*cos((k-1)*(i-1)*2*pi/n)
180
+ !
181
+ ! -TWO * r(2*k-1)*sin((k-1)*(i-1)*2*pi/n)
182
+ !
183
+ ! for n odd and for i = 1, ..., n
184
+ !
185
+ ! r(i) = r(1) plus the sum from k=2 to k=(n+1)/2 of
186
+ !
187
+ ! TWO * r(2*k-2)*cos((k-1)*(i-1)*2*pi/n)
188
+ !
189
+ ! -TWO * r(2*k-1)*sin((k-1)*(i-1)*2*pi/n)
190
+ !
191
+ ! ***** note
192
+ ! this transform is unnormalized since a call of rfftf
193
+ ! followed by a call of rfftb will multiply the input
194
+ ! sequence by n.
195
+ !
196
+ ! wsave contains results which must not be destroyed between
197
+ ! calls of rfftb or rfftf.
198
+ !
199
+ !
200
+ ! **********************************************************************
201
+ !
202
+ ! subroutine ezffti(n, wsave)
203
+ !
204
+ ! subroutine ezffti initializes the array wsave which is used in
205
+ ! both ezfftf and ezfftb. the prime factorization of n together with
206
+ ! a tabulation of the trigonometric functions are computed and
207
+ ! stored in wsave.
208
+ !
209
+ ! input parameter
210
+ !
211
+ ! n the length of the sequence to be transformed.
212
+ !
213
+ ! output parameter
214
+ !
215
+ ! wsave a work array which must be dimensioned at least 3*n+15.
216
+ ! the same work array can be used for both ezfftf and ezfftb
217
+ ! as long as n remains unchanged. different wsave arrays
218
+ ! are required for different values of n.
219
+ !
220
+ !
221
+ ! **********************************************************************
222
+ !
223
+ ! subroutine ezfftf(n, r, azero, a, b, wsave)
224
+ !
225
+ ! subroutine ezfftf computes the fourier coefficients of a real
226
+ ! perodic sequence (fourier analysis). the transform is defined
227
+ ! below at output parameters azero, a and b. ezfftf is a simplified
228
+ ! but slower Version of rfftf.
229
+ !
230
+ ! input parameters
231
+ !
232
+ ! n the length of the array r to be transformed. the method
233
+ ! is must efficient when n is the product of small primes.
234
+ !
235
+ ! r a real array of length n which contains the sequence
236
+ ! to be transformed. r is not destroyed.
237
+ !
238
+ !
239
+ ! wsave a work array which must be dimensioned at least 3*n+15.
240
+ ! in the program that calls ezfftf. the wsave array must be
241
+ ! initialized by calling subroutine ezffti(n, wsave) and a
242
+ ! different wsave array must be used for each different
243
+ ! value of n. this initialization does not have to be
244
+ ! repeated so long as n remains unchanged thus subsequent
245
+ ! transforms can be obtained faster than the first.
246
+ ! the same wsave array can be used by ezfftf and ezfftb.
247
+ !
248
+ ! output parameters
249
+ !
250
+ ! azero the sum from i=1 to i=n of r(i)/n
251
+ !
252
+ ! a, b for n even b(n/2)=0. and a(n/2) is the sum from i=1 to
253
+ ! i=n of (-1)**(i-1)*r(i)/n
254
+ !
255
+ ! for n even define kmax=n/2-1
256
+ ! for n odd define kmax=(n-1)/2
257
+ !
258
+ ! then for k=1, ..., kmax
259
+ !
260
+ ! a(k) equals the sum from i=1 to i=n of
261
+ !
262
+ ! 2./n*r(i)*cos(k*(i-1)*2*pi/n)
263
+ !
264
+ ! b(k) equals the sum from i=1 to i=n of
265
+ !
266
+ ! 2./n*r(i)*sin(k*(i-1)*2*pi/n)
267
+ !
268
+ !
269
+ ! **********************************************************************
270
+ !
271
+ ! subroutine ezfftb(n, r, azero, a, b, wsave)
272
+ !
273
+ ! subroutine ezfftb computes a real perodic sequence from its
274
+ ! fourier coefficients (fourier synthesis). the transform is
275
+ ! defined below at output parameter r. ezfftb is a simplified
276
+ ! but slower Version of rfftb.
277
+ !
278
+ ! input parameters
279
+ !
280
+ ! n the length of the output array r. the method is most
281
+ ! efficient when n is the product of small primes.
282
+ !
283
+ ! azero the constant fourier coefficient
284
+ !
285
+ ! a, b arrays which contain the remaining fourier coefficients
286
+ ! these arrays are not destroyed.
287
+ !
288
+ ! the length of these arrays depends on whether n is even or
289
+ ! odd.
290
+ !
291
+ ! if n is even n/2 locations are required
292
+ ! if n is odd(n-1)/2 locations are required
293
+ !
294
+ ! wsave a work array which must be dimensioned at least 3*n+15.
295
+ ! in the program that calls ezfftb. the wsave array must be
296
+ ! initialized by calling subroutine ezffti(n, wsave) and a
297
+ ! different wsave array must be used for each different
298
+ ! value of n. this initialization does not have to be
299
+ ! repeated so long as n remains unchanged thus subsequent
300
+ ! transforms can be obtained faster than the first.
301
+ ! the same wsave array can be used by ezfftf and ezfftb.
302
+ !
303
+ !
304
+ ! output parameters
305
+ !
306
+ ! r if n is even define kmax=n/2
307
+ ! if n is odd define kmax=(n-1)/2
308
+ !
309
+ ! then for i=1, ..., n
310
+ !
311
+ ! r(i)=azero plus the sum from k=1 to k=kmax of
312
+ !
313
+ ! a(k)*cos(k*(i-1)*2*pi/n)+b(k)*sin(k*(i-1)*2*pi/n)
314
+ !
315
+ ! ********************* complex notation **************************
316
+ !
317
+ ! for j=1, ..., n
318
+ !
319
+ ! r(j) equals the sum from k=-kmax to k=kmax of
320
+ !
321
+ ! c(k)*exp(i*k*(j-1)*2*pi/n)
322
+ !
323
+ ! where
324
+ !
325
+ ! c(k) = .5*cmplx(a(k), -b(k)) for k=1, ..., kmax
326
+ !
327
+ ! c(-k) = conjg(c(k))
328
+ !
329
+ ! c(0) = azero
330
+ !
331
+ ! and i=sqrt(-1)
332
+ !
333
+ ! *************** amplitude - phase notation ***********************
334
+ !
335
+ ! for i=1, ..., n
336
+ !
337
+ ! r(i) equals azero plus the sum from k=1 to k=kmax of
338
+ !
339
+ ! alpha(k)*cos(k*(i-1)*2*pi/n+beta(k))
340
+ !
341
+ ! where
342
+ !
343
+ ! alpha(k) = sqrt(a(k)*a(k)+b(k)*b(k))
344
+ !
345
+ ! cos(beta(k))=a(k)/alpha(k)
346
+ !
347
+ ! sin(beta(k))=-b(k)/alpha(k)
348
+ !
349
+ ! **********************************************************************
350
+ !
351
+ ! subroutine sinti(n, wsave)
352
+ !
353
+ ! subroutine sinti initializes the array wsave which is used in
354
+ ! subroutine sint. the prime factorization of n together with
355
+ ! a tabulation of the trigonometric functions are computed and
356
+ ! stored in wsave.
357
+ !
358
+ ! input parameter
359
+ !
360
+ ! n the length of the sequence to be transformed. the method
361
+ ! is most efficient when n+1 is a product of small primes.
362
+ !
363
+ ! output parameter
364
+ !
365
+ ! wsave a work array with at least int(2.5*n+15) locations.
366
+ ! different wsave arrays are required for different values
367
+ ! of n. the contents of wsave must not be changed between
368
+ ! calls of sint.
369
+ !
370
+ ! **********************************************************************
371
+ !
372
+ ! subroutine sint(n, x, wsave)
373
+ !
374
+ ! subroutine sint computes the discrete fourier sine transform
375
+ ! of an odd sequence x(i). the transform is defined below at
376
+ ! output parameter x.
377
+ !
378
+ ! sint is the unnormalized inverse of itself since a call of sint
379
+ ! followed by another call of sint will multiply the input sequence
380
+ ! x by 2*(n+1).
381
+ !
382
+ ! the array wsave which is used by subroutine sint must be
383
+ ! initialized by calling subroutine sinti(n, wsave).
384
+ !
385
+ ! input parameters
386
+ !
387
+ ! n the length of the sequence to be transformed. the method
388
+ ! is most efficient when n+1 is the product of small primes.
389
+ !
390
+ ! x an array which contains the sequence to be transformed
391
+ !
392
+ !
393
+ ! wsave a work array with dimension at least int(2.5*n+15)
394
+ ! in the program that calls sint. the wsave array must be
395
+ ! initialized by calling subroutine sinti(n, wsave) and a
396
+ ! different wsave array must be used for each different
397
+ ! value of n. this initialization does not have to be
398
+ ! repeated so long as n remains unchanged thus subsequent
399
+ ! transforms can be obtained faster than the first.
400
+ !
401
+ ! output parameters
402
+ !
403
+ ! x for i=1, ..., n
404
+ !
405
+ ! x(i)= the sum from k=1 to k=n
406
+ !
407
+ ! 2*x(k)*sin(k*i*pi/(n+1))
408
+ !
409
+ ! a call of sint followed by another call of
410
+ ! sint will multiply the sequence x by 2*(n+1).
411
+ ! hence sint is the unnormalized inverse
412
+ ! of itself.
413
+ !
414
+ ! wsave contains initialization calculations which must not be
415
+ ! destroyed between calls of sint.
416
+ !
417
+ ! **********************************************************************
418
+ !
419
+ ! subroutine costi(n, wsave)
420
+ !
421
+ ! subroutine costi initializes the array wsave which is used in
422
+ ! subroutine cost. the prime factorization of n together with
423
+ ! a tabulation of the trigonometric functions are computed and
424
+ ! stored in wsave.
425
+ !
426
+ ! input parameter
427
+ !
428
+ ! n the length of the sequence to be transformed. the method
429
+ ! is most efficient when n-1 is a product of small primes.
430
+ !
431
+ ! output parameter
432
+ !
433
+ ! wsave a work array which must be dimensioned at least 3*n+15.
434
+ ! different wsave arrays are required for different values
435
+ ! of n. the contents of wsave must not be changed between
436
+ ! calls of cost.
437
+ !
438
+ ! **********************************************************************
439
+ !
440
+ ! subroutine cost(n, x, wsave)
441
+ !
442
+ ! subroutine cost computes the discrete fourier cosine transform
443
+ ! of an even sequence x(i). the transform is defined below at output
444
+ ! parameter x.
445
+ !
446
+ ! cost is the unnormalized inverse of itself since a call of cost
447
+ ! followed by another call of cost will multiply the input sequence
448
+ ! x by 2*(n-1). the transform is defined below at output parameter x
449
+ !
450
+ ! the array wsave which is used by subroutine cost must be
451
+ ! initialized by calling subroutine costi(n, wsave).
452
+ !
453
+ ! input parameters
454
+ !
455
+ ! n the length of the sequence x. n must be greater than 1.
456
+ ! the method is most efficient when n-1 is a product of
457
+ ! small primes.
458
+ !
459
+ ! x an array which contains the sequence to be transformed
460
+ !
461
+ ! wsave a work array which must be dimensioned at least 3*n+15
462
+ ! in the program that calls cost. the wsave array must be
463
+ ! initialized by calling subroutine costi(n, wsave) and a
464
+ ! different wsave array must be used for each different
465
+ ! value of n. this initialization does not have to be
466
+ ! repeated so long as n remains unchanged thus subsequent
467
+ ! transforms can be obtained faster than the first.
468
+ !
469
+ ! output parameters
470
+ !
471
+ ! x for i=1, ..., n
472
+ !
473
+ ! x(i) = x(1)+(-1)**(i-1)*x(n)
474
+ !
475
+ ! + the sum from k=2 to k=n-1
476
+ !
477
+ ! 2*x(k)*cos((k-1)*(i-1)*pi/(n-1))
478
+ !
479
+ ! a call of cost followed by another call of
480
+ ! cost will multiply the sequence x by 2*(n-1)
481
+ ! hence cost is the unnormalized inverse
482
+ ! of itself.
483
+ !
484
+ ! wsave contains initialization calculations which must not be
485
+ ! destroyed between calls of cost.
486
+ !
487
+ ! **********************************************************************
488
+ !
489
+ ! subroutine sinqi(n, wsave)
490
+ !
491
+ ! subroutine sinqi initializes the array wsave which is used in
492
+ ! both sinqf and sinqb. the prime factorization of n together with
493
+ ! a tabulation of the trigonometric functions are computed and
494
+ ! stored in wsave.
495
+ !
496
+ ! input parameter
497
+ !
498
+ ! n the length of the sequence to be transformed. the method
499
+ ! is most efficient when n is a product of small primes.
500
+ !
501
+ ! output parameter
502
+ !
503
+ ! wsave a work array which must be dimensioned at least 3*n+15.
504
+ ! the same work array can be used for both sinqf and sinqb
505
+ ! as long as n remains unchanged. different wsave arrays
506
+ ! are required for different values of n. the contents of
507
+ ! wsave must not be changed between calls of sinqf or sinqb.
508
+ !
509
+ ! **********************************************************************
510
+ !
511
+ ! subroutine sinqf(n, x, wsave)
512
+ !
513
+ ! subroutine sinqf computes the fast fourier transform of quarter
514
+ ! wave data. that is , sinqf computes the coefficients in a sine
515
+ ! series representation with only odd wave numbers. the transform
516
+ ! is defined below at output parameter x.
517
+ !
518
+ ! sinqb is the unnormalized inverse of sinqf since a call of sinqf
519
+ ! followed by a call of sinqb will multiply the input sequence x
520
+ ! by 4*n.
521
+ !
522
+ ! the array wsave which is used by subroutine sinqf must be
523
+ ! initialized by calling subroutine sinqi(n, wsave).
524
+ !
525
+ !
526
+ ! input parameters
527
+ !
528
+ ! n the length of the array x to be transformed. the method
529
+ ! is most efficient when n is a product of small primes.
530
+ !
531
+ ! x an array which contains the sequence to be transformed
532
+ !
533
+ ! wsave a work array which must be dimensioned at least 3*n+15.
534
+ ! in the program that calls sinqf. the wsave array must be
535
+ ! initialized by calling subroutine sinqi(n, wsave) and a
536
+ ! different wsave array must be used for each different
537
+ ! value of n. this initialization does not have to be
538
+ ! repeated so long as n remains unchanged thus subsequent
539
+ ! transforms can be obtained faster than the first.
540
+ !
541
+ ! output parameters
542
+ !
543
+ ! x for i=1, ..., n
544
+ !
545
+ ! x(i) = (-1)**(i-1)*x(n)
546
+ !
547
+ ! + the sum from k=1 to k=n-1 of
548
+ !
549
+ ! 2*x(k)*sin((2*i-1)*k*pi/(2*n))
550
+ !
551
+ ! a call of sinqf followed by a call of
552
+ ! sinqb will multiply the sequence x by 4*n.
553
+ ! therefore sinqb is the unnormalized inverse
554
+ ! of sinqf.
555
+ !
556
+ ! wsave contains initialization calculations which must not
557
+ ! be destroyed between calls of sinqf or sinqb.
558
+ !
559
+ ! **********************************************************************
560
+ !
561
+ ! subroutine sinqb(n, x, wsave)
562
+ !
563
+ ! subroutine sinqb computes the fast fourier transform of quarter
564
+ ! wave data. that is , sinqb computes a sequence from its
565
+ ! representation in terms of a sine series with odd wave numbers.
566
+ ! the transform is defined below at output parameter x.
567
+ !
568
+ ! sinqf is the unnormalized inverse of sinqb since a call of sinqb
569
+ ! followed by a call of sinqf will multiply the input sequence x
570
+ ! by 4*n.
571
+ !
572
+ ! the array wsave which is used by subroutine sinqb must be
573
+ ! initialized by calling subroutine sinqi(n, wsave).
574
+ !
575
+ !
576
+ ! input parameters
577
+ !
578
+ ! n the length of the array x to be transformed. the method
579
+ ! is most efficient when n is a product of small primes.
580
+ !
581
+ ! x an array which contains the sequence to be transformed
582
+ !
583
+ ! wsave a work array which must be dimensioned at least 3*n+15.
584
+ ! in the program that calls sinqb. the wsave array must be
585
+ ! initialized by calling subroutine sinqi(n, wsave) and a
586
+ ! different wsave array must be used for each different
587
+ ! value of n. this initialization does not have to be
588
+ ! repeated so long as n remains unchanged thus subsequent
589
+ ! transforms can be obtained faster than the first.
590
+ !
591
+ ! output parameters
592
+ !
593
+ ! x for i=1, ..., n
594
+ !
595
+ ! x(i)= the sum from k=1 to k=n of
596
+ !
597
+ ! 4*x(k)*sin((2k-1)*i*pi/(2*n))
598
+ !
599
+ ! a call of sinqb followed by a call of
600
+ ! sinqf will multiply the sequence x by 4*n.
601
+ ! therefore sinqf is the unnormalized inverse
602
+ ! of sinqb.
603
+ !
604
+ ! wsave contains initialization calculations which must not
605
+ ! be destroyed between calls of sinqb or sinqf.
606
+ !
607
+ ! **********************************************************************
608
+ !
609
+ ! subroutine cosqi(n, wsave)
610
+ !
611
+ ! subroutine cosqi initializes the array wsave which is used in
612
+ ! both cosqf and cosqb. the prime factorization of n together with
613
+ ! a tabulation of the trigonometric functions are computed and
614
+ ! stored in wsave.
615
+ !
616
+ ! input parameter
617
+ !
618
+ ! n the length of the array to be transformed. the method
619
+ ! is most efficient when n is a product of small primes.
620
+ !
621
+ ! output parameter
622
+ !
623
+ ! wsave a work array which must be dimensioned at least 3*n+15.
624
+ ! the same work array can be used for both cosqf and cosqb
625
+ ! as long as n remains unchanged. different wsave arrays
626
+ ! are required for different values of n. the contents of
627
+ ! wsave must not be changed between calls of cosqf or cosqb.
628
+ !
629
+ ! **********************************************************************
630
+ !
631
+ ! subroutine cosqf(n, x, wsave)
632
+ !
633
+ ! subroutine cosqf computes the fast fourier transform of quarter
634
+ ! wave data. that is , cosqf computes the coefficients in a cosine
635
+ ! series representation with only odd wave numbers. the transform
636
+ ! is defined below at output parameter x
637
+ !
638
+ ! cosqf is the unnormalized inverse of cosqb since a call of cosqf
639
+ ! followed by a call of cosqb will multiply the input sequence x
640
+ ! by 4*n.
641
+ !
642
+ ! the array wsave which is used by subroutine cosqf must be
643
+ ! initialized by calling subroutine cosqi(n, wsave).
644
+ !
645
+ !
646
+ ! input parameters
647
+ !
648
+ ! n the length of the array x to be transformed. the method
649
+ ! is most efficient when n is a product of small primes.
650
+ !
651
+ ! x an array which contains the sequence to be transformed
652
+ !
653
+ ! wsave a work array which must be dimensioned at least 3*n+15
654
+ ! in the program that calls cosqf. the wsave array must be
655
+ ! initialized by calling subroutine cosqi(n, wsave) and a
656
+ ! different wsave array must be used for each different
657
+ ! value of n. this initialization does not have to be
658
+ ! repeated so long as n remains unchanged thus subsequent
659
+ ! transforms can be obtained faster than the first.
660
+ !
661
+ ! output parameters
662
+ !
663
+ ! x for i=1, ..., n
664
+ !
665
+ ! x(i) = x(1) plus the sum from k=2 to k=n of
666
+ !
667
+ ! 2*x(k)*cos((2*i-1)*(k-1)*pi/(2*n))
668
+ !
669
+ ! a call of cosqf followed by a call of
670
+ ! cosqb will multiply the sequence x by 4*n.
671
+ ! therefore cosqb is the unnormalized inverse
672
+ ! of cosqf.
673
+ !
674
+ ! wsave contains initialization calculations which must not
675
+ ! be destroyed between calls of cosqf or cosqb.
676
+ !
677
+ ! **********************************************************************
678
+ !
679
+ ! subroutine cosqb(n, x, wsave)
680
+ !
681
+ ! subroutine cosqb computes the fast fourier transform of quarter
682
+ ! wave data. that is , cosqb computes a sequence from its
683
+ ! representation in terms of a cosine series with odd wave numbers.
684
+ ! the transform is defined below at output parameter x.
685
+ !
686
+ ! cosqb is the unnormalized inverse of cosqf since a call of cosqb
687
+ ! followed by a call of cosqf will multiply the input sequence x
688
+ ! by 4*n.
689
+ !
690
+ ! the array wsave which is used by subroutine cosqb must be
691
+ ! initialized by calling subroutine cosqi(n, wsave).
692
+ !
693
+ !
694
+ ! input parameters
695
+ !
696
+ ! n the length of the array x to be transformed. the method
697
+ ! is most efficient when n is a product of small primes.
698
+ !
699
+ ! x an array which contains the sequence to be transformed
700
+ !
701
+ ! wsave a work array that must be dimensioned at least 3*n+15
702
+ ! in the program that calls cosqb. the wsave array must be
703
+ ! initialized by calling subroutine cosqi(n, wsave) and a
704
+ ! different wsave array must be used for each different
705
+ ! value of n. this initialization does not have to be
706
+ ! repeated so long as n remains unchanged thus subsequent
707
+ ! transforms can be obtained faster than the first.
708
+ !
709
+ ! output parameters
710
+ !
711
+ ! x for i=1, ..., n
712
+ !
713
+ ! x(i)= the sum from k=1 to k=n of
714
+ !
715
+ ! 4*x(k)*cos((2*k-1)*(i-1)*pi/(2*n))
716
+ !
717
+ ! a call of cosqb followed by a call of
718
+ ! cosqf will multiply the sequence x by 4*n.
719
+ ! therefore cosqf is the unnormalized inverse
720
+ ! of cosqb.
721
+ !
722
+ ! wsave contains initialization calculations which must not
723
+ ! be destroyed between calls of cosqb or cosqf.
724
+ !
725
+ ! **********************************************************************
726
+ !
727
+ !
728
+ ! **********************************************************************
729
+ !
730
+ ! subroutine cfftf(n, c, wsave)
731
+ !
732
+ ! subroutine cfftf computes the forward complex discrete fourier
733
+ ! transform (the fourier analysis). equivalently , cfftf computes
734
+ ! the fourier coefficients of a complex periodic sequence.
735
+ ! the transform is defined below at output parameter c.
736
+ !
737
+ ! the transform is not normalized. to obtain a normalized transform
738
+ ! the output must be divided by n. otherwise a call of cfftf
739
+ ! followed by a call of cfftb will multiply the sequence by n.
740
+ !
741
+ ! the array wsave which is used by subroutine cfftf must be
742
+ ! initialized by calling subroutine cffti(n, wsave).
743
+ !
744
+ ! input parameters
745
+ !
746
+ !
747
+ ! n the length of the complex sequence c. the method is
748
+ ! more efficient when n is the product of small primes. n
749
+ !
750
+ ! c a complex array of length n which contains the sequence
751
+ !
752
+ ! wsave a real work array which must be dimensioned at least 4n+15
753
+ ! in the program that calls cfftf. the wsave array must be
754
+ ! initialized by calling subroutine cffti(n, wsave) and a
755
+ ! different wsave array must be used for each different
756
+ ! value of n. this initialization does not have to be
757
+ ! repeated so long as n remains unchanged thus subsequent
758
+ ! transforms can be obtained faster than the first.
759
+ ! the same wsave array can be used by cfftf and cfftb.
760
+ !
761
+ ! output parameters
762
+ !
763
+ ! c for j=1, ..., n
764
+ !
765
+ ! c(j)=the sum from k=1, ..., n of
766
+ !
767
+ ! c(k)*exp(-i*(j-1)*(k-1)*2*pi/n)
768
+ !
769
+ ! where i=sqrt(-1)
770
+ !
771
+ ! wsave contains initialization calculations which must not be
772
+ ! destroyed between calls of subroutine cfftf or cfftb
773
+ !
774
+ ! **********************************************************************
775
+
776
+ module type_PeriodicFastFourierTransform
777
+
778
+ use fishpack_precision, only: &
779
+ wp, & ! Working precision
780
+ ip, & ! Integer precision
781
+ PI, &
782
+ TWO_PI, &
783
+ HALF_PI
784
+
785
+ ! Explicit typing only
786
+ implicit None
787
+
788
+ ! Everything is private unless stated otherwise
789
+ private
790
+ public :: PeriodicFastFourierTransform
791
+ public :: rffti ! initialize rfftf and rfftb
792
+ public :: rfftf ! forward transform of a real periodic sequence
793
+ public :: rfftb ! backward transform of a real coefficient array
794
+ public :: ezffti !initialize ezfftf and ezfftb
795
+ public :: ezfftf ! a simplified real periodic forward transform
796
+ public :: ezfftb ! a simplified real periodic backward transform
797
+ public :: sinti ! initialize sint
798
+ public :: sint ! sine transform of a real odd sequence
799
+ public :: costi ! initialize cost
800
+ public :: cost ! cosine transform of a real even sequence
801
+ public :: sinqi ! initialize sinqf and sinqb
802
+ public :: sinqf ! forward sine transform with odd wave numbers
803
+ public :: sinqb ! unnormalized inverse of sinqf
804
+ public :: cosqi ! initialize cosqf and cosqb
805
+ public :: cosqf ! forward cosine transform with odd wave numbers
806
+ public :: cosqb ! unnormalized inverse of cosqf
807
+ public :: cffti ! initialize cfftf and cfftb
808
+ public :: cfftf ! forward transform of a complex periodic sequence
809
+ public :: cfftb ! unnormalized inverse of cfftf
810
+
811
+ ! Parameters confined to the module
812
+ real(wp), parameter :: ZERO = 0.0_wp
813
+ real(wp), parameter :: HALF = 0.5_wp
814
+ real(wp), parameter :: ONE = 1.0_wp
815
+ real(wp), parameter :: TWO = 2.0_wp
816
+ real(wp), parameter :: THREE = 3.0_wp
817
+ real(wp), parameter :: FOUR = 4.0_wp
818
+ real(wp), parameter :: FIVE = 5.0_wp
819
+ real(wp), parameter :: SQRT_2 = sqrt(TWO)
820
+ real(wp), parameter :: SQRT_3 = sqrt(THREE)
821
+ real(wp), parameter :: SQRT_5 = sqrt(FIVE)
822
+
823
+ type, public :: PeriodicFastFourierTransform
824
+ contains
825
+ ! Type-bound procedures
826
+ procedure, nopass, public :: rffti
827
+ procedure, nopass, public :: rfftf
828
+ procedure, nopass, public :: rfftb
829
+ procedure, nopass, public :: ezffti
830
+ procedure, nopass, public :: ezfftf
831
+ procedure, nopass, public :: ezfftb
832
+ procedure, nopass, public :: sinti
833
+ procedure, nopass, public :: sint
834
+ procedure, nopass, public :: costi
835
+ procedure, nopass, public :: cost
836
+ procedure, nopass, public :: sinqi
837
+ procedure, nopass, public :: sinqf
838
+ procedure, nopass, public :: sinqb
839
+ procedure, nopass, public :: cosqi
840
+ procedure, nopass, public :: cosqf
841
+ procedure, nopass, public :: cosqb
842
+ procedure, nopass, public :: cffti
843
+ procedure, nopass, public :: cfftf
844
+ procedure, nopass, public :: cfftb
845
+ end type PeriodicFastFourierTransform
846
+
847
+ contains
848
+
849
+ subroutine ezfftf(n, r, azero, a, b, wsave)
850
+
851
+ ! Dummy arguments
852
+ integer(ip), intent(in) :: n
853
+ real(wp), intent(out) :: azero
854
+ real(wp), intent(in) :: r(*)
855
+ real(wp), intent(out) :: a(*)
856
+ real(wp), intent(out) :: b(*)
857
+ real(wp) :: wsave(*)
858
+
859
+ ! Local variables
860
+ integer(ip) :: ns2, ns2m
861
+ real(wp) :: cf, cfm
862
+
863
+ !
864
+ if (3 > n) then
865
+ if (n /= 2) then
866
+ azero = r(1)
867
+ return
868
+ end if
869
+ azero = HALF*(r(1)+r(2))
870
+ a(1) = HALF*(r(1)-r(2))
871
+ return
872
+ end if
873
+
874
+ wsave(:n) = r(:n)
875
+
876
+ call rfftf(n, wsave, wsave(n+1))
877
+
878
+ cf = TWO/n
879
+ cfm = -cf
880
+ azero = HALF*cf*wsave(1)
881
+ ns2 =(n + 1)/2
882
+ ns2m = ns2 - 1
883
+ a(:ns2m) = cf*wsave(2:ns2m*2:2)
884
+ b(:ns2m) = cfm*wsave(3:ns2m*2+1:2)
885
+
886
+ if (mod(n, 2) /= 1) then
887
+ a(ns2) = HALF*cf*wsave(n)
888
+ b(ns2) = ZERO
889
+ end if
890
+
891
+ end subroutine ezfftf
892
+
893
+ subroutine ezfftb(n, r, azero, a, b, wsave)
894
+
895
+ ! Dummy arguments
896
+
897
+ integer(ip), intent(in) :: n
898
+ real(wp), intent(in) :: azero
899
+ real(wp) :: r(*)
900
+ real(wp), intent(in) :: a(*)
901
+ real(wp), intent(in) :: b(*)
902
+ real(wp) :: wsave(*)
903
+
904
+ ! Local variables
905
+
906
+ integer(ip) :: ns2
907
+
908
+
909
+ if (3 > n) then
910
+ if (n /= 2) then
911
+ r(1) = azero
912
+ return
913
+ end if
914
+ r(1) = azero + a(1)
915
+ r(2) = azero - a(1)
916
+ return
917
+ end if
918
+
919
+ ns2 =(n - 1)/2
920
+ r(2:ns2*2:2) = HALF*a(:ns2)
921
+ r(3:ns2*2+1:2) = -HALF*b(:ns2)
922
+ r(1) = azero
923
+
924
+ if (mod(n, 2) == 0) r(n) = a(ns2+1)
925
+
926
+ call rfftb(n, r, wsave(n+1))
927
+
928
+ end subroutine ezfftb
929
+
930
+ subroutine ezffti(n, wsave)
931
+
932
+ ! Dummy arguments
933
+
934
+ integer(ip) :: n
935
+ real(wp) :: wsave(*)
936
+
937
+
938
+ if (n /= 1) call real_periodic_initialization_lower_routine(n, wsave(2*n+1), wsave(3*n+1))
939
+
940
+ end subroutine ezffti
941
+
942
+ subroutine real_periodic_initialization_lower_routine(n, wa, ifac)
943
+
944
+ ! Dummy arguments
945
+
946
+ integer(ip), intent(in) :: n
947
+ real(wp), intent(inout) :: ifac(*)
948
+ real(wp), intent(inout) :: wa(*)
949
+
950
+ ! Local variables
951
+
952
+ integer(ip), parameter :: NTRYH(*) = [4, 2, 3, 5]
953
+ integer(ip) :: nl, nf, j, ntry, nq, nr, i, is, nfm1
954
+ integer(ip) :: l1, k1, iip, l2, ido, iipm, ii
955
+ real(wp) :: argh, arg1, ch1, sh1, dch1, dsh1, temp
956
+
957
+
958
+ ! Initialize
959
+ ntry = 0
960
+ nl = n
961
+ nf = 0
962
+ j = 0
963
+
964
+ factorization_loop: do
965
+
966
+ j = j + 1
967
+
968
+ if (j <= 4) then
969
+ ntry = NTRYH(j)
970
+ else
971
+ ntry = ntry + 2
972
+ end if
973
+
974
+ inner_loop: do
975
+
976
+ nq = nl/ntry
977
+ nr = nl - ntry*nq
978
+
979
+ if (nr /= 0) cycle factorization_loop
980
+
981
+ nf = nf + 1
982
+ ifac(nf+2) = ntry
983
+ nl = nq
984
+
985
+ if (ntry == 2) then
986
+ if (nf /= 1) then
987
+ ifac(nf+2:4:(-1)) = ifac(nf+1:3:(-1))
988
+ ifac(3) = 2
989
+ end if
990
+ end if
991
+
992
+ if (nl /= 1) cycle inner_loop
993
+
994
+ exit inner_loop
995
+ end do inner_loop
996
+ exit factorization_loop
997
+ end do factorization_loop
998
+
999
+ ifac(1) = n
1000
+ ifac(2) = nf
1001
+ argh = TWO_PI/n
1002
+ is = 0
1003
+ nfm1 = nf - 1
1004
+ l1 = 1
1005
+
1006
+ if (nfm1 /= 0) then
1007
+ do k1 = 1, nfm1
1008
+ iip = int(ifac(k1+2), kind=ip)
1009
+ l2 = l1*iip
1010
+ ido = n/l2
1011
+ iipm = iip - 1
1012
+ arg1 = real(l1, kind=wp)*argh
1013
+ ch1 = ONE
1014
+ sh1 = ZERO
1015
+ dch1 = cos(arg1)
1016
+ dsh1 = sin(arg1)
1017
+ do j = 1, iipm
1018
+ temp = dch1*ch1 - dsh1*sh1
1019
+ sh1 = dch1*sh1 + dsh1*ch1
1020
+ ch1 = temp
1021
+ i = is + 2
1022
+ wa(i-1) = ch1
1023
+ wa(i) = sh1
1024
+ if (ido >= 5) then
1025
+ do ii = 5, ido, 2
1026
+ i = i + 2
1027
+ wa(i-1) = ch1*wa(i-3) - sh1*wa(i-2)
1028
+ wa(i) = ch1*wa(i-2) + sh1*wa(i-3)
1029
+ end do
1030
+ end if
1031
+ is = is + ido
1032
+ end do
1033
+ l1 = l2
1034
+ end do
1035
+ end if
1036
+
1037
+ end subroutine real_periodic_initialization_lower_routine
1038
+
1039
+ subroutine costi(n, wsave)
1040
+
1041
+ ! Dummy arguments
1042
+
1043
+ integer(ip), intent(in) :: n
1044
+ real(wp) :: wsave(*)
1045
+
1046
+ ! Local variables
1047
+
1048
+ integer(ip) :: nm1, np1, ns2, k, kc
1049
+ real(wp) :: dt, fk
1050
+
1051
+
1052
+ if (n > 3) then
1053
+ nm1 = n - 1
1054
+ np1 = n + 1
1055
+ ns2 = n/2
1056
+ dt = pi/nm1
1057
+ fk = ZERO
1058
+
1059
+ do k = 2, ns2
1060
+ kc = np1 - k
1061
+ fk = fk + ONE
1062
+ wsave(k) = TWO * sin(fk*dt)
1063
+ wsave(kc) = TWO * cos(fk*dt)
1064
+ end do
1065
+
1066
+ call rffti(nm1, wsave(n+1))
1067
+
1068
+ end if
1069
+
1070
+ end subroutine costi
1071
+
1072
+ subroutine cost(n, x, wsave)
1073
+
1074
+ ! Dummy arguments
1075
+
1076
+ integer(ip), intent(in) :: n
1077
+ real(wp) :: x(*)
1078
+ real(wp) :: wsave(*)
1079
+
1080
+ ! Local variables
1081
+
1082
+ integer(ip) :: nm1, np1, ns2, k, kc, modn, i
1083
+ real(wp) :: x1h, x1p3, tx2, c1, t1, t2, xim2, xi
1084
+
1085
+ !
1086
+ nm1 = n - 1
1087
+ np1 = n + 1
1088
+ ns2 = n/2
1089
+
1090
+ if (3 < n) then
1091
+ if (3 > n) then
1092
+ x1h = x(1) + x(2)
1093
+ x(2) = x(1) - x(2)
1094
+ x(1) = x1h
1095
+ return
1096
+ end if
1097
+ if (n <= 3) then
1098
+ x1p3 = x(1) + x(3)
1099
+ tx2 = x(2) + x(2)
1100
+ x(2) = x(1) - x(3)
1101
+ x(1) = x1p3 + tx2
1102
+ x(3) = x1p3 - tx2
1103
+ return
1104
+ end if
1105
+ c1 = x(1) - x(n)
1106
+ x(1) = x(1) + x(n)
1107
+ do k = 2, ns2
1108
+ kc = np1 - k
1109
+ t1 = x(k) + x(kc)
1110
+ t2 = x(k) - x(kc)
1111
+ c1 = c1 + wsave(kc)*t2
1112
+ t2 = wsave(k)*t2
1113
+ x(k) = t1 - t2
1114
+ x(kc) = t1 + t2
1115
+ end do
1116
+
1117
+ modn = mod(n, 2)
1118
+
1119
+ if (modn /= 0) x(ns2+1) = x(ns2+1) + x(ns2+1)
1120
+
1121
+ call rfftf(nm1, x, wsave(n+1))
1122
+
1123
+ xim2 = x(2)
1124
+ x(2) = c1
1125
+
1126
+ do i = 4, n, 2
1127
+ xi = x(i)
1128
+ x(i) = x(i-2) - x(i-1)
1129
+ x(i-1) = xim2
1130
+ xim2 = xi
1131
+ end do
1132
+
1133
+ if (modn /= 0) x(n) = xim2
1134
+
1135
+ end if
1136
+
1137
+ end subroutine cost
1138
+
1139
+ subroutine sinti(n, wsave)
1140
+
1141
+ ! Dummy arguments
1142
+ integer(ip), intent(in) :: n
1143
+ real(wp) :: wsave(*)
1144
+
1145
+ ! Local variables
1146
+ integer(ip) :: ns2, np1, k
1147
+ real(wp) :: dt
1148
+
1149
+ if (n > 1) then
1150
+ ns2 = n/2
1151
+ np1 = n + 1
1152
+ dt = PI/np1
1153
+
1154
+ do k = 1, ns2
1155
+ wsave(k) = TWO * sin(k*dt)
1156
+ end do
1157
+
1158
+ call rffti(np1, wsave(ns2+1))
1159
+ end if
1160
+
1161
+ end subroutine sinti
1162
+
1163
+ subroutine sint(n, x, wsave)
1164
+
1165
+ ! Dummy arguments
1166
+ integer(ip) :: n
1167
+ real(wp) :: x(*)
1168
+ real(wp) :: wsave(*)
1169
+
1170
+ ! Local variables
1171
+ integer(ip) :: np1, iw1, iw2, iw3
1172
+
1173
+
1174
+ np1 = n + 1
1175
+ iw1 = n/2 + 1
1176
+ iw2 = iw1 + np1
1177
+ iw3 = iw2 + np1
1178
+
1179
+ call sint1(n, x, wsave, wsave(iw1), wsave(iw2), wsave(iw3))
1180
+
1181
+ end subroutine sint
1182
+
1183
+ subroutine sint1(n, war, was, xh, x, ifac)
1184
+
1185
+ ! Dummy arguments
1186
+
1187
+ integer(ip), intent(in) :: n
1188
+ real(wp) :: ifac(*)
1189
+ real(wp) :: war(*)
1190
+ real(wp), intent(in) :: was(*)
1191
+ real(wp) :: xh(*)
1192
+ real(wp) :: x(*)
1193
+
1194
+ ! Local variables
1195
+
1196
+ integer(ip) :: i, np1, ns2, k, kc, modn
1197
+ real(wp) :: temp, t1, t2
1198
+
1199
+
1200
+ xh(:n) = war(:n)
1201
+ war(:n) = x(:n)
1202
+
1203
+ if (3 > n) then
1204
+ if (n /= 2) then
1205
+ xh(1) = xh(1) + xh(1)
1206
+ x(:n) = war(:n)
1207
+ war(:n) = xh(:n)
1208
+ return
1209
+ end if
1210
+ temp = SQRT_3*(xh(1)+xh(2))
1211
+ xh(2) = SQRT_3*(xh(1)-xh(2))
1212
+ xh(1) = temp
1213
+ x(:n) = war(:n)
1214
+ war(:n) = xh(:n)
1215
+ return
1216
+ end if
1217
+
1218
+ np1 = n + 1
1219
+ ns2 = n/2
1220
+ x(1) = ZERO
1221
+
1222
+ do k = 1, ns2
1223
+ kc = np1 - k
1224
+ t1 = xh(k) - xh(kc)
1225
+ t2 = was(k)*(xh(k)+xh(kc))
1226
+ x(k+1) = t1 + t2
1227
+ x(kc+1) = t2 - t1
1228
+ end do
1229
+
1230
+ modn = mod(n, 2)
1231
+
1232
+ if (modn /= 0) x(ns2+2) = FOUR * xh(ns2+1)
1233
+
1234
+ call real_forward_lower_routine(np1, x, xh, war, ifac)
1235
+
1236
+ xh(1) = HALF*x(1)
1237
+
1238
+ do i = 3, n, 2
1239
+ xh(i-1) = -x(i)
1240
+ xh(i) = xh(i-2) + x(i-1)
1241
+ end do
1242
+
1243
+ if (modn == 0) xh(n) = -x(n+1)
1244
+
1245
+ x(:n) = war(:n)
1246
+ war(:n) = xh(:n)
1247
+
1248
+ end subroutine sint1
1249
+
1250
+ subroutine cosqi(n, wsave)
1251
+
1252
+ ! Dummy arguments
1253
+
1254
+ integer(ip) :: n
1255
+ real(wp) :: wsave(*)
1256
+
1257
+ ! Local variables
1258
+
1259
+ integer(ip) :: k ! Counter
1260
+ real(wp) :: fk, dt
1261
+
1262
+
1263
+ dt = HALF_PI/n
1264
+
1265
+ fk = ZERO
1266
+ do k = 1, n
1267
+ fk = fk + ONE
1268
+ wsave(k) = cos(fk*dt)
1269
+ end do
1270
+
1271
+ call rffti(n, wsave(n+1))
1272
+
1273
+ end subroutine cosqi
1274
+
1275
+ subroutine cosqf(n, x, wsave)
1276
+
1277
+ ! Dummy arguments
1278
+
1279
+ integer(ip), intent(in) :: n
1280
+ real(wp) :: x(*)
1281
+ real(wp) :: wsave(*)
1282
+
1283
+ ! Local variables
1284
+
1285
+ real(wp) :: temp
1286
+
1287
+
1288
+ if (3 < n) then
1289
+ if (n > 2) call cosqf1(n, x, wsave, wsave(n+1))
1290
+ temp = SQRT_2*x(2)
1291
+ x(2) = x(1) - temp
1292
+ x(1) = x(1) + temp
1293
+ end if
1294
+
1295
+ end subroutine cosqf
1296
+
1297
+ subroutine cosqf1(n, x, w, xh)
1298
+
1299
+ ! Dummy arguments
1300
+
1301
+ integer(ip), intent(in) :: n
1302
+ real(wp) :: x(*)
1303
+ real(wp), intent(in) :: w(*)
1304
+ real(wp) :: xh(*)
1305
+
1306
+ ! Local variables
1307
+
1308
+ integer(ip) :: ns2, np2, k, kc, modn, i
1309
+ real(wp) :: temp
1310
+
1311
+
1312
+ ns2 =(n + 1)/2
1313
+ np2 = n + 2
1314
+
1315
+ do k = 2, ns2
1316
+ kc = np2 - k
1317
+ xh(k) = x(k) + x(kc)
1318
+ xh(kc) = x(k) - x(kc)
1319
+ end do
1320
+
1321
+ modn = mod(n, 2)
1322
+
1323
+ if (modn == 0) xh(ns2+1) = x(ns2+1) + x(ns2+1)
1324
+
1325
+ do k = 2, ns2
1326
+ kc = np2 - k
1327
+ x(k) = w(k-1)*xh(kc) + w(kc-1)*xh(k)
1328
+ x(kc) = w(k-1)*xh(k) - w(kc-1)*xh(kc)
1329
+ end do
1330
+
1331
+ if (modn == 0) x(ns2+1) = w(ns2)*xh(ns2+1)
1332
+
1333
+ call rfftf(n, x, xh)
1334
+
1335
+ do i = 3, n, 2
1336
+ temp = x(i-1) - x(i)
1337
+ x(i) = x(i-1) + x(i)
1338
+ x(i-1) = temp
1339
+ end do
1340
+
1341
+ end subroutine cosqf1
1342
+
1343
+ subroutine cosqb(n, x, wsave)
1344
+
1345
+ ! Dummy arguments
1346
+
1347
+ integer(ip) :: n
1348
+ real(wp) :: x(*)
1349
+ real(wp) :: wsave(*)
1350
+
1351
+ ! Local variables
1352
+
1353
+ real(wp), parameter :: TWO_SQRT_2 = TWO * sqrt(TWO) ! 2.82842712474619
1354
+ real(wp) :: temp
1355
+
1356
+ if (3 > n) then
1357
+ if (n /= 2) then
1358
+ x(1) = FOUR * x(1)
1359
+ else
1360
+ temp = FOUR * (x(1)+x(2))
1361
+ x(2) = TWO_SQRT_2*(x(1)-x(2))
1362
+ x(1) = temp
1363
+ end if
1364
+ end if
1365
+
1366
+ call cosqb1(n, x, wsave, wsave(n+1))
1367
+
1368
+ end subroutine cosqb
1369
+
1370
+ subroutine cosqb1(n, x, w, xh)
1371
+
1372
+ ! Dummy arguments
1373
+
1374
+ integer(ip) :: n
1375
+ real(wp) :: x(*)
1376
+ real(wp), intent(in) :: w(*)
1377
+ real(wp) :: xh(*)
1378
+
1379
+ ! Local variables
1380
+
1381
+ integer(ip) :: ns2, np2, i, modn, k, kc
1382
+ real(wp) :: xim1
1383
+
1384
+
1385
+ ns2 =(n + 1)/2
1386
+ np2 = n + 2
1387
+
1388
+ do i = 3, n, 2
1389
+ xim1 = x(i-1) + x(i)
1390
+ x(i) = x(i) - x(i-1)
1391
+ x(i-1) = xim1
1392
+ end do
1393
+
1394
+ x(1) = TWO*x(1)
1395
+
1396
+ modn = mod(n, 2)
1397
+
1398
+ if (modn == 0) x(n) = x(n) + x(n)
1399
+
1400
+ call rfftb(n, x, xh)
1401
+
1402
+ do k = 2, ns2
1403
+ kc = np2 - k
1404
+ xh(k) = w(k-1)*x(kc) + w(kc-1)*x(k)
1405
+ xh(kc) = w(k-1)*x(k) - w(kc-1)*x(kc)
1406
+ end do
1407
+
1408
+ if (modn == 0) x(ns2+1) = w(ns2)*(x(ns2+1)+x(ns2+1))
1409
+
1410
+ do k = 2, ns2
1411
+ kc = np2 - k
1412
+ x(k) = xh(k) + xh(kc)
1413
+ x(kc) = xh(k) - xh(kc)
1414
+ end do
1415
+
1416
+ x(1) = TWO*x(1)
1417
+
1418
+ end subroutine cosqb1
1419
+
1420
+ subroutine sinqi(n, wsave)
1421
+
1422
+ ! Dummy arguments
1423
+
1424
+ integer(ip) :: n
1425
+ real(wp) :: wsave(*)
1426
+
1427
+
1428
+ call cosqi(n, wsave)
1429
+
1430
+ end subroutine sinqi
1431
+
1432
+ subroutine sinqf(n, x, wsave)
1433
+
1434
+ ! Dummy arguments
1435
+
1436
+ integer(ip) :: n
1437
+ real(wp) :: x(*)
1438
+ real(wp) :: wsave(*)
1439
+
1440
+ ! Local variables
1441
+
1442
+ integer(ip) :: ns2, k, kc
1443
+ real(wp) :: xhold
1444
+
1445
+
1446
+ if (n /= 1) then
1447
+
1448
+ ns2 = n/2
1449
+
1450
+ do k = 1, ns2
1451
+ kc = n - k
1452
+ xhold = x(k)
1453
+ x(k) = x(kc+1)
1454
+ x(kc+1) = xhold
1455
+ end do
1456
+
1457
+ call cosqf(n, x, wsave)
1458
+
1459
+ x(2:n:2) = -x(2:n:2)
1460
+
1461
+ end if
1462
+
1463
+ end subroutine sinqf
1464
+
1465
+ subroutine sinqb(n, x, wsave)
1466
+
1467
+ ! Dummy arguments
1468
+
1469
+ integer(ip) :: n
1470
+ real(wp) :: x(*)
1471
+ real(wp) :: wsave(*)
1472
+
1473
+ ! Local variables
1474
+
1475
+ integer(ip) :: ns2, k, kc
1476
+ real(wp) :: xhold
1477
+
1478
+
1479
+ if (n <= 1) then
1480
+ x(1) = FOUR * x(1)
1481
+ else
1482
+ ns2 = n/2
1483
+ x(2:n:2) = -x(2:n:2)
1484
+
1485
+ call cosqb(n, x, wsave)
1486
+
1487
+ do k = 1, ns2
1488
+ kc = n - k
1489
+ xhold = x(k)
1490
+ x(k) = x(kc+1)
1491
+ x(kc+1) = xhold
1492
+ end do
1493
+ end if
1494
+
1495
+ end subroutine sinqb
1496
+
1497
+ ! Purpose:
1498
+ !
1499
+ ! Initializes the array wsave which is used in
1500
+ ! both cfftf and cfftb. the prime factorization of n together with
1501
+ ! a tabulation of the trigonometric functions are computed and
1502
+ ! stored in wsave.
1503
+ !
1504
+ ! input parameter
1505
+ !
1506
+ ! n the length of the sequence to be transformed
1507
+ !
1508
+ ! output parameter
1509
+ !
1510
+ ! wsave a work array which must be dimensioned at least 4*n+15
1511
+ ! the same work array can be used for both cfftf and cfftb
1512
+ ! as long as n remains unchanged. different wsave arrays
1513
+ ! are required for different values of n. the contents of
1514
+ ! wsave must not be changed between calls of cfftf or cfftb.
1515
+ !
1516
+ pure subroutine cffti(n, wsave)
1517
+
1518
+ ! Dummy arguments
1519
+ integer(ip), intent(in) :: n
1520
+ real(wp), intent(out) :: wsave(*)
1521
+
1522
+ ! Local variables
1523
+ integer(ip) :: iw1, iw2
1524
+
1525
+ if (n /= 1) then
1526
+ iw1 = 2*n + 1
1527
+ iw2 = iw1 + 2*n
1528
+ call complex_initialization_lower_routine(n, wsave(iw1), wsave(iw2))
1529
+ end if
1530
+
1531
+ end subroutine cffti
1532
+
1533
+ pure subroutine complex_initialization_lower_routine(n, wa, ifac)
1534
+
1535
+ ! Dummy arguments
1536
+ integer(ip), intent(in) :: n
1537
+ real(wp), intent(out) :: ifac(*)
1538
+ real(wp), intent(out) :: wa(*)
1539
+
1540
+ ! Local variables
1541
+ integer(ip), parameter :: NTRYH(*) = [3, 4, 2, 5]
1542
+ integer(ip) :: ntest, nf, j, ntry, nq, nr
1543
+ integer(ip) :: i, l1, k1, iip, ld, l2, ido
1544
+ integer(ip) :: idot, iipm, i1, ii
1545
+ real(wp) :: argh, fi, argld, arg
1546
+
1547
+ ! Initialize
1548
+ nf = 0
1549
+ ntest = n
1550
+ ntry = 0
1551
+ j = 0
1552
+
1553
+ factorization_loop: do
1554
+
1555
+ j = j + 1
1556
+
1557
+ if (j <= 4) then
1558
+ ntry = NTRYH(j)
1559
+ else
1560
+ ntry = ntry + 2
1561
+ end if
1562
+
1563
+ inner_loop: do
1564
+
1565
+ nq = ntest/ntry
1566
+ nr = ntest - ntry*nq
1567
+
1568
+ if (nr /= 0) cycle factorization_loop
1569
+
1570
+ nf = nf + 1
1571
+ ifac(nf+2) = ntry
1572
+ ntest = nq
1573
+
1574
+ if (ntry == 2) then
1575
+ if (nf /= 1) then
1576
+ ifac(nf+2:4:(-1)) = ifac(nf+1:3:(-1))
1577
+ ifac(3) = 2
1578
+ end if
1579
+ end if
1580
+
1581
+ if (ntest /= 1) cycle inner_loop
1582
+ exit inner_loop
1583
+ end do inner_loop
1584
+ exit factorization_loop
1585
+ end do factorization_loop
1586
+
1587
+ ifac(1) = n
1588
+ ifac(2) = nf
1589
+ argh = TWO_PI/n
1590
+ i = 2
1591
+ l1 = 1
1592
+ do k1 = 1, nf
1593
+ iip = int(ifac(k1+2), kind=ip)
1594
+ ld = 0
1595
+ l2 = l1*iip
1596
+ ido = n/l2
1597
+ idot = ido + ido + 2
1598
+ iipm = iip - 1
1599
+ set_workspace_loop: do j = 1, iipm
1600
+ i1 = i
1601
+ wa(i-1) = ONE
1602
+ wa(i) = ZERO
1603
+ ld = ld + l1
1604
+ fi = ZERO
1605
+ argld = real(ld, kind=wp)*argh
1606
+ do ii = 4, idot, 2
1607
+ i = i + 2
1608
+ fi = fi + ONE
1609
+ arg = fi*argld
1610
+ wa(i-1) = cos(arg)
1611
+ wa(i) = sin(arg)
1612
+ end do
1613
+
1614
+ if (iip <= 5) cycle set_workspace_loop
1615
+
1616
+ wa(i1-1) = wa(i-1)
1617
+ wa(i1) = wa(i)
1618
+
1619
+ end do set_workspace_loop
1620
+ l1 = l2
1621
+ end do
1622
+
1623
+ end subroutine complex_initialization_lower_routine
1624
+
1625
+ ! Purpose:
1626
+ !
1627
+ ! Computes the backward complex discrete fourier
1628
+ ! transform (the fourier synthesis). equivalently , cfftb computes
1629
+ ! a complex periodic sequence from its fourier coefficients.
1630
+ ! the transform is defined below at output parameter c.
1631
+ !
1632
+ ! a call of cfftf followed by a call of cfftb will multiply the
1633
+ ! sequence by n.
1634
+ !
1635
+ ! the array wsave which is used by subroutine cfftb must be
1636
+ ! initialized by calling subroutine cffti(n, wsave).
1637
+ !
1638
+ ! input parameters
1639
+ !
1640
+ !
1641
+ ! n the length of the complex sequence c. the method is
1642
+ ! more efficient when n is the product of small primes.
1643
+ !
1644
+ ! c a complex array of length n which contains the sequence
1645
+ !
1646
+ ! wsave a real work array which must be dimensioned at least 4n+15
1647
+ ! in the program that calls cfftb. the wsave array must be
1648
+ ! initialized by calling subroutine cffti(n, wsave) and a
1649
+ ! different wsave array must be used for each different
1650
+ ! value of n. this initialization does not have to be
1651
+ ! repeated so long as n remains unchanged thus subsequent
1652
+ ! transforms can be obtained faster than the first.
1653
+ ! the same wsave array can be used by cfftf and cfftb.
1654
+ !
1655
+ ! output parameters
1656
+ !
1657
+ ! c for j=1, ..., n
1658
+ !
1659
+ ! c(j)=the sum from k=1, ..., n of
1660
+ !
1661
+ ! c(k)*exp(i*(j-1)*(k-1)*2*pi/n)
1662
+ !
1663
+ ! where i=sqrt(-1)
1664
+ !
1665
+ ! wsave contains initialization calculations which must not be
1666
+ ! destroyed between calls of subroutine cfftf or cfftb
1667
+ !
1668
+ subroutine cfftb(n, c, wsave)
1669
+
1670
+ ! Dummy arguments
1671
+ integer(ip), intent(in) :: n
1672
+ real(wp), intent(inout) :: c(*)
1673
+ real(wp), intent(inout) :: wsave(*)
1674
+
1675
+ ! Local variables
1676
+ integer(ip) :: iw1, iw2
1677
+
1678
+ if (n /= 1) then
1679
+ iw1 = 2*n + 1
1680
+ iw2 = iw1 + 2*n
1681
+ call complex_backward_lower_routine(n, c, wsave, wsave(iw1), wsave(iw2))
1682
+ end if
1683
+
1684
+ end subroutine cfftb
1685
+
1686
+ subroutine complex_backward_lower_routine(n, c, ch, wa, ifac)
1687
+
1688
+ ! Dummy arguments
1689
+ integer(ip), intent(in) :: n
1690
+ real(wp), intent(inout) :: c(*)
1691
+ real(wp), intent(in) :: ifac(*)
1692
+ real(wp) :: ch(*)
1693
+ real(wp) :: wa(*)
1694
+
1695
+ ! Local variables
1696
+ integer(ip) :: nf, na, l1, iw, k1, iip, l2, ido
1697
+ integer(ip) :: idot, idl1, ix2, ix3, ix4, nac, n2
1698
+
1699
+
1700
+ nf = int(ifac(2), kind=ip)
1701
+ na = 0
1702
+ l1 = 1
1703
+ iw = 1
1704
+ do k1 = 1, nf
1705
+ iip = int(ifac(k1+2), kind=ip)
1706
+ l2 = iip*l1
1707
+ ido = n/l2
1708
+ idot = ido + ido
1709
+ idl1 = idot*l1
1710
+
1711
+ select case (iip)
1712
+ case (2)
1713
+ if (na == 0) then
1714
+ call complex_backward_pass_2(idot, l1, c, ch, wa(iw))
1715
+ else
1716
+ call complex_backward_pass_2(idot, l1, ch, c, wa(iw))
1717
+ end if
1718
+ na = 1 - na
1719
+ case (3)
1720
+ ix2 = iw + idot
1721
+ if (na == 0) then
1722
+ call complex_backward_pass_3(idot, l1, c, ch, wa(iw), wa(ix2))
1723
+ else
1724
+ call complex_backward_pass_3(idot, l1, ch, c, wa(iw), wa(ix2))
1725
+ end if
1726
+ na = 1 - na
1727
+ case (4)
1728
+ ix2 = iw + idot
1729
+ ix3 = ix2 + idot
1730
+ if (na == 0) then
1731
+ call complex_backward_pass_4(idot, l1, c, ch, wa(iw), wa(ix2), wa(ix3))
1732
+ else
1733
+ call complex_backward_pass_4(idot, l1, ch, c, wa(iw), wa(ix2), wa(ix3))
1734
+ end if
1735
+ na = 1 - na
1736
+ case (5)
1737
+ ix2 = iw + idot
1738
+ ix3 = ix2 + idot
1739
+ ix4 = ix3 + idot
1740
+ if (na == 0) then
1741
+ call complex_backward_pass_5(idot, l1, c, ch, wa(iw), wa(ix2), &
1742
+ wa(ix3), wa(ix4))
1743
+ else
1744
+ call complex_backward_pass_5(idot, l1, ch, c, wa(iw), wa(ix2), &
1745
+ wa(ix3), wa(ix4))
1746
+ end if
1747
+ na = 1 - na
1748
+ case default
1749
+ if (na == 0) then
1750
+ call complex_backward_pass_n(nac, idot, iip, l1, idl1, c, c, c, ch, &
1751
+ ch, wa(iw))
1752
+ else
1753
+ call complex_backward_pass_n(nac, idot, iip, l1, idl1, ch, ch, ch, &
1754
+ c, c, wa(iw))
1755
+ end if
1756
+ if (nac /= 0) then
1757
+ na = 1 - na
1758
+ end if
1759
+ end select
1760
+ l1 = l2
1761
+ iw = iw + (iip - 1)*idot
1762
+ end do
1763
+
1764
+ if (na /= 0) then
1765
+ n2 = 2*n
1766
+ c(:n2) = ch(:n2)
1767
+ end if
1768
+
1769
+ end subroutine complex_backward_lower_routine
1770
+
1771
+ pure subroutine complex_backward_pass_2(ido, l1, cc, ch, wa1)
1772
+
1773
+ ! Dummy arguments
1774
+
1775
+ integer(ip), intent(in) :: ido
1776
+ integer(ip), intent(in) :: l1
1777
+ real(wp), intent(in) :: cc(ido, 2, l1)
1778
+ real(wp), intent(out) :: ch(ido, l1, 2)
1779
+ real(wp), intent(in) :: wa1(1)
1780
+
1781
+ ! Local variables
1782
+
1783
+ integer(ip) :: k, i
1784
+ real(wp) :: tr2, ti2
1785
+
1786
+
1787
+ if(ido <= 2) then
1788
+ ch(1,:, 1) = cc(1, 1,:) + cc(1, 2,:)
1789
+ ch(1,:, 2) = cc(1, 1,:) - cc(1, 2,:)
1790
+ ch(2,:, 1) = cc(2, 1,:) + cc(2, 2,:)
1791
+ ch(2,:, 2) = cc(2, 1,:) - cc(2, 2,:)
1792
+ else
1793
+ do k = 1, l1
1794
+ do i = 2, ido, 2
1795
+ ch(i-1, k, 1) = cc(i-1, 1, k) + cc(i-1, 2, k)
1796
+ tr2 = cc(i-1, 1, k) - cc(i-1, 2, k)
1797
+ ch(i, k, 1) = cc(i, 1, k) + cc(i, 2, k)
1798
+ ti2 = cc(i, 1, k) - cc(i, 2, k)
1799
+ ch(i, k, 2) = wa1(i-1)*ti2 + wa1(i)*tr2
1800
+ ch(i-1, k, 2) = wa1(i-1)*tr2 - wa1(i)*ti2
1801
+ end do
1802
+ end do
1803
+ end if
1804
+
1805
+ end subroutine complex_backward_pass_2
1806
+
1807
+ pure subroutine complex_backward_pass_3(ido, l1, cc, ch, wa1, wa2)
1808
+
1809
+ ! Dummy arguments
1810
+
1811
+ integer(ip), intent(in) :: ido
1812
+ integer(ip), intent(in) :: l1
1813
+ real(wp), intent(in) :: cc(ido, 3, l1)
1814
+ real(wp), intent(out) :: ch(ido, l1, 3)
1815
+ real(wp), intent(in) :: wa1(*)
1816
+ real(wp), intent(in) :: wa2(*)
1817
+
1818
+ ! Local variables
1819
+
1820
+ integer(ip) :: k, i
1821
+ real(wp), parameter :: taur = -HALF
1822
+ real(wp), parameter :: taui = SQRT_3/2 ! 0.866025403784439
1823
+ real(wp) :: tr2, cr2, ti2, ci2, cr3, ci3, dr2, dr3, di2, di3
1824
+
1825
+
1826
+ select case(ido)
1827
+ case (2)
1828
+ do k = 1, l1
1829
+ tr2 = cc(1, 2, k) + cc(1, 3, k)
1830
+ cr2 = cc(1, 1, k) + taur*tr2
1831
+ ch(1, k, 1) = cc(1, 1, k) + tr2
1832
+ ti2 = cc(2, 2, k) + cc(2, 3, k)
1833
+ ci2 = cc(2, 1, k) + taur*ti2
1834
+ ch(2, k, 1) = cc(2, 1, k) + ti2
1835
+ cr3 = taui*(cc(1, 2, k)-cc(1, 3, k))
1836
+ ci3 = taui*(cc(2, 2, k)-cc(2, 3, k))
1837
+ ch(1, k, 2) = cr2 - ci3
1838
+ ch(1, k, 3) = cr2 + ci3
1839
+ ch(2, k, 2) = ci2 + cr3
1840
+ ch(2, k, 3) = ci2 - cr3
1841
+ end do
1842
+ case default
1843
+ do k = 1, l1
1844
+ do i = 2, ido, 2
1845
+ tr2 = cc(i-1, 2, k) + cc(i-1, 3, k)
1846
+ cr2 = cc(i-1, 1, k) + taur*tr2
1847
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2
1848
+ ti2 = cc(i, 2, k) + cc(i, 3, k)
1849
+ ci2 = cc(i, 1, k) + taur*ti2
1850
+ ch(i, k, 1) = cc(i, 1, k) + ti2
1851
+ cr3 = taui*(cc(i-1, 2, k)-cc(i-1, 3, k))
1852
+ ci3 = taui*(cc(i, 2, k)-cc(i, 3, k))
1853
+ dr2 = cr2 - ci3
1854
+ dr3 = cr2 + ci3
1855
+ di2 = ci2 + cr3
1856
+ di3 = ci2 - cr3
1857
+ ch(i, k, 2) = wa1(i-1)*di2 + wa1(i)*dr2
1858
+ ch(i-1, k, 2) = wa1(i-1)*dr2 - wa1(i)*di2
1859
+ ch(i, k, 3) = wa2(i-1)*di3 + wa2(i)*dr3
1860
+ ch(i-1, k, 3) = wa2(i-1)*dr3 - wa2(i)*di3
1861
+ end do
1862
+ end do
1863
+ end select
1864
+
1865
+ end subroutine complex_backward_pass_3
1866
+
1867
+ pure subroutine complex_backward_pass_4(ido, l1, cc, ch, wa1, wa2, wa3)
1868
+
1869
+ ! Dummy arguments
1870
+
1871
+ integer(ip), intent(in) :: ido
1872
+ integer(ip), intent(in) :: l1
1873
+ real(wp), intent(in) :: cc(ido, 4, l1)
1874
+ real(wp), intent(out) :: ch(ido, l1, 4)
1875
+ real(wp), intent(in) :: wa1(*)
1876
+ real(wp), intent(in) :: wa2(*)
1877
+ real(wp), intent(in) :: wa3(*)
1878
+
1879
+ ! Local variables
1880
+
1881
+ integer(ip) :: k, i
1882
+ real(wp) :: ti1, ti2, tr4, ti3, tr1, tr2, ti4
1883
+ real(wp) :: tr3, cr3, ci3, cr2, cr4, ci2, ci4
1884
+
1885
+
1886
+ select case(ido)
1887
+ case (2)
1888
+ do k = 1, l1
1889
+ ti1 = cc(2, 1, k) - cc(2, 3, k)
1890
+ ti2 = cc(2, 1, k) + cc(2, 3, k)
1891
+ tr4 = cc(2, 4, k) - cc(2, 2, k)
1892
+ ti3 = cc(2, 2, k) + cc(2, 4, k)
1893
+ tr1 = cc(1, 1, k) - cc(1, 3, k)
1894
+ tr2 = cc(1, 1, k) + cc(1, 3, k)
1895
+ ti4 = cc(1, 2, k) - cc(1, 4, k)
1896
+ tr3 = cc(1, 2, k) + cc(1, 4, k)
1897
+ ch(1, k, 1) = tr2 + tr3
1898
+ ch(1, k, 3) = tr2 - tr3
1899
+ ch(2, k, 1) = ti2 + ti3
1900
+ ch(2, k, 3) = ti2 - ti3
1901
+ ch(1, k, 2) = tr1 + tr4
1902
+ ch(1, k, 4) = tr1 - tr4
1903
+ ch(2, k, 2) = ti1 + ti4
1904
+ ch(2, k, 4) = ti1 - ti4
1905
+ end do
1906
+ case default
1907
+ do k = 1, l1
1908
+ do i = 2, ido, 2
1909
+ ti1 = cc(i, 1, k) - cc(i, 3, k)
1910
+ ti2 = cc(i, 1, k) + cc(i, 3, k)
1911
+ ti3 = cc(i, 2, k) + cc(i, 4, k)
1912
+ tr4 = cc(i, 4, k) - cc(i, 2, k)
1913
+ tr1 = cc(i-1, 1, k) - cc(i-1, 3, k)
1914
+ tr2 = cc(i-1, 1, k) + cc(i-1, 3, k)
1915
+ ti4 = cc(i-1, 2, k) - cc(i-1, 4, k)
1916
+ tr3 = cc(i-1, 2, k) + cc(i-1, 4, k)
1917
+ ch(i-1, k, 1) = tr2 + tr3
1918
+ cr3 = tr2 - tr3
1919
+ ch(i, k, 1) = ti2 + ti3
1920
+ ci3 = ti2 - ti3
1921
+ cr2 = tr1 + tr4
1922
+ cr4 = tr1 - tr4
1923
+ ci2 = ti1 + ti4
1924
+ ci4 = ti1 - ti4
1925
+ ch(i-1, k, 2) = wa1(i-1)*cr2 - wa1(i)*ci2
1926
+ ch(i, k, 2) = wa1(i-1)*ci2 + wa1(i)*cr2
1927
+ ch(i-1, k, 3) = wa2(i-1)*cr3 - wa2(i)*ci3
1928
+ ch(i, k, 3) = wa2(i-1)*ci3 + wa2(i)*cr3
1929
+ ch(i-1, k, 4) = wa3(i-1)*cr4 - wa3(i)*ci4
1930
+ ch(i, k, 4) = wa3(i-1)*ci4 + wa3(i)*cr4
1931
+ end do
1932
+ end do
1933
+ end select
1934
+
1935
+ end subroutine complex_backward_pass_4
1936
+
1937
+ pure subroutine complex_backward_pass_5(ido, l1, cc, ch, wa1, wa2, wa3, wa4)
1938
+
1939
+ ! Dummy arguments
1940
+
1941
+ integer(ip), intent(in) :: ido
1942
+ integer(ip), intent(in) :: l1
1943
+ real(wp), intent(in) :: cc(ido, 5, l1)
1944
+ real(wp), intent(out) :: ch(ido, l1, 5)
1945
+ real(wp), intent(in) :: wa1(*)
1946
+ real(wp), intent(in) :: wa2(*)
1947
+ real(wp), intent(in) :: wa3(*)
1948
+ real(wp), intent(in) :: wa4(*)
1949
+
1950
+ ! Local variables
1951
+
1952
+ integer(ip) :: k, i
1953
+ real(wp), parameter :: tr11 = (SQRT_5 - ONE)/4 ! 0.309016994374947
1954
+ real(wp), parameter :: ti11 = (sqrt(ONE/(FIVE + SQRT_5)))/2 ! 0.951056516295154
1955
+ real(wp), parameter :: tr12 = (-ONE - SQRT_5)/4 ! -.809016994374947
1956
+ real(wp), parameter :: ti12 = sqrt( FIVE/(TWO*(FIVE + SQRT_5 ))) ! 0.587785252292473
1957
+ real(wp) :: ti5, ti2, ti4, ti3, tr5, tr2, tr4
1958
+ real(wp) :: tr3, cr2, ci2, cr3, ci3, cr5, ci5, cr4, ci4, dr3, dr4, di3
1959
+ real(wp) :: di4, dr5, dr2, di5, di2
1960
+
1961
+
1962
+ select case(ido)
1963
+ case (2)
1964
+ do k = 1, l1
1965
+ ti5 = cc(2, 2, k) - cc(2, 5, k)
1966
+ ti2 = cc(2, 2, k) + cc(2, 5, k)
1967
+ ti4 = cc(2, 3, k) - cc(2, 4, k)
1968
+ ti3 = cc(2, 3, k) + cc(2, 4, k)
1969
+ tr5 = cc(1, 2, k) - cc(1, 5, k)
1970
+ tr2 = cc(1, 2, k) + cc(1, 5, k)
1971
+ tr4 = cc(1, 3, k) - cc(1, 4, k)
1972
+ tr3 = cc(1, 3, k) + cc(1, 4, k)
1973
+ ch(1, k, 1) = cc(1, 1, k) + tr2 + tr3
1974
+ ch(2, k, 1) = cc(2, 1, k) + ti2 + ti3
1975
+ cr2 = cc(1, 1, k) + tr11*tr2 + tr12*tr3
1976
+ ci2 = cc(2, 1, k) + tr11*ti2 + tr12*ti3
1977
+ cr3 = cc(1, 1, k) + tr12*tr2 + tr11*tr3
1978
+ ci3 = cc(2, 1, k) + tr12*ti2 + tr11*ti3
1979
+ cr5 = ti11*tr5 + ti12*tr4
1980
+ ci5 = ti11*ti5 + ti12*ti4
1981
+ cr4 = ti12*tr5 - ti11*tr4
1982
+ ci4 = ti12*ti5 - ti11*ti4
1983
+ ch(1, k, 2) = cr2 - ci5
1984
+ ch(1, k, 5) = cr2 + ci5
1985
+ ch(2, k, 2) = ci2 + cr5
1986
+ ch(2, k, 3) = ci3 + cr4
1987
+ ch(1, k, 3) = cr3 - ci4
1988
+ ch(1, k, 4) = cr3 + ci4
1989
+ ch(2, k, 4) = ci3 - cr4
1990
+ ch(2, k, 5) = ci2 - cr5
1991
+ end do
1992
+ case default
1993
+ do k = 1, l1
1994
+ do i = 2, ido, 2
1995
+ ti5 = cc(i, 2, k) - cc(i, 5, k)
1996
+ ti2 = cc(i, 2, k) + cc(i, 5, k)
1997
+ ti4 = cc(i, 3, k) - cc(i, 4, k)
1998
+ ti3 = cc(i, 3, k) + cc(i, 4, k)
1999
+ tr5 = cc(i-1, 2, k) - cc(i-1, 5, k)
2000
+ tr2 = cc(i-1, 2, k) + cc(i-1, 5, k)
2001
+ tr4 = cc(i-1, 3, k) - cc(i-1, 4, k)
2002
+ tr3 = cc(i-1, 3, k) + cc(i-1, 4, k)
2003
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2 + tr3
2004
+ ch(i, k, 1) = cc(i, 1, k) + ti2 + ti3
2005
+ cr2 = cc(i-1, 1, k) + tr11*tr2 + tr12*tr3
2006
+ ci2 = cc(i, 1, k) + tr11*ti2 + tr12*ti3
2007
+ cr3 = cc(i-1, 1, k) + tr12*tr2 + tr11*tr3
2008
+ ci3 = cc(i, 1, k) + tr12*ti2 + tr11*ti3
2009
+ cr5 = ti11*tr5 + ti12*tr4
2010
+ ci5 = ti11*ti5 + ti12*ti4
2011
+ cr4 = ti12*tr5 - ti11*tr4
2012
+ ci4 = ti12*ti5 - ti11*ti4
2013
+ dr3 = cr3 - ci4
2014
+ dr4 = cr3 + ci4
2015
+ di3 = ci3 + cr4
2016
+ di4 = ci3 - cr4
2017
+ dr5 = cr2 + ci5
2018
+ dr2 = cr2 - ci5
2019
+ di5 = ci2 - cr5
2020
+ di2 = ci2 + cr5
2021
+ ch(i-1, k, 2) = wa1(i-1)*dr2 - wa1(i)*di2
2022
+ ch(i, k, 2) = wa1(i-1)*di2 + wa1(i)*dr2
2023
+ ch(i-1, k, 3) = wa2(i-1)*dr3 - wa2(i)*di3
2024
+ ch(i, k, 3) = wa2(i-1)*di3 + wa2(i)*dr3
2025
+ ch(i-1, k, 4) = wa3(i-1)*dr4 - wa3(i)*di4
2026
+ ch(i, k, 4) = wa3(i-1)*di4 + wa3(i)*dr4
2027
+ ch(i-1, k, 5) = wa4(i-1)*dr5 - wa4(i)*di5
2028
+ ch(i, k, 5) = wa4(i-1)*di5 + wa4(i)*dr5
2029
+ end do
2030
+ end do
2031
+ end select
2032
+
2033
+ end subroutine complex_backward_pass_5
2034
+
2035
+ subroutine complex_backward_pass_n(nac, ido, iip, l1, idl1, cc, c1, c2, ch, ch2, wa)
2036
+
2037
+ ! Dummy arguments
2038
+
2039
+ integer(ip), intent(out) :: nac
2040
+ integer(ip), intent(in) :: ido
2041
+ integer(ip), intent(in) :: iip
2042
+ integer(ip), intent(in) :: l1
2043
+ integer(ip), intent(in) :: idl1
2044
+ real(wp), intent(in) :: cc(ido, iip, l1)
2045
+ real(wp), intent(out) :: c1(ido, l1, iip)
2046
+ real(wp), intent(inout) :: c2(idl1, iip)
2047
+ real(wp), intent(inout) :: ch(ido, l1, iip)
2048
+ real(wp), intent(inout) :: ch2(idl1, iip)
2049
+ real(wp), intent(in) :: wa(*)
2050
+
2051
+ ! Local variables
2052
+
2053
+ integer(ip) :: idot, nt, iipp2, iipph, idp, j, jc, k
2054
+ integer(ip) :: i, idl, inc, l, lc, idlj, idij, idj
2055
+ real(wp) :: war, wai
2056
+
2057
+
2058
+ idot = ido/2
2059
+ nt = iip*idl1
2060
+ iipp2 = iip + 2
2061
+ iipph = (iip + 1)/2
2062
+ idp = iip*ido
2063
+
2064
+ if (l1 <= ido) then
2065
+ do j = 2, iipph
2066
+ jc = iipp2 - j
2067
+ ch(:,:, j) = cc(:, j,:) + cc(:, jc,:)
2068
+ ch(:,:, jc) = cc(:, j,:) - cc(:, jc,:)
2069
+ end do
2070
+ ch(:,:, 1) = cc(:, 1,:)
2071
+ else
2072
+ do j = 2, iipph
2073
+ jc = iipp2 - j
2074
+ ch(:,:, j) = cc(:, j,:) + cc(:, jc,:)
2075
+ ch(:,:, jc) = cc(:, j,:) - cc(:, jc,:)
2076
+ end do
2077
+ ch(:,:, 1) = cc(:, 1,:)
2078
+ end if
2079
+
2080
+ idl = 2 - ido
2081
+ inc = 0
2082
+
2083
+ do l = 2, iipph
2084
+ lc = iipp2 - l
2085
+ idl = idl + ido
2086
+ c2(:, l) = ch2(:, 1) + wa(idl-1)*ch2(:, 2)
2087
+ c2(:, lc) = wa(idl)*ch2(:, iip)
2088
+ idlj = idl
2089
+ inc = inc + ido
2090
+ do j = 3, iipph
2091
+ jc = iipp2 - j
2092
+ idlj = idlj + inc
2093
+ if (idlj > idp) idlj = idlj - idp
2094
+ war = wa(idlj-1)
2095
+ wai = wa(idlj)
2096
+ c2(:, l) = c2(:, l) + war*ch2(:, j)
2097
+ c2(:, lc) = c2(:, lc) + wai*ch2(:, jc)
2098
+ end do
2099
+ end do
2100
+
2101
+ do j = 2, iipph
2102
+ ch2(:, 1) = ch2(:, 1) + ch2(:, j)
2103
+ end do
2104
+
2105
+ do j = 2, iipph
2106
+ jc = iipp2 - j
2107
+ ch2(:idl1-1:2, j) = c2(:idl1-1:2, j) - c2(2:idl1:2, jc)
2108
+ ch2(:idl1-1:2, jc) = c2(:idl1-1:2, j) + c2(2:idl1:2, jc)
2109
+ ch2(2:idl1:2, j) = c2(2:idl1:2, j) + c2(:idl1-1:2, jc)
2110
+ ch2(2:idl1:2, jc) = c2(2:idl1:2, j) - c2(:idl1-1:2, jc)
2111
+ end do
2112
+
2113
+ nac = 1
2114
+
2115
+ if(ido /= 2) then
2116
+ nac = 0
2117
+ c2(:, 1) = ch2(:, 1)
2118
+ c1(1,:, 2:iip) = ch(1,:, 2:iip)
2119
+ c1(2,:, 2:iip) = ch(2,:, 2:iip)
2120
+
2121
+ if(idot <= l1) then
2122
+ idij = 0
2123
+ do j = 2, iip
2124
+ idij = idij + 2
2125
+ do i = 4, ido, 2
2126
+ idij = idij + 2
2127
+ c1(i-1,:, j) = wa(idij-1)*ch(i-1,:, j) - wa(idij)*ch(i,:, j)
2128
+ c1(i,:, j) = wa(idij-1)*ch(i,:, j) + wa(idij)*ch(i-1,:, j)
2129
+ end do
2130
+ end do
2131
+ else
2132
+ idj = 2 - ido
2133
+ do j = 2, iip
2134
+ idj = idj + ido
2135
+ do k = 1, l1
2136
+ idij = idj
2137
+ c1(3:ido-1:2, k, j) = wa(idij+1:ido-3+idij:2)*ch(3:ido-1:2, k, j &
2138
+ ) - wa(idij+2:ido-2+idij:2)*ch(4:ido:2, k, j)
2139
+ c1(4:ido:2, k, j) = wa(idij+1:ido-3+idij:2)*ch(4:ido:2, k, j) + &
2140
+ wa(idij+2:ido-2+idij:2)*ch(3:ido-1:2, k, j)
2141
+ end do
2142
+ end do
2143
+ end if
2144
+ end if
2145
+
2146
+ end subroutine complex_backward_pass_n
2147
+
2148
+ subroutine cfftf(n, c, wsave)
2149
+
2150
+ ! Dummy arguments
2151
+
2152
+ integer(ip), intent(in) :: n
2153
+ real(wp), intent(inout) :: c(*)
2154
+ real(wp), intent(inout) :: wsave(*)
2155
+
2156
+ ! Local variables
2157
+
2158
+ integer(ip) :: iw1, iw2
2159
+
2160
+
2161
+ if (n /= 1) then
2162
+ iw1 = 2*n + 1
2163
+ iw2 = iw1 + 2*n
2164
+ call complex_forward_lower_routine(n, c, wsave, wsave(iw1), wsave(iw2))
2165
+ end if
2166
+
2167
+ end subroutine cfftf
2168
+
2169
+ subroutine complex_forward_lower_routine(n, c, ch, wa, ifac)
2170
+
2171
+ ! Dummy arguments
2172
+
2173
+ integer(ip), intent(in) :: n
2174
+ real(wp), intent(inout) :: c(*)
2175
+ real(wp), intent(inout) :: ch(*)
2176
+ real(wp), intent(in) :: wa(*)
2177
+ real(wp), intent(in) :: ifac(*)
2178
+
2179
+ ! Local variables
2180
+
2181
+ integer(ip) :: nf, na, l1, iw, k1, iip, l2, ido
2182
+ integer(ip) :: idot, idl1, ix2, ix3, ix4, nac, n2
2183
+
2184
+
2185
+ nf = int(ifac(2), kind=ip)
2186
+ na = 0
2187
+ l1 = 1
2188
+ iw = 1
2189
+
2190
+ do k1 = 1, nf
2191
+ iip = int(ifac(k1+2), kind=ip)
2192
+ l2 = iip*l1
2193
+ ido = n/l2
2194
+ idot = ido + ido
2195
+ idl1 = idot*l1
2196
+
2197
+ select case (iip)
2198
+ case (2)
2199
+ if (na == 0) then
2200
+ call complex_forward_pass_2(idot, l1, c, ch, wa(iw))
2201
+ else
2202
+ call complex_forward_pass_2(idot, l1, ch, c, wa(iw))
2203
+ end if
2204
+ na = 1 - na
2205
+ case (3)
2206
+ ix2 = iw + idot
2207
+ if (na == 0) then
2208
+ call complex_forward_pass_3(idot, l1, c, ch, wa(iw), wa(ix2))
2209
+ else
2210
+ call complex_forward_pass_3(idot, l1, ch, c, wa(iw), wa(ix2))
2211
+ end if
2212
+ na = 1 - na
2213
+ case (4)
2214
+ ix3 = ix2 + idot
2215
+ if (na == 0) then
2216
+ call complex_forward_pass_4(idot, l1, c, ch, wa(iw), wa(ix2), wa(ix3))
2217
+ else
2218
+ call complex_forward_pass_4(idot, l1, ch, c, wa(iw), wa(ix2), wa(ix3))
2219
+ end if
2220
+ na = 1 - na
2221
+ case (5)
2222
+ ix2 = iw + idot
2223
+ ix3 = ix2 + idot
2224
+ ix4 = ix3 + idot
2225
+ if (na == 0) then
2226
+ call complex_forward_pass_5(idot, l1, c, ch, wa(iw), wa(ix2), wa(ix3), wa(ix4))
2227
+ else
2228
+ call complex_forward_pass_5(idot, l1, ch, c, wa(iw), wa(ix2), wa(ix3), wa(ix4))
2229
+ end if
2230
+ na = 1 - na
2231
+ case default
2232
+ if (na == 0) then
2233
+ call complex_forward_pass_n(nac, idot, iip, l1, idl1, c, c, c, ch, ch, wa(iw))
2234
+ else
2235
+ call complex_forward_pass_n(nac, idot, iip, l1, idl1, ch, ch, ch, c, c, wa(iw))
2236
+ end if
2237
+ if (nac /= 0) na = 1 - na
2238
+ end select
2239
+ l1 = l2
2240
+ iw = iw + (iip - 1)*idot
2241
+ end do
2242
+
2243
+ if (na /= 0) then
2244
+ n2 = n + n
2245
+ c(:n2) = ch(:n2)
2246
+ end if
2247
+
2248
+ end subroutine complex_forward_lower_routine
2249
+
2250
+
2251
+ pure subroutine complex_forward_pass_2(ido, l1, cc, ch, wa1)
2252
+
2253
+ ! Dummy arguments
2254
+
2255
+ integer(ip), intent(in) :: ido
2256
+ integer(ip), intent(in) :: l1
2257
+ real(wp), intent(in) :: cc(ido, 2, l1)
2258
+ real(wp), intent(out) :: ch(ido, l1, 2)
2259
+ real(wp), intent(in) :: wa1(*)
2260
+
2261
+ ! Local variables
2262
+
2263
+ integer(ip) :: k, i
2264
+ real(wp) :: tr2, ti2
2265
+
2266
+
2267
+ if(ido <= 2) then
2268
+ ch(1,:, 1) = cc(1, 1,:) + cc(1, 2,:)
2269
+ ch(1,:, 2) = cc(1, 1,:) - cc(1, 2,:)
2270
+ ch(2,:, 1) = cc(2, 1,:) + cc(2, 2,:)
2271
+ ch(2,:, 2) = cc(2, 1,:) - cc(2, 2,:)
2272
+ else
2273
+ do k = 1, l1
2274
+ do i = 2, ido, 2
2275
+ ch(i-1, k, 1) = cc(i-1, 1, k) + cc(i-1, 2, k)
2276
+ tr2 = cc(i-1, 1, k) - cc(i-1, 2, k)
2277
+ ch(i, k, 1) = cc(i, 1, k) + cc(i, 2, k)
2278
+ ti2 = cc(i, 1, k) - cc(i, 2, k)
2279
+ ch(i, k, 2) = wa1(i-1)*ti2 - wa1(i)*tr2
2280
+ ch(i-1, k, 2) = wa1(i-1)*tr2 + wa1(i)*ti2
2281
+ end do
2282
+ end do
2283
+ end if
2284
+
2285
+ end subroutine complex_forward_pass_2
2286
+
2287
+
2288
+ pure subroutine complex_forward_pass_3(ido, l1, cc, ch, wa1, wa2)
2289
+
2290
+ ! Dummy arguments
2291
+
2292
+ integer(ip), intent(in) :: ido
2293
+ integer(ip), intent(in) :: l1
2294
+ real(wp), intent(in) :: cc(ido, 3, l1)
2295
+ real(wp), intent(out) :: ch(ido, l1, 3)
2296
+ real(wp), intent(in) :: wa1(*)
2297
+ real(wp), intent(in) :: wa2(*)
2298
+
2299
+ ! Local variables
2300
+
2301
+ integer(ip) :: k, i
2302
+ real(wp), parameter :: taur = -HALF
2303
+ real(wp), parameter :: taui = -sqrt(THREE)/2 ! - 0.866025403784439
2304
+ real(wp) :: tr2, cr2, ti2, ci2, cr3, ci3, dr2, dr3, di2, di3
2305
+
2306
+
2307
+ select case(ido)
2308
+ case (2)
2309
+ do k = 1, l1
2310
+ tr2 = cc(1, 2, k) + cc(1, 3, k)
2311
+ cr2 = cc(1, 1, k) + taur*tr2
2312
+ ch(1, k, 1) = cc(1, 1, k) + tr2
2313
+ ti2 = cc(2, 2, k) + cc(2, 3, k)
2314
+ ci2 = cc(2, 1, k) + taur*ti2
2315
+ ch(2, k, 1) = cc(2, 1, k) + ti2
2316
+ cr3 = taui*(cc(1, 2, k)-cc(1, 3, k))
2317
+ ci3 = taui*(cc(2, 2, k)-cc(2, 3, k))
2318
+ ch(1, k, 2) = cr2 - ci3
2319
+ ch(1, k, 3) = cr2 + ci3
2320
+ ch(2, k, 2) = ci2 + cr3
2321
+ ch(2, k, 3) = ci2 - cr3
2322
+ end do
2323
+ case default
2324
+ do k = 1, l1
2325
+ do i = 2, ido, 2
2326
+ tr2 = cc(i-1, 2, k) + cc(i-1, 3, k)
2327
+ cr2 = cc(i-1, 1, k) + taur*tr2
2328
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2
2329
+ ti2 = cc(i, 2, k) + cc(i, 3, k)
2330
+ ci2 = cc(i, 1, k) + taur*ti2
2331
+ ch(i, k, 1) = cc(i, 1, k) + ti2
2332
+ cr3 = taui*(cc(i-1, 2, k)-cc(i-1, 3, k))
2333
+ ci3 = taui*(cc(i, 2, k)-cc(i, 3, k))
2334
+ dr2 = cr2 - ci3
2335
+ dr3 = cr2 + ci3
2336
+ di2 = ci2 + cr3
2337
+ di3 = ci2 - cr3
2338
+ ch(i, k, 2) = wa1(i-1)*di2 - wa1(i)*dr2
2339
+ ch(i-1, k, 2) = wa1(i-1)*dr2 + wa1(i)*di2
2340
+ ch(i, k, 3) = wa2(i-1)*di3 - wa2(i)*dr3
2341
+ ch(i-1, k, 3) = wa2(i-1)*dr3 + wa2(i)*di3
2342
+ end do
2343
+ end do
2344
+ end select
2345
+
2346
+ end subroutine complex_forward_pass_3
2347
+
2348
+ pure subroutine complex_forward_pass_4(ido, l1, cc, ch, wa1, wa2, wa3)
2349
+
2350
+ ! Dummy arguments
2351
+
2352
+ integer(ip), intent(in) :: ido
2353
+ integer(ip), intent(in) :: l1
2354
+ real(wp), intent(in) :: cc(ido, 4, l1)
2355
+ real(wp), intent(out) :: ch(ido, l1, 4)
2356
+ real(wp), intent(in) :: wa1(*)
2357
+ real(wp), intent(in) :: wa2(*)
2358
+ real(wp), intent(in) :: wa3(*)
2359
+
2360
+ ! Local variables
2361
+
2362
+ integer(ip) :: k, i
2363
+ real(wp) :: ti1, ti2, tr4, ti3, tr1, tr2, ti4
2364
+ real(wp) :: tr3, cr3, ci3, cr2, cr4, ci2, ci4
2365
+
2366
+
2367
+ select case(ido)
2368
+ case (2)
2369
+ do k = 1, l1
2370
+ ti1 = cc(2, 1, k) - cc(2, 3, k)
2371
+ ti2 = cc(2, 1, k) + cc(2, 3, k)
2372
+ tr4 = cc(2, 2, k) - cc(2, 4, k)
2373
+ ti3 = cc(2, 2, k) + cc(2, 4, k)
2374
+ tr1 = cc(1, 1, k) - cc(1, 3, k)
2375
+ tr2 = cc(1, 1, k) + cc(1, 3, k)
2376
+ ti4 = cc(1, 4, k) - cc(1, 2, k)
2377
+ tr3 = cc(1, 2, k) + cc(1, 4, k)
2378
+ ch(1, k, 1) = tr2 + tr3
2379
+ ch(1, k, 3) = tr2 - tr3
2380
+ ch(2, k, 1) = ti2 + ti3
2381
+ ch(2, k, 3) = ti2 - ti3
2382
+ ch(1, k, 2) = tr1 + tr4
2383
+ ch(1, k, 4) = tr1 - tr4
2384
+ ch(2, k, 2) = ti1 + ti4
2385
+ ch(2, k, 4) = ti1 - ti4
2386
+ end do
2387
+ case default
2388
+ do k = 1, l1
2389
+ do i = 2, ido, 2
2390
+ ti1 = cc(i, 1, k) - cc(i, 3, k)
2391
+ ti2 = cc(i, 1, k) + cc(i, 3, k)
2392
+ ti3 = cc(i, 2, k) + cc(i, 4, k)
2393
+ tr4 = cc(i, 2, k) - cc(i, 4, k)
2394
+ tr1 = cc(i-1, 1, k) - cc(i-1, 3, k)
2395
+ tr2 = cc(i-1, 1, k) + cc(i-1, 3, k)
2396
+ ti4 = cc(i-1, 4, k) - cc(i-1, 2, k)
2397
+ tr3 = cc(i-1, 2, k) + cc(i-1, 4, k)
2398
+ ch(i-1, k, 1) = tr2 + tr3
2399
+ cr3 = tr2 - tr3
2400
+ ch(i, k, 1) = ti2 + ti3
2401
+ ci3 = ti2 - ti3
2402
+ cr2 = tr1 + tr4
2403
+ cr4 = tr1 - tr4
2404
+ ci2 = ti1 + ti4
2405
+ ci4 = ti1 - ti4
2406
+ ch(i-1, k, 2) = wa1(i-1)*cr2 + wa1(i)*ci2
2407
+ ch(i, k, 2) = wa1(i-1)*ci2 - wa1(i)*cr2
2408
+ ch(i-1, k, 3) = wa2(i-1)*cr3 + wa2(i)*ci3
2409
+ ch(i, k, 3) = wa2(i-1)*ci3 - wa2(i)*cr3
2410
+ ch(i-1, k, 4) = wa3(i-1)*cr4 + wa3(i)*ci4
2411
+ ch(i, k, 4) = wa3(i-1)*ci4 - wa3(i)*cr4
2412
+ end do
2413
+ end do
2414
+ end select
2415
+
2416
+ end subroutine complex_forward_pass_4
2417
+
2418
+ pure subroutine complex_forward_pass_5(ido, l1, cc, ch, wa1, wa2, wa3, wa4)
2419
+
2420
+ ! Dummy arguments
2421
+
2422
+ integer(ip), intent(in) :: ido
2423
+ integer(ip), intent(in) :: l1
2424
+ real(wp), intent(in) :: cc(ido, 5, l1)
2425
+ real(wp), intent(out) :: ch(ido, l1, 5)
2426
+ real(wp), intent(in) :: wa1(*)
2427
+ real(wp), intent(in) :: wa2(*)
2428
+ real(wp), intent(in) :: wa3(*)
2429
+ real(wp), intent(in) :: wa4(*)
2430
+
2431
+ ! Local variables
2432
+
2433
+ integer(ip) :: k, i
2434
+ real(wp) :: ti5, ti2, ti4, ti3, tr5, tr2, tr4
2435
+ real(wp) :: tr3, cr2, ci2, cr3, ci3, cr5, ci5, cr4, ci4, dr3, dr4, di3
2436
+ real(wp) :: di4, dr5, dr2, di5, di2
2437
+ real(wp), parameter :: tr11 = (SQRT_5 - ONE)/4 ! 0.309016994374947
2438
+ real(wp), parameter :: ti11 = -sqrt((FIVE + SQRT_5)/2)/2 ! -.951056516295154
2439
+ real(wp), parameter :: tr12 = (-ONE - SQRT_5)/4 ! -.809016994374947
2440
+ real(wp), parameter :: ti12 = -sqrt(FIVE/(TWO * (FIVE + SQRT_5)) ) ! -0.587785252292473
2441
+
2442
+
2443
+ select case(ido)
2444
+ case (2)
2445
+ do k = 1, l1
2446
+ ti5 = cc(2, 2, k) - cc(2, 5, k)
2447
+ ti2 = cc(2, 2, k) + cc(2, 5, k)
2448
+ ti4 = cc(2, 3, k) - cc(2, 4, k)
2449
+ ti3 = cc(2, 3, k) + cc(2, 4, k)
2450
+ tr5 = cc(1, 2, k) - cc(1, 5, k)
2451
+ tr2 = cc(1, 2, k) + cc(1, 5, k)
2452
+ tr4 = cc(1, 3, k) - cc(1, 4, k)
2453
+ tr3 = cc(1, 3, k) + cc(1, 4, k)
2454
+ ch(1, k, 1) = cc(1, 1, k) + tr2 + tr3
2455
+ ch(2, k, 1) = cc(2, 1, k) + ti2 + ti3
2456
+ cr2 = cc(1, 1, k) + tr11*tr2 + tr12*tr3
2457
+ ci2 = cc(2, 1, k) + tr11*ti2 + tr12*ti3
2458
+ cr3 = cc(1, 1, k) + tr12*tr2 + tr11*tr3
2459
+ ci3 = cc(2, 1, k) + tr12*ti2 + tr11*ti3
2460
+ cr5 = ti11*tr5 + ti12*tr4
2461
+ ci5 = ti11*ti5 + ti12*ti4
2462
+ cr4 = ti12*tr5 - ti11*tr4
2463
+ ci4 = ti12*ti5 - ti11*ti4
2464
+ ch(1, k, 2) = cr2 - ci5
2465
+ ch(1, k, 5) = cr2 + ci5
2466
+ ch(2, k, 2) = ci2 + cr5
2467
+ ch(2, k, 3) = ci3 + cr4
2468
+ ch(1, k, 3) = cr3 - ci4
2469
+ ch(1, k, 4) = cr3 + ci4
2470
+ ch(2, k, 4) = ci3 - cr4
2471
+ ch(2, k, 5) = ci2 - cr5
2472
+ end do
2473
+ case default
2474
+ do k = 1, l1
2475
+ do i = 2, ido, 2
2476
+ ti5 = cc(i, 2, k) - cc(i, 5, k)
2477
+ ti2 = cc(i, 2, k) + cc(i, 5, k)
2478
+ ti4 = cc(i, 3, k) - cc(i, 4, k)
2479
+ ti3 = cc(i, 3, k) + cc(i, 4, k)
2480
+ tr5 = cc(i-1, 2, k) - cc(i-1, 5, k)
2481
+ tr2 = cc(i-1, 2, k) + cc(i-1, 5, k)
2482
+ tr4 = cc(i-1, 3, k) - cc(i-1, 4, k)
2483
+ tr3 = cc(i-1, 3, k) + cc(i-1, 4, k)
2484
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2 + tr3
2485
+ ch(i, k, 1) = cc(i, 1, k) + ti2 + ti3
2486
+ cr2 = cc(i-1, 1, k) + tr11*tr2 + tr12*tr3
2487
+ ci2 = cc(i, 1, k) + tr11*ti2 + tr12*ti3
2488
+ cr3 = cc(i-1, 1, k) + tr12*tr2 + tr11*tr3
2489
+ ci3 = cc(i, 1, k) + tr12*ti2 + tr11*ti3
2490
+ cr5 = ti11*tr5 + ti12*tr4
2491
+ ci5 = ti11*ti5 + ti12*ti4
2492
+ cr4 = ti12*tr5 - ti11*tr4
2493
+ ci4 = ti12*ti5 - ti11*ti4
2494
+ dr3 = cr3 - ci4
2495
+ dr4 = cr3 + ci4
2496
+ di3 = ci3 + cr4
2497
+ di4 = ci3 - cr4
2498
+ dr5 = cr2 + ci5
2499
+ dr2 = cr2 - ci5
2500
+ di5 = ci2 - cr5
2501
+ di2 = ci2 + cr5
2502
+ ch(i-1, k, 2) = wa1(i-1)*dr2 + wa1(i)*di2
2503
+ ch(i, k, 2) = wa1(i-1)*di2 - wa1(i)*dr2
2504
+ ch(i-1, k, 3) = wa2(i-1)*dr3 + wa2(i)*di3
2505
+ ch(i, k, 3) = wa2(i-1)*di3 - wa2(i)*dr3
2506
+ ch(i-1, k, 4) = wa3(i-1)*dr4 + wa3(i)*di4
2507
+ ch(i, k, 4) = wa3(i-1)*di4 - wa3(i)*dr4
2508
+ ch(i-1, k, 5) = wa4(i-1)*dr5 + wa4(i)*di5
2509
+ ch(i, k, 5) = wa4(i-1)*di5 - wa4(i)*dr5
2510
+ end do
2511
+ end do
2512
+ end select
2513
+
2514
+ end subroutine complex_forward_pass_5
2515
+
2516
+ subroutine complex_forward_pass_n(nac, ido, iip, l1, idl1, cc, c1, c2, ch, ch2, wa)
2517
+
2518
+ ! Dummy arguments
2519
+
2520
+ integer(ip), intent(out) :: nac
2521
+ integer(ip), intent(in) :: ido
2522
+ integer(ip), intent(in) :: iip
2523
+ integer(ip), intent(in) :: l1
2524
+ integer(ip), intent(in) :: idl1
2525
+ real(wp), intent(inout) :: cc(ido, iip, l1)
2526
+ real(wp), intent(inout) :: c1(ido, l1, iip)
2527
+ real(wp), intent(inout) :: c2(idl1, iip)
2528
+ real(wp), intent(inout) :: ch(ido, l1, iip)
2529
+ real(wp), intent(inout) :: ch2(idl1, iip)
2530
+ real(wp), intent(in) :: wa(*)
2531
+
2532
+ ! Local variables
2533
+
2534
+ integer(ip) :: idot, nt, iipp2, iipph, idp, j, jc
2535
+ integer(ip) :: k, i, idl, inc, l, lc
2536
+ integer(ip) :: idlj, idij, idj
2537
+ real(wp) :: war, wai
2538
+
2539
+
2540
+ idot = ido/2
2541
+ nt = iip*idl1
2542
+ iipp2 = iip + 2
2543
+ iipph = (iip + 1)/2
2544
+ idp = iip*ido
2545
+
2546
+ if (l1 <= ido) then
2547
+ do j = 2, iipph
2548
+ jc = iipp2 - j
2549
+ ch(:,:, j) = cc(:, j,:) + cc(:, jc,:)
2550
+ ch(:,:, jc) = cc(:, j,:) - cc(:, jc,:)
2551
+ end do
2552
+ ch(:,:, 1) = cc(:, 1,:)
2553
+ else
2554
+ do j = 2, iipph
2555
+ jc = iipp2 - j
2556
+ ch(:,:, j) = cc(:, j,:) + cc(:, jc,:)
2557
+ ch(:,:, jc) = cc(:, j,:) - cc(:, jc,:)
2558
+ end do
2559
+ ch(:,:, 1) = cc(:, 1,:)
2560
+ end if
2561
+
2562
+ idl = 2 - ido
2563
+ inc = 0
2564
+
2565
+ do l = 2, iipph
2566
+ lc = iipp2 - l
2567
+ idl = idl + ido
2568
+ c2(:, l) = ch2(:, 1) + wa(idl-1)*ch2(:, 2)
2569
+ c2(:, lc) = -wa(idl)*ch2(:, iip)
2570
+ idlj = idl
2571
+ inc = inc + ido
2572
+ do j = 3, iipph
2573
+ jc = iipp2 - j
2574
+ idlj = idlj + inc
2575
+ if (idlj > idp) then
2576
+ idlj = idlj - idp
2577
+ end if
2578
+ war = wa(idlj-1)
2579
+ wai = wa(idlj)
2580
+ c2(:, l) = c2(:, l) + war*ch2(:, j)
2581
+ c2(:, lc) = c2(:, lc) - wai*ch2(:, jc)
2582
+ end do
2583
+ end do
2584
+
2585
+ do j = 2, iipph
2586
+ ch2(:, 1) = ch2(:, 1) + ch2(:, j)
2587
+ end do
2588
+
2589
+ do j = 2, iipph
2590
+ jc = iipp2 - j
2591
+ ch2(:idl1-1:2, j) = c2(:idl1-1:2, j) - c2(2:idl1:2, jc)
2592
+ ch2(:idl1-1:2, jc) = c2(:idl1-1:2, j) + c2(2:idl1:2, jc)
2593
+ ch2(2:idl1:2, j) = c2(2:idl1:2, j) + c2(:idl1-1:2, jc)
2594
+ ch2(2:idl1:2, jc) = c2(2:idl1:2, j) - c2(:idl1-1:2, jc)
2595
+ end do
2596
+
2597
+ nac = 1
2598
+
2599
+ if (ido /= 2) then
2600
+
2601
+ nac = 0
2602
+ c2(:, 1) = ch2(:, 1)
2603
+ c1(1,:, 2:iip) = ch(1,:, 2:iip)
2604
+ c1(2,:, 2:iip) = ch(2,:, 2:iip)
2605
+
2606
+ if (idot <= l1) then
2607
+ idij = 0
2608
+ do j = 2, iip
2609
+ idij = idij + 2
2610
+ do i = 4, ido, 2
2611
+ idij = idij + 2
2612
+ c1(i-1,:, j) = wa(idij-1)*ch(i-1,:, j) + wa(idij)*ch(i,:, j)
2613
+ c1(i,:, j) = wa(idij-1)*ch(i,:, j) - wa(idij)*ch(i-1,:, j)
2614
+ end do
2615
+ end do
2616
+ else
2617
+ idj = 2 - ido
2618
+ do j = 2, iip
2619
+ idj = idj + ido
2620
+ do k = 1, l1
2621
+ idij = idj
2622
+ c1(3:ido-1:2, k, j) = wa(idij+1:ido-3+idij:2)*ch(3:ido-1:2, k, j &
2623
+ ) + wa(idij+2:ido-2+idij:2)*ch(4:ido:2, k, j)
2624
+ c1(4:ido:2, k, j) = wa(idij+1:ido-3+idij:2)*ch(4:ido:2, k, j) - &
2625
+ wa(idij+2:ido-2+idij:2)*ch(3:ido-1:2, k, j)
2626
+ end do
2627
+ end do
2628
+ end if
2629
+ end if
2630
+
2631
+ end subroutine complex_forward_pass_n
2632
+
2633
+ ! subroutine rffti(n, wsave)
2634
+ !
2635
+ ! Purpose:
2636
+ !
2637
+ ! Initializes the array wsave which is used in
2638
+ ! both rfftf and rfftb. the prime factorization of n together with
2639
+ ! a tabulation of the trigonometric functions are computed and
2640
+ ! stored in wsave.
2641
+ !
2642
+ ! input parameter
2643
+ !
2644
+ ! n the length of the sequence to be transformed.
2645
+ !
2646
+ ! output parameter
2647
+ !
2648
+ ! wsave a work array which must be dimensioned at least 2*n+15.
2649
+ ! the same work array can be used for both rfftf and rfftb
2650
+ ! as long as n remains unchanged. different wsave arrays
2651
+ ! are required for different values of n. the contents of
2652
+ ! wsave must not be changed between calls of rfftf or rfftb.
2653
+ !
2654
+ pure subroutine rffti(n, wsave)
2655
+
2656
+ ! Dummy arguments
2657
+ integer(ip), intent(in) :: n
2658
+ real(wp), intent(out) :: wsave(*)
2659
+
2660
+ if (n /= 1) then
2661
+ call real_initialization_lower_routine(n, wsave(n+1), wsave(2*n+1))
2662
+ end if
2663
+
2664
+ end subroutine rffti
2665
+
2666
+ pure subroutine real_initialization_lower_routine(n, wa, ifac)
2667
+
2668
+ ! Dummy arguments
2669
+ integer(ip), intent(in) :: n
2670
+ real(wp), intent(out) :: ifac(*)
2671
+ real(wp), intent(out) :: wa(*)
2672
+
2673
+ ! Local variables
2674
+ integer, parameter :: NTRYH(*) = [4, 2, 3, 5]
2675
+ integer(ip) :: nl, nf, j, ntry, nq, nr, i, is, nfm1, l1, k1, iip
2676
+ integer(ip) :: ld, l2, ido, iipm, ii
2677
+ real(wp) :: argh, argld, fi, arg
2678
+
2679
+ ! Initialize values
2680
+ ntry = 0
2681
+ nl = n
2682
+ nf = 0
2683
+ j = 0
2684
+
2685
+ factorization_loop: do
2686
+
2687
+ j = j + 1
2688
+
2689
+ if (j <= 4) then
2690
+ ntry = NTRYH(j)
2691
+ else
2692
+ ntry = ntry + 2
2693
+ end if
2694
+
2695
+ inner_loop: do
2696
+
2697
+ nq = nl/ntry
2698
+ nr = nl - ntry*nq
2699
+
2700
+ if (nr /= 0) cycle factorization_loop
2701
+
2702
+ nf = nf + 1
2703
+ ifac(nf+2) = ntry
2704
+ nl = nq
2705
+
2706
+ if (ntry == 2) then
2707
+ if (nf /= 1) then
2708
+ ifac(nf+2:4:(-1)) = ifac(nf+1:3:(-1))
2709
+ ifac(3) = 2
2710
+ end if
2711
+ end if
2712
+
2713
+ if (nl /= 1) cycle inner_loop
2714
+
2715
+ exit inner_loop
2716
+ end do inner_loop
2717
+ exit factorization_loop
2718
+ end do factorization_loop
2719
+
2720
+ ifac(1) = n
2721
+ ifac(2) = nf
2722
+ argh = TWO_PI/n
2723
+ is = 0
2724
+ nfm1 = nf - 1
2725
+ l1 = 1
2726
+
2727
+ if (nfm1 /= 0) then
2728
+ do k1 = 1, nfm1
2729
+ iip = int(ifac(k1+2), kind=ip)
2730
+ ld = 0
2731
+ l2 = l1*iip
2732
+ ido = n/l2
2733
+ iipm = iip - 1
2734
+ do j = 1, iipm
2735
+ ld = ld + l1
2736
+ i = is
2737
+ argld = real(ld, kind=wp)*argh
2738
+ fi = ZERO
2739
+ do ii = 3, ido, 2
2740
+ i = i + 2
2741
+ fi = fi + ONE
2742
+ arg = fi*argld
2743
+ wa(i-1) = cos(arg)
2744
+ wa(i) = sin(arg)
2745
+ end do
2746
+ is = is + ido
2747
+ end do
2748
+ l1 = l2
2749
+ end do
2750
+ end if
2751
+
2752
+ end subroutine real_initialization_lower_routine
2753
+
2754
+ subroutine rfftb(n, r, wsave)
2755
+
2756
+ ! Dummy arguments
2757
+
2758
+ integer(ip) :: n
2759
+ real(wp) :: r(*)
2760
+ real(wp) :: wsave(*)
2761
+
2762
+
2763
+ if (n /= 1) then
2764
+ call real_backward_lower_routine(n, r, wsave, wsave(n+1), wsave(2*n+1))
2765
+ end if
2766
+
2767
+ end subroutine rfftb
2768
+
2769
+ subroutine real_backward_lower_routine(n, c, ch, wa, ifac)
2770
+
2771
+ ! Dummy arguments
2772
+
2773
+ integer(ip), intent(in) :: n
2774
+ real(wp), intent(in) :: ifac(*)
2775
+ real(wp) :: c(*)
2776
+ real(wp) :: ch(*)
2777
+ real(wp) :: wa(*)
2778
+
2779
+ ! Local variables
2780
+
2781
+ integer(ip) :: nf, na, l1, iw, k1, iip
2782
+ integer(ip) :: l2, ido, idl1, ix2, ix3, ix4
2783
+
2784
+
2785
+ nf = int(ifac(2), kind=ip)
2786
+ na = 0
2787
+ l1 = 1
2788
+ iw = 1
2789
+
2790
+ do k1 = 1, nf
2791
+ iip = int(ifac(k1+2), kind=ip)
2792
+ l2 = iip*l1
2793
+ ido = n/l2
2794
+ idl1 = ido*l1
2795
+
2796
+ select case (iip)
2797
+ case (4)
2798
+ ix2 = iw + ido
2799
+ ix3 = ix2 + ido
2800
+ if (na == 0) then
2801
+ call real_backward_pass_4(ido, l1, c, ch, wa(iw), wa(ix2), wa(ix3))
2802
+ else
2803
+ call real_backward_pass_4(ido, l1, ch, c, wa(iw), wa(ix2), wa(ix3))
2804
+ end if
2805
+ na = 1 - na
2806
+ case (2)
2807
+ if (na == 0) then
2808
+ call real_backward_pass_2(ido, l1, c, ch, wa(iw))
2809
+ else
2810
+ call real_backward_pass_2(ido, l1, ch, c, wa(iw))
2811
+ end if
2812
+ na = 1 - na
2813
+ case (3)
2814
+ ix2 = iw + ido
2815
+ if (na == 0) then
2816
+ call real_backward_pass_3(ido, l1, c, ch, wa(iw), wa(ix2))
2817
+ else
2818
+ call real_backward_pass_3(ido, l1, ch, c, wa(iw), wa(ix2))
2819
+ end if
2820
+ na = 1 - na
2821
+ case (5)
2822
+ ix2 = iw + ido
2823
+ ix3 = ix2 + ido
2824
+ ix4 = ix3 + ido
2825
+ if (na == 0) then
2826
+ call real_backward_pass_5(ido, l1, c, ch, wa(iw), wa(ix2), wa( &
2827
+ ix3), wa(ix4))
2828
+ else
2829
+ call real_backward_pass_5(ido, l1, ch, c, wa(iw), wa(ix2), wa( &
2830
+ ix3), wa(ix4))
2831
+ end if
2832
+ na = 1 - na
2833
+ case default
2834
+ if (na == 0) then
2835
+ call real_backward_pass_n(ido, iip, l1, idl1, c, c, c, ch, ch, wa(iw))
2836
+ else
2837
+ call real_backward_pass_n(ido, iip, l1, idl1, ch, ch, ch, c, c, wa(iw))
2838
+ end if
2839
+
2840
+ if (ido == 1) na = 1 - na
2841
+
2842
+ end select
2843
+ l1 = l2
2844
+ iw = iw + (iip - 1)*ido
2845
+ end do
2846
+
2847
+ if (na /= 0) c(:n) = ch(:n)
2848
+
2849
+ end subroutine real_backward_lower_routine
2850
+
2851
+ pure subroutine real_backward_pass_2(ido, l1, cc, ch, wa1)
2852
+
2853
+ ! Dummy arguments
2854
+
2855
+ integer(ip), intent(in) :: ido
2856
+ integer(ip), intent(in) :: l1
2857
+ real(wp), intent(in) :: cc(ido, 2, l1)
2858
+ real(wp), intent(out) :: ch(ido, l1, 2)
2859
+ real(wp), intent(in) :: wa1(*)
2860
+
2861
+ ! Local variables
2862
+
2863
+ integer(ip) :: k, idp2, i, ic
2864
+ real(wp) :: tr2, ti2
2865
+
2866
+
2867
+ ch(1,:, 1) = cc(1, 1,:) + cc(ido, 2,:)
2868
+ ch(1,:, 2) = cc(1, 1,:) - cc(ido, 2,:)
2869
+
2870
+ if (ido >= 2) then
2871
+ if (ido /= 2) then
2872
+ idp2 = ido + 2
2873
+ do k = 1, l1
2874
+ do i = 3, ido, 2
2875
+ ic = idp2 - i
2876
+ ch(i-1, k, 1) = cc(i-1, 1, k) + cc(ic-1, 2, k)
2877
+ tr2 = cc(i-1, 1, k) - cc(ic-1, 2, k)
2878
+ ch(i, k, 1) = cc(i, 1, k) - cc(ic, 2, k)
2879
+ ti2 = cc(i, 1, k) + cc(ic, 2, k)
2880
+ ch(i-1, k, 2) = wa1(i-2)*tr2 - wa1(i-1)*ti2
2881
+ ch(i, k, 2) = wa1(i-2)*ti2 + wa1(i-1)*tr2
2882
+ end do
2883
+ end do
2884
+ if (mod(ido, 2) == 1) then
2885
+ return
2886
+ end if
2887
+ end if
2888
+ ch(ido,:, 1) = cc(ido, 1,:) + cc(ido, 1,:)
2889
+ ch(ido,:, 2) = -(cc(1, 2,:)+cc(1, 2,:))
2890
+ end if
2891
+
2892
+ end subroutine real_backward_pass_2
2893
+
2894
+ pure subroutine real_backward_pass_3(ido, l1, cc, ch, wa1, wa2)
2895
+
2896
+ ! Dummy arguments
2897
+
2898
+ integer(ip), intent(in) :: ido
2899
+ integer(ip), intent(in) :: l1
2900
+ real(wp), intent(in) :: cc(ido, 3, l1)
2901
+ real(wp), intent(out) :: ch(ido, l1, 3)
2902
+ real(wp), intent(in) :: wa1(*)
2903
+ real(wp), intent(in) :: wa2(*)
2904
+
2905
+ ! Local variables
2906
+
2907
+ integer(ip) :: k, idp2, i, ic
2908
+ real(wp), parameter :: taur = -HALF
2909
+ real(wp), parameter :: taui = sqrt(THREE)/TWO ! 0.866025403784439
2910
+ real(wp) :: tr2, cr2, ci3, ti2, ci2, cr3, dr2, dr3, di2, di3
2911
+
2912
+
2913
+ do k = 1, l1
2914
+ tr2 = cc(ido, 2, k) + cc(ido, 2, k)
2915
+ cr2 = cc(1, 1, k) + taur*tr2
2916
+ ch(1, k, 1) = cc(1, 1, k) + tr2
2917
+ ci3 = taui*(cc(1, 3, k)+cc(1, 3, k))
2918
+ ch(1, k, 2) = cr2 - ci3
2919
+ ch(1, k, 3) = cr2 + ci3
2920
+ end do
2921
+
2922
+ if(ido /= 1) then
2923
+ idp2 = ido + 2
2924
+ do k = 1, l1
2925
+ do i = 3, ido, 2
2926
+ ic = idp2 - i
2927
+ tr2 = cc(i-1, 3, k) + cc(ic-1, 2, k)
2928
+ cr2 = cc(i-1, 1, k) + taur*tr2
2929
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2
2930
+ ti2 = cc(i, 3, k) - cc(ic, 2, k)
2931
+ ci2 = cc(i, 1, k) + taur*ti2
2932
+ ch(i, k, 1) = cc(i, 1, k) + ti2
2933
+ cr3 = taui*(cc(i-1, 3, k)-cc(ic-1, 2, k))
2934
+ ci3 = taui*(cc(i, 3, k)+cc(ic, 2, k))
2935
+ dr2 = cr2 - ci3
2936
+ dr3 = cr2 + ci3
2937
+ di2 = ci2 + cr3
2938
+ di3 = ci2 - cr3
2939
+ ch(i-1, k, 2) = wa1(i-2)*dr2 - wa1(i-1)*di2
2940
+ ch(i, k, 2) = wa1(i-2)*di2 + wa1(i-1)*dr2
2941
+ ch(i-1, k, 3) = wa2(i-2)*dr3 - wa2(i-1)*di3
2942
+ ch(i, k, 3) = wa2(i-2)*di3 + wa2(i-1)*dr3
2943
+ end do
2944
+ end do
2945
+ end if
2946
+
2947
+ end subroutine real_backward_pass_3
2948
+
2949
+ pure subroutine real_backward_pass_4(ido, l1, cc, ch, wa1, wa2, wa3)
2950
+
2951
+ ! Dummy arguments
2952
+
2953
+ integer(ip), intent(in) :: ido
2954
+ integer(ip), intent(in) :: l1
2955
+ real(wp), intent(in) :: cc(ido, 4, l1)
2956
+ real(wp), intent(out) :: ch(ido, l1, 4)
2957
+ real(wp), intent(in) :: wa1(*)
2958
+ real(wp), intent(in) :: wa2(*)
2959
+ real(wp), intent(in) :: wa3(*)
2960
+
2961
+ ! Local variables
2962
+
2963
+ integer(ip) :: k, idp2, i, ic
2964
+ real(wp), parameter :: SQRT_2 = sqrt(TWO) ! 1.414213562373095
2965
+ real(wp) :: tr1, tr2, tr3, tr4, ti1, ti2, ti3, ti4, cr3, ci3
2966
+ real(wp) :: cr2, cr4, ci2, ci4
2967
+
2968
+
2969
+ do k = 1, l1
2970
+ tr1 = cc(1, 1, k) - cc(ido, 4, k)
2971
+ tr2 = cc(1, 1, k) + cc(ido, 4, k)
2972
+ tr3 = cc(ido, 2, k) + cc(ido, 2, k)
2973
+ tr4 = cc(1, 3, k) + cc(1, 3, k)
2974
+ ch(1, k, 1) = tr2 + tr3
2975
+ ch(1, k, 2) = tr1 - tr4
2976
+ ch(1, k, 3) = tr2 - tr3
2977
+ ch(1, k, 4) = tr1 + tr4
2978
+ end do
2979
+
2980
+ if (2 <= ido) then
2981
+ if (ido /= 2) then
2982
+ idp2 = ido + 2
2983
+ do k = 1, l1
2984
+ do i = 3, ido, 2
2985
+ ic = idp2 - i
2986
+ ti1 = cc(i, 1, k) + cc(ic, 4, k)
2987
+ ti2 = cc(i, 1, k) - cc(ic, 4, k)
2988
+ ti3 = cc(i, 3, k) - cc(ic, 2, k)
2989
+ tr4 = cc(i, 3, k) + cc(ic, 2, k)
2990
+ tr1 = cc(i-1, 1, k) - cc(ic-1, 4, k)
2991
+ tr2 = cc(i-1, 1, k) + cc(ic-1, 4, k)
2992
+ ti4 = cc(i-1, 3, k) - cc(ic-1, 2, k)
2993
+ tr3 = cc(i-1, 3, k) + cc(ic-1, 2, k)
2994
+ ch(i-1, k, 1) = tr2 + tr3
2995
+ cr3 = tr2 - tr3
2996
+ ch(i, k, 1) = ti2 + ti3
2997
+ ci3 = ti2 - ti3
2998
+ cr2 = tr1 - tr4
2999
+ cr4 = tr1 + tr4
3000
+ ci2 = ti1 + ti4
3001
+ ci4 = ti1 - ti4
3002
+ ch(i-1, k, 2) = wa1(i-2)*cr2 - wa1(i-1)*ci2
3003
+ ch(i, k, 2) = wa1(i-2)*ci2 + wa1(i-1)*cr2
3004
+ ch(i-1, k, 3) = wa2(i-2)*cr3 - wa2(i-1)*ci3
3005
+ ch(i, k, 3) = wa2(i-2)*ci3 + wa2(i-1)*cr3
3006
+ ch(i-1, k, 4) = wa3(i-2)*cr4 - wa3(i-1)*ci4
3007
+ ch(i, k, 4) = wa3(i-2)*ci4 + wa3(i-1)*cr4
3008
+ end do
3009
+ end do
3010
+ if (mod(ido, 2) == 1) then
3011
+ return
3012
+ end if
3013
+ end if
3014
+ do k = 1, l1
3015
+ ti1 = cc(1, 2, k) + cc(1, 4, k)
3016
+ ti2 = cc(1, 4, k) - cc(1, 2, k)
3017
+ tr1 = cc(ido, 1, k) - cc(ido, 3, k)
3018
+ tr2 = cc(ido, 1, k) + cc(ido, 3, k)
3019
+ ch(ido, k, 1) = tr2 + tr2
3020
+ ch(ido, k, 2) = SQRT_2*(tr1 - ti1)
3021
+ ch(ido, k, 3) = ti2 + ti2
3022
+ ch(ido, k, 4) = -SQRT_2*(tr1 + ti1)
3023
+ end do
3024
+ end if
3025
+
3026
+ end subroutine real_backward_pass_4
3027
+
3028
+ pure subroutine real_backward_pass_5(ido, l1, cc, ch, wa1, wa2, wa3, wa4)
3029
+
3030
+ ! Dummy arguments
3031
+
3032
+ integer(ip), intent(in) :: ido
3033
+ integer(ip), intent(in) :: l1
3034
+ real(wp), intent(in) :: cc(ido, 5, l1)
3035
+ real(wp), intent(out) :: ch(ido, l1, 5)
3036
+ real(wp), intent(in) :: wa1(*)
3037
+ real(wp), intent(in) :: wa2(*)
3038
+ real(wp), intent(in) :: wa3(*)
3039
+ real(wp), intent(in) :: wa4(*)
3040
+
3041
+ ! Local variables
3042
+
3043
+ integer(ip) :: k, idp2, i, ic
3044
+ real(wp) :: ti5, ti4, tr2, tr3, cr2, cr3, ci5
3045
+ real(wp) :: ci4, ti2, ti3, tr5, tr4, ci2, ci3, cr5, cr4, dr3, dr4, di3
3046
+ real(wp) :: di4, dr5, dr2, di5, di2
3047
+ real(wp), parameter :: tr11 = (SQRT_5 - ONE)/4 ! 0.309016994374947
3048
+ real(wp), parameter :: ti11 = sqrt((FIVE + SQRT_5)/2)/2 ! 0.951056516295154
3049
+ real(wp), parameter :: tr12 = (-ONE - SQRT_5)/4 ! -.809016994374947
3050
+ real(wp), parameter :: ti12 = sqrt(FIVE/(TWO * (FIVE + SQRT_5)) ) ! 0.587785252292473
3051
+
3052
+
3053
+
3054
+ do k = 1, l1
3055
+ ti5 = cc(1, 3, k) + cc(1, 3, k)
3056
+ ti4 = cc(1, 5, k) + cc(1, 5, k)
3057
+ tr2 = cc(ido, 2, k) + cc(ido, 2, k)
3058
+ tr3 = cc(ido, 4, k) + cc(ido, 4, k)
3059
+ ch(1, k, 1) = cc(1, 1, k) + tr2 + tr3
3060
+ cr2 = cc(1, 1, k) + tr11*tr2 + tr12*tr3
3061
+ cr3 = cc(1, 1, k) + tr12*tr2 + tr11*tr3
3062
+ ci5 = ti11*ti5 + ti12*ti4
3063
+ ci4 = ti12*ti5 - ti11*ti4
3064
+ ch(1, k, 2) = cr2 - ci5
3065
+ ch(1, k, 3) = cr3 - ci4
3066
+ ch(1, k, 4) = cr3 + ci4
3067
+ ch(1, k, 5) = cr2 + ci5
3068
+ end do
3069
+
3070
+ if(ido /= 1) then
3071
+ idp2 = ido + 2
3072
+ do k = 1, l1
3073
+ do i = 3, ido, 2
3074
+ ic = idp2 - i
3075
+ ti5 = cc(i, 3, k) + cc(ic, 2, k)
3076
+ ti2 = cc(i, 3, k) - cc(ic, 2, k)
3077
+ ti4 = cc(i, 5, k) + cc(ic, 4, k)
3078
+ ti3 = cc(i, 5, k) - cc(ic, 4, k)
3079
+ tr5 = cc(i-1, 3, k) - cc(ic-1, 2, k)
3080
+ tr2 = cc(i-1, 3, k) + cc(ic-1, 2, k)
3081
+ tr4 = cc(i-1, 5, k) - cc(ic-1, 4, k)
3082
+ tr3 = cc(i-1, 5, k) + cc(ic-1, 4, k)
3083
+ ch(i-1, k, 1) = cc(i-1, 1, k) + tr2 + tr3
3084
+ ch(i, k, 1) = cc(i, 1, k) + ti2 + ti3
3085
+ cr2 = cc(i-1, 1, k) + tr11*tr2 + tr12*tr3
3086
+ ci2 = cc(i, 1, k) + tr11*ti2 + tr12*ti3
3087
+ cr3 = cc(i-1, 1, k) + tr12*tr2 + tr11*tr3
3088
+ ci3 = cc(i, 1, k) + tr12*ti2 + tr11*ti3
3089
+ cr5 = ti11*tr5 + ti12*tr4
3090
+ ci5 = ti11*ti5 + ti12*ti4
3091
+ cr4 = ti12*tr5 - ti11*tr4
3092
+ ci4 = ti12*ti5 - ti11*ti4
3093
+ dr3 = cr3 - ci4
3094
+ dr4 = cr3 + ci4
3095
+ di3 = ci3 + cr4
3096
+ di4 = ci3 - cr4
3097
+ dr5 = cr2 + ci5
3098
+ dr2 = cr2 - ci5
3099
+ di5 = ci2 - cr5
3100
+ di2 = ci2 + cr5
3101
+ ch(i-1, k, 2) = wa1(i-2)*dr2 - wa1(i-1)*di2
3102
+ ch(i, k, 2) = wa1(i-2)*di2 + wa1(i-1)*dr2
3103
+ ch(i-1, k, 3) = wa2(i-2)*dr3 - wa2(i-1)*di3
3104
+ ch(i, k, 3) = wa2(i-2)*di3 + wa2(i-1)*dr3
3105
+ ch(i-1, k, 4) = wa3(i-2)*dr4 - wa3(i-1)*di4
3106
+ ch(i, k, 4) = wa3(i-2)*di4 + wa3(i-1)*dr4
3107
+ ch(i-1, k, 5) = wa4(i-2)*dr5 - wa4(i-1)*di5
3108
+ ch(i, k, 5) = wa4(i-2)*di5 + wa4(i-1)*dr5
3109
+ end do
3110
+ end do
3111
+ end if
3112
+
3113
+ end subroutine real_backward_pass_5
3114
+
3115
+ subroutine real_backward_pass_n(ido, iip, l1, idl1, cc, c1, c2, ch, ch2, wa)
3116
+
3117
+ ! Dummy arguments
3118
+
3119
+ integer(ip), intent(in) :: ido
3120
+ integer(ip), intent(in) :: iip
3121
+ integer(ip), intent(in) :: l1
3122
+ integer(ip), intent(in) :: idl1
3123
+ real(wp), intent(in) :: cc(ido, iip, l1)
3124
+ real(wp), intent(inout) :: c1(ido, l1, iip)
3125
+ real(wp), intent(inout) :: c2(idl1, iip)
3126
+ real(wp), intent(inout) :: ch(ido, l1, iip)
3127
+ real(wp), intent(inout) :: ch2(idl1, iip)
3128
+ real(wp), intent(in) :: wa(*)
3129
+
3130
+ ! Local variables
3131
+
3132
+ integer:: idp2, nbd, iipp2, iipph, k, i, j, jc, j2, l, lc, is, idij
3133
+ real(wp) :: arg, dcp, dsp, ar1, ai1, ar1h, dc2, ds2, ar2, ai2, ar2h
3134
+
3135
+
3136
+ arg = TWO_PI/iip
3137
+ dcp = cos(arg)
3138
+ dsp = sin(arg)
3139
+ idp2 = ido + 2
3140
+ nbd =(ido - 1)/2
3141
+ iipp2 = iip + 2
3142
+ iipph = (iip + 1)/2
3143
+
3144
+ ch(:,:, 1) = cc(:, 1,:)
3145
+
3146
+ do j = 2, iipph
3147
+ jc = iipp2 - j
3148
+ j2 = j + j
3149
+ ch(1,:, j) = cc(ido, j2-2,:) + cc(ido, j2-2,:)
3150
+ ch(1,:, jc) = cc(1, j2-1,:) + cc(1, j2-1,:)
3151
+ end do
3152
+
3153
+ if(ido /= 1) then
3154
+ if (l1 <= nbd) then
3155
+ do j = 2, iipph
3156
+ jc = iipp2 - j
3157
+ ch(2:ido-1:2,:, j) = cc(2:ido-1:2, 2*j-1,:) + cc(idp2-4: &
3158
+ idp2-1-ido:(-2), 2*j-2,:)
3159
+ ch(2:ido-1:2,:, jc) = cc(2:ido-1:2, 2*j-1,:) - cc(idp2-4: &
3160
+ idp2-1-ido:(-2), 2*j-2,:)
3161
+ ch(3:ido:2,:, j) = cc(3:ido:2, 2*j-1,:) - cc(idp2-3:idp2- &
3162
+ ido:(-2), 2*j-2,:)
3163
+ ch(3:ido:2,:, jc) = cc(3:ido:2, 2*j-1,:) + cc(idp2-3:idp2- &
3164
+ ido:(-2), 2*j-2,:)
3165
+ end do
3166
+ else
3167
+ do j = 2, iipph
3168
+ jc = iipp2 - j
3169
+ ch(2:ido-1:2,:, j) = cc(2:ido-1:2, 2*j-1,:) + cc(idp2-4: &
3170
+ idp2-1-ido:(-2), 2*j-2,:)
3171
+ ch(2:ido-1:2,:, jc) = cc(2:ido-1:2, 2*j-1,:) - cc(idp2-4: &
3172
+ idp2-1-ido:(-2), 2*j-2,:)
3173
+ ch(3:ido:2,:, j) = cc(3:ido:2, 2*j-1,:) - cc(idp2-3:idp2- &
3174
+ ido:(-2), 2*j-2,:)
3175
+ ch(3:ido:2,:, jc) = cc(3:ido:2, 2*j-1,:) + cc(idp2-3:idp2- &
3176
+ ido:(-2), 2*j-2,:)
3177
+ end do
3178
+ end if
3179
+ end if
3180
+
3181
+ ar1 = ONE
3182
+ ai1 = ZERO
3183
+
3184
+ do l = 2, iipph
3185
+ lc = iipp2 - l
3186
+ ar1h = dcp*ar1 - dsp*ai1
3187
+ ai1 = dcp*ai1 + dsp*ar1
3188
+ ar1 = ar1h
3189
+ c2(:, l) = ch2(:, 1) + ar1*ch2(:, 2)
3190
+ c2(:, lc) = ai1*ch2(:, iip)
3191
+ dc2 = ar1
3192
+ ds2 = ai1
3193
+ ar2 = ar1
3194
+ ai2 = ai1
3195
+ do j = 3, iipph
3196
+ jc = iipp2 - j
3197
+ ar2h = dc2*ar2 - ds2*ai2
3198
+ ai2 = dc2*ai2 + ds2*ar2
3199
+ ar2 = ar2h
3200
+ c2(:, l) = c2(:, l) + ar2*ch2(:, j)
3201
+ c2(:, lc) = c2(:, lc) + ai2*ch2(:, jc)
3202
+ end do
3203
+ end do
3204
+
3205
+ do j = 2, iipph
3206
+ ch2(:, 1) = ch2(:, 1) + ch2(:, j)
3207
+ end do
3208
+
3209
+ do j = 2, iipph
3210
+ jc = iipp2 - j
3211
+ ch(1,:, j) = c1(1,:, j) - c1(1,:, jc)
3212
+ ch(1,:, jc) = c1(1,:, j) + c1(1,:, jc)
3213
+ end do
3214
+
3215
+ if(ido /= 1) then
3216
+ if (l1 <= nbd) then
3217
+ do j = 2, iipph
3218
+ jc = iipp2 - j
3219
+ ch(2:ido-1:2,:, j) = c1(2:ido-1:2,:, j) - c1(3:ido:2,:, jc)
3220
+ ch(2:ido-1:2,:, jc) = c1(2:ido-1:2,:, j) + c1(3:ido:2,:, jc)
3221
+ ch(3:ido:2,:, j) = c1(3:ido:2,:, j) + c1(2:ido-1:2,:, jc)
3222
+ ch(3:ido:2,:, jc) = c1(3:ido:2,:, j) - c1(2:ido-1:2,:, jc)
3223
+ end do
3224
+ else
3225
+ do j = 2, iipph
3226
+ jc = iipp2 - j
3227
+ ch(2:ido-1:2,:, j) = c1(2:ido-1:2,:, j) - c1(3:ido:2,:, jc)
3228
+ ch(2:ido-1:2,:, jc) = c1(2:ido-1:2,:, j) + c1(3:ido:2,:, jc)
3229
+ ch(3:ido:2,:, j) = c1(3:ido:2,:, j) + c1(2:ido-1:2,:, jc)
3230
+ ch(3:ido:2,:, jc) = c1(3:ido:2,:, j) - c1(2:ido-1:2,:, jc)
3231
+ end do
3232
+ end if
3233
+ end if
3234
+
3235
+ if(ido /= 1) then
3236
+ c2(:, 1) = ch2(:, 1)
3237
+ c1(1,:, 2:iip) = ch(1,:, 2:iip)
3238
+ if (nbd <= l1) then
3239
+ is = -ido
3240
+ do j = 2, iip
3241
+ is = is + ido
3242
+ idij = is
3243
+ do i = 3, ido, 2
3244
+ idij = idij + 2
3245
+ c1(i-1,:, j) = wa(idij-1)*ch(i-1,:, j) - wa(idij)*ch(i,:, j)
3246
+ c1(i,:, j) = wa(idij-1)*ch(i,:, j) + wa(idij)*ch(i-1,:, j)
3247
+ end do
3248
+ end do
3249
+ else
3250
+ is = -ido
3251
+ do j = 2, iip
3252
+ is = is + ido
3253
+ do k = 1, l1
3254
+ idij = is
3255
+ c1(2:ido-1:2, k, j) = wa(idij+1:ido-2+idij:2)*ch(2:ido-1:2, &
3256
+ k, j) - wa(idij+2:ido-1+idij:2)*ch(3:ido:2, k, j)
3257
+ c1(3:ido:2, k, j) = wa(idij+1:ido-2+idij:2)*ch(3:ido:2, k, j) &
3258
+ + wa(idij+2:ido-1+idij:2)*ch(2:ido-1:2, k, j)
3259
+ end do
3260
+ end do
3261
+ end if
3262
+ end if
3263
+
3264
+ end subroutine real_backward_pass_n
3265
+
3266
+ subroutine rfftf(n, r, wsave)
3267
+
3268
+ ! Dummy arguments
3269
+
3270
+ integer(ip) :: n
3271
+ real(wp) :: r(*)
3272
+ real(wp) :: wsave(*)
3273
+
3274
+
3275
+ if (n /= 1) then
3276
+ call real_forward_lower_routine(n, r, wsave, wsave(n+1), wsave(2*n+1))
3277
+ end if
3278
+
3279
+ end subroutine rfftf
3280
+
3281
+ subroutine real_forward_lower_routine(n, c, ch, wa, ifac)
3282
+
3283
+ ! Dummy arguments
3284
+
3285
+ integer(ip), intent(in) :: n
3286
+ real(wp), intent(in) :: ifac(*)
3287
+ real(wp) :: c(*)
3288
+ real(wp) :: ch(*)
3289
+ real(wp) :: wa(*)
3290
+
3291
+ ! Local variables
3292
+
3293
+ integer(ip) :: nf, na, l2, iw, k1, kh
3294
+ integer(ip) :: iip, l1, ido, idl1, ix2, ix3, ix4
3295
+
3296
+
3297
+ nf = int(ifac(2), kind=ip)
3298
+ na = 1
3299
+ l2 = n
3300
+ iw = n
3301
+
3302
+ do k1 = 1, nf
3303
+ kh = nf - k1
3304
+ iip = int(ifac(kh+3), kind=ip)
3305
+ l1 = l2/iip
3306
+ ido = n/l2
3307
+ idl1 = ido*l1
3308
+ iw = iw - (iip - 1)*ido
3309
+ na = 1 - na
3310
+
3311
+ select case (iip)
3312
+ case (2)
3313
+ if (na == 0) then
3314
+ call real_forward_pass_2(ido, l1, c, ch, wa(iw))
3315
+ else
3316
+ call real_forward_pass_2(ido, l1, ch, c, wa(iw))
3317
+ end if
3318
+ case (3)
3319
+ ix2 = iw + ido
3320
+ if (na == 0) then
3321
+ call real_forward_pass_3(ido, l1, c, ch, wa(iw), wa(ix2))
3322
+ else
3323
+ call real_forward_pass_3(ido, l1, ch, c, wa(iw), wa(ix2))
3324
+ end if
3325
+ case (4)
3326
+ ix2 = iw + ido
3327
+ ix3 = ix2 + ido
3328
+ if (na == 0) then
3329
+ call real_forward_pass_4(ido, l1, c, ch, wa(iw), wa(ix2), wa(ix3))
3330
+ else
3331
+ call real_forward_pass_4(ido, l1, ch, c, wa(iw), wa(ix2), wa(ix3))
3332
+ end if
3333
+ case (5)
3334
+ ix2 = iw + ido
3335
+ ix3 = ix2 + ido
3336
+ ix4 = ix3 + ido
3337
+ if (na == 0) then
3338
+ call real_forward_pass_5(ido, l1, c, ch, wa(iw), wa(ix2), wa(ix3), wa(ix4))
3339
+ else
3340
+ call real_forward_pass_5(ido, l1, ch, c, wa(iw), wa(ix2), wa(ix3), wa(ix4))
3341
+ end if
3342
+ case default
3343
+ if(ido == 1) then
3344
+ na = 1 - na
3345
+ end if
3346
+ if (na == 0) then
3347
+ call real_forward_pass_n(ido, iip, l1, idl1, c, c, c, ch, ch, wa(iw))
3348
+ na = 1
3349
+ else
3350
+ call real_forward_pass_n(ido, iip, l1, idl1, ch, ch, ch, c, c, wa(iw))
3351
+ na = 0
3352
+ end if
3353
+ end select
3354
+ l2 = l1
3355
+ end do
3356
+
3357
+ if (na /= 1) c(:n) = ch(:n)
3358
+
3359
+ end subroutine real_forward_lower_routine
3360
+
3361
+ pure subroutine real_forward_pass_2(ido, l1, cc, ch, wa1)
3362
+
3363
+ ! Dummy arguments
3364
+
3365
+ integer(ip), intent(in) :: ido
3366
+ integer(ip), intent(in) :: l1
3367
+ real(wp), intent(in) :: cc(ido, l1, 2)
3368
+ real(wp), intent(out) :: ch(ido, 2, l1)
3369
+ real(wp), intent(in) :: wa1(*)
3370
+
3371
+ ! Local variables
3372
+
3373
+ integer(ip) :: k, idp2, i, ic
3374
+ real(wp) :: tr2, ti2
3375
+
3376
+
3377
+ ch(1, 1,:) = cc(1,:, 1) + cc(1,:, 2)
3378
+ ch(ido, 2,:) = cc(1,:, 1) - cc(1,:, 2)
3379
+
3380
+ if (ido >= 2) then
3381
+ if (ido /= 2) then
3382
+ idp2 = ido + 2
3383
+ do k = 1, l1
3384
+ do i = 3, ido, 2
3385
+ ic = idp2 - i
3386
+ tr2 = wa1(i-2)*cc(i-1, k, 2) + wa1(i-1)*cc(i, k, 2)
3387
+ ti2 = wa1(i-2)*cc(i, k, 2) - wa1(i-1)*cc(i-1, k, 2)
3388
+ ch(i, 1, k) = cc(i, k, 1) + ti2
3389
+ ch(ic, 2, k) = ti2 - cc(i, k, 1)
3390
+ ch(i-1, 1, k) = cc(i-1, k, 1) + tr2
3391
+ ch(ic-1, 2, k) = cc(i-1, k, 1) - tr2
3392
+ end do
3393
+ end do
3394
+ if (mod(ido, 2) == 1) then
3395
+ return
3396
+ end if
3397
+ end if
3398
+ ch(1, 2,:) = -cc(ido,:, 2)
3399
+ ch(ido, 1,:) = cc(ido,:, 1)
3400
+ end if
3401
+
3402
+ end subroutine real_forward_pass_2
3403
+
3404
+ pure subroutine real_forward_pass_3(ido, l1, cc, ch, wa1, wa2)
3405
+
3406
+ ! Dummy arguments
3407
+
3408
+ integer(ip), intent(in) :: ido
3409
+ integer(ip), intent(in) :: l1
3410
+ real(wp), intent(in) :: cc(ido, l1, 3)
3411
+ real(wp), intent(out) :: ch(ido, 3, l1)
3412
+ real(wp), intent(in) :: wa1(*)
3413
+ real(wp), intent(in) :: wa2(*)
3414
+
3415
+ ! Local variables
3416
+
3417
+ integer(ip) :: k, idp2, i, ic
3418
+ real(wp), parameter :: taur = -HALF
3419
+ real(wp), parameter :: taui = sqrt(THREE)/TWO ! 0.866025403784439
3420
+ real(wp) :: cr2, dr2, di2, dr3, di3, ci2, tr2, ti2, tr3, ti3
3421
+
3422
+
3423
+ do k = 1, l1
3424
+ cr2 = cc(1, k, 2) + cc(1, k, 3)
3425
+ ch(1, 1, k) = cc(1, k, 1) + cr2
3426
+ ch(1, 3, k) = taui*(cc(1, k, 3)-cc(1, k, 2))
3427
+ ch(ido, 2, k) = cc(1, k, 1) + taur*cr2
3428
+ end do
3429
+
3430
+ if(ido /= 1) then
3431
+ idp2 = ido + 2
3432
+ do k = 1, l1
3433
+ do i = 3, ido, 2
3434
+ ic = idp2 - i
3435
+ dr2 = wa1(i-2)*cc(i-1, k, 2) + wa1(i-1)*cc(i, k, 2)
3436
+ di2 = wa1(i-2)*cc(i, k, 2) - wa1(i-1)*cc(i-1, k, 2)
3437
+ dr3 = wa2(i-2)*cc(i-1, k, 3) + wa2(i-1)*cc(i, k, 3)
3438
+ di3 = wa2(i-2)*cc(i, k, 3) - wa2(i-1)*cc(i-1, k, 3)
3439
+ cr2 = dr2 + dr3
3440
+ ci2 = di2 + di3
3441
+ ch(i-1, 1, k) = cc(i-1, k, 1) + cr2
3442
+ ch(i, 1, k) = cc(i, k, 1) + ci2
3443
+ tr2 = cc(i-1, k, 1) + taur*cr2
3444
+ ti2 = cc(i, k, 1) + taur*ci2
3445
+ tr3 = taui*(di2 - di3)
3446
+ ti3 = taui*(dr3 - dr2)
3447
+ ch(i-1, 3, k) = tr2 + tr3
3448
+ ch(ic-1, 2, k) = tr2 - tr3
3449
+ ch(i, 3, k) = ti2 + ti3
3450
+ ch(ic, 2, k) = ti3 - ti2
3451
+ end do
3452
+ end do
3453
+ end if
3454
+
3455
+ end subroutine real_forward_pass_3
3456
+
3457
+ subroutine real_forward_pass_4(ido, l1, cc, ch, wa1, wa2, wa3)
3458
+
3459
+ ! Dummy arguments
3460
+
3461
+ integer(ip), intent(in) :: ido
3462
+ integer(ip), intent(in) :: l1
3463
+ real(wp), intent(in) :: cc(ido, l1, 4)
3464
+ real(wp), intent(out) :: ch(ido, 4, l1)
3465
+ real(wp), intent(in) :: wa1(*)
3466
+ real(wp), intent(in) :: wa2(*)
3467
+ real(wp), intent(in) :: wa3(*)
3468
+
3469
+ ! Local variables
3470
+
3471
+ integer(ip) :: k, idp2, i, ic
3472
+ real(wp) :: tr1, tr2, cr2, ci2, cr3, ci3
3473
+ real(wp) :: cr4, ci4, tr4, ti1
3474
+ real(wp) :: ti4, ti2, ti3, tr3
3475
+ real(wp), parameter :: ONE_OVER_SQRT_2 = ONE/SQRT_2
3476
+
3477
+
3478
+ do k = 1, l1
3479
+ tr1 = cc(1, k, 2) + cc(1, k, 4)
3480
+ tr2 = cc(1, k, 1) + cc(1, k, 3)
3481
+ ch(1, 1, k) = tr1 + tr2
3482
+ ch(ido, 4, k) = tr2 - tr1
3483
+ ch(ido, 2, k) = cc(1, k, 1) - cc(1, k, 3)
3484
+ ch(1, 3, k) = cc(1, k, 4) - cc(1, k, 2)
3485
+ end do
3486
+
3487
+ if (ido >= 2) then
3488
+ if (ido /= 2) then
3489
+ idp2 = ido + 2
3490
+ do k = 1, l1
3491
+ do i = 3, ido, 2
3492
+ ic = idp2 - i
3493
+ cr2 = wa1(i-2)*cc(i-1, k, 2) + wa1(i-1)*cc(i, k, 2)
3494
+ ci2 = wa1(i-2)*cc(i, k, 2) - wa1(i-1)*cc(i-1, k, 2)
3495
+ cr3 = wa2(i-2)*cc(i-1, k, 3) + wa2(i-1)*cc(i, k, 3)
3496
+ ci3 = wa2(i-2)*cc(i, k, 3) - wa2(i-1)*cc(i-1, k, 3)
3497
+ cr4 = wa3(i-2)*cc(i-1, k, 4) + wa3(i-1)*cc(i, k, 4)
3498
+ ci4 = wa3(i-2)*cc(i, k, 4) - wa3(i-1)*cc(i-1, k, 4)
3499
+ tr1 = cr2 + cr4
3500
+ tr4 = cr4 - cr2
3501
+ ti1 = ci2 + ci4
3502
+ ti4 = ci2 - ci4
3503
+ ti2 = cc(i, k, 1) + ci3
3504
+ ti3 = cc(i, k, 1) - ci3
3505
+ tr2 = cc(i-1, k, 1) + cr3
3506
+ tr3 = cc(i-1, k, 1) - cr3
3507
+ ch(i-1, 1, k) = tr1 + tr2
3508
+ ch(ic-1, 4, k) = tr2 - tr1
3509
+ ch(i, 1, k) = ti1 + ti2
3510
+ ch(ic, 4, k) = ti1 - ti2
3511
+ ch(i-1, 3, k) = ti4 + tr3
3512
+ ch(ic-1, 2, k) = tr3 - ti4
3513
+ ch(i, 3, k) = tr4 + ti3
3514
+ ch(ic, 2, k) = tr4 - ti3
3515
+ end do
3516
+ end do
3517
+ if (mod(ido, 2) == 1) then
3518
+ return
3519
+ end if
3520
+ end if
3521
+ do k = 1, l1
3522
+ ti1 = -ONE_OVER_SQRT_2*(cc(ido, k, 2)+cc(ido, k, 4))
3523
+ tr1 = ONE_OVER_SQRT_2*(cc(ido, k, 2)-cc(ido, k, 4))
3524
+ ch(ido, 1, k) = tr1 + cc(ido, k, 1)
3525
+ ch(ido, 3, k) = cc(ido, k, 1) - tr1
3526
+ ch(1, 2, k) = ti1 - cc(ido, k, 3)
3527
+ ch(1, 4, k) = ti1 + cc(ido, k, 3)
3528
+ end do
3529
+ end if
3530
+
3531
+ end subroutine real_forward_pass_4
3532
+
3533
+ subroutine real_forward_pass_5(ido, l1, cc, ch, wa1, wa2, wa3, wa4)
3534
+
3535
+ ! Dummy arguments
3536
+
3537
+ integer(ip), intent(in) :: ido
3538
+ integer(ip), intent(in) :: l1
3539
+ real(wp), intent(in) :: cc(ido, l1, 5)
3540
+ real(wp), intent(out) :: ch(ido, 5, l1)
3541
+ real(wp), intent(in) :: wa1(*)
3542
+ real(wp), intent(in) :: wa2(*)
3543
+ real(wp), intent(in) :: wa3(*)
3544
+ real(wp), intent(in) :: wa4(*)
3545
+
3546
+ ! Local variables
3547
+
3548
+ integer(ip) :: k, idp2, i, ic
3549
+ real(wp) :: cr2, ci5, cr3, ci4, dr2, di2, dr3
3550
+ real(wp) :: di3, dr4, di4, dr5, di5, cr5, ci2, cr4, ci3, tr2, ti2, tr3
3551
+ real(wp) :: ti3, tr5, ti5, tr4, ti4
3552
+ real(wp), parameter :: tr11 = (SQRT_5 - ONE)/4
3553
+ real(wp), parameter :: ti11 = sqrt((FIVE + SQRT_5)/2)/2
3554
+ real(wp), parameter :: tr12 = (-ONE - SQRT_5)/4
3555
+ real(wp), parameter :: ti12 = sqrt(FIVE/(TWO * (FIVE + SQRT_5)))
3556
+
3557
+
3558
+ do k = 1, l1
3559
+ cr2 = cc(1, k, 5) + cc(1, k, 2)
3560
+ ci5 = cc(1, k, 5) - cc(1, k, 2)
3561
+ cr3 = cc(1, k, 4) + cc(1, k, 3)
3562
+ ci4 = cc(1, k, 4) - cc(1, k, 3)
3563
+ ch(1, 1, k) = cc(1, k, 1) + cr2 + cr3
3564
+ ch(ido, 2, k) = cc(1, k, 1) + tr11*cr2 + tr12*cr3
3565
+ ch(1, 3, k) = ti11*ci5 + ti12*ci4
3566
+ ch(ido, 4, k) = cc(1, k, 1) + tr12*cr2 + tr11*cr3
3567
+ ch(1, 5, k) = ti12*ci5 - ti11*ci4
3568
+ end do
3569
+
3570
+ if(ido /= 1) then
3571
+ idp2 = ido + 2
3572
+ do k = 1, l1
3573
+ do i = 3, ido, 2
3574
+ ic = idp2 - i
3575
+ dr2 = wa1(i-2)*cc(i-1, k, 2) + wa1(i-1)*cc(i, k, 2)
3576
+ di2 = wa1(i-2)*cc(i, k, 2) - wa1(i-1)*cc(i-1, k, 2)
3577
+ dr3 = wa2(i-2)*cc(i-1, k, 3) + wa2(i-1)*cc(i, k, 3)
3578
+ di3 = wa2(i-2)*cc(i, k, 3) - wa2(i-1)*cc(i-1, k, 3)
3579
+ dr4 = wa3(i-2)*cc(i-1, k, 4) + wa3(i-1)*cc(i, k, 4)
3580
+ di4 = wa3(i-2)*cc(i, k, 4) - wa3(i-1)*cc(i-1, k, 4)
3581
+ dr5 = wa4(i-2)*cc(i-1, k, 5) + wa4(i-1)*cc(i, k, 5)
3582
+ di5 = wa4(i-2)*cc(i, k, 5) - wa4(i-1)*cc(i-1, k, 5)
3583
+ cr2 = dr2 + dr5
3584
+ ci5 = dr5 - dr2
3585
+ cr5 = di2 - di5
3586
+ ci2 = di2 + di5
3587
+ cr3 = dr3 + dr4
3588
+ ci4 = dr4 - dr3
3589
+ cr4 = di3 - di4
3590
+ ci3 = di3 + di4
3591
+ ch(i-1, 1, k) = cc(i-1, k, 1) + cr2 + cr3
3592
+ ch(i, 1, k) = cc(i, k, 1) + ci2 + ci3
3593
+ tr2 = cc(i-1, k, 1) + tr11*cr2 + tr12*cr3
3594
+ ti2 = cc(i, k, 1) + tr11*ci2 + tr12*ci3
3595
+ tr3 = cc(i-1, k, 1) + tr12*cr2 + tr11*cr3
3596
+ ti3 = cc(i, k, 1) + tr12*ci2 + tr11*ci3
3597
+ tr5 = ti11*cr5 + ti12*cr4
3598
+ ti5 = ti11*ci5 + ti12*ci4
3599
+ tr4 = ti12*cr5 - ti11*cr4
3600
+ ti4 = ti12*ci5 - ti11*ci4
3601
+ ch(i-1, 3, k) = tr2 + tr5
3602
+ ch(ic-1, 2, k) = tr2 - tr5
3603
+ ch(i, 3, k) = ti2 + ti5
3604
+ ch(ic, 2, k) = ti5 - ti2
3605
+ ch(i-1, 5, k) = tr3 + tr4
3606
+ ch(ic-1, 4, k) = tr3 - tr4
3607
+ ch(i, 5, k) = ti3 + ti4
3608
+ ch(ic, 4, k) = ti4 - ti3
3609
+ end do
3610
+ end do
3611
+ end if
3612
+
3613
+ end subroutine real_forward_pass_5
3614
+
3615
+ subroutine real_forward_pass_n(ido, iip, l1, idl1, cc, c1, c2, ch, ch2, wa)
3616
+
3617
+ ! Dummy arguments
3618
+
3619
+ integer(ip), intent(in) :: ido
3620
+ integer(ip), intent(in) :: iip
3621
+ integer(ip), intent(in) :: l1
3622
+ integer(ip), intent(in) :: idl1
3623
+ real(wp), intent(out) :: cc(ido, iip, l1)
3624
+ real(wp), intent(inout) :: c1(ido, l1, iip)
3625
+ real(wp), intent(inout) :: c2(idl1, iip)
3626
+ real(wp), intent(inout) :: ch(ido, l1, iip)
3627
+ real(wp), intent(inout) :: ch2(idl1, iip)
3628
+ real(wp), intent(in) :: wa(*)
3629
+
3630
+ ! Local variables
3631
+
3632
+ integer(ip) :: iipph, iipp2, idp2, nbd, j
3633
+ integer(ip) :: k, is, idij, i, jc, l, lc
3634
+ real(wp) :: arg, dcp, dsp, ar1, ai1
3635
+ real(wp) :: ar1h, dc2, ds2, ar2, ai2, ar2h
3636
+
3637
+
3638
+ arg = TWO_PI/iip
3639
+ dcp = cos(arg)
3640
+ dsp = sin(arg)
3641
+ iipph = (iip + 1)/2
3642
+ iipp2 = iip + 2
3643
+ idp2 = ido + 2
3644
+ nbd =(ido - 1)/2
3645
+
3646
+ block_construct: block
3647
+ if (ido /= 1) then
3648
+ ch2(:, 1) = c2(:, 1)
3649
+ ch(1,:, 2:iip) = c1(1,:, 2:iip)
3650
+ if (nbd <= l1) then
3651
+ is = -ido
3652
+ do j = 2, iip
3653
+ is = is + ido
3654
+ idij = is
3655
+ do i = 3, ido, 2
3656
+ idij = idij + 2
3657
+ ch(i-1,:, j)=wa(idij-1)*c1(i-1,:, j)+wa(idij)*c1(i,:, j)
3658
+ ch(i,:, j)=wa(idij-1)*c1(i,:, j)-wa(idij)*c1(i-1,:, j)
3659
+ end do
3660
+ end do
3661
+ else
3662
+ is = -ido
3663
+ do j = 2, iip
3664
+ is = is + ido
3665
+ do k = 1, l1
3666
+ idij = is
3667
+ ch(2:ido-1:2, k, j) = wa(idij+1:ido-2+idij:2)*c1(2:ido-1 &
3668
+ :2, k, j) + wa(idij+2:ido-1+idij:2)*c1(3:ido:2, k, j)
3669
+ ch(3:ido:2, k, j) = wa(idij+1:ido-2+idij:2)*c1(3:ido:2, k &
3670
+ , j) - wa(idij+2:ido-1+idij:2)*c1(2:ido-1:2, k, j)
3671
+ end do
3672
+ end do
3673
+ end if
3674
+ if (l1 <= nbd) then
3675
+ do j = 2, iipph
3676
+ jc = iipp2 - j
3677
+ c1(2:ido-1:2,:, j)=ch(2:ido-1:2,:, j)+ch(2:ido-1:2,:, jc)
3678
+ c1(2:ido-1:2,:, jc) = ch(3:ido:2,:, j) - ch(3:ido:2,:, jc)
3679
+ c1(3:ido:2,:, j) = ch(3:ido:2,:, j) + ch(3:ido:2,:, jc)
3680
+ c1(3:ido:2,:, jc) = ch(2:ido-1:2,:, jc) - ch(2:ido-1:2,:, j)
3681
+ end do
3682
+ exit block_construct
3683
+ end if
3684
+ do j = 2, iipph
3685
+ jc = iipp2 - j
3686
+ c1(2:ido-1:2,:, j) = ch(2:ido-1:2,:, j) + ch(2:ido-1:2,:, jc)
3687
+ c1(2:ido-1:2,:, jc) = ch(3:ido:2,:, j) - ch(3:ido:2,:, jc)
3688
+ c1(3:ido:2,:, j) = ch(3:ido:2,:, j) + ch(3:ido:2,:, jc)
3689
+ c1(3:ido:2,:, jc) = ch(2:ido-1:2,:, jc) - ch(2:ido-1:2,:, j)
3690
+ end do
3691
+ exit block_construct
3692
+ end if
3693
+ c2(:, 1) = ch2(:, 1)
3694
+ end block block_construct
3695
+
3696
+ do j = 2, iipph
3697
+ jc = iipp2 - j
3698
+ c1(1,:, j) = ch(1,:, j) + ch(1,:, jc)
3699
+ c1(1,:, jc) = ch(1,:, jc) - ch(1,:, j)
3700
+ end do
3701
+
3702
+ ar1 = ONE
3703
+ ai1 = ZERO
3704
+ do l = 2, iipph
3705
+ lc = iipp2 - l
3706
+ ar1h = dcp*ar1 - dsp*ai1
3707
+ ai1 = dcp*ai1 + dsp*ar1
3708
+ ar1 = ar1h
3709
+ ch2(:, l) = c2(:, 1) + ar1*c2(:, 2)
3710
+ ch2(:, lc) = ai1*c2(:, iip)
3711
+ dc2 = ar1
3712
+ ds2 = ai1
3713
+ ar2 = ar1
3714
+ ai2 = ai1
3715
+ do j = 3, iipph
3716
+ jc = iipp2 - j
3717
+ ar2h = dc2*ar2 - ds2*ai2
3718
+ ai2 = dc2*ai2 + ds2*ar2
3719
+ ar2 = ar2h
3720
+ ch2(:, l) = ch2(:, l) + ar2*c2(:, j)
3721
+ ch2(:, lc) = ch2(:, lc) + ai2*c2(:, jc)
3722
+ end do
3723
+ end do
3724
+
3725
+ do j = 2, iipph
3726
+ ch2(:, 1) = ch2(:, 1) + c2(:, j)
3727
+ end do
3728
+
3729
+ cc(:, 1,:) = ch(:,:, 1)
3730
+ cc(ido, 2:(iipph-1)*2:2,:) = transpose(ch(1,:, 2:iipph))
3731
+ cc(1, 3:iipph*2-1:2,:) = transpose(ch(1,:, iipp2-2:iipp2-iipph:(-1)))
3732
+
3733
+ if(ido /= 1) then
3734
+ if (l1 <= nbd) then
3735
+ cc(2:ido-1:2, 3:iipph*2-1:2,:) = &
3736
+ reshape( &
3737
+ source = ch(2:ido-1:2,:,2:iipph)+ch(2:ido-1:2,:, iipp2-2:iipp2-iipph:(-1)), &
3738
+ shape = [(ido-1)/2, iipph-1, l1], &
3739
+ order = [1, 3, 2] &
3740
+ )
3741
+ cc(idp2-4:idp2-1-ido:(-2), 2:(iipph-1)*2:2,:) = &
3742
+ reshape( &
3743
+ source = ch(2:ido-1:2,:, 2:iipph)-ch(2:ido-1:2,:, iipp2-2:iipp2-iipph:(-1)), &
3744
+ shape = [(ido-1)/2, iipph-1, l1], &
3745
+ order = [1, 3, 2] &
3746
+ )
3747
+ cc(3:ido:2, 3:iipph*2-1:2,:) = &
3748
+ reshape(&
3749
+ source = ch(3:ido:2,:,2:iipph)+ch(3:ido:2,:,iipp2-2:iipp2-iipph:(-1)), &
3750
+ shape = [(ido-1)/2, iipph-1, l1], &
3751
+ order = [1, 3, 2] &
3752
+ )
3753
+ cc(idp2-3:idp2-ido:(-2), 2:(iipph-1)*2:2,:) = &
3754
+ reshape(&
3755
+ source = ch(3:ido:2,:, iipp2-2:iipp2-iipph:(-1))-ch(3:ido:2,:, 2:iipph), &
3756
+ shape = [(ido-1)/2, iipph-1, l1], &
3757
+ order = [1, 3, 2] &
3758
+ )
3759
+ else
3760
+ cc(2:ido-1:2, 3:iipph*2-1:2,:) = &
3761
+ reshape( &
3762
+ source = ch(2:ido-1:2,:, 2:iipph)+ch(2:ido-1:2,:, iipp2-2:iipp2-iipph:(-1)), &
3763
+ shape = [(ido-1)/2, iipph-1, l1], &
3764
+ order = [1, 3, 2] &
3765
+ )
3766
+ cc(idp2-4:idp2-1-ido:(-2), 2:(iipph-1)*2:2,:) = &
3767
+ reshape( &
3768
+ source = ch(2:ido-1:2,:, 2:iipph)-ch(2:ido-1:2,:, iipp2-2:iipp2-iipph:(-1)), &
3769
+ shape = [(ido-1)/2, iipph-1, l1], &
3770
+ order = [1, 3, 2] &
3771
+ )
3772
+ cc(3:ido:2, 3:iipph*2-1:2,:) = &
3773
+ reshape( &
3774
+ source = ch(3:ido:2,:, 2:iipph)+ch(3:ido:2,:, iipp2-2:iipp2-iipph:(-1)), &
3775
+ shape = [(ido-1)/2, iipph-1, l1], &
3776
+ order = [1, 3, 2] &
3777
+ )
3778
+ cc(idp2-3:idp2-ido:(-2), 2:(iipph-1)*2:2,:) = &
3779
+ reshape( &
3780
+ source = ch(3:ido:2,:,iipp2-2:iipp2-iipph:(-1))-ch(3:ido:2,:, 2:iipph), &
3781
+ shape = [(ido-1)/2, iipph-1, l1], &
3782
+ order = [1, 3, 2] &
3783
+ )
3784
+ end if
3785
+ end if
3786
+
3787
+ end subroutine real_forward_pass_n
3788
+
3789
+ end module type_PeriodicFastFourierTransform