Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > computing average value

Reply
Thread Tools

computing average value

 
 
Raider
Guest
Posts: n/a
 
      02-26-2006
I'm trying to get average value. My first attempt is:

#include <...>

template <typename T>
struct avg : public unary_function<T, void>
{
T sum, count;
avg() : sum(0), count(0) {}
void operator()(T value) { sum+=value; ++count; }
T result() { return sum / count; }
};

int main()
{
const int N = 4;
double arr[N] = { 1, 2, 3, 4 };
avg<double> res = std::for_each(arr, arr+N, avg<double>());
std::cout << "avg=" << res.result() << std::endl;
}

Questions are:
1. Is for_each a right way? May be I should use accumulate or
something?
2. ": public unary_function<T, void>" is not nessesary. Should I use it
anyway?

Raider

 
Reply With Quote
 
 
 
 
Ivan Vecerina
Guest
Posts: n/a
 
      02-26-2006
"Raider" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
: I'm trying to get average value. My first attempt is:
:
: #include <...>
:
: template <typename T>
: struct avg : public unary_function<T, void>
: {
: T sum, count;
: avg() : sum(0), count(0) {}
: void operator()(T value) { sum+=value; ++count; }
: T result() { return sum / count; }
: };
:
: int main()
: {
: const int N = 4;
: double arr[N] = { 1, 2, 3, 4 };
: avg<double> res = std::for_each(arr, arr+N, avg<double>());
: std::cout << "avg=" << res.result() << std::endl;
: }
:
: Questions are:
: 1. Is for_each a right way? May be I should use accumulate or
: something?

I have to say that my first instinct would be to use (in main):
double avg = std::accumulate( arr, arr+N, 0 ) / N;
Only if the item count is unknown would you need a special class.

I think that a problem with for_each is that you have no
guarantee that the algorithm won't create copies of the
provided function object.
So std::accumulate would be safer. You could eventually use
a custom predicate, and an accumulation value of type
std:air<double,unsigned> -- sum and count -- or similar.

: 2. ": public unary_function<T, void>" is not nessesary.
: Should I use it anyway?
It is probably a good habit to take, as it will be useful for
some more advanced generic programming techniques.


hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <> http://www.brainbench.com


 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      02-26-2006
Ivan Vecerina wrote:

> "Raider" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) oups.com...
> : I'm trying to get average value. My first attempt is:
> :
> : #include <...>
> :
> : template <typename T>
> : struct avg : public unary_function<T, void>
> : {
> : T sum, count;
> : avg() : sum(0), count(0) {}
> : void operator()(T value) { sum+=value; ++count; }
> : T result() { return sum / count; }
> : };
> :
> : int main()
> : {
> : const int N = 4;
> : double arr[N] = { 1, 2, 3, 4 };
> : avg<double> res = std::for_each(arr, arr+N, avg<double>());
> : std::cout << "avg=" << res.result() << std::endl;
> : }
> :
> : Questions are:
> : 1. Is for_each a right way? May be I should use accumulate or
> : something?
>
> I have to say that my first instinct would be to use (in main):
> double avg = std::accumulate( arr, arr+N, 0 ) / N;
> Only if the item count is unknown would you need a special class.
>
> I think that a problem with for_each is that you have no
> guarantee that the algorithm won't create copies of the
> provided function object.


My understanding of the standard is that this guarantee actually is made:

[25.1.1]

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
Effects: Applies f to the result of dereferencing every iterator in the
range [first, last), starting from first and proceeding to
last - 1.
Returns: f.
Complexity: Applies f exactly last - first times.
Notes: If f returns a result, the result is ignored.

As I read this paragraph, "f" denotes the function object passed. The only
copy that is made is in passing the object by value. Other than that, you
should be safe. Besides:

(a) If copies were to be made, the return of f would not make sense. This
hook is provided to pass back information that the function object may
collect during its pass over the objects in the sequence.

