-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfft.js
82 lines (72 loc) · 1.79 KB
/
fft.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict'
var ops = require('ndarray-ops')
var ndarray = require('ndarray')
var pool = require('typedarray-pool')
var fftm = require('./lib/fft-matrix.js')
function ndfft(dir, x, y) {
var shape = x.shape
, d = shape.length
, size = 1
, stride = new Array(d)
, pad = 0
, i, j
for(i=d-1; i>=0; --i) {
stride[i] = size
size *= shape[i]
pad = Math.max(pad, fftm.scratchMemory(shape[i]))
if(x.shape[i] !== y.shape[i]) {
throw new Error('Shape mismatch, real and imaginary arrays must have same size')
}
}
var buf_size = 4 * size + pad
var buffer
if( x.dtype === 'array' ||
x.dtype === 'float64' ||
x.dtype === 'custom' ) {
buffer = pool.mallocDouble(buf_size)
} else {
buffer = pool.mallocFloat(buf_size)
}
var x1 = ndarray(buffer, shape.slice(0), stride, 0)
, y1 = ndarray(buffer, shape.slice(0), stride.slice(0), size)
, x2 = ndarray(buffer, shape.slice(0), stride.slice(0), 2*size)
, y2 = ndarray(buffer, shape.slice(0), stride.slice(0), 3*size)
, tmp, n, s1, s2
, scratch_ptr = 4 * size
//Copy into x1/y1
ops.assign(x1, x)
ops.assign(y1, y)
for(i=d-1; i>=0; --i) {
fftm(dir, size/shape[i], shape[i], buffer, x1.offset, y1.offset, scratch_ptr)
if(i === 0) {
break
}
//Compute new stride for x2/y2
n = 1
s1 = x2.stride
s2 = y2.stride
for(j=i-1; j<d; ++j) {
s2[j] = s1[j] = n
n *= shape[j]
}
for(j=i-2; j>=0; --j) {
s2[j] = s1[j] = n
n *= shape[j]
}
//Transpose
ops.assign(x2, x1)
ops.assign(y2, y1)
//Swap buffers
tmp = x1
x1 = x2
x2 = tmp
tmp = y1
y1 = y2
y2 = tmp
}
//Copy result back into x
ops.assign(x, x1)
ops.assign(y, y1)
pool.free(buffer)
}
module.exports = ndfft