我有两个浮点数向量,我希望它们成为一个复数向量。我被困住了。我不介意使用迭代器,但我确信它会重新发现我不知道的轮子。我的代码引导我走向正确的方向吗?
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();
在这里,您正在创建一个“复杂”对象,其实部和虚部是浮点向量。
也许您真正想做的是创建一个复杂对象的向量,其实部和虚部都是浮点数?
编辑:myComplexVector 不是向量,是一个复数。这就是为什么它的
const_iterator
没有被定义。
为什么不做得更简单呢?
vector< complex<float> > result;
for( int i = 0; i < vA.size(); i++ ) {
result.push_back( complex<float>( vA[i], vB[i] ) );
}
最简单的方法就是编写循环
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 类型。
您可以创建一个通用的“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中有这样的函数...
这没有任何意义:
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] ) );
}
复数只是一对两个实数
a
和 b
,表示复数 a+bi
。你到底想用这两个向量做什么?
我理解你的问题,你想将实部向量与虚部向量组合成复数向量。
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
),尽量避免这种情况。
Boost Zip 迭代器了解一般想法)。
#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;
}