template<class T> inline static Matrix<T> min (const Matrix<T>& M, const size_t& dim = 0) { Vector<size_t> dims = size(M); size_t m = dims[0]; size_t n = numel(M)/m; dims[dim] = 1; Matrix<T> ret(dims); for (size_t i = 0; i < n; ++i) ret[i] = *std::min_element(M.Begin()+i*m,M.Begin()+(i+1)*m); return ret; }
/* * @brief Create new vector * and copy the data into the new vector. If the target * is bigger, the remaining space is set 0. If it is * smaller data is truncted. * * @param M The matrix to resize * @param sz New length * @return Resized vector */ template <class T> inline static Matrix<T> resize (const Matrix<T>& M, size_t sz) { Matrix<T> res (sz,1); size_t copysz = std::min(numel(M), sz); typename Vector<T>:: iterator rb = res.Begin (); typename Vector<T>::const_iterator mb = M.Begin (); std::copy (mb, mb+copysz, rb); return res; }
/** * @brief Unary minus (additive inverse) * * @return Negation */ inline Matrix<T,P> operator- () const { Matrix<T,P> res (_dim); #if defined USE_VALARRAY res = -_M; #else #ifdef EW_OMP #pragma omp parallel for for (size_t i = 0; i < Size(); ++i) res[i] = -_M[i]; #else std::transform (_M.begin(), _M.end(), res.Begin(), std::negate<T>()); #endif #endif return res; }
/** * @brief Product along a dimension * * Usage: * @code * Matrix<cxfl> m = rand<double> (8,7,6); * m = prod (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> prod (const Matrix<T>& M, size_t d) { Matrix<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 and outer sizes Vector<size_t>::const_iterator ci = sz.Begin(); size_t insize = std::accumulate (ci, ci+d, 1, c_multiply<size_t>); size_t outsize = std::accumulate (ci+d+1, ci+d+std::min(M.NDim(),sz.Size()), 1, c_multiply<size_t>); // Adjust size vector and allocate sz [d] = 1; res = Matrix<T>(sz); // Sum #pragma omp parallel default (shared) { #pragma omp for for (size_t 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 Ones matrix * * @param col Column * @param lin Rows * @param cha Dimension * @param set Dimension * @param eco Dimension * @param phs Dimension * @param rep Dimension * @param seg Dimension * @param par Dimension * @param slc Dimension * @param ida Dimension * @param idb Dimension * @param idc Dimension * @param idd Dimension * @param ide Dimension * @param ave Dimension * * @return Ones matrix * */ template <class T> inline static Matrix<T> ones (const size_t& col, const size_t& lin, const size_t& cha = 1, const size_t& set = 1, const size_t& eco = 1, const size_t& phs = 1, const size_t& rep = 1, const size_t& seg = 1, const size_t& par = 1, const size_t& slc = 1, const size_t& ida = 1, const size_t& idb = 1, const size_t& idc = 1, const size_t& idd = 1, const size_t& ide = 1, const size_t& ave = 1) { Matrix<T> res (col, lin, cha, set, eco, phs, rep, seg, par, slc, ida, idb, idc, idd, ide, ave); std::fill (res.Begin(), res.End(), T(1)); return res; }
/** * @brief Product of all elements * * Usage: * @code * Matrix<cxfl> m = rand<double> (8,7,6); * m = prod (m); * @endcode * * @param M Matrix * @return Sum of M along dimension d */ template <class T> inline static T prod (const Matrix<T>& M) { return std::accumulate(M.Begin(), M.End(), T(1), c_multiply<T>); }
template <class T> inline static T sum2 (const Matrix<T>& M) { return std::accumulate (M.Begin(), M.End(), (T)1, std::plus<T>()); }
template<class T> inline static T mmin (const Matrix<T>& M) { return *std::min_element(M.Begin(), M.End()); }