Developer documentation
Version 3.0.3-105-gd3941f44
random_loop.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __algo_random_loop_h__
18#define __algo_random_loop_h__
19
20#include "apply.h"
21#include "progressbar.h"
22#include "stride.h"
23#include "image_helpers.h"
24#include <unordered_set>
25#include <algorithm> // std::shuffle
26#include <iterator>
27
28namespace MR
29{
30
31 template <class ImageType, class RandomEngine>
33 public:
34 Random_loop (ImageType& in,
35 RandomEngine& random_engine,
36 const size_t& axis = 0,
37 const size_t& number_iterations = std::numeric_limits<ssize_t>::max()):
38 image (in),
39 engine (random_engine),
40 ax (axis),
41 idx(image.size(axis)),
42 max_cnt (number_iterations),
43 status (true),
44 cnt (0)
45 {
46 init();
48 }
49 void init() {
50 std::iota (std::begin(idx), std::end(idx), 0);
51 std::shuffle(std::begin(idx), std::end(idx), engine);
52 cnt = 0;
53 it = std::begin(idx);
54 stop = std::end(idx);
55 }
56
58 ++cnt;
59 image.index(ax) = *it;
60 it++;
61 }
62
64 {
66 if (cnt > max_cnt or it == stop) {
67 status = false;
68 }
69 }
70 operator bool() const
71 {
72 return status && image.index(ax) >= 0 && image.index(ax) < image.size(ax);
73 }
74
75 private:
76 ImageType& image;
77 RandomEngine& engine;
78 size_t ax;
82 size_t max_cnt;
83 bool status;
84 size_t cnt;
85 };
86
87 // Random_sparse_loop: ok for VERY sparse loops, slows down significantly at higher density (>5%)
88 template <class ImageType>
90 public:
91 Random_sparse_loop (ImageType& in,
92 const size_t& axis = 0,
93 const size_t& number_iterations = std::numeric_limits<ssize_t>::max(),
94 const bool repeat = false,
95 const ssize_t& min_index = 0,
96 const ssize_t& max_index = std::numeric_limits<ssize_t>::max()):
97 image (in),
98 repeat_ (repeat),
99 status (true),
100 ax (axis),
101 cnt (0),
102 min_idx (min_index)
103 {
104 if (max_index < image.size(ax))
105 range = max_index - min_idx + 1;
106 else
107 range = image.size(ax) - min_idx;
108 if (number_iterations < range)
109 max_cnt = number_iterations;
110 else
111 max_cnt = range;
112 assert (range >= 1);
113 assert (max_cnt >= 1);
114 if (repeat_)
116 else
118 }
119
121 while (cnt < max_cnt){
122 index = rand() % range + min_idx;
123 if (!idx_done.count(index)){
124 idx_done.insert(index);
125 break;
126 }
127 }
128 ++cnt;
129 image.index(ax) = index;
130 assert(idx_done.size() < range);
131 }
132
134 index = rand() % range + min_idx;
135 ++cnt;
136 image.index(ax) = index;
137 }
138
140 {
141 if (repeat_)
143 else
145 if (cnt > max_cnt) {
146 status = false;
147 }
148 }
149 operator bool() const
150 {
151 return status && image.index(ax) >= 0 && image.index(ax) < image.size(ax);
152 }
153
154 private:
155 ImageType& image;
156 bool repeat_;
157 bool status;
158 size_t ax;
159 size_t cnt;
160 ssize_t min_idx;
161 size_t range;
162 size_t max_cnt;
163 ssize_t index;
164 std::unordered_set<ssize_t> idx_done;
165 };
166
167 template <class ImageType, class IterType>
169 public:
170 Iterator_loop (ImageType& in,
171 IterType first,
172 IterType last,
173 const size_t& axis = 0,
174 const size_t& number_iterations = std::numeric_limits<ssize_t>::max()):
175 image (in),
176 ax (axis),
177 start (first),
178 stop (last),
179 max_cnt (number_iterations),
180 status (true),
181 cnt (0)
182 {
184 }
185
187 ++cnt;
188 image.index(ax) = *start;
189 start++;
190 }
191
193 {
195 if (cnt > max_cnt or start == stop) {
196 status = false;
197 }
198 }
199 operator bool() const
200 {
201 return status && image.index(ax) >= 0 && image.index(ax) < image.size(ax);
202 }
203
204 private:
205 ImageType& image;
206 size_t ax;
207 IterType& start;
208 IterType& stop;
209 size_t max_cnt;
210 bool status;
211 size_t cnt;
212 };
213
214
216}
217
218#endif
219
220
Iterator_loop(ImageType &in, IterType first, IterType last, const size_t &axis=0, const size_t &number_iterations=std::numeric_limits< ssize_t >::max())
Definition: random_loop.h:170
Random_loop(ImageType &in, RandomEngine &random_engine, const size_t &axis=0, const size_t &number_iterations=std::numeric_limits< ssize_t >::max())
Definition: random_loop.h:34
void operator++()
Definition: random_loop.h:63
void set_next_index()
Definition: random_loop.h:57
Random_sparse_loop(ImageType &in, const size_t &axis=0, const size_t &number_iterations=std::numeric_limits< ssize_t >::max(), const bool repeat=false, const ssize_t &min_index=0, const ssize_t &max_index=std::numeric_limits< ssize_t >::max())
Definition: random_loop.h:91
void set_next_index_with_repeat()
Definition: random_loop.h:133
#define NOMEMALIGN
Definition: memory.h:22
Definition: base.h:24
int axis