Best way to boost::array<T,n> a,b; a += b;

S

Steven T. Hatton

What's a good STL way of performing compound assignments using the elements
of one STL-like collection as the rhs and the correspondingly indexed
elements of another collection as the lhs? IOW:

template<typename T, size_t Size_S>
boost::array<T,Size_S>& operator+=(boost::array<T,Size_S>& lhs
, const boost::array<T, Size_S>& rhs) {
for(size_t i = 0; i < Size_S; i++) { lhs += rhs; }
return lhs;
}


--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
S

Steven T. Hatton

Steven said:
What's a good STL way of performing compound assignments using the
elements of one STL-like collection as the rhs and the correspondingly
indexed
elements of another collection as the lhs? IOW:

template<typename T, size_t Size_S>
boost::array<T,Size_S>& operator+=(boost::array<T,Size_S>& lhs
, const boost::array<T, Size_S>& rhs) {
for(size_t i = 0; i < Size_S; i++) { lhs += rhs; }
return lhs;
}


This is what I came up with. Is there a better way? Are there any
advantages or disadvantages to either of the forms I've presented?

using boost::array;

template<typename T, size_t Size_S>
array<T,Size_S>& operator+=(array<T,Size_S>& lhs, const array<T, Size_S>&
rhs)
{
std::transform(lhs.begin(), lhs.end()
, rhs.begin()
, lhs.begin()
, std::plus<T>());
return lhs;
}

int main(){
array<double, 4> a = {1,2,3,4};
array<double, 4> b = {5,6,7,8};
a+=b;
copy(a.begin(),a.end(),std::eek:stream_iterator<double>(std::cout," "));
std::cout << std::endl;
}

--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
T

Tom Widmer

What's a good STL way of performing compound assignments using the elements
of one STL-like collection as the rhs and the correspondingly indexed
elements of another collection as the lhs? IOW:

template<typename T, size_t Size_S>
boost::array<T,Size_S>& operator+=(boost::array<T,Size_S>& lhs
, const boost::array<T, Size_S>& rhs) {
for(size_t i = 0; i < Size_S; i++) { lhs += rhs; }
return lhs;
}


Well, std::transform works fine, but if you are performing maths on
vectors you should really use a linear algebra library, such as boost
uBLAS or valarray, both of which support this via operator+. The
former (and some implementations of the latter) uses expression
templates to delay evaluation of temporary expressions until required,
allowing loop fusion and other optimizations.

Tom
 
S

Steven T. Hatton

Tom said:
What's a good STL way of performing compound assignments using the
elements of one STL-like collection as the rhs and the correspondingly
indexed
elements of another collection as the lhs? IOW:

template<typename T, size_t Size_S>
boost::array<T,Size_S>& operator+=(boost::array<T,Size_S>& lhs
, const boost::array<T, Size_S>& rhs) {
for(size_t i = 0; i < Size_S; i++) { lhs += rhs; }
return lhs;
}


Well, std::transform works fine, but if you are performing maths on
vectors you should really use a linear algebra library, such as boost
uBLAS or valarray, both of which support this via operator+. The
former (and some implementations of the latter) uses expression
templates to delay evaluation of temporary expressions until required,
allowing loop fusion and other optimizations.

Tom


Thanks. I haven't looked at the boost uBLAS. Perhaps I'll go visit that
presently. I didn't like the design of some of the boost math offerings
because of the heavy reliance on macros. But maybe I need to learn to
accept such things.

I wrote some of my own template classes which perform operations such as dot
product matrix multiplication, etc., using template metaprogramming and
compiletime recursion. The seem to work quite well.

I'm actually converting what I was doing with boost::array<> to
std::valarray<>. I find valarray hard to work with. There are a few
features I wish it had that really detract from its appeal. Cumulative
boolean operators such as std::valarray<>::and() which would work similarly
to sum() and render the truth value of (v[0] && v[1],...,v[n-1]). As it
stands, determining the equality of two valarray instances is not a
straightforward proposition. A generalize inner product would be nice. We
could then do things such as inner_product(va,vb, and, equal) to obtain the
result I'm wanting from the comparison of two valarrays.

Nicolai Josuttis doesn't have a lot of praise to heap on the standard
specification of valarray. I wonder what could or should be done to
improve it.
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
S

Steven T. Hatton

Steven said:
Tom said:
What's a good STL way of performing compound assignments using the
elements of one STL-like collection as the rhs and the correspondingly
indexed
elements of another collection as the lhs? IOW:

template<typename T, size_t Size_S>
boost::array<T,Size_S>& operator+=(boost::array<T,Size_S>& lhs
, const boost::array<T, Size_S>& rhs)
{
for(size_t i = 0; i < Size_S; i++) { lhs += rhs; }
return lhs;
}


Well, std::transform works fine, but if you are performing maths on
vectors you should really use a linear algebra library, such as boost
uBLAS or valarray, both of which support this via operator+. The
former (and some implementations of the latter) uses expression
templates to delay evaluation of temporary expressions until required,
allowing loop fusion and other optimizations.

Tom


Thanks. I haven't looked at the boost uBLAS. Perhaps I'll go visit that
presently. I didn't like the design of some of the boost math offerings
because of the heavy reliance on macros. But maybe I need to learn to
accept such things.

I wrote some of my own template classes which perform operations such as
dot product matrix multiplication, etc., using template metaprogramming
and
compiletime recursion. The seem to work quite well.

I'm actually converting what I was doing with boost::array<> to
std::valarray<>. I find valarray hard to work with. There are a few
features I wish it had that really detract from its appeal. Cumulative
boolean operators such as std::valarray<>::and() which would work
similarly to sum() and render the truth value of (v[0] &&
v[1],...,v[n-1]). As it stands, determining the equality of two valarray
instances is not a
straightforward proposition. A generalize inner product would be nice.
We could then do things such as inner_product(va,vb, and, equal) to obtain
the result I'm wanting from the comparison of two valarrays.

Nicolai Josuttis doesn't have a lot of praise to heap on the standard
specification of valarray. I wonder what could or should be done to
improve it.


And the size should be part of the type. Valarray size is practically
immutable anyway, since resizing also reinitializes.
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top