/************************************************************************
tstats.h -- template implementation of statistical calculation tools
with few exceptions, template stat functions use local long doubles for maximum
accuracy; therefore, all clases using TSTATS must have a valid (long double) cast
************************************************************************/
#include <math.h> //for powl() and sqrtl() functions

template <class T>
T maxof(const T data[], const unsigned n) {
    return data[indexofmax(data, n)];
}

template <class T>
unsigned indexofmax(const T data[], const unsigned n) {
    T max = data[0];
    unsigned index = 0;
    for (unsigned i = 1; i < n; i++) {
        if (max < data[i]) {
            max = data[i];
            index = i;
        }
    }
    return index;
}

template <class T>
long double average(const T data[], const unsigned n) {
    long double result, total = 0.0L;
    for (int i = 0; i < n; i++)
        total += (long double)data[i];
    if (n > 0) {
        result = total / (long double)n;
        return result;
    }
    else return -1.0L; //covers div by 0 error
}

template <class T>
T stdevs(const T data[], const unsigned n) {
    long double avg, result, sum = 0;
    avg = average(data, n);
    for (int i = 0; i < n; i++)
        sum += powl((long double)(data[i] - avg),2);
    if (n > 1) {
        result = sum/(long double)(n - 1); //n-1 for sample deviation
        result = sqrtl(result);
        return (T)result;
    }
    else return -1; //covers div by 0 error
}