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

#endif

#include <time.h>
using namespace std;
#include <iostream>
#include <time.h>
#include "ominus.cpp"
#include "expandorigin.cpp"
//#include "..\src\gd.cpp"
//#include "..\src\poly.cpp"
//#include "..\src\serie.cpp"
//#include "..\src\smatrix.cpp"
//#include "..\src\tools.cpp"
#include "gd.cpp"
#include "poly.cpp"
#include "serie.cpp"
#include "smatrix.cpp"
#include "tools.cpp"



double inline min(double a,double b)
{
		if(a>b) return b;
		else return a;
}

poly rresid( serie s, long T){
poly temp;
gd m, cr;
int crossi=1000;
int crossj=1000;

for (int i=0; i<s.getp().getn(); i++)
{
    m = s.getp().getpol(i);
    if(m.getd()<= T)
    {
        temp = oplus(temp,m);
    }

       if(m.getd() > T)
    {
        crossi= min(i,crossi);
     //   std::cout << " crossi:" << std::endl << crossi<< std::endl;
    }
    if(crossi < 1000)
     {
     cr (s.getp().getpol(crossi).getg(),infinity);
         temp = oplus(temp,cr);
     }
}

for (int j=0; j<=s.getq().getn(); j++)
{
    m = s.getq().getpol(j);
    if(m.getd()<= T)
    {
    temp = oplus(temp,m);
    }
       if(m.getd() > T)
    {
        crossj= min(j,crossj);
  //      std::cout << " crossj:" << std::endl << crossj<< std::endl;
    }

}
//std::cout << " rresid(u)" << std::endl << temp<< std::endl;
return temp;


}

poly ru( serie s, long T){
poly temp;
gd m, cr;
int crossi=1000;
int crossj=1000;

for (int i=0; i<s.getp().getn(); i++)
{
    m = s.getp().getpol(i);
    if(m.getd()<= T)
    {
        temp = oplus(temp,m);
    }

       if(m.getd() > T)
    {
        crossi= min(i,crossi);
       // std::cout << " crossi:" << std::endl << crossi<< std::endl;
    }
    if(crossi < 1000)
     {
     cr (s.getp().getpol(crossi).getg(),infinity);
         temp = oplus(temp,cr);
     }
}

for (int j=0; j<=s.getq().getn(); j++)
{
    m = s.getq().getpol(j);
    if(m.getd()<= T)
    {
    temp = oplus(temp,m);
    }
       if(m.getd() > T)
    {
        crossj= min(j,crossj);
       // std::cout << " crossj:" << std::endl << crossj<< std::endl;
    }

}
// std::cout << " r(u)" << std::endl << temp<< std::endl;
return temp;


}

/////////////////////////////////////////////////////////////////////
/* Example :  Hardouin L., Cottenceau B., Lagrange S., Le Corronc E.

Performance a&nalysis of linear systems over idempotent semiring with additive inputs
Wodes 2008, Goteborg, Sweden
	*/
/////////////////////////////////////////////////////////////////////



