void check_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) const { MTL_DEBUG_THROW_IF(begin_r < begin_row(), range_error("begin_row out of range")); // if (end_r > end_row()) std::cout << "end_row out of range\n"; MTL_DEBUG_THROW_IF(end_r > end_row(), range_error("end_row out of range")); MTL_DEBUG_THROW_IF(begin_c < begin_col(), range_error("begin_col out of range")); MTL_DEBUG_THROW_IF(end_c > end_col(), range_error("end_col out of range")); }
void mult(const VectorIn& v, VectorOut& w, Assign) const { MTL_DEBUG_THROW_IF(std::size_t(size(v)) != n, incompatible_size()); MTL_DEBUG_THROW_IF(size(w) != 0 && std::size_t(size(w)) != m, incompatible_size()); if (size(w) == 0) w.change_dim(m); if (m == n) Assign::first_update(w, v); else if (m < n) Assign::first_update(w, v[irange(m)]); else { VectorOut w1(w[irange(n)]), w2(w[irange(n, imax)]); Assign::first_update(w1, v); Assign::init(w2); } }
void mult(const VectorIn& v, VectorOut& w, Assign) const { MTL_DEBUG_THROW_IF(int(size(v)) != s, incompatible_size()); MTL_DEBUG_THROW_IF(size(v) != size(w), incompatible_size()); const int nb = n < 3 ? 1 : (n - 2) / 4 * 4 + 1; // Inner domain for (int i= 1; i < m-1; i++) { int kmax= i * n + nb; for (int k= i * n + 1; k < kmax; k+= 4) { typename Collection<VectorIn>::value_type const v0= v[k], v1= v[k+1], v2= v[k+2], v3= v[k+3]; Assign::apply(w[k], 4 * v0 - v[k-n] - v[k+n] - v[k-1] - v1); Assign::apply(w[k+1], 4 * v1 - v[k-n+1] - v[k+n+1] - v0 - v2); Assign::apply(w[k+2], 4 * v2 - v[k-n+2] - v[k+n+2] - v1 - v3); Assign::apply(w[k+3], 4 * v3 - v[k-n+3] - v[k+n+3] - v2 - v[k+4]); } for (int j= nb, k= i * n + j; j < n-1; j++, k++) Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1] - v[k+1]); } // Upper border for (int j= 1; j < n-1; j++) Assign::apply(w[j], 4 * v[j] - v[j+n] - v[j-1] - v[j+1]); // Lower border for (int j= 1, k= (m-1) * n + j; j < n-1; j++, k++) Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k-1] - v[k+1]); // Left border for (int i= 1, k= n; i < m-1; i++, k+= n) Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k+1]); // Right border for (int i= 1, k= n+n-1; i < m-1; i++, k+= n) Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1]); // Corners Assign::apply(w[0], 4 * v[0] - v[1] - v[n]); Assign::apply(w[n-1], 4 * v[n-1] - v[n-2] - v[2*n - 1]); Assign::apply(w[(m-1)*n], 4 * v[(m-1)*n] - v[(m-2)*n] - v[(m-1)*n+1]); Assign::apply(w[m*n-1], 4 * v[m*n-1] - v[m*n-2] - v[m*n-n-1]); }
void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_) { vampir_trace<6001> tracer; // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation TT& first_eval= const_cast<TT&>(const_first_eval); UU& second_eval= const_cast<UU&>(const_second_eval); MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size()); for (std::size_t i= 0, s= size(first_eval); i < s; i++) { first_eval(i); second_eval(i); } }
void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_) { vampir_trace<6003> tracer; // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation TT& first_eval= const_cast<TT&>(const_first_eval); UU& second_eval= const_cast<UU&>(const_second_eval); MTL_DEBUG_THROW_IF(mtl::vector::size(first_eval) != mtl::vector::size(second_eval), incompatible_size()); for (std::size_t i= size(first_eval); i-- > 0; ) { // std::cout << "i is " << i << "\n"; first_eval(i); second_eval(i); } }
void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_) { vampir_trace<6002> tracer; // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation TT& first_eval= const_cast<TT&>(const_first_eval); UU& second_eval= const_cast<UU&>(const_second_eval); MTL_DEBUG_THROW_IF(mtl::vec::size(first_eval) != mtl::vec::size(second_eval), incompatible_size()); const std::size_t s= size(first_eval), sb= s >> 2 << 2; for (std::size_t i= 0; i < sb; i+= 4) { first_eval.template at<0>(i); second_eval.template at<0>(i); first_eval.template at<1>(i); second_eval.template at<1>(i); first_eval.template at<2>(i); second_eval.template at<2>(i); first_eval.template at<3>(i); second_eval.template at<3>(i); } for (std::size_t i= sb; i < s; i++) { first_eval(i); second_eval(i); } }
void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_) { vampir_trace<6004> tracer; // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation TT& first_eval= const_cast<TT&>(const_first_eval); UU& second_eval= const_cast<UU&>(const_second_eval); MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size()); std::size_t s= size(first_eval), i= s-1, m= s % 4; for (; m; m--) { // std::cout << "i is " << i << "\n"; first_eval(i); second_eval(i--); } for(long j= i - 3; j >= 0; j-= 4) { // std::cout << "i is " << j+3 << ".." << j << "\n"; first_eval.template at<3>(j); second_eval.template at<3>(j); first_eval.template at<2>(j); second_eval.template at<2>(j); first_eval.template at<1>(j); second_eval.template at<1>(j); first_eval.template at<0>(j); second_eval.template at<0>(j); } }
void set_ranges(size_type br, size_type er, size_type bc, size_type ec) { MTL_DEBUG_THROW_IF(br > er, range_error("begin row > end row")); MTL_DEBUG_THROW_IF(bc > ec, range_error("begin column > end column")); my_begin_row= br; my_end_row= er; my_begin_col= bc; my_end_col= ec; }
// Either changed matrix is uninitialized (i.e. 0x0) or dimensions are equal void check_dim(size_type num_rows, size_type num_cols) const { MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0 && (this->num_rows() != num_rows || this->num_cols() != num_cols), incompatible_size()); }