Alexandria  2.27.0
SDC-CH common library for the Euclid project
SamplingPolicy.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2022 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 final : 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 final : public Interface<IterType> {
60 
61 public:
62  Bootstrap(IterType begin, IterType end) : m_end(end), m_dist{0, static_cast<int>(std::distance(begin, end) - 1)} {}
63 
64  IterType start(IterType begin, IterType end) const override {
65  auto random_index = m_dist(m_gen);
66  auto result = begin;
67  std::advance(result, random_index);
68  return result;
69  }
70 
71  IterType next(IterType) const override {
72  return m_end;
73  }
74 
75 private:
76  IterType m_end;
79 };
80 
81 template <typename IterType>
82 Bootstrap<IterType> bootstrapFactory(IterType begin, IterType end) {
83  return Bootstrap<IterType>{begin, end};
84 }
85 
86 template <typename IterType>
87 class Jackknife final : public Interface<IterType> {
88 
89 public:
90  explicit Jackknife(std::size_t sample_size) : m_sample_size(sample_size), m_current(sample_size) {
91  m_iter_list.reserve(sample_size);
92  }
93 
94  IterType start(IterType begin, IterType end) const override {
95 
96  m_end = end;
97 
98  // Clear the iterators list, for the case it has already something inside
101 
102  // Put all the possible iterators in a temporary linked list
103  std::list<IterType> all_iter_list{};
104  for (auto it = begin; it != end; ++it) {
105  all_iter_list.push_back(it);
106  }
107 
108  // Create the random device to use
110  std::mt19937 gen(rd());
111 
112  // Pick up m_sample_size random iterators from the temporary list
113  int all_max_index = all_iter_list.size() - 1;
114  for (std::size_t i = 0; i < m_sample_size && all_max_index >= 0; ++i, --all_max_index) {
115  std::uniform_int_distribution<> dis(0, all_max_index);
116  auto it = all_iter_list.begin();
117  std::advance(it, dis(gen));
118  m_iter_list.push_back(*it);
119  all_iter_list.erase(it);
120  }
121 
122  // Set the current iterator at the beginning of the vector and return it
123  m_current = 0;
125  return m_iter_list[m_current];
126  }
127 
128  IterType next(IterType) const override {
129  ++m_current;
130  if (m_current >= m_iter_list_size) {
131  return m_end;
132  }
133  return m_iter_list[m_current];
134  }
135 
136 private:
140  mutable IterType m_end;
142 };
143 
144 template <typename IterType>
146  return Jackknife<IterType>{sample_size};
147 }
148 
149 } // namespace SamplingPolicy
150 } // namespace SOM
151 } // namespace Euclid
152 
153 #endif /* SOM_SAMPLINGPOLICY_H */
T advance(T... args)
IterType start(IterType begin, IterType end) const override
IterType next(IterType) const override
Bootstrap(IterType begin, IterType end)
std::uniform_int_distribution m_dist
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)
Jackknife< IterType > jackknifeFactory(IterType, std::size_t sample_size)
Bootstrap< IterType > bootstrapFactory(IterType begin, IterType end)
STL namespace.
T push_back(T... args)
T reserve(T... args)
T size(T... args)