NAME
Math::FFT::Libfftw3 - An interface to libfftw3.
SYNOPSIS
use v6;
use Math::FFT::Libfftw3::C2C;
use Math::FFT::Libfftw3::Constants; # needed for the FFTW_BACKWARD constant
my @in = (0, π/100 … 2*π)».sin;
put @in».Complex».round(10⁻¹²); # print the original array as complex values rounded to 10⁻¹²
my Math::FFT::Libfftw3::C2C $fft .= new: data => @in;
my @out = $fft.execute;
put @out; # print the direct transform output
my Math::FFT::Libfftw3::C2C $fftr .= new: data => @out, direction => FFTW_BACKWARD;
my @outr = $fftr.execute;
put @outr».round(10⁻¹²); # print the backward transform output rounded to 10⁻¹²
use v6;
use Math::FFT::Libfftw3::C2C;
use Math::FFT::Libfftw3::Constants; # needed for the FFTW_BACKWARD constant
# direct 2D transform
my Math::FFT::Libfftw3::C2C $fft .= new: data => 1..18, dims => (6, 3);
my @out = $fft.execute;
put @out;
# reverse 2D transform
my Math::FFT::Libfftw3::C2C $fftr .= new: data => @out, dims => (6,3), direction => FFTW_BACKWARD;
my @outr = $fftr.execute;
put @outr».round(10⁻¹²);
For more examples see the example
directory.
Description
Math::FFT::Libfftw3 provides an interface to libfftw3 and allows you to perform Fast Fourier Transforms.
Documentation
new(:@data!, :@dims?, Int :$direction? = FFTW_FORWARD, Int :$flag? = FFTW_ESTIMATE, Int :$dim?, Int :$thread? = NONE, Int :$nthreads? = 1)
new(:$data!, Int :$direction? = FFTW_FORWARD, Int :$flag? = FFTW_ESTIMATE, Int :$dim?, Int :$thread? = NONE, Int :$nthreads? = 1)
The first constructor accepts any Positional of type Int, Rat, Num, Complex (and IntStr, RatStr, NumStr, ComplexStr);
it allows List of Ints, Array of Complex, Seq of Rat, shaped arrays of any base type, etc.
The only mandatory argument is @data.
Multidimensional data are expressed in row-major order (see the C Library Documentation)
and the array @dims must be passed to the constructor, or the data will be interpreted as a 1D array.
If one uses a shaped array, there's no need to pass the @dims array, because the dimensions will be read
from the array itself.
The $direction parameter is used to specify a direct or backward transform; it defaults to FFTW_FORWARD
.
The $flag parameter specifies the way the underlying library has to analyze the data in order to create a plan
for the transform; it defaults to FFTW_ESTIMATE
(see the C Library Documentation).
The $dim parameter asks for an optimization for a specific matrix rank. The parameter is optional and if present
must be in the range 1..3.
The $thread parameter specifies the kind of threaded operation one wants to get; this argument is optional and if
not specified is assumed as NONE.
There are three possibile values:
THREAD will use specific POSIX thread library while OPENMP will select an OpenMP library.
The $nthreads specifies the number of threads to use; it defaults to 1.
The second constructor accepts a scalar: an object of type Math::Matrix (if that module is installed, otherwise
it returns a Failure); the meaning of all the other parameters is the same as in the other constructor.
execute(Int :$output? = OUT-COMPLEX --> Positional)
Executes the transform and returns the output array of values as a normalized row-major array.
The parameter $output can be optionally used to specify how the array is to be returned:
- OUT-COMPLEX
- OUT-REIM
- OUT-NUM
The default (OUT-COMPLEX) is to return an array of Complex.
OUT-REIM makes the execute
method return the native representation of the data: an array of couples of
real/imaginary values.
OUT-NUM makes the execute
method return just the real part of the complex values.
Attributes
Some of this class' attributes are readable:
- @.out
- $.rank
- @.dims
- $.direction
- @.kind (available only in the R2R transform)
- $.dim (used when a specialized tranform has been requested)
- $.flag (how to compute a plan)
- $.adv (normal or advanced interface)
- $.howmany (only for the advanced interface)
- $.istride (only for the advanced interface)
- $.ostride (only for the advanced interface)
- $.idist (only for the advanced interface)
- $.odist (only for the advanced interface)
- @.inembed (only for the advanced interface)
- @.onembed (only for the advanced interface)
- $.thread (only for the threaded model)
Wisdom interface
This interface allows to save and load a plan associated to a transform (There are some caveats.
See C Library Documentation).
plan-save(Str $filename --> True)
Saves the plan into a file. Returns True if successful and a Failure object otherwise.
plan-load(Str $filename --> True)
Loads the plan From a file. Returns True if successful and a Failure object otherwise.
Advanced interface
This interface allows to compose several transformations in one pass.
See C Library Documentation.
advanced(Int $rank!, @dims!, Int $howmany!, @inembed!, Int $istride!, Int $idist!, @onembed!, Int $ostride!, Int $odist!)
This method activates the advanced interface. The meaning of the arguments are detailed in the
C Library Documentation.
This method returns self
, so it can be concatenated to the .new()
method:
my $fft = Math::FFT::Libfftw3::C2C.new(data => (1..30).flat)
.advanced: $rank, @dims, $howmany,
@inembed, $istride, $idist,
@onembed, $ostride, $odist;
The interface for the R2C transform is slightly different.
In particular:
- in the
execute
method, when performing the reverse transform, the output array has only real values, so the :$output
parameter is ignored.
See the pod
documentation inside the module for further details.
This module implements several R2R transforms.
The major difference is that the constructor has a new $kind
argument, which specifies the kind of trasform that
will be performed on the input data.
See the pod
documentation inside the module for further details.
C Library documentation
For more details on libfftw see the FFTW home.
The manual is available here.
Prerequisites
This module requires the libfftw3 library to be installed. Please follow the instructions below based on your platform:
Debian Linux
sudo apt-get install libfftw3-double3
The module looks for a library called libfftw3.so.
Installation
To install it using zef (a module management tool):
$ zef update
$ zef install Math::FFT::Libfftw3
Testing
To run the tests:
$ prove -e "raku -Ilib"
Notes
Math::FFT::Libfftw3 relies on a C library which might not be present in one's
installation, so it's not a substitute for a pure Raku module.
If you need a pure Raku module, Math::FourierTransform works just fine.
This module needs Raku ≥ 2018.09 only if one wants to use shaped arrays as input data. An attempt to feed a shaped
array to the new
method using $*RAKU.compiler.version < v2018.09
results in an exception.
TODO
There are some alternative interfaces to implement:
- The guru interface to apply the same plan to different data.
- The distributed-memory interface, for parallel systems supporting the MPI message-passing interface.
Author
Fernando Santagata
Copyright and license
The Artistic License 2.0