
#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{

// System Matrices
 smatrix a(5,5), Y0(5,5), b(5,2), c(2,5), Y0b(5,2), cY0(2,5), h(2,2);
smatrix abis(5,5);
smatrix em(5,5);
 int i,j;



 for (i=0;i<5;i++) em(i,i)=e;


a(0,0) = gd(1,2);
a(0,1) = gd(1,1);
a(0,2) = gd(3,0);
a(0,3) = gd(3,2);
a(0,4) = gd(3,0);

a(1,0) = gd(3,1);
a(1,1) = gd(1,1);
a(1,2) = gd(2,1);
a(1,3) = gd(1,0);
a(1,4) = gd(3,2);

a(2,2) = gd(1,0);
a(2,3) = gd(1,0);
a(2,4) = gd(1,2);

a(3,2) = gd(2,1);
a(3,3) = gd(3,1);
a(3,4) = gd(3,2);

a(4,2) = gd(1,0);
a(4,3) = gd(2,2);
a(4,4) = gd(2,0);

b(3,1) = gd(1,1);
b(4,0) = gd(2,0);

c(0,1) = gd(1,1);
c(1,3) = gd(2,0);

// Calculation of the transfer function matrix

Y0 = star(a);
smatrix A=otimes(Y0,Y0);
if (Y0==A) cout<<"Star OK"<<endl;
else {

    cout<<"Wrong Star"<<endl;

    for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
    {

    if(!(A(i,j)==Y0(i,j))) cout<<"i,j"<<i<<j<<endl;

    }

    }
}
/*smatrix ai,astop;
smatrix stop(5,5);
serie s;
smatrix abistop;
poly p,q;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
    { s.init(p.init(0,35),q.init(0,35),e);
      stop(i,j)=s;
    }
}
abis=oplus(em,a);
i=0;
astop=e;
do
{   astop=abistop;
    ai=otimes(abis,a);
    abis=oplus(em,ai);

    abistop=inf(abis,stop);




    i++;
    cout<<"i : "<<i<<endl;

}while(!(astop==abistop));
getchar();
abis=abistop;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
    { Y0=inf(Y0,stop);
            if(!(abis(i,j)==Y0(i,j)))
            {
                cout<<"i,j"<<i<<","<<j<<"\n abis"<<abis(i,j)<<"\n Y0"<<Y0(i,j)<<endl;
                getchar();
            }
    }
}

*/
Y0=star(a);

Y0b = otimes(Y0,b);
cY0 = otimes(c,Y0);
h = otimes(cY0,Y0b);



// Calculation of the first iteration
smatrix X1(5,5), Y1(5,5), temp(5,2), h1(2,2);
smatrix g;
h1=otimes(cY0,b);
if (!(h1==h) ) cout<<"pb"<<endl;
cout<<"h1"<<h1<<endl;
cout<<"h"<<h<<endl;

h1=h;
do{
    h=h1;
/////First step calculation of X1
//temp =lfrac(h,cY0);
temp=rfrac(h,Y0b);
//if(temp==oplus(temp,cY0)) cout<<"CA*B/A*B >CA*"<<endl;;
//X1 = rfrac(temp,Y0b);
X1=lfrac(temp,cY0);
//if(X1==oplus(Y0,X1)) cout<<"X1 >A*"<<endl;;
//cout<<"X1"<<X1<<endl;
//cout<<"Y0b"<<Y0b<<endl;
//if(X1==oplus(Y0,X1)) cout<<"X1>A*"<<endl;;
///// Second step: calculation of Y1
Y1 = rfrac(X1,X1);
//if(otimes(Y1,X1)==X1) cout <<"18ok"<<endl;
g=otimes(X1,b);
h1=otimes(c,g);


if (Y1==otimes(Y1,Y1)) cout<<"Star OK"<<endl;
else cout<<"Wrong Star"<<endl;

temp = otimes(Y1,b);
h1 = otimes(c,temp);

if(h1 == h){cout<<" Y1 et Y0 leads to the same transfer function \n";}
else {cout<<" Y1 et Y0 leads to two different transfer functions: WRONG \n";}

}
while (!(h1 == h));
cout<<"h1"<<h1<<endl;
cout<<"h"<<h<<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);
 }
}
