#ifndef POLYGON_HPP #define POLYGON_HPP #include #include #include #include #include "config.hpp" #include "coeffs.hpp" #include "polygon_step.hpp" #include "flint/fmpz_poly.h" #include "flint/fmpz_poly_q.h" #include "flint/fmpz_poly_mat.h" #include "flint/fmpq_poly.h" using namespace std; //*********** //* Polygon * //*********** //! Class for self avoiding polygon in the square lattice //! Polygon are drown on a grid and hace length bounded //! by max_len. The grid have a border prevent the polygon //! to go too far. A typical example of the grid is //! ########## //! # # //! ####S # //! ########## //! where S is the starting point and # is border. //! Polygon will grow applyng step. A grid case contains //! contains the path distance from the starting point. //! We store the unique id of a step in an historic grid. //! In order to perfoem backward without clearing the grid, //! we associate the step id to the corresponding path //! distance. Hence the case (i,j) of the grid contribute //! to the polygon if grid[(i,j)]=t and histo_grid[t]=s //! and step_histo[s]=t. class Polygon{ public: //! Width of the grid static const size_t grid_width=max_len-1; //! Height of the grid static const size_t grid_height=max_len/2+2; //! Size of the grid static const size_t grid_size=grid_width*grid_height; //! Position of the starting point static const int64 xinit=max_len/2-2; static const int64 yinit=1; //! Border value static const size_t border=0; //! Empty value static const size_t empty=-1; //! The living grid the polygon size_t grid[grid_size]; //! The history grid of the polygon size_t grid_histo[grid_size]; //! The history step of the polygon size_t step_histo[max_len+1]; //! Head poistion on the grid size_t head; //! Lenght of the polygon size_t length; //! Empty constructor Polygon(); //! Copy operator Polygon& operator=(const Polygon& P); //! Init data of the polygon void init(); //! Display the polygon void display() const; //! Apply a step to the polygon //! \param s step to apply void apply(Step& s); //! Test is the case at position ind is admissible //! as the next case of the polygon; this at path //! length t. //! \param t path_length of the next case //! \param ind index of the case to test //! \param s last step applied to the polygon bool test(size_t t,size_t ind,Step* s) const; //! Test if the polygon is closed bool is_closed() const; //! Return indice of the next vertex of the polygon //! \param t path length of the current vertex //! \param c current vertex indice size_t next_vertex(size_t t,size_t c) const; //! Return the fp coefficient of the polygon void fp(fmpq_poly_t r) const; //------------------ // Static functions //------------------ //! Return x coordinate of the case with indice ind. //! \param ind indice of the case static int64 x(size_t ind); //! Return y coordinate of the case with indice ind. //! \param ind indice of the case static int64 y(size_t ind); //! Return indice of the case on the left of case with //! indice ind. //! \param ind indice of the case static size_t left(size_t ind); //! Return indice of the case on the right of case with //! indice ind. //! \param ind indice of the case static size_t right(size_t ind); //! Return indice of the case on the up of case with //! indice ind. //! \param ind indice of the case static size_t up(size_t ind); //! Return indice of the case on the down of case with //! indice ind. //! \param ind indice of the case static size_t down(size_t ind); //! Return indice of the case at position (x,y). //! \param x x-coordinate of the case //! \prama y y-coordiante of the case static size_t pos(size_t x,size_t y); }; //************** //* InfoVertex * //************** //! This class is used to obtained the adjacence matrix //! of the haired polygon. class InfoVertex{ public: //! Indice of the vertex size_t id; //! Coordinates of the vertex int64 x,y; //! Degree of the vertex size_t deg; //! Neighbhorhoods of the vertex size_t v[4]; //! Empty constructor (not explicety used) InfoVertex(); //! Constructor for a vertex with not yet detected neighbhors. //! \param id indice of the vertex //! \param x x-coordinate of the vertex //! \param y y-coordinate of the vertex InfoVertex(size_t id,int64 x,int64 y); //! Constructor for a vertex with four identified neighbhors. //! \param id indice of the vertex //! \param x x-coordinate of the vertex //! \param y y-coordinate of the vertex //! \param l indice of the vertex on the left //! \param r indice of the vertex on the right //! \param u indice of the vertex on the up //! \param d indice of the vertex on the dwon InfoVertex(size_t id,int64 x,int64 y,size_t l,size_t r,size_t u,size_t d); }; //******************** //* Inline functions * //******************** //--------- // Polygon //--------- inline Polygon::Polygon(){ } inline bool Polygon::test(size_t t,size_t ind,Step* s) const{ size_t v=grid[ind]; if(v>s->t) return true; return grid_histo[ind]!=s->histo[v]; } inline void Polygon::apply(Step& step){ length=step.t; grid[head=step.newh]=step.t; grid_histo[head]=step.num(); memcpy(step_histo,step.histo,(step.t+1)*sizeof(size_t)); } inline bool Polygon::is_closed() const{ return grid[down(head)]==1; } //---------------- // Static Polygon //---------------- inline size_t Polygon::left(size_t ind){ return ind-1; } inline size_t Polygon::right(size_t ind){ return ind+1; } inline size_t Polygon::up(size_t ind){ return ind+grid_width; } inline size_t Polygon::down(size_t ind){ return ind-grid_width; } inline int64 Polygon::x(size_t ind){ return ind%grid_width; } inline int64 Polygon::y(size_t ind){ return ind/grid_width; } inline size_t Polygon::pos(size_t x,size_t y){ return x+y*grid_width; } //------------ // InfoVertex //------------ inline InfoVertex::InfoVertex(){ } inline InfoVertex::InfoVertex(size_t _id,int64 _x,int64 _y): id(_id),x(_x),y(_y),deg(0){ } inline InfoVertex::InfoVertex(size_t _id,int64 _x,int64 _y,size_t l,size_t r,size_t u,size_t d): id(_id),x(_x),y(_y),deg(4),v{l,r,u,d}{ } #endif