如何从两个向量(实数和图像)获取复数向量

问题描述 投票:0回答:8

我有两个浮点数向量,我希望它们成为一个复数向量。我被困住了。我不介意使用迭代器,但我确信它会重新发现我不知道的轮子。我的代码引导我走向正确的方向吗?

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();
c++ stl vector complex-numbers
8个回答
5
投票

在这里,您正在创建一个“复杂”对象,其实部和虚部是浮点向量。
也许您真正想做的是创建一个复杂对象的向量,其实部和虚部都是浮点数?

编辑:myComplexVector 不是向量,是一个复数。这就是为什么它的

const_iterator
没有被定义。


3
投票

为什么不做得更简单呢?

vector< complex<float> > result;
for( int i = 0; i < vA.size(); i++ ) {
    result.push_back( complex<float>( vA[i], vB[i] ) );
}

1
投票

最简单的方法就是编写循环

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

编辑:...并按照 Neil 的建议正确声明 myComplexVector 类型。


1
投票

您可以创建一个通用的“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
投票

这没有任何意义:

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
投票

复数只是一对两个实数

a
b
,表示复数
a+bi
。你到底想用这两个向量做什么?


0
投票

我理解你的问题,你想将实部向量与虚部向量组合成复数向量。

std::complex
有一个模板参数,可让您选择复数各部分的数字表示(即,如果您想要基于
double
float
或什至某种自定义数字类型的复数值...)。然后,复杂类型根据底层类型定义基本复杂代数。

在您的代码中,您试图基于浮点数向量构造一个复数类型(即具有实部和虚部为向量的single复数值),这显然是错误的。相反,您需要一个 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 迭代器了解一般想法)。


0
投票
使用 c++23,这很容易。

#include <vector> #include <ranges> #include <complex> int main() { const std::vector<float> real { 1.0f, 2.0f, 3.0f}; const std::vector<float> imaginary { 4.0f, 5.0f, 6.0f}; const auto toComplex = [](const float& real, const float& imaginary) { return std::complex<float>(real, imaginary); }; const std::vector<std::complex<float>> myComplexVector = std::views::zip_transform(toComplex, real, imaginary) | std::ranges::to<std::vector>(); return 0; }
    
© www.soinside.com 2019 - 2024. All rights reserved.