import { arraySize } from '../../utils/array.js'; import { factory } from '../../utils/factory.js'; var name = 'fft'; var dependencies = ['typed', 'matrix', 'addScalar', 'multiplyScalar', 'divideScalar', 'exp', 'tau', 'i']; export var createFft = /* #__PURE__ */factory(name, dependencies, _ref => { var { typed, matrix, addScalar, multiplyScalar, divideScalar, exp, tau, i: I } = _ref; /** * Calculate N-dimensional fourier transform * * Syntax: * * math.fft(arr) * * Examples: * * math.fft([[1, 0], [1, 0]]) // returns [[{re:2, im:0}, {re:2, im:0}], [{re:0, im:0}, {re:0, im:0}]] * * * See Also: * * ifft * * @param {Array | Matrix} arr An array or matrix * @return {Array | Matrix} N-dimensional fourier transformation of the array */ return typed(name, { Array: _ndFft, Matrix: function Matrix(matrix) { return matrix.create(_ndFft(matrix.toArray())); } }); /** * Perform an N-dimensional Fourier transform * * @param {Array} arr The array * @return {Array} resulting array */ function _ndFft(arr) { var size = arraySize(arr); if (size.length === 1) return _fft(arr, size[0]); // ndFft along dimension 1,...,N-1 then 1dFft along dimension 0 return _1dFft(arr.map(slice => _ndFft(slice, size.slice(1))), 0); } /** * Perform an 1-dimensional Fourier transform * * @param {Array} arr The array * @param {number} dim dimension of the array to perform on * @return {Array} resulting array */ function _1dFft(arr, dim) { var size = arraySize(arr); if (dim !== 0) return new Array(size[0]).fill(0).map((_, i) => _1dFft(arr[i], dim - 1)); if (size.length === 1) return _fft(arr); function _transpose(arr) { // Swap first 2 dimensions var size = arraySize(arr); return new Array(size[1]).fill(0).map((_, j) => new Array(size[0]).fill(0).map((_, i) => arr[i][j])); } return _transpose(_1dFft(_transpose(arr), 1)); } /** * Perform an 1-dimensional Fourier transform * * @param {Array} arr The array * @return {Array} resulting array */ function _fft(arr) { var len = arr.length; if (len === 1) return [arr[0]]; if (len % 2 === 0) { var ret = [..._fft(arr.filter((_, i) => i % 2 === 0), len / 2), ..._fft(arr.filter((_, i) => i % 2 === 1), len / 2)]; for (var k = 0; k < len / 2; k++) { var p = ret[k]; var q = multiplyScalar(ret[k + len / 2], exp(multiplyScalar(multiplyScalar(tau, I), divideScalar(-k, len)))); ret[k] = addScalar(p, q); ret[k + len / 2] = addScalar(p, multiplyScalar(-1, q)); } return ret; } throw new Error('Can only calculate FFT of power-of-two size'); } });