divide all elements in a vector by a number

U

utab

Dear all,

I was wondering if I could divide all elements of a vector by the max
element of that vector.

I checked the STL references and found transform, for_each and lately
BOOST_FOREACH, but transform and for_each algorithms are not suited
since I have another argument to supply to the functions, namely
max_element. I wondered if this is possible or not through the
standard.

BOOST_FOREACH seemed the best option to me. But I wondered :)

Rgds,
 
V

Victor Bazarov

utab said:
Dear all,

I was wondering if I could divide all elements of a vector by the max
element of that vector.

I checked the STL references and found transform, for_each and lately
BOOST_FOREACH, but transform and for_each algorithms are not suited
since I have another argument to supply to the functions, namely
max_element. I wondered if this is possible or not through the
standard.

BOOST_FOREACH seemed the best option to me. But I wondered :)

Everybody is supposed to do their own homework.

V
 
J

Juha Nieminen

utab said:
I was wondering if I could divide all elements of a vector by the max
element of that vector.

Is it really that hard to write a simple for-loop? It will probably be
easier to read than the STL acrobatics needed to do the same thing.
Probably shorter too.
 
D

David Harmon

On Thu, 15 Nov 2007 08:35:52 -0800 (PST) in comp.lang.c++, utab
Dear all,

I was wondering if I could divide all elements of a vector by the max
element of that vector.

I checked the STL references and found transform, for_each and lately
BOOST_FOREACH, but transform and for_each algorithms are not suited
since I have another argument to supply to the functions,

You are halfway there, now check the "bind" family, for example
std::bind2nd or the powerful boost::bind versions.

Something along the lines of (unchecked!)

std::transform(v.begin(), v.end(), v.begin(),
std::bind2nd(std::divides<double>,
std::max_element(v.begin(), v.end()));
 
D

Daniel T.

utab said:
I was wondering if I could divide all elements of a vector by the max
element of that vector.

I checked the STL references and found transform, for_each and lately
BOOST_FOREACH, but transform and for_each algorithms are not suited
since I have another argument to supply to the functions, namely
max_element. I wondered if this is possible or not through the
standard.

First find the max element of the vector (hint: there is an algorithm
for that.) Then transform each element by dividing it by that number.

For extra credit: With the proper use of functors, the whole thing can
be done in one line of code.

Make a stab at it and post it with this same subject. I'd love to see if
you can come up with it, and will help you out if you can at least get
close. :)
 
U

utab

Everybody is supposed to do their own homework.

V

Oops, you are not right since I did not paste any code :)

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void print(double d)
{
cout << " " << d << endl;
}

int main()
{
vector<double> x;
for(double i=0;i!=10;++i)
x.push_back(i);

double max=*max_element(x.begin(),x.end());

cout << max << endl;

vector<double>::iterator iterx=x.begin();
for(;iterx!=x.end();++iterx)
{
if(fabs(max)>1e-6){ // just a pre-caution for divide by 0.
*iterx=*iterx/max;
}
}
for_each(x.begin(),x.end(),print);

return 0;
}

That was the question, without a loop, is this possible?
I could not find the answer in my references,
I made the example quickly, hope it is error free!
Rgds,
 
U

utab

On Thu, 15 Nov 2007 08:35:52 -0800 (PST) in comp.lang.c++, utab




You are halfway there, now check the "bind" family, for example
std::bind2nd or the powerful boost::bind versions.

Something along the lines of (unchecked!)

std::transform(v.begin(), v.end(), v.begin(),
std::bind2nd(std::divides<double>,
std::max_element(v.begin(), v.end()));

bind,
thank you for the input.
 
U

utab

Is it really that hard to write a simple for-loop? It will probably be
easier to read than the STL acrobatics needed to do the same thing.
Probably shorter too.

Just curious, you are right in your reasoning,
Rgds.
 
U

utab

For extra credit: With the proper use of functors, the whole thing can
be done in one line of code.

Make a stab at it and post it with this same subject. I'd love to see if
you can come up with it, and will help you out if you can at least get
close. :)

One line of code, I am really interested and will certainly give that
a try, thanks for the guidance

Rgds
 
V

Victor Bazarov

utab said:
Everybody is supposed to do their own homework.

V

Oops, you are not right since I did not paste any code :)

[..code..]

That was the question, without a loop, is this possible?

Yes, but you'd have to use recursion. As to whether it's possible
using 'transform', 'bind', 'divides', etc., you have your reply, but
keep in mind there is always a loop whether *you* write it or it is
written *for you* in the library routine.
I could not find the answer in my references,
I made the example quickly, hope it is error free!

I didn't check it. But I'd probably moved the 'if(fabs(max)))' out
of the loop and changed the 'max' to something else (since there
are functions named 'max' in 'std').

V
 
F

Fei Liu

Daniel said:
First find the max element of the vector (hint: there is an algorithm
for that.) Then transform each element by dividing it by that number.

For extra credit: With the proper use of functors, the whole thing can
be done in one line of code.

Make a stab at it and post it with this same subject. I'd love to see if
you can come up with it, and will help you out if you can at least get
close. :)

Although there are mulitple ways of doing this in one line as an
academic exercise, I think performance and readiability wise, a 2 liner
is better for practical purposes. I don't doubt your intention but let's
not send out the wrong signal. :)

