Boost logo

Ublas :

From: Gunter Winkler (guwi17_at_[hidden])
Date: 2007-05-31 06:13:45


On Thursday 31 May 2007 02:23, Ian Fellows wrote:
> here is the function :
>
> void row_product_assign(matrix<float> &mat,vector<float> &vec)
> {
> #ifndef NDEBUG
> if(vec.size()!=mat.size2())
> std::cout<<"Error: In row_product_assign. vector length not equal to
> matrix.\n";
> #endif
> for(unsigned i = 0; i < mat.size2 (); ++ i)
> {
> //I get errors here with noalias : error C2676: binary '*=' :
> 'boost::numeric::ublas::noalias_proxy<C>' does not define this operator or
> a conversion to a type acceptable to the predefined operator
> (column(mat,i))*=vec(i);

multiplication with a scalar is assumed to be alias free. (This may give
undefined results if you write A *= A(2,2);) Thus noalias() does not provide
operator *= ().

> }
> }
>
> Also, I was wondering if anyone had any suggestions on how to add a scalar
> to a vector/matrix efficiently? My crude attempt is:

vec += scalar_vector<vec::value_type>(vec.size(), t);

> void row_product_assign_alias(matrix<float> &mat,vector<float> &vec)
> {
> #ifndef NDEBUG
> if(vec.size()!=mat.size2())
> std::cout<<"Error: In row_product_assign. vector length not equal to
> matrix.\n";
> #endif
> for(unsigned i = 0; i < mat.size2 (); ++ i)
> {
> column(mat,i)*=vec(i);
> }
> }

noalias(mat) = element_prod(mat, outer_prod(vec,
scalar_vector<mat_type::value_type>(mat.size1(),1.0)));
// IMO better name: multiply_assign or simply scale
// the noalias assumes that the new value of mat(i,j) only depends on
// mat(i,j) and some independent values, which is ok for this operation

> void row_product_alias(matrix<float> &mat,vector<float> &vec,matrix<float>
> &target_matrix)
> {
> #ifndef NDEBUG
> if(vec.size()!=mat.size2())
> std::cout<<"Error: In row_product_assign. vector length not equal to
> matrix.\n";
> #endif
> for(unsigned i = 0; i < mat.size2 (); ++ i)
> {
> column(target_matrix,i)=column(mat,i)*vec(i);
> }
> }

noalias(target_matrix) = element_prod(mat, outer_prod(vec,
scalar_vector<mat_type::value_type>(mat.size1(),1.0)));

> matrix<float> element_row_sum_alias(const matrix<float> &mat,const
> vector<float> &vec)
> {
> matrix<float> target_matrix(mat.size1(),mat.size2());
> #ifndef NDEBUG
> if(vec.size()!=mat.size1())
> std::cout<<"Error: In element_row_sum. vector length not equal to
> matrix.\n";
> #endif
> for(unsigned i = 0; i < mat.size1 (); ++ i)
> {
> row(target_matrix,i)=row(mat,i)+vec;
> }
> return(target_matrix);
> }

noalias(target) = mat + outer_prod(
scalar_vector<mat_type::value_type>(target.size1(), 1.0), vec);
// note: target == mat is ok here.
noalias(mat) += outer_prod( scalar_vector<mat_type::value_type>(target.size1
(), 1.0), vec);

mfg
Gunter