#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
using namespace std;
#endif
/////////////////////////////////////////////////////////////////////
/* Example : Observer basesd controller and comparison with output feedbnack
 Example taken from paper
[2] "Observer-based Controllers for (Max-Plus)-Linear Systems"
Laurent Hardouin, Ying Shang, Carlos Andrey Maia, Bertrand Cottenceau
(IEEE TAC, 2010)
// see also animation on http://perso-laris.univ-angers.fr/~hardouin/Observer.html
// 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, it is the most friendly to do
*/
#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(2,2);	// matrice d'état

	smatrix Lopt,L1,L2,Loptcausal;
	int i,j;

	smatrix CA,AB,CAB,AR,CAR;
	smatrix Gref;
	smatrix Popt, Fopt,Kopt;


	A(0,1)=gd(0,6);//(g^1,d^4)

	smatrix C(1,2);	// output matrix only coefficient on diagonl equal to e or epsilon

    C(0,0)=gd(0,0);
//    C(1,1)=gd(0,7);

    smatrix B(2,1);	// matrice entrée et sortie, epsilon everywhere
	B(0,0)=gd(0,2);
	B(1,0)=gd(0,4);


	smatrix R(2,2);
	R(0,0)=gd(0,0);
	R(1,1)=gd(0,0);

	smatrix As=star(A);

cout<<" As"<<As<<endl;
	CA=otimes(C,As);  // CA*

    AB=otimes(As,B);

cout<<" AB"<<AB<<endl;

    CAB=otimes(C,AB);

cout<<" CAB"<<CAB<<endl;

    AR=otimes(As,R);


cout<<" AR"<<AR<<endl;
    CAR=otimes(C,AR);


cout<<" CAR"<<CAR<<endl;

	L1=rfrac(AB,CAB);
	L2=rfrac(AR,CAR);

cout<<" AB rfrac CAB "<<L1<<endl;

cout<<" AR rfrac CAR "<<L2<<endl;

	Lopt=inf(L1,L2);

cout<<"Lopt noncausal : " <<Lopt<<endl;


smatrix LCAB=otimes(Lopt,CAB);

cout<<"L1CAB : " <<LCAB<<endl;

smatrix LCAR=otimes(Lopt,CAR);

cout<<"LCAR : " <<LCAR<<endl;

	Loptcausal=prcaus(Lopt); // L_opt


cout<<"Lopt causal : " <<Loptcausal<<endl;


smatrix LCABc=otimes(Loptcausal,CAB);

cout<<"LCAB causal : " <<LCABc<<endl;

smatrix LCARc=otimes(Loptcausal,CAR);

smatrix LCARcc=otimes(C,LCARc) ;
cout<<"LCAR causal : " <<LCARcc<<endl;




	return(0);
}

 catch(mem_limite l)
 {
	 cout<<"Exception : too many coefficents 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ée uniquement
	 cout<<"Exception  "<<obj.erreur<<endl;
	 return(1);
 }
}
