Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function for calculating the mean of an array double[] using accumulate

It must be the most common function for what everyone has a code snippet somewhere, but I have actually spent no less than 1.5 hour searching for it on SO as well as on other C++ sites and have not found a solution.

I would like to calculate the mean of a double array[] using a function. I would like to pass the array to the function as a reference. There are millions of examples where the mean is calculated in a main() loop, but what I am looking for is a function what I can put in an external file and use it any time later.

So far, here is my latest version, what gives a compile error:

double mean_array( double array[] )
{
    int count = sizeof( array ) / sizeof( array[0] );
    double sum = accumulate( array, array + count, 0 );
    return ( double ) sum / count;
}

The compile error is:

error C3861: 'accumulate': identifier not found

Can you tell me how to fix this function? What does that compile error mean?

If I use std::accumulate (over the already defined using namespace std), then I get the following error:

'accumulate' : is not a member of 'std'
'accumulate': identifier not found

Why is 'accumulate' not a member of 'std'?

p.s.: I know I can do 'sum += array[i]' way and not use accumulate, but I would like to understand what is happening here and how can I make my example work.

like image 209
hyperknot Avatar asked Oct 26 '11 06:10

hyperknot


People also ask

What is accumulate function?

std::accumulate() is a built-in function in C++'s Standard Template Library. The function takes in a beginning iterator, an ending iterator, initial value, and (by default) computes the sum of the given initial value and the elements in the given range. The function can also​ be used for left folding.

How do you use an accumulate for an array in C++?

Using Accumulate MethodThe accumulate method in c++ used to find the array sum. This function can be accessed from the numeric library in c++.

What does accumulate function do in C++?

1) accumulate(): This function returns the sum of all the values lying in a range between [first, last) with the variable sum.

What is the syntax of the accumulate function?

accumulate()This iterator takes two arguments, iterable target and the function which would be followed at each iteration of value in target. If no function is passed, addition takes place by default. If the input iterable is empty, the output iterable will also be empty.


2 Answers

Try to add

#include <numeric>

It will bring in the 'std::accumulate' function you're looking for.

Going further, you're gonna have a problem to find out the number of elements in your array. Indeed, an array cannot be passed to a function in the hope that the function will be able to know the size of the array. It will decay to a pointer. Therefore, your count calculation will be wrong. If you want to be able to pass an actual size specified array, you have to use a templated function.

template <int N>
double mean_array( double ( & array )[N] )
{
    return std::accumulate( array, array + N, 0.0) / (double)(N);
}
like image 177
Didier Trosset Avatar answered Sep 19 '22 15:09

Didier Trosset


Its not quite the question you asked, but there is an easy bug to make in your code sample. The initial value in accumulate is templated, and in your code its templated to integers. If you pass it a set of doubles, these will be cast to integers and you will get the wrong answers. Having made this mistake before, I made myself a quick guarentee as follows:

  /** Check that not inputting integer type into accumulate
   *  This is considered an error in this program (where a double was expected
   *  @tparam InputIterator The iterator to accumulate
   *  @tparam T The type to accumulate - will fail if integer.
   *  @param first The first iterator to accumulate from.
   *  @param last the iterator to acculate to,
   *  @param init The initial value
   *  @return The accumulated value as evaluated by std::accumulate.
   */
  template<class InputIterator, class T>
  inline
  T
  accumulate_checked(InputIterator first, InputIterator last, T init )
  {
    return std::accumulate(first,last, init);
  }

  //Not implemented for integers (will not compile if called).
  template<class InputIterator>
  inline
  int
  accumulate_checked(InputIterator first, InputIterator last, int init );

Thought I would share it in case it is of interest.

Just for completeness, your function can look like:

double mean_array( double *array, size_t count )
{
    double sum = std::accumulate(array,array+count,0.0)
    return sum / count;
}

or to be extra careful

double mean_array( double *array, size_t count )
{
    double sum = accumulate_checked(array,array+count,0.0)
    return sum / count;
}

or better still the templated version from Didier Trosset

like image 28
Tom Avatar answered Sep 20 '22 15:09

Tom