#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
using namespace std;
#endif
#include <time.h>



/////////////////////////////////////////////////////////////////////
/* Example : Discrete Event Systems in Dioid Framework : Control Theory
 Laurent Hardouin, Olivier Boutin, Bertrand Cottenceau, Thomas Brunsch, Joerg Raisch
 Springer, DISC Book
This program compute :
1. the optimal control when a reference output is a priori known
2. the optimal input filtering when the reference output is unknown
3. the optimal feedback
*/
#include "..\src\gd.cpp"
#include "..\src\polywithmymerge.cpp"
#include "..\src\serie.cpp"
#include "..\src\smatrix.cpp"
#include "..\src\tools.cpp"


using namespace std;

int main(void)
{
try{

smatrix a(10,10), as(10,10),b(10,4), c(1,10);
smatrix asb, casb;
poly p;


// the system, matrix a
a(1,0)=gd(0,110*24); // bordeaux time processing
a(0,1)=gd(25,0); // bordeaux simultaneous capacity

a(3,2)=gd(0,220*24); // seville time processing
a(2,3)=gd(32,0); // seville simultaneous capacity

a(5,4)=gd(0,100*24); // nantes time processing
a(4,5)=gd(18,0); // nantes simultaneous capacity

a(7,6)=gd(0,108*24); // Hambourg time processing
a(6,7)=gd(20,0); // Hambourg simultaneous capacity


a(8,1)=gd(0,6); // tranportation time from Bordeaux to Toulouse
a(8,3)=gd(0,32); // tranportation time from Seville to Toulouse
a(8,5)=gd(0,15); // tranportation time from Nantes to Toulouse
a(8,7)=gd(0,80); // tranportation time from Hambourg to Toulouse

a(9,8)=gd(0,60*24);
a(8,9)=gd(5,0);



// the system matrix b
b(0,0)=gd(0,0);
b(2,1)=gd(0,0);
b(4,2)=gd(0,0);
b(6,3)=gd(0,0);


// the system matrix c
c(0,9)=gd(0,0);
//c(0,1)=gd(0,0);
//c(0,3)=gd(0,0);
//c(0,5)=gd(0,0);
//c(0,7)=gd(0,0);

// the star of the matrix a
as= star(a);

asb = otimes(as,b); // transfer matrix between input and state vector
casb = otimes(c,asb); // trnasfer matrix between input and output
cout<<"Transfer of the system CA*B \n"<<casb<<endl;
smatrix Popt; //the optimal filter
smatrix Fopt; // the optima feedback

Popt=lfrac(casb,casb);
cout<<"Optimal Filter non causal\n P_opt \n"<<Popt<<endl;
Popt=prcaus(Popt);
cout<<"Optimal Filter causal\n P_opt \n"<<Popt<<endl;

Fopt=rfrac(Popt,Popt);
Fopt=rfrac(Fopt,casb);
cout<<"Optimal Feedback non Causal \n Fopt \n"<<Fopt<<"\n";
Fopt=prcaus(Fopt);
cout<<"Optimal Feedback non Causal \n Fopt \n"<<Fopt<<"\n";



//fstream f;

//  f.open("/home/brunsch/CAsB.txt",ios::out);
//f<<casb;
//f.close();

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