1 Matrix <-> C/C++ array

1.1 Matrix -> C/C++ array

.data() stores the address, so we can give the address to a pointer.

1.2. C/C++ array -> Matrix

Using Map to convert a C/C++ array to a Matrix.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

int main(int argc, char *argv[]){
    int n;
    n = atoi(argv[1]);
    MatrixXf b(n, 1);
    b = MatrixXf::Random(n, 1);
    cout << "b:\n" << b << endl;
    // convert Matrix b to C/C++ array c.
    float *c;
    c = b.data();

    // convert C/C++ array c to Matrix d.
    MatrixXf d;
    d = Map<MatrixXf>(c, n, 1);
    cout << "d:\n" << d << endl;
    return 0;
}

2 FFT in Eigen3

2.1 Installation

  • First type sudo apt-get install libeigen3-dev to install Eigen3;
  • Eigen3 was installed in the default directory /usr/include/eigen3;
  • Copy unsupported under /usr/include/eigen3 to the directory /usr/include.

2.2 Compared with FFTW3

 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
#include <iostream>
#include <Eigen/Dense>
#include <cstdio>
#include <cstdlib>
#include <fftw3.h>
#include <ctime>
#include <unsupported/Eigen/FFT>

using namespace std;
using namespace Eigen;
//using namespace un

int main(int argc, char *argv[]){
        Eigen::FFT<float> fft;
        int n = atoi(argv[1]);
        MatrixXf input(n, 1);
        input = MatrixXf::Random(n, 1);

        MatrixXcf output(n, 1);
        clock_t t11 = clock();
        //for(int i = 0; i < input.cols(); i ++)
        output.col(0) = fft.fwd(input.col(0));
        /*
        cout << "Input:\n" << input << endl;
        cout << "Output:\n" << endl;
        cout << "Real:\n" << output.real() << endl;
        cout << "Imag:\n" << output.imag() << endl;

        cout << "type:\n" << typeid(input).name() << endl;
        */
        clock_t t12 = clock();
        fftw_complex *in, *out;
        fftw_plan p;
        in = (fftw_complex *) fftw_malloc( sizeof(fftw_complex) * n );
        out = (fftw_complex *) fftw_malloc( sizeof(fftw_complex) * n );
        for(int i = 0; i < n; i ++){
                in[i][0] = input.col(0)[i];
                in[i][1] = 0;
        }
        clock_t t21 = clock();
        p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
        fftw_execute(p);
        fftw_destroy_plan(p);
        clock_t t22 = clock();
        cout << "Time used for Eigen3 FFT: " << ((double)t12-(double)t11)/CLOCKS_PER_SEC << " s!" << endl;
        cout << "Time used for FFT3: " << ((double)t22-(double)t21)/CLOCKS_PER_SEC << " s!" << endl;

        fftw_free(in); fftw_free(out);
        return 0;
}

The efficiency of FFTW is 2 - 3 times of FFT in Eigen3.