Error mapping fftw complex to Eigen matrix - c++

I have the following code where I am using both libraries Eigen and FFTW in C++. I am aware of the unsuported FFT that Eigen has, but I am using the FFTW library for additional features. So, I am trying to take the FFT with a C++ array and then map the output to a complex Eigen matrix (to perform some linear algebra operations on it). I have the code:
struct cplx_buffer
{
fftw_complex* a;
int rows;
int cols;
fftw_complex& operator()(int i, int j) const { return a[i * cols + j]; }
};
struct real_buffer
{
double* a;
int rows;
int cols;
double& operator()(int i, int j) const { return a[i * cols + j]; }
};
int main(){
static const int nx = 10;
static const int ny = 10;
static const int nyk = ny/2 + 1;
static const int mm = nx* 3/2;
cplx_buffer outW = my_fftw_allocate_cplx((ny+1), mm);
real_buffer inW = my_fftw_allocate_real((ny+1), mm);
//initialize the input
for (int i = 0; i < ny+1; i++){
for (int j = 0; j < mm; j++){
inW(i,j) = //expression
}
}
//Take FFT of rows
{ // Transform all the rows
fftw_execute(fftw_plan_many_dft_r2c(1, &nx, inW.rows, inW.a, &inW.cols, 1, inW.cols, outW.a, &inW.cols, 1, outW.cols, FFTW_ESTIMATE));
}
Eigen::Map<Eigen::MatrixXcd, Eigen::Unaligned> invnek(*reinterpret_cast<fftw_complex*>(&outW),(ny+1),mm); //ERROR
}
The error:
no instance of constructor "Eigen::Map<PlainObjectType, MapOptions, StrideType>::Map [with PlainObjectType=Eigen::MatrixXcd, MapOptions=0, StrideType=Eigen::Stride<0, 0>]" matches the argument list
How can I reinterpret_cast here correctly?

Related

