Error in function: no instance of overloaded function matches the argument list

I have a script that is working fine, but when I try to write a function with the same script I get the error "no instance of overloaded function "aapx" matches the argument list".

I know that an Eigen::Matrix should always be passed by reference to a function so I did and I thought maybe the issue is I am initializing a Eigen::Matrix<std::complex<double> and passing a Eigen::MatrixXcd but that doesn't seem to fix the error either.

The function

1
2
3
4
void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd>& ph){ 
//some calculations

}

The main code looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
static const int nx = 10;
static const int ny = 10; 
static const int mm = nx* 3/2;

Eigen::Matrix<std::complex<double>, (ny+1), (nx)> uh;
uh.setZero();

Eigen::Matrix<std::complex<double>, (ny+1), (nx)> vh;
vh.setZero();

Eigen::Matrix<std::complex<double>, (ny+1), nx> ph;  
ph.setZero();

aapx(uh,vh,ph); //ERROR 

I can post the full code, it's just the function is a bit long. The full error:

no instance of overloaded function "aapx" matches the argument list
argument types are: (Eigen::Matrix<std::_Complex<double>, 11, 10, 0, 11, 10>, Eigen::Matrix<std::_Complex<double>, 11, 10, 0, 11, 10>, Eigen::Matrix<std::_Complex<double>, 11, 10, 0, 11, 10>)
Last edited on
Hi,

Probably due to the declaration parameters being const

