/** @brief Constructs a tensor with a matrix * * \note Initially the tensor will be two-dimensional. * * @param v matrix to be copied. */ BOOST_UBLAS_INLINE tensor (const matrix_type &v) : tensor_expression_type<self_type>() , extents_ () , strides_ () , data_ (v.data()) { if(!data_.empty()){ extents_ = extents_type{v.size1(),v.size2()}; strides_ = strides_type(extents_); } }
static pointer storage (matrix_type& v) { return v.data(); }
static pointer storage (matrix_type& v) { typedef typename detail::generate_const<V,ArrT>::type array_type; return vector_traits<array_type>::storage (v.data()); }
static int lower_bandwidth(matrix_type& hm) { return detail::matrix_bandwidth( hm.data(), uplo_type() ); }
static int leading_dimension (matrix_type& hm) { return matrix_traits<m_type>::leading_dimension (hm.data()); }
static pointer storage (matrix_type& hm) { return matrix_traits<m_type>::storage (hm.data()); }
static std::ptrdiff_t leading_dimension (matrix_type& sm) { return matrix_traits<m_type>::leading_dimension (sm.data()); }
void operator()( const state_type& x, matrix_type& jacobi, const double& t, state_type& dfdt) const { // fill 0 into jacobi and dfdt for (state_type::iterator i(dfdt.begin()); i != dfdt.end(); ++i) { *i = 0.0; } for (matrix_type::array_type::iterator i(jacobi.data().begin()); i != jacobi.data().end(); ++i) { *i = 0.0; } // Calculate jacobian for each reaction and merge it. for (reaction_container_type::const_iterator i(reactions_.begin()); i != reactions_.end(); i++) { // Calculate a reaction's jacobian. // prepare state_array that contain amounts of reactants index_container_type::size_type reactants_size(i->reactants.size()); index_container_type::size_type products_size(i->products.size()); Ratelaw::state_container_type reactants_states(reactants_size); Ratelaw::state_container_type products_states(products_size); Ratelaw::state_container_type::size_type cnt(0); for (index_container_type::const_iterator j((*i).reactants.begin()); j != (*i).reactants.end(); ++j, cnt++) { reactants_states[cnt] = x[*j]; } cnt = 0; for (index_container_type::const_iterator j((*i).products.begin()); j != (*i).products.end(); ++j, cnt++) { products_states[cnt] = x[*j]; } // prepare matrix object that will be filled with numerical differentiate. matrix_type::size_type row_length = reactants_size + products_size; matrix_type::size_type col_length = row_length; matrix_type mat(row_length, col_length); // get the pointer of Ratelaw object and call it. if (i->ratelaw.expired() || i->ratelaw.lock()->is_available() == false) { boost::scoped_ptr<Ratelaw> temporary_ratelaw_obj(new RatelawMassAction(i->k)); temporary_ratelaw_obj->jacobi_func(mat, reactants_states, products_states, volume_); } else { boost::shared_ptr<Ratelaw> ratelaw = (*i).ratelaw.lock(); (*ratelaw).jacobi_func(mat, reactants_states, products_states, volume_); } //merge jacobian for(matrix_type::size_type row(0); row < row_length; row++) { matrix_type::size_type j_row(row < reactants_size ? (*i).reactants[row] : (*i).products[row - reactants_size]); for(matrix_type::size_type col(0); col < col_length; col++) { matrix_type::size_type j_col(col < reactants_size ? (*i).reactants[col] : (*i).products[col - reactants_size]); jacobi(j_row, j_col) += mat(row, col); } } } }