@@ -49,6 +49,18 @@ auto generate_complex_data(std::size_t n) {
4949 return std::move (c) / static_cast <T>(2 ); // divide by 2 (sqrt(2) would be fine too) to make sure FFT doesn't go infinite
5050}
5151
52+ template <
53+ typename T, std::size_t dim,
54+ typename xt::xarray<T> (&hfft) (const xt::xarray<std::complex <T> > &),
55+ typename xt::xarray<std::complex <T> > (&ihfft) (const xt::xarray<T> &)
56+ >
57+ auto generate_hermitian_data (std::size_t n) {
58+ xt::xarray<std::complex <T>, xt::layout_type::row_major> c = generate_complex_data<T, dim>(n);
59+ auto c_fourier = hfft (c);
60+ auto c_hermitian = ihfft (c_fourier);
61+ return std::move (c_hermitian) / static_cast <T>(10 ); // divide away the FFT infinities (hopefully)
62+ }
63+
5264
5365// Some testing output + the actual GoogleTest assert statement
5466template <typename input_t , typename fourier_t , typename output_t >
@@ -256,42 +268,47 @@ TYPED_TEST(TransformAndInvert, realFFT_4D_xtensor) {
256268// //
257269
258270TYPED_TEST (TransformAndInvert, hermFFT_1D_xarray) {
259- xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_complex_data<TypeParam, 1 >(data_size);
260- auto a_fourier = xt::fftw::hfft (a);
271+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_hermitian_data<TypeParam, 1 , xt::fftw::hfft, xt::fftw::ihfft>(data_size);
272+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a_conj = xt::conj (a);
273+ auto a_fourier = xt::fftw::hfft (a_conj);
261274 std::cout << " fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
262- auto should_be_a = xt::fftw::ihfft (a_fourier);
275+ auto should_be_a = xt::conj ( xt:: fftw::ihfft (a_fourier) );
263276 assert_results_complex (a, a_fourier, should_be_a);
264277}
265278
266279TYPED_TEST (TransformAndInvert, hermFFT_2D_xarray) {
267- xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_complex_data<TypeParam, 2 >(data_size);
268- auto a_fourier = xt::fftw::hfft2 (a);
280+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_hermitian_data<TypeParam, 2 , xt::fftw::hfft2, xt::fftw::ihfft2>(data_size);
281+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a_conj = xt::conj (a);
282+ auto a_fourier = xt::fftw::hfft2 (a_conj);
269283 std::cout << " fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
270- auto should_be_a = xt::fftw::ihfft2 (a_fourier);
284+ auto should_be_a = xt::conj ( xt:: fftw::ihfft2 (a_fourier) );
271285 assert_results_complex (a, a_fourier, should_be_a);
272286}
273287
274288TYPED_TEST (TransformAndInvert, hermFFT_3D_xarray) {
275- xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_complex_data<TypeParam, 3 >(data_size);
276- auto a_fourier = xt::fftw::hfft3 (a);
289+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_hermitian_data<TypeParam, 3 , xt::fftw::hfft3, xt::fftw::ihfft3>(data_size);
290+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a_conj = xt::conj (a);
291+ auto a_fourier = xt::fftw::hfft3 (a_conj);
277292 std::cout << " fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
278- auto should_be_a = xt::fftw::ihfft3 (a_fourier);
293+ auto should_be_a = xt::conj ( xt:: fftw::ihfft3 (a_fourier) );
279294 assert_results_complex (a, a_fourier, should_be_a);
280295}
281296
282297TYPED_TEST (TransformAndInvert, hermFFT_nD_n_equals_4_xarray) {
283- xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_complex_data<TypeParam, 4 >(data_size);
284- auto a_fourier = xt::fftw::hfftn<4 >(a);
298+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_hermitian_data<TypeParam, 4 , xt::fftw::hfftn<4 >, xt::fftw::ihfftn<4 >>(data_size);
299+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a_conj = xt::conj (a);
300+ auto a_fourier = xt::fftw::hfftn<4 >(a_conj);
285301 std::cout << " fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
286- auto should_be_a = xt::fftw::ihfftn<4 >(a_fourier);
302+ auto should_be_a = xt::conj (xt:: fftw::ihfftn<4 >(a_fourier) );
287303 assert_results_complex (a, a_fourier, should_be_a);
288304}
289305
290306TYPED_TEST (TransformAndInvert, hermFFT_nD_n_equals_1_xarray) {
291- xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_complex_data<TypeParam, 1 >(data_size);
292- auto a_fourier = xt::fftw::hfftn<1 >(a);
307+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a = generate_hermitian_data<TypeParam, 1 , xt::fftw::hfft, xt::fftw::ihfft>(data_size);
308+ xt::xarray<std::complex <TypeParam>, xt::layout_type::row_major> a_conj = xt::conj (a);
309+ auto a_fourier = xt::fftw::hfftn<1 >(a_conj);
293310 std::cout << " fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
294- auto should_be_a = xt::fftw::ihfftn<1 >(a_fourier);
311+ auto should_be_a = xt::conj (xt:: fftw::ihfftn<1 >(a_fourier) );
295312 assert_results_complex (a, a_fourier, should_be_a);
296313}
297314
@@ -301,31 +318,31 @@ TYPED_TEST(TransformAndInvert, hermFFT_nD_n_equals_1_xarray) {
301318
302319/*
303320TYPED_TEST(TransformAndInvert, hermFFT_1D_xtensor) {
304- xt::xtensor<std::complex<TypeParam>, 1> a = generate_complex_data <TypeParam, 1>(data_size);
321+ xt::xtensor<std::complex<TypeParam>, 1> a = generate_hermitian_data <TypeParam, 1>(data_size);
305322 auto a_fourier = xt::fftw::hfft(a);
306323 std::cout << "fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
307324 auto should_be_a = xt::fftw::ihfft(a_fourier);
308325 assert_results_complex(a, a_fourier, should_be_a);
309326}
310327
311328TYPED_TEST(TransformAndInvert, hermFFT_2D_xtensor) {
312- xt::xtensor<std::complex<TypeParam>, 2> a = generate_complex_data <TypeParam, 2>(data_size);
329+ xt::xtensor<std::complex<TypeParam>, 2> a = generate_hermitian_data <TypeParam, 2>(data_size);
313330 auto a_fourier = xt::fftw::hfft2(a);
314331 std::cout << "fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
315332 auto should_be_a = xt::fftw::ihfft2(a_fourier);
316333 assert_results_complex(a, a_fourier, should_be_a);
317334}
318335
319336TYPED_TEST(TransformAndInvert, hermFFT_3D_xtensor) {
320- xt::xtensor<std::complex<TypeParam>, 3> a = generate_complex_data <TypeParam, 3>(data_size);
337+ xt::xtensor<std::complex<TypeParam>, 3> a = generate_hermitian_data <TypeParam, 3>(data_size);
321338 auto a_fourier = xt::fftw::hfft3(a);
322339 std::cout << "fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
323340 auto should_be_a = xt::fftw::ihfft3(a_fourier);
324341 assert_results_complex(a, a_fourier, should_be_a);
325342}
326343
327344TYPED_TEST(TransformAndInvert, hermFFT_4D_xtensor) {
328- xt::xtensor<std::complex<TypeParam>, 4> a = generate_complex_data <TypeParam, 4>(data_size);
345+ xt::xtensor<std::complex<TypeParam>, 4> a = generate_hermitian_data <TypeParam, 4>(data_size);
329346 auto a_fourier = xt::fftw::hfftn(a);
330347 std::cout << "fourier transform of input before ifft (which is destructive!): " << a_fourier << std::endl;
331348 auto should_be_a = xt::fftw::ihfftn(a_fourier);
0 commit comments