Problem with complex numbers

Hi all,

I don't know how to solve the problem when compiling next code: in function 'void resfexact(std::vector<double>&, double, std::complex<double>&)':

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include <vector>
#include <complex.h>
#include <complex>
#ifndef PI
    #define PI 3.14159265358979323846
#endif

using namespace std;

void resfexact(vector<double> &xnodo, double k, complex<double> &pbal)
{

double r0=0.25;
complex<double> u0;
double r;

u0=10*I/(2*PI*pow(k,3)*pow(343,3));

r=sqrt(xnodo[0]*xnodo[0]+xnodo[1]*xnodo[1]+xnodo[2]*xnodo[2]);

pbal=cexp(-I*k*(r-r0))*I*k*1.21*u0*pow(r0,2)/((343*r*(1+I*k*r0));

}


Can anyone guess, please?
in function 'void resfexact(std::vector<double>&, double, std::complex<double>&)':

Right after that, it should say what the problem actually is. That line is telling you which function the problem is in.

If I had to guess, I'd say that in the line
u0=10*I/(2*PI*pow(k,3)*pow(343,3));
the variable I does not exist.

1
2
#include <complex.h>
#include <complex> 

Just the C++ header will do fine.
Last edited on
Sorry, errors are:
line 21:col 22: [Error] 'cexp' was not declared in this scope
line21: col 65: [Error] expected ')' before ';' token

I tried your corrections, and it does it mend the problem.
I isn't defined. Did you mean it to be the square root of -1, which you could get by
constexpr complex<double> I{ 0.0, 1.0 };
or is it something else ... or does it even mean different things in different places?

Use exp, not cexp for the exponential function, irrespective of whether it is complex or not.

On line 21 you have too many ( brackets; probably one of those before 343 is redundant.

If I is a complex number (and your intention is unclear) then you will have to code it as
10.0*I
rather than
10*I
(since only double * complex<double> is defined). Similarly with
(1+I*k*r0)
becoming
(1.0+I*k*r0)
if I is complex.

Read your compiler messages and fix them from the top; they are fairly self-explanatory.
Last edited on
I tried your suggestion. I think that <complex.h> should stay in code, unless the program doesn't recognize I term.

I checked to do 1.0 + I and 10.0*I, but do still drop the error stating:

21 32 [Error] no match for 'operator*' (operand types are '__complex__ double' and 'std::complex<double>').

Can you guess of any other modfication for the product operator, please?

Thanks a lot
Have you defined I yet? (I would presume so, given the error message).

For a modern compiler (I hope that you have one) the better header should be
#include <complex>
and that alone.

Can you post your revised code. It is not possible to guess what you might or might not have written.

Better still, post something that will run as a whole so that it is actually possible to test it.
think that <complex.h> should stay in code, unless the program doesn't recognize I term

The capital letter I is a macro defined in complex.h because it's part of C complex numbers. C++ complex numbers (defined in <complex>) are totally different. You will not get C's I to work in a C++ program.

The attempt to do that is what the compiler is pointing out in the last post: there is no 'operator*' between a C complex number and a C++ complex number
Last edited on
For the following function, however, the compiler works, and I cannot see the difference between the two. Notice that number "I" still appears at line 27.

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
#include <vector>
#include <complex.h>
#include <complex>
//#include<gsl/gsl_sf_bessel.h>
#ifndef PI
    #define PI 3.14159265358979323846
#endif

using namespace std;

void pistonff(vector<double> &xnodo, double k, double a, complex<double> &baliozehatz)
{

double r, theta;
double f, besselfun1;

f=k*343/2/PI;

r=sqrt(xnodo[0]*xnodo[0]+xnodo[1]*xnodo[1]+xnodo[2]*xnodo[2]);

theta=acos(xnodo[0]/r);

/** 1st order Bessel function **/

besselfun1=k*a*sin(theta);

baliozehatz=-20*1.21*pow(PI,2)*cexp(I*k*r)*(2.*besselfun1/(k*a*sin(theta)))/(r*pow(f,2));
}
@Galtor

Have you read Cubbi's post?

Just use one complex header. Do not confuse the two sets of definitions. This is a C++ forum, so I suggest that you use
#include <complex>
and then define I explicitly as
const complex<double> I{ 0.0, 1.0 };
(or use constexpr instead of const)

You need to post the code that you say doesn't work, not the code that does. There were other problems in your previous code besides this, including unbalanced brackets. It looks suspiciously as if you are trying to copy-and-paste older C code into your own C++ functions.


The following version of both your functions works OK. Try it in C++ shell (the little gear-wheel icon at top left of the code sample). Note, in particular, the use of exp, not cexp. The latter seems to come with the C99 version of C (see http://en.cppreference.com/w/c/numeric/complex) and not C++ (see http://www.cplusplus.com/reference/complex/). If you have cexp in a lot of your functions then you may have a lot of problems mixing with C++.

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
#include <iostream>
#include <vector>
#include <complex>           // <=====
using namespace std;

const double PI = 3.14159265358979323846;
const complex<double> I{ 0.0, 1.0 };           // <=====


void resfexact( vector<double> &xnodo, double k, complex<double> &pbal )
{
   double r0 = 0.25;
   complex<double> u0;
   double r = sqrt( xnodo[0] * xnodo[0] + xnodo[1] * xnodo[1] + xnodo[2] * xnodo[2] );
   u0 = 10.0 * I / ( 2.0 * PI * pow( k, 3 ) * pow( 343, 3 ) );

   pbal = exp( -I * k * ( r - r0 ) ) * I * k * 1.21 * u0 * r0 * r0 / ( 343 * r * ( 1.0 + I * k * r0 ) );
}


void pistonff( vector<double> &xnodo, double k, double a, complex<double> &baliozehatz )
{
   double f = k * 343 / ( 2.0 * PI );
   double r = sqrt( xnodo[0] * xnodo[0] + xnodo[1] * xnodo[1] + xnodo[2] * xnodo[2] );
   double theta = acos( xnodo[0] / r );
   double besselfun1 = k * a * sin( theta );     // 1st order Bessel function

   baliozehatz = -20.0 * 1.21 * PI * PI * exp( I * k * r ) * ( 2.0 * besselfun1 / ( k * a * sin( theta ) ) )
               / ( r * f * f );
}


int main()
{
   double k = 0.1, a = 2.0;
   vector<double> x = { 1.0, 2.0, 3.0 };
   complex<double> pbal, baliozehatz;

   resfexact( x, k, pbal );
   pistonff( x, k, a, baliozehatz );
   cout << "pbal = " << pbal << '\n';
   cout << "baliozehatz = " << baliozehatz << '\n';
}


Last edited on
Ok, the code from @lastchance worked. Thanks a lot!
Topic archived. No new replies allowed.