/** * @brief Sum along a dimension * * Usage: * @code * Matrix<cxfl> m = rand<double> (8,7,6); * m = sum (m,0); // dims (7,6); * @endcode * * @param M Matrix * @param d Dimension * @return Sum of M along dimension d */ template <class T> inline static Matrix<T> sum (const MatrixType<T>& M, const size_t& d = 0) { Vector<size_t> sz = size(M); size_t dim = sz[d]; Matrix<T> res; assert (d < M.NDim()); // No meaningful sum over particular dimension if (dim == 1) return res; // Empty? allocation if (isempty(M)) return res; // Inner size size_t insize = 1; for (size_t i = 0; i < d; ++i) insize *= sz[i]; // Outer size size_t outsize = 1; for (size_t i = d+1; i < std::min(M.NDim(),sz.size()); ++i) outsize *= sz[i]; // Adjust size vector and allocate sz [d] = 1; res = Matrix<T>(sz); // Sum #pragma omp parallel default (shared) { #pragma omp for for (int i = 0; i < outsize; ++i) { for (size_t j = 0; j < insize; ++j) { res[i*insize + j] = T(0); for (size_t k = 0; k < dim; ++k) res[i*insize + j] += M[i*insize*dim + j + k*insize]; } } } return res; }
/** * @brief Highest dimension unequal 1 * * Usage: * @code * Matrix<cxfl> m = rand<double> (8,7,6); * size_t nd = ndims(m); // 2 * @endcode * * @param M Matrix * @return Highest non-one dimension */ template <class T> inline static size_t ndims (const MatrixType<T>& M) { size_t nd = 0; for (size_t i = 1; i < M.NDim(); ++i) if (size(M,i) > 1) nd = i; return (nd + 1); }