Assigning values to complex numbers

I am an occasional C++ user mostly doing gfortran. Now I have to harness an FFT c++ module. So I write this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  complex *pSignal = new complex[1024];
  complex valueC;
  double value;
  int N = 1024, nn = 0;
  outFileInput.open ("cppFFTinp.dat");
   
  for (unsigned int Position = 0; Position < N; ++Position)
  {  
     *pSignal++;
     std::imag (valueC) = 0.0;   
     value = 0.5 * (1.0 - cos (2.0 * pi * Position/ (N-1)));
     std::real (valueC) = value;
     pSignal[Position] = valueC;
     outFileInput << Position << "  " << value << endl;
   }   


The code above is an attempt to load discrete values of a function for FFT c++ routines. The input function is real, the routines expect complex input, thus I attempt to define imaginary parts all zeros.

I get a cascade of compile errors that make little sense to me. Before I posted I googled and found to my frustration that people writing language references neglect to give an example of how to make an assignment to a complex number using real and imaginary parts.

Thanks, - A.
Last edited on
closed account (D80DSL3A)
Are you trying to use the C++ complex numbers library?
http://www.cplusplus.com/reference/complex/

It's a template class, so you must specify the numeric type used as its elements.
eg, if type double then:
complex<double> valueC;
You can assign a value to a complex variable this way:
valueC = std::complex<double>(value,0.0);// imag part = 0.0
What is the intent of line 9? It dereferences the pointer, producing a complex value then increments the pointer. You're not using the value, and the offset changes which element line 13 will be referring to. Probably better just remove line 9.
Thanks for the answer. I will sidetrack now. It seems I am having trouble with complex.h header file. There are a few vastly different variants on the web. At the same time it seems to be absent in my standard C library.

My environment is Ubuntu 12.04. The compiler is g++.

So far I have tried a few variants of complex.h I found googling and they all give me an error: complex does not have a type.

What is wrong with these declarations:

1
2
3
4
5
6
7
8
9
10
int main ()
{  
  ofstream outFileInput,outFileOutput;
  complex *pSignal = new complex[1024];
  complex *Output  = new complex[1024];
  complex valueC;
  double value, pi = 3.1415926535897932384626;
  int N = 1024, nn = 0;
  outFileInput.open ("cppFFTinp.dat");
  outFileOutput.open("cppFFTout.dat");


Thanks, - Alex.
1) #include <complex> in the beginning
2) Template parameters for complex class: std::complex<double> *pSignal = new std::complex<double>[1024];
Thank you. First this. It seems I am making progress on my own. I corrected the definitions and that part went through the compiler. Now those statements look this:

1
2
double complex *pSignal = new double complex[1024];
double complex *Output  = new double complex[1024];


which is pretty much as the latest poster suggested, I reckon.

Now I get an error at the statement fun2code suggested. The statement, I want to remind is:

valueC = std::complex<double>(value,0.0);

The error is:

expected unqualified-id before ‘_Complex’

What is the problem?

Thanks, - Alex
Last edited on
Here is working code:
http://coliru.stacked-crooked.com/a/32d05a415c9e9ad7

Study it and look how it works.
Well, so what? You compiled that set of declarations with g++ and got a bunch of warnings that the variables are declared but unused. Big deal. What do you want me to study? Where shall I go from here?

I posted a specific ERROR in my previous post. It is an ERROR. It says: the compiler expects an unqualified-id before '_Complex'

Study it an look how it works.
1) How valueC is declared? Did you declare it properly properly?
There is no error in this statement, as long as previous code is correct. See here: http://coliru.stacked-crooked.com/a/9b479eb868c5b18a
Post complete code and error message with line it refers to.
"How valueC is declared?"

It is in the link you posted: http://coliru.stacked-crooked.com/a/32d05a415c9e9ad7

I don't know how to make it even more clear.
As I shown in another link, your statement is completely correct and there is absolutely no problem with it alone.

If you say that your other code is completely correct too, then it might be a compiler problem. You may want to update or switch compilers.

Also it would really help to post your complete code and not out-of-context lines, so somebody would have a chance to spot actual problem.
OK, I decided to post the "complete code" as you asked. Here it is:

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
 // http://www.librow.com/articles/article-10
#include <iostream>
#include "fft.h"
#include <math.h>
// ****************************
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <stdlib.h> 
#include <complex.h>

// ****************************
using namespace std;
int main ()
{  
  ofstream outFileInput,outFileOutput;
  double complex *pSignal = new double complex[1024];
  double complex *Output  = new double complex[1024];
  double complex valueC;
  double value, pi = 3.1415926535897932384626;
  int N = 1024, nn = 0;
  outFileInput.open ("cppFFTinp.dat");
  outFileOutput.open("cppFFTout.dat");
//   ...Fill signal array with data
   
  for (unsigned int Position = 0; Position < N; ++Position)
  {  
     pSignal++;       
     value = 0.5 * (1.0 - cos (2.0 * pi * Position/ (N-1)));
     valueC = std::complex<double>(value,0.0);
     pSignal[Position] = valueC;
     outFileInput << Position << "  " << value << endl;
   }    


The link on the top is the original FFT c++ code I am trying to use.

Now, the errors are too numerous to post then in entirety. I have to limit the error output to a few lines:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 fft.cpp: In function ‘int main()’:
fft.cpp:30:20: error: expected unqualified-id before ‘_Complex’
fft.cpp:30:20: error: expected ‘;’ before ‘_Complex’
fft.cpp:35:35: error: no matching function for call to ‘CFFT::Forward(__complex__ double*&, __complex__ double*&, int&)’
fft.cpp:35:35: note: candidates are:
fft.h:20:16: note: static bool CFFT::Forward(const complex*, complex*, unsigned int)
fft.h:20:16: note:   no known conversion for argument 1 from ‘__complex__ double*’ to ‘const complex*’
fft.h:26:16: note: static bool CFFT::Forward(complex*, unsigned int)
fft.h:26:16: note:   candidate expects 2 arguments, 3 provided
fft.cpp: At global scope:
fft.cpp:66:41: error: ISO C++ forbids declaration of ‘Input’ with no type [-fpermissive]
fft.cpp:66:63: error: ISO C++ forbids declaration of ‘Output’ with no type [-fpermissive]
fft.cpp:66:6: error: prototype forbool CFFT::Forward(const __complex__ int*, __complex__ int*, unsigned int)’ does not match any in class ‘CFFT’
fft.h:26:16: error: candidates are: static bool CFFT::Forward(complex*, unsigned int)
 


Now, if I remove my code the file will compile. I've had it before. Somehow my code messes things up down the line also.

Thanks,- Alex

Now I get an error at the statement fun2code suggested. The statement, I want to remind is:
valueC = std::complex<double>(value,0.0);
The error is:
expected unqualified-id before ‘_Complex’

What is the problem?

Impossible to say, because you have not posted sufficiently complete blocks of code.

I can add such statement to the latest code that you link without an error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <fstream>
#include <iostream>
#include <complex> // defines template class complex

using namespace std;

int main ()
{
  ofstream outFileInput,outFileOutput;
  complex<double> *pSignal = new complex<double>[1024];
  complex<double> *Output  = new complex<double>[1024];
  complex<double> valueC(1.0, 2.0); // declares and initializes variable valueC
  double value = 42.0;
  valueC = std::complex<double>(value, 0.0);
  double value, pi = 3.1415926535897932384626;
  int N = 1024, nn = 0;
  outFileInput.open ("cppFFTinp.dat");
  outFileOutput.open("cppFFTout.dat");
}



Edit: You had posted more code while I was writing this (the forum is a bit sluggish to show latest posts). Now the problem is clear: you are using a different "complex".
Last edited on
In this thread everybody assumed you are using C++ complex class.
You are using C complex type which is completely incompatible with C++ one.
Reference for C types: http://en.cppreference.com/w/c/numeric/complex
Reference for C++ class: http://en.cppreference.com/w/cpp/numeric/complex
@MiiNiPaa: Alex did show a link: http://www.librow.com/articles/article-10

That link provides the "fft.h" and a non-standard class complex that is incompatible with both C's _Complex and C++'s std::complex.

That class contains:
1
2
3
4
5
6
7
   //   Assignment
   complex& complex::operator= (const double val)
   {
      m_re = val;
      m_im = 0.;
      return *this;
   }


This particular FFT-implementation depends on that custom class complex, so the application should use nothing "complex-related" from the standard library.


Lesson 1. Know what you are dealing with. You need the proprietary "complex.h"
Lesson 2. Do not have that using namespace std; It masks other errors.
I sort of suspected what you are saying, that complex.h might be the culprit. I do have a different complex.h in the folder where my source code resides. I got it at the same website. So, I should be all set with that. That complex.h is proprietary. It does contain the Assignment you posted.

When I commented out using namespace std; I got a new cascade of errors. None of them can be resolved without the std library.

Thanks, - Alex
Last edited on
The problem in using namespace std; is that it brings all names from standard library into the global namespace.

You can either use the std:: prefix on all the library names in the code or use different "using" for frequently used names. For example:
1
2
3
4
5
using std::ofstream;
using std::cout;
using std::endl;

// now this scope can use names 'ofstream', 'cout', 'endl' without std:: prefix 

See http://www.gotw.ca/gotw/053.htm

You can also use type aliases:
1
2
3
4
5
using std::begin;
using ComplexV = std::vector<complex>; // alias

ComplexV myarray( 42 ); // real type is std::vector<complex>
ComplexV::iterator it= begin(myarray);
keskiverto, thank you. It is very interesting. I am learning a lot in here. Might take me a few days to test it, it is the end of the weekend now in my area.

- Alex
OK, I am compiling the code now. Thank you for your help. Alex.

P.S. How can I close the thread? Where is the mark "SOLVED?"
Last edited on
Topic archived. No new replies allowed.