/** * Returns an array of complex numbers representing the frequency spectrum * of real valued time domain sequence array. (count($array) must be integer power of 2) * Inspired by http://rosettacode.org/wiki/Fast_Fourier_transform#Python * * @param array $array Real-valued series input, eg. time-series. * @return array Array of complex numbers representing input signal in Fourier domain. * @throws \Exception */ public static function fft($array) { $arrayLength = count($array); if ($arrayLength <= 1) { return array(new Complex($array[0], 0)); } if (log($arrayLength) / M_LN2 % 1 !== 0) { throw new \Exception('Array length must be integer power of 2'); } $even = self::fft(self::segment($array, 0, 2)); $odd = self::fft(self::segment($array, 1, 2)); $result = array(); $halfLength = $arrayLength / 2; for ($k = 0; $k < $arrayLength; ++$k) { $phase = -2 * M_PI * $k / $arrayLength; $phasor = new Complex(cos($phase), sin($phase)); if ($k < $halfLength) { $result[$k] = $even[$k]->add($phasor->multiply($odd[$k])); } else { $result[$k] = $even[$k - $halfLength]->subtract($phasor->multiply($odd[$k - $halfLength])); } } return $result; }
/** * Returns the cosine of this complex number. * * @return Complex the cosine of this complex number. */ public function cos() { $e = new Complex(M_E, 0); $i = new Complex(0, 1); $negativeI = new Complex(0, -1); $numerator = $e->complexPow($i->multiply($this))->add($e->complexPow($negativeI->multiply($this))); return $numerator->divide(new Complex(2, 0)); }