[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Is there an STL algo to fill a vector with product of 2 other vectors?

Steve555

12/9/2008 2:44:00 PM

Hi

I'm looking for an algorithm that takes 2 vectors and a function
pointer as arguments?
I want to use the function pointer to calculate a result e.g. the
product, and put the result either in place, or in a third vector.

I've looked through the list of algorithms and there doesn't appear to
be one.
transform() is the closest, but alas works on only a single vector.

Thanks

Steve

(I know I could write the whole thing from scratch, but I'm trying to
get in to the habit of using STL where possible)
19 Answers

Victor Bazarov

12/9/2008 3:05:00 PM

0

Steve555 wrote:
> I'm looking for an algorithm that takes 2 vectors and a function
> pointer as arguments?
> I want to use the function pointer to calculate a result e.g. the
> product, and put the result either in place, or in a third vector.
>
> I've looked through the list of algorithms and there doesn't appear to
> be one.
> transform() is the closest, but alas works on only a single vector.
>
> Thanks
>
> Steve
>
> (I know I could write the whole thing from scratch, but I'm trying to
> get in to the habit of using STL where possible)

I suspect it's possible to write in a couple of statements if you
convert your vectors to valarrays (and back).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Pete Becker

12/9/2008 3:28:00 PM

0

On 2008-12-09 09:43:51 -0500, Steve555 <foursheds@btinternet.com> said:

>
> I've looked through the list of algorithms and there doesn't appear to
> be one.
> transform() is the closest, but alas works on only a single vector.

There are two versions of transform. One works on a single input range
and the other works on two input ranges. The latter sounds like just
what you need.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Steve555

12/9/2008 3:56:00 PM

0

On 9 Dec, 15:27, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-12-09 09:43:51 -0500, Steve555 <foursh...@btinternet.com> said:
>
>
>
> > I've looked through the list of algorithms and there doesn't appear to
> > be one.
> > transform() is the closest, but alas works on only a single vector.
>
> There are two versions of transform. One works on a single input range
> and the other works on two input ranges. The latter sounds like just
> what you need.
>
> --
>   Pete
> Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
> Standard C++ Library Extensions: a Tutorial and Reference
> (www.petebecker.com/tr1book)

Thanks Pete, hadn't spotted the second version.
I have a simple example working with multiplies<int>()
, but what about an arbitrary functor, how do I declare the arguments?
e.g: (where in1, in2, out, are my 3 vectors)

void pointlessCalc(in1, in2, out)
{
out = (in1 + 1) * (in2 +2);
}

Steve


jason.cipriani@gmail.com

12/9/2008 4:34:00 PM

0

On Dec 9, 10:55 am, Steve555 <foursh...@btinternet.com> wrote:
> On 9 Dec, 15:27, Pete Becker <p...@versatilecoding.com> wrote:
>
>
>
> > On 2008-12-09 09:43:51 -0500, Steve555 <foursh...@btinternet.com> said:
>
> > > I've looked through the list of algorithms and there doesn't appear to
> > > be one.
> > > transform() is the closest, but alas works on only a single vector.
>
> > There are two versions of transform. One works on a single input range
> > and the other works on two input ranges. The latter sounds like just
> > what you need.
>
> > --
> >   Pete
> > Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
> > Standard C++ Library Extensions: a Tutorial and Reference
> > (www.petebecker.com/tr1book)
>
> Thanks Pete, hadn't spotted the second version.
> I have a simple example working with multiplies<int>()
> , but what about an arbitrary functor, how do I declare the arguments?
> e.g: (where in1, in2, out, are my 3 vectors)

See:

http://www.sgi.com/tech/stl/tran...

Specifically, your functor must follow this:

http://www.sgi.com/tech/stl/BinaryFun...

For example:

template <typename T> bool equals (const T &a, const T &b) {
return a == b;
}

void somewhere () {

std::vector<int> x, y;
x.push_back(1);
x.push_back(2);
y.push_back(2);
y.push_back(2);

std::vector<bool> result(x.size());
std::transform(x.begin(), x.end(), y.begin(), result.begin(),
equals<int>);

assert(result[0] == false);
assert(result[1] == true);

}


> void pointlessCalc(in1, in2, out)
> {
>    out = (in1 + 1) * (in2 +2);
>
> }

You'd want to return the value:

out pointlessCalc (in1, in2);


Jason

James Kanze

12/9/2008 5:10:00 PM

0

On Dec 9, 3:43 pm, Steve555 <foursh...@btinternet.com> wrote:

> I'm looking for an algorithm that takes 2 vectors and a
> function pointer as arguments? I want to use the function
> pointer to calculate a result e.g. the product, and put the
> result either in place, or in a third vector.

> I've looked through the list of algorithms and there doesn't
> appear to be one. transform() is the closest, but alas works
> on only a single vector.

There are two versions of std::transform. The following code
should do the trick:
assert( v1.size() == v2.size() ) ;
std::transform( v1.begin(), v1.end(),
v2.begin(),
std::back_inserter( v3 ),
std::multiplies< double >() ) ;

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Steve555

12/9/2008 6:23:00 PM

0

On 9 Dec, 16:34, "jason.cipri...@gmail.com" <jason.cipri...@gmail.com>
wrote:
> On Dec 9, 10:55 am, Steve555 <foursh...@btinternet.com> wrote:
>
>
>
> > On 9 Dec, 15:27, Pete Becker <p...@versatilecoding.com> wrote:
>
> > > On 2008-12-09 09:43:51 -0500, Steve555 <foursh...@btinternet.com> said:
>
> > > > I've looked through the list of algorithms and there doesn't appear to
> > > > be one.
> > > > transform() is the closest, but alas works on only a single vector.
>
> > > There are two versions of transform. One works on a single input range
> > > and the other works on two input ranges. The latter sounds like just
> > > what you need.
>
> > > --
> > >   Pete
> > > Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
> > > Standard C++ Library Extensions: a Tutorial and Reference
> > > (www.petebecker.com/tr1book)
>
> > Thanks Pete, hadn't spotted the second version.
> > I have a simple example working with multiplies<int>()
> > , but what about an arbitrary functor, how do I declare the arguments?
> > e.g: (where in1, in2, out, are my 3 vectors)
>
> See:
>
> http://www.sgi.com/tech/stl/tran...
>
> Specifically, your functor must follow this:
>
> http://www.sgi.com/tech/stl/BinaryFun...
>
> For example:
>
> template <typename T> bool equals (const T &a, const T &b) {
>         return a == b;
>
> }
>
> void somewhere () {
>
>         std::vector<int> x, y;
>         x.push_back(1);
>         x.push_back(2);
>         y.push_back(2);
>         y.push_back(2);
>
>         std::vector<bool> result(x.size());
>         std::transform(x.begin(), x.end(), y.begin(), result.begin(),
> equals<int>);
>
>         assert(result[0] == false);
>         assert(result[1] == true);
>
> }
> > void pointlessCalc(in1, in2, out)
> > {
> >    out = (in1 + 1) * (in2 +2);
>
> > }
>
> You'd want to return the value:
>
> out pointlessCalc (in1, in2);
>
> Jason

Thanks for the example Jason, I wasn't sure whether it was expecting
values, or iterators in to the containers.

Steve555

12/9/2008 6:54:00 PM

0

On 9 Dec, 17:09, James Kanze <james.ka...@gmail.com> wrote:
> On Dec 9, 3:43 pm, Steve555 <foursh...@btinternet.com> wrote:
>
> > I'm looking for an algorithm that takes 2 vectors and a
> > function pointer as arguments?  I want to use the function
> > pointer to calculate a result e.g. the product, and put the
> > result either in place, or in a third vector.
> > I've looked through the list of algorithms and there doesn't
> > appear to be one.  transform() is the closest, but alas works
> > on only a single vector.
>
> There are two versions of std::transform.  The following code
> should do the trick:
>     assert( v1.size() == v2.size() ) ;
>     std::transform( v1.begin(), v1.end(),
>                     v2.begin(),
>                     std::back_inserter( v3 ),
>                     std::multiplies< double >() ) ;
>
> --
> James Kanze (GABI Software)             email:james.ka...@gmail.com
> Conseils en informatique orientée objet/
>                    Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Thanks James, but I wasn't sure why you used std::back_inserter()?

red floyd

12/9/2008 8:36:00 PM

0

Steve555 wrote:
> On 9 Dec, 17:09, James Kanze <james.ka...@gmail.com> wrote:
>> On Dec 9, 3:43 pm, Steve555 <foursh...@btinternet.com> wrote:
>>
>>> I'm looking for an algorithm that takes 2 vectors and a
>>> function pointer as arguments? I want to use the function
>>> pointer to calculate a result e.g. the product, and put the
>>> result either in place, or in a third vector.
>>> I've looked through the list of algorithms and there doesn't
>>> appear to be one. transform() is the closest, but alas works
>>> on only a single vector.
>> There are two versions of std::transform. The following code
>> should do the trick:
>> assert( v1.size() == v2.size() ) ;
>> std::transform( v1.begin(), v1.end(),
>> v2.begin(),
>> std::back_inserter( v3 ),
>> std::multiplies< double >() ) ;
>>
>> --
>> James Kanze (GABI Software) email:james.ka...@gmail.com
>> Conseils en informatique orientée objet/
>> Beratung in objektorientierter Datenverarbeitung
>> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
>
> Thanks James, but I wasn't sure why you used std::back_inserter()?

because that will push_back() the results onto the v3. Otherwise, you
risk running off the end of the resultant, especially if it's empty.

Steve555

12/9/2008 10:28:00 PM

0

On 9 Dec, 20:35, red floyd <no.spam.h...@example.com> wrote:
> Steve555 wrote:
> > On 9 Dec, 17:09, James Kanze <james.ka...@gmail.com> wrote:
> >> On Dec 9, 3:43 pm, Steve555 <foursh...@btinternet.com> wrote:
>
> >>> I'm looking for an algorithm that takes 2 vectors and a
> >>> function pointer as arguments?  I want to use the function
> >>> pointer to calculate a result e.g. the product, and put the
> >>> result either in place, or in a third vector.
> >>> I've looked through the list of algorithms and there doesn't
> >>> appear to be one.  transform() is the closest, but alas works
> >>> on only a single vector.
> >> There are two versions of std::transform.  The following code
> >> should do the trick:
> >>     assert( v1.size() == v2.size() ) ;
> >>     std::transform( v1.begin(), v1.end(),
> >>                     v2.begin(),
> >>                     std::back_inserter( v3 ),
> >>                     std::multiplies< double >() ) ;
>
> >> --
> >> James Kanze (GABI Software)             email:james.ka...@gmail.com
> >> Conseils en informatique orientée objet/
> >>                    Beratung in objektorientierter Datenverarbeitung
> >> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
>
> > Thanks James, but I wasn't sure why you used std::back_inserter()?
>
> because that will push_back() the results onto the v3.  Otherwise, you
> risk running off the end of the resultant, especially if it's empty.

Thanks Red, but, Doh! This is bad news! I thought the whole point of
using these smart containers was that they grew to accomodate whatever
was put in to them?
When I use this (and other?) algorithms, they might write in to
unallocated memory if I don't tell them not to?
When designing this algorithm, how could it have been seen as a good
idea for it to default to a behavior that would not allocate the
correct memory? If you supply an iterator to a new vector to store the
transform of other vectors, what else could you possibly intend?

(OK, it's not so much trouble to add it, but it does seem like adding
the redundant instruction DontCrash() ;) )

