m,n-cubes Generator 1.0
Generation of the Rote sequences for m,n-cubes of plans through (0,0,0)
|
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 }