#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
{
/////////////////////////////////////////////////////////////////////\\
// Backward Equations , Optimal control \\
/////////////////////////////////////////////////////////////////////

   smatrix   A(2,2); // state matrix 6x6
   smatrix   B(2,1); // input matrix 6x2, 2 inputs
   smatrix  C(1,2);  // output matrix 1x6, 1 output
   smatrix  H; // transfer matrix, the dimension will be defined automatically
   smatrix u_opt; // control law
   smatrix y_opt; // output when u_opt is applied
   smatrix z(1,1); // the desired output


    //state matrix declaration
    A(0,0)=gd(1 ,3); // 1 token and 0 time unit  between x_2 and x_1


    A(0,1)=gd(2 ,0); // 1 token and 0 time unit between x_4 a,d x_3
    A(1,0)=gd(0 ,1); // 0 token and 2 time units between x_1 and x_2
    A(1,1)=gd(1, 4);

    //Input and Output matrices
    B(0,0)=gd(0, 1);


    C(0,1)=gd(0 ,0);
smatrix At(2,2);
At(0,0)=gd(0,0);
At(1,1)=gd(0,0);
smatrix As2=A;
for(int i=0;i<10;i++)
{
    cout<<"At "<<i<<"\n"<<At<<endl;
    At=oplus(At,As2);
    As2=otimes(As2,A);
}

    smatrix As;
    smatrix CAs;
    As=star(A);
    CAs=otimes(C,As);
    H = otimes(CAs,B);
  cout<<"\n The A* matrix \n"<<As;
    cout<<"\n The model (transfer function) H \n"<<H;
    serie s1,s2,s3;
    gd r;
    poly p,q;
    p.init(0,0);
    q.init(4,3);
    r.init(5,3);
    s1.init(p,q,r);
    p.init(1,3);
    q.init(2,4);
    r.init(4,1);
    s2.init(p,q,r);

    s3=oplus(s1,s2);
    cout<<" s1 "<<s1<<endl;
    cout<<" s2 "<<s2<<endl;
    cout<<" s1 + s2 "<<s3<<endl;

s3=otimes(s1,s2);
cout<<" s1*s2 "<<s3<<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);
 }
}
