astrotypes  0.0
TimeFrequencyTest.cpp
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2018 PulsarSearchSoft
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
26 
27 
28 using namespace pss::astrotypes::units;
29 
30 namespace pss {
31 namespace astrotypes {
32 namespace test {
33 
34 
35 TimeFrequencyTest::TimeFrequencyTest()
36  : ::testing::Test()
37 {
38 }
39 
41 {
42 }
43 
45 {
46 }
47 
49 {
50 }
51 
52 TEST_F(TimeFrequencyTest, test_time_freq_instantiation)
53 {
54  DimensionSize<Time> time_size(50);
55  DimensionSize<Frequency> freq_size(10);
56  TimeFrequency<uint8_t> tf1(time_size, freq_size);
57  ASSERT_EQ(time_size, tf1.size<Time>());
58  ASSERT_EQ(freq_size, tf1.size<Frequency>());
59 
60  TimeFrequency<uint16_t> tf2(freq_size, time_size);
61  ASSERT_EQ(time_size, tf2.size<Time>());
62  ASSERT_EQ(freq_size, tf2.size<Frequency>());
63 }
64 
65 TEST_F(TimeFrequencyTest, test_time_freq_spectrum)
66 {
67  DimensionSize<Time> time_size(50);
68  DimensionSize<Frequency> freq_size(10);
69  TimeFrequency<uint8_t> tf1(time_size, freq_size);
70 
71  for(unsigned spectrum_num =0; spectrum_num < (std::size_t)time_size; ++spectrum_num)
72  {
73  unsigned n=0;
74  typename TimeFrequency<uint8_t>::Spectra s = tf1.spectrum(spectrum_num);
75  std::for_each(s.begin(), s.end(), [&](uint8_t& v) { v = ++n; } );
76  ASSERT_EQ(n, (unsigned)(freq_size));
77  }
78 
79  // test assignment operator
80  typename TimeFrequency<uint8_t>::Spectra s3 = tf1.spectrum(3);
81  s3 = tf1.spectrum(5);
82  ASSERT_TRUE(s3.begin() == tf1.spectrum(5).begin());
83 
84  // test spectrum() on const object
85  TimeFrequency<uint8_t> const& tf2 = tf1;
87  s2 = tf2.spectrum(5);
88 }
89 
90 TEST_F(TimeFrequencyTest, test_time_freq_slice)
91 {
92  DimensionSize<Time> time_size(50);
93  DimensionSize<Frequency> freq_size(10);
94  const TimeFrequency<uint8_t> tf1(time_size, freq_size);
95 
96  for(unsigned spectrum_num =0; spectrum_num < (std::size_t)time_size; ++spectrum_num)
97  {
98  unsigned n=0;
99  auto s = tf1.slice(DimensionSpan<Time>(DimensionSize<Time>(spectrum_num)));
100  std::for_each(s.cbegin(), s.cend(), [&](uint8_t) { ++n; } );
101  ASSERT_EQ(n, (unsigned)(freq_size * spectrum_num));
102  // a slice of a slice
103  auto s2 = s.slice(DimensionSpan<Time>(DimensionSize<Time>(1)));
104  ASSERT_EQ(s2.data_size(), (unsigned)(freq_size));
105  }
106 }
107 
108 TEST_F(TimeFrequencyTest, test_time_freq_slice_copy)
109 {
110  DimensionSize<Time> time_size(50);
111  DimensionSize<Frequency> freq_size(10);
112  const TimeFrequency<uint8_t> tf1(time_size, freq_size);
113  auto s = tf1.slice(DimensionSpan<Time>(DimensionSize<Time>(5)));
114  decltype(s) slice_copy = s;
115  ASSERT_TRUE(slice_copy.parent() == s.parent());
116 }
117 
118 TEST_F(TimeFrequencyTest, test_time_freq_channel)
119 {
120  DimensionSize<Time> time_size(2);
121  DimensionSize<Frequency> freq_size(10);
122  TimeFrequency<int> tf1(time_size, freq_size);
123  unsigned val=0;
124  std::generate(tf1.begin(), tf1.end(), [&]() { return val++; });
125 
126  typedef typename TimeFrequency<int>::Channel Channel;
127  for(unsigned channel_num=0; channel_num < (std::size_t)freq_size; ++ channel_num) {
128  SCOPED_TRACE(channel_num);
129  SCOPED_TRACE("channel_num:");
130  Channel c = tf1.channel(channel_num);
131  Channel c_copy = c;
132  ASSERT_EQ(&*c.begin(), &*c_copy.begin());
133 
134  for(DimensionIndex<Time> num(0); num < time_size; ++num) {
135  ASSERT_EQ(c[num], (int)((unsigned)num * freq_size) + channel_num) << num;
136  c[num] += 1; // can we modify the value?
137  c[num] -= 1;
138  }
139  ASSERT_EQ(c.size<Frequency>(), DimensionSize<Frequency>(1));
140  ASSERT_EQ(c.size<Time>(), time_size);
141  SliceIterator<Channel, false> it=c.begin();
142  SliceIterator<Channel, true> it_const=c.cbegin();
143  ASSERT_EQ(c[DimensionIndex<Time>(0)], *it);
144  ASSERT_EQ(it, it_const);
145  unsigned count=0;
146  while(it != c.end()) {
147  ASSERT_EQ(count * (std::size_t)freq_size + channel_num, *it) << " count=" << count;
148  ++count;
149  ++it;
150  }
151  ASSERT_EQ(count, (unsigned)(time_size));
152  unsigned count2=0;
153  std::for_each(c.cbegin(), c.cend(), [&](int const& val)
154  {
155  ASSERT_EQ(count2 * (std::size_t)freq_size + channel_num, val) << " count=" << count2;
156  ++count2;
157  } );
158  ASSERT_EQ(count, (unsigned)(time_size));
159  }
160 
161  TimeFrequency<int> const& tf2 = tf1;
162  typename TimeFrequency<int>::ConstChannel c2 = tf2.channel(5);
163  ASSERT_EQ(c2.size<Frequency>(), DimensionSize<Frequency>(1));
164  ASSERT_EQ(c2.size<Time>(), time_size);
165 }
166 
167 TEST_F(TimeFrequencyTest, test_time_freq_channel_begin_end)
168 {
169  DimensionSize<Time> time_size(2);
170  DimensionSize<Frequency> freq_size(10);
171  TimeFrequency<int> tf1(time_size, freq_size);
172  typename TimeFrequency<int>::Channel channel = tf1.channel(0);
173  std::fill(channel.begin(), channel.end(), 0);
174 }
175 
176 TEST_F(TimeFrequencyTest, test_freq_time_instantiation)
177 {
178  DimensionSize<Time> time_size(50);
179  DimensionSize<Frequency> freq_size(10);
180  FrequencyTime<uint8_t> tf1(time_size, freq_size);
181  ASSERT_EQ(time_size, tf1.size<Time>());
182  ASSERT_EQ(freq_size, tf1.size<Frequency>());
183 
184  FrequencyTime<uint16_t> tf2(freq_size, time_size);
185  ASSERT_EQ(time_size, tf2.size<Time>());
186  ASSERT_EQ(freq_size, tf2.size<Frequency>());
187 }
188 
189 TEST_F(TimeFrequencyTest, test_freq_time_spectrum)
190 {
191  DimensionSize<Time> time_size(50);
192  DimensionSize<Frequency> freq_size(10);
193  FrequencyTime<uint8_t> ft1(time_size, freq_size);
194 
195  typename FrequencyTime<uint8_t>::Spectra s = ft1.spectrum(0);
196  unsigned n=0;
197  std::for_each(s.cbegin(), s.cend(), [&](uint8_t) { ++n; } );
198  ASSERT_EQ(n, (unsigned)(freq_size));
199 
200  FrequencyTime<uint8_t> const& ft2 = ft1;
201  typename FrequencyTime<uint8_t>::ConstSpectra s2 = ft2.spectrum(3);
202 
203  // verify spectra interface works for slices
206  auto spectra = slice.spectrum(2);
207  auto const& const_spectra = const_cast<decltype(slice) const&>(slice).spectrum(2);
208  ASSERT_EQ(spectra.size<Frequency>(), DimensionSize<Frequency>(4));
209  ASSERT_EQ(const_spectra.size<Frequency>(), DimensionSize<Frequency>(4));
210 }
211 
212 TEST_F(TimeFrequencyTest, test_freq_time_channel)
213 {
214  DimensionSize<Time> time_size(50);
215  DimensionSize<Frequency> freq_size(10);
216  FrequencyTime<uint8_t> ft1(time_size, freq_size);
217 
218  typename FrequencyTime<uint8_t>::Channel c = ft1.channel(0);
219  ASSERT_EQ(c.size<Frequency>(), DimensionSize<Frequency>(1));
220  ASSERT_EQ(c.size<Time>(), time_size);
221  std::fill(c.begin(), c.end(), 0);
222 
223  FrequencyTime<uint8_t> const& tf2 = ft1;
224  typename FrequencyTime<uint8_t>::ConstChannel c2 = tf2.channel(5);
225  ASSERT_EQ(c2.size<Frequency>(), DimensionSize<Frequency>(0));
226  ASSERT_EQ(c2.size<Time>(), time_size);
227 
228  // verify channel interface works for slices
231  auto channel = slice.channel(2);
232  auto const& const_channel = const_cast<decltype(slice) const&>(slice).channel(2);
233  ASSERT_EQ((std::size_t)channel.size<Time>(), 10U);
234  ASSERT_EQ((std::size_t)const_channel.size<Time>(), 10U);
235 }
236 
237 TEST_F(TimeFrequencyTest, test_time_freq_transpose)
238 {
239  DimensionSize<Time> time_size(50);
240  DimensionSize<Frequency> freq_size(10);
241  TimeFrequency<uint8_t> tf(time_size, freq_size);
242  unsigned val=0;
243  std::generate(tf.begin(), tf.end(), [&]() { return val++; });
244  static_assert(has_exact_dimensions<decltype(tf), units::Time, units::Frequency>::value, "oh oh");
245  static_assert(has_dimension<decltype(tf), units::Time>::value, "oh oh");
246 
247  // call the transpose constructor
248  FrequencyTime<uint8_t> ft(tf);
249 
250  ASSERT_EQ(ft.dimension<Time>(), time_size);
251  ASSERT_EQ(ft.dimension<Frequency>(), freq_size);
252  for(DimensionIndex<Time> ti(0); ti < time_size; ++ti)
253  {
254  for(DimensionIndex<Frequency> fi(0); fi < freq_size; ++fi)
255  {
256  ASSERT_EQ(tf[ti][fi], ft[fi][ti]);
257  }
258  }
259 }
260 
261 TEST_F(TimeFrequencyTest, test_freq_time_transpose)
262 {
263  DimensionSize<Time> time_size(50);
264  DimensionSize<Frequency> freq_size(10);
265  FrequencyTime<uint8_t> ft1(time_size, freq_size);
266  unsigned val=0;
267  std::generate(ft1.begin(), ft1.end(), [&]() { return val++; });
268 
269  // call the transpose constructor
270  TimeFrequency<uint8_t> tf1(ft1);
271 
272  ASSERT_EQ(tf1.dimension<Time>(), time_size);
273  ASSERT_EQ(tf1.dimension<Frequency>(), freq_size);
274  for(DimensionIndex<Time> ti(0); ti < time_size; ++ti)
275  {
276  for(DimensionIndex<Frequency> fi(0); fi < freq_size; ++fi)
277  {
278  ASSERT_EQ(tf1[ti][fi], ft1[fi][ti]);
279  }
280  }
281 }
282 
283 
284 TEST_F(TimeFrequencyTest, test_time_freq_has_exact_dimensions)
285 {
286  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<TimeFrequency<double>, units::Time, units::Frequency>::type>::value, "expecting true");
287  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>, units::Time>::type>::value, "expecting false");
288  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>, units::Frequency, units::Time>::type>::value, "expecting false");
289 }
290 
291 TEST_F(TimeFrequencyTest, test_freq_time_has_exact_dimensions)
292 {
293  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>, units::Time, units::Frequency>::type>::value, "expecting false");
294  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>, units::Time>::type>::value, "expecting false");
295  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<FrequencyTime<double>, units::Frequency, units::Time>::type>::value, "expecting true");
296 }
297 
298 TEST_F(TimeFrequencyTest, test_time_freq_slice_has_dimension)
299 {
300  static_assert(std::is_same<std::true_type, typename has_dimension<TimeFrequency<double>, units::Time>::type>::value, "expecting true");
301  static_assert(std::is_same<std::true_type, typename has_dimension<TimeFrequency<double>, units::Frequency>::type>::value, "expecting true");
302  static_assert(std::is_same<std::true_type, typename has_dimensions<TimeFrequency<double>, units::Time, units::Frequency>::type>::value, "expecting true");
303  static_assert(std::is_same<std::true_type, typename has_dimensions<TimeFrequency<double>, units::Frequency, units::Time>::type>::value, "expecting true");
304 }
305 
306 TEST_F(TimeFrequencyTest, test_freq_time_slice_has_dimension)
307 {
308  static_assert(std::is_same<std::true_type, typename has_dimension<FrequencyTime<double>, units::Time>::type>::value, "expecting true");
309  static_assert(std::is_same<std::true_type, typename has_dimension<FrequencyTime<double>, units::Frequency>::type>::value, "expecting true");
310  static_assert(std::is_same<std::true_type, typename has_dimensions<FrequencyTime<double>, units::Time, units::Frequency>::type>::value, "expecting true");
311  static_assert(std::is_same<std::true_type, typename has_dimensions<FrequencyTime<double>, units::Frequency, units::Time>::type>::value, "expecting true");
312 }
313 
314 TEST_F(TimeFrequencyTest, test_time_freq_slice_has_exact_dimensions)
315 {
316  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Channel, units::Time, units::Frequency>::type>::value, "expecting false");
317  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Channel, units::Frequency>::type>::value, "expecting false");
318  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<TimeFrequency<double>::Channel, units::Time>::type>::value, "expecting true");
319  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Spectra, units::Frequency, units::Time>::type>::value, "expecting false");
320  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Spectra, units::Time, units::Frequency>::type>::value, "expecting false");
321  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Spectra, units::Time>::type>::value, "expecting false");
322  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<TimeFrequency<double>::Spectra, units::Frequency>::type>::value, "expecting true");
323  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<TimeFrequency<double>::Spectra, units::Frequency, units::Time>::type>::value, "expecting false");
324 }
325 
326 TEST_F(TimeFrequencyTest, test_freq_time_slice_has_exact_dimensions)
327 {
328  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Spectra, units::Time, units::Frequency>::type>::value, "expecting false");
329  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Spectra, units::Time>::type>::value, "expecting false");
330  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Spectra, units::Frequency, units::Time>::type>::value, "expecting false");
331  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<FrequencyTime<double>::Spectra, units::Frequency>::type>::value, "expecting true");
332  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Channel, units::Time, units::Frequency>::type>::value, "expecting false");
333  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Channel, units::Frequency, units::Time>::type>::value, "expecting false");
334  static_assert(std::is_same<std::false_type, typename has_exact_dimensions<FrequencyTime<double>::Channel, units::Frequency>::type>::value, "expecting false");
335  static_assert(std::is_same<std::true_type, typename has_exact_dimensions<FrequencyTime<double>::Channel, units::Time>::type>::value, "expecting true");
336 }
337 
338 } // namespace test
339 } // namespace astrotypes
340 } // namespace pss
A tagged dimensionIndex variable.
Defines a contiguous range over dimension in index.
Definition: DimensionSpan.h:41
std::enable_if< std::is_same< Dim, units::Time >::value, DimensionSize< units::Time > >::type size() const
return a slice of the specified dimension spanning the index_range provided
boost::units::time_dimension Time
Definition: Time.h:42
BaseT::ConstChannel ConstChannel
TEST_F(MultiArrayTest, test_single_dimension_size)
BaseT::ConstChannel ConstChannel
BaseT::ConstSpectra ConstSpectra
return true if the Dimensions provided match exactly those of the structure T (including order) ...
Definition: TypeTraits.h:107
BaseT::ConstSpectra ConstSpectra
A template class representing values associated with a time and frequecny such as Stokes values or vo...
A compile time dimesion tagging of size_t.
Definition: DimensionSize.h:39
A template class representing values associated with a time and frequecny such as Stokes values or vo...
return true if the all Dimensions provided are represented in the structure
Definition: TypeTraits.h:84
iterator begin()
iterators acting over he entire data structure
Channel channel(std::size_t channel_number)
retrun a single channel across all time samples
return true if the Dimension is represented in the structure
Definition: TypeTraits.h:71
std::enable_if< std::is_same< Dim, units::Frequency >::value, DimensionSize< units::Frequency > >::type dimension() const
Spectra spectrum(std::size_t offset)
return a single spectrum from the specified offset
boost::units::frequency_dimension Frequency
Definition: Frequency.h:45