/**
 * Evaluate basic statistical parameters about a set of samples.
 * Histogram generation can also be enabled to display a very basic ASCII-art
 * histogram.
 * Usage: create the samples collector, then put the samples on it one by one.
 * Statistic data can be retrieved ad any moment by calling the getter methods.
 * 
 * @author Umberto Salsi <salsi@icosaedro.it>
 * @version $Date: 2017/08/27 13:17:20 $
 * @file
 */

#ifndef STATISTICS_H
#define STATISTICS_H

#ifdef statistics_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

typedef struct statistics_Type statistics_Type;

/**
 * Creates a new, empty samples collector. Can be released with memory_dispose().
 * @return Statistical samples collector.
 */
EXTERN statistics_Type * statistics_new(void);

/**
 * Add a sample to the set.
 * @param this Samples collector.
 * @param x Sample to add.
 */
EXTERN void statistics_put(statistics_Type *this, double x);

/**
 * Returns the number of samples accounted so far.
 * @param this Samples collector.
 * @return Number of sample accounted so far.
 */
EXTERN int statistics_count(statistics_Type *this);

/**
 * Minimum value accounted so far.
 * Fatal error if there are still no samples.
 * @param this Samples collector.
 * @return Minimum value accounted so far.
 */
EXTERN double statistics_min(statistics_Type *this);

/**
 * Maximum value accounted so far.
 * Fatal error if there are still no samples.
 * @param this Samples collector.
 * @return Maximum value accounted so far.
 */
EXTERN double statistics_max(statistics_Type *this);

/**
 * Mean value of the samples accounted so far.
 * Fatal error if there are less than two samples available.
 * @param this Samples collector.
 * @return Mean value of the samples accounted so far.
 */
EXTERN double statistics_mean(statistics_Type *this);

/**
 * Returns the mean squared deviation of the samples accounted so far.
 * Fatal error if there are less than two samples available.
 * @param this Samples collector.
 * @return Mean squared deviation of the samples accounted so far.
 */
EXTERN double statistics_variance(statistics_Type *this);

/**
 * Returns the standard deviation of the samples accounted so far.
 * It is the square root of the mean squared deviation.
 * Fatal error if there are less than two samples available.
 * @param this Samples collector.
 * @return Standard deviation of the samples accounted so far.
 */
EXTERN double statistics_deviation(statistics_Type *this);

/**
 * Returns a summary of the statistical parameters of the samples
 * accounted so far.
 * @param this Samples collector.
 * @return One-line message including number of samples,
 * min, max, mean and deviation (when available).
 */
EXTERN char * statistics_toString(statistics_Type *this);

/**
 * Enables histogram generation for the interval [min,max[ of values.
 * Fatal error if already enabled.
 * Fatal error if there are already samples in the set.
 * @param this Samples collector.
 * @param min Minimum value to display.
 * @param max Values equal or greater than this aren't displayed. Must be greater
 * than the minimum value.
 * @param number_of_intervals Number of intervals. Must be at least 1.
 */
EXTERN void statistics_histogramEnable(statistics_Type *this, double min, double max, int number_of_intervals);

/**
 * Returns the number of samples that fell in the range of the histogram.
 * This value can be less than the total number of samples submitted whenever
 * some sample fell outside histogram range.
 * Fatal error if histogram not enabled.
 * @param this Samples collector.
 * @return Number of samples that fell in the range of the histogram.
 */
EXTERN int statistics_histogramNumberOfSamples(statistics_Type *this);

/**
 * Returns the number of samples that fell in the i-th interval of the histogram.
 * Fatal error if histogram not enabled.
 * Fatal error if the index is out of the range [0,number_of_intervals[.
 * @param this Samples collector.
 * @param i Index of the interval.
 * @return Number of samples that fell in the i-th interval of the histogram.
 */
EXTERN int statistics_histogramBar(statistics_Type *this, int i);

/**
 * Displays the histogram on standard output.
 * Does nothing if histogram has not been enabled.
 * @param this Samples collector.
 * @param this
 */
EXTERN void statistics_histogramPrint(statistics_Type *this);

#undef EXTERN
#endif
