Developer documentation
Version 3.0.3-105-gd3941f44
stride.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 __stride_h__
18#define __stride_h__
19
20#include "app.h"
21#include "types.h"
22#include "debug.h"
23#include "datatype.h"
24#include "math/math.h"
25
26namespace MR
27{
28
30
60 namespace Stride
61 {
62
64
65 extern const App::OptionGroup Options;
66
67
68
69
71 namespace
72 {
73 template <class HeaderType>
74 class Compare { NOMEMALIGN
75 public:
76 Compare (const HeaderType& header) : S (header) { }
77 bool operator() (const size_t a, const size_t b) const {
78 if (S.stride(a) == 0)
79 return false;
80 if (S.stride(b) == 0)
81 return true;
82 return abs (S.stride (a)) < abs (S.stride (b));
83 }
84 private:
85 const HeaderType& S;
86 };
87
88 class Wrapper { NOMEMALIGN
89 public:
90 Wrapper (List& strides) : S (strides) { }
91 size_t ndim () const {
92 return S.size();
93 }
94 const ssize_t& stride (size_t axis) const {
95 return S[axis];
96 }
97 ssize_t& stride (size_t axis) {
98 return S[axis];
99 }
100 private:
101 List& S;
102 };
103
104 template <class HeaderType>
105 class InfoWrapper : public Wrapper
106 { NOMEMALIGN
107 public:
108 InfoWrapper (List& strides, const HeaderType& header) : Wrapper (strides), D (header) {
109 assert (ndim() == D.ndim());
110 }
111 ssize_t size (size_t axis) const {
112 return D.size (axis);
113 }
114 private:
115 const HeaderType& D;
116 };
117 }
119
120
121
122
124 template <class HeaderType>
125 List get (const HeaderType& header)
126 {
127 List ret (header.ndim());
128 for (size_t i = 0; i < header.ndim(); ++i)
129 ret[i] = header.stride (i);
130 return ret;
131 }
132
134 template <class HeaderType>
135 void set (HeaderType& header, const List& stride)
136 {
137 size_t n = 0;
138 for (; n < std::min<size_t> (header.ndim(), stride.size()); ++n)
139 header.stride (n) = stride[n];
140 for (; n < stride.size(); ++n)
141 header.stride (n) = 0;
142 }
143
145 template <class HeaderType, class FromHeaderType>
146 void set (HeaderType& header, const FromHeaderType& from)
147 {
148 set (header, get(from));
149 }
150
151
152
153
155
158 template <class HeaderType>
159 vector<size_t> order (const HeaderType& header, size_t from_axis = 0, size_t to_axis = std::numeric_limits<size_t>::max())
160 {
161 to_axis = std::min<size_t> (to_axis, header.ndim());
162 assert (to_axis > from_axis);
163 vector<size_t> ret (to_axis-from_axis);
164 for (size_t i = 0; i < ret.size(); ++i)
165 ret[i] = from_axis+i;
166 Compare<HeaderType> compare (header);
167 std::sort (ret.begin(), ret.end(), compare);
168 return ret;
169 }
170
172
175 template <> inline
176 vector<size_t> order<List> (const List& strides, size_t from_axis, size_t to_axis)
177 {
178 const Wrapper wrapper (const_cast<List&> (strides));
179 return order (wrapper, from_axis, to_axis);
180 }
181
182
183
184
186
190 template <class HeaderType>
191 void sanitise (HeaderType& header)
192 {
193 // remove duplicates
194 for (size_t i = 0; i < header.ndim()-1; ++i) {
195 if (header.size (i) == 1) header.stride (i) = 0;
196 if (!header.stride (i)) continue;
197 for (size_t j = i+1; j < header.ndim(); ++j) {
198 if (!header.stride (j)) continue;
199 if (abs (header.stride (i)) == abs (header.stride (j))) header.stride (j) = 0;
200 }
201 }
202
203 size_t max = 0;
204 for (size_t i = 0; i < header.ndim(); ++i)
205 if (size_t (abs (header.stride (i))) > max)
206 max = abs (header.stride (i));
207
208 for (size_t i = 0; i < header.ndim(); ++i) {
209 if (header.stride (i)) continue;
210 if (header.size (i) > 1) header.stride (i) = ++max;
211 }
212 }
213
214
215
217
221 template <class HeaderType>
222 inline void sanitise (List& strides, const HeaderType& header)
223 {
224 InfoWrapper<HeaderType> wrapper (strides, header);
225 sanitise (wrapper);
226 }
227
228
230
234 List& sanitise (List& current, const List& desired, const vector<ssize_t>& header);
235
236
238 template <class HeaderType>
239 void actualise (HeaderType& header)
240 {
241 sanitise (header);
242 vector<size_t> x (order (header));
243 ssize_t skip = 1;
244 for (size_t i = 0; i < header.ndim(); ++i) {
245 header.stride (x[i]) = header.stride (x[i]) < 0 ? -skip : skip;
246 skip *= header.size (x[i]);
247 }
248 }
250
252 template <class HeaderType>
253 inline void actualise (List& strides, const HeaderType& header)
254 {
255 InfoWrapper<HeaderType> wrapper (strides, header);
256 actualise (wrapper);
257 }
258
260 template <class HeaderType>
261 inline List get_actual (HeaderType& header)
262 {
263 List strides (get (header));
264 actualise (strides, header);
265 return strides;
266 }
267
269 template <class HeaderType>
270 inline List get_actual (const List& strides, const HeaderType& header)
271 {
272 List out (strides);
273 actualise (out, header);
274 return out;
275 }
276
277
278
280 template <class HeaderType>
281 void symbolise (HeaderType& header)
282 {
283 vector<size_t> p (order (header));
284 for (ssize_t i = 0; i < ssize_t (p.size()); ++i)
285 if (header.stride (p[i]) != 0)
286 header.stride (p[i]) = header.stride (p[i]) < 0 ? -(i+1) : i+1;
287 }
289 template <>
290 inline void symbolise (List& strides)
291 {
292 Wrapper wrapper (strides);
293 symbolise (wrapper);
294 }
295
297 template <class HeaderType>
298 inline List get_symbolic (const HeaderType& header)
299 {
300 List strides (get (header));
301 symbolise (strides);
302 return strides;
303 }
304
306 template <>
307 inline List get_symbolic (const List& list)
308 {
309 List strides (list);
310 symbolise (strides);
311 return strides;
312 }
313
314
316
318 template <class HeaderType>
319 size_t offset (const HeaderType& header)
320 {
321 size_t offset = 0;
322 for (size_t i = 0; i < header.ndim(); ++i)
323 if (header.stride (i) < 0)
324 offset += size_t (-header.stride (i)) * (header.size (i) - 1);
325 return offset;
326 }
327
329
332 template <class HeaderType>
333 size_t offset (List& strides, const HeaderType& header)
334 {
335 InfoWrapper<HeaderType> wrapper (strides, header);
336 return offset (wrapper);
337 }
338
339
340
342
363 template <class HeaderType>
364 List get_nearest_match (const HeaderType& current, const List& desired)
365 {
366 List in (get_symbolic (current)), out (desired);
367 out.resize (in.size(), 0);
368
369 vector<ssize_t> dims (current.ndim());
370 for (size_t n = 0; n < dims.size(); ++n)
371 dims[n] = current.size(n);
372
373 for (size_t i = 0; i < out.size(); ++i)
374 if (out[i])
375 if (abs (out[i]) != abs (in[i]))
376 return sanitise (in, out, dims);
377
378 sanitise (in, current);
379 return in;
380 }
381
382
383
384
387 {
388 List strides (axis+1,0);
389 strides[axis] = 1;
390 return strides;
391 }
392
394 template <class HeaderType>
395 inline List contiguous_along_axis (size_t axis, const HeaderType& header)
396 {
398 }
399
401 template <class HeaderType>
402 inline List contiguous_along_spatial_axes (const HeaderType& header)
403 {
404 List strides = get (header);
405 for (size_t n = 3; n < strides.size(); ++n)
406 strides[n] = 0;
407 return strides;
408 }
409
410
411
413
414
415 template <class HeaderType>
416 inline void set_from_command_line (HeaderType& header, const List& default_strides = List())
417 {
418 auto cmdline_strides = __from_command_line (get (header));
419 if (cmdline_strides.size())
420 set (header, cmdline_strides);
421 else if (default_strides.size())
422 set (header, default_strides);
423 }
424
425
426
427 }
428}
429
430#endif
431
a class to hold a named list of Option's
#define NOMEMALIGN
Definition: memory.h:22
std::pair< int, int > current()
Definition: gl.h:135
vector< size_t > order(const HeaderType &header, size_t from_axis=0, size_t to_axis=std::numeric_limits< size_t >::max())
sort range of axes with respect to their absolute stride.
Definition: stride.h:159
void actualise(HeaderType &header)
convert strides from symbolic to actual strides
Definition: stride.h:239
List get_symbolic(const HeaderType &header)
get symbolic strides:
Definition: stride.h:298
List __from_command_line(const List &current)
vector< ssize_t > List
Definition: stride.h:63
List contiguous_along_axis(size_t axis)
convenience function to get volume-contiguous strides
Definition: stride.h:386
List contiguous_along_spatial_axes(const HeaderType &header)
convenience function to get spatially contiguous strides
Definition: stride.h:402
vector< size_t > order< List >(const List &strides, size_t from_axis, size_t to_axis)
sort axes with respect to their absolute stride.
Definition: stride.h:176
List get_nearest_match(const HeaderType &current, const List &desired)
produce strides from current that match those specified in desired
Definition: stride.h:364
void symbolise(HeaderType &header)
convert strides from actual to symbolic strides
Definition: stride.h:281
List get_actual(HeaderType &header)
get actual strides:
Definition: stride.h:261
size_t offset(const HeaderType &header)
calculate offset to start of data
Definition: stride.h:319
void sanitise(HeaderType &header)
remove duplicate and invalid strides.
Definition: stride.h:191
void set_from_command_line(HeaderType &header, const List &default_strides=List())
Definition: stride.h:416
void set(HeaderType &header, const List &stride)
set the strides of header from a vector<ssize_t>
Definition: stride.h:135
const App::OptionGroup Options
Definition: app.h:274
List get(const HeaderType &header)
return the strides of header as a vector<ssize_t>
Definition: stride.h:125
Definition: base.h:24
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)
Definition: types.h:297
Eigen::MatrixXd S
int axis