annotate fft/jsfft/test/test_helper.js @ 40:223f770b5341 kissfft-double tip

Try a double-precision kissfft
author Chris Cannam
date Wed, 07 Sep 2016 10:40:32 +0100
parents 66f9fd5ac611
children
rev   line source
Chris@25 1 !function() {
Chris@25 2
Chris@25 3 var EPSILON = 1e-4,
Chris@25 4 assert = require('assert'),
Chris@25 5 complex_array_lib = require('../lib/complex_array'),
Chris@25 6 fft_lib = require('../lib/fft'),
Chris@25 7 ComplexArray = complex_array_lib.ComplexArray,
Chris@25 8 isComplexArray = complex_array_lib.isComplexArray,
Chris@25 9 PI = Math.PI,
Chris@25 10 SQRT2 = Math.SQRT2,
Chris@25 11 SQRT1_2 = Math.SQRT1_2,
Chris@25 12 cos = Math.cos,
Chris@25 13 sin = Math.sin,
Chris@25 14 sqrt = Math.sqrt
Chris@25 15
Chris@25 16 global.assertComplexArraysAlmostEqual = function(first, second) {
Chris@25 17 var message = second + ' != ' + first
Chris@25 18
Chris@25 19 assert.equal(first.length, second.length, message)
Chris@25 20
Chris@25 21 first.forEach(function(value, i) {
Chris@25 22 assertApproximatelyEqual(value.real, second.real[i], message)
Chris@25 23 assertApproximatelyEqual(value.imag, second.imag[i], message)
Chris@25 24 })
Chris@25 25 }
Chris@25 26
Chris@25 27 global.assertFFTMatches = function(original, expected) {
Chris@25 28 var transformed, copy
Chris@25 29
Chris@25 30 if (!isComplexArray(expected)) {
Chris@25 31 throw TypeError('expected match should be a ComplexArray')
Chris@25 32 }
Chris@25 33
Chris@25 34 copy = new ComplexArray(original)
Chris@25 35 transformed = fft_lib.FFT(original)
Chris@25 36 assertComplexArraysAlmostEqual(expected, transformed)
Chris@25 37 assertComplexArraysAlmostEqual(copy, fft_lib.InvFFT(transformed))
Chris@25 38 }
Chris@25 39
Chris@25 40 global.assertFFTMatchesDFT = function(input) {
Chris@25 41 input = new ComplexArray(input)
Chris@25 42
Chris@25 43 assertComplexArraysAlmostEqual(DFT(input), fft_lib.FFT(input))
Chris@25 44 }
Chris@25 45
Chris@25 46 global.DFT = function(input) {
Chris@25 47 var n = input.length,
Chris@25 48 amplitude = 1 / sqrt(n),
Chris@25 49 output = new ComplexArray(input),
Chris@25 50 phase = {real: 0, imag: 0},
Chris@25 51 delta = {real: 0, imag: 0},
Chris@25 52 i, j,
Chris@25 53 _swap
Chris@25 54
Chris@25 55 if (!isComplexArray(input)) {
Chris@25 56 input = new ComplexArray(input)
Chris@25 57 }
Chris@25 58
Chris@25 59 for(i = 0; i < n; i++) {
Chris@25 60 output.real[i] = 0, output.imag[i] = 0
Chris@25 61 phase.real = 1, phase.imag = 0
Chris@25 62 delta.real = cos(2*PI*i/n), delta.imag = sin(2*PI*i/n)
Chris@25 63
Chris@25 64 for(j = 0; j < n; j++) {
Chris@25 65 output.real[i] += phase.real * input.real[j] - phase.imag * input.imag[j]
Chris@25 66 output.imag[i] += phase.real * input.imag[j] + phase.imag * input.real[j]
Chris@25 67 _swap = phase.real
Chris@25 68 phase.real = phase.real * delta.real - phase.imag * delta.imag
Chris@25 69 phase.imag = _swap * delta.imag + phase.imag * delta.real
Chris@25 70 }
Chris@25 71 output.real[i] *= amplitude
Chris@25 72 output.imag[i] *= amplitude
Chris@25 73 }
Chris@25 74
Chris@25 75 return output
Chris@25 76 }
Chris@25 77
Chris@25 78 function assertApproximatelyEqual(first, second, message) {
Chris@25 79 var delta = Math.abs(first - second)
Chris@25 80 assert.ok(delta < EPSILON, message)
Chris@25 81 }
Chris@25 82
Chris@25 83 }()