BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Convolve.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Resolution/Convolve.h
6 //! @brief Defines class Math::Convolve.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifdef SWIG
16 #error no need to expose this header to Swig
17 #endif
18 
19 #ifndef USER_API
20 #ifndef BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
21 #define BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
22 
23 #include <fftw3.h>
24 #include <vector>
25 
26 //! Convolution of two real vectors (in 1D or 2D) using Fast Fourier Transform.
27 //!
28 //! Usage:
29 //! std::vector<double> signal, kernel, result;
30 //! Convolve cv;
31 //! cv.fftconvolve(signal, kernel, result)
32 //!
33 //! Given code rely on code from Jeremy Fix page, http://jeremy.fix.free.fr/spip.php?article15,
34 //! see also "Efficient convolution using the Fast Fourier Transform, Application in C++"
35 //! by Jeremy Fix, May 30, 2011
36 //!
37 //! @ingroup tools_internal
38 class Convolve {
39 public:
40  //! definition of 1d vector of double
41  typedef std::vector<double> double1d_t;
42 
43  //! definition of 2d vector of double
44  typedef std::vector<double1d_t> double2d_t;
45 
46  Convolve();
47 
48  //! convolution modes
49  //! use LINEAR_SAME or CIRCULAR_SAME_SHIFTED for maximum performance
58  };
59 
60  //! convolution in 1D
61  void fftconvolve(const double1d_t& source, const double1d_t& kernel, double1d_t& result);
62 
63  //! convolution in 2D
64  void fftconvolve(const double2d_t& source, const double2d_t& kernel, double2d_t& result);
65 
66  //! prepare arrays for 2D convolution of given vectors
67  void init(int h_src, int w_src, int h_kernel, int w_kernel);
68 
69  //! Sets convolution mode
70  void setMode(EConvolutionMode mode) { m_mode = mode; }
71 
72 private:
73  //! compute circual convolution of source and kernel using fast Fourier transformation
74  void fftw_circular_convolution(const double2d_t& source, const double2d_t& kernel);
75 
76  //! find closest number X>n that can be factorised according to fftw3 favorite factorisation
77  int find_closest_factor(int n);
78 
79  //! if a number can be factorised using only favorite fftw3 factors
80  bool is_optimal(int n);
81 
82  //! Workspace for Fourier convolution.
83 
84  //! Workspace contains input (source and kernel), intermediate and output
85  //! arrays to run convolution via fft; 'source' it is our signal, 'kernel'
86  //! it is our resolution function.
87  //! Sizes of input arrays are adjusted; output arrays are alocated via
88  //! fftw3 allocation for maximum performance.
89  class Workspace {
90  public:
91  Workspace();
92  ~Workspace();
93  void clear();
94  friend class Convolve;
95 
96  private:
97  int h_src, w_src; // size of original 'source' array in 2 dimensions
98  int h_kernel, w_kernel; // size of original 'kernel' array in 2 dimensions
99  // size of adjusted source and kernel arrays (in_src, out_src, in_kernel, out_kernel)
101  //! adjusted input 'source' array
102  double* in_src;
103  //! result of Fourier transformation of source
104  double* out_src;
105  //! adjusted input 'kernel' array
106  double* in_kernel;
107  //! result of Fourier transformation of kernel
108  double* out_kernel;
109  //! result of product of FFT(source) and FFT(kernel)
110  double* dst_fft;
111  int h_dst, w_dst; // size of resulting array
112  int h_offset, w_offset; // offsets to copy result into output arrays
113  fftw_plan p_forw_src;
114  fftw_plan p_forw_kernel;
115  fftw_plan p_back;
116  };
117 
118  //! input and output data for fftw3
120  //! convolution mode
122  std::vector<size_t> m_implemented_factors; // favorite factorization terms of fftw3
123 };
124 
125 #endif // BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
126 #endif // USER_API
Workspace for Fourier convolution.
Definition: Convolve.h:89
double * out_src
result of Fourier transformation of source
Definition: Convolve.h:104
fftw_plan p_back
Definition: Convolve.h:115
double * in_src
adjusted input 'source' array
Definition: Convolve.h:102
double * in_kernel
adjusted input 'kernel' array
Definition: Convolve.h:106
double * dst_fft
result of product of FFT(source) and FFT(kernel)
Definition: Convolve.h:110
fftw_plan p_forw_src
Definition: Convolve.h:113
fftw_plan p_forw_kernel
Definition: Convolve.h:114
double * out_kernel
result of Fourier transformation of kernel
Definition: Convolve.h:108
Convolution of two real vectors (in 1D or 2D) using Fast Fourier Transform.
Definition: Convolve.h:38
EConvolutionMode m_mode
convolution mode
Definition: Convolve.h:121
Workspace ws
input and output data for fftw3
Definition: Convolve.h:119
std::vector< double1d_t > double2d_t
definition of 2d vector of double
Definition: Convolve.h:44
std::vector< size_t > m_implemented_factors
Definition: Convolve.h:122
std::vector< double > double1d_t
definition of 1d vector of double
Definition: Convolve.h:41
Convolve()
Definition: Convolve.cpp:20
EConvolutionMode
convolution modes use LINEAR_SAME or CIRCULAR_SAME_SHIFTED for maximum performance
Definition: Convolve.h:50
@ FFTW_LINEAR_FULL
Definition: Convolve.h:51
@ FFTW_CIRCULAR_SAME_SHIFTED
Definition: Convolve.h:56
@ FFTW_LINEAR_VALID
Definition: Convolve.h:54
@ FFTW_UNDEFINED
Definition: Convolve.h:57
@ FFTW_LINEAR_SAME_UNPADDED
Definition: Convolve.h:52
@ FFTW_CIRCULAR_SAME
Definition: Convolve.h:55
@ FFTW_LINEAR_SAME
Definition: Convolve.h:53
void init(int h_src, int w_src, int h_kernel, int w_kernel)
prepare arrays for 2D convolution of given vectors
Definition: Convolve.cpp:155
void setMode(EConvolutionMode mode)
Sets convolution mode.
Definition: Convolve.h:70
void fftconvolve(const double1d_t &source, const double1d_t &kernel, double1d_t &result)
convolution in 1D
Definition: Convolve.cpp:138
bool is_optimal(int n)
if a number can be factorised using only favorite fftw3 factors
Definition: Convolve.cpp:343
void fftw_circular_convolution(const double2d_t &source, const double2d_t &kernel)
compute circual convolution of source and kernel using fast Fourier transformation
Definition: Convolve.cpp:273
int find_closest_factor(int n)
find closest number X>n that can be factorised according to fftw3 favorite factorisation
Definition: Convolve.cpp:328