该代码使用哪种FFT算法?

时间:2016-09-05 06:51:52

标签: php fft

我在网上找到它并且没有评论。

它附带一个Complex.class,它基本上模拟了复数及其操作。

我想自己发表评论,但我真的无法确定使用哪种算法。我上网后发现Cooley-Tukey算法是最普遍的,但我不确定这段代码是否使用它。

private $dim;
private $p;
private $ind;
private $func;
private $w1;
private $w1i;
private $w2;

public function __construct($dim) {
    $this->dim = $dim;
    $this->p = log($this->dim, 2);
}


public function fft($func) {
    $this->func = $func;

    // Copying func in w1 as a complex.
    for ($i = 0; $i < $this->dim; $i++)
        $this->w1[$i] = new Complex($func[$i], 0);

    $w[0] = new Complex(1, 0);
    $w[1] = new Complex(cos((-2 * M_PI) / $this->dim), sin((-2 * M_PI) / $this->dim));

    for ($i = 2; $i < $this->dim; $i++)
        $w[$i] = Complex::Cmul($w[$i-1], $w[1]);

    return $this->calculate($w);
}

private function calculate($w) {
    $k = 1;
    $ind[0] = 0;

    for ($j = 0; $j < $this->p; $j++) {
        for ($i = 0; $i < $k; $i++) {
            $ind[$i] *= 2;
            $ind[$i+$k] = $ind[$i] + 1;
        }
        $k *= 2;
    }

    for ($i = 0; $i < $this->p; $i++) {
        $indw = 0;
        for ($j = 0; $j < pow(2, $i); $j++) {
            $inf = ($this->dim / pow(2, $i)) * $j;
            $sup = (($this->dim / pow(2, $i)) * ($j+1)) - 1;
            $comp = ($this->dim / pow(2, $i)) / 2;

            for ($k = $inf; $k <= floor($inf+(($sup-$inf)/2)); $k++)
                $this->w2[$k] = Complex::Cadd(Complex::Cmul($this->w1[$k], $w[0]), Complex::Cmul($this->w1[$k+$comp], $w[$ind[$indw]]));    

            $indw++;

            for ($k = floor($inf+(($sup-$inf)/2)+1); $k <= $sup; $k++)
                $this->w2[$k] = Complex::Cadd(Complex::Cmul($this->w1[$k], $w[$ind[$indw]]), Complex::Cmul($this->w1[$k-$comp], $w[0]));

            $indw++;
        }

        for($j = 0; $j < $this->dim; $j++)
            $this->w1[$j] = $this->w2[$j];
    }

    for ($i = 0; $i < $this->dim; $i++)
        $this->w1[$i] = $this->w2[$ind[$i]];

    return $this->w1;
}

1 个答案:

答案 0 :(得分:0)

这是基于Cooley-Tukey算法的基数2 FFT实现,其工作在“计算”功能中完成。它只适用于2的幂的FFT长度,虽然我没有在函数本身中看到任何参数检查。

$ i迭代多个FFT通道(其中有log2(N),其中N是FFT的长度),并且在每次通过中,旋转因子(存储在$ w中)乘以来自的输出在找到复杂的和与差之前的前一阶段。

有更好的FFT实现,例如FFTW,它实现了混合基数方法,允许计算任意长度的FFT。