#ifndef MODEL_H
#define MODEL_H

#include <stat/libFN.h>

using namespace bdm;

//! Model stredni hodnoty vyvoje stavu pro k1 
class IMk1 : public diffbifn {
protected:
	double alp1, alp2; // pomery odboceni...

public:
	//! Constructor
	IMk1() :diffbifn () {dimy=4; dimx=3; dimu=1;}; 
	//! set CONSTANT parameters
	void set_parameters ( double alp10,  double alp20) {alp1=alp10; alp2=alp20;}

	vec eval ( const vec &x0, const vec &u0 ) {
		// napln stav nulami
		vec xk=zeros ( dimy );

		xk ( 0 ) = 0.2* x0(1) - 0.1* x0(2)+ u0(0);  // vycucane z prstu
		xk ( 1 ) = x0(0); 
		xk ( 2 ) = x0(1);
		xk ( 3 ) = x0(2);

		return xk;
	}

	void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
		// Vysledek se uklada do matice A

		if (full) { // priznak full se nastavi na zacatku => je treba naplnit celou matici
			A = eye(dimy);
			A(0,1) = 0.2;
			A(0,2) = -0.1;
		} else {
		}; // pokud neni priznak full, staci naplnit jen to co se zmenilo. V tomhle pripade se nemeni nic
	}

	void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {it_error ( "not needed" );};

};

//! model stredni hodnoty pozorovani pro k1
class OMk1 : public diffbifn {
public:
	//! Constructor
	OMk1() :diffbifn ( ) {dimy=2;dimx=3;dimu=2;}; //<======= TODO 
	// Model pozorovani  je trivialni jen se zkopiruji stavy
	vec eval(const vec &x0, const vec &u0 ){
		vec dt(dimy);
		// Pozoruji pouze prvni dva stavy
		dt(0) = x0(0);
		dt(1) = x0(1); 
		return dt;
	}
	//
	void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
		// Vysledek se uklada do matice A

		if (full) { // priznak full se nastavi na zacatku => je treba naplnit celou matici
			A = zeros(dimy,dimx);
			A(0,0)=1.0;
			A(1,1)=1.0;
		} else {}; // pokud neni priznak full, staci naplnit jen to co se zmenilo. V tomhle pripade se nemeni nic
	}
};

#endif //MODEL_H