(b) If this is *not* the intended meaning of the standard, that should
qualify as a bug in the standard.


[snip]


Best

Kai-Uwe Bux
 
Reply With Quote
 
Ivan Vecerina
Guest
Posts: n/a
 
      02-26-2006
"Kai-Uwe Bux" <(E-Mail Removed)> wrote in message
news:dtscim$rus$(E-Mail Removed)...
: Ivan Vecerina wrote:
....
: > I think that a problem with for_each is that you have no
: > guarantee that the algorithm won't create copies of the
: > provided function object.
:
: My understanding of the standard is that this guarantee actually is
made:
:
: [25.1.1]
:
: template<class InputIterator, class Function>
: Function for_each(InputIterator first, InputIterator last, Function f);
: Effects: Applies f to the result of dereferencing every iterator in the
: range [first, last), starting from first and proceeding to
: last - 1.
: Returns: f.
: Complexity: Applies f exactly last - first times.
: Notes: If f returns a result, the result is ignored.
:
: As I read this paragraph, "f" denotes the function object passed. The
only
: copy that is made is in passing the object by value. Other than that,
you
: should be safe.

Right -- I'm afraid that I confused for_each with other algorithms.
for_each
is actually the one that provides the most guarantees regarding side
effects
and order of execution. See for example the following discussion:
http://www.angelikalanger.com/Articl...Transform.html


Thank you for the correction,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      02-26-2006
In article <(E-Mail Removed) .com>,
"Raider" <(E-Mail Removed)> wrote:

> I'm trying to get average value. My first attempt is:
>
> #include <...>
>
> template <typename T>
> struct avg : public unary_function<T, void>
> {
> T sum, count;


'sum' above probably shouldn't be of type T

> avg() : sum(0), count(0) {}
> void operator()(T value) { sum+=value; ++count; }
> T result() { return sum / count; }
> };
>
> int main()
> {
> const int N = 4;
> double arr[N] = { 1, 2, 3, 4 };
> avg<double> res = std::for_each(arr, arr+N, avg<double>());
> std::cout << "avg=" << res.result() << std::endl;
> }
>
> Questions are:
> 1. Is for_each a right way? May be I should use accumulate or
> something?


Although for_each works, I'd be inclined to use accumulate. What you are
doing is accumulating the total of the items and the number of items,
then doing a divide on them...

template < typename T >
pair<T, int> avg_accum( const std:air<T, int>& prev, T next )
{
return make_pair( prev.first + next, prev.second + 1 );
}

pair< double, int > p = accumulate( arr, arr + N, make_pair( 0.0, 0 ),
&avg_accum<double> );
cout << "avg2 = " << (p.first/p.second) << '\n';


Of course in your particular case, you already know the number of items
so you could just use the specialized form of accumulate, but the above
will even work for input iterators, whereas the specialized form would
not.


> 2. ": public unary_function<T, void>" is not nessesary. Should I use it
> anyway?


I think it's good to be in the habit of using them, it communicates
intent, and is useful for functor composition.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
 
Reply With Quote
 
Raider
Guest
Posts: n/a
 
      02-27-2006
> 'sum' above probably shouldn't be of type T

I think it must be as follows:

typename T sum;
int count;

And thanks for the rest feedback!

Raider

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Optical Computing: special issue - Natural Computing, Springer optical supercomputing C Programming 0 01-16-2009 12:18 PM
Optical Computing: special issue - Natural Computing, Springer optical supercomputing C Programming 0 12-19-2008 12:22 PM
Computing average of time deltas Peter Szinek Ruby 1 03-19-2007 01:53 PM
Razer Tarantula Gaming Keyboard Review at XYZ Computing at XYZ Computing Silverstrand Front Page News 0 11-01-2006 05:13 PM
MS Excel question - AVERAGE() but excluding zero-value entries Steve Freides Computer Support 9 10-29-2006 03:29 AM



Advertisments