Skip to content

Commit 4cd6ad5

Browse files
committed
Some clean work and update makefile.
1 parent 43d44e3 commit 4cd6ad5

13 files changed

+417
-139
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ make
3030

3131
## Links
3232
[netlib/dfftpack1.0(fftpack4.0)](http://www.netlib.org/fftpack/)
33-
[Documents of fft routines in GNU/gsl based on `netlib/fftpack`](https://www.gnu.org/software/gsl/doc/html/fft.html#)
33+
[Documents of fft routines in GNU/gsl based on `netlib/fftpack`](https://www.gnu.org/software/gsl/doc/html/fft.html#)
3434
[Documents of scipy.fftpack](https://docs.scipy.org/doc/scipy/reference/fftpack.html)

doc/specs/fftpack.md

Lines changed: 116 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ The contents of `wsave` must not be changed between calls of `zfftf` or `zfftb`.
4949
```fortran
5050
program demo_zffti
5151
use fftpack, only: zffti
52-
complex(kind=8) :: x(4)
52+
complex(kind=8) :: x(4) = [1.0, 2.0, 3.0, 4.0]
5353
real(kind=8) :: w(31)
54-
x = [real(kind=8) :: 1.0, 2.0, 3.0, 4.0]
5554
call zffti(4,w)
5655
end program demo_zffti
5756
```
@@ -64,12 +63,9 @@ Computes the forward complex discrete fourier transform (the fourier analysis).
6463
Equivalently, `zfftf` computes the fourier coefficients of a complex periodic sequence.
6564
The transform is defined below at output parameter `c`.
6665

67-
The transform is not normalized. To obtain a normalized transform
68-
the output must be divided by `n`. Otherwise a call of `zfftf`
69-
followed by a call of `zfftb` will multiply the sequence by `n`.
66+
The transform is not normalized. To obtain a normalized transform the output must be divided by `n`. Otherwise a call of `zfftf` followed by a call of `zfftb` will multiply the sequence by `n`.
7067

71-
The array `wsave` which is used by subroutine `zfftf` must be
72-
initialized by calling subroutine `zffti(n,wsave)`.
68+
The array `wsave` which is used by subroutine `zfftf` must be initialized by calling subroutine `zffti(n,wsave)`.
7369

7470
#### Status
7571

@@ -89,7 +85,7 @@ Pure function.
8985
This argument is `intent(in)`.
9086
The length of the `complex` sequence `c`. The method is more efficient when `n` is the product of small primes.
9187

92-
`c`: Shall be a `complex` array.
88+
`c`: Shall be a `complex` and rank-1 array.
9389
This argument is `intent(inout)`.
9490
A `complex` array of length `n` which contains the sequence.
9591
```
@@ -133,17 +129,13 @@ end program demo_zfftf
133129

134130
Unnormalized inverse of `zfftf`.
135131

136-
Computes the backward `complex` discrete fourier
137-
transform (the fourier synthesis). Equivalently, `zfftb` computes
138-
a `complex` periodic sequence from its fourier coefficients.
132+
Computes the backward `complex` discrete fourier transform (the fourier synthesis).
133+
Equivalently, `zfftb` computes a `complex` periodic sequence from its fourier coefficients.
139134
The transform is defined below at output parameter `c`.
140135

141-
The transform is not normalized. to obtain a normalized transform
142-
the output must be divided by `n`. otherwise a call of `zfftf`
143-
followed by a call of `zfftb` will multiply the sequence by `n`.
136+
The transform is not normalized. to obtain a normalized transform the output must be divided by `n`. Otherwise a call of `zfftf` followed by a call of `zfftb` will multiply the sequence by `n`.
144137

145-
The array `wsave` which is used by subroutine `zfftf` must be
146-
initialized by calling subroutine `zffti(n,wsave)`.
138+
The array `wsave` which is used by subroutine `zfftf` must be initialized by calling subroutine `zffti(n,wsave)`.
147139

148140
#### Status
149141

@@ -219,24 +211,20 @@ Pure function.
219211

220212
#### Argument
221213

222-
`x`: Shall be a `complex` array.
214+
`x`: Shall be a `complex` and rank-1 array.
223215
This argument is `intent(in)`.
224216

225217
`n`: Shall be an `integer` scalar.
226218
This argument is `intent(in)` and `optional`.
227-
The needed length of the `complex` sequence `c`.
228-
229-
##### Warning
230-
231-
if `n <= size(x)`, the first `n` elements of `x` will be included in the calculation.
232-
233-
if `n > size(x)`, the all elements of `x` and `n-size(x)` elements filled with zeros will be included in the calculation.
219+
Defines the length of the Fourier transform. If `n` is not specified (the default) then `n = size(x)`. If `n <= size(x)`, `x` is truncated, if `n > size(x)`, `x` is zero-padded.
234220

235221
#### Return value
236222

237-
`fft(x)` returns the Discrete Fourier Transform (DFT) of `x` using the Fast Fourier Transform (FFT) algorithm.
223+
Returns a `complex` and rank-1 array, the Discrete Fourier Transform (DFT) of `x`.
238224

239-
`fft(x, n)` returns `n` point DFT of `x` using the FFT algorithm.
225+
#### Notes
226+
227+
Within numerical accuracy, `x == ifft(fft(x))/size(x)`.
240228

241229
#### Example
242230

@@ -271,35 +259,23 @@ Pure function.
271259

272260
#### Argument
273261

274-
`x`: Shall be a `complex` array.
262+
`x`: Shall be a `complex` and rank-1 array.
275263
This argument is `intent(in)`.
276264

277265
`n`: Shall be an `integer` scalar.
278266
This argument is `intent(in)` and `optional`.
279-
The needed length of the `complex` sequence `c`.
280-
281-
##### Warning
282-
283-
if `n <= size(x)`, the first `n` elements of `x` will be included in the calculation.
284-
285-
if `n > size(x)`, the all elements of `x` and `n-size(x)` elements filled with zeros will be included in the calculation.
267+
Defines the length of the Fourier transform. If `n` is not specified (the default) then `n = size(x)`. If `n <= size(x)`, `x` is truncated, if `n > size(x)`, `x` is zero-padded.
286268

287269
#### Return value
288270

289-
`ifft(x)` returns the inverse Discrete Fourier transform of `x` using the Fast Fourier Transform algorithm..
290-
291-
`ifft(x, n)` returns `n` point inverse DFT of `x` using the FFT algorithm.
271+
Returns a `complex` and rank-1 array, the unnormalized inverse Discrete Fourier Transform (DFT) of `x`.
292272

293273
#### Example
294274

295275
```fortran
296276
program demo_ifft
297277
use fftpack, only: fft, ifft
298-
complex(kind=8) :: x(4)
299-
x = [real(kind=8) :: 1.0, 2.0, 3.0, 4.0]
300-
print *, fft(x) !! [(10.0,0.0), (-2.0,2.0), (-2.0,0.0), (-2.0,-2.0)].
301-
print *, fft(x,3) !! [(6.0,0.0), (-1.5,0.86), (-1.5,0.86)].
302-
print *, fft(x,5) !! [(10.0,0.0), (-4.0,1.3), (1.5,-2.1), (1.5,2.1), (-4.0,1.3)].
278+
complex(kind=8) :: x(4) = [1.0, 2.0, 3.0, 4.0]
303279
print *, ifft(fft(x))/4.0 !! [(1.0,0.0), (2.0,0.0), (3.0,0.0), (4.0,0.0)]
304280
print *, ifft(fft(x), 3) !! [(6.0,2.0), (10.3,-1.0), (13.73,-1.0)]
305281
end program demo_ifft
@@ -335,9 +311,8 @@ The length of the sequence to be transformed.
335311
`wsave`: Shall be a `real` array.
336312
This argument is `intent(out)`.
337313
A work array which must be dimensioned at least `2*n+15`.
338-
The same work array can be used for both `dfftf` and `dfftb`
339-
as long as `n` remains unchanged. Different `wsave` arrays
340-
are required for different values of `n`.
314+
The same work array can be used for both `dfftf` and `dfftb` as long as `n` remains unchanged.
315+
Different `wsave` arrays are required for different values of `n`.
341316

342317
##### Warning
343318

@@ -358,16 +333,12 @@ end program demo_dffti
358333

359334
#### Description
360335

361-
Computes the fourier coefficients of a real
362-
perodic sequence (fourier analysis). The transform is defined
363-
below at output parameter `r`.
336+
Computes the fourier coefficients of a real perodic sequence (fourier analysis).
337+
The transform is defined below at output parameter `r`.
364338

365-
The transform is not normalized. To obtain a normalized transform
366-
the output must be divided by `n`. Otherwise a call of `dfftf`
367-
followed by a call of `dfftb` will multiply the sequence by `n`.
339+
The transform is not normalized. To obtain a normalized transform the output must be divided by `n`. Otherwise a call of `dfftf` followed by a call of `dfftb` will multiply the sequence by `n`.
368340

369-
The array `wsave` which is used by subroutine `dfftf` must be
370-
initialized by calling subroutine `dffti(n,wsave)`.
341+
The array `wsave` which is used by subroutine `dfftf` must be initialized by calling subroutine `dffti(n,wsave)`.
371342

372343
#### Status
373344

@@ -430,7 +401,7 @@ The contents of `wsave` must not be changed between calls of `dfftf` or `dfftb`.
430401
```fortran
431402
program demo_dfftf
432403
use fftpack, only: dffti, dfftf
433-
real(kind=8) :: x(4) = [1,2,3,4]
404+
real(kind=8) :: x(4) = [1, 2, 3, 4]
434405
real(kind=8) :: w(23)
435406
call dffti(4,w)
436407
call dfftf(4,x,w) !! `x` returns [10.0, -2.0, 2.0, -2.0].
@@ -443,17 +414,13 @@ end program demo_dfftf
443414

444415
Unnormalized inverse of `dfftf`.
445416

446-
Computes the backward `real` discrete fourier
447-
transform (the fourier synthesis). Equivalently, `dfftb` computes
448-
a `real` periodic sequence from its fourier coefficients.
417+
Computes the backward `real` discrete fourier transform (the fourier synthesis).
418+
Equivalently, `dfftb` computes a `real` periodic sequence from its fourier coefficients.
449419
The transform is defined below at output parameter `c`.
450420

451-
The transform is not normalized. to obtain a normalized transform
452-
the output must be divided by `n`. otherwise a call of `dfftf`
453-
followed by a call of `dfftb` will multiply the sequence by `n`.
421+
The transform is not normalized. To obtain a normalized transform the output must be divided by `n`. Otherwise a call of `dfftf` followed by a call of `dfftb` will multiply the sequence by `n`.
454422

455-
The array `wsave` which is used by subroutine `dfftf` must be
456-
initialized by calling subroutine `dffti(n,wsave)`.
423+
The array `wsave` which is used by subroutine `dfftf` must be initialized by calling subroutine `dffti(n,wsave)`.
457424

458425
#### Status
459426

@@ -548,16 +515,8 @@ Defines the length of the Fourier transform. If `n` is not specified (the defaul
548515

549516
#### Return value
550517

551-
The returned real array contains:
552-
```
553-
[y(1),Re(y(2)),Im(y(2)),...,Re(y(n/2+1))] if n is even
554-
[y(1),Re(y(2)),Im(y(2)),...,Re(y(n/2+1)),Im(y(n/2+1))] if n is odd
555-
```
556-
where,
557-
```
558-
y(j) = sum[k=1..n] x[k] * exp(-sqrt(-1)*j*k*2*pi/n)
559-
j = 1..n
560-
```
518+
Returns a `real` and rank-1 array, the Discrete Fourier Transform (DFT) of `x`.
519+
561520
#### Notes
562521

563522
Within numerical accuracy, `y == rfft(irfft(y))/size(y)`.
@@ -604,7 +563,7 @@ Defines the length of the Fourier transform. If `n` is not specified (the defaul
604563

605564
#### Return value
606565

607-
The unnormalized inverse discrete Fourier transform.
566+
Returns a `real` and rank-1 array, the unnormalized inverse discrete Fourier transform.
608567

609568
#### Example
610569

@@ -616,3 +575,87 @@ program demo_irfft
616575
print *, irfft(rfft(x), 3) !! [6.0, 8.53, 15.46]
617576
end program demo_irfft
618577
```
578+
579+
## Utility functions
580+
581+
### `fftshift`
582+
583+
#### Description
584+
585+
Rearranges the Fourier transform by moving the zero-frequency component to the center of the array.
586+
587+
#### Status
588+
589+
Experimental.
590+
591+
#### Class
592+
593+
Pure function.
594+
595+
#### Snytax
596+
597+
`result = [[fftpack(module):fftshift(interface)]](x)`
598+
599+
#### Argument
600+
601+
`x`: Shall be a `complex/real` and rank-1 array.
602+
This argument is `intent(in)`.
603+
604+
#### Return value
605+
606+
Returns the `complex/real` and rank-1 Fourier transform by moving the zero-frequency component to the center of the array.
607+
608+
#### Example
609+
610+
```fortran
611+
program demo_fftshift
612+
use fftpack, only: fftshift
613+
complex(kind=8) :: c(5) = [1, 2, 3, 4, 5]
614+
real(kind=8) :: x(5) = [1, 2, 3, 4, 5]
615+
print *, fftshift(c(1:4)) !! [(3.0,0.0), (4.0,0.0), (1.0,0.0), (2.0,0.0)]
616+
print *, fftshift(c) !! [(4.0,0.0), (5.0,0.0), (1.0,0.0), (2.0,0.0), (3.0,0.0)]
617+
print *, fftshift(x(1:4)) !! [3.0, 4.0, 1.0, 2.0]
618+
print *, fftshift(x) !! [4.0, 5.0, 1.0, 2.0, 3.0]
619+
end program demo_fftshift
620+
```
621+
622+
### `ifftshift`
623+
624+
#### Description
625+
626+
Rearranges the Fourier transform with zero frequency shifting back to the original transform output. In other words, `ifftshift` is the result of undoing `fftshift`.
627+
628+
#### Status
629+
630+
Experimental.
631+
632+
#### Class
633+
634+
Pure function.
635+
636+
#### Snytax
637+
638+
`result = [[fftpack(module):ifftshift(interface)]](x)`
639+
640+
#### Argument
641+
642+
`x`: Shall be a `complex/real` and rank-1 array.
643+
This argument is `intent(in)`.
644+
645+
#### Return value
646+
647+
Returns the `complex/real` and rank-1 Fourier transform with zero frequency shifting back to the original transform output.
648+
649+
#### Example
650+
651+
```fortran
652+
program demo_ifftshift
653+
use fftpack, only: fftshift, ifftshift
654+
complex(kind=8) :: c(5) = [1, 2, 3, 4, 5]
655+
real(kind=8) :: x(5) = [1, 2, 3, 4, 5]
656+
print *, ifftshift(fftshift(c(1:4))) !! [(1.0,0.0), (2.0,0.0), (3.0,0.0), (4.0,0.0)]
657+
print *, ifftshift(fftshift(c) ) !! [(1.0,0.0), (2.0,0.0), (3.0,0.0), (4.0,0.0), (5.0,0.0)]
658+
print *, ifftshift(fftshift(x(1:4))) !! [1.0, 2.0, 3.0, 4.0]
659+
print *, ifftshift(fftshift(x)) !! [1.0, 2.0, 3.0, 4.0, 5.0]
660+
end program demo_ifftshift
661+
```

fpm.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ auto-executables = false
1515
auto-tests = false
1616
auto-examples = false
1717

18+
# Original test
1819
[[test]]
1920
name = "tstfft"
2021
source-dir = "test"
2122
main = "tstfft.f"
2223

24+
# `fftpack` fft routines
2325
[[test]]
2426
name = "fftpack_zfft"
2527
source-dir = "test"
@@ -49,3 +51,14 @@ main = "test_fftpack_rfft.f90"
4951
name = "fftpack_irfft"
5052
source-dir = "test"
5153
main = "test_fftpack_irfft.f90"
54+
55+
# `fftpack` utility routines
56+
[[test]]
57+
name = "fftpack_fftshift"
58+
source-dir = "test"
59+
main = "test_fftpack_fftshift.f90"
60+
61+
[[test]]
62+
name = "fftpack_ifftshift"
63+
source-dir = "test"
64+
main = "test_fftpack_ifftshift.f90"

0 commit comments

Comments
 (0)