void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd>& ph){

https://en.cppreference.com/w/cpp/language/functions
cppreference wrote:
Multiple functions in the same scope may have the same name, as long as their parameter lists and, for non-static member functions, cv/ref (since C++11)-qualifications are different. This is known as function overloading. Function declarations that differ only in the return type and the noexcept specification (since C++17) cannot be overloaded. The address of an overloaded function is determined differently.


Emphasis by me.

I can post the full code, it's just the function is a bit long.


If you have more than 8196 char in a single function then you have a design problem. One can make multiple posts so we can see all the code.
@TheIdeasMan
Thanks, I was trying to follow with the examples on this link, thus the use of const :


I am aware my function is not very ideal, but I was running a generic test where this function will be probably be broken up to multiple functions. I will post the full function here actually in a separate comment.
The full function looks like:
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, const Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd>& ph){

	//define a new Eigen matrix
	Eigen::Matrix<std::complex<double>, (ny+1), mm> uhp;
	uhp.setZero();
	//pad the first input with zeros 
	uhp(all,seqN(0,nx/2)) = uh(all,seqN(0,nx/2));
	uhp(all,seq(last-nx/2+1, last)) = uh(all,seq(last+1-nx/2, last)); 

	//define a new Eigen matrix
	Eigen::Matrix<std::complex<double>, (ny+1), mm> vhp;
	vhp.setZero();
	//pad the first input with zeros
	vhp(all,seqN(0,nx/2)) = vh(all,seqN(0,nx/2)); 
	vhp(all,seq(last-nx/2+1, last)) = vh(all,seq(last+1-nx/2, last));

	//define a c++ array in order to use FFTW with Eigen matrices
	fftw_complex *uhpk; //dummy variable
	uhpk = (fftw_complex*) fftw_malloc((((mm)*(ny+1))*nyk)* sizeof(fftw_complex)); 
	memset(uhpk, 42, (((mm)*(ny+1))*nyk)* sizeof(fftw_complex));

	memcpy(uhpk,uhp.data(),uhp.size() * sizeof(fftw_complex));
	//######################################################
	//use 1dfft function (note: write in a separate function)

	cplx_buffer dummyII2 = my_fftw_allocate_cplx((ny+1), mm);
	for (int i = 0; i < mm; i++){ 
		for (int j = 0; j < ny+1; j++){ 
			for (int k = 0; k < ncomp; k++){
				dummyII2(j,i)[k] = uhpk[i*(ny+1)+j][k];
			}
		}
	
	}
	real_buffer dummyRR2 = my_fftw_allocate_real((ny+1), mm);
	//real(ifft(duxk,[],2))
	{ // Transform all the rows
	fftw_execute(fftw_plan_many_dft_c2r(1, &nx, dummyII2.rows, dummyII2.a, &dummyII2.cols, 1, dummyII2.cols, dummyRR2.a, &dummyII2.cols, 1, dummyRR2.cols, FFTW_ESTIMATE));
	//std::cout << "Inverse FT of input, row-wise\n"; 
	//print_matrixR(dummyRR2);
	}
	double *up;
	up = (double*) fftw_malloc((((ny+1)*mm))*sizeof(double)); 
	for (int i = 0; i < ny+1; i++){ 
		for (int j = 0; j < mm; j++){ 
			up[j*(ny+1)+i] = dummyRR2(i,j);
		}
	}

	fftw_complex *vhpk; 
	vhpk = (fftw_complex*) fftw_malloc((((mm)*(ny+1))*nyk)* sizeof(fftw_complex));
	memset(vhpk, 42, (((mm)*(ny+1))*nyk)* sizeof(fftw_complex)); 

	memcpy(vhpk,vhp.data(),vhp.size() * sizeof(fftw_complex));
	cplx_buffer dummyIi2 = my_fftw_allocate_cplx((ny+1), mm);

	for (int i = 0; i < mm; i++){ 
		for (int j = 0; j < ny+1; j++){ 
			for (int k = 0; k < ncomp; k++){
				dummyIi2(j,i)[k] = vhpk[i*(ny+1)+j][k];
			}
		}
	
	}
	
	real_buffer dummyRr2 = my_fftw_allocate_real((ny+1), mm);
	
	{ // Transform all the rows
	fftw_execute(fftw_plan_many_dft_c2r(1, &nx, dummyIi2.rows, dummyIi2.a, &dummyIi2.cols, 1, dummyIi2.cols, dummyRr2.a, &dummyIi2.cols, 1, dummyRr2.cols, FFTW_ESTIMATE));
	}

	double *vp;
	vp = (double*) fftw_malloc((((ny+1)*mm))*sizeof(double)); 
	//use for loop to set dummyR with vp and flip rows and cols
	for (int i = 0; i < ny+1; i++){ 
		for (int j = 0; j < mm; j++){ 
			vp[j*(ny+1)+i] = dummyRr2(i,j);
		}
	}

	double *w;
	w = (double*) fftw_malloc((((ny+1)*mm))*sizeof(double));
	
	//take the product in real space: w=up.*vp;
	for (int i = 0; i < ny+1; i++){ 
		for (int j = 0; j < mm; j++){ 
			w[j*(ny+1)+i] = vp[j*(ny+1)+i] * up[j*(ny+1)+i];
		}
	}

	
	real_buffer inW = my_fftw_allocate_real((ny+1), mm);
	for (int i = 0; i < ny+1; i++){ 
		for (int j = 0; j < mm; j++){ 
			inW(i,j) = w[j*(ny+1)+i];
		}
	}

	// FFT along the x direction:  wh=fft(w,[],2);
	cplx_buffer outW = my_fftw_allocate_cplx((ny+1), mm); //((ny+1), nx);

	 { // 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));
	}

	fftw_complex *whk;
	whk = (fftw_complex*) fftw_malloc((((mm)*(ny+1))*nyk)* sizeof(fftw_complex));  
	memset(whk, 42, (((mm)*(ny+1))*nyk)* sizeof(fftw_complex)); 

	for (int i = 0; i < mm; i++){ 
		for (int j = 0; j < ny+1; j++){ 
			for (int k = 0; k < ncomp; k++){ 
				whk[i*(ny+1)+j][k] = outW(j,i)[k];
			}
		}
	
	}
	Eigen::Map<Eigen::MatrixXcd, Eigen::Unaligned> wh(reinterpret_cast<std::complex<double>*>(whk),(ny+1),mm); 

	ph(all,seqN(0,nx/2)) = wh(all,seqN(0,nx/2));
	ph(all,seq(last+1-nx/2, last)) = wh(all,seq(last+1-nx/2, last));
	ph = 1.5 * ph;
//free stuff
}

