How to do FFT on MatrixXd in Eigen? - c++

It seems the code below is correct:
#include <Eigen/Core>
#include <unsupported/Eigen/FFT>
int main ()
{
Eigen::FFT<float> fft;
Eigen::Matrix<float, dim_x, dim_y> in = setMatrix();
Eigen::Matrix<complex<float>, dim_x, dim_y> out;
for (int k = 0; k < in.rows(); k++) {
Eigen::Matrix<complex<float>, dim_x, 1> tmpOut;
fft.fwd(tmpOut, in.row(k));
out.row(k) = tmpOut;
}
for (int k = 0; k < in.cols(); k++) {
Eigen::Matrix<complex<float>, 1, dim_y> tmpOut;
fft.fwd(tmpOut, out.col(k));
out.col(k) = tmpOut;
}
}
But this must specify the size of matrix in compile time, when I change the Matrix to MatrixXd, this has error when compiling. I want to know how could I do FFT on MatrixXd so I could specify the matrix size when it is running.

Change all your variables to Eigen::Dynamic size instead of hard coding them and it should work. Or, use the built-in types as such:
#include <Eigen/Core>
#include <unsupported/Eigen/FFT>
int main ()
{
size_t dim_x = 28, dim_y = 126;
Eigen::FFT<float> fft;
Eigen::MatrixXf in = Eigen::MatrixXf::Random(dim_x, dim_y);
Eigen::MatrixXcf out;
out.setZero(dim_x, dim_y);
for (int k = 0; k < in.rows(); k++) {
Eigen::VectorXcf tmpOut(dim_x);
fft.fwd(tmpOut, in.row(k));
out.row(k) = tmpOut;
}
for (int k = 0; k < in.cols(); k++) {
Eigen::VectorXcf tmpOut(dim_y);
fft.fwd(tmpOut, out.col(k));
out.col(k) = tmpOut;
}
return 0;
}

Related

Define matrices in an array element C++

I have written some c++ code that receives a Matrix as input and now I want to create a 2D array with matrices in each element so that I can send the individual matrices to the function.
typedef vector< vector > Matrix;
double a[2][2] = Matrix(2, vector(2));
so that each element of a is a 2x2 Matrix.
The reason I don't want to just create a 4D array with vectors is that I want to keep all of the original functions that I have already created with matrices as input.
Any way this is possible?
Here is a simple example code...
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <vector>
typedef vector< vector > Matrix;
void test2D_array(int l, int m, Matrix &a, Matrix &b) {
int R = l - 1;
for (int i = 0; i < m+1; i++) {
b[l - 1][i] = a[l][i];
b[l - 2][i] = (l - 1) * a[l - 1][i];
for (int k = R-1; k > 0; k--) {
b[k - 1][i] = b[k + 1][i] + a[k][i];
}
}
}
int main(void) {
Matrix a(2, vector<double>(2));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = 1;
}
}
Matrix b(2, vector<double>(2));
test2D_array(2, 2, a, b);
// What I want to accomplish...
// Matrix a[2][2] = Matrix((2, vector<double>(2)); i.e. 4D array with each element a 2x2 matrix
// for (int i = 0; i < 2; i++) {
// for (int j = 0; j < 2; j++) {
// test2D_array(2, 2, a[i][j], b);
// }
//}
//
return 0;
}

Return matrix from function with variable lenght

I want to return the matrix from the function, but I can't find a way how. I've found some ways, but they can't be used for VLA. I've read about using std::vector, but that also didn't work.
int gengrid(int gridsize)
{
gridsize = 10 - 1;
int grid[gridsize+3][gridsize+3];
srand(time(NULL));
int count = 0;
std::fill_n(grid[0], 12, 0);
for(int i = 1; i < gridsize + 2; i++)
{
grid[i][0] = 0;
for(int j = 1; j < gridsize + 2; j++)
{
grid[i][j] = rand()%2;
}
grid[i][gridsize+2] = 0;
}
std::fill_n(grid[gridsize+2], gridsize + 3, 0);
return grid;
}
Okay, I found out my solution.
I initialize vector matrix with
static std::vector<std::vector<int>> grid(gridsize+3, std::vector<int>(gridsize+3));
which sets 0 by default for all elements.
(honestly, I don't know, how it's working, maybe somebody would comment explanation of this behavior.)
Complete code here:
#include <iostream>
#include <time.h>
#include <vector>
std::vector<std::vector<int>> gengrid(int gridsize)
{
gridsize = 10 - 1;
static std::vector<std::vector<int>> grid(gridsize+3, std::vector<int>(gridsize+3));//[gridsize+3][gridsize+3];
srand(time(NULL));
int count = 0;
for(int i = 1; i < gridsize + 2; i++)
{
grid[i][0] = 0;
for(int j = 1; j < gridsize + 2; j++)
{
grid[i][j] = rand()%2;
}
grid[i][gridsize+2] = 0;
}
return grid;
}
int main()
{
std::vector<std::vector<int>> grid = gengrid(10);
for(int i = 0; i < 9 + 3; i++)
{
for(int j = 0; j < 9 + 3; j++)
{
std::cout << grid[i][j];
}
std::cout << std::endl;
}
return 0;
}

Error when executing 2D dft using different row,col size with FFTW

