#include "../bdm/base/datasources.h"
#include "../bdm/base/loggers.h"
#include "../mat_checks.h"
#include "UnitTest++.h"

using namespace bdm;

TEST ( EpdfDS_test ) {
	UIFile uif ( "epdfds.cfg" );

	shared_ptr<EpdfDS> ds = UI::build<EpdfDS> ( uif, "ds" );

	vec mean = zeros ( 2 );
	vec dt = zeros ( 2 );
	for ( int i = 0; i < 100; i++ ) {
		ds->step();
		ds->getdata ( dt );
		mean += dt;
	}
	CHECK_CLOSE_EX ( vec_2 ( 1.0, 2.0 ) , mean / 100, 1e-2 );
}

TEST ( PdfDS_test ) {
	UIFile uif ( "pdfds.cfg" );

	shared_ptr<PdfDS> ds = UI::build<PdfDS> ( uif, "ds", UI::compulsory );

	vec dt = zeros ( 2 );
	vec ut = "1.0";
	ds->write ( ut );
	for ( int i = 0; i < 100; i++ ) {
		ds->step();
	}
	ds->getdata ( dt );
	CHECK_CLOSE ( -0.2 , dt ( 0 ), 1e-4 );

	ut = "2.0";
	ds->write ( ut );
	for ( int i = 0; i < 100; i++ ) {
		ds->step();
	}
	ds->getdata ( dt );
	CHECK_CLOSE ( -0.4 , dt ( 0 ), 1e-4 );
}

TEST ( StateDS_test ) {
	RV y ( "y", 1 );
	RV u ( "u", 1 );
	RV x ( "x", 2 );

	shared_ptr<mlnorm<fsqmat> > IM = new mlnorm<fsqmat>;
	IM->set_parameters ( mat ( "1 2 0.5; 0 1 0.3" ), zeros ( 2 ), fsqmat ( 1e-10*eye ( 2 ) ) );
	IM->set_rv ( x );
	IM->set_rvc ( concat ( x.copy_t ( -1 ), u ) );
	IM->validate();

	shared_ptr<mlnorm<fsqmat> > OM = new mlnorm<fsqmat>;
	OM->set_parameters ( mat ( "1 0" ), zeros ( 1 ), fsqmat ( 1e-10*eye ( 1 ) ) );
	OM->set_rv ( y );
	OM->set_rvc ( x );
	OM->validate();

	StateDS sds;
	sds.set_parameters ( IM, OM );
	sds.validate();

	for ( int t = 1; t < 10; t++ ) {
		sds.write ( vec_1 ( double ( t ) ) );
		sds.step();
	}

	vec dt;
	sds.getdata ( dt );
	CHECK_CLOSE ( vec ( "94.5, 94.5, 13.5, 9" ), dt, 1e-2 );
}
