Skip to content

Add FFT in Rust #688

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

Merged
merged 7 commits into from
Jul 5, 2020
Merged

Conversation

fanninpm
Copy link
Contributor

@fanninpm fanninpm commented May 6, 2020

@Liikt (and maybe @strega-nil) I felt like I had to do something dirty a little bit inelegant in order to make Clippy shut up. (You'll see what I mean.)

fanninpm added 2 commits May 6, 2020 12:46
This code is incomplete right now. (It hasn't resolved all compiler
warnings/errors, and I haven't put it through Clippy yet.)
Liikt
Liikt previously requested changes May 20, 2020
Copy link

@Liikt Liikt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change all the &[Complex<f64>] to Vec<Complex<f64>> then you can drop the references and just move the value into the functions.

@berquist berquist added the Implementation This provides an implementation for an algorithm. (Code and maybe md files are edited.) label May 24, 2020
Copy link
Member

@berquist berquist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a big ask, but I think that, like at least the Julia and C implementations, this should compare to FFTW. It looks like the de facto crate is https://crates.io/crates/fftw.

let mut v = Complex::new(1.0_f64, 0.0_f64);
for k in 0..((stride / 2) as usize) {
let k_plus_j = new_x[k + j];
let k_plus_j_plus_half_stride = new_x[k + j + ((stride / 2) as usize)];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this intermediate and k_plus_j_plus_half_stride_2, since they're only used in one place each, don't buy you anything and make the code harder to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In getting rid of those three intermediates, I had to sacrifice the -= operator. If I didn't do that, the compiler warns that I "cannot borrow new_x as immutable because it is also borrowed as mutable".

})
.sum()
})
.collect::<Vec<_>>()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The turbofish isn't necessary here due to the return type in the function signature.

}
let y = cooley_tukey(&x.clone());
let z = iterative_cooley_tukey(&x.clone());
let t = dft(&x.clone());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed, these don't need to be cloned either.

I also think that you should leave the functions as not taking ownership.

fanninpm added 3 commits May 24, 2020 15:15
We don't need to borrow a clone of an object if we only need to borrow
the object.
@fanninpm
Copy link
Contributor Author

Maybe a big ask, but I think that, like at least the Julia and C implementations, this should compare to FFTW. It looks like the de facto crate is https://crates.io/crates/fftw.

@berquist I'll try to add references to fftw later. (Note that #686 actually uses a different crate that offers a pure Rust FFT implementation.)

@berquist
Copy link
Member

If you think using rustfft is better than fftw, then go ahead, I have no preference. Which crate is used is pretty clear from the import. Since we don't have Cargo.toml, you might want to specify in a code comment which version(s) you're using.

@fanninpm
Copy link
Contributor Author

@berquist I have implemented rustfft into a new function fft(). Is there anything else that needs to be addressed before this gets merged?

@berquist
Copy link
Member

berquist commented Jul 5, 2020

I think this will be fine, but is there a better way for me to test this other than creating a temporary Cargo package and running it inside?

@jdonszelmann
Copy link
Contributor

jdonszelmann commented Jul 5, 2020

I tested my last submission with just rustc. rustc myprogram.rs && ./myprogram but that's a lot harder when using libraries etc. I think this is an issue fore more languages where you need some sort of project structure for the program to work properly. Maybe include this structure in the AAA? I know it might clutter up some things a bit, but new users may not know that this structure is required, and for those it might actually be very useful.

@fanninpm
Copy link
Contributor Author

fanninpm commented Jul 5, 2020

is there a better way for me to test this other than creating a temporary Cargo package and running it inside?

@berquist @jonay2000 Currently, there isn't any way to test this without doing the above. (See #691 for further description.)

@berquist
Copy link
Member

berquist commented Jul 5, 2020

I'm getting

error[E0308]: mismatched types
  --> src/main.rs:19:25
   |
19 |     transformer.process(&mut new_x, &mut y);
   |                         ^^^^^^^^^^ expected slice, found struct `std::vec::Vec`
   |
   = note: expected mutable reference `&mut [rustfft::num_complex::Complex<_>]`
              found mutable reference `&mut std::vec::Vec<num::Complex<f64>>`

error[E0308]: mismatched types
  --> src/main.rs:19:37
   |
19 |     transformer.process(&mut new_x, &mut y);
   |                                     ^^^^^^ expected slice, found struct `std::vec::Vec`
   |
   = note: expected mutable reference `&mut [rustfft::num_complex::Complex<_>]`
              found mutable reference `&mut std::vec::Vec<num::Complex<f64>>`

with num = 0.3.0, rand = 0.7.3, and rustfft = 3.0.1. Which version of rustfft should I use?

Copy link
Member

@berquist berquist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks!

@berquist berquist dismissed Liikt’s stale review July 5, 2020 22:47

Moving the arguments into the functions doesn't seem important, since you don't need to take ownership of the input, unless you can figure out how to do the operations in-place.

@berquist berquist merged commit 8e6cb6a into algorithm-archivists:master Jul 5, 2020
@fanninpm fanninpm deleted the fft_in_rust branch July 5, 2020 23:51
PeanutbutterWarrior added a commit to PeanutbutterWarrior/algorithm-archive that referenced this pull request Nov 28, 2021
Amaras pushed a commit that referenced this pull request Nov 28, 2021
* Add rust builder and build script

* Move file to be discovered by SCons, and update Cargo.toml to reflect this

* Add rustc to SCons

* Add Cargo.toml files for code requiring libraries

* Add cargo building when Cargo.toml is present

* Fix copying fail on linux due to directory name and file name collision

* Add build artifacts to SCons clean command and .gitignore

* Fix Not a directory issue due to getting parent directory of a file

* Remove redefinition of languages dictionary

* Add rustc and cargo install to docker

* Update Cooley-Tukey to use correct version of crates

* Update split-operator method to use correct library versions and apply fixes from #688
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Implementation This provides an implementation for an algorithm. (Code and maybe md files are edited.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants