/*!
\file
\brief Application Estimator

The general task of estimation is defined on the following scheme:
\dot
digraph estimation{
	node [shape=box];
	{rank="same"; "Data Source"; "Bayesian Model"}
	"Data Source" -> "Bayesian Model" [label="data"];
	"Bayesian Model" -> "Result Logger" [label="estimated\n statistics"]; 
	"Data Source" -> "Result Logger" [label="Simulated\n data"];
}
\enddot

Here, 
\li Data Source is an object (class DS) providing sequential data, \f$ [d_1, d_2, \ldots d_t] \f$.
\li Bayesian Model is an object (class BM) performing Bayesian filtering,
\li Result Logger is an object (class logger) dedicated to storing important data from the experiment.

\section  cmd Command-line usage
Execute command:
\code
$> estimator config_file.cfg
\endcode

Full description of the experiment is in the file config_file.cfg which is expected to have the following structure:
\code
system = {type = "DS_offspring", ...};      // definition of a data source
estimator = {type = "BM_offspring", ...};   // definition of an estimator
logger = {type = "logger_type",...};        // definition of a logger
experiment = {ndat = 11000; };              // definition of number of data records
\endcode

The above description must be specialized to specific classes. See, \subpage arx_ui how to do it for estimation of an ARX model.

\section ex Matlab usage
Execute command:
\code
>> estimator('config_file.cfg');
\endcode
when using loggers storing results on hard drives, and
\code
>> Res=estimator('config_file.cfg');
\endcode
when using logger of the type \c "mex_logger". The results will be stored in structure \c M.

 */

#include <stat/datasources.h>
#include <estim/arx.h>
#include <user_info.h>
#include <stat/loggers.h>

using namespace bdm;
int main ( int argc, char* argv[] ) {
	const char *fname;
	if ( argc>1 ) {
		fname = argv[1];
	}
	else {
		cout << "Missing configuration file.\n Usage: \n $> estimator config_file.cfg";
		//abort();
	}
	fname = "arx_test.cfg";
	UIFile F ( fname );

	logger* L = UI::build<logger>( F, "logger");
	ArxDS * DS = UI::build<ArxDS>( F, "system" );
	BM* E = UI::build<BM>( F, "estimator" );
	int Ndat = F.lookupValue ( "experiment.ndat",Ndat );

	DS->log_add ( *L );
	int L_est= L->add ( E->posterior()._rv(), "est" ); // estimate
	int L_lb = L->add ( E->posterior()._rv(), "lb" ); // lower bound
	int L_ub = L->add ( E->posterior()._rv(), "ub" ); // upper bound
	L->init();

	vec dt=zeros ( DS->_drv()._dsize() );   //data variable
	datalink dl ( E->_drv(),DS->_drv() ); //datalink between a datasource and estimator

	for ( int tK=1;tK<Ndat;tK++ ) {
		DS->step();							// simulator step
		DS->getdata ( dt );					// read data
		E->bayes ( dl.pushdown ( dt ) );		// update estimates

		DS->logit ( *L );
		L->logit ( L_est, E->posterior().mean() );
		L->logit ( L_lb,  E->posterior().mean()-2*sqrt ( E->posterior().variance() ) );
		L->logit ( L_ub,  E->posterior().mean() +2*sqrt ( E->posterior().variance() ) );

		L->step();
	}

	L->finalize();

	delete L;
	delete DS;
	delete E;
	return 0;
}