I keep getting the errors no match for 'operator[]', 'A', 'J' and 'N' were not declared in my code. what is the problem with it? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 months ago.
Improve this question
This is the code for my matrix class
The goal here was to Complete the member functions 'void Matrix::add(const Matrix &), void Matrix::mul(double),
void Matrix::mul(const Matrix &), void Matrix::tr(void), and void Matrix::eye(int)'
of the Matrix class in the header file file matrix class
but as soon as I completed that my code started giving me errors and will not run. I am not sure what the problem is.
#ifndef MATRIX_H_
#define MATRIX_H_
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
#define ROW_MAX 10
#define COL_MAX 10
// In the following, the matrix object is referred to as A,
// upper case letters denote matrices,
// and lover case letters denote scalars.
class Matrix
{
public:
Matrix(int m_, int n_, double v_) : m(m_), n(n_) { fill(v_); }; // constructor for an m_ x n_ matrix A initialized to v_
Matrix(int m_, int n_) : Matrix(m_, n_, 0.0) {} // constructor for an m_ x n_ matrix A initialized to 0.0
Matrix(int m_) : Matrix(m_, m_) {} // constructor for an m_ x m_ matrix A initialized to 0.0
Matrix() : Matrix(0) {} // constructor for a 0 x 0 matrix A (empty matrix)
Matrix(const Matrix &A_) { set(A_); } // copy constructor
void from_str(const string &str_); // reads in m, n, and the matrix elements from the string str_ in the format of "m n A[0][0] A[0][1]...A[m-1][n-1]"
string to_str(void); // returns the string representation of A in the format of "m n A[0][0] A[0][1]...A[m-1][n-1]"
int getRows(void) const; // returns the number of rows
int getCols(void) const; // returns the number of columns
double get(int i_, int j_) const; // returns A[i_][j_]
void set(int i_, int j_, double v_); // sets A[i_][j_] to v_ (A[i_][j_] = v_)
void set(const Matrix &A_); // sets A to A_ (A = A_)
void add(const Matrix &A_); // adds A_ to A (A := A + A_)
void mul(double v_); // multiplies A by the scalar v_ (A := v_ A)
void mul(const Matrix &A_); // multiplies A by A_ (A := A A_)
void tr(void); // sets A to its transpose (A := A^T)
void eye(int m_); // sets A to the m_ x m_ identity matrix (A := I)
private:
int m; // the number of rows
int n; // the number of cols
void setRows(int m_); // sets the number of rows to m_
void setCols(int n_); // sets the number of columns to n_
double data[ROW_MAX][COL_MAX]; // holds the matrix data as 2D array
void fill(double v_); // fills the matrix with v_
};
void Matrix::fill(double v_)
{
for (int i = 0; i < getRows(); i++)
{
for (int j = 0; j < getCols(); j++)
{
set(i, j, v_);
}
}
}
void Matrix::from_str(const string &str_)
{
istringstream stream(str_);
int m_ = 0, n_ = 0;
stream >> m_;
stream >> n_;
setRows(m_);
setCols(n_);
int i = 0, j = 0;
double v_;
while (stream >> v_)
{
set(i, j, v_);
j += 1;
if (j == getCols())
{
i = i + 1;
j = 0;
}
if (i == getRows())
{
break;
}
}
}
string Matrix::to_str(void)
{
ostringstream _stream("");
_stream << getRows() << " " << getCols();
for (int i = 0; i < getRows(); i++)
{
for (int j = 0; j < getCols(); j++)
{
_stream << " " << fixed << defaultfloat << get(i, j);
}
}
return _stream.str();
}
int Matrix::getRows(void) const
{
return m;
}
int Matrix::getCols(void) const
{
return n;
}
void Matrix::setRows(int m_)
{
m = m_;
}
void Matrix::setCols(int n_)
{
n = n_;
}
double Matrix::get(int i_, int j_) const
{
return data[i_][j_];
}
void Matrix::set(int i_, int j_, double v_)
{
data[i_][j_] = v_;
}
void Matrix::set(const Matrix &A_)
{
setRows(A_.getRows());
setCols(A_.getCols());
for (int i = 0; i < getRows(); i++)
{
for (int j = 0; j < getCols(); j++)
{
set(i, j, A_.get(i, j));
}
}
}
void Matrix::add(const Matrix &A_)
{
int r = getRows();
int c = getCols();
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
A_[i][j] = A_[i][j] + A_[i][j];
}
}
}
void Matrix::mul(double v_)
{
int r = getRows();
int c = getCols();
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
A[i][j] = v_ * A[i][j];
}
}
}
void Matrix::mul(const Matrix &A_)
{
int r = getRows();
int c = getCols();
int result[r][c];
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
result[i][j] = 0;
for (int k = 0; k < r; k++)
{
result[i][j] += A[i][k] * A_[k][j];
}
}
}
}
void Matrix::tr(void)
{
int r = getRows();
int c = getCols();
int result[r][c];
for (int i = 0; i < N; i++)
{
for (intj = 0; j < N; j++)
{
result[i][j] = A[j][i];
}
}
}
void Matrix::eye(int m_)
{
int r = getRows();
int c = getCols();
for (int row = 0; row < m_; row++)
{
for (int col = 0; col < m_; col++)
{
if (row == col)
A[row][col] = 1;
else
A[row][col] = 0;
}
}
}
#endif
There's quite a few problems in your code. For example, in 'add', you have the following:
A_[i][j] = A_[i][j] + A_[i][j];
However, A_ is const, so you can't be modifying its data. Further, the Matrix class does not have an operator[], so you can't use A_[i] in the first place. You likely want the following:
data[i][j] = A_.data[i][j] + A_.data[i][j];
In your mul(double v_) function, you have the following line:
A[i][j] = v_ * A[i][j];
Again, there is no operator[] for your matrix, so it's not valid. Further, this function does not even have an A defined. You want to deal with the data directly.
data[i][j] = v_ * data[i][j];
In the mul(const Matrix &A_) you again have similar issues with using [], and again you have an A instead of A_. There's other issues in this function, such as not using the result after you've done the calculations.
In the tr function, you have intj instead of int j, and you're using a variable N which is not defined.
The function eye references the variable A which, again, never defined. You want data.
Using an IDE, or even an online compiler like godbolt, points out exactly where every one of these errors are. You can see here a fixed version of the code, though this doesn't fix any logic errors, just the syntax ones.

CTPL C++ threadpooling datarace on accessing array's elements

