@1708
asked on
DCT of 2D array using fftw in c++
I want to find dct of a matrix in c++ just like how it is done in matlab.
Below is the code I used
1) Matrix a[m][n] is obtained by multiplying signal with hamming window .
2) When I pass Matrix "a" as input to " fftw_plan plan = fftw_plan_r2r_2d(n, m,&a[0][0],&b[0][0], FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE); "
I get the following error :
cannot convert ‘long double*’ to ‘double*’ for argument ‘4’ to ‘fftw_plan_s* fftw_plan_r2r_2d(int, int, double*, double*, fftw_r2r_kind, fftw_r2r_kind, unsigned int)’
How do I pass a matrix to DCT function using fftw3 ,which is declared as mentioned above .
PS :When I declared it as double a[m][n] = {//Enter the elements}; //when m =640 ; n = 645
It gives Segmentation fault
{Because of which I tried to define matrix a in heap as mentioned but when given to the dct function throws error .}
Can anyone kindly solve my issue .
Thanks in Advance.
Below is the code I used
#include <fftw3.h>
using namespace std;
double** create2DArray(int row, int col)
{
double** arr = new double*[row];
for(int i = 0; i < row; i++)
arr[i] = new double[col];
return arr;
}
int main()
{
int m = 3;
int n = 3;
/*double a[m][n] =
{
{0.2, 0.3 ,1},
{0 ,12 ,5},
{0.3, 0.3, 1}
};*/
double** a= create2DArray(m,n);
for( int j = 0; j < m;j++ )
{
for(int i = 0; i < n; i++)
{
a[i][j] = Signal[i]*hamming[i];
}
}
double** b= create2DArray(m,n);
printf("Original vector\n");
for(int i=0;i<m;i++)
{
for(int j = 0 ;j<n;j++)
{
cout << a[i][j] <<" " ;
}
cout<< endl;
}
fftw_plan plan = fftw_plan_r2r_2d(n, m,&a[0][0],&b[0][0], FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
printf("DCT\n");
for(int i=0;i<m;i++)
{
for(int j = 0 ;j<n;j++)
{
cout << b[i][j] <<" " ;
}
cout<< endl;
}
fftw_plan plani = fftw_plan_r2r_2d(n, m,&b[0][0],&a[0][0], FFTW_REDFT01, FFTW_REDFT01,FFTW_MEASURE);
fftw_execute(plani);
printf("IDCT\n");
for(int i=0;i<m;i++)
{
for(int j = 0 ;j<n;j++)
{
cout << a[i][j]/(m*n*4) <<" " ;
}
cout<< endl;
}
return 0;
1) Matrix a[m][n] is obtained by multiplying signal with hamming window .
2) When I pass Matrix "a" as input to " fftw_plan plan = fftw_plan_r2r_2d(n, m,&a[0][0],&b[0][0], FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE); "
I get the following error :
cannot convert ‘long double*’ to ‘double*’ for argument ‘4’ to ‘fftw_plan_s* fftw_plan_r2r_2d(int, int, double*, double*, fftw_r2r_kind, fftw_r2r_kind, unsigned int)’
How do I pass a matrix to DCT function using fftw3 ,which is declared as mentioned above .
PS :When I declared it as double a[m][n] = {//Enter the elements}; //when m =640 ; n = 645
It gives Segmentation fault
{Because of which I tried to define matrix a in heap as mentioned but when given to the dct function throws error .}
Can anyone kindly solve my issue .
Thanks in Advance.
fftw_plan_r2r_2d(int, int, double*, double*, fftw_r2r_kind, fftw_r2r_kind, unsigned int)’the code you posted uses double arrays. it can't be responsible for the error message which complains that a 'long double *' was passed to function fftw_plan_r2r_2d.
you still are posting code which doesn't fit to your problem what actually makes it impossible to help.
Sara
ASKER
@sarabande
Apologise for the mistake I made ,I got confused :
The following code :output the following result :
Original matrix
1 2
3 4
DCT
12 -2.82843
0 0
IDCT
16 32
3 4
1) IDCT is found (and is correct ) only for the first row .
2) DCT output is wrong .
The correct output should have been :
DCT
40 -5.65685
-11.3137 0
IDCT
16 32
48 64
Apologise for the mistake I made ,I got confused :
double** create2DArray(int row, int col)
{
double** arr = new double*[row];
for(int i = 0; i < row; i++)
arr[i] = new double[col];
return arr;
}
int main()
{
int m = 2;
int n = 2;
double** a= create2DArray(m,n);
//Intilialising Matrix a
int count = 1;
for(int i = 0 ; i<m;i++)
{
for(int j = 0 ; j<n;j++)
{
a[i][j] = count ;//[1 2 ;3 4]
count++;
}
}
double** b= create2DArray(m,n); // To hold the output
fftw_plan plan = fftw_plan_r2r_2d(n, m,&a[0][0],&b[0][0], FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_plan plani = fftw_plan_r2r_2d(n, m,&b[0][0],&a[0][0], FFTW_REDFT01, FFTW_REDFT01,FFTW_MEASURE);
fftw_execute(plani);
return 0;
}
The following code :output the following result :
Original matrix
1 2
3 4
DCT
12 -2.82843
0 0
IDCT
16 32
3 4
1) IDCT is found (and is correct ) only for the first row .
2) DCT output is wrong .
The correct output should have been :
DCT
40 -5.65685
-11.3137 0
IDCT
16 32
48 64
please post the code of function fftw_plan_r2r_2d and corresponding matlab code.
i found c sample code using float type (which only has a precison of 5 to 6 significant decimal digits.
so i would assume that using long double type for all would not solve the problem.
did you correctly use zero-based arrays in your c code when porting the matlab code (where all arrays are 1-based) ?
Sara
i found c sample code using float type (which only has a precison of 5 to 6 significant decimal digits.
so i would assume that using long double type for all would not solve the problem.
did you correctly use zero-based arrays in your c code when porting the matlab code (where all arrays are 1-based) ?
Sara
ASKER
fftw_plan_r2r_2d is not a user defined function .
I have used the library #include <fftw3.h> in my code .Which uses fftw_plan_r2r_2d to do dct on matrix .
And the result of this dct would be "similiar " to the dct2 in matlab , but different by a scaling factor .
The code workes fine when input matrix is defines as
double a [m][n] = {{1,2},{3,4}};
When when declared as shown in code 2 , ends up in wrong result .
I have used the library #include <fftw3.h> in my code .Which uses fftw_plan_r2r_2d to do dct on matrix .
And the result of this dct would be "similiar " to the dct2 in matlab , but different by a scaling factor .
The code workes fine when input matrix is defines as
double a [m][n] = {{1,2},{3,4}};
When when declared as shown in code 2 , ends up in wrong result .
The code workes fine when input matrix is defines as
double a [m][n] = {{1,2},{3,4}};
ok. then you need to change the create2DArray to create an 1d array (actually it is as if you would concatenate the rows of the matrix).
double* create2DArray(int row, int col)
{
double* arr = new double[row*col];
return arr;
}
int main()
{
int m = 2;
int n = 2;
double* a= create2DArray(m,n);
//Intilialising Matrix a
int count = 1;
for(int i = 0 ; i<m;i++)
{
for(int j = 0 ; j<n;j++)
{
a[i*n+j] = count ;//[1 2 ;3 4]
count++;
}
}
double* b= create2DArray(m,n); // To hold the output
fftw_plan plan = fftw_plan_r2r_2d(n, m, a, b, FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_plan plani = fftw_plan_r2r_2d(n, m, b, a, FFTW_REDFT01, FFTW_REDFT01,FFTW_MEASURE);
fftw_execute(plani);
delete[]a;
delete[]b;
//delete fftw_plan; // ??
return 0;
}
Sara
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks a lot for your feedback .
the function fftw_plan_r2r_2d expects the matrix to be passed as in the second case.because of this you also could use a std::vector<double> for your matrix.
std::vector<double> a(m*n);
int count = 1;
for(int i = 0 ; i<m;i++)
{
for(int j = 0 ; j<n;j++)
{
a[i*n+j] = count ;//[1 2 ;3 4]
count++;
}
}
std::vector<double> b(m*n);
fftw_plan plan = fftw_plan_r2r_2d(n, m, &a[0], &b[0], FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE);
...
a std::vector provides a contiguous 1d array (same as the corrected create2DArray). differently, you would not need to care for deletion, as the std::vector has a destructor which does that for you.
Sara
https://www.experts-exchange.com/questions/28997412/How-to-pass-a-matrix-to-a-function-without-knowing-its-size.html
If you continue your discussion in your first question to the point of resolving that issue, I think that will help you with this problem.
Could you come up with a simpler complete program (i.e., a few lines of code) that illustrates your problem without bringing in the DCT and Matlab concepts. To illustrate your compiler error and your program crash, you should be able to throw away a good amount of the details in your OP and just deal with the essential issues. Leaving out the DCT and Matlab concepts will help us focus on your C++ problems.