-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FFT functions #46
Comments
Somewhere there will be a border between "basic" functions included in the math.js library, and "advanced" functions located in separate math.js modules. I'm not yet sure where this line will be exactly, but I think this will become clear over time. Let's just start with adding these functions (we definitely need them!), and when some section grows too big/advanced, move the functionality to a separate module. |
Yes, definitely. Once again taking example on numpy, there is only very basic stuff there, and advanced functionality is provided in But FFT is extremely basic stuff. In fact it is in numpy. I can take care of that. |
Nice to have the road paved already by applications like numpy, so we don't have to invent everything ourselves :) |
Nice Library. I desperately need FFT in it. What is the progress with implementation? Can I help? |
FFT is still not implemented, sorry. Help would be welcome here. For now you could use the FFT of for example http://numericjs.com/, you can import functions from this library into math.js if your like. |
FFT/iFFT would need to operate on the real/complex vector. |
I would start with a basic For a second iteration we could optimize performance by using typed arrays. However typed arrays are not (yet) supported by all browsers so the library must be able to fall back on regular Arrays. Support for typed arrays is a needed for all functions of math.js, not just One future matrix type could be a |
I have started small repo here: https://github.com/drom/fourier |
To prevent round-off errors from breaking on round-off errors, we have a little utility approx.js, which compares whether two numbers are approximately equal. https://github.com/josdejong/mathjs/blob/master/tools/approx.js |
I have done KISS implementation of dft / idft. Will do the radix 2 / 4 / 8 / 16 next. For the accuracy will follow the following methodology http://www.fftw.org/accuracy/method.html in order to compare with other FFTs. |
sounds good :) |
I have implemented power-of-2 radix-2 decimation in time version with normal arrays and typed array. |
Interesting to see what typed arrays do for the performance of such an algorithm. If it's just 10-15% it may not even be worth all extra work. Could there be more asm.js related techniques allowing the JS engine to better optimize this? (or is the current implementation already close to what you could get from a bare-bone C implementation?...) |
I have opened relevant issue here: drom/fourier#1 |
Thanks. So if I understand it correctly:
|
I have done some more experiments with FFT code. Results are here: drom/fourier#1 |
@josdejong take a look at the emscripten compilation of FFTW that I upload to this repository: https://github.com/echo66/FFTW3-emscripten/ |
It does not look complete. How can one use it? I have implemented asm.js version of my FFT. You can see the results. |
@drom , look at this file: https://github.com/echo66/FFTW3-emscripten/blob/master/test_code.js |
@echo66 As i mentioned above, it does not look like FFT implementation. How do you use this code? |
Oh, I just noticed that I forgot to upload the compiled files. Done. Just open the simple_1d_wrapper.html and see the results. |
The initial delay is due to the loading of the "simple_1d_wrapper.js" file (1.4 MB). |
@echo66 it is better now. But, how dose one simply use it? Can you benchmark it for 64K with jsperf, or benchmark.js ? |
A comparison between several FFT solutions: http://jsperf.com/comparing-two-fft-functions/3 I will add @drom FFT code to it. @drom, can you upload a "browserified" version of your library? Btw, It is kind of ironic to see that chrome is faster than firefox when dealing with ASM code. x) |
It is kind of ironic to see that chrome is faster than firefox when dealing with ASM code. x) |
@echo66 I have added browserified version of my FFT. And updated your benchmark to use it. |
An exaustive benchmark for FFTWJS and drom's FFT: Can you check if I'm using fourier.js in the right way? @drom, can you describe the details of your implementation, regarding optimization and code templates? I'm really interested in knowing more about those. |
@echo66 your benchmark look fine to me.
More details are here: drom/fourier#1 |
If you create a multidimensional version of fourier.js, I see no reason to use FFTWJS. |
@echo66 I have never done Nd FFT in my life. Can you suggest good description? reference code? or pull request? ;) |
Sorry, I never implemented a FFT before. :/ Still, you have this implementation: https://github.com/scijs/ndarray-fft |
Note 1: for each execution of forward and inverse in the FFTW wrapper, I'm creating a new FFTW plan. And it is always the same type of plan. I probably should take a look at it. Note 2: for all browsers in the benchmark, the FFTWJS has a stable, but sub-optimal, performance. Note 3: I didn't include the other FFT implementations because they presented some memory problems in previous tests, when dealing with "big" vectors (32768, 65536). |
Hi Jos, Created a simple FFT implementation with radix-2. This is a decimation-in-time version. It is out-of-place, memory/space complexity is not optimized. Implementation details are common knowledge, for example on https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm https://gist.github.com/mrquincle/b11fff96209c9d1396b0 I haven't visualized it, but this should be nice to combine with vis.js. Cheers, Anne |
Thanks Anne, that looks neat! Should be quite straight forward to add this code to math.js, though we have to add docs and unit tests of course. Would you like to pick that up too? |
Sure, remind me if I forget. |
great, thanks! |
Hi is this implemented yet? |
No this hasn't been implemented. Anyone interested in picking this up? |
I can do this once I am done the eig functions |
Great, thanks for your offer Arkajit! |
I would like to add a +1 for adding this feature. I'm a physicist trying to create an ObservableHQ notebook to solve the Schrödinger equation. Currently I'm using numjs because it's got FFT, but it doesn't have complex arithmetic so I'm having the create that functionality myself....and probably not doing a good job at it. |
A cool comparison of different implementations of FFT in JavaScript: https://github.com/scijs/fourier-transform/blob/master/benchmark.md |
Which category should the function be implemented in? (Just in case someone will actually implement it.) Also, the multidimensional Fourier transform seems to be a good generalization as the module normally works with multidimensional arrays/matrices. (It may or may not affect the performance to implement this.) |
I think we can add
That sounds good. If there is performance impact I suppose we could have two implementations under the hood (1 dimensional and multi dimensional), and automatically pick the right one. |
* Fix #46 Draft Implementations * Add docs * Fixup * Add type declaration and test * Fixup tests * Fixup test * Format * Add examples in docs * Update fft.js Edit example in docs (`math.fft` returns complex matrix). * Update ifft.js Edit example in docs (`math.ffti` returns complex matrix). * Update fft.js Edit docs examples, representation of complex number from `a+bi` to `{re:a, im:b}` * Update ifft.js Edit docs examples, representation of complex number from `a+bi` to `{re:a, im:b}` * Update index.ts Edit test. Add test for `math.ifft` `math.fft` returns complex matrix. * Update index.ts Use `approx.deepEqual` instead off `assert.deepStrictEqual`. * Update index.ts Format code * Update index.ts Use `assert.ok(math.deepEqual(...))` instead of `approx.deepEqual`. * Update index.ts Format * Update index.ts Typo: replace `approx` with `assert`. Co-authored-by: Jos de Jong <wjosdejong@gmail.com>
As for now, the function can only operate on a power-of-two--size array. It still needs to be fixed to support the input of arbitrary sizes. (Either open a new issue or reopen this one would be fine.) |
Yes that is true. Can you open a new issue about fft support for arbitrary size matrices? |
I don't know if that stays in the scope of mathjs.
If you're interested I can implement them.
The text was updated successfully, but these errors were encountered: