views:

1189

answers:

7

Hi, I have two vectors of floats and i want them to become one vector of Complex numbers. I'm stuck. I don't mind using iterators, but i am sure it'd be rediscovering the wheel i'm not informed about. Is my code leading me in the right direction?

typedef std::vector<float> CVFloat;
CVFloat vA, vB;
//fil vectors
typedef std::complex<CVFloat> myComplexVector;
myComplexVector* vA_Complex = new myComplexVector(vA, vB);

The code above is going through the compiler correctly, but when i want to get single numbers from myComplexVector using iterator i get error "Undefined symbol 'const_iterator'" (Borland C++)

myComplexVector::const_iterator it = vA_Complex->begin();
+4  A: 

Here you are creating a "complex" object whose real and imaginary parts are vectors of floats.
Maybe what you actually want to do is creating a vector of complex objects whose real and imaginary parts are floats?

EDIT: myComplexVector is not a vector, is a complex. That's why a const_iterator for it is not defined.

Paolo Tedesco
Heh, you're right of course. It works perfectly, thank you:) Sometimes it's so easy to get lost with some fake ideas.It is part of bigger project. I optimize convultion and i have to use existing class of dft which holds real and imag vectors separately.
Moyshe
You're welcome :) glad I could help.
Paolo Tedesco
A: 

A complex number is simply a pair of two real numbers a and b which denote the complex number a+bi. What exactly are you trying to do with the two vectors?

Yuval A
+1  A: 

This doesn't make any sense:

typedef std::complex<CVFloat> myComplexVector;

surely you mean

typedef std::complex <float> ComplexFloat;
typedef std::vector <ComplexFloat> CFVector;

or something similar?

Once ou have it you can simply iterate over the float vectors (assuming they contain matching values) and add to your complex vector using push_back():

CFVector v;

for ( int i = 0; i < vA.size(); i++ ) {
  v.push_back( ComplexFloat( vA[i], vB[i] ) );
}
anon
+1  A: 

The easiest way is just write the loop

myComplexVector cv;
for(CVFloat::iterator it1=vA.begin(), end1=vA.end(), 
      it2=vB.begin(), end2=vB.end();
    it1!=end1 && it2 != end2; ++it1, ++it2)
  cv.push_back(std::complex(*it1, *it2));

Edit: ... and follow Neil's advice to declare myComplexVector type properly.

jpalecek
+1  A: 

You can create a general "zip" function taking iterators to both vectors, and a convertor functor and an output iterator:

template< typename at_It1, typename at_It2, typename at_Transform, typename at_Out >
void zip( at_It1 from1, const at_It1 to1, 
          at_It2 from2, const at_It2 to2,
          at_Transform  tranformer,
          at_Out& av_Out ) {
    while( from1 != to1 ) {
        av_Out = transformer( *from1, *from2 );
        ++av_Out; ++from1; ++from2;
    }
}

struct DoubleToComplex {
     complex<double> operator()( const double d1, const double d2 ) const {
         return complex<double>( d1, d2 );
     }
};



zip( vA.begin(), vA.end(),
     vB.begin(), vB.end(),
     DoubleToComplex(),
     std::back_inserter( vTarget ) );

And I wish there were such a function in the STL...

xtofl
+1  A: 

Whay not do it much much easier?

vector< complex<float> > result;
for( int i = 0; i < vA.size(); i++ ) {
    result.push_back( complex<float>( vA[i], vB[i] ) );
}
sharptooth
Why to declare simple pair as complex in the time where complex already defined with all necessary operators overloaded?
Mykola Golubyev
You mean the sdt::complex class? I just had no idea it exists before you asked.
sharptooth
A: 

I understand your question that you want to combine a vector of real parts with a vector of imaginary parts into a vector of complex numbers.

std::complex has one template parameter which lets you chose the numerical represenation of the parts of the complex (i.e. if you want complex values based on double or float or even some custom number type...). The complex type then defines basic complex algebra in terms of the underlying type.

In your code you are trying to construct a complex type based on a vector of floats (i.e. a single complex value having a real and imaginary part being a vector), which is obviously wrong. Instead you want a vector of complex numbers of type float

You'd have to do something like:

// ...
typedef std::vector<std::complex<float> > floatComplexVector;
floatComplexVector vA_Complex; // No need to 'new' !?

for (CVFLoat::const_iterator itA = vA.begin(), itB = vB.begin(); 
     itA != vA.end() && itB != vB.end(); 
     ++itA,++itB)
  vA_Complex.push_back(std::complex<float>(*itA, *itB));

Remarks:

  • In most cases it isn't necessary to create containers such as vectors on the heap (i.e. using new) Try to avoid this.

  • Unfortunately the C++ standard library doesnt contain a combining iterator (i.e. one that "automatically" combines two sequences) which would allow a more elegant solution (see Boost Zip iterator for a general idea).

MartinStettner