/*!
\file
\brief Test of basic elements of the ARX class

See file \ref arx for mathematical background.

This class tests functions ARX::bayes (Bayes rule) ARX::structure_est and ARX::predictor_student

Untested functions: none.

 */

#include "estim/arx.h"
#include "../mat_checks.h"

using namespace bdm;

TEST ( arx_stress ) {
    // Setup model
    vec th ( "0.8 -0.3 0.4 0.01" );
    int ord = th.length(); //auxiliary variable
    double sqr = 0.1;

    //Test constructor
    mat V0 = 0.00001 * eye ( ord + 1 );
    V0 ( 0 ) = 1; //
    double nu0 = ord + 5.0;

    ARX Ar;
    Ar.set_statistics ( 1, V0, nu0 );               // Estimator
    Ar.set_constant ( false );
    Ar.validate();
    const epdf& f_thr = Ar.posterior();          // refrence to posterior of the estimator

    //Test estimation
    int ndat = 100;                 // number of data records
    vec Yt ( ndat );                // Store generated data
    Yt.set_subvector ( 0, randn ( ord ) ); //initial values
    vec rgr ( ord );                // regressor

    //print moments of the prior distribution
    cout << "prior mean: " << f_thr.mean() << endl;
    cout << "prior variance: " << f_thr.variance() << endl;

    // cycle over time:
    for ( int t = ord; t < ndat; t++ ) {
        //Generate regressor
        for ( int j = 0; j < ( ord ); j++ ) {
            rgr ( j ) = Yt ( t - j - 1 );
        }
        //model
        Yt ( t ) = th * rgr + sqr * NorRNG();

        Ar.bayes ( vec_1 ( Yt ( t ) ), rgr );       // Bayes rule

        // Build predictor
        mlstudent* 	Pr = Ar.predictor ( );
		estudent<ldmat>* 	PrS = Ar.epredictor_student (rgr );
		
		cout << "m1: " << Pr->_A()*rgr+Pr->_mu_const() << 
		" v1:" << Pr->e()._R();
		cout << "ms: " << PrS->mean() << " vs:" << PrS->variance()  << 
		" del:" << PrS->_delta() <<endl;
		
		// Test similarity of likelihoods from the Bayes rule and the predictor
        cout << "BR log-lik: " << Ar._ll();
		cout << " , predictor ll: " <<  Pr->evallogcond ( vec_1 ( Yt ( t ) ), rgr );
		cout << " , epredictor_student ll: " <<  PrS->evallog ( vec_1 ( Yt ( t ) ) )  << endl;
		delete Pr;
		delete PrS;
	}
    //print posterior moments
    cout << "posterior mean: " << f_thr.mean() << endl;
    cout << "posterior variance: " << f_thr.variance() << endl;

    // Test brute-froce structure estimation

    cout << "Structure estimation: " << endl;
    cout << Ar.structure_est ( egiw ( 1, V0, nu0 ) ) << endl;
}
