Skip to content

Commit bffb1fb

Browse files
author
preiter
committed
v0.2.2 - change c2r's behavior
1 parent d31b225 commit bffb1fb

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ndrustfft"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
authors = ["preiter <phil.reiter93@gmail.com>"]
55
edition = "2018"
66
description = "N-dimensional FFT, real-to-complex FFT and real-to-real DCT"

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ other axis' will create temporary copies of the input array.
2727
- `dct3`: [`nddct3`],[`nddct3_par`]
2828
- `dct4`: [`nddct4`],[`nddct4_par`]
2929

30+
`ndrustfft` >= v0.2.2:
31+
32+
Real-to-complex transforms now behave like numpys rfft.
33+
The first element (for odd and even input) and the last element (for even input)
34+
of the coefficient array should be real due to Hermitian symmetry.
35+
Thus, the solution of the inverse transform is independent of the imaginary
36+
part of the first and last element (for even input). Note, this is different
37+
to the behaviour of the `RealFft` crate.
38+
3039
### Parallel
3140
The library ships all functions with a parallel version
3241
which leverages the parallel abilities of ndarray.

src/lib.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@
2525
//! - `dct3`: [`nddct3`],[`nddct3_par`]
2626
//! - `dct4`: [`nddct4`],[`nddct4_par`]
2727
//!
28+
//! `ndrustfft` >= v0.2.2:
29+
//!
30+
//! Real-to-complex transforms now behave like numpys rfft.
31+
//! The first element (for odd and even input) and the last element (for even input)
32+
//! of the coefficient array should be real due to Hermitian symmetry.
33+
//! Thus, the solution of the inverse transform is independent of the imaginary
34+
//! part of the first and last element (for even input). Note, this is different
35+
//! to the behaviour of the `RealFft` crate.
36+
//!
2837
//! ## Parallel
2938
//! The library ships all functions with a parallel version
3039
//! which leverages the parallel abilities of ndarray.
@@ -428,6 +437,12 @@ impl<T: FftNum> R2cFftHandler<T> {
428437
a.re = b.re * n64;
429438
a.im = b.im * n64;
430439
}
440+
// First element must be real
441+
indata[0].im = T::zero();
442+
// If original vector is even, last element must be real
443+
if self.n % 2 == 0 {
444+
indata[self.m - 1].im = T::zero();
445+
}
431446
self.plan_bwd.process(&mut indata, out).unwrap();
432447
}
433448

@@ -873,6 +888,40 @@ mod test {
873888
approx_eq(&v, &v_copy);
874889
}
875890

891+
#[test]
892+
fn test_ifft_c2r_first_last_element() {
893+
let n = 6;
894+
let mut v = Array1::<f64>::zeros(n);
895+
let mut vhat = Array1::<Complex<f64>>::zeros(n / 2 + 1);
896+
let solution_numpy_first_elem: Array1<f64> =
897+
array![0.16667, 0.16667, 0.16667, 0.16667, 0.16667, 0.16667];
898+
let solution_numpy_last_elem: Array1<f64> =
899+
array![0.16667, -0.16667, 0.16667, -0.16667, 0.16667, -0.16667];
900+
let mut rfft_handler = R2cFftHandler::<f64>::new(n);
901+
902+
// First element should be purely real, thus the imaginary
903+
// part should not matter. However, original realfft gives
904+
// different results for different imaginary parts
905+
vhat[0].re = 1.;
906+
vhat[0].im = 100.;
907+
// backward
908+
ndifft_r2c(&vhat, &mut v, &mut rfft_handler, 0);
909+
// assert
910+
approx_eq(&v, &solution_numpy_first_elem);
911+
912+
// Same for last element, if input is even
913+
for v in vhat.iter_mut() {
914+
v.re = 0.;
915+
v.im = 0.;
916+
}
917+
vhat[3].re = 1.;
918+
vhat[3].im = 100.;
919+
// backward
920+
ndifft_r2c(&vhat, &mut v, &mut rfft_handler, 0);
921+
// assert
922+
approx_eq(&v, &solution_numpy_last_elem);
923+
}
924+
876925
#[test]
877926
fn test_dct1() {
878927
// Solution from scipy.fft.dct(x, type=1)

0 commit comments

Comments
 (0)