【问题标题】:Matlab FFT (Fast Fourier Transform) function of non log-base2 numbers非对数base2数的Matlab FFT(快速傅里叶变换)函数
【发布时间】:2012-08-21 11:34:29
【问题描述】:

我正在开发一个应用程序,它使用Apple's Accelerate Framework FFT 函数,我试图让它模仿Matlab's FFT function 的功能。我将当前代码设置为输出方式与我在 matlab 中的输出方式完全相同。唯一不输出相同的情况是数据数组中的元素数量!= 以 2 为底的对数(FFT 技术上必需的)。我想知道是否有人知道 Matlab 函数是如何处理这种情况的。如果我使用苹果代码来做,它会产生不同的结果。

注意:我不是简单地调用 fft(x)。我也 FFT 移位并取绝对值并将其平方。我也在苹果代码中反映了这些,因为它们不受 FFT 的直接影响。它们是事后调用的。

示例 1 - 16 个元素(对数基数 2):类似的输出

Matlab 调用:

x = 1:16;
Fxx = abs(fftshift(fft(x))).^2;

Fxx =

  Columns 1 through 7

64    66.5322    74.9807    92.5736    128    207.3490    437.0193

 Columns 8 through 14

1681.5451    18496    1682.5451    437.0193    207.3490    128    92.5736

  Columns 15 through 16

74.9807    66.5322

*Apple 代码因长度而省略

苹果输出:

Fxx[0] = 64.000000
Fxx[1] = 66.532232
Fxx[2] = 74.980664
Fxx[3] = 92.573612
Fxx[4] = 128.000000
Fxx[5] = 207.349044
Fxx[6] = 437.019336
Fxx[7] = 1681.545112
Fxx[8] = 18496.000000
Fxx[9] = 1681.545112
Fxx[10] = 437.019336
Fxx[11] = 207.349044
Fxx[12] = 128.000000
Fxx[13] = 92.573612
Fxx[14] = 74.980664
Fxx[15] = 66.532232

示例 2 - 10 个元素(不是对数基数 2):不同的输出

Matlab 调用:

x = 1:10;
Fxx = abs(fftshift(fft(x))).^2;

Fxx = 

Columns 1 through 7

25    27.6393    38.1966    72.3607    261.8034    3025    261.8034

Columns 8 through 10

72.3607    38.1966    27.6393

*Apple 代码因长度而省略

苹果输出:

Fxx[0] = 16.000000
Fxx[1] = 45.250000
Fxx[2] = 18.745166
Fxx[3] = 32.000000
Fxx[4] = 109.254834
Fxx[5] = 1296.000000
Fxx[6] = 109.254834
Fxx[7] = 32.000000
Fxx[8] = 18.745166
Fxx[9] = 45.250000

如您所见,它们在第一个示例和第二个示例中显然产生了相同的输出。我已经测试了正输入和负输入,它们唯一不同的时候是它们不是以 2 为基数的。有谁知道 Matlab 如何处理这个问题?也许它用 0 填充数组,直到它的对数基数为 2,然后对某些点进行平均?我做了很多搜索,无法弄清楚在这种特殊情况下他们做了什么来获得他们的输出。

【问题讨论】:

  • 您如何称呼 Accelerate FFT?在原始的主要 Accelerate FFT 调用中,例如 vDSP_fft_zop,长度作为整数传递,该整数是元素数量的以二为底的对数。因此,每个长度都是 2 的幂。有支持其他长度的新 DFT 例程(“FFT”是执行 DFT 数学函数的算法的名称,因此每个 FFT 都是 DFT,而 DFT 更通用),并且有专门长度的旧例程(vDSP_fft3_zop 和 vDSP_fft5_zop)。 DFT 例程支持特定长度 f*2^n,其中 f 为 3、5 或 15。
  • 所有 Accelerate FFT/DFT 例程都执行相同的功能,从输入向量 h 生成输出向量 H,使得 H[k] = sum(e^(-2*pi ij*k/N)*h[j], 0
  • 请注意,对于 FFT,2 的幂不是“技术上必要的”。这是存在最有效实现的情况之一,但还有许多其他算法被认为是 FFT,其大小是许多小素数的复合乘积,即使在某些因素较大的情况下,加速基于字面数学定义的过度实现可能很重要。
  • @twalberg: 对,“快速” (O(n lg n)) 傅立叶变换适用于每个尺寸。

标签: matlab fft accelerate-framework vdsp


【解决方案1】:

来自official MATLAB documentation

FFT 函数(fft、fft2、fftn、ifft、ifft2、ifftn)基于名为 FFTW 的库。

为了在 N 是复合的(即 N = N1N2 时)计算 N 点 DFT,FFTW 库使用 @ 分解问题987654323@,首先计算N1个大小为N2的变换,然后计算N2个大小为N1的变换子>.

当 N 是质数时,FFTW 库首先使用 Rader's algorithm 将 N 点问题分解为三个 (N – 1) 点问题。然后,它使用上述 Cooley-Tukey 分解来计算 (N – 1) 点 DFT。

我不确定 Apple 的 Accelerate Framework 如何计算此类 FFT,但我更喜欢 MATLAB 来产生正确的结果。

【讨论】:

    【解决方案2】:

    这并没有解决您的问题,但我注意到计算。如果您对结果进行平方,绝对值是一种浪费的操作。如果速度是一个问题,把它拿出来。此外,不是计算 x^2 而是计算 x*x。您可以更快地获得相同的结果。不知道效率差异是否会很明显,但是当更便宜同样简单或更简单时,计算上更昂贵是没有意义的。

    【讨论】:

      猜你喜欢
      • 2013-10-17
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多