Alexandria  2.22.0
Please provide a description of the project.
SamplingPolicy.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * @file SamplingPolicy.h
21  * @author nikoapos
22  */
23 
24 #ifndef SOM_SAMPLINGPOLICY_H
25 #define SOM_SAMPLINGPOLICY_H
26 
27 #include <iterator>
28 #include <list>
29 #include <random>
30 #include <utility>
31 
32 namespace Euclid {
33 namespace SOM {
34 namespace SamplingPolicy {
35 
36 template <typename IterType>
37 class Interface {
38 
39 public:
40  virtual IterType start(IterType begin, IterType end) const = 0;
41 
42  virtual IterType next(IterType iter) const = 0;
43 };
44 
45 template <typename IterType>
46 class FullSet : public Interface<IterType> {
47 
48 public:
49  IterType start(IterType begin, IterType) const override {
50  return begin;
51  }
52 
53  IterType next(IterType iter) const override {
54  return ++iter;
55  }
56 };
57 
58 template <typename IterType>
59 class Bootstrap : public Interface<IterType> {
60 
61 public:
62  IterType start(IterType begin, IterType end) const override {
63 
64  m_end = end;
65 
67  std::mt19937 gen(rd());
68  std::uniform_int_distribution<> dis(0, std::distance(begin, end) - 1);
69  auto random_index = dis(gen);
70 
71  auto result = begin;
72  std::advance(result, random_index);
73 
74  return result;
75  }
76 
77  IterType next(IterType) const override {
78  return m_end;
79  }
80 
81 private:
82  mutable IterType m_end;
83 };
84 
85 template <typename IterType>
87  return Bootstrap<IterType>{};
88 }
89 
90 template <typename IterType>
91 class Jackknife : public Interface<IterType> {
92 
93 public:
94  explicit Jackknife(std::size_t sample_size) : m_sample_size(sample_size), m_current(sample_size) {
95  m_iter_list.reserve(sample_size);
96  }
97 
98  IterType start(IterType begin, IterType end) const override {
99 
100  m_end = end;
101 
102  // Clear the iterators list, for the case it has already something inside
103  m_iter_list.clear();
105 
106  // Put all the possible iterators in a temporary linked list
107  std::list<IterType> all_iter_list{};
108  for (auto it = begin; it != end; ++it) {
109  all_iter_list.push_back(it);
110  }
111 
112  // Create the random device to use
114  std::mt19937 gen(rd());
115 
116  // Pick up m_sample_size random iterators from the temporary list
117  int all_max_index = all_iter_list.size() - 1;
118  for (std::size_t i = 0; i < m_sample_size && all_max_index >= 0; ++i, --all_max_index) {
119  std::uniform_int_distribution<> dis(0, all_max_index);
120  auto it = all_iter_list.begin();
121  std::advance(it, dis(gen));
122  m_iter_list.push_back(*it);
123  all_iter_list.erase(it);
124  }
125 
126  // Set the current iterator at the beginning of the vector and return it
127  m_current = 0;
129  return m_iter_list[m_current];
130  }
131 
132  IterType next(IterType) const override {
133  ++m_current;
134  if (m_current >= m_iter_list_size) {
135  return m_end;
136  }
137  return m_iter_list[m_current];
138  }
139 
140 private:
144  mutable IterType m_end;
146 };
147 
148 template <typename IterType>
150  return Jackknife<IterType>{sample_size};
151 }
152 
153 } // namespace SamplingPolicy
154 } // namespace SOM
155 } // namespace Euclid
156 
157 #endif /* SOM_SAMPLINGPOLICY_H */
T advance(T... args)
IterType start(IterType begin, IterType end) const override
IterType next(IterType) const override
IterType next(IterType iter) const override
IterType start(IterType begin, IterType) const override
virtual IterType start(IterType begin, IterType end) const =0
virtual IterType next(IterType iter) const =0
IterType start(IterType begin, IterType end) const override
IterType next(IterType) const override
Jackknife(std::size_t sample_size)
T clear(T... args)
T distance(T... args)
Jackknife< IterType > jackknifeFactory(IterType, std::size_t sample_size)
Bootstrap< IterType > bootstrapFactory(IterType)
T push_back(T... args)
T reserve(T... args)
T size(T... args)