To the OP, do look up boost::lambda, suppose you already have the
maximum value in max_r, there is a succinct way to express your
algorithm through transform:

std::transform(from.begin(), from.end(), to.begin(), _1/max_r);

You can do in place transformation:
std::transform(from.begin(), from.end(), from.begin(), _1/max_r);

Fei
 
U

utab

Oops, you are not right since I did not paste any code :)
[..code..]

That was the question, without a loop, is this possible?

Yes, but you'd have to use recursion. As to whether it's possible
using 'transform', 'bind', 'divides', etc., you have your reply, but
keep in mind there is always a loop whether *you* write it or it is
written *for you* in the library routine.
I could not find the answer in my references,
I made the example quickly, hope it is error free!

I didn't check it. But I'd probably moved the 'if(fabs(max)))' out
of the loop and changed the 'max' to something else (since there
are functions named 'max' in 'std').

V

Thank you all for the replies and guidance
 
U

utab

On Thu, 15 Nov 2007 08:35:52 -0800 (PST) in comp.lang.c++, utab




You are halfway there, now check the "bind" family, for example
std::bind2nd or the powerful boost::bind versions.

Something along the lines of (unchecked!)

std::transform(v.begin(), v.end(), v.begin(),
std::bind2nd(std::divides<double>,
std::max_element(v.begin(), v.end()));

The correct form should be, after some reading in the directions you
provided,

transform(x.begin(), x.end(), x.begin(),
std::bind2nd(std::divides<double>(),*max_element(x.begin(),
x.end())));

I have once more appreciated the full power of STL.

These tricks are very nice :), thank you

Best regards,
 
J

Joel Yliluoma

Dear all,

I was wondering if I could divide all elements of a vector by the max
element of that vector.

In addition to the answers you have already received, you could
consider using std::valarray. It is specifically designed for
doing mathematical operations to a mass of items at the same
time. Who knows, maybe it has also parallel or vectorization
optimizations in it for modern platforms.
 
J

Joel Yliluoma

Dear all,

I was wondering if I could divide all elements of a vector by the max
element of that vector.

In addition to the answers you have already received, you could
consider using std::valarray. It is specifically designed for
doing mathematical operations to a mass of items at the same
time. Who knows, maybe it has also parallel or vectorization
optimizations in it for modern platforms.

Example:
std::valarray<int> tmp;
...
tmp /= tmp.max();
 
J

James Kanze

[...]
Although there are mulitple ways of doing this in one line as an
academic exercise, I think performance and readiability wise, a 2 liner
is better for practical purposes. I don't doubt your intention but let's
not send out the wrong signal. :)

I think by "one line", he really meant one C++ statement. I've
never managed to get even the simplest call to std::transform on
a single line, while still keeping a reasonable line length.
(If humans are to read the code, something about 60 characters,
not counting indentation, is about the limit. You can exceed it
occassionally, but 80 characters is a good absolute limit.)

David Harmon's suggestion is only one C++ statement, is very
readable, and probably results in the best performance you're
likely to get.
 
U

utab

In addition to the answers you have already received, you could
consider using std::valarray. It is specifically designed for
doing mathematical operations to a mass of items at the same
time. Who knows, maybe it has also parallel or vectorization
optimizations in it for modern platforms.

Example:
std::valarray<int> tmp;
...
tmp /= tmp.max();

I see this is also a nice suggestion since my concern for using C++ is
mainly on number crunching.

Rgds,
 
K

Kai-Uwe Bux

James said:
Daniel said:
I was wondering if I could divide all elements of a vector by the max
element of that vector.
[...]
Although there are mulitple ways of doing this in one line as an
academic exercise, I think performance and readiability wise, a 2 liner
is better for practical purposes. I don't doubt your intention but let's
not send out the wrong signal. :)

I think by "one line", he really meant one C++ statement. I've
never managed to get even the simplest call to std::transform on
a single line, while still keeping a reasonable line length.
(If humans are to read the code, something about 60 characters,
not counting indentation, is about the limit. You can exceed it
occassionally, but 80 characters is a good absolute limit.)

David Harmon's suggestion is only one C++ statement, is very
readable, and probably results in the best performance you're
likely to get.

I must be missing something here. The one-command versions (and also the
2-command ones) that I can see are either not readable or not correct (at
least they have undefined behavior when the vector is empty or when the
maximum element is 0).


Best

Kai-Uwe Bux
 
D

Daniel T.

Kai-Uwe Bux said:
I must be missing something here. The one-command versions (and also the
2-command ones) that I can see are either not readable or not correct (at
least they have undefined behavior when the vector is empty or when the
maximum element is 0).

Well, the one David harman posted was what I was thinking about. I grant
that it would have undefined behavior if the maximum element is 0
(however, isn't 0/0 well defined?) but it would work fine if the array
is empty.

I would probably preface it with an assert to make sure that such isn't
the case.
 
V

Victor Bazarov

Daniel said:
[..] isn't 0/0 well defined?[..]

Most definitely not. Is it 1 (since the numerator and the denominator
are the same)? Is it 0 (since the numerator is 0)? Is it division by
zero (since the denominator is 0)?

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top