UNPKG

fft

Version:

A Fast Fourier Transform library for JS.

166 lines (120 loc) 4.3 kB
<!DOCTYPE html> <head> <title>fft.js</title> <script src='lib/real.js'></script> <script src='lib/complex.js'></script> <script> function kahanDiff(x, xOffset, xStride, y, yOffset, yStride, n, run) { var sum = 0.0, compensation = 0.0 for (var i = 0; i < x.length / run / xStride; i++) { for (var j = 0; j < run; j++) { var v = Math.abs(x[xOffset + run * xStride * i + j] - y[yOffset + run * yStride * i + j] / n) - compensation var t = sum + v compensation = (t - sum) - v sum = t if (isNaN(sum)) { debugger } } } return sum } function kahanStrideDiff(x, xOffset, xStride, run) { var sum = 0.0, compensation = 0.0 for (var i = 0; i < x.length / run / xStride; i++) { for (var j = run; j < run * xStride; j++) { var v = Math.abs(x[xOffset + run * xStride * i + j]) - compensation var t = sum + v compensation = (t - sum) - v sum = t if (isNaN(sum)) { debugger } } } return sum } function kahanOffsetDiff(x, xOffset) { var sum = 0.0, compensation = 0.0 for (var i = 0; i < xOffset; i++) { var v = Math.abs(x[i]) - compensation var t = sum + v compensation = (t - sum) - v sum = t if (isNaN(sum)) { debugger } } return sum } function testComplex(n) { var i = new Float64Array(2 * n), o1 = new Float64Array(2 * n), o2 = new Float64Array(2 * n) var fft = new FFT.complex(n, false), ifft = new FFT.complex(n, true) for (var j = 0; j < (2 * n); j++) { i[j] = Math.random() } fft.process(o1, 0, 1, i, 0, 1) ifft.process(o2, 0, 1, o1, 0, 1) return kahanDiff(i, 0, 1, o2, 0, 1, n, 2) } function testComplexStride(n) { var iStride = ~~(12 * Math.random()) + 1, o1Stride = ~~(16 * Math.random()) + 1, o2Stride = ~~(5 * Math.random()) + 1 var i = new Float64Array(2 * iStride * n), o1 = new Float64Array(2 * o1Stride * n), o2 = new Float64Array(2 * o2Stride * n) var fft = new FFT.complex(n, false), ifft = new FFT.complex(n, true) for (var j = 0; j < n; j++) { i[2 * j * iStride + 0] = Math.random() i[2 * j * iStride + 1] = Math.random() } fft.process(o1, 0, o1Stride, i, 0, iStride) ifft.process(o2, 0, o2Stride, o1, 0, o1Stride) return [kahanDiff(i, 0, iStride, o2, 0, o2Stride, n, 2), kahanStrideDiff(o2, 0, o2Stride, 2)] } function testRealToComplex(n) { var i = new Float64Array(n), o1 = new Float64Array(2 * n), o2 = new Float64Array(2 * n) var fft = new FFT.complex(n, false), ifft = new FFT.complex(n, true) for (var j = 0; j < n; j++) { i[j] = Math.random() } fft.process(o1, 0, 1, i, 0, 1, 'real') ifft.process(o2, 0, 1, o1, 0, 1) return [kahanDiff(i, 0, 1, o2, 0, 2, n, 1), kahanStrideDiff(o2, 2, 1)] } function testRealToComplexWithOffset(n) { var iOffset = ~~(12 * Math.random()), o1Offset = ~~(12 * Math.random()), o2Offset = ~~(12 * Math.random()) var i = new Float64Array(iOffset + n), o1 = new Float64Array(o1Offset + 2 * n), o2 = new Float64Array(o2Offset + 2 * n) var fft = new FFT.complex(n, false), ifft = new FFT.complex(n, true) for (var j = 0; j < n; j++) { i[iOffset + j] = Math.random() } fft.process(o1, o1Offset, 1, i, iOffset, 1, 'real') ifft.process(o2, o2Offset, 1, o1, o1Offset, 1) return [kahanDiff(i, 1, o2, 2, n, 1), kahanStrideDiff(o2, 2, 1), kahanOffsetDiff(o1, o1Offset), kahanOffsetDiff(o2, o2Offset)] } var count = 0 for (var i = 2; i < 100; i++) { var v = testComplex(i) if (isNaN(v) || v > 1e-12) { console.log('Complex', i, v), count++ } } for (var i = 2; i < 100; i++) { var v = testComplexStride(i) if (isNaN(v[0]) || v[0] > 1e-12 || v[1] > 0) { console.log('Complex Strided', i, v), count++ } } for (var i = 2; i < 100; i++) { var v = testRealToComplex(i) if (isNaN(v[0]) || isNaN(v[1]) || v[0] > 1e-12 || v[1] > 1e-12) { console.log('Real to Complex', i, v), count++ } } for (var i = 2; i < 100; i++) { var v = testRealToComplexWithOffset(i) if (isNaN(v[0]) || isNaN(v[1]) || isNaN(v[2]) || isNaN(v[3]) || v[0] > 1e-12 || v[1] > 1e-12 || v[2] > 0 || v[3] > 0) { console.log('Real to Complex Offset', i, v), count++ } } console.log("Failcount", count) </script> </head>