treewalk.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <chrono>
  4. #include <cmath>
  5. #include <cpuid.h>
  6. #include <fstream>
  7. #include "treewalk.hpp"
  8. using namespace std;
  9. using namespace std::chrono;
  10. fstream file;
  11. void treat(const monoid& m){
  12. // int w=m.e*m.left-m.conductor;
  13. int q=ceil(float(m.conductor)/float(m.min));
  14. unsigned int rho=q*m.min-m.conductor;
  15. if(m.wilf<=rho){
  16. if((m.wilf<0) or (m.wilf<=rho and m.e>2 and m.left_primitive>1 and q>=4)){
  17. output(m,file);
  18. }
  19. }
  20. }
  21. //static const int mcut=ceil(float(3*(MAX_GENUS+2))/5);
  22. bool cut(const monoid& m){
  23. if(3*m.left_primitive>=m.min) return true;
  24. return false;
  25. }
  26. void walk(int m,int k)
  27. {
  28. monoid data[MAX_GENUS-1], *stack[MAX_GENUS], *current,temp,temp2;
  29. monoid **stack_pointer = stack+1;
  30. for (ind_t i=1; i<MAX_GENUS; i++) stack[i] = &(data[i-1]);
  31. init_ordinary(data[0],m);
  32. for(int i=0;i<k;++i){
  33. auto it = generator_iter<CHILDREN>(data[i]);
  34. it.move_next();
  35. // printq_monoid_gen(data[i]);
  36. ind_t pos=0;
  37. if(i==0){
  38. it.move_next();
  39. pos=1;
  40. }
  41. remove_generator(data[i+1],data[i],it.get_gen(),pos);
  42. }
  43. temp=data[k];
  44. stack[0]=&temp;
  45. cout<<"Root : ";
  46. print_monoid_gen(temp);
  47. auto it = generator_iter<CHILDREN>(temp);
  48. it.move_next();
  49. ind_t pos=1;
  50. if(k==0){
  51. it.move_next();
  52. ++pos;
  53. }
  54. while (it.move_next()){
  55. stack_pointer[0] = stack_pointer[1];
  56. remove_generator(**stack_pointer, temp, it.get_gen(),pos++);
  57. cout<<"Pop "<<it.get_gen()<<" : ";
  58. print_monoid_gen(**stack_pointer);
  59. treat(**stack_pointer);
  60. stack_pointer++;
  61. }
  62. while (stack_pointer != stack)
  63. {
  64. --stack_pointer;
  65. current = *stack_pointer;
  66. if(not cut(*current))
  67. {
  68. if (current->genus < MAX_GENUS - 1)
  69. {
  70. auto it = generator_iter<CHILDREN>(*current);
  71. ind_t pos=0;
  72. while (it.move_next())
  73. {
  74. // exchange top with top+1
  75. stack_pointer[0] = stack_pointer[1];
  76. remove_generator(**stack_pointer, *current, it.get_gen(),pos++);
  77. treat(**stack_pointer);
  78. stack_pointer++;
  79. }
  80. *stack_pointer = current;
  81. }
  82. else
  83. {
  84. auto it = generator_iter<CHILDREN>(*current);
  85. ind_t pos=0;
  86. while (it.move_next())
  87. {
  88. remove_generator(temp2, *current, it.get_gen(),pos++);
  89. treat(temp2);
  90. }
  91. }
  92. }
  93. }
  94. }
  95. int main(int argc, char **argv)
  96. {
  97. if(argc!=4){
  98. cerr<<"Usage : "<<argv[0]<<" [m] [k] filename with k in [0,MAX_GENUS-m]"<<endl;
  99. exit(-1);
  100. }
  101. int m=atoi(argv[1]);
  102. int k=atoi(argv[2]);
  103. char* filename_base=argv[3];
  104. if(k<0 or k>=MAX_GENUS-m){
  105. cerr<<"k must be in [0,MAX_GENUS-m]"<<endl;
  106. exit(-2);
  107. }
  108. unsigned int ax, bx, cx, dx;
  109. if (!__get_cpuid(0x00000001, &ax, &bx, &cx, &dx))
  110. {
  111. cerr << "Unable to determine the processor type !" << endl;
  112. return EXIT_FAILURE;
  113. }
  114. if (!(cx & bit_SSSE3))
  115. {
  116. cerr << "This programm require sse3 instructions set !" << endl;
  117. return EXIT_FAILURE;
  118. }
  119. if (!(cx & bit_POPCNT))
  120. {
  121. cerr << "This programm require popcount instruction !" << endl;
  122. return EXIT_FAILURE;
  123. }
  124. cout << "Testing Wilf's conjecture for numerical semigroups of genus <= "
  125. << MAX_GENUS << " for m="<<m<<" and k="<<k<<"."<<endl;
  126. /*cerr << "Testing Wilf's conjecture for numerical semigroups of genus <= "
  127. << MAX_GENUS << " for m="<<m<<" and k="<<k<<"."<<endl;*/
  128. auto begin = high_resolution_clock::now();
  129. string filename=string(filename_base)+"_wilf_"+to_string(m)+"_"+to_string(k);
  130. file.open(filename.c_str(),ios::out|ios::trunc);
  131. walk(m,k);
  132. auto end = high_resolution_clock::now();
  133. duration<double> ticks = end-begin;
  134. cout << " Computation time = " << std::setprecision(4) << ticks.count() << " s." << endl;
  135. file.close();
  136. return EXIT_SUCCESS;
  137. }