29#if defined(RealFFT_RECURSES)
30#error Recursive header files inclusion detected in RealFFT.h
33#define RealFFT_RECURSES
39#ifndef DGTAL_WITH_FFTW3
40 #error You need to have activated FFTW3 (DGTAL_WITH_FFTW3) to include this file.
51#include <boost/math/constants/constants.hpp>
53#include "DGtal/kernel/domains/HyperRectDomain.h"
54#include "DGtal/images/ArrayImageAdapter.h"
55#include "DGtal/kernel/PointVector.h"
65template <
typename TFFTW>
69 typename TFFTW::complex*
apply(
typename TFFTW::complex* ptr ) {
return ptr; }
72 typename TFFTW::complex*
apply( std::complex<typename TFFTW::real>* ptr ) {
return reinterpret_cast<typename TFFTW::complex*
>(ptr); }
82#define FFTW_WRAPPER_GEN(suffix) \
83 using size_t = std::size_t; \
84 using complex = fftw ## suffix ## _complex; \
85 using plan = fftw ## suffix ## _plan; \
86 using self = FFTWWrapper<real>; \
88 static inline void* malloc( size_t n ) noexcept { return fftw ## suffix ## _malloc(n); } \
89 static inline void free( void* p ) noexcept { fftw ## suffix ## _free(p); } \
90 static inline void execute( const plan p ) noexcept { fftw ## suffix ## _execute(p); } \
91 static inline void destroy_plan( plan p ) noexcept { fftw ## suffix ## _destroy_plan(p); } \
93 template < typename C > \
95 plan plan_dft_r2c( int rank, const int* n, real* in, C* out, unsigned flags ) noexcept \
97 return fftw ## suffix ## _plan_dft_r2c(rank, n, in, FFTWComplexCast<self>::apply(out), flags); \
100 template < typename C > \
102 plan plan_dft_c2r( int rank, const int* n, C* in, real* out, unsigned flags ) noexcept \
104 return fftw ## suffix ## _plan_dft_c2r(rank, n, FFTWComplexCast<self>::apply(in), out, flags); \
107 template < typename C > \
109 void execute_dft_r2c( const plan p, real* in, C* out ) noexcept \
111 fftw ## suffix ## _execute_dft_r2c(p, in, FFTWComplexCast<self>::apply(out)); \
114 template < typename C > \
116 void execute_dft_c2r( const plan p, C* in, real* out ) noexcept \
118 fftw ## suffix ## _execute_dft_c2r(p, FFTWComplexCast<self>::apply(in), out); \
125 template < typename C > \
127 plan plan_dft( int rank, const int* n, real* in, C* out, int way, unsigned flags ) noexcept \
129 if ( way == FFTW_FORWARD ) \
130 return plan_dft_r2c( rank, n, in, out, flags ); \
132 return plan_dft_c2r( rank, n, out, in, flags ); \
139 template < typename C > \
141 void execute_dft( const plan p, real* in, C* out, int way ) noexcept \
143 if ( way == FFTW_FORWARD ) \
144 execute_dft_r2c( p, in, out ); \
146 execute_dft_c2r( p, out, in ); \
150template <
typename Real =
double>
154 static_assert( ! std::is_same<Real, float>::value,
"[DGtal::RealFFT] The FFTW3 library for float precision (libfftw3f) has not been found." );
155 static_assert( ! std::is_same<Real, double>::value,
"[DGtal::RealFFT] The FFTW3 library for double precision (libfftw3) has not been found." );
156 static_assert( ! std::is_same<Real, long double>::value,
"[DGtal::RealFFT] The FFTW3 library for long double precision (libfftw3l) has not been found." );
157 static_assert( ! std::is_same<Real, Real>::value,
"[DGtal::RealFFT] Value type not supported." );
160#ifdef DGTAL_WITH_FFTW3_DOUBLE
172#ifdef DGTAL_WITH_FFTW3_FLOAT
184#ifdef DGTAL_WITH_FFTW3_LONG
191 using real =
long double;
216template <
typename TSpace,
typename T>
233 using SpatialImage = ArrayImageAdapter< Real*, Domain >;
235 using FreqImage = ArrayImageAdapter< Complex*, Domain >;
236 using ConstFreqImage = ArrayImageAdapter< const Complex*, Domain >;
275 Self & operator= (
Self && ) =
delete;
442 void doFFT(
unsigned flags = FFTW_ESTIMATE,
int way = FFTW_FORWARD,
bool normalized = false );
459 void forwardFFT(
unsigned flags = FFTW_ESTIMATE );
484 void backwardFFT(
unsigned flags = FFTW_ESTIMATE,
bool normalized = true );
626 getSpatialImage().setValue( getNativeSpatialCoords( aScaledPoint ), aValue );
645 return apply_conj ? std::conj( aScaledValue ) : aScaledValue;
717 operator<< (
std::ostream & out, const RealFFT<TDomain,T> &
object );
723#include "DGtal/math/RealFFT.ih"
730#undef RealFFT_RECURSES
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
Aim: Implements basic operations that will be used in Point and Vector classes.
Point const & getFreqExtent() const noexcept
Real getScaledSpatialValue(RealPoint const &aScaledPoint) const noexcept
Point const & getSpatialExtent() const noexcept
Gets the spatial domain extent.
void forwardFFT(unsigned flags=FFTW_ESTIMATE)
const Domain myFreqDomain
Frequential domain (complex).
void setScaledSpatialValue(RealPoint const &aScaledPoint, Real aValue) noexcept
RealPoint getScaledSpatialExtent() const noexcept
FreqImage getFreqImage() noexcept
ArrayImageAdapter< const Real *, Domain > ConstSpatialImage
Constant spatial image type.
void setScaledFreqValue(RealPoint const &aScaledPoint, Complex aScaledValue) noexcept
const Point mySpatialExtent
Extent of the spatial domain.
const Domain mySpatialDomain
Spatial domain (real).
RealPoint getScaledSpatialLowerBound() const noexcept
SpatialImage getSpatialImage() noexcept
void backwardFFT(unsigned flags=FFTW_ESTIMATE, bool normalized=true)
Domain const & getFreqDomain() const noexcept
Complex calcNativeFreqValue(RealPoint const &aScaledPoint, Complex const &aScaledValue) const noexcept
ArrayImageAdapter< Complex *, Domain > FreqImage
Mutable frequency image type.
PointVector< Space::dimension, Real > RealPoint
Real point type.
RealPoint myScaledSpatialExtent
Extent of the scaled spatial domain.
void createPlan(unsigned flags, int way)
RealFFT< Domain, T > Self
Self type.
std::size_t getPadding() const noexcept
typename Space::Point Point
Point type.
typename Space::Dimension Dimension
Space dimension type.
const Domain myFullSpatialDomain
Full spatial domain (real) including the padding.
void setScaledSpatialExtent(RealPoint const &anExtent) noexcept
void selfDisplay(std::ostream &out) const
Complex * getFreqStorage() noexcept
RealPoint calcScaledFreqCoords(Point const &aPoint) const noexcept
static const constexpr Dimension dimension
Space dimension.
std::complex< Real > Complex
Complex value type.
RealPoint calcScaledSpatialCoords(Point const &aPoint) const noexcept
Point calcNativeFreqCoords(RealPoint const &aScaledPoint, bool &applyConj) const noexcept
Real myScaledFreqMag
Magnitude ratio for the scaled frequency values.
detail::FFTWWrapper< T > FFTW
HyperRectDomain< Space > Domain
Domain type.
RealFFT(Self &&)=delete
Move constructor. Deleted.
Complex getScaledFreqValue(RealPoint const &aScaledPoint) const noexcept
Real * getSpatialStorage() noexcept
ArrayImageAdapter< Real *, Domain > SpatialImage
Mutable spatial image type.
void doFFT(unsigned flags=FFTW_ESTIMATE, int way=FFTW_FORWARD, bool normalized=false)
const Point myFreqExtent
Extent of the frequential domain.
RealPoint myScaledSpatialLowerBound
Lower bound of the scaled spatial domain.
RealFFT(Domain const &aDomain)
Domain const & getSpatialDomain() const noexcept
ArrayImageAdapter< const Complex *, Domain > ConstFreqImage
Constant frequency image type.
bool isValid() const noexcept
void setScaledSpatialLowerBound(RealPoint const &aPoint) noexcept
Complex calcScaledFreqValue(RealPoint const &aScaledPoint, Complex const &aValue) const noexcept
Point calcNativeSpatialCoords(RealPoint const &aScaledPoint) const noexcept
PointVector< dim, Integer > Point
DGtal::Dimension Dimension
detail namespace gathers internal classes and functions.
DGtal is the top-level namespace which contains all DGtal functions and types.
Facility to cast to the complex type used by fftw.
static TFFTW::complex * apply(std::complex< typename TFFTW::real > *ptr)
static TFFTW::complex * apply(typename TFFTW::complex *ptr)
Wrapper to fftw functions depending on value type.