File indexing completed on 2025-01-18 09:57:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 namespace Eigen {
0011
0012 namespace internal {
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 template <typename T>
0023 inline
0024 T * fftw_cast(const T* p)
0025 {
0026 return const_cast<T*>( p);
0027 }
0028
0029 inline
0030 fftw_complex * fftw_cast( const std::complex<double> * p)
0031 {
0032 return const_cast<fftw_complex*>( reinterpret_cast<const fftw_complex*>(p) );
0033 }
0034
0035 inline
0036 fftwf_complex * fftw_cast( const std::complex<float> * p)
0037 {
0038 return const_cast<fftwf_complex*>( reinterpret_cast<const fftwf_complex*>(p) );
0039 }
0040
0041 inline
0042 fftwl_complex * fftw_cast( const std::complex<long double> * p)
0043 {
0044 return const_cast<fftwl_complex*>( reinterpret_cast<const fftwl_complex*>(p) );
0045 }
0046
0047 template <typename T>
0048 struct fftw_plan {};
0049
0050 template <>
0051 struct fftw_plan<float>
0052 {
0053 typedef float scalar_type;
0054 typedef fftwf_complex complex_type;
0055 fftwf_plan m_plan;
0056 fftw_plan() :m_plan(NULL) {}
0057 ~fftw_plan() {if (m_plan) fftwf_destroy_plan(m_plan);}
0058
0059 inline
0060 void fwd(complex_type * dst,complex_type * src,int nfft) {
0061 if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0062 fftwf_execute_dft( m_plan, src,dst);
0063 }
0064 inline
0065 void inv(complex_type * dst,complex_type * src,int nfft) {
0066 if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0067 fftwf_execute_dft( m_plan, src,dst);
0068 }
0069 inline
0070 void fwd(complex_type * dst,scalar_type * src,int nfft) {
0071 if (m_plan==NULL) m_plan = fftwf_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0072 fftwf_execute_dft_r2c( m_plan,src,dst);
0073 }
0074 inline
0075 void inv(scalar_type * dst,complex_type * src,int nfft) {
0076 if (m_plan==NULL)
0077 m_plan = fftwf_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0078 fftwf_execute_dft_c2r( m_plan, src,dst);
0079 }
0080
0081 inline
0082 void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {
0083 if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0084 fftwf_execute_dft( m_plan, src,dst);
0085 }
0086 inline
0087 void inv2( complex_type * dst,complex_type * src,int n0,int n1) {
0088 if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0089 fftwf_execute_dft( m_plan, src,dst);
0090 }
0091
0092 };
0093 template <>
0094 struct fftw_plan<double>
0095 {
0096 typedef double scalar_type;
0097 typedef fftw_complex complex_type;
0098 ::fftw_plan m_plan;
0099 fftw_plan() :m_plan(NULL) {}
0100 ~fftw_plan() {if (m_plan) fftw_destroy_plan(m_plan);}
0101
0102 inline
0103 void fwd(complex_type * dst,complex_type * src,int nfft) {
0104 if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0105 fftw_execute_dft( m_plan, src,dst);
0106 }
0107 inline
0108 void inv(complex_type * dst,complex_type * src,int nfft) {
0109 if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0110 fftw_execute_dft( m_plan, src,dst);
0111 }
0112 inline
0113 void fwd(complex_type * dst,scalar_type * src,int nfft) {
0114 if (m_plan==NULL) m_plan = fftw_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0115 fftw_execute_dft_r2c( m_plan,src,dst);
0116 }
0117 inline
0118 void inv(scalar_type * dst,complex_type * src,int nfft) {
0119 if (m_plan==NULL)
0120 m_plan = fftw_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0121 fftw_execute_dft_c2r( m_plan, src,dst);
0122 }
0123 inline
0124 void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {
0125 if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0126 fftw_execute_dft( m_plan, src,dst);
0127 }
0128 inline
0129 void inv2( complex_type * dst,complex_type * src,int n0,int n1) {
0130 if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0131 fftw_execute_dft( m_plan, src,dst);
0132 }
0133 };
0134 template <>
0135 struct fftw_plan<long double>
0136 {
0137 typedef long double scalar_type;
0138 typedef fftwl_complex complex_type;
0139 fftwl_plan m_plan;
0140 fftw_plan() :m_plan(NULL) {}
0141 ~fftw_plan() {if (m_plan) fftwl_destroy_plan(m_plan);}
0142
0143 inline
0144 void fwd(complex_type * dst,complex_type * src,int nfft) {
0145 if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0146 fftwl_execute_dft( m_plan, src,dst);
0147 }
0148 inline
0149 void inv(complex_type * dst,complex_type * src,int nfft) {
0150 if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0151 fftwl_execute_dft( m_plan, src,dst);
0152 }
0153 inline
0154 void fwd(complex_type * dst,scalar_type * src,int nfft) {
0155 if (m_plan==NULL) m_plan = fftwl_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0156 fftwl_execute_dft_r2c( m_plan,src,dst);
0157 }
0158 inline
0159 void inv(scalar_type * dst,complex_type * src,int nfft) {
0160 if (m_plan==NULL)
0161 m_plan = fftwl_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0162 fftwl_execute_dft_c2r( m_plan, src,dst);
0163 }
0164 inline
0165 void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {
0166 if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0167 fftwl_execute_dft( m_plan, src,dst);
0168 }
0169 inline
0170 void inv2( complex_type * dst,complex_type * src,int n0,int n1) {
0171 if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
0172 fftwl_execute_dft( m_plan, src,dst);
0173 }
0174 };
0175
0176 template <typename _Scalar>
0177 struct fftw_impl
0178 {
0179 typedef _Scalar Scalar;
0180 typedef std::complex<Scalar> Complex;
0181
0182 inline
0183 void clear()
0184 {
0185 m_plans.clear();
0186 }
0187
0188
0189 inline
0190 void fwd( Complex * dst,const Complex *src,int nfft)
0191 {
0192 get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src),nfft );
0193 }
0194
0195
0196 inline
0197 void fwd( Complex * dst,const Scalar * src,int nfft)
0198 {
0199 get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src) ,nfft);
0200 }
0201
0202
0203 inline
0204 void fwd2(Complex * dst, const Complex * src, int n0,int n1)
0205 {
0206 get_plan(n0,n1,false,dst,src).fwd2(fftw_cast(dst), fftw_cast(src) ,n0,n1);
0207 }
0208
0209
0210 inline
0211 void inv(Complex * dst,const Complex *src,int nfft)
0212 {
0213 get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft );
0214 }
0215
0216
0217 inline
0218 void inv( Scalar * dst,const Complex * src,int nfft)
0219 {
0220 get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft );
0221 }
0222
0223
0224 inline
0225 void inv2(Complex * dst, const Complex * src, int n0,int n1)
0226 {
0227 get_plan(n0,n1,true,dst,src).inv2(fftw_cast(dst), fftw_cast(src) ,n0,n1);
0228 }
0229
0230
0231 protected:
0232 typedef fftw_plan<Scalar> PlanData;
0233
0234 typedef Eigen::numext::int64_t int64_t;
0235
0236 typedef std::map<int64_t,PlanData> PlanMap;
0237
0238 PlanMap m_plans;
0239
0240 inline
0241 PlanData & get_plan(int nfft,bool inverse,void * dst,const void * src)
0242 {
0243 bool inplace = (dst==src);
0244 bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0;
0245 int64_t key = ( (nfft<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1;
0246 return m_plans[key];
0247 }
0248
0249 inline
0250 PlanData & get_plan(int n0,int n1,bool inverse,void * dst,const void * src)
0251 {
0252 bool inplace = (dst==src);
0253 bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0;
0254 int64_t key = ( ( (((int64_t)n0) << 30)|(n1<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1 ) + 1;
0255 return m_plans[key];
0256 }
0257 };
0258
0259 }
0260
0261 }