73 template <
class HeaderType>
76 Compare (
const HeaderType& header) :
S (header) { }
77 bool operator() (
const size_t a,
const size_t b)
const {
82 return abs (
S.stride (a)) <
abs (
S.stride (b));
90 Wrapper (
List& strides) :
S (strides) { }
91 size_t ndim ()
const {
94 const ssize_t& stride (
size_t axis)
const {
97 ssize_t& stride (
size_t axis) {
104 template <
class HeaderType>
105 class InfoWrapper :
public Wrapper
108 InfoWrapper (
List& strides,
const HeaderType& header) : Wrapper (strides), D (header) {
109 assert (ndim() == D.ndim());
111 ssize_t size (
size_t axis)
const {
112 return D.size (
axis);
124 template <
class HeaderType>
127 List ret (header.ndim());
128 for (
size_t i = 0; i < header.ndim(); ++i)
129 ret[i] = header.stride (i);
134 template <
class HeaderType>
135 void set (HeaderType& header,
const List& stride)
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;
145 template <
class HeaderType,
class FromHeaderType>
146 void set (HeaderType& header,
const FromHeaderType& from)
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())
161 to_axis = std::min<size_t> (to_axis, header.ndim());
162 assert (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);
178 const Wrapper wrapper (
const_cast<List&
> (strides));
179 return order (wrapper, from_axis, to_axis);
190 template <
class HeaderType>
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;
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));
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;
221 template <
class HeaderType>
224 InfoWrapper<HeaderType> wrapper (strides, header);
238 template <
class HeaderType>
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]);
252 template <
class HeaderType>
255 InfoWrapper<HeaderType> wrapper (strides, header);
260 template <
class HeaderType>
269 template <
class HeaderType>
280 template <
class HeaderType>
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;
292 Wrapper wrapper (strides);
297 template <
class HeaderType>
318 template <
class HeaderType>
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);
332 template <
class HeaderType>
335 InfoWrapper<HeaderType> wrapper (strides, header);
363 template <
class HeaderType>
367 out.resize (in.size(), 0);
370 for (
size_t n = 0; n < dims.size(); ++n)
373 for (
size_t i = 0; i < out.size(); ++i)
375 if (
abs (out[i]) !=
abs (in[i]))
394 template <
class HeaderType>
401 template <
class HeaderType>
405 for (
size_t n = 3; n < strides.size(); ++n)
415 template <
class HeaderType>
419 if (cmdline_strides.size())
420 set (header, cmdline_strides);
421 else if (default_strides.size())
422 set (header, default_strides);
a class to hold a named list of Option's
std::pair< int, int > current()
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.
void actualise(HeaderType &header)
convert strides from symbolic to actual strides
List get_symbolic(const HeaderType &header)
get symbolic strides:
List __from_command_line(const List ¤t)
List contiguous_along_axis(size_t axis)
convenience function to get volume-contiguous strides
List contiguous_along_spatial_axes(const HeaderType &header)
convenience function to get spatially contiguous strides
vector< size_t > order< List >(const List &strides, size_t from_axis, size_t to_axis)
sort axes with respect to their absolute stride.
List get_nearest_match(const HeaderType ¤t, const List &desired)
produce strides from current that match those specified in desired
void symbolise(HeaderType &header)
convert strides from actual to symbolic strides
List get_actual(HeaderType &header)
get actual strides:
size_t offset(const HeaderType &header)
calculate offset to start of data
void sanitise(HeaderType &header)
remove duplicate and invalid strides.
void set_from_command_line(HeaderType &header, const List &default_strides=List())
void set(HeaderType &header, const List &stride)
set the strides of header from a vector<ssize_t>
const App::OptionGroup Options
List get(const HeaderType &header)
return the strides of header as a vector<ssize_t>
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)