elementwise product or sum of two vectors

E

er

hi,

i'm trying to implement x*=y or x+=y; where x and y are containers and
*= and += are element wise i.e. x*=y is meant as
x[1]*=y[1],...,x[n]*=y[n] and likewise for +=;
i'm wondering if
a) there exists a function already defined for this purpose for the
types that i intend it for (see below)
b) is there a way to make * or + a parameter so that i don't have to
write two (nearly identical) pieces of code for each (see below).
c) more generally, is there a better way to do this?

// possible types for B and D:
// type boost::numeric::ublas::vector<double>
//

//code starts here:
template<typename D> class Op_product_term_by_term{
public:
Op_product_term_by_term(D& dest):iter(dest.begin()),end(dest.end())
{};
void operator()(double elem);
private:
typename D::iterator iter;
typename D::iterator end;
};
template<typename D> void Op_product_term_by_term<D>::eek:perator()
(double elem){
if(iter<end){
*(iter++)*=elem;
}else{
throw std::runtime_error("Aux::Op_product_term_by_term");
};
};
template<typename D> class Op_sum_term_by_term{
public:
Op_sum_term_by_term(D& dest):iter(dest.begin()),end(dest.end()){};
void operator()(double elem);
private:
typename D::iterator iter;
typename D::iterator end;
};
template<typename D> void Op_sum_term_by_term<D>::eek:perator()(double
elem){
if(iter<end){
*(iter++)+=elem;
}else{
throw std::runtime_error("Aux::Op_sum_term_by_term");
};
};
}
template<typename D, typename B> void product_term_by_term(D&
dest,const B& by){
if(dest.size()==by.size()){
for_each(by.begin(),by.end(),Op_product_term_by_term<D>(dest));
}else{
throw std::runtime_error("Aux::product_term_by_term");
};
};
template<typename D, typename B> void sum_term_by_term(D& dest,const
B& by){
if(dest.size()==by.size()){
for_each(by.begin(),by.end(),Op_sum_term_by_term<D>(dest));
}else{
throw std::runtime_error("Aux::sum_term_by_term");
};
};
 
V

Victor Bazarov

er said:
i'm trying to implement x*=y or x+=y; where x and y are containers and
*= and += are element wise i.e. x*=y is meant as
x[1]*=y[1],...,x[n]*=y[n] and likewise for +=;
i'm wondering if
a) there exists a function already defined for this purpose for the
types that i intend it for (see below)

You mean, like 'std::for_each'?
b) is there a way to make * or + a parameter so that i don't have to
write two (nearly identical) pieces of code for each (see below).

Probably. See 'std::plus' and 'std::multiplies'...
c) more generally, is there a better way to do this?

You mean, like using 'valarray', for example?

V
 
E

er

er said:
i'm trying to implement x*=y or x+=y; where x and y are containers and
*= and += are element wise i.e. x*=y is meant as
x[1]*=y[1],...,x[n]*=y[n] and likewise for +=;
i'm wondering if
a) there exists a function already defined for this purpose for the
types that i intend it for (see below)

You mean, like 'std::for_each'?
b) is there a way to make * or + a parameter so that i don't have to
write two (nearly identical) pieces of code for each (see below).

Probably. See 'std::plus' and 'std::multiplies'...
c) more generally, is there a better way to do this?

You mean, like using 'valarray', for example?

V

like this?
std::transform(vec.begin(), vec.end(), dest.begin(),
dest.end(),std::plus<double>());
 
V

Victor Bazarov

er said:
er said:
i'm trying to implement x*=y or x+=y; where x and y are containers
and *= and += are element wise i.e. x*=y is meant as
x[1]*=y[1],...,x[n]*=y[n] and likewise for +=;
i'm wondering if
a) there exists a function already defined for this purpose for the
types that i intend it for (see below)

You mean, like 'std::for_each'?
b) is there a way to make * or + a parameter so that i don't have to
write two (nearly identical) pieces of code for each (see below).

Probably. See 'std::plus' and 'std::multiplies'...
c) more generally, is there a better way to do this?

You mean, like using 'valarray', for example?

V

like this?
std::transform(vec.begin(), vec.end(), dest.begin(),
dest.end(),std::plus<double>());

Yes, probably. Does it work?

V
 
E

er

like this?
std::transform(vec.begin(), vec.end(), dest.begin(),
dest.end(),std::plus<double>());

i mean

std::transform(vec.begin(), vec.end(),
dest.begin(),dest.begin(),std::plus<double>())

definitely cleaner. thanks.
 
E

er

i mean

std::transform(vec.begin(), vec.end(),
dest.begin(),dest.begin(),std::plus<double>())

definitely cleaner. thanks.

another thought:

it definitely achieves x+=y but i'm wondering if it's quite in the
spirit of x+=y, and not instead x=x+y. i believe the 2nd
creates a temp object to store x?
 
V

Victor Bazarov

er said:
i mean

std::transform(vec.begin(), vec.end(),
dest.begin(),dest.begin(),std::plus<double>())

definitely cleaner. thanks.

another thought:

it definitely achieves x+=y but i'm wondering if it's quite in the
spirit of x+=y, and not instead x=x+y. i believe the 2nd
creates a temp object to store x?


I think you need to trust your compiler to be able to opimize the
expression

A = A + B

as if it were written

A += B

Basically, when in doubt, profile.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top