#ifndef _WIN32
#include "../include/lminmaxgd.h"
#else
#include "..\include\lminmaxgd.h"
using namespace std;
#endif
/////////////////////////////////////////////////////////////////////
/* Example : transport avec ZeCury
*/
#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(4,4);	// matrice d'état
int t1=0,t2=10,t3=7;
int g1=5,r1=5,g2=4,r2=7;
int T2=17;
int G1=10, G2=10;
 smatrix E(4,4);
  smatrix D(4,4);
  smatrix C(1,4);
  smatrix B(4,4);


	A(0,2)=gd(1,r1);//
	A(1,0)=gd(0,t2);
	A(1,3)=gd(1,r2);
	A(2,0)=gd(0,g1);
	A(3,1)=gd(0,g2);


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


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

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

  E(0,1)=gd(0,-T2);
  E(0,2)=gd(0,-G1);
  E(1,3)=gd(0,-G2);
  D(0,0)=e;
  D(1,1)=e;
  D(2,2)=e;
  D(3,3)=e;
   smatrix AStar=star(A);
   smatrix EStar=star(E);


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




smatrix P;

P=lfrac(AB,AB);
smatrix Eigenmatrix(4,4);
poly p,q;
gd r;
r.init(1,11);
q.init(0,0);
Eigenmatrix(0,0).init(p,q,r);
Eigenmatrix(1,1).init(p,q,r);
Eigenmatrix(2,2).init(p,q,r);
Eigenmatrix(3,3).init(p,q,r);
P=otimes(AB,Eigenmatrix);


smatrix test1,test2,x1,x2,x3,x4,x;
int n=0;
smatrix EAB,DAB,EABP,DABP;
EAB=otimes(E,AB);
DAB=otimes(D,AB);

x4=P;
cout <<"P"<<P<<endl;getchar();
do
{
    P=x4;
EABP=otimes(EAB,P);
DABP=otimes(DAB,P);
cout<<"DABP"<<DABP<<endl;
x1=lfrac(EABP,DAB);
x2=lfrac(DABP,EAB);

 x3=inf(x1,x2);
 x4=inf(x3,P);


 x4=prcaus(x4);






 cout<<"n"<<++n<<endl;
 cout<<"x1"<<x1<<endl;
 cout<<"x2"<<x2<<endl;
 cout<<"x4"<<x4<<endl;

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

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


cout <<"P"<<P<<endl;getchar();



// on verifie que (A+BF)*BP=E*A*BP


    smatrix ABP=otimes(AB,P);
    smatrix CABP=otimes(C,ABP);

    cout<<"ABP"<<ABP<<endl;


    smatrix test3=otimes(E,ABP);
    smatrix test4=otimes(D,ABP);
    if (test3==test4)
        cout<<" P est causal et ABP in im E \n P= \n"<<P<<endl;
        else cout<<" NOK  P est non causal et ABP in im  E* "<<endl;


    getchar();
    smatrix F;
    F=lfrac(CABP,CABP);
    F=rfrac(F,ABP);
    F=prcaus(F);
    cout <<"F \n"<<F<<endl;

cout <<"F \n"<<F<<endl; getchar();
    smatrix BP=otimes(B,P);
    smatrix BPF=otimes(BP,F);
    smatrix ABF=oplus(A,BPF);

    smatrix ABFS=star(ABF);
    smatrix CABFS=otimes(C,ABFS);
    smatrix CABFSBP=otimes(CABFS,BP);
    smatrix ABFSBP=otimes(ABFS,BP);
    if(ABFSBP==ABP)
    cout<<"F est causal "<<F<<endl;
    getchar();
    getchar();

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