Does accessing the same array's different elements create a data race?
I have a "Matrix" wrapper class for an array with matrix interface, and i wrote a parallel multiplication by a scalar function for it.
I use CTPL library for thread pools.
I know that writing from a thread into an array cell passed by reference is not a data race (please correct me if i'm wrong) so i decided to pass a cell from the array to the function so i can write multiplication result into the cell itself, not by passing the reference to an array and the index, so i can avoid a data race.
I ran the function 10k times and the results did not differ even once, but a sanitizer i use ("-fsanitize=thread -fPIE -pie -g" in Cmake flags) still alerts me of a data race on the line where i create the thread pool.
Is the sanitizer mistaken or am i really experiencing a data race somewhere?
Here are the pieces of code, relevant to the prolem:
Wrapper:
class Matrix {
protected:
int width;
int height;
double* matrix;
public:
Matrix(int m, int n);
Matrix(int m, int n, const std::vector<double>& values);
int get_width() {
return width;
}
int get_height() {
return height;
}
double get_element(int row_num, int col_num);
void set_element(int row_num, int col_num, double el);
double* get_cell_ref(int row_num, int col_num);
};
Method implementations:
Matrix::Matrix(int m, int n) {
assert(m > 0 && n > 0);
matrix = new double[m * n]{0};
width = n;
height = m;
}
Matrix::Matrix(int m, int n, const std::vector<double>& values) {
assert(m > 0 && n > 0 && values.size() == m * n);
matrix = new double[m * n];
width = n;
height = m;
for (int i = 0; i < m * n; ++i) {
matrix[i] = values[i];
}
}
double Matrix::get_element(int row_num, int col_num) {
assert(check_valid(row_num, col_num, get_width(), get_height()));
return matrix[col_num + get_width() * row_num];
}
void Matrix::set_element(int row_num, int col_num, double el) {
assert(check_valid(row_num, col_num, get_width(), get_height()));
matrix[col_num + row_num * get_width()] = el;
}
double* Matrix::get_cell_ref(int row_num, int col_num) {
int idx = col_num + get_width() * row_num;
return &matrix[idx];
}
The function that supposedly has a data race:
Matrix* scalar_multiply_parallel(Matrix* a, double mul, int threadN) {
auto* b = new Matrix(a->get_height(), a->get_width());
ctpl::thread_pool thr_pool(threadN);
std::vector<std::future<void>> futures(a->get_height() * a->get_width());
for (int i =0; i < a->get_height(); i++) {
for (int j =0; j < a->get_width(); j++) {
int idx = j + a->get_width() * i;
auto util = [&a, &b, i, j, mul](int) {
//b->set_element(i, j, a->get_element(i, j) * mul);
double *cell;
cell = b->get_cell_ref(i, j);
*cell = a->get_element(i, j) * mul;
};
futures[idx] = thr_pool.push(util);
}
}
for (auto& f: futures) {
f.get();
}
return b;
}

How to call a dynamic matrix into a function?

I have declared a matrix this way:
double **MB;
MB = new double *[650000];
for (int count = 0; count < 650000; count++)
MB[count] = new double [2];
Now I want to call my matrix in a function that should modify it.
bool notindic (..., double MB [][2], ...) {}
and in the main:
notindic(..., MB, ...)
Now it gives me this error: *[Error] cannot convert 'double**' to 'double ()[2]' for argument '3' to 'bool notindic(std::string, std::string, double ()[2], int, int)'
How can I fix it?
Thank you.
Just pass array pointer as parameter
#include <iostream>
const int NX = 65;
const int NY = 2;
bool notindic(double** MB) {
for(int i = 0; i < NX; ++i) {
for(int j = 0; j < NY; ++j) {
MB[i][j] = i + j;
}
}
}
int main() {
double **MB = new double *[650000];
for (int count = 0; count < 650000; count++) {
MB[count] = new double [2];
}
notindic(MB);
for(int i = 0; i < NX; ++i) {
for(int j = 0; j < NY; ++j) {
std::cout << MB[i][j] << " ";
}
std::cout << std::endl;
}
}
Forget about all that pointer nonsense. It's error-prone, exception-unsafe, hard to write, hard to read, hard to maintain and may perform poorly. Represent your matrix as std::vector<double> and calculate the offsets accordingly.
bool notindic (std::vector<double> const& matrix, int m) {
// ...
auto const element = matrix[y * m + x];
// ...
}
auto const m = 650000;
auto const n = 2;
std::vector<double> my_matrix(m * n);
auto const result = notindic(my_matrix, m);
While you're at it, wrap it in a class like this:
template <class T>
class Matrix final
{
public:
Matrix(int m, int n) :
data(m * n),
m(m)
{
}
T& operator()(int x, int y)
{
return data[y * m + x];
}
T const& operator()(int x, int y) const
{
return data[y * m + x];
}
private:
std::vector<T> data;
int m;
};
bool notindic (Matrix<double> const& matrix) {
// ...
auto const element = matrix(x, y);
// ...
}
auto const m = 650000;
auto const n = 2;
Matrix<double> my_matrix(m, n);
auto const result = notindic(my_matrix);
Add additional member functions if you need them.

C++ 4d array memory deallocation is slow

My code has a 4D matrix in it for some math problem solving
int**** Sads = new int***[inputImage->HeightLines];
for (size_t i = 0; i < inputImage->HeightLines; i++)
{
Sads[i] = new int**[inputImage->WidthColumns];
for (size_t j = 0; j < inputImage->WidthColumns; j++)
{
Sads[i][j] = new int*[W_SIZE];
for (size_t k = 0; k < W_SIZE; k++)
{
Sads[i][j][k] = new int[W_SIZE];
}
}
}
//do something with Sads...
for (int i = 0; i < inputImage->HeightLines; i++)
{
int*** tempI = Sads[i];
for (int j = 0; j < inputImage->WidthColumns; j++)
{
int** tempJ = tempI[j];
for (int k = 0; k < W_SIZE; k++)
{
delete[] tempJ[k];
}
delete[] Sads[i][j];
}
delete[] Sads[i];
}
delete[] Sads;
The sizes are very large WidthColumns = 2018, HeightLines = 1332, W_SIZE =7, the memory allocation is very fast but the memory deallocation (delete) is very slow.
Is there a way to optimize it?
I tired openMP but it throws unrelated errors of missing DLL which are there... if I removed the #pragma omp parallel for everything works fine. but slow...
Using a pointer to a pointer to... is a bad idea because it will fragment your data a lot.
I would create a class ta manage the indices transform and use 1D array, it's a bit more complicated but it will be faster.
Anyway, a trick: nothing prevent you to build your int**** with pointers to a zone in memory that isn't sparse (1D array you preallocated) and then use it as a 4D array.
I'd probably be inclined to use a std::vector. Now memory allocation is taken care of for me (in one allocation/deallocation) and I get free copy/move semantics.
All I have to do is provide the offset calculations:
#include <vector>
#include <cstddef>
struct vector4
{
vector4(std::size_t lines, std::size_t columns)
: lines_(lines), columns_(columns)
, storage_(totalSize())
{}
auto totalSize() const -> std::size_t
{
return lines_ * columns_ * w_size * w_size;
}
int* at(std::size_t a)
{
return storage_.data() + (a * columns_ * w_size * w_size);
}
int* at(std::size_t a, std::size_t b)
{
return at(a) + (b * w_size * w_size);
}
int* at(std::size_t a, std::size_t b, std::size_t c)
{
return at(a, b) + (c * w_size);
}
int& at(std::size_t a, std::size_t b, std::size_t c, std::size_t d)
{
return *(at(a, b, c) + d);
}
private:
std::size_t lines_, columns_;
static constexpr std::size_t w_size = 32; // ?
std::vector<int> storage_;
};
int main()
{
auto v = vector4(20, 20);
v.at(3, 2, 5, 1) = 6;
// other things
// now let it go out of scope
}
The correct way to create, use, and delete a 4D array is this, using the closure of the statement group to delete the automatic variables.
{
const int H = 10;
const int I = 10;
const int J = 10;
const int K = 10;
int h = 0;
int i = 0;
int j = 0;
int k = 0;
int fourDimArray [H][I][J][K];
fourDimArray[h][i][j][k] = 0;
}
If you have a need to dynamically allocate, then use either STL's list or vector class or use something like this with perhaps inline methods to calculate the index of the 1D array from the 4D array indices if you need blazing speed.
int * fourDimArrayAsOneDim = new int[H*I*J*K];
fourDimArrayAsOneDim[indexFromIndices(h, i, j, k)] = 0;
delete [] fourDimArrayAsOneDim;

understanding the logic of Rotating a N x N matrix

Hi I have started solving C++ questions. One among them is rotating a N x N matrix to a 90 degree clockwise.
below is the code link, that i'm referring to. I had never solved matrix problems in C++/any.
http://www.geeksforgeeks.org/turn-an-image-by-90-degree/
#include <stdio.h>
#include <stdlib.h>
void displayMatrix(unsigned int const *p, unsigned int row, unsigned int col);
void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col);
int main()
{
// declarations
unsigned int image[][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
unsigned int *pSource;
unsigned int *pDestination;
unsigned int m, n;
// setting initial values and memory allocation
m = 3, n = 4, pSource = (unsigned int *)image;
pDestination = (unsigned int *)malloc(sizeof(int)*m*n);
// process each buffer
displayMatrix(pSource, m, n);
rotate(pSource, pDestination, m, n);
displayMatrix(pDestination, n, m);
free(pDestination);
getchar();
return 0;
}
void displayMatrix(unsigned int const *p, unsigned int r, unsigned int c)
{
unsigned int row, col;
printf("\n\n");
for(row = 0; row < r; row++)
{
for(col = 0; col < c; col++)
{
printf("%d\t", *(p + row * c + col)); // what is this??? couldnt understand this logic?
}
printf("\n");
}
printf("\n\n");
}
void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col)
{
unsigned int r, c;
for(r = 0; r < row; r++)
{
for(c = 0; c < col; c++)
{
*(pD + c * row + (row - r - 1)) = *(pS + r * col + c); // not understanding this logic as well.
}
}
}
could any one please explain more about this logic. I'm not able to resolve few places in the above problems that i have mentioned in the code itself.
Also please let me know the time and space complexity detailed..Thanks in advance.
The code relies on a two-dimensional array being contiguously stored and treats it as one-dimensional.
The line
*(pD + c * row + (row - r - 1)) = *(pS + r * col + c);
is equivalent to
pD[c][row-r-1] = pS[r][c];