int main()
{
    //smatrix z1o,z2o, z1p, z2p;
    long T=28;
	gd temp_gd, h1, h2,Beta,h3,h4;
	poly temp,SR_tf1,x21,b3;
	//serie temp_serie,u1opts, u2opts;//,s3,s4;
	smatrix transfunctionH1,transfunctionH2,transfunctionH3,transfunctionH4,temp_matrix;
	int time_length;
	int index;
	token_num* token_info;
	token_num* window_info;
	int window_length;
    smatrix A1(2,2),B1(2,1),C1(1,2),AS1(2,2);
    smatrix A2(2,2),B2(2,1),C2(1,2),AS2(2,2);
    smatrix A3(2,2),B3(2,1),C3(1,2),AS3(2,2);
    smatrix A4(2,2),B4(2,1),C4(1,2),AS4(2,2);
    smatrix u1_star,x1_star,u1,u2,u3,u4;
    smatrix u2_star,x2_star,x3_star,x4_star,u1p_star;

    smatrix z1(1,1);//,s3(1,1), s4(1,1);
    smatrix z2(1,1);
/////////////////////////////////////////////////////////////

    SR_tf1.init(2,2);
//////////
    h1.init(0,3);
    h2.init(0,5);
    h3.init(0,6);
    h4.init(0,4);
    Beta.init(2,2);

    A1(0,1).init(temp.init(1,1),epsilon,e);
    A1(1,0).init(temp.init(0,3),epsilon,e);


    A2(0,1).init(temp.init(1,1),epsilon,e);
    A2(1,0).init(temp.init(0,5),epsilon,e);

    A3(0,1).init(temp.init(1,1),epsilon,e);
    A3(1,0).init(temp.init(0,6),epsilon,e);


    A4(0,1).init(temp.init(1,1),epsilon,e);
    A4(1,0).init(temp.init(0,4),epsilon,e);

    B1(0,0).init(epsilon,e,e);
    B2(0,0).init(epsilon,e,e);
    B3(0,0).init(epsilon,e,e);
    B4(0,0).init(epsilon,e,e);

    C1(0,1).init(epsilon,e,e);
    C2(0,1).init(epsilon,e,e);
    C3(0,1).init(epsilon,e,e);
    C4(0,1).init(epsilon,e,e);

   temp.init(0,0)(1,1)(3,3)(6,infinity);
   u1(0,0).init(epsilon,temp,e);

   temp.init(0,0)(2,1)(3,3)(4,infinity);
   u2(0,0).init(epsilon,temp,e);

   temp.init(0,0)(3,3)(5,infinity);
   u3(0,0).init(epsilon,temp,e);

   temp.init(0,0)(2,5)(7,infinity);
   u4(0,0).init(epsilon,temp,e);
//////////////////////////////////////////////////////////////
    AS1 = star(A1);
    AS2 = star(A2);
    AS3 = star(A3);
    AS4 = star(A4);
    transfunctionH1 = otimes(AS1,B1);
   // std::cout << " AS1 otimes B1 :" << std::endl << transfunctionH1<< std::endl;

    transfunctionH2 = otimes(AS2,B2);
    transfunctionH3 = otimes(AS3,B3);
    transfunctionH4 = otimes(AS4,B4);

  //      std::cout << " AS1 otimes B1 :" << std::endl << transfunctionH2<< std::endl;

//    u2_star = lfrac(z2,transfunctionH2);
//
    x1_star = otimes(transfunctionH1,u1);
    x2_star = otimes(transfunctionH2,u2);
    x3_star = otimes(transfunctionH3,u3);
    x4_star = otimes(transfunctionH4,u4);
//        std::cout<<"u1* : "<<std::endl<<u1_star<<std::endl;
        std::cout<<"x1_star : "<<std::endl<<x1_star<<std::endl;

        std::cout<<"x2_star : "<<std::endl<<x2_star<<std::endl;
        getchar();
////////////////////////////////////////////////////////////////
//
poly x11,x12,x22,x1121,x1222,x31,x32,x41,x42,temp1,temp2,u2poly,u1poly,u3poly,u4poly;
x11=oplus(x1_star(0,0).getp(),x1_star(0,0).getq());
x12=oplus(x1_star(1,0).getp(),x1_star(1,0).getq());
//x21=oplus(x2_star(0,0).getp(),x2_star(0,0).getq());
//x22=oplus(x2_star(1,0).getp(),x2_star(1,0).getq());

u2poly=oplus(u2(0,0).getp(),u2(0,0).getq());
u1poly=oplus(u1(0,0).getp(),u1(0,0).getq());
u3poly=oplus(u3(0,0).getp(),u3(0,0).getq());
u4poly=oplus(u4(0,0).getp(),u4(0,0).getq());

int i=0;
x11.init(0,0)(1,5)(2,7)(3,10)(4,12)(5,15)(6,infinity);
//x12=otimes(h1,x11);
int step=1;
x21=oplus(x2_star(0,0).getp(),x2_star(0,0).getq());
 //x21=epsilon; //*****
 cout << "x21_init"<< x21 <<endl;

     do{
   i++;

cout << "i"<< i <<endl;

b3= x21;// prevoius value of x21
cout << "x21"<< b3 <<endl;
temp1=otimes(h2,x21);
cout << " H2 . x21"<< temp1 <<endl;
temp2=otimes(h1,x11);
cout << " H1 . x11"<< temp2 <<endl;
temp=odot_mark2(temp1,temp2);
cout << " H1 . x11 odot H2 . x21"<< temp <<endl;

temp=otimes(Beta,temp);
cout << " B(H1 . x11 odot H2 . x21)"<< temp <<endl;
temp=odotflat(temp,x11);
cout << " B(H1 . x11 odot H2 . x21)odotflat x11"<< temp <<endl;
temp=oplus(temp,u2poly);
cout<<"step"<<step<<endl;
cout << "temp"<< temp <<endl;
getchar();

if(!(temp==b3)){
x21=temp;
}
else
step=21;

step ++;
} while ( step <20);

if (step==22)
{
    std::cout<<"x21 is ok"<<std::endl<<x21<<std::endl;
    std::cout<<"num of itterations"<<std::endl<<i<<std::endl;
}

x12=otimes(h1,x11);
std::cout<<"x12 "<<std::endl<<x12<<std::endl;
x22=otimes(h2,x21);
x1222=odot_mark2(x12,x22);
x1121=odot_mark2(x11,x21);

int j=0;

step=1;

 x31=oplus(x3_star(0,0).getp(),x3_star(0,0).getq()); //*****
 cout << "x31_init"<< x31 <<endl;

     //

     do{
   j++;

cout << "j"<< j <<endl;

b3= x31;// prevoius value of x21
cout << "x31"<< b3 <<endl;
temp1=otimes(h3,x31);
cout << " H3 . x31"<< temp1 <<endl;
temp2=x1222;
cout << " x12 odot x22"<< temp2 <<endl;
temp=odot_mark2(temp1,temp2);
cout << " x12 odot x22 odot H3 . x31"<< temp <<endl;

temp=otimes(Beta,temp);
cout << " B(x12 odot x22 odot H3 . x31)"<< temp <<endl;
temp=odotflat(temp,x1121);
temp=oplus(temp,u3poly);

cout << "temp"<< temp <<endl;

if(!(temp==b3)){
x31=temp;
}
else
step=21;

step ++;
} while ( step <20);
////poly u2star;
////u2star=frac(y2star,H2);
//
if (step==22)
{
     std::cout<<"x31 is ok"<<std::endl<<x31<<std::endl;
          std::cout<<"num of itterations"<<std::endl<<j<<std::endl;


}

poly x122232, x112131;
x32=otimes(h3,x31);
x122232=odot_mark2(x1222,x32);
x112131=odot_mark2(x1121,x31);

int k=0;

step=1;

 x41=oplus(x4_star(0,0).getp(),x4_star(0,0).getq()); //*****
 cout << "x41_init"<< x41 <<endl;

     //

     do{
   k++;

cout << "k"<< k <<endl;

b3= x41;// prevoius value of x21
cout << "x41"<< b3 <<endl;
temp1=otimes(h4,x41);
cout << " H4 . x41"<< temp1 <<endl;
temp2=x122232;
temp=odot_mark2(temp1,temp2);
cout << " x12 odot x22 odot x32 odot H4 . x41"<< temp <<endl;

temp=otimes(Beta,temp);
cout << " B(x12 odot x22 odot x32 odot H4 . x41)"<< temp <<endl;
temp=odotflat(temp,x112131);
temp=oplus(temp,u4poly);

cout << "temp"<< temp <<endl;

if(!(temp==b3)){
x41=temp;
}
else
step=21;

step ++;
} while ( step <20);
////poly u2star;
////u2star=frac(y2star,H2);
//
if (step==22)
{
     std::cout<<"x41 is ok"<<std::endl<<x41<<std::endl;
          std::cout<<"num of itterations"<<std::endl<<k<<std::endl;


}

 std::cout<<"x11 is ok"<<std::endl<<x11<<std::endl;
  std::cout<<"x21 is ok"<<std::endl<<x21<<std::endl<<"num of iterations"<<std::endl<<i<<std::endl;
   std::cout<<"x31 is ok"<<std::endl<<x31<<std::endl<<"num of iterations"<<std::endl<<j<<std::endl;
    std::cout<<"x41 is ok"<<std::endl<<x41<<std::endl<<"num of iterations"<<std::endl<<k<<std::endl;





}