Steve

Kai-Uwe Bux

12/9/2008 11:13:00 PM

0

Steve555 wrote:

> On 9 Dec, 20:35, red floyd <no.spam.h...@example.com> wrote:
>> Steve555 wrote:
>> > On 9 Dec, 17:09, James Kanze <james.ka...@gmail.com> wrote:
>> >> On Dec 9, 3:43 pm, Steve555 <foursh...@btinternet.com> wrote:
>>
>> >>> I'm looking for an algorithm that takes 2 vectors and a
>> >>> function pointer as arguments?  I want to use the function
>> >>> pointer to calculate a result e.g. the product, and put the
>> >>> result either in place, or in a third vector.
>> >>> I've looked through the list of algorithms and there doesn't
>> >>> appear to be one.  transform() is the closest, but alas works
>> >>> on only a single vector.
>> >> There are two versions of std::transform.  The following code
>> >> should do the trick:
>> >> assert( v1.size() == v2.size() ) ;
>> >> std::transform( v1.begin(), v1.end(),
>> >> v2.begin(),
>> >> std::back_inserter( v3 ),
>> >> std::multiplies< double >() ) ;
>>
>> >> --
>> >> James Kanze (GABI Software)             email:james.ka...@gmail.com
>> >> Conseils en informatique orientée objet/
>> >> Beratung in objektorientierter Datenverarbeitung
>> >> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
>>
>> > Thanks James, but I wasn't sure why you used std::back_inserter()?
>>
>> because that will push_back() the results onto the v3.  Otherwise, you
>> risk running off the end of the resultant, especially if it's empty.
>
> Thanks Red, but, Doh! This is bad news! I thought the whole point of
> using these smart containers was that they grew to accomodate whatever
> was put in to them?

They do, but you have to actually _put_ an item into them. That is what
push_back(), push_front(), and insert() do. Note that operator[] will _not_
put an item into the container.

> When I use this (and other?) algorithms, they might write in to
> unallocated memory if I don't tell them not to?

Yes, you have to tell them.

> When designing this algorithm, how could it have been seen as a good
> idea for it to default to a behavior that would not allocate the
> correct memory?

You are confused. The algorithm does not even know about the container. The
algorithm only sees the iterators. In the case of an output_iterator, the
file will grow as you write items; in the case of an insert_iterator, the
container will grow; in the case of a vector<T>::iterator, the container
will _not_ grow.

> If you supply an iterator to a new vector to store the
> transform of other vectors, what else could you possibly intend?

How is the algorithm supposed to know that the vector is _new_? All it sees
is a vector<T>::iterator and that means the intend is to overwrite existing
elements.

> (OK, it's not so much trouble to add it, but it does seem like adding
> the redundant instruction DontCrash() ;) )

No.

BTW: You could write a drop in replacement for std::vector<> that makes the
vector grow when iterators move past the end. However, that has an
overhead.


Best

Kai-Uwe Bux