where, the 1D FFt is defined as:
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
static const int nx = 10;
static const int ny = 10; 
static const int mm = nx* 3/2;

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]; }
};

real_buffer my_fftw_allocate_real(int x, int y) { return real_buffer{ fftw_alloc_real(x * y), x, y }; }
cplx_buffer my_fftw_allocate_cplx(int x, int y) { return cplx_buffer{ fftw_alloc_complex(x * y), x, y }; }
Last edited on
OK, when I said const might be a problem, I meant in respect to overloaded functions, but can you explain why you need an overloaded function there? There weren't any examples in the link you posted.

Without overloading, const reference would be fine.

In the first part of the link, it talks about expression templates, maybe that is why overloading does not work?

If you have overloaded functions can you show both of them? Or just the declarations?

I know that an Eigen::Matrix should always be passed by reference to a function so I did and I thought maybe the issue is I am initializing a Eigen::Matrix<std::complex<double> and passing a Eigen::MatrixXcd but that doesn't seem to fix the error either.


But you are initialising and passing as Eigen::Matrix<std::complex<double> , but the function expects a Eigen::Ref<const Eigen::MatrixXcd>& Note the first parameter is a const Eigen::Ref<const Eigen::MatrixXcd>& but the other two are Eigen::Ref<const Eigen::MatrixXcd>& (no const at the front)

Another thing, if I am using doubles I write them explicitly with decimal points, as in 10.0 not 10 which is an int and causes the compiler to do an implicit cast. This can be a problem with templated functions.

Edit:
And you have in main

1
2
static const int nx = 10;
static const int ny = 10;


but use them to initialise a std::complex<double>
Last edited on

But you are initialising and passing as Eigen::Matrix<std::complex<double> , but the function expects a Eigen::Ref<const Eigen::MatrixXcd>& Note the first parameter is a const Eigen::Ref<const Eigen::MatrixXcd>& but the other two are Eigen::Ref<const Eigen::MatrixXcd>& (no const at the front)


That's true, but then even when initializing and passing as Eigen::MatrixXcd does not solve the problem.

Also, an example for a generic non-templated function from the Eigen website shows something sort of similar to my function (at least I thought so):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <Eigen/SVD>
 
float inv_cond(const Eigen::Ref<const Eigen::MatrixXf>& a)
{
  const Eigen::VectorXf sing_vals = a.jacobiSvd().singularValues();
  return sing_vals(sing_vals.size()-1) / sing_vals(0);
}
 
int main()
{
  Eigen::MatrixXf m = Eigen::MatrixXf::Random(4, 4);
  std::cout << "matrix m:\n" << m << "\n\n";
  std::cout << "inv_cond(m):          " << inv_cond(m)                      << "\n";
  std::cout << "inv_cond(m(1:3,1:3)): " << inv_cond(m.topLeftCorner(3,3))   << "\n";
  std::cout << "inv_cond(m+I):        " << inv_cond(m+Eigen::MatrixXf::Identity(4, 4)) << "\n";
}


Note how the example doesn't initialize and pass a as const Eigen::Ref<const Eigen::MatrixXf>& but just Eigen::MatrixXf
But why is the compiler complaining about overloaded functions? Try putting your aapx function in it's own namespace so it doesn't clash with some other aapx function somewhere else. Putting all of your own code in namespaces is a good idea to stop clashes, and it's the reason that namespaces were invented.

Or rename your function as a temporary measure to see if that is what the problem is.

Note how the example doesn't initialize and pass a as const Eigen::Ref<const Eigen::MatrixXf>& but just Eigen::MatrixXf


I am not saying you need to pass arguments as const, just that const is a problem for overload resolution. But it sounds like you shouldn't have overloaded functions anyway.

This make me nervous about the potential error with integer division:
static const int mm = nx* 3/2;