I'm studying FFTW and My code was stopped on fftw_plan_dft_2d.
Here is my flow.
I flattened my 2d complex array into 1d fftw_complex array.
Hand over this array to 'FFT' which has fftw function.
It is run okay When I run this with width : 10, height : 10.
But I got error when I run this with different width and height like width : 10, height : 12.
When I run this, it just stopped with -1073740940 CODE.
So run again with debug mode, it stopped in below line
forward = fftw_plan_dft_2d(width, height, fftData_in, fftData_out, FFTW_FORWARD, FFTW_ESTIMATE);
I think my code has no problem and also c2c has no problem with different nx,ny size.
Could you guys help me with your knowledge?
#include "fftw3.h"
#include <math.h>
#include <complex>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
fftw_complex* FFT(double** data_Y, int t_height, int t_width)
{
int i, j, height, width;
height = t_height;
width = t_width;
fftw_complex *fftData_in;
fftw_complex *fftData_out;
fftData_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * height*width); // input buffer
fftData_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * height*width); // output buffer
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
fftData_in[i*height + j][0] = data_Y[i][j];
fftData_in[i*height + j][1] = 0;
fftData_out[i*height + j][0] = 0;
fftData_out[i*height + j][1] = 0;
}
}
fftw_plan forward;
forward = fftw_plan_dft_2d(width, height, fftData_in, fftData_out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(forward);
fftw_destroy_plan(forward);
fftw_free(fftData_in);
return fftData_out;
}
int main()
{
int m_height = 10;
int m_width = 5;
double ** data_Y = new double*[m_height];
for (int i = 0; i < m_height; i++) {
data_Y[i] = new double[m_width];
}
for (int i = 0; i < m_height; i++) {
for (int j = 0; j < m_width; j++) {
data_Y[i][j] = j + 1;
}
}
for (int i = 0; i < m_height; i++) {
for (int j = 0; j < m_width; j++) {
printf("[%f]",data_Y[i][j]);
}
printf("\n");
}
//FFT
fftw_complex *fftData = FFT(data_Y, m_height, m_width);
printf("============================REAL=======================\n");
for (int i = 0; i < m_height; i++) {
for (int j = 0; j < m_width; j++) {
printf("[%.5f]", fftData[i*m_height + j][0]);
}
printf("\n");
}
printf("============================IMAG===========================\n");
for (int i = 0; i < m_height; i++) {
for (int j = 0; j < m_width; j++) {
printf("[%.5f]", fftData[i*m_height + j][1]);
}
printf("\n");
}
return 0;
}

Convert arma::cx_mat to array of arrays

How do I convert a arma::cx_mat to an array of arrays?
The motivation for the conversion is to use libmatio, which is a C library, to output a .mat file.
So far I have created a function to convert from arma:cx_mat to a vector of vectors:
std::vector<std::vector<double>> mat_to_vv(arma::cx_mat &M)
{
std::vector<std::vector<double>> vv(M.n_rows);
for(size_t i=0; i<M.n_rows; ++i)
{
vv[i] = arma::conv_to<std::vector<double>>::from(M.row(i));
};
return vv;
}
If you need convert real part from cx_mat into C array of arrays can use this function:
double** mat_to_carr(arma::cx_mat &M,std::size_t &n,std::size_t &m)
{
const std::size_t nrows = M.n_rows;
const std::size_t ncols = M.n_cols;
double **array = (double**)malloc(nrows * sizeof(double *));
for(std::size_t i = 0; i < nrows; i++)
{
array[i] = (double*)malloc(ncols * sizeof(double));
for (std::size_t j = 0; j < ncols; ++j)
array[i][j] = M(i + j*ncols).real();
}
n = nrows;
m = ncols;
return array;
}
Note, need free the array when it is no longer needed.
Example:
int main()
{
cx_mat X(5, 5, fill::randn);
std::size_t n,m;
auto array = mat_to_carr(X,n,m);
for (std::size_t i = 0; i < n; ++i)
{
for (std::size_t j = 0; j < m; ++j)
std::cout<<array[i][j]<<" ";
std::cout<<std::endl;
}
for(std::size_t i = 0; i < n; i++)
free(array[i]);
free(array);
return 0;
}

dealing with emxArray_real_T data in C++

I have converted a piece of code to C++ using Matlab and now have them in MSVC++.
My function: myFunction gets two inputs and has one output. Following, I tried to make the inputs, a, b, and allocate the output, but I got this error: error C3861: 'emxCreate_real_T': identifier not found
The function prototype looks like this, which in essence is C = A + B:
#include "myTestFunction.h"
#include "myTestFunction_emxutil.h"
void myTestFunction(const emxArray_real_T *A, const emxArray_real_T *B,
emxArray_real_T *C)
{
int i0;
int loop_ub;
i0 = C->size[0] * C->size[1];
C->size[0] = A->size[0];
C->size[1] = A->size[1];
emxEnsureCapacity((emxArray__common *)C, i0, (int)sizeof(double));
loop_ub = A->size[0] * A->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
C->data[i0] = A->data[i0] + B->data[i0];
}
}
and here is my main function:
int main() {
double a[3][3];
double b[2][2];
double result[4][4] = {};
emxArray_real_T *inpA, *inpB, *outp;
// define input matrix
double p = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++){
a[i][j] = p;
p = p + 1;
}
}
double k = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
b[i][j] = k;
k = k + 1;
}
}
inpA = emxCreateWrapper_real_T(*a, 3, 3);
inpB = emxCreateWrapper_real_T(*b, 2, 2);
outp = emxCreateWrapper_real_T(*result, 4, 4);
//inpA = emxCreate_real_T(a, 3, 3);
//inpB = emxCreate_real_T(b, 2, 2);
//outp = emxCreate_real_T(result, 4, 4);
myTestFunction(inpA, inpB, outp);
//print result
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
cout << outp[i].data[j] << endl;
}
return 0;
}
How should I declare the inputs and output?
You're missing an include file. Based on the link you provided in your comment, there is probably a myTestFunction_emxAPI.h file that needs to be included.
Also, I see that the b[2][2] array that you created is being accessed beyond its bounds by the for (int i = 0; i < 3; i++)' andfor (int j = 0; j < 3; j++)` loops.