I'm debating code efficiency vs. convenience. I'm writing a general header file to help me if I ever need to use certain functions again. The one I'm working on right now deals with statistics, here's my code:
#ifndef STATS_H
#define STATS_H
#include <cmath>
double Mean ( double array[], int size ){
double sum = 0;
int i;
for ( i = 0; i < size; i++ ){
sum += array[i];
}
return ( sum / size );
}
double Std_Dev ( double array[], int size, double mean ){
double sum = 0;
int i;
for ( i = 0; i < size; i++ ){
sum += pow( ( mean - array[i] ), 2);
}
return sqrt( ( sum / ( size - 1) ) );
}
#endif
I'm debating whether I should add an extra field to pass mean along or just have the standard deviation function always run mean. On one hand you never have to worry about anything but those two arguments possibly for the stats functions and on the other you don't have a function running (possibly) unnecessarily every time you call another function.
There's no "or", the answer is "and". Have an overload that allows the caller to provide the mean if it has already been calculated before and have the normal version calculate the mean itself.
Edit: If these are in a header, you also need to declare these function as static inline or better yet, make them template functions. That way it will work for all array types. And instead of passing a pointer + size, it would be more appropriate for the function to accept a pair of iterators.
Okay, I'm still a little on the noob side. I think when I thought about the trade off I thought that I should just make it only have one function because it would make it simpler to remember but that's stupid. I'll just overload it like you said.
Anyways, it is part of a header file. I'm not exactly sure how declaring it as static inline or as template functions would work. Also how would the iterator work? As I said, I'm still young coding-wise but I'm learning fast.
EDIT: Okay, I've just read how a template function would work and I can see it's benefits. I was wondering how I could make it much simpler to pass the array ( I was frustrated that int array wouldn't convert to double nicely ). I'll have to read about static inline next, but I'd still appreciate any comments you have for me.
Duoas, a little explanation would be nice I don't quite understand how that code works.
Edit: I can see that you were giving an example of how to use a template but I don't quite understand how your example actually works, so I could still use some explanation.
I just read the Templates part of the websites tutorials and think I can set it up reasonably well but if yours works better that would be cool.
It is a template function -- the compiler fills in the type for ArgNumber (which in my example is int) and the size of the array for Size.
It's a trick, nothing more. Your function is actually more efficient, since the template function generates an entire function for every different Size.
You can fix this with some careful template programming, but ATM I'm not so sure it is worth your time to get turned by this (admittedly cool) diversion. You can fix that by simply having the template function inline to a call to the C-style function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Here is the actual function, which is generated for all types
// ArgNumber+ResultNumber with an argument array of any length:
template <typename ArgNumber, typename ResultNumber>
ResultNumber Mean( const ArgNumber* xs, size_t Size ) {
...
}
// And here is our magical, vanishing fancy way to call the function
// (so that we don't have to supply the second argument to the above
// function ourselves if we can avoid it):
template <typename ArgNumber, typename ResultNumber, size_t Size>
inline
ResultNumber Mean( const ArgNumber* xs[ Size ] ) {
return Mean( xs, Size );
}