indutny / fft.js

The fastest JS Radix-4/Radix-2 FFT implementation
278 stars 31 forks source link

Entire output is NaN #21

Closed iamtheyammer closed 1 year ago

iamtheyammer commented 1 year ago

Hey there, I'm having a bit of an odd issue when running the realTransform on accelerometer data: the data looks like [-0.338591208,-0.785074071,-1.147213186,0.221686656,...], and my code is as follows:

function fftData(realData) {
  const fftableData = [...] // data array of length 4096

  const f = new FFT(fftableData.length);
  const fftData = f.createComplexArray();
  f.realTransform(fftData, fftableData);
  const output = new Array(fftableData.length);
  f.fromComplexArray(fftData, output);
  return output;
}

Here's the data-- it's just a JSON file inside a ZIP, because GitHub doesn't allow JSON uploads.

However, output is always full of NaN values-- no real values in sight. Any ideas what's going on?

axkibe commented 1 year ago

Works for me...

ouptu is

       8985.555196741,  -565.9589795092131,  -582.6343347672059,
  -452.86248699969997,  -374.0687910148206, -138.37260277601763,
   249.62591038419706, -251.18264992494665,   77.30656682605604,
  -171.10491602836407, -102.15349496270171, -212.96478971333357,
  -134.50077630800266,   6.608230687967804,   251.6455916034614,
    71.67857677531848, -109.15228883410862,  1.1367015129094824,
  -251.78701252522953,   -71.8025025272894,  116.25216788462215,
    251.3443786079466,   56.39223939182003,  -85.08881820177851,
   -206.9329348788527,   -84.1518850477417,  206.29801771172328,

and so on.

Note your fftableData has "null" entries at the end. This is not good. You should pad with zeros. But as said, it works for me nevertheless.

EDIT: Ps but the data you linked looks like

  32.77957749,
  36.11375107,
  28.91525557,
  17.83578997,
  15.88723342,
  16.46950617,
  7.161092026,
  -45.0725789,
  -38.09731139,
...

not the values you posted above.

iamtheyammer commented 1 year ago

Apologies y’all, completely forgot about this issue. Fixed by filtering out the null values, but it would be nice if the function ignored them or threw an error rather than just returning NaN.

axkibe commented 1 year ago

Putting these kind of checks in place would make the function run slower tough, and since this lib seems to be very concerned on maximizing this...

iamtheyammer commented 1 year ago

Right. However, I imagine that at some point they run through the entire array of input (they must?) and so a check could be added there. I’ll check the code and see if I can find it.

iamtheyammer commented 1 year ago

https://github.com/indutny/fft.js/blob/master/lib/fft.js#L152 may be the spot

axkibe commented 1 year ago

Sure thing, but you'll have to add an if, and a if is a branching instruction which will slow down execution times. I don't say it's impossible or even hard, but its a trade off.

If they would use TypedArrays, then of course the contents would be limited to types (so null does get convertes to 0 by the javascript engine). However you still can have NaNs in input, and here it still stands, garbage in, garbage out.