【问题标题】:Using std::complex with iPhone's vDSP functions将 std::complex 与 iPhone 的 vDSP 功能一起使用
【发布时间】:2011-09-24 09:54:33
【问题描述】:

我一直在编写一些 vDSP 代码,但遇到了一个烦人的问题。我的代码是跨平台的,因此使用 std::complex 来存储它的复杂值。

现在我假设我可以按如下方式设置 FFT:

DSPSplitComplex dspsc;
dspsc.realp = &complexVector.front().real();
dspsc.imagp = &complexVector.front().imag();

然后在适当的 vDSP_fft_* 调用中使用 2 的步幅。

但是这似乎不起作用。我可以通过做一个 vDSP_ztoc 来解决这个问题,但这需要我真的不想闲逛的临时缓冲区。有没有办法直接在交错的复杂数据上使用 vDSP_fft_* 函数?也有人能解释为什么我不能像上面那样以 2 的步幅做吗?

谢谢

编辑:正如 Bo Persson 指出的那样,real 和 imag 函数实际上并不返回引用。

但是,如果我改为执行以下操作,它仍然不起作用

DSPSplitComplex dspsc;
dspsc.realp = ((float*)&complexVector.front()) + 0;
dspsc.imagp = ((float*)&complexVector.front()) + 1;

所以我原来的问题仍然存在:(

【问题讨论】:

  • @Mat:vDSP_fft_* 调用返回不正确的数据。

标签: iphone c++ c vdsp


【解决方案1】:

std::complex 函数 real()imag() 按值返回,它们不返回对 complex 成员的引用。

这意味着您无法通过这种方式获取他们的地址。

【讨论】:

  • 啊,没注意到!干杯!所以无论如何它都行不通......臭虫。
  • 根据 C++11,您应该能够将指向 std::complex 的指针转换为指向两个浮点数(或双精度数)数组的指针。不过,我们不知道这是否适用于早期的编译器。
【解决方案2】:

这就是你的做法。

const COMPLEX *in = reinterpret_cast<const COMPLEX*>(std::complex);

来源:http://www.fftw.org/doc/Complex-numbers.html

编辑: 澄清来源; COMPLEX 和 fftw_complex 使用相同的数据布局(尽管 fftw_complex 使用 double 和 COMPLEX float

【讨论】:

  • FFTW 与 vDSP 有什么关系?
  • COMPLEX 和 fftw_complex 使用相同的数据布局(尽管 fftw_comples 使用双精度数和 COMPLEX 浮点数)。我已经验证了这个演员表,它适用于 vDSP_* 函数。
  • 绝对不是。 DSPSplitComplexvDSP_fft_* 函数所必需的,并且是非交错格式。 std::complex 和 FFTW 的 COMPLEX 都是交错的。当然你可以使用vDSP_ctoz/vDSP_ztoc,但这个问题的重点是避免这样做。
  • 我的评论是正确的,COMPLEXfftw_complex 类型代表相同的数据布局。但是,我误解了你的问题。我很清楚vDSP_fft_* 需要COMPLEX_SPLIT (DSPSplitComplex) 和vDSP_ctoz。我想您的一种解决方法可能是使用 fftw 而不是 Accelerate,因为它允许您使用交错布局。它们对小输入的表现相似。基准测试:gist.github.com/admsyn/3452792
  • 除非我需要为 FFTW 或 GPL 购买基于 iPhone 的商用产品的许可证。因此,这真的不是一个有用的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 2021-04-04
  • 2022-12-20
  • 2014-04-27
  • 2015-06-21
  • 2014-08-29
相关资源
最近更新 更多