JayBeams  0.1
Another project to have fun coding.
ut_time_delay_estimator_many.cpp
Go to the documentation of this file.
8 
9 #include <boost/test/unit_test.hpp>
10 #include <chrono>
11 #include <complex>
12 
13 /**
14  * @test Verify that FTE handles a timeseries filled with 0
15  * dimension 3
16  */
17 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_with_0) {
18  int const nsamples = 1 << 15;
19  int const S = 20;
20  int const V = 4;
21  int const confidence_tol = 1;
22 
23  using array_type = jb::fftw::aligned_multi_array<float, 3>;
25  using confidence_type = typename tested_type::confidence_type;
26  using estimated_delay_type = typename tested_type::estimated_delay_type;
27  using sum2_type = typename tested_type::sum2_type;
28 
29  array_type a(boost::extents[S][V][nsamples]);
30  array_type b(boost::extents[S][V][nsamples]);
31  confidence_type confidence(a);
32  // expected confidence result to compare within tolerance tol
33  confidence_type expected_confidence(a);
34 
35  estimated_delay_type argmax(a);
36  // expected argmax result to compare within tolerance tol
37  estimated_delay_type expected_argmax(a);
38 
39  // sum of square value of timeseries
40  sum2_type sum2(a);
41 
42  // construct the tested FTE
43  tested_type tested(a, b);
44 
45  // fill both timeseries with 0
46  int count = 0;
47  for (int i = 0; i != S; ++i) {
48  for (int j = 0; j != V; ++j, ++count) {
49  for (int k = 0; k != nsamples; ++k) {
50  a[i][j][k] = float(0);
51  b[i][j][k] = float(0);
52  }
53  sum2[count] = float(0);
54  expected_argmax[count] = static_cast<std::size_t>(0);
55  expected_confidence[count] = float(0);
56  }
57  }
58 
59  // run the TDE...
60  tested.estimate_delay(confidence, argmax, a, b, sum2);
61  // check confidence within nsamples +/- tol
62  BOOST_CHECK_MESSAGE(
64  confidence, expected_confidence, confidence_tol),
65  "confidence is not within tolerance(" << confidence_tol << ")");
66  // we do not check the value of argmax because in this case it is
67  // meaningless, any value in the range is equally invalid.
68 }
69 
70 /**
71  * @test Verify TDE handles exact same timeseries, delay = 0
72  * dimension 3
73  */
74 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_delay_0) {
75  int const nsamples = 1 << 15;
76  int const S = 20;
77  int const V = 4;
78  int const argmax_tol = 4;
79  // we use a very rough approximation to the confidence error here ...
80  int const confidence_tol = nsamples;
81 
82  using array_type = jb::fftw::aligned_multi_array<float, 3>;
84  using confidence_type = typename tested_type::confidence_type;
85  using estimated_delay_type = typename tested_type::estimated_delay_type;
86  using sum2_type = typename tested_type::sum2_type;
87 
88  array_type a(boost::extents[S][V][nsamples]);
89  array_type b(boost::extents[S][V][nsamples]);
90  confidence_type confidence(a);
91  // expected confidence result to compare within tolerance tol
92  confidence_type expected_confidence(a);
93 
94  estimated_delay_type argmax(a);
95  // expected argmax result to compare within tolerance tol
96  estimated_delay_type expected_argmax(a);
97 
98  // sum of square value of timeseries
99  sum2_type sum2(a);
100 
101  // construct the tested FTE
102  tested_type tested(a, b);
103 
104  // fill the timeseries with triangle or square
106 
107  // no delay a = b
108  int count = 0;
109  for (int i = 0; i != S; ++i) {
110  for (int j = 0; j != V; ++j, ++count) {
111  for (int k = 0; k != nsamples; ++k) {
112  a[i][j][k] = b[i][j][k];
113  }
114  }
115  }
116 
117  // get the square sum
118  sum2 = jb::testing::sum_square(a);
119 
120  // run the TDE...
121  tested.estimate_delay(confidence, argmax, a, b, sum2);
122  // argmax should be around 0, which means possible around nsamples-1 also
123  // so, let's "shift mod" argmax by nsamples/2 in order to make
124  // close_enough check simple to implement...
125  count = 0;
126  std::size_t shift = nsamples / 2;
127  for (int i = 0; i != S; ++i) {
128  for (int j = 0; j != V; ++j, ++count) {
129  expected_confidence[count] = static_cast<float>(nsamples);
130  expected_argmax[count] = shift;
131  argmax[count] = (argmax[count] + shift) % nsamples;
132  }
133  }
134 
135  // check argmax within delay +/- tol
136  BOOST_CHECK_MESSAGE(
138  argmax, expected_argmax, argmax_tol),
139  "argmax is not within tolerance("
140  << argmax_tol << "), argmax[0]=" << argmax[0]
141  << ", expected_argmax[0]=" << expected_argmax[0]);
142  // check confidence within nsamples +/- tol
143  BOOST_CHECK_MESSAGE(
145  confidence, expected_confidence, confidence_tol),
146  "confidence is not within tolerance(" << confidence_tol << ")");
147 }
148 
149 /**
150  * @test Verify that we can create and use a simple time delay estimator
151  * multi array dimension 3, with float value.
152  */
153 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_float) {
154  int const nsamples = 1 << 15;
155  int const S = 20;
156  int const V = 4;
157  int const delay = 2500;
158  // using float, requires higher tolerance
159  int const argmax_tol = 4;
160  // we use a very rough approximation to the confidence error here ...
161  int const confidence_tol = nsamples;
162 
163  using array_type = jb::fftw::aligned_multi_array<float, 3>;
165  using confidence_type = typename tested_type::confidence_type;
166  using estimated_delay_type = typename tested_type::estimated_delay_type;
167  using sum2_type = typename tested_type::sum2_type;
168 
169  array_type a(boost::extents[S][V][nsamples]);
170  array_type b(boost::extents[S][V][nsamples]);
171  confidence_type confidence(a);
172  // expected confidence result to compare within tolerance tol
173  confidence_type expected_confidence(a);
174 
175  estimated_delay_type argmax(a);
176  // expected argmax result to compare within tolerance tol
177  estimated_delay_type expected_argmax(a);
178 
179  // sum of square value of timeseries
180  sum2_type sum2(a);
181 
182  // construct the tested FTE
183  tested_type tested(a, b);
184 
185  // fill the timeseries with triangle or square
187 
188  // a = delay shift timeseries b
189  int count = 0;
190  for (int i = 0; i != S; ++i) {
191  for (int j = 0; j != V; ++j, ++count) {
192  for (int k = 0; k != nsamples; ++k) {
193  a[i][j][k] = b[i][j][(k + delay) % nsamples];
194  }
195  expected_argmax[count] = static_cast<std::size_t>(delay);
196  expected_confidence[count] = static_cast<float>(nsamples);
197  }
198  }
199 
200  // get the square sum
201  sum2 = jb::testing::sum_square(a);
202 
203  // run the TDE...
204  tested.estimate_delay(confidence, argmax, a, b, sum2);
205  // check argmax within delay +/- tol
206  BOOST_CHECK_MESSAGE(
208  argmax, expected_argmax, argmax_tol),
209  "argmax is not within tolerance("
210  << argmax_tol << "), argmax[0]=" << argmax[0]
211  << ", expected_argmax[0]=" << expected_argmax[0]);
212  // check confidence within nsamples +/- tol
213  BOOST_CHECK_MESSAGE(
215  confidence, expected_confidence, confidence_tol),
216  "confidence is not within tolerance(" << confidence_tol << ")");
217 }
218 
219 /**
220  * @test Verify that we can create and use a simple time delay estimator
221  * multi array dimension 2, with float values.
222  */
223 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_2_dim_tde_float) {
224  int const nsamples = 1 << 15;
225  int const S = 20;
226  int const delay = 2500;
227  // using float, requires higher tolerance
228  int const argmax_tol = 4;
229  // we use a very rough approximation to the confidence error here ...
230  int const confidence_tol = nsamples;
231 
232  using array_type = jb::fftw::aligned_multi_array<float, 2>;
234  using confidence_type = typename tested_type::confidence_type;
235  using estimated_delay_type = typename tested_type::estimated_delay_type;
236  using sum2_type = typename tested_type::sum2_type;
237 
238  array_type a(boost::extents[S][nsamples]);
239  array_type b(boost::extents[S][nsamples]);
240  confidence_type confidence(a);
241  // expected confidence result to compare within tolerance tol
242  confidence_type expected_confidence(a);
243 
244  estimated_delay_type argmax(a);
245  // expected argmax result to compare within tolerance tol
246  estimated_delay_type expected_argmax(a);
247 
248  sum2_type sum2(a);
249 
250  // construct the tested FTE
251  tested_type tested(a, b);
252 
253  // fill the timeseries with triangle or square
255 
256  // a = delay shift timeseries b
257  int count = 0;
258  for (int i = 0; i != S; ++i) {
259  for (int k = 0; k != nsamples; ++k) {
260  a[i][k] = b[i][(k + delay) % nsamples];
261  }
262  expected_argmax[count] = static_cast<std::size_t>(delay);
263  expected_confidence[count] = static_cast<float>(nsamples);
264  count++;
265  }
266 
267  // get the square sum
268  sum2 = jb::testing::sum_square(a);
269 
270  // run the TDE...
271  tested.estimate_delay(confidence, argmax, a, b, sum2);
272  // check argmax within delay +/- tol
273  BOOST_CHECK_MESSAGE(
275  argmax, expected_argmax, argmax_tol),
276  "argmax is not within tolerance("
277  << argmax_tol << "), argmax[0]=" << argmax[0]
278  << ", expected_argmax[0]=" << expected_argmax[0]);
279  // check confidence within nsamples +/- tol
280  BOOST_CHECK_MESSAGE(
282  confidence, expected_confidence, confidence_tol),
283  "confidence is not within tolerance(" << confidence_tol << ")");
284 }
285 
286 /**
287  * @test Verify that we can create and use a simple time delay estimator
288  * multi_array dimension 1 with float values.
289  */
290 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_1_dim_tde_float) {
291  int const nsamples = 1 << 15;
292  int const delay = 2500;
293  // using float, requires higher tolerance
294  int const argmax_tol = 4;
295  // we use a very rough approximation to the confidence error here ...
296  int const confidence_tol = nsamples;
297 
298  using array_type = jb::fftw::aligned_multi_array<float, 1>;
300  using confidence_type = typename tested_type::confidence_type;
301  using estimated_delay_type = typename tested_type::estimated_delay_type;
302  using sum2_type = typename tested_type::sum2_type;
303 
304  array_type a(boost::extents[nsamples]);
305  array_type b(boost::extents[nsamples]);
306  confidence_type confidence(a);
307  // expected confidence result to compare within tolerance tol
308  confidence_type expected_confidence(a);
309 
310  estimated_delay_type argmax(a);
311  // expected argmax result to compare within tolerance tol
312  estimated_delay_type expected_argmax(a);
313 
314  sum2_type sum2(b);
315 
316  // construct the tested FTE
317  tested_type tested(a, b);
318 
319  // fill the timeseries with triangle or square
321 
322  // a = delay shift timeseries b
323  for (int k = 0; k != nsamples; ++k) {
324  a[k] = b[(k + delay) % nsamples];
325  }
326  expected_argmax[0] = static_cast<std::size_t>(delay);
327  expected_confidence[0] = static_cast<float>(nsamples);
328 
329  // get the square sum
330  sum2 = jb::testing::sum_square(a);
331 
332  // run the TDE...
333  tested.estimate_delay(confidence, argmax, a, b, sum2);
334  // check argmax within delay +/- tol
335  BOOST_CHECK_MESSAGE(
337  argmax, expected_argmax, argmax_tol),
338  "argmax is not within tolerance("
339  << argmax_tol << "), argmax[0]=" << argmax[0]
340  << ", expected_argmax[0]=" << expected_argmax[0]);
341  // check confidence within nsamples +/- tol
342  BOOST_CHECK_MESSAGE(
344  confidence, expected_confidence, confidence_tol),
345  "confidence is not within tolerance(" << confidence_tol << ")");
346 }
347 
348 /**
349  * @test Verify that we can create and use a simple time delay estimator based
350  * on jb::fftw::aligned_vector timeseries with float values.
351  */
352 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_vector_tde_float) {
353  int const nsamples = 1 << 15;
354  int const delay = 2500;
355  // using float, requires higher tolerance
356  int const argmax_tol = 4;
357  // we use a very rough approximation to the confidence error here ...
358  int const confidence_tol = nsamples;
359 
360  using array_type = jb::fftw::aligned_vector<float>;
362  using confidence_type = typename tested_type::confidence_type;
363  using estimated_delay_type = typename tested_type::estimated_delay_type;
364  using sum2_type = typename tested_type::sum2_type;
365 
366  array_type a(nsamples);
367  array_type b(nsamples);
368  confidence_type confidence(a);
369  // expected confidence result to compare within tolerance tol
370  confidence_type expected_confidence(a);
371 
372  estimated_delay_type argmax(a);
373  // expected argmax result to compare within tolerance tol
374  estimated_delay_type expected_argmax(a);
375 
376  sum2_type sum2(b);
377 
378  // construct the tested FTE
379  tested_type tested(a, b);
380 
381  // fill the timeseries with triangle or square
383 
384  // a = delay shift timeseries b
385  for (int k = 0; k != nsamples; ++k) {
386  a[k] = b[(k + delay) % nsamples];
387  }
388  expected_argmax[0] = static_cast<std::size_t>(delay);
389  expected_confidence[0] = static_cast<float>(nsamples);
390 
391  // get the square sum
392  sum2 = jb::testing::sum_square(a);
393 
394  // run the TDE...
395  tested.estimate_delay(confidence, argmax, a, b, sum2);
396  // check argmax within delay +/- tol
397  BOOST_CHECK_MESSAGE(
399  argmax, expected_argmax, argmax_tol),
400  "argmax is not within tolerance("
401  << argmax_tol << "), argmax[0]=" << argmax[0]
402  << ", expected_argmax[0]=" << expected_argmax[0]);
403  // check confidence within nsamples +/- tol
404  BOOST_CHECK_MESSAGE(
406  confidence, expected_confidence, confidence_tol),
407  "confidence is not within tolerance(" << confidence_tol << ")");
408 }
409 
410 /**
411  * @test Verify that we can create and use a simple time delay estimator
412  * multi array dimension 3, with double value.
413  */
414 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_double) {
415  int const nsamples = 1 << 15;
416  int const S = 20;
417  int const V = 4;
418  int const delay = 2500;
419  int const argmax_tol = 1;
420  // we use a very rough approximation to the confidence error here ...
421  int const confidence_tol = nsamples;
422 
423  using array_type = jb::fftw::aligned_multi_array<double, 3>;
425  using confidence_type = typename tested_type::confidence_type;
426  using estimated_delay_type = typename tested_type::estimated_delay_type;
427  using sum2_type = typename tested_type::sum2_type;
428 
429  array_type a(boost::extents[S][V][nsamples]);
430  array_type b(boost::extents[S][V][nsamples]);
431  confidence_type confidence(a);
432  // expected confidence result to compare within tolerance tol
433  confidence_type expected_confidence(a);
434 
435  estimated_delay_type argmax(a);
436  // expected argmax result to compare within tolerance tol
437  estimated_delay_type expected_argmax(a);
438 
439  // sum of square value of timeseries
440  sum2_type sum2(b);
441 
442  // construct the tested FTE
443  tested_type tested(a, b);
444 
445  // fill the timeseries with triangle or square
447 
448  // a = delay shift timeseries b
449  int count = 0;
450  for (int i = 0; i != S; ++i) {
451  for (int j = 0; j != V; ++j, ++count) {
452  for (int k = 0; k != nsamples; ++k) {
453  a[i][j][k] = b[i][j][(k + delay) % nsamples];
454  }
455  expected_argmax[count] = static_cast<std::size_t>(delay);
456  expected_confidence[count] = static_cast<double>(nsamples);
457  }
458  }
459 
460  // get the square sum
461  sum2 = jb::testing::sum_square(a);
462 
463  // run the TDE...
464  tested.estimate_delay(confidence, argmax, a, b, sum2);
465  // check argmax within delay +/- tol
466  BOOST_CHECK_MESSAGE(
468  argmax, expected_argmax, argmax_tol),
469  "argmax is not within tolerance("
470  << argmax_tol << "), argmax[0]=" << argmax[0]
471  << ", expected_argmax[0]=" << expected_argmax[0]);
472  // check confidence within nsamples +/- tol
473  BOOST_CHECK_MESSAGE(
475  confidence, expected_confidence, confidence_tol),
476  "confidence is not within tolerance(" << confidence_tol << ")");
477 }
478 
479 /**
480  * @test Verify that we can create and use a simple time delay estimator
481  * multi array dimension 2, with double values.
482  */
483 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_2_dim_tde_double) {
484  int const nsamples = 1 << 15;
485  int const S = 20;
486  int const delay = 2500;
487  int const argmax_tol = 1;
488  // we use a very rough approximation to the confidence error here ...
489  int const confidence_tol = nsamples;
490 
491  using array_type = jb::fftw::aligned_multi_array<double, 2>;
493  using confidence_type = typename tested_type::confidence_type;
494  using estimated_delay_type = typename tested_type::estimated_delay_type;
495  using sum2_type = typename tested_type::sum2_type;
496 
497  array_type a(boost::extents[S][nsamples]);
498  array_type b(boost::extents[S][nsamples]);
499  confidence_type confidence(a);
500  // expected confidence result to compare within tolerance tol
501  confidence_type expected_confidence(a);
502 
503  estimated_delay_type argmax(a);
504  // expected argmax result to compare within tolerance tol
505  estimated_delay_type expected_argmax(a);
506 
507  sum2_type sum2(b);
508 
509  // construct the tested FTE
510  tested_type tested(a, b);
511 
512  // fill the timeseries with triangle or square
514 
515  // a = delay shift timeseries b
516  int count = 0;
517  for (int i = 0; i != S; ++i) {
518  for (int k = 0; k != nsamples; ++k) {
519  a[i][k] = b[i][(k + delay) % nsamples];
520  }
521  expected_argmax[count] = static_cast<std::size_t>(delay);
522  expected_confidence[count] = static_cast<double>(nsamples);
523  count++;
524  }
525 
526  // get the square sum
527  sum2 = jb::testing::sum_square(a);
528 
529  // run the TDE...
530  tested.estimate_delay(confidence, argmax, a, b, sum2);
531  // check argmax within delay +/- tol
532  BOOST_CHECK_MESSAGE(
534  argmax, expected_argmax, argmax_tol),
535  "argmax is not within tolerance("
536  << argmax_tol << "), argmax[0]=" << argmax[0]
537  << ", expected_argmax[0]=" << expected_argmax[0]);
538  // check confidence within nsamples +/- tol
539  BOOST_CHECK_MESSAGE(
541  confidence, expected_confidence, confidence_tol),
542  "confidence is not within tolerance(" << confidence_tol << ")");
543 }
544 
545 /**
546  * @test Verify that we can create and use a simple time delay estimator
547  * multi_array dimension 1 with double values.
548  */
549 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_1_dim_tde_double) {
550  int const nsamples = 1 << 15;
551  int const delay = 2500;
552  int const argmax_tol = 1;
553  // we use a very rough approximation to the confidence error here ...
554  int const confidence_tol = nsamples;
555 
556  using array_type = jb::fftw::aligned_multi_array<double, 1>;
558  using confidence_type = typename tested_type::confidence_type;
559  using estimated_delay_type = typename tested_type::estimated_delay_type;
560  using sum2_type = typename tested_type::sum2_type;
561 
562  array_type a(boost::extents[nsamples]);
563  array_type b(boost::extents[nsamples]);
564  confidence_type confidence(a);
565  // expected confidence result to compare within tolerance tol
566  confidence_type expected_confidence(a);
567 
568  estimated_delay_type argmax(a);
569  // expected argmax result to compare within tolerance tol
570  estimated_delay_type expected_argmax(a);
571 
572  sum2_type sum2(b);
573 
574  // construct the tested FTE
575  tested_type tested(a, b);
576 
577  // fill the timeseries with triangle or square
579 
580  // a = delay shift timeseries b
581  for (int k = 0; k != nsamples; ++k) {
582  a[k] = b[(k + delay) % nsamples];
583  }
584  expected_argmax[0] = static_cast<std::size_t>(delay);
585  expected_confidence[0] = static_cast<double>(nsamples);
586 
587  // get the square sum
588  sum2 = jb::testing::sum_square(a);
589 
590  // run the TDE...
591  tested.estimate_delay(confidence, argmax, a, b, sum2);
592  // check argmax within delay +/- tol
593  BOOST_CHECK_MESSAGE(
595  argmax, expected_argmax, argmax_tol),
596  "argmax is not within tolerance("
597  << argmax_tol << "), argmax[0]=" << argmax[0]
598  << ", expected_argmax[0]=" << expected_argmax[0]);
599  // check confidence within nsamples +/- tol
600  BOOST_CHECK_MESSAGE(
602  confidence, expected_confidence, confidence_tol),
603  "confidence is not within tolerance(" << confidence_tol << ")");
604 }
605 
606 /**
607  * @test Verify that we can create and use a simple time delay estimator based
608  * on std::vector timeseries with double values.
609  */
610 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_vector_tde_double) {
611  int const nsamples = 1 << 15;
612  int const delay = 2500;
613  int const argmax_tol = 1;
614  // we use a very rough approximation to the confidence error here ...
615  int const confidence_tol = nsamples;
616 
617  using array_type = jb::fftw::aligned_vector<double>;
619  using confidence_type = typename tested_type::confidence_type;
620  using estimated_delay_type = typename tested_type::estimated_delay_type;
621  using sum2_type = typename tested_type::sum2_type;
622 
623  array_type a(nsamples);
624  array_type b(nsamples);
625  confidence_type confidence(a);
626  // expected confidence result to compare within tolerance tol
627  confidence_type expected_confidence(a);
628 
629  estimated_delay_type argmax(a);
630  // expected argmax result to compare within tolerance tol
631  estimated_delay_type expected_argmax(a);
632 
633  sum2_type sum2(b);
634 
635  // construct the tested FTE
636  tested_type tested(a, b);
637 
638  // fill the timeseries with triangle or square
640 
641  // a = delay shift timeseries b
642  for (int k = 0; k != nsamples; ++k) {
643  a[k] = b[(k + delay) % nsamples];
644  }
645  expected_argmax[0] = static_cast<std::size_t>(delay);
646  expected_confidence[0] = static_cast<double>(nsamples);
647 
648  // get the square sum
649  sum2 = jb::testing::sum_square(a);
650 
651  // run the TDE...
652  tested.estimate_delay(confidence, argmax, a, b, sum2);
653  // check argmax within delay +/- tol
654  BOOST_CHECK_MESSAGE(
656  argmax, expected_argmax, argmax_tol),
657  "argmax is not within tolerance("
658  << argmax_tol << "), argmax[0]=" << argmax[0]
659  << ", expected_argmax[0]=" << expected_argmax[0]);
660  // check confidence within nsamples +/- tol
661  BOOST_CHECK_MESSAGE(
663  confidence, expected_confidence, confidence_tol),
664  "confidence is not within tolerance(" << confidence_tol << ")");
665 }
666 
667 /**
668  * @test Verify that we can create and use a simple time delay estimator
669  * multi array dimension 3, with std::complex<float> value.
670  */
671 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_complex_float) {
672  int const nsamples = 1 << 15;
673  int const S = 20;
674  int const V = 4;
675  int const delay = 2500;
676  // using float, requires higher tolerance
677  int const argmax_tol = 4;
678  // we use a very rough approximation to the confidence error here ...
679  int const confidence_tol = nsamples;
680 
683  using confidence_type = typename tested_type::confidence_type;
684  using estimated_delay_type = typename tested_type::estimated_delay_type;
685  using sum2_type = typename tested_type::sum2_type;
686 
687  array_type a(boost::extents[S][V][nsamples]);
688  array_type b(boost::extents[S][V][nsamples]);
689  confidence_type confidence(a);
690  // expected confidence result to compare within tolerance tol
691  confidence_type expected_confidence(a);
692 
693  estimated_delay_type argmax(a);
694  // expected argmax result to compare within tolerance tol
695  estimated_delay_type expected_argmax(a);
696 
697  // sum of square value of timeseries
698  sum2_type sum2(b);
699 
700  // construct the tested FTE
701  tested_type tested(a, b);
702 
703  // fill the timeseries with triangle or square
705 
706  // a = delay shift timeseries b
707  int count = 0;
708  for (int i = 0; i != S; ++i) {
709  for (int j = 0; j != V; ++j, ++count) {
710  for (int k = 0; k != nsamples; ++k) {
711  a[i][j][k] = b[i][j][(k + delay) % nsamples];
712  }
713  expected_argmax[count] = static_cast<std::size_t>(delay);
714  expected_confidence[count] = static_cast<float>(nsamples);
715  }
716  }
717 
718  // get the square sum
719  sum2 = jb::testing::sum_square(a);
720 
721  // run the TDE...
722  tested.estimate_delay(confidence, argmax, a, b, sum2);
723  // check argmax within delay +/- tol
724  BOOST_CHECK_MESSAGE(
726  argmax, expected_argmax, argmax_tol),
727  "argmax is not within tolerance("
728  << argmax_tol << "), argmax[0]=" << argmax[0]
729  << ", expected_argmax[0]=" << expected_argmax[0]);
730  // check confidence within nsamples +/- tol
731  BOOST_CHECK_MESSAGE(
733  confidence, expected_confidence, confidence_tol),
734  "confidence is not within tolerance(" << confidence_tol << ")");
735 }
736 
737 /**
738  * @test Verify that we can create and use a simple time delay estimator
739  * multi array dimension 2, with std::complex<float> values.
740  */
741 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_2_dim_tde_complex_float) {
742  int const nsamples = 1 << 15;
743  int const S = 20;
744  int const delay = 2500;
745  // using float, requires higher tolerance
746  int const argmax_tol = 4;
747  // we use a very rough approximation to the confidence error here ...
748  int const confidence_tol = nsamples;
749 
752  using confidence_type = typename tested_type::confidence_type;
753  using estimated_delay_type = typename tested_type::estimated_delay_type;
754  using sum2_type = typename tested_type::sum2_type;
755 
756  array_type a(boost::extents[S][nsamples]);
757  array_type b(boost::extents[S][nsamples]);
758  confidence_type confidence(a);
759  // expected confidence result to compare within tolerance tol
760  confidence_type expected_confidence(a);
761 
762  estimated_delay_type argmax(a);
763  // expected argmax result to compare within tolerance tol
764  estimated_delay_type expected_argmax(a);
765 
766  sum2_type sum2(b);
767 
768  // construct the tested FTE
769  tested_type tested(a, b);
770 
771  // fill the timeseries with triangle or square
773 
774  // a = delay shift timeseries b
775  int count = 0;
776  for (int i = 0; i != S; ++i) {
777  for (int k = 0; k != nsamples; ++k) {
778  a[i][k] = b[i][(k + delay) % nsamples];
779  }
780  expected_argmax[count] = static_cast<std::size_t>(delay);
781  expected_confidence[count] = static_cast<float>(nsamples);
782  count++;
783  }
784 
785  // get the square sum
786  sum2 = jb::testing::sum_square(a);
787 
788  // run the TDE...
789  tested.estimate_delay(confidence, argmax, a, b, sum2);
790  // check argmax within delay +/- tol
791  BOOST_CHECK_MESSAGE(
793  argmax, expected_argmax, argmax_tol),
794  "argmax is not within tolerance("
795  << argmax_tol << "), argmax[0]=" << argmax[0]
796  << ", expected_argmax[0]=" << expected_argmax[0]);
797  // check confidence within nsamples +/- tol
798  BOOST_CHECK_MESSAGE(
800  confidence, expected_confidence, confidence_tol),
801  "confidence is not within tolerance(" << confidence_tol << ")");
802 }
803 
804 /**
805  * @test Verify that we can create and use a simple time delay estimator
806  * multi_array dimension 1 with std::complex<float> values.
807  */
808 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_1_dim_tde_complex_float) {
809  int const nsamples = 1 << 15;
810  int const delay = 2500;
811  // using float, requires higher tolerance
812  int const argmax_tol = 4;
813  // we use a very rough approximation to the confidence error here ...
814  int const confidence_tol = nsamples;
815 
818  using confidence_type = typename tested_type::confidence_type;
819  using estimated_delay_type = typename tested_type::estimated_delay_type;
820  using sum2_type = typename tested_type::sum2_type;
821 
822  array_type a(boost::extents[nsamples]);
823  array_type b(boost::extents[nsamples]);
824  confidence_type confidence(a);
825  // expected confidence result to compare within tolerance tol
826  confidence_type expected_confidence(a);
827 
828  estimated_delay_type argmax(a);
829  // expected argmax result to compare within tolerance tol
830  estimated_delay_type expected_argmax(a);
831 
832  sum2_type sum2(b);
833 
834  // construct the tested FTE
835  tested_type tested(a, b);
836 
837  // fill the timeseries with triangle or square
839 
840  // a = delay shift timeseries b
841  for (int k = 0; k != nsamples; ++k) {
842  a[k] = b[(k + delay) % nsamples];
843  }
844  expected_argmax[0] = static_cast<std::size_t>(delay);
845  expected_confidence[0] = static_cast<float>(nsamples);
846 
847  // get the square sum
848  sum2 = jb::testing::sum_square(a);
849 
850  // run the TDE...
851  tested.estimate_delay(confidence, argmax, a, b, sum2);
852  // check argmax within delay +/- tol
853  BOOST_CHECK_MESSAGE(
855  argmax, expected_argmax, argmax_tol),
856  "argmax is not within tolerance("
857  << argmax_tol << "), argmax[0]=" << argmax[0]
858  << ", expected_argmax[0]=" << expected_argmax[0]);
859  // check confidence within nsamples +/- tol
860  BOOST_CHECK_MESSAGE(
862  confidence, expected_confidence, confidence_tol),
863  "confidence is not within tolerance(" << confidence_tol << ")");
864 }
865 
866 /**
867  * @test Verify that we can create and use a simple time delay estimator based
868  * on std::vector timeseries with std::complex<float> values.
869  */
870 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_vector_tde_complex_float) {
871  int const nsamples = 1 << 15;
872  int const delay = 2500;
873  // using float, requires higher tolerance
874  int const argmax_tol = 4;
875  // we use a very rough approximation to the confidence error here ...
876  int const confidence_tol = nsamples;
877 
880  using confidence_type = typename tested_type::confidence_type;
881  using estimated_delay_type = typename tested_type::estimated_delay_type;
882  using sum2_type = typename tested_type::sum2_type;
883 
884  array_type a(nsamples);
885  array_type b(nsamples);
886  confidence_type confidence(a);
887  // expected confidence result to compare within tolerance tol
888  confidence_type expected_confidence(a);
889 
890  estimated_delay_type argmax(a);
891  // expected argmax result to compare within tolerance tol
892  estimated_delay_type expected_argmax(a);
893  sum2_type sum2(b);
894 
895  // construct the tested FTE
896  tested_type tested(a, b);
897 
898  // fill the timeseries with triangle or square
900 
901  // a = delay shift timeseries b
902  for (int k = 0; k != nsamples; ++k) {
903  a[k] = b[(k + delay) % nsamples];
904  }
905  expected_argmax[0] = static_cast<std::size_t>(delay);
906  expected_confidence[0] = static_cast<float>(nsamples);
907 
908  // get the square sum
909  sum2 = jb::testing::sum_square(a);
910 
911  // run the TDE...
912  tested.estimate_delay(confidence, argmax, a, b, sum2);
913  // check argmax within delay +/- tol
914  BOOST_CHECK_MESSAGE(
916  argmax, expected_argmax, argmax_tol),
917  "argmax is not within tolerance("
918  << argmax_tol << "), argmax[0]=" << argmax[0]
919  << ", expected_argmax[0]=" << expected_argmax[0]);
920  // check confidence within nsamples +/- tol
921  BOOST_CHECK_MESSAGE(
923  confidence, expected_confidence, confidence_tol),
924  "confidence is not within tolerance(" << confidence_tol << ")");
925 }
926 
927 /**
928  * @test Verify that we can create and use a simple time delay estimator
929  * multi array dimension 3, with std::complex<double> value.
930  */
931 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_complex_double) {
932  int const nsamples = 1 << 15;
933  int const S = 20;
934  int const V = 4;
935  int const delay = 2500;
936  int const argmax_tol = 1;
937  // we use a very rough approximation to the confidence error here ...
938  int const confidence_tol = nsamples;
939 
942  using confidence_type = typename tested_type::confidence_type;
943  using estimated_delay_type = typename tested_type::estimated_delay_type;
944  using sum2_type = typename tested_type::sum2_type;
945 
946  array_type a(boost::extents[S][V][nsamples]);
947  array_type b(boost::extents[S][V][nsamples]);
948  confidence_type confidence(a);
949  // expected confidence result to compare within tolerance tol
950  confidence_type expected_confidence(a);
951 
952  estimated_delay_type argmax(a);
953  // expected argmax result to compare within tolerance tol
954  estimated_delay_type expected_argmax(a);
955 
956  // sum of square value of timeseries
957  sum2_type sum2(b);
958 
959  // construct the tested FTE
960  tested_type tested(a, b);
961 
962  // fill the timeseries with triangle or square
964 
965  // a = delay shift timeseries b
966  int count = 0;
967  for (int i = 0; i != S; ++i) {
968  for (int j = 0; j != V; ++j, ++count) {
969  for (int k = 0; k != nsamples; ++k) {
970  a[i][j][k] = b[i][j][(k + delay) % nsamples];
971  }
972  expected_argmax[count] = static_cast<std::size_t>(delay);
973  expected_confidence[count] = static_cast<double>(nsamples);
974  }
975  }
976 
977  // get the square sum
978  sum2 = jb::testing::sum_square(a);
979 
980  // run the TDE...
981  tested.estimate_delay(confidence, argmax, a, b, sum2);
982  // check argmax within delay +/- tol
983  BOOST_CHECK_MESSAGE(
985  argmax, expected_argmax, argmax_tol),
986  "argmax is not within tolerance("
987  << argmax_tol << "), argmax[0]=" << argmax[0]
988  << ", expected_argmax[0]=" << expected_argmax[0]);
989  // check confidence within nsamples +/- tol
990  BOOST_CHECK_MESSAGE(
992  confidence, expected_confidence, confidence_tol),
993  "confidence is not within tolerance(" << confidence_tol << ")");
994 }
995 
996 /**
997  * @test Verify that we can create and use a simple time delay estimator
998  * multi array dimension 2, with std::complex<double> values.
999  */
1000 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_2_dim_tde_complex_double) {
1001  int const nsamples = 1 << 15;
1002  int const S = 20;
1003  int const delay = 2500;
1004  int const argmax_tol = 1;
1005  // we use a very rough approximation to the confidence error here ...
1006  int const confidence_tol = nsamples;
1007 
1010  using confidence_type = typename tested_type::confidence_type;
1011  using estimated_delay_type = typename tested_type::estimated_delay_type;
1012  using sum2_type = typename tested_type::sum2_type;
1013 
1014  array_type a(boost::extents[S][nsamples]);
1015  array_type b(boost::extents[S][nsamples]);
1016  confidence_type confidence(a);
1017  // expected confidence result to compare within tolerance tol
1018  confidence_type expected_confidence(a);
1019 
1020  estimated_delay_type argmax(a);
1021  // expected argmax result to compare within tolerance tol
1022  estimated_delay_type expected_argmax(a);
1023 
1024  sum2_type sum2(b);
1025 
1026  // construct the tested FTE
1027  tested_type tested(a, b);
1028 
1029  // fill the timeseries with triangle or square
1031 
1032  // a = delay shift timeseries b
1033  int count = 0;
1034  for (int i = 0; i != S; ++i) {
1035  for (int k = 0; k != nsamples; ++k) {
1036  a[i][k] = b[i][(k + delay) % nsamples];
1037  }
1038  expected_argmax[count] = static_cast<std::size_t>(delay);
1039  expected_confidence[count] = static_cast<double>(nsamples);
1040  count++;
1041  }
1042 
1043  // get the square sum
1044  sum2 = jb::testing::sum_square(a);
1045 
1046  // run the TDE...
1047  tested.estimate_delay(confidence, argmax, a, b, sum2);
1048  // check argmax within delay +/- tol
1049  BOOST_CHECK_MESSAGE(
1051  argmax, expected_argmax, argmax_tol),
1052  "argmax is not within tolerance("
1053  << argmax_tol << "), argmax[0]=" << argmax[0]
1054  << ", expected_argmax[0]=" << expected_argmax[0]);
1055  // check confidence within nsamples +/- tol
1056  BOOST_CHECK_MESSAGE(
1058  confidence, expected_confidence, confidence_tol),
1059  "confidence is not within tolerance(" << confidence_tol << ")");
1060 }
1061 
1062 /**
1063  * @test Verify that we can create and use a simple time delay estimator
1064  * multi_array dimension 1 with std::complex<double> values.
1065  */
1066 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_1_dim_tde_complex_double) {
1067  int const nsamples = 1 << 15;
1068  int const delay = 2500;
1069  int const argmax_tol = 1;
1070  // we use a very rough approximation to the confidence error here ...
1071  int const confidence_tol = nsamples;
1072 
1075  using confidence_type = typename tested_type::confidence_type;
1076  using estimated_delay_type = typename tested_type::estimated_delay_type;
1077  using sum2_type = typename tested_type::sum2_type;
1078 
1079  array_type a(boost::extents[nsamples]);
1080  array_type b(boost::extents[nsamples]);
1081  confidence_type confidence(a);
1082  // expected confidence result to compare within tolerance tol
1083  confidence_type expected_confidence(a);
1084 
1085  estimated_delay_type argmax(a);
1086  // expected argmax result to compare within tolerance tol
1087  estimated_delay_type expected_argmax(a);
1088 
1089  sum2_type sum2(b);
1090 
1091  // construct the tested FTE
1092  tested_type tested(a, b);
1093 
1094  // fill the timeseries with triangle or square
1096 
1097  // a = delay shift timeseries b
1098  for (int k = 0; k != nsamples; ++k) {
1099  a[k] = b[(k + delay) % nsamples];
1100  }
1101  expected_argmax[0] = static_cast<std::size_t>(delay);
1102  expected_confidence[0] = static_cast<double>(nsamples);
1103 
1104  // get the square sum
1105  sum2 = jb::testing::sum_square(a);
1106 
1107  // run the TDE...
1108  tested.estimate_delay(confidence, argmax, a, b, sum2);
1109  // check argmax within delay +/- tol
1110  BOOST_CHECK_MESSAGE(
1112  argmax, expected_argmax, argmax_tol),
1113  "argmax is not within tolerance("
1114  << argmax_tol << "), argmax[0]=" << argmax[0]
1115  << ", expected_argmax[0]=" << expected_argmax[0]);
1116  // check confidence within nsamples +/- tol
1117  BOOST_CHECK_MESSAGE(
1119  confidence, expected_confidence, confidence_tol),
1120  "confidence is not within tolerance(" << confidence_tol << ")");
1121 }
1122 
1123 /**
1124  * @test Verify that we can create and use a simple time delay estimator based
1125  * on std::vector timeseries with std::complex<double> values.
1126  */
1127 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_vector_tde_complex_double) {
1128  int const nsamples = 1 << 15;
1129  int const delay = 2500;
1130  int const argmax_tol = 1;
1131  // we use a very rough approximation to the confidence error here ...
1132  int const confidence_tol = nsamples;
1133 
1136  using confidence_type = typename tested_type::confidence_type;
1137  using estimated_delay_type = typename tested_type::estimated_delay_type;
1138  using sum2_type = typename tested_type::sum2_type;
1139 
1140  array_type a(nsamples);
1141  array_type b(nsamples);
1142  confidence_type confidence(a);
1143  // expected confidence result to compare within tolerance tol
1144  confidence_type expected_confidence(a);
1145 
1146  estimated_delay_type argmax(a);
1147  // expected argmax result to compare within tolerance tol
1148  estimated_delay_type expected_argmax(a);
1149 
1150  sum2_type sum2(b);
1151 
1152  // construct the tested FTE
1153  tested_type tested(a, b);
1154 
1155  // fill the timeseries with triangle or square
1157 
1158  // a = delay shift timeseries b
1159  for (int k = 0; k != nsamples; ++k) {
1160  a[k] = b[(k + delay) % nsamples];
1161  }
1162  expected_argmax[0] = static_cast<std::size_t>(delay);
1163  expected_confidence[0] = static_cast<double>(nsamples);
1164 
1165  // get the square sum
1166  sum2 = jb::testing::sum_square(a);
1167 
1168  // run the TDE...
1169  tested.estimate_delay(confidence, argmax, a, b, sum2);
1170  // check argmax within delay +/- tol
1171  BOOST_CHECK_MESSAGE(
1173  argmax, expected_argmax, argmax_tol),
1174  "argmax is not within tolerance("
1175  << argmax_tol << "), argmax[0]=" << argmax[0]
1176  << ", expected_argmax[0]=" << expected_argmax[0]);
1177  // check confidence within nsamples +/- tol
1178  BOOST_CHECK_MESSAGE(
1180  confidence, expected_confidence, confidence_tol),
1181  "confidence is not within tolerance(" << confidence_tol << ")");
1182 }
1183 
1184 /**
1185  * @test Verify thattime delay estimator handles errors
1186  */
1187 BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_errors) {
1188  int const nsamples = 1 << 15;
1189  int const S = 20;
1190  int const V = 4;
1191 
1192  using array_type = jb::fftw::aligned_multi_array<float, 3>;
1194 
1195  array_type a(boost::extents[S][V][nsamples]);
1196  array_type b(boost::extents[S - 1][V][nsamples]);
1197  array_type c(boost::extents[S][V][nsamples]);
1198 
1199  using confidence_type = typename tested_type::confidence_type;
1200  using estimated_delay_type = typename tested_type::estimated_delay_type;
1201  using sum2_type = typename tested_type::sum2_type;
1202 
1203  confidence_type confidence(a);
1204  estimated_delay_type argmax(a);
1205  sum2_type sum2(a);
1206 
1207  // check contructor size exception
1208  BOOST_CHECK_THROW(tested_type tested(a, b), std::exception);
1209  // construct one...
1210  tested_type tested2(a, c);
1211  // check the TDE size exception
1212  BOOST_CHECK_THROW(
1213  tested2.estimate_delay(confidence, argmax, a, b, sum2), std::exception);
1214  BOOST_CHECK_THROW(
1215  tested2.estimate_delay(confidence, argmax, b, c, sum2), std::exception);
1216 }
std::vector< T, jb::fftw::allocator< T > > aligned_vector
Alias std::vector with properly allocated storage for FFTW3.
auto sum_square(container_t const &ts)
Compute the sum square of a family of timeseries.
Definition: sum_square.hpp:17
boost::multi_array< value_type, num_dims, jb::fftw::allocator< value_type > > aligned_multi_array
Alias boost::multi_array with properly allocated storage for FFTW3.
BOOST_AUTO_TEST_CASE(fftw_time_delay_estimator_many_3_dim_tde_with_0)
void create_triangle_timeseries(int nsamples, timeseries &ts)
Create a simple timeseries where the values look like a triangle.
A time delay estimator based on cross-correlation.
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.