#include <iostream> #include <vector> int main() { // shape, stride & data of the matrix size_t shape [] = { 2, 3, 4, 5}; size_t strides[] = {60,20, 5, 1}; std::vector<double> data(2*3*4*5); for ( size_t i = 0 ; i < data.size() ; ++i ) data[i] = 1.; // shape, stride & data (zero-initialized) of the reduced matrix size_t rshape [] = { 2, 4, 5}; size_t rstrides[] = {20, 5, 1}; std::vector<double> rdata(2*4*5, 0.0); // compute reduction // for ( size_t a = 0 ; a < shape[0] ; ++a ) // for ( size_t c = 0 ; c < shape[2] ; ++c ) // for ( size_t d = 0 ; d < shape[3] ; ++d ) // for ( size_t b = 0 ; b < shape[1] ; ++b ) // rdata[ a*rstrides[0] + c*rstrides[1] + d*rstrides[2] ] += \ // data [ a*strides [0] + b*strides [1] + c*strides [2] + d*strides [3] ]; size_t cmp_axis = 1, axis_count = sizeof shape/ sizeof *shape; std::vector<size_t> adjusted_strides; //adjusted strides is basically same as strides //only difference being that the first element is the //total number of elements in the n dim array. //The only reason to introduce this array was //so that I don't have to write any if-elses adjusted_strides.push_back(shape[0]*strides[0]); adjusted_strides.insert(adjusted_strides.end(), strides, strides + axis_count); for(size_t i = 0; i < data.size(); ++i) { size_t ni = i/adjusted_strides[cmp_axis]*adjusted_strides[cmp_axis+1] + i%adjusted_strides[cmp_axis+1]; rdata[ni] += data[i]; } // print resulting reduced matrix for ( size_t a = 0 ; a < rshape[0] ; ++a ) for ( size_t b = 0 ; b < rshape[1] ; ++b ) for ( size_t c = 0 ; c < rshape[2] ; ++c ) std::cout << "(" << a << "," << b << "," << c << ") " << \ rdata[ a*rstrides[0] + b*rstrides[1] + c*rstrides[2] ] << std::endl; return 0; }
Standard input is empty
(0,0,0) 3 (0,0,1) 3 (0,0,2) 3 (0,0,3) 3 (0,0,4) 3 (0,1,0) 3 (0,1,1) 3 (0,1,2) 3 (0,1,3) 3 (0,1,4) 3 (0,2,0) 3 (0,2,1) 3 (0,2,2) 3 (0,2,3) 3 (0,2,4) 3 (0,3,0) 3 (0,3,1) 3 (0,3,2) 3 (0,3,3) 3 (0,3,4) 3 (1,0,0) 3 (1,0,1) 3 (1,0,2) 3 (1,0,3) 3 (1,0,4) 3 (1,1,0) 3 (1,1,1) 3 (1,1,2) 3 (1,1,3) 3 (1,1,4) 3 (1,2,0) 3 (1,2,1) 3 (1,2,2) 3 (1,2,3) 3 (1,2,4) 3 (1,3,0) 3 (1,3,1) 3 (1,3,2) 3 (1,3,3) 3 (1,3,4) 3