Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
f2cl
f2cl
Commits
4f8b8372
Commit
4f8b8372
authored
Sep 17, 2020
by
Raymond Toy
Browse files
Factor out common routine for getting the wsave entry
parent
54c40a35
Changes
1
Hide whitespace changes
Inline
Side-by-side
packages/fftpack5/fftpack5.lisp
View file @
4f8b8372
...
...
@@ -6,11 +6,13 @@
(
defvar
*wsave-cache*
(
make-hash-table
)
"Cache for different wsave tables. The key is the FFT size; the
value is the wsave table needed by the FFT routines."
)
value is
a
the wsave table needed by the FFT routines."
)
(
defun
convert-rfft
(
x
)
(
declare
(
type
(
simple-array
single-float
(
*
))
x
))
(
let*
((
n
(
length
x
))
"Convert the output of FFTPACK RFFT1F (forward real FFT) into a more
user-friendly format with complex values"
(
declare
(
type
(
simple-array
single-float
(
*
))
x
))
(
let*
((
n
(
length
x
))
(
nhalf
(
floor
(
/
n
2
)))
(
out
(
make-array
(
+
1
nhalf
)
:element-type
'
(
complex
single-float
))))
(
setf
(
aref
out
0
)
(
complex
(
aref
x
0
)
0.0
))
...
...
@@ -24,23 +26,34 @@
(
complex
(
aref
x
(
1-
n
))
0.0
)))
out
))
(
defun
get-wsave-entry
(
n
)
"Get the wsave array and it's length that is needed for computing
the (forward and inverse) FFTs. The value is cached, so if it's the
cache, return it. Otherwise compute a new value and save it in the
cache."
(
let
((
entry
(
gethash
n
*wsave-cache*
)))
(
if
entry
entry
(
let*
((
lensav
(
+
n
4
(
floor
(
log
n
2
))))
(
wsave
(
make-array
lensav
:element-type
'single-float
)))
(
multiple-value-bind
(
ignore-0
ignore-1
ignore-2
ier
)
(
rfft1i
n
wsave
lensav
0
)
(
declare
(
ignore
ignore-0
ignore-1
ignore-2
))
(
unless
(
zerop
ier
)
(
error
"lensav is not big enough"
))
(
setf
(
gethash
n
*wsave-cache*
)
wsave
)
wsave
)))))
(
defun
rfft
(
x
)
(
declare
(
type
(
simple-array
single-float
(
*
))
x
))
;; Initialize the wave table if needed
(
let*
((
n
(
length
x
))
(
lensav
(
+
n
(
floor
(
log
n
2
))
4
))
(
work
(
make-array
n
:element-type
'single-float
)))
(
unless
(
gethash
n
*wsave-cache*
)
(
let*
((
wsave
(
make-array
lensav
:element-type
'single-float
)))
(
multiple-value-bind
(
ignore-0
ignore-1
ignore-2
ier
)
(
rfft1i
n
wsave
lensav
0
)
(
declare
(
ignore
ignore-0
ignore-1
ignore-2
))
(
unless
(
zerop
ier
)
(
error
"lensav is not big enough"
))
(
setf
(
gethash
n
*wsave-cache*
)
wsave
))))
(
work
(
make-array
n
:element-type
'single-float
))
(
wsave
(
get-wsave-entry
n
))
(
lensav
(
length
wsave
)))
(
let
((
ier
(
nth-value
8
(
rfft1f
n
1
x
n
(
gethash
n
*wsave-cache*
)
lensav
work
n
0
))))
(
rfft1f
n
1
x
n
wsave
lensav
work
n
0
))))
(
unless
(
zerop
ier
)
(
error
"rfft1f failed with code ~A"
ier
))
;; If X is the transformed value, then the output from rfftf is:
...
...
@@ -72,21 +85,14 @@
(
declare
(
type
(
simple-array
(
complex
single-float
)
(
*
))
x
))
;; Initialize the wave table if needed
(
let*
((
inv
(
convert-inverse-rfft
x
n
))
(
lensav
(
+
n
(
floor
(
log
n
2
))
4
))
(
work
(
make-array
n
:element-type
'single-float
)))
(
unless
(
gethash
n
*wsave-cache*
)
(
let*
((
wsave
(
make-array
lensav
:element-type
'single-float
)))
(
multiple-value-bind
(
ignore-0
ignore-1
ignore-2
ier
)
(
rfft1i
n
wsave
lensav
0
)
(
declare
(
ignore
ignore-0
ignore-1
ignore-2
))
(
unless
(
zerop
ier
)
(
error
"lensav is not big enough"
))
(
setf
(
gethash
n
*wsave-cache*
)
wsave
))))
(
work
(
make-array
n
:element-type
'single-float
))
(
wsave
(
get-wsave-entry
n
))
(
lensav
(
length
wsave
)))
(
let*
((
ier
(
progn
(
format
t
"converted ~A~%"
inv
)
(
nth-value
8
(
rfft1b
n
1
inv
n
(
gethash
n
*wsave-cache*
)
lensav
work
n
0
)))))
(
rfft1b
n
1
inv
n
wsave
lensav
work
n
0
)))))
(
unless
(
zerop
ier
)
(
error
"rfft1b failed with code ~A"
ier
))
inv
)))
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment