Я нашел это онлайн, и нет никаких комментариев.
Он поставляется с Complex.class, который в основном имитирует комплексные числа и их операции.
Я хотел бы прокомментировать это сам, но я действительно не могу определить, какой алгоритм используется. Я вышел в интернет и обнаружил, что алгоритм Кули-Тьюки является наиболее распространенным, но я не уверен, что этот код использует его.
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;
}
Это основанная на алгоритме 2 FFT основанная на алгоритме Кули-Тьюки работа, выполняемая с помощью функции «вычислить». Он будет работать только с длинами FFT, которые имеют степень 2, хотя я не вижу никакой проверки параметров в самой функции.
$ i повторяется по нескольким проходам FFT (из которых есть log2 (N), где N — длина FFT), и на каждом проходе множители (сохраненные в $ w) умножаются на выходные данные предыдущего этапа прежде чем найти сложную сумму и разницу.
Существуют гораздо лучшие реализации БПФ, такие как БПФ, которые реализуют подход смешанного радиуса, который позволяет вычислять произвольную длину БПФ.
Других решений пока нет …