I would rather :
static const int mm = (nx* 3) / 2;
Last edited on
But why is the compiler complaining about overloaded functions? Try putting your aapx function in it's own namespace so it doesn't clash with some other aapx function somewhere else

Oops! You're right, I have another function with the same name but in MATLAB and I thought it wouldn't be a problem since they have different file extensions.

Now, I found a useful post here:

I got rid off the error but when I run the new code I get:
In file included from arithmeticFunctions3D.cpp:6:
spectralFunctions3D.h:15:17: error: ‘Eigen’ is not a namespace-name
   15 | using namespace Eigen;
      |                 ^~~~~
In file included from arithmeticFunctions3D.cpp:6:
spectralFunctions3D.h:21:17: error: ‘Eigen’ does not name a type
   21 | void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, const Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd> ph);
      |                 ^~~~~
spectralFunctions3D.h:21:27: error: expected unqualified-id before ‘<’ token
   21 | void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, const Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd> ph);
      |                           ^
spectralFunctions3D.h:21:27: error: expected ‘)’ before ‘<’ token
   21 | void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, const Eigen::Ref<const Eigen::MatrixXcd>& vh, Eigen::Ref<const Eigen::MatrixXcd> ph);
      |          ~                ^
      |                           )
spectralFunctions3D.h:21:27: error: expected initializer before ‘<’ token


The weirdest error is the first,
 error: ‘Eigen’ is not a namespace-name
   15 | using namespace Eigen;

How is that even possible?
Is the Eigen stuff inside an Eigen namespace?

What does the new code look like?

Edit:

So i have been reading some of the Eigen documentation, there is an Eigen namespace. But why do you now want to have using namespace Eigen; ? Just leave it with everything qualified with Eigen::

Do you know how to make your own namespace?
Last edited on
This is full code with headers and main testing script (Test.cpp). I am so confused, I am getting weird different errors. All I care about is testing the function aapx in Test.cpp. Here's a link:
Thanks for the link to the code, it will take me awhile to go through that, I need to install Eigen and have a detailed read of the manual.

Just looking at the code, you seem to have way too many header files included. Only include what you need. You have even included all the same ones in the cpp file as well.

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
#ifndef arithmeticFUN_H
#define arithmeticFUN_H
#include <string>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <cmath>
#include "fftw3.h"
#include <cstring>
#include<stdint.h>
#include <sstream>
#include <iostream> //test
#include <fstream>
#include <iterator>
//#include <fstream> //for file operations
#include <iomanip>
#include <Eigen/Dense>
//#include <unsupported/Eigen/FFT>
#include <Eigen/SparseCore> //SparseMatrix and SparseVector classes, matrix assembly, basic sparse linear algebra (including sparse triangular solvers)
#include <Eigen/Sparse>



void Arr3DArr2DMult(double arr3D[][ncomp], double arr2D[], double arrOut[][ncomp]);
void iArr3DMult(double arr[][ncomp], double arrOut[][ncomp]);
#endif 


I would get rid of:

1
2
using namespace std;
using namespace Eigen;


Just qualify with std:: and Eigen:: repectively where required.
Well I installed Eigen and fftw3.

The first error I get is:

In file included from /usr/include/Eigen/Core:19,
from /usr/include/Eigen/Dense:1,
from spectralFunctions3D.h:3,
from spectralFunctions3D.cpp:7:
/usr/include/Eigen/src/Core/Ref.h: In instantiation of ‘Eigen::RefBase<Derived>& Eigen::RefBase<Derived>::operator=(const Eigen::RefBase<Derived>&) [with Derived = Eigen::Ref<const Eigen::Matrix<std::complex<double>, -1, -1> >]’:
/usr/include/Eigen/src/Core/Ref.h:329:77: required from here
/usr/include/Eigen/src/Core/Ref.h:90:3: error: use of deleted function ‘Eigen::MapBase<Eigen::Ref<const Eigen::Matrix<std::complex<double>, -1, -1> >, 0>& Eigen::MapBase<Eigen::Ref<const Eigen::Matrix<std::complex<double>, -1, -1> >, 0>::operator=(const Eigen::MapBase<Eigen::Ref<const Eigen::Matrix<std::complex<double>, -1, -1> >, 0>&)’
90 | EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Which all came from #include <Eigen/Dense>

Maybe it's an installation issue from my end. All I did for fftw3 was: configure; make ; make install If so, I am not helping much !! :+(

all I care about is testing the function aapx in Test.cpp.


Can you make a minimal test case that does that? Is all that 2573 LOC necessary to test that one function?

Hey! Thanks for looking at the code, I see where exactly the error stems from in my function. I will try setting up a smaller example.
C++ error messages are daunting but they reliably contain useful information. It's usually just a matter of knowing what to look for, and being able to stop one's eyes from glazing over.

I was able to reproduce TheIdeasMan's error message. It is very long, but it ultimately contains
eigen/Eigen/src/Core/MapBase.h:37:34: error: passing ‘const Eigen::internal::variable_if_dynamic<long int, -1>’ as ‘this’ argument discards qualifiers [-fpermissive]
// ...
spectralFunctions3D.cpp:228:44:   required from here

Which traces the source of the error back to your program.

Line 228, column 44 is the equals sign in
ph(all,seqN(0,nx/2)) = wh(all,seqN(0,nx/2));
The error message says this assignment asks the compiler to throw away const ("[discard] qualifiers", where "qualifiers" essentially means const).

In general, an assignment expression x = y doesn't care about the const-ness of y. But it does care about the const-ness of x because this assignment tries to change it.

ph is the x in the assignment in question. It's not const but it does refers to a const matrix (of type const Eigen::MatrixXcd). Remove it:

1
2
3
void aapx(const Eigen::Ref<const Eigen::MatrixXcd>& uh, 
          const Eigen::Ref<const Eigen::MatrixXcd>& vh,
          Eigen::Ref<Eigen::MatrixXcd> ph)


This change is enough to get the code to compile but not link.

This is the error message from the linker:

ld.lld: error: duplicate symbol: my_fftw_allocate_real(int, int)
>>> defined at Test.cpp:61
>>>            /tmp/ccezRTyF.o:(my_fftw_allocate_real(int, int))
>>> defined at spectralFunctions3D.cpp:52
>>>            /tmp/cc14RAhJ.o:(.text+0x0)

ld.lld: error: duplicate symbol: my_fftw_allocate_cplx(int, int)
>>> defined at Test.cpp:62
>>>            /tmp/ccezRTyF.o:(my_fftw_allocate_cplx(int, int))
>>> defined at spectralFunctions3D.cpp:53
>>>            /tmp/cc14RAhJ.o:(.text+0x65)

ld.lld: error: duplicate symbol: print_matrix(cplx_buffer const&)
>>> defined at Test.cpp:65
>>>            /tmp/ccezRTyF.o:(print_matrix(cplx_buffer const&))
>>> defined at spectralFunctions3D.cpp:56
>>>            /tmp/cc14RAhJ.o:(.text+0xCA)

ld.lld: error: duplicate symbol: print_matrixR(real_buffer const&)
>>> defined at Test.cpp:81
>>>            /tmp/ccezRTyF.o:(print_matrixR(real_buffer const&))
>>> defined at spectralFunctions3D.cpp:72
>>>            /tmp/cc14RAhJ.o:(.text+0x201)
collect2: error: ld returned 1 exit status


A "symbol" is essentially a function. The problem is that these functions are defined in two separate files.
Declare the functions in one header file; define them in exactly one source file.
I made a new header and source file pair for these.
Move the definitions of cplx_buffer and real_buffer into the header file too, to avoid the definitions getting out of sync.

