/** @file evaluation.h
 *
 *	Declaration of evaluation module interface.
 *
 *	Evaluation module performs evaluation of statistics such as:
 *	- chi square test
 *	- log likelihood ratio
 *	- mutual information
 *	- pearsons coefficient
 *	- t test
 *	- z score
 *
 *	The only required input is table of *-frequencies of given N-gram.
 *
 *	Statistics evaluation requires calculation of contigency table and expected
 *	*-frequencies table, which are therefore also available.
 *
 *	(C) Ceslav Przywara 2008, MFF UK Prague
 *
 */

#ifndef _EVALUATION_H
#define _EVALUATION_H

// We work with N-grams here.
#include "ngrams.h"

namespace ace {

// Forward declaration (class declares some friend functions).
class EvaluationTables;

/** Namespace wraps evaluation functions.
 */
namespace eval {
	/** @return Chi square statistics for given eval. tables.
	 */
	double chi_square_test(const EvaluationTables& tables);
	/** @return Log likelihood ratio statistics for given eval. tables.
	 */
	double log_likelihood_ratio(const EvaluationTables& tables);
	/** @return Mutual information statistics for given eval. tables.
	 */
	double mutual_information(const EvaluationTables& tables);
	/** @return Pearson's coefficient statistics for given eval. tables.
	 */
	double pearsons_coefficient(const EvaluationTables& tables);
	/** @return T test statistics for given eval. tables.
	 */
	double t_test(const EvaluationTables& tables);
	/** @return Z score statistics for given eval. tables.
	 */
	double z_score(const EvaluationTables& tables);

} // namespace eval
	
/** Container acts like table of expected frequencies (which are floating point numbers).
 */
typedef std::vector<double> exp_table_t;

/** Class evaluates contigency and expected frequency tables.
 */
class EvaluationTables {
	/** Container for information used for contingency table evaluation.
	 */
	static std::vector<std::vector<size_t> > _bits_for_cont_table;
	/** Container for information used for inv. frequency table evaluation.
	 */
	static std::vector<std::vector<size_t> > _bits_for_inv_table;

	/** Frequency table (is passed from outside, so shall be const).
	 *	f(A,*,C) [101]
	 */
	const freq_table_t _freq;
	/** Contigency table.
	 *	f(A,!B,C) [101]
	 */
	freq_table_t _cont;
	/** Inverted frequency table.
	 *	f(*,!B,*) [101]
	 */
	freq_table_t _inv;
	/** Expected frequency table.
	 */
	exp_table_t _exp;

public:
	/** Constructor expects *-frequencies table.
	 *	@param frequencies Table with *-frequencies of certain N-gram.
	 */
	EvaluationTables(const freq_table_t frequencies);
	/** Performs start-up (static) initialization. Must be called before any
	 *	EvaluationTables object is initialized.
	 */
	static void init(void);
	/** @return *-frequency table.
	 */
	inline const freq_table_t& frequency(void) const { return _freq; }
	/** @return Contigency table.
	 */
	inline const freq_table_t& contigency(void) const { return _cont; }
	/** @return Inverted *-frequency table.
	 */
	inline const freq_table_t& inverted_frequency(void) const { return _inv; }
	/** @return Expected *-frequency table.
	 */
	inline const exp_table_t& expected_frequency(void) const { return _exp; }
	/** @return Size of frequency table (which is equal to size of any table).
	 */
	inline size_t size(void) const { return _freq.size(); }

	/**
	 */
	friend double eval::chi_square_test(const EvaluationTables& tables);
	/**
	 */
	friend double eval::log_likelihood_ratio(const EvaluationTables& tables);
	/**
	 */
	friend double eval::mutual_information(const EvaluationTables& tables);
	/**
	 */
	friend double eval::pearsons_coefficient(const EvaluationTables& tables);
	/**
	 */
	friend double eval::t_test(const EvaluationTables& tables);
	/**
	 */
	friend double eval::z_score(const EvaluationTables& tables);
};

} // namespace ace

#endif
