
#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
#endif

/**************************************************************************************/
/* this example present the main function of the library
   and the different manner to declare monomial polynom serie and matrix */
/**************************************************************************************/
using namespace std;
#include "..\src\gd.cpp"
#include "..\src\poly.cpp"
#include "..\src\serie.cpp"
#include "..\src\smatrix.cpp"
#include "..\src\tools.cpp"
int main(void)
{
try{


//This example is from the link http://www.istia.univ-angers.fr/~hardouin/GET_incertain.html
//by adding disturbance signals and only consider the black token, i.e. the lower bound case

// System Matrices
 smatrix A(5,5),B(5,1), C(1,5);
smatrix Astar;
smatrix M(5,5),MT(5,5),N,Nstar;
smatrix U0(1,1);
smatrix Un(1,1);
smatrix Un1(1,1);
smatrix Uopt(1,1);
smatrix H,G;
smatrix AB;

 int i,j;




// defining A=A_bar= A * \gamma in CDC11 paper
    A(0,1)=gd(1,0);
    A(1,0)=gd(0,5);
    A(1,1)=e;
    A(2,0)=gd(0,2);
    A(2,2)=e;
    A(2,3)=gd(2,0);
    A(3,2)=gd(0,4);
    A(3,3)=gd(0,0);

    A(4,1)=gd(0,0);
    A(4,3)=gd(0,0);
    A(4,4)=gd(0,0);
    cout << "A :" << A<< endl;

    //defining B matrix

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

    cout << "B :" << B<< endl;

    //defining C matrix
    C(0,4)=gd(0,0);
    cout << "C :" << C<< endl;

    // defining M matrix
    M(0,0)=gd(0,0);
    M(0,1)=gd(0,0);
    M(1,0)=gd(0,0);
    M(1,1)=gd(0,0);
    M(2,0)=gd(0,0);
    M(2,2)=gd(0,0);
    M(2,3)=gd(-1,0);
    M(3,2)=gd(1,0);
    M(3,3)=gd(0,0);
    M(4,1)=gd(1,0);
    M(4,3)=gd(0,0);
    M(4,4)=gd(0,0);
    // defining -MT matrix


    MT(0,0)=gd(0,0);
    MT(1,0)=gd(0,0);
    MT(0,1)=gd(0,0);
    MT(1,1)=gd(0,0);
    MT(0,2)=gd(0,0);
    MT(2,2)=gd(0,0);
    MT(3,2)=gd(1,0);
    MT(2,3)=gd(-1,0);
    MT(3,3)=gd(0,0);
    MT(1,4)=gd(-1,0);
    MT(3,4)=gd(0,0);
    MT(4,4)=gd(0,0);

    N=oplus(M,MT);
    Nstar=star(N);



    cout << "MT :" << MT   << endl;


// Calculation of the transfer function matrix

Astar = star(A);

cout<<"Astar\n"<<Astar<<endl;

AB=otimes(Astar,B);

H=otimes(Nstar,AB);
G=AB;
// defintion of an inital point
gd m;
U0(0,0).init(e,m.init(5,infinity),e);


Un=U0;
smatrix temp;

int Step=0;
temp=otimes(H,Un);
Un=lfrac(temp,G);
Un=inf(Un,U0);
Un1=Un;
do
{   Un=Un1;
    temp=otimes(G,Un);
    Un1=lfrac(temp,H);
    temp=otimes(H,Un1);
    Un1=lfrac(temp,G);
    Step++;
}
while(!(Un==Un1)&&Step<10);


if(Un==Un1)
{
     cout<<"control obtained"<<endl;
     cout<<Un<<endl;
}
else
{
     cout<<"control not obtained"<<endl;
     cout<<Un1<<endl;

}

}

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

}
