24 FourierTransform::FourierTransform() = 
default;
 
   26 FourierTransform::Workspace::Workspace()
 
   27     : h_src(0), w_src(0), h_fftw(0), w_fftw(0), in_src(0), out_fftw(0), p_forw_src(nullptr)
 
   31 FourierTransform::Workspace::~Workspace()
 
   36 void FourierTransform::Workspace::clear()
 
   47         fftw_free((fftw_complex*)out_fftw);
 
   50     if (p_forw_src != 
nullptr)
 
   51         fftw_destroy_plan(p_forw_src);
 
   62     int h_src = 
static_cast<int>(source.size());
 
   63     int w_src = 
static_cast<int>((source.size() ? source[0].size() : 0));
 
   69     fftw_forward_FT(source);
 
   71     double* ptr = ws.out_fftw;
 
   75     result.resize(
static_cast<size_t>(ws.h_fftw),
 
   76                   std::vector<double>(
static_cast<size_t>(ws.w_fftw)));
 
   79     for (
size_t i = 0; i < static_cast<size_t>(ws.h_fftw); i++) {
 
   80         size_t k = 
static_cast<size_t>(ws.h_fftw) - i;
 
   82             k -= 
static_cast<size_t>(ws.h_fftw);
 
   83         for (
size_t j = 0; j < static_cast<size_t>(ws.w_fftw / 2 + 1); j++) {
 
   85             size_t l = 
static_cast<size_t>(ws.w_fftw) - j;
 
   87                 result[k][l] = result[i][j];
 
  100     if (result.size() % 2 == 0)
 
  101         row_shift = result.size() / 2;
 
  103         row_shift = result.size() / 2 + 1;
 
  106     if (result[0].size() % 2 == 0)
 
  107         col_shift = result[0].size() / 2;
 
  109         col_shift = result[0].size() / 2 + 1;
 
  112     std::rotate(result.begin(), result.begin() + 
static_cast<int>(row_shift), result.end());
 
  115     for (
size_t i = 0; i < static_cast<size_t>(ws.h_fftw); i++) {
 
  116         std::rotate(result[i].begin(), result[i].begin() + 
static_cast<int>(col_shift),
 
  128     source2d.push_back(source);
 
  131     fft(source2d, result2d);
 
  133     if (result2d.size() != 1)
 
  136     result = result2d[0];
 
  146     if (result.size() % 2 == 0)
 
  147         col_shift = result.size() / 2;
 
  149         col_shift = result.size() / 2 + 1;
 
  151     std::rotate(result.begin(), result.begin() + 
static_cast<int>(col_shift), result.end());
 
  159     if (!h_src || !w_src) {
 
  160         std::ostringstream os;
 
  161         os << 
"FourierTransform::init() -> Panic! Wrong dimensions " << h_src << 
" " << w_src
 
  173     ws.in_src = 
new double[
static_cast<size_t>(ws.h_fftw * ws.w_fftw)];
 
  174     ws.out_fftw = 
static_cast<double*
>(
 
  175         fftw_malloc(
sizeof(fftw_complex) * 
static_cast<size_t>(ws.h_fftw * (ws.w_fftw / 2 + 1))));
 
  178     ws.p_forw_src = fftw_plan_dft_r2c_2d(ws.h_fftw, ws.w_fftw, ws.in_src,
 
  179                                          (fftw_complex*)ws.out_fftw, FFTW_ESTIMATE);
 
  183     if (ws.p_forw_src == 
nullptr)
 
  185             "FourierTransform::init() -> Error! Can't initialise p_forw_src plan.");
 
  192 void FourierTransform::fftw_forward_FT(
const double2d_t& src)
 
  194     if (ws.h_fftw <= 0 || ws.w_fftw <= 0)
 
  196             "FourierTransform::fftw_forward_FT() -> Panic! Initialisation is missed.");
 
  198     double *ptr, *ptr_end;
 
  201     for (ptr = ws.in_src, ptr_end = ws.in_src + ws.h_fftw * ws.w_fftw; ptr != ptr_end; ++ptr)
 
  205     for (
size_t row = 0; row < static_cast<size_t>(ws.h_src); ++row)
 
  206         for (
size_t col = 0; col < static_cast<size_t>(ws.w_src); ++col)
 
  207             ws.in_src[(
static_cast<int>(row) % ws.h_fftw) * ws.w_fftw
 
  208                       + (
static_cast<int>(col) % ws.w_fftw)] += src[row][col];
 
  211     fftw_execute(ws.p_forw_src);
 
  213     double re_out, im_out;
 
  214     for (ptr = ws.out_fftw, ptr_end = ws.out_fftw + 2 * ws.h_fftw * (ws.w_fftw / 2 + 1);
 
  215          ptr != ptr_end; ++ptr) {
 
  220         *(ptr - 1) = sqrt(re_out * re_out + im_out * im_out);
 
  222         *ptr = atan2(im_out, re_out);
 
Defines many exception classes in namespace Exceptionss.