C++:在std :: complex和2x浮点值之间转换以用作接口

use*_*501 1 c++

Breif

我希望能够在复制数据时以最小的开销在std :: complex和float之间进行转换.(如果可能,根本没有.)

情况

我有一个包含数据样本的类.在类的一侧,有一个程序以std :: complex的形式读写数据.数据要么都是实数值,要么都是虚数,因此输入是(float*).在类中,有一个函数执行处理,例如傅立叶变换处理,它接受float*的参数.(指向浮点数的指针.)类中的数据存储在std :: vector中.

因此描述是;

std::vector<std::complex<float>>;

这种选择的原因是输出并不总是实数或虚数.使用vector.at(index).real()或vector.at(index).imag()访问数据将是有利的,因为这使得编码其他函数(例如计算平均功率的函数)变得更加容易.(另一种方法是使用索引来取消引用指针.通常,我对此方法没有任何问题,但是许多其他SO程序员会告诉你这是一个糟糕的方法,因为你必须能够乘以2并添加up ...在这种情况下,确保你的算法正确变得更加困难,因为数据的存储方式发生了变化[1],因此我同意SO的共识.案件.)

[1]:输入数据是(浮点*)到所有实数值.2个输入值块被交织成两倍大小的数组:real0 = data0 [0],imag0 = data1 [0],real1 = data0 [1],imag1 = data1 [1],......等......

然后将其存储为: { complex(real0, imag0) , complex(real1, imag1) , ... etc ... }

但后来使用FFT进行处理,它使用float*,并使用索引而不是complex.real()和complex.imag().

然后另一组函数使用complex.real()和complex.imag()计算值,而不仅仅是索引.

然后以上述两种形式返回结果:使用std :: vector>&(引用)和float*...

可能的解决方案1

显然,这种改变数据存储方式的方法是愚蠢的.应该是这种或那种方式,而不是很多不同的方式.

不幸的是,我没有编写大部分代码,所以我无法编辑它...解决方案2它是...

可能的解决方案2

可以返回指向vector类中数据的指针.为此,我假设:

std :: complex类按顺序存储实数和虚数值

如果不是这样,以下将不起作用:

// Function inside my_class which returns access to real components
float* getReal(int& stride, int& length)
{
    stride = 2;
    return &my_vector.at(0); // Think this is the same as my_vector.data()?
}

// This is then used in the following way to set all real values to 0.0
void Reset()
{
    int stride, length;
    float* data_p = my_class.getReal(stride, length);
    float* data_p_last_value = data_p + length - 1;

    for(; data_p <= data_p_last_value; ++ data_p)
    {
        (*data_p) = 0.0;
    }
}
Run Code Online (Sandbox Code Playgroud)

但这有点不太好看.有没有另类,更"流畅"或直观的方法?

T.C*_*.C. 7

std::complex是一个非常特殊的类,指定用于与其他语言(包括C)中的复数类型的互操作性.标准保证(§26.4[complex.numbers]/p2,4):

在专业化complex<float>,complex<double>complex<long double>是文字类型(3.9).

[...]

如果z是类型的左值表达式,cv std::complex<T>则:

  • 表达reinterpret_cast<cv T(&)[2]>(z)应该是格式良好的,
  • reinterpret_cast<cv T(&)[2]>(z)[0] 应指定z的实部,和
  • reinterpret_cast<cv T(&)[2]>(z)[1] 应指定z的虚部.

此外,如果a是类型的表达式,cv std::complex<T>*并且表达式a[i]是为整数表达式定义的i,那么:

  • reinterpret_cast<cv T*>(a)[2*i]应指定的实部a[i]
  • reinterpret_cast<cv T*>(a)[2*i + 1]应指定的虚部a[i].

因此,您建议的解决方案2中的方法是安全的模数错误(例如,您使用的lengthReset()未初始化的,并且您的算法似乎将所有内容归零,而不仅仅是真实的部分).