m,n-cubes Generator 1.0
Generation of the Rote sequences for m,n-cubes of plans through (0,0,0)
rote_generation.cpp
Go to the documentation of this file.
00001 
00106 #include <iostream>
00107 #include <cstdlib>
00108 #include <CGAL/Cartesian.h>
00109 #include <CGAL/Arr_segment_traits_2.h>
00110 #include <CGAL/Arr_extended_dcel.h>
00111 #include <CGAL/Arrangement_2.h>
00112 #include <CGAL/Gmpz.h>
00113 #include <CGAL/Gmpq.h>
00114 #include <boost/math/common_factor_rt.hpp>
00115 #include <stack>
00116 
00117 using namespace std;
00118 
00119 int m, n;
00120 
00126 struct VertexData {};
00127 
00133 struct EdgeData {
00134   int i, j;
00135   EdgeData() : i(0), j(0) {};
00136   EdgeData(const int& i_, const int& j_) : i(i_), j(j_) {};
00137 };
00138 
00140 struct FaceData {
00141   bool discovered; 
00142   char** matrix; 
00143 
00144 
00148   FaceData() : discovered(false) {
00149     typedef char* char_ptr;
00150     matrix = new char_ptr [m];
00151     matrix[0] = new char[m*n];
00152     for(int i = 1; i < m; ++i)
00153       matrix[i] = matrix[i-1] + n;
00154     for(int i = 0; i < m; i++)
00155       for(int j = 0; j < n; ++j)
00156     matrix[i][j] = 0;
00157   }
00158   void delete_face() {
00159     delete [] matrix[0];
00160     delete [] matrix;
00161   }
00162 };
00163 
00169 ostream& operator<< (ostream& stream, char** matrix) {
00170   // assuming the matrix has size m x n
00171   for(int i = 0; i < m; ++i) {
00172     for(int j = 0; j < n; ++j)
00173       stream << "[" << (int) matrix[i][j] << "]";
00174     stream << endl;
00175   }
00176   return stream;
00177 }
00178 
00180 typedef CGAL::Gmpz Integer;
00181 
00183 typedef CGAL::Gmpq rat;
00184 
00186 typedef CGAL::Cartesian<rat> Kernel;
00187 typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
00188 typedef Traits_2::Point_2 Point_2;
00189 typedef Traits_2::X_monotone_curve_2 Segment_2;
00190 
00192 typedef CGAL::Arr_extended_dcel<Traits_2,
00193                 VertexData,
00194                 EdgeData,
00195                 FaceData> Dcel;
00196 
00198 typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
00199 
00204 typedef Arrangement_2::Face_handle Face_ptr;
00205 
00206 
00220 void flip (int const& i, int const& j, char** matrix_src, char** matrix_dest) {
00221   // assuming i, j and k are in the correct interval, and matrices have
00222   // size m x n
00223   for(int r = 0; r < m; ++r)
00224     for(int s = 0; s < n; ++s)
00225       matrix_dest[r][s] = matrix_src[r][s];
00226   for (int r = int(1); r*i < int(m) && r*j < int(n); ++r)
00227     matrix_dest[r*i][r*j] = 1 - matrix_dest[r*i][r*j];
00228 }
00229 
00244 std::list <Face_ptr> dfs(Arrangement_2 const& graph, Face_ptr f) {
00245   std::list <Face_ptr> depth_first_result;
00246   std::stack <Face_ptr> vertices;
00247 
00248   vertices.push(f);
00249   f->data().discovered = true;
00250   while ( ! vertices.empty() ) {
00251     Face_ptr head = vertices.top();
00252     vertices.pop();
00253     
00254     depth_first_result.push_back(head);
00255     //    cout << head->data().matrix << endl;
00256     
00257     Arrangement_2::Ccb_halfedge_circulator first, curr, flip_op;
00258     first = curr = head->outer_ccb();
00259     do {
00260       Face_ptr son = curr->twin()->face();
00261       if( ! son->is_unbounded() && ! son->data().discovered) {
00262     vertices.push(son);
00263     son->data().discovered = true;
00264     flip(curr->data().i, curr->data().j, head->data().matrix, son->data().matrix);
00265       }
00266     } while(++curr != first);
00267   }
00268   
00269   return depth_first_result;
00270 }
00271 
00286 int main(int argc, char** argv) {
00287   if(argc != 3) cout << "usage : ./generator [m] [n]\nExit 1.\n", exit(1);
00288 
00289   string mm(*++argv); string nn(*++argv);
00290   (void) sscanf(nn.c_str(),"%d",&n);
00291   (void) sscanf(mm.c_str(),"%d",&m);
00292   
00293   cout << " -- " << m << "," << n << "-cubes generation --" << endl;
00294 
00295   Arrangement_2 arr;
00296 
00297   //general case
00298   for(int j(1); j < n; j++)
00299     for(int i(1); i < m; i++)
00300       for(int k(1); k < i+j; k++) {
00301     if(boost::math::gcd(j,boost::math::gcd(i,k)) == 1) {
00302       rat x0, y0, x1, y1;
00303       if(k > j) {
00304         y0 = rat(1);
00305         x0 = rat (k - j, i);
00306       }
00307       else if (k < j)
00308         x0 = rat(0), y0 = rat(k, j);
00309       else
00310         x0 = rat(0), y0 = rat(1);
00311       if(k < i) {
00312         y1 = rat(0);
00313         x1 = rat(k , i);
00314       }
00315       else if (k > i)
00316         x1 = rat(1), y1 = rat(k - i, j);
00317       else 
00318         x1 = rat(1), y1 = rat(0);
00319       
00320       insert(arr, Segment_2 (Point_2 (x0,y0), Point_2 (x1,y1)));
00321     }
00322       }
00323 
00324 
00325   //horizontal segments
00326   for(int j(1); j < n; j++)
00327     for(int k(1); k < j; k++)
00328       if(boost::math::gcd(j,k) == 1)
00329     insert(arr, Segment_2 (Point_2 (rat (0), rat (k, j)),
00330                    Point_2 (rat(1), rat(k, j))));
00331 
00332   insert(arr, Segment_2 (Point_2 (rat(0), rat(0)),
00333              Point_2 (rat(1), rat(0))));
00334   
00335   insert(arr, Segment_2 (Point_2 (rat(0), rat(1)),
00336              Point_2 (rat(1), rat(1)))); 
00337 
00338 
00339   //vectical segments
00340   for(int i(1); i < m; i++)
00341     for(int k(1); k < i; k++)
00342       if(boost::math::gcd(i,k) == 1)
00343     insert(arr, Segment_2 (Point_2 (rat(k, i), rat(0)),
00344                    Point_2 (rat(k, i), rat(1))));
00345 
00346   insert(arr, Segment_2 (Point_2 (rat(0), rat(0)),
00347              Point_2 (rat(0), rat(1))));
00348 
00349   insert(arr, Segment_2 (Point_2 (rat(1), rat(0)),
00350              Point_2 (rat(1), rat(1))));
00351 
00352   Arrangement_2::Face_handle start; //flat m,n-cube
00353   Arrangement_2::Edge_iterator eit;
00354   
00355 
00356   for(eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
00357     Point_2 a = eit->source()->point(), b = eit->target()->point();
00358 
00359     if((a.x() == 0 && a.y() == 0) || (b.x() == 0 && b.y() == 0))
00360       if( ! eit->face()->is_unbounded())
00361     start = eit->face();
00362       else
00363     start = eit->twin()->face();
00364 
00365     if((a.x() - b.x()) != 0) { 
00366       rat alpha = (a.y() - b.y()) / (a.x() - b.x());
00367       rat beta = a.y() - alpha*a.x();
00368 
00369       Integer p = alpha.numerator(), q = alpha.denominator(),
00370     p_ = beta.numerator(), q_ = beta.denominator();
00371       Integer gcd_ = boost::math::gcd(q*q_, boost::math::gcd(-p*q_, p_*q));
00372       int i = (int) (-p*q_/gcd_).to_double(), j = (int) (q*q_/gcd_).to_double();
00373       eit->set_data(EdgeData(i,j));
00374       eit->twin()->set_data(EdgeData(i,j));
00375     }
00376     else {
00377       rat k = a.x();
00378       Integer p = k.numerator(), q = k.denominator();
00379       Integer gcd_ = boost::math::gcd(p,q);
00380       int i = (int) (q/gcd_).to_double();
00381       eit->set_data(EdgeData(i, 0));
00382       eit->twin()->set_data(EdgeData(i, 0));
00383     }
00384   }
00385  
00386   std::list <Face_ptr> rote_sequences = dfs(arr, start);
00387   for(list<Face_ptr>::iterator it = rote_sequences.begin();
00388       it != rote_sequences.end(); it++) {
00389     cout << (*it)->data().matrix << endl;
00390     (*it)->data().delete_face();
00391   }
00392   cout << "Number of m,n-cubes of plans through (0,0,0) : " << rote_sequences.size() << endl;
00393 
00394   return 0;
00395 }
 All Classes Files Functions Variables Typedefs