File: FourierTransform.h

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (103 lines) | stat: -rw-r--r-- 3,947 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Base/Math/FourierTransform.h
//! @brief     Defines class Math::FourierTransform.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2015
//! @authors   Scientific Computing Group at MLZ Garching
//
//  ************************************************************************************************

#ifdef SWIG
#error no need to expose this header to Swig
#endif // SWIG
#ifndef BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H
#define BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H

#include "Base/Type/Field2D.h"
#include <fftw3.h>

//! Fourier transform of vectors (in 1D or 2D) using Fast Fourier Transform (fftw package).
class FourierTransform {
public:
    FourierTransform();

    // forward transform
    std::vector<complex_t> rfft(const std::vector<double>& src);
    complex2d_t rfft(const double2d_t& src);

    // forward transform with real-valued amplitudes in output
    std::vector<double> ramplitude(const std::vector<double>& src);
    double2d_t ramplitude(const double2d_t& src);

    // backward transform
    std::vector<double> irfft(const std::vector<complex_t>& src, int w_src);
    double2d_t irfft(const complex2d_t& src, int w_real);

    // Frequency shifts are useful for providing different representations of spectrum: with lowest
    // frequency at edges of array (default output of fft) or with lowest frequency in center of
    // array

    // shift low frequency from corners to center
    static std::vector<double> fftshift(const std::vector<double>& src);
    static std::vector<complex_t> fftshift(const std::vector<complex_t>& src);
    static double2d_t fftshift(const double2d_t& src);
    static complex2d_t fftshift(const complex2d_t& src);

    // shift low frequency from center to corners
    static std::vector<double> ifftshift(const std::vector<double>& src);
    static std::vector<complex_t> ifftshift(const std::vector<complex_t>& src);
    static double2d_t ifftshift(const double2d_t& src);
    static complex2d_t ifftshift(const complex2d_t& src);

private:
    // prepare arrays and workspaces for FT
    void init(int h, int w_real);
    void init_r2c(int h, int w_real);
    void init_c2r(int h, int w_real);

    // convert FT output to the 2D vector
    complex2d_t rfft2complex_vec() const;
    double2d_t irfft2double_vec() const;

    // convert complex FT to the real amplitudes
    double2d_t fft2amp(complex2d_t& source) const;

    // compute forward/backward FT of source using Fast Fourier transformation from fftw
    void fftw_forward_FT(const double2d_t& src) const;
    void fftw_backward_FT(const complex2d_t& src) const;

    //! Workspace for Fourier Transform.

    //! Workspace contains input, intermediate and output
    //! arrays to run FT via fft; 'real' is our signal
    //! Output arrays are allocated via fftw3 allocation for maximum performance.
    class Workspace {
    public:
        Workspace() = default;
        ~Workspace();
        void clear();
        friend class FourierTransform;

    private:
        //! Here, h = height (# rows), w = width (# columns)
        int h{0};      // height of input AND output arrays in 2D
        int w_real{0}; // size of input (r2c) or output (c2r) real-valued array in 2D
        int w_fftw{0}; // size of output (r2c) or input (c2r) 'complex-valued FT' array in 2D

        double* arr_real{nullptr}; // pointer to input/output real-valued array
        double* arr_fftw{nullptr}; // pointer to input/output 'complex-valued FT' array

        fftw_plan p_forw{nullptr};
        fftw_plan p_back{nullptr};
    };

    //! input and output data for fftw3
    Workspace ws;
};

#endif // BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H