#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
using namespace std;
#endif
/////////////////////////////////////////////////////////////////////
/* Example : Automatica 2001, to appear
           "Model reference control for timed event graphs in dioids"
// you must link with a library which contains all source files given in folder src
// gd.cpp poly.cpp serie.cpp smatrix.cpp tools.cpp interf.cpp
// or add these files in your project
// or alternatively you can include the folowing files
//
#include "..\src\gd.cpp"
#include "..\src\poly.cpp"
#include "..\src\serie.cpp"
#include "..\src\smatrix.cpp"
#include "..\src\tools.cpp"
	*/
/////////////////////////////////////////////////////////////////////


int main()
{
try
{

	smatrix A(3,3);	// matrice d'état

	smatrix H(1,2);

	smatrix CA(1,3);
    smatrix Gref(1,2), E(2,2);

	A(0,0)=gd(1,2);//(1,2)
	A(1,1)=gd(1,3);
	A(2,0)=gd(1,3);
	A(2,1)=gd(0,8);
	A(2,2)=gd(1,2);

	smatrix B(3,2),C(1,3);	// matrice entrée et sortie

	C(0,2)=gd(0,2);

	B(0,0)=e;	// x1=u1
	B(1,1)=e;	// x6=u2

	smatrix As=star(A);
	CA=otimes(C,As);  // CA*
    cout << "CA* :" << CA << endl;

	H=otimes(CA,B); // input/output transfer CA*B
	cout << "H :" << H << endl;


	serie s1;
	gd m;
	s1.init(epsilon,e,m.init(1,3));

    Gref(0,0)=otimes(H(0,0),s1);
	Gref(0,1)=otimes(H(0,1),s1);

    cout << "Gref :"  << Gref << endl;

	// Retour sortie sur l'état optimal Sr=(CA*)\Gref/H
	smatrix GrefdivCA=lfrac(Gref,CA);
	smatrix Sr(3,1);
	Sr=rfrac(GrefdivCA,H);
	cout <<"Feedback periodique Sr : "<<  Sr << endl;

	Sr=prcaus(Sr);
    cout <<"Feedback causal Sr : "<<  Sr << endl;
	// Systeme controlé par Gbf=((CA*Sr)*)H
	smatrix CASr=otimes(CA,Sr);
	CASr=star(CASr);
	smatrix Gbfsr(1,2);

	Gbfsr=otimes(CASr,H);

	cout <<"Systeme corrige : "<< Gbfsr << endl;
	return(0);
}

 catch(mem_limite l)
 {
	 cout<<"Exception : too many coefficent in polynom "<<l.memoire<<endl;
	 return(1);
 }

 catch(taille_incorrecte obj)
 { // 0 : r non causal
   // 1 : tentative d'accès à un element d'une matrice avec un indice incorrect
   // 2 : matrice de taille incompatible pour oplus, inf, otimes, rfrac, lfrac
   // 3 : etoile de matrice carré uniquement
	 cout<<"Exception  "<<obj.erreur<<endl;
	 return(1);
 }
}