After fixing that it builds. When I run it I get

    (0.0000,0.0000)     (0.0000,0.0000)  (1194.7556,0.0000)    (-0.0000,0.0000) (1194.7556,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
   (-0.0000,0.0000)    (0.0000,-0.0000)  (1011.2950,0.0000)   (-0.0000,-0.0000) (1011.2950,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
   (-0.0000,0.0000)     (0.0000,0.0000)  (595.5283,-0.0000)    (0.0000,-0.0000)  (595.5283,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)    (0.0000,-0.0000)   (217.0802,0.0000)    (0.0000,-0.0000)  (217.0802,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)     (0.0000,0.0000)    (33.1877,0.0000)    (0.0000,-0.0000)   (33.1877,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)     (0.0000,0.0000)     (1.8495,0.0000)    (0.0000,-0.0000)    (1.8495,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)    (0.0000,-0.0000)     (1.4138,0.0000)   (-0.0000,-0.0000)    (1.4138,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
   (-0.0000,0.0000)    (0.0000,-0.0000)   (33.1877,-0.0000)    (0.0000,-0.0000)   (33.1877,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
   (-0.0000,0.0000)    (0.0000,-0.0000)    (97.7172,0.0000)    (0.0000,-0.0000)   (97.7172,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)
    (0.0000,0.0000)    (0.0000,-0.0000)   (132.7506,0.0000)    (0.0000,-0.0000)  (132.7506,-0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)     (0.0000,0.0000)



Also note that the header guard at the top of spectralFunctions3D has a typo:
1
2
#ifndef spectralFUN_H
#define spectralFUBN_H 
Last edited on
@mbozzi
Thanks so much!! I actually, just fixed the error as I saw your comment.
Also, I was struggling with adding my struct in the header files, but I will follow with what you did and try running it again.


Also note that the header guard at the top of spectralFunctions3D has a typo:
#ifndef spectralFUN_H
#define spectralFUBN_H

oh, I don't see the typo sorry what do you mean by that?
Thanks again
Don't see the typo

On line 2 of spectralFunctions3D.h you wrote:
spectralFUBN_H
but meant
spectralFUN_H
Those names need to match, else the header guard won't do it's job.

I was struggling with adding my struct in the header files, but I will follow with what you did and try running it again.


I arbitrarily chose to call my new header/source file "common.h" and "common.cpp". My header file looks like:

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
#if ! defined COMMON_H_INCLUDED
#define COMMON_H_INCLUDED

#include "fftw3.h"

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]; }
};

real_buffer my_fftw_allocate_real(int x, int y);
cplx_buffer my_fftw_allocate_cplx(int x, int y);
void print_matrixR(cplx_buffer const& m);
void print_matrix(real_buffer const& m);

#endif 


And the corresponding source file looks like:

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
#include "common.h"
#include <iostream>
#include <complex>
#include <iomanip>

real_buffer my_fftw_allocate_real(int x, int y) { return real_buffer{ fftw_alloc_real(x * y), x, y }; }
cplx_buffer my_fftw_allocate_cplx(int x, int y) { return cplx_buffer{ fftw_alloc_complex(x * y), x, y }; }

void print_matrix(cplx_buffer const& m)
{
  std::cout << std::fixed << std::setprecision(2);
  //std::cout << std::fixed << std::setprecision(4);

  for (int i = 0; i < m.rows; i++)
  {
    for (int j = 0; j < m.cols; j++)
    {
      std::cout << std::setw(16) << std::complex<double> { m(i, j)[0], m(i, j)[1] };
    }
    std::cout << '\n';
  }
  std::cout << '\n';
}

//*************print matrix for inverse FFT ******************
void print_matrixR(real_buffer const& m)
{
  std::cout << std::fixed << std::setprecision(2);
  //std::cout << std::fixed << std::setprecision(4);

  for (int i = 0; i < m.rows; i++)
  {
    for (int j = 0; j < m.cols; j++)
    {
      std::cout << std::setw(10) <<   m(i, j) ;
    }
    std::cout << '\n';
  }
  std::cout << '\n';
}


In all the other .cpp files I made sure to include common.h.

The point of this is to move any repeated code into one place.
Last edited on
Thanks a lot!! This actually was one of the source of my issues!
Topic archived. No new replies allowed.