Как получить Вектор Комплексных чисел из двух векторов (real & imag) - PullRequest
1 голос
/ 25 марта 2009

У меня есть два вектора с плавающей точкой, и я хочу, чтобы они стали одним вектором комплексных чисел. Я застрял. Я не возражаю против использования итераторов, но я уверен, что это будет открытие колеса, о котором я не информирован. Мой код ведет меня в правильном направлении?

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

Приведенный выше код корректно проходит через компилятор, но когда я хочу получить отдельные числа из myComplexVector с помощью итератора, я получаю сообщение об ошибке "Неопределенный символ 'const_iterator'" (Borland C ++)

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

Ответы [ 7 ]

5 голосов
/ 25 марта 2009

Здесь вы создаете «сложный» объект, действительная и мнимая части которого являются векторами чисел с плавающей точкой.
Возможно, что вы на самом деле хотите сделать, это создать вектор сложных объектов, чья действительная и воображаемая части являются плавающими?

РЕДАКТИРОВАТЬ: myComplexVector не вектор, это комплекс. Вот почему const_iterator для него не определено.

2 голосов
/ 25 марта 2009

Почему бы не сделать это намного проще?

vector< complex<float> > result;
for( int i = 0; i < vA.size(); i++ ) {
    result.push_back( complex<float>( vA[i], vB[i] ) );
}
2 голосов
/ 25 марта 2009

Вы можете создать общую функцию "zip", которая будет принимать итераторы для обоих векторов, функтор конвертора и выходной итератор:

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 ) );

И хотелось бы, чтобы в STL была такая функция ...

1 голос
/ 25 марта 2009

Самый простой способ - написать цикл

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));

Редактировать: ... и следовать совету Нила, чтобы правильно объявить тип myComplexVector.

1 голос
/ 25 марта 2009

Это не имеет никакого смысла:

typedef std::complex<CVFloat> myComplexVector;

конечно, вы имеете в виду

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

или что-то подобное?

Как только у вас есть это, вы можете просто перебрать векторы с плавающей точкой (при условии, что они содержат совпадающие значения) и добавить к вашему сложному вектору, используя push_back ():

CFVector v;

for ( int i = 0; i < vA.size(); i++ ) {
  v.push_back( ComplexFloat( vA[i], vB[i] ) );
}
0 голосов
/ 25 марта 2009

Я понимаю ваш вопрос, что вы хотите объединить вектор действительных частей с вектором мнимых частей в вектор комплексных чисел.

std::complex имеет один шаблонный параметр, который позволяет вам выбирать числовое представление частей комплекса (то есть, если вы хотите, чтобы комплексные значения основывались на double или float или даже каком-либо пользовательском типе числа ...). Комплексный тип тогда определяет базовую комплексную алгебру в терминах базового типа.

В вашем коде вы пытаетесь создать сложный тип на основе вектора чисел с плавающей точкой (т. Е. одиночное комплексное значение, имеющее действительную и мнимую часть, являющуюся вектором), что, очевидно, неверно. Вместо этого вам нужен вектор комплексных чисел типа float

Вы должны сделать что-то вроде:

// ...
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));

Примечания:

  • В большинстве случаев нет необходимости создавать контейнеры, например векторы, в куче (т. Е. Используя new). Постарайтесь избежать этого.

  • К сожалению, стандартная библиотека C ++ не содержит объединяющего итератора (то есть того, который «автоматически» объединяет две последовательности), который позволял бы более элегантное решение (для общей идеи см. Boost Zip iterator ) .

0 голосов
/ 25 марта 2009

Комплексное число - это просто пара двух действительных чисел a и b, которые обозначают комплексное число a+bi. Что именно вы пытаетесь сделать с двумя векторами?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...