libpnicore
c_index_map_imp.hpp
1 //
2 // (c) Copyright 2013 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpnicore.
5 //
6 // libpnicore is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpnicore is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpnicore. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // ============================================================================
20 //
21 // Created on: Oct 20, 2013
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 
25 #pragma once
26 
27 #include <iostream>
28 #include <sstream>
29 #include <array>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33 
34 #include "../../error/exceptions.hpp"
35 #include "../../error/exception_utils.hpp"
36 
37 namespace pni{
38 namespace core{
39 
48  {
49  private:
62  template<typename IITERT,
63  typename SITERT>
64  static size_t offset(IITERT &&index_start,
65  IITERT &&index_stop,
66  SITERT &&shape_start)
67  {
68  //initialize the offset and the stride variable
69  size_t offset = *index_start++,stride=1;
70 
71  //loop over all indices - remember that the iterators are
72  //reverse iterators
73  while(index_start!=index_stop)
74  {
75  //compute the actuall stride
76  stride *= *shape_start++;
77  //compute the offset contribution
78  offset += stride*(*index_start++);
79  }
80 
81  return offset;
82  }
83 
84  //------------------------------------------------------------------
104  template<
105  typename SELITER,
106  typename SITER,
107  typename IITER
108  >
109  static size_t offset(SELITER &&sel_shape_start,
110  SELITER &&sel_shape_end,
111  SELITER &&sel_offset,
112  SELITER &&sel_stride,
113  SITER &&shape_start,
114  IITER &&sel_index)
115  {
116  size_t index = *sel_offset++;
117 
118  if(*sel_shape_start++ != 1) index += (*sel_index++)*(*sel_stride);
119  ++sel_stride;
120 
121  //initialize the offset and the stride variable
122  size_t offset = index ,dim_stride=1;
123 
124  //loop over all indices - remember that the iterators are
125  //reverse iterators
126  while(sel_shape_start!=sel_shape_end)
127  {
128  //compute the index from the selection
129  index = *sel_offset++;
130  if(*sel_shape_start++ != 1)
131  index += (*sel_index++)*(*sel_stride);
132 
133  ++sel_stride; //increment the selection stride in any case
134 
135  //compute the actuall stride
136  dim_stride *= *shape_start++;
137  //compute the offset contribution
138  offset += dim_stride*index;
139  }
140 
141  return offset;
142  }
143 
144 
145  //------------------------------------------------------------------
159  template<
160  typename IITERT,
161  typename SITERT
162  >
163  static void index(SITERT &&shape_start,
164  SITERT &&shape_stop,
165  IITERT &&index_start,
166  size_t offset)
167  {
168  size_t t;
169  size_t stride = std::accumulate(++shape_start,shape_stop,1,
170  std::multiplies<size_t>());
171  t = offset%stride;
172  *(index_start++) = (offset-t)/stride;
173  offset = t;
174  while(shape_start != shape_stop)
175  {
176  //increment here the shape_start iterator - we already start
177  //with start+1 with the stride computation
178  stride /= *shape_start++;
179  t = offset%stride;
180  *(index_start++) = (offset-t)/stride;
181  offset = t;
182  }
183  }
184  public:
185 
186  //-----------------------------------------------------------------
201  template<
202  typename CSHAPE,
203  typename CINDEX
204  >
205  static size_t offset(const CSHAPE &shape,const CINDEX &index)
206  {
207  //use here reverse iterators as required by the c-ordering
208  return offset(index.rbegin(),index.rend(),shape.rbegin());
209  }
210 
211  //-----------------------------------------------------------------
227  template<
228  typename SELTYPE,
229  typename CSHAPE,
230  typename SINDEX
231  >
232  static size_t offset(const SELTYPE &sel,const CSHAPE &shape,
233  const SINDEX &index)
234  {
235  return offset(sel.full_shape().rbegin(), //original selection shape
236  sel.full_shape().rend(), //
237  sel.offset().rbegin(), //selection offset
238  sel.stride().rbegin(), //selection stride
239  shape.rbegin(), //original shape begin
240  index.rbegin()); //selection index start
241  }
242 
243  //-----------------------------------------------------------------
258  template<
259  typename CINDEX,
260  typename CSHAPE
261  >
262  static void index(const CSHAPE &shape,CINDEX &idx,size_t offset)
263  {
264  //for index computation we can use the forward iterators
265  index(shape.begin(),shape.end(),idx.begin(),offset);
266  }
267 
268  //-----------------------------------------------------------------
285  template<
286  typename CTYPE,
287  typename SELTYPE
288  >
289  static bool is_contiguous(const CTYPE &shape,const SELTYPE &sel)
290  {
291  auto oshape = sel.template full_shape<CTYPE>();
292 
293  auto oiter = oshape.begin();
294  auto siter = shape.begin();
295 
296  for(;siter != shape.end(); ++oiter,++siter)
297  {
298  if((*oiter!=1)&&(*oiter!=*siter)) return false;
299  }
300 
301  return true;
302 
303  }
304 
305  };
306 //end of namespace
307 }
308 }
static size_t offset(IITERT &&index_start, IITERT &&index_stop, SITERT &&shape_start)
compute the offset
Definition: c_index_map_imp.hpp:64
static void index(SITERT &&shape_start, SITERT &&shape_stop, IITERT &&index_start, size_t offset)
compute the index
Definition: c_index_map_imp.hpp:163
Definition: add_op.hpp:29
static bool is_contiguous(const CTYPE &shape, const SELTYPE &sel)
identify a contiguous selection
Definition: c_index_map_imp.hpp:289
C index map implementation.
Definition: c_index_map_imp.hpp:47
static size_t offset(const CSHAPE &shape, const CINDEX &index)
compute the offset
Definition: c_index_map_imp.hpp:205
static size_t offset(const SELTYPE &sel, const CSHAPE &shape, const SINDEX &index)
compute offset for selection
Definition: c_index_map_imp.hpp:232
static void index(const CSHAPE &shape, CINDEX &idx, size_t offset)
compute index
Definition: c_index_map_imp.hpp:262
static size_t offset(SELITER &&sel_shape_start, SELITER &&sel_shape_end, SELITER &&sel_offset, SELITER &&sel_stride, SITER &&shape_start, IITER &&sel_index)
compute selection offset
Definition: c_index_map_imp.hpp:109