#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
using namespace std;
#endif
/////////////////////////////////////////////////////////////////////
/* Example : transport system paper ZeCury
Maia C.A., Hardouin L., Cury J.E.R.
"Some results on the feedback control of max-plus linear systems under state constrains",
Conference on Decision and Control, CDC 2013, Firenze.
*/
#include "..\src\gd.cpp"
#include "..\src\poly.cpp"
#include "..\src\serie.cpp"
#include "..\src\smatrix.cpp"
#include "..\src\tools.cpp"

/////////////////////////////////////////////////////////////////////


int main()
{
try
{
int i,j;
	smatrix A(2,2);	// matrice d'état

smatrix P(2,3);	// matrice de contrainte Gx + P= F x+ Q => Gx = Fx by expanding the state
smatrix Q(2,3);	//

  smatrix C(2,2);
  smatrix B(2,1);
poly p;
P(0,0)=gd(0,0);

P(0,2)=p.init(0,-3)(1,0);
P(1,0)=gd(0,1);
P(1,1)=gd(0,0);
P(1,2)=p.init(0,-3)(0,0);

Q(0,0)=gd(0,0);
//Q(0,2)=gd(0,0);
Q(1,1)=gd(0,0);
//Q(1,2)=gd(0,0);


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


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

	B(0,0)=gd(0,0);





   smatrix AStar=star(A);



cout<<"AStar"<<AStar; getchar();



smatrix AB=otimes(AStar,B);
cout <<"AB \n"<<AB<<endl;
getchar();
smatrix CAB=otimes(C,AB);
cout <<"CAB \n"<<CAB<<endl;
smatrix CA=otimes(C,AStar);
cout <<"CA \n"<<CA<<endl;
/*smatrix AdualEStarB=otimes(AdualEStar,B);
cout <<"AdualEStarB \n"<<AdualEStarB<<endl;getchar();

smatrix CAdualEStarB=otimes(C,AdualEStarB);
smatrix Gref=CAdualEStarB;
*/





smatrix test1,test2,x1,x2,x3,x4,x;
int n=0;
smatrix Z(2,1);
smatrix zeta;
poly pt;

pt.init(0,-1)(1,2)(2,infinity);


Z(0,0).init(epsilon, pt,e);
pt.init(0,3)(1,2)(2,infinity);
Z(1,0).init(epsilon, pt,e);


zeta=lfrac(Z,AB);
cout<<" zeta "<<zeta<<endl;

smatrix U(2,1);
U(0,0)=zeta(0,0);
U(1,0)=e;
cout<<" U "<<U<<endl;
smatrix ABex(3,2);
ABex(0,0)=AB(0,0);
ABex(1,0)=AB(1,0);
ABex(2,1)=e;

cout<<" P "<<P<<endl;
cout<<" ABex "<<ABex<<endl;

smatrix ABexU=otimes(ABex,U);
smatrix PAB,QAB;
PAB=otimes(P,ABex);
cout<<" PAB "<<PAB<<endl;
cout<<" Q "<<Q<<endl;
cout<<" ABex "<<ABex<<endl;
QAB=otimes(Q,ABex);
cout<<" Q "<<Q<<endl;
cout<<" QAB "<<QAB<<endl;
x4=U;
do
{
 x=x4;

 test1=otimes(PAB,x);
 test2=otimes(QAB,x);
 x1= lfrac(test1,PAB);
 x2= lfrac(test2,QAB);

 x2=inf(x2,x1);
 x3=prcaus(x);

 x4=inf(x3,x2);
  x4=prcaus(x);



 cout<<"n"<<++n<<endl;

 }
while((!(x==x4)) &&n<10);

if (n<10)
{
     cout<<" it is ok \n"<<endl;
}
else
{
     cout<<" it is Nok \n"<<endl;
}

U=x4;
cout <<"U"<<x4<<endl;getchar();
smatrix u(1,1);
u(0,0)=U(0,0);
cout<<"u "<<u<<endl;
smatrix xc=otimes(AB,u);
cout<<" xc "<<xc<<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);
 }
}

