#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); 	
}