JayBeams  0.1
Another project to have fun coding.
ut_plan.cpp
Go to the documentation of this file.
1 #include <jb/fftw/plan.hpp>
3 #include <valgrind/valgrind.h>
4 
5 #include <boost/test/unit_test.hpp>
6 #include <algorithm>
7 
8 /**
9  * Helper functions to test jb::fftw::plan
10  */
11 namespace {
12 
13 template <typename precision_t>
14 void test_plan_complex2complex() {
15  int nsamples = 1 << 15;
16  int tol = nsamples;
17 
18  typedef std::complex<precision_t> complex;
19 
20  std::vector<complex> in(nsamples);
21  std::vector<complex> tmp(nsamples);
22  std::vector<complex> out(nsamples);
23 
24  std::size_t h = nsamples / 2;
25  for (std::size_t i = 0; i != h; ++i) {
26  in[i] = complex(i - h / 4.0, 0);
27  in[i + h] = complex(h / 4.0 - i, 0);
28  }
29 
30  auto dir = jb::fftw::create_forward_plan(in, tmp);
31  auto inv = jb::fftw::create_backward_plan(tmp, out);
32 
33  dir.execute(in, tmp);
34  inv.execute(tmp, out);
35  for (std::size_t i = 0; i != std::size_t(nsamples); ++i) {
36  out[i] /= nsamples;
37  }
39 }
40 
41 template <typename precision_t>
42 void test_plan_real2complex() {
43  int nsamples = 1 << 15;
44  int tol = nsamples;
45 
46  typedef std::complex<precision_t> complex;
47 
48  std::vector<precision_t> in(nsamples);
49  std::vector<complex> tmp(nsamples);
50  std::vector<precision_t> out(nsamples);
51 
52  std::size_t h = nsamples / 2;
53  for (std::size_t i = 0; i != h; ++i) {
54  in[i] = i - h / 4.0;
55  in[i + h] = h / 4.0 - i;
56  }
57 
58  auto dir = jb::fftw::create_forward_plan(in, tmp);
59  auto inv = jb::fftw::create_backward_plan(tmp, out);
60 
61  dir.execute(in, tmp);
62  inv.execute(tmp, out);
63  for (std::size_t i = 0; i != std::size_t(nsamples); ++i) {
64  out[i] /= nsamples;
65  }
67 }
68 
69 template <typename precision_t>
70 void test_plan_errors() {
71  int nsamples = 1 << 15;
72 
73  typedef std::complex<precision_t> complex;
74 
75  std::vector<complex> in(nsamples);
76  std::vector<complex> tmp(nsamples);
77  std::vector<complex> err(nsamples / 2);
78 
79  BOOST_CHECK_THROW(jb::fftw::create_forward_plan(in, err), std::exception);
80  BOOST_CHECK_THROW(jb::fftw::create_backward_plan(in, err), std::exception);
81 
82  auto dir = jb::fftw::create_forward_plan(in, tmp);
83  BOOST_CHECK_THROW(dir.execute(in, err), std::exception);
84 }
85 
86 } // anonymous namespace
87 
88 /**
89  * @test Verify that we can create and operate a jb::fftw::plan<double>
90  */
91 BOOST_AUTO_TEST_CASE(fftw_plan_complex_double) {
92  test_plan_complex2complex<double>();
93 }
94 
95 /**
96  * @test Verify that we can create and operate a jb::fftw::plan<double>
97  */
98 BOOST_AUTO_TEST_CASE(fftw_plan_double) {
99  test_plan_real2complex<double>();
100 }
101 
102 /**
103  * @test Verify jb::fftw::plan<double> detects obvious errors
104  */
105 BOOST_AUTO_TEST_CASE(fftw_plan_error_double) {
106  test_plan_errors<double>();
107 }
108 
109 /**
110  * @test Verify that we can create and operate a jb::fftw::plan<float>
111  */
112 BOOST_AUTO_TEST_CASE(fftw_plan_complex_float) {
113  test_plan_complex2complex<float>();
114 }
115 
116 /**
117  * @test Verify that we can create and operate a jb::fftw::plan<float>
118  */
119 BOOST_AUTO_TEST_CASE(fftw_plan_float) {
120  test_plan_real2complex<float>();
121 }
122 
123 /**
124  * @test Verify jb::fftw::plan<float> detects obvious errors
125  */
126 BOOST_AUTO_TEST_CASE(fftw_plan_error_float) {
127  test_plan_errors<float>();
128 }
129 
130 /**
131  * @test Verify that we can create and operate a jb::fftw::plan<long double>
132  */
133 BOOST_AUTO_TEST_CASE(fftw_plan_complex_long_double) {
134  if (RUNNING_ON_VALGRIND > 0) {
135  BOOST_TEST_MESSAGE("long double not supported by valgrind, skip test");
136  return;
137  }
138  test_plan_complex2complex<long double>();
139 }
140 
141 /**
142  * @test Verify that we can create and operate a jb::fftw::plan<long double>
143  */
144 BOOST_AUTO_TEST_CASE(fftw_plan_long_double) {
145  if (RUNNING_ON_VALGRIND > 0) {
146  BOOST_TEST_MESSAGE("long double not supported by valgrind, skip test");
147  return;
148  }
149  test_plan_real2complex<long double>();
150 }
151 
152 /**
153  * @test Verify jb::fftw::plan<long double> detects obvious errors
154  */
155 BOOST_AUTO_TEST_CASE(fftw_plan_error_long_double) {
156  if (RUNNING_ON_VALGRIND > 0) {
157  BOOST_TEST_MESSAGE("long double not supported by valgrind, skip test");
158  return;
159  }
160  test_plan_errors<long double>();
161 }
plan< in_array_type, out_array_type > create_forward_plan(in_array_type const &in, out_array_type &out, int flags=default_plan_flags)
Create a plan to compute many DFTs given the input and output arrays.
Definition: plan.hpp:231
plan< in_array_type, out_array_type > create_backward_plan(in_array_type const &in, out_array_type &out, int flags=default_plan_flags)
Create a plan to compute many inverse DFT given the input and output arrays.
Definition: plan.hpp:261
BOOST_AUTO_TEST_CASE(fftw_plan_complex_double)
Definition: ut_plan.cpp:91
bool check_collection_close_enough(collection_t const &a, collection_t const &b, int tol=1, int max_differences_printed=JB_TESTING_MAX_DIFFERENCES_PRINTED)
Given two collections of numbers of the same value type, find the differences that are out of a given...
std::size_t nsamples(container_type const &a)
Count the elements in the last dimension of a vector-like container.