C ++ / STL: std :: transform with given step?

I have a 1d array containing Nd data, I would like to efficiently traverse it using std :: transform or std :: for_each.

unigned int nelems; unsigned int stride=3;// we are going to have 3D points float *pP;// this will keep xyzxyzxyz... Load(pP); std::transform(pP, pP+nelems, strMover<float>(pP, stride));//How to define the strMover?? 
+6
source share
4 answers

Well, I decided to use for_each instead of converting any other solutions:

 generator<unsigned int> gen(0, 1); vector<unsigned int> idx(m_nelem);//make an index std::generate(idx.begin(), idx.end(),gen); std::for_each(idx.begin(), idx.end(), strMover<float>(&pPOS[0],&m_COM[0],stride)); 

Where

 template<class T> T op_sum (T i, T j) { return i+j; } template<class T> class strMover { T *pP_; T *pMove_; unsigned int stride_; public: strMover(T *pP,T *pMove, unsigned int stride):pP_(pP), pMove_(pMove),stride_(stride) {} void operator() ( const unsigned int ip ) { std::transform(&pP_[ip*stride_], &pP_[ip*stride_]+stride_, pMove_, &pP_[ip*stride_], op_sum<T>); } }; 

At first glance, it is a stream safe solution.

+1
source

The answer is not to change strMover , but to change the iterator. Define a new iterator class that wraps float * , but moves forward 3 places when operator++ called.

You can use boost a permutation iterator and use non-line permutation, which includes only the range of interest to you.

If you try to flip your own iterator, there are some errors: in order to stay strict with the standard, you need to carefully think about which correct β€œend” iterator for such a step iterator, since a naive implementation will be a fun step outside the allowed β€œone end” to the end "into the dark region far beyond the end of the array, where the pointers should not enter, for fear of nasal demons .

But I have to ask: why do you first store an array of three-dimensional points as an array of float ? Just define the Point3D data Point3D and create an array instead. Much easier.

+3
source

This is terrible, people told you to use step iterators instead. Besides the fact that you cannot use the functional objects from the standard library with this approach, you make the compiler very difficult to create multi-core or sse-optimizations using such crutches. Look for "stride iterator" for the correct solution, for example in a C ++ cookbook.

And back to the original question ... use valarray and stride to model multidimensional arrays.

+1
source

use boost adapters. you can get iterators from them. the only drawback is compilation time.

 vector<float> pp = vector_load(pP); boost::for_each(pp|stride(3)|transformed(dosmtn())); 
0
source

All Articles