/IntegerProgramming/binomial.cc

https://github.com/burcin/Singular · C++ · 1919 lines · 1020 code · 624 blank · 275 comment · 246 complexity · 3edf4ffa2ec885a70652823fe4dd052a MD5 · raw file

  1. // binomial.cc
  2. // implementation of class binomial
  3. #ifndef BINOMIAL_CC
  4. #define BINOMIAL_CC
  5. #include <climits>
  6. #include "binomial__term_ordering.h"
  7. ///////////////////////// constructors and destructor //////////////////////
  8. // For a better overview, the constructor code is separated for
  9. // NO_SUPPORT_DRIVEN_METHODS and SUPPORT_DRIVEN_METHODS.
  10. #ifdef NO_SUPPORT_DRIVEN_METHODS
  11. binomial::binomial(const short& number_of_variables)
  12. :_number_of_variables(number_of_variables)
  13. {
  14. exponent_vector=new Integer[_number_of_variables];
  15. }
  16. binomial::binomial(const short& number_of_variables,const Integer* exponents)
  17. :_number_of_variables(number_of_variables)
  18. {
  19. // range check for rarely used constructors
  20. if(_number_of_variables<=0)
  21. {
  22. cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
  23. "argument out of range"<<endl;
  24. exponent_vector=NULL;
  25. // to avoid problems when deleting
  26. return;
  27. }
  28. // initialization
  29. exponent_vector=new Integer[_number_of_variables];
  30. for(short i=0;i<_number_of_variables;i++)
  31. exponent_vector[i]=exponents[i];
  32. }
  33. binomial::binomial(const short& number_of_variables,const Integer* exponents,
  34. const term_ordering& w)
  35. :_number_of_variables(number_of_variables)
  36. {
  37. // range check for rarely used constructors
  38. if(_number_of_variables<=0)
  39. {
  40. cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
  41. "argument out of range"<<endl;
  42. exponent_vector=NULL;
  43. // to avoid problems when deleting
  44. return;
  45. }
  46. exponent_vector=new Integer[_number_of_variables];
  47. // determine head and tail
  48. if(w.compare_to_zero(exponents)>=0)
  49. for(short i=0;i<_number_of_variables;i++)
  50. exponent_vector[i]=exponents[i];
  51. else
  52. for(short i=0;i<_number_of_variables;i++)
  53. exponent_vector[i]=-exponents[i];
  54. }
  55. binomial::binomial(const binomial& b)
  56. :_number_of_variables(b._number_of_variables)
  57. {
  58. exponent_vector=new Integer[_number_of_variables];
  59. for(short i=0;i<_number_of_variables;i++)
  60. exponent_vector[i]=b.exponent_vector[i];
  61. }
  62. #endif // NO_SUPPORT_DRIVEN_METHODS
  63. #ifdef SUPPORT_DRIVEN_METHODS
  64. binomial::binomial(const short& number_of_variables)
  65. :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
  66. {
  67. exponent_vector=new Integer[_number_of_variables];
  68. }
  69. binomial::binomial(const short& number_of_variables, const Integer* exponents)
  70. :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
  71. {
  72. // range check for rarely used constructors
  73. if(_number_of_variables<=0)
  74. {
  75. exponent_vector=NULL;
  76. // to avoid problems when deleting
  77. cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
  78. "argument out of range"<<endl;
  79. return;
  80. }
  81. exponent_vector=new Integer[_number_of_variables];
  82. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  83. // number of bits of a long int
  84. for(short i=0;i<_number_of_variables;i++)
  85. {
  86. #ifdef SUPPORT_VARIABLES_FIRST
  87. Integer actual_entry=exponents[i];
  88. exponent_vector[i]=actual_entry;
  89. #endif // SUPPORT_VARIABLES_FIRST
  90. #ifdef SUPPORT_VARIABLES_LAST
  91. short j=_number_of_variables-1-i;
  92. Integer actual_entry=exponents[j];
  93. exponent_vector[j]=actual_entry;
  94. #endif // SUPPORT_VARIABLES_LAST
  95. if(i<size_of_support_vectors)
  96. // variable i is considered in the support vectors
  97. if(actual_entry>0)
  98. head_support|=(1<<i);
  99. // bit i of head_support is set to 1 (counting from 0)
  100. else
  101. if(actual_entry<0)
  102. tail_support|=(1<<i);
  103. // bit i of tail_support is set to 1
  104. }
  105. }
  106. binomial::binomial(const short& number_of_variables, const Integer* exponents,
  107. const term_ordering& w)
  108. :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
  109. {
  110. // range check for rarely used constructors
  111. if(_number_of_variables<=0)
  112. {
  113. cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
  114. "argument out of range"<<endl;
  115. exponent_vector=NULL;
  116. // to avoid problems when deleting
  117. return;
  118. }
  119. exponent_vector=new Integer[_number_of_variables];
  120. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  121. // number of bits of a long int
  122. // determine head and tail
  123. short sign;
  124. if(w.compare_to_zero(exponents)>=0)
  125. sign=1;
  126. else
  127. sign=-1;
  128. for(short i=0;i<_number_of_variables;i++)
  129. {
  130. #ifdef SUPPORT_VARIABLES_FIRST
  131. Integer actual_entry=sign*exponents[i];
  132. exponent_vector[i]=actual_entry;
  133. #endif // SUPPORT_VARIABLES_FIRST
  134. #ifdef SUPPORT_VARIABLES_LAST
  135. short j=_number_of_variables-1-i;
  136. Integer actual_entry=sign*exponents[j];
  137. exponent_vector[j]=actual_entry;
  138. #endif // SUPPORT_VARIABLES_LAST
  139. if(i<size_of_support_vectors)
  140. // variable i is considered in the support vectors
  141. if(actual_entry>0)
  142. head_support|=(1<<i);
  143. // bit i of head_support is set to 1 (counting from 0)
  144. else
  145. if(actual_entry<0)
  146. tail_support|=(1<<i);
  147. // bit i of tail_support is set to 1
  148. }
  149. }
  150. binomial::binomial(const binomial& b)
  151. :_number_of_variables(b._number_of_variables),
  152. head_support(b.head_support),tail_support(b.tail_support)
  153. {
  154. exponent_vector=new Integer[_number_of_variables];
  155. for(short i=0;i<_number_of_variables;i++)
  156. exponent_vector[i]=b.exponent_vector[i];
  157. }
  158. #endif // SUPPORT_DRIVEN_METHODS
  159. binomial::~binomial()
  160. {
  161. delete[] exponent_vector;
  162. }
  163. /////////////////// object information /////////////////////////////////////
  164. short binomial::number_of_variables() const
  165. {
  166. return _number_of_variables;
  167. }
  168. short binomial::error_status() const
  169. {
  170. if(_number_of_variables<0)
  171. return _number_of_variables;
  172. return 0;
  173. }
  174. //////////////////// assignment and access operators ////////////////////////
  175. binomial& binomial::operator=(const binomial& b)
  176. {
  177. if(&b==this)
  178. return *this;
  179. #ifdef SUPPORT_DRIVEN_METHODS
  180. head_support=b.head_support;
  181. tail_support=b.tail_support;
  182. #endif // SUPPORT_DRIVEN_METHODS
  183. if(_number_of_variables!=b._number_of_variables)
  184. {
  185. delete[] exponent_vector;
  186. _number_of_variables=b._number_of_variables;
  187. if(_number_of_variables<=0)
  188. {
  189. cerr<<"\nWARNING: binomial& binomial::operator=(const binomial&):\n"
  190. "assigment from corrupt binomial"<<endl;
  191. exponent_vector=NULL;
  192. return (*this);
  193. }
  194. exponent_vector=new Integer[_number_of_variables];
  195. }
  196. for(short i=0;i<_number_of_variables;i++)
  197. exponent_vector[i]=b.exponent_vector[i];
  198. return(*this);
  199. }
  200. Integer binomial::operator[](const short& i) const
  201. {
  202. return exponent_vector[i];
  203. }
  204. //////////////////// comparison operators ///////////////////////////////////
  205. BOOLEAN binomial::operator==(const binomial& b) const
  206. {
  207. if(this == &b)
  208. return(TRUE);
  209. #ifdef SUPPORT_DRIVEN_METHODS
  210. if(head_support!=b.head_support)
  211. return(FALSE);
  212. if(tail_support!=b.tail_support)
  213. return(FALSE);
  214. #endif // SUPPORT_DRIVEN_METHODS
  215. for(short i=0;i<_number_of_variables;i++)
  216. if(exponent_vector[i]!=b.exponent_vector[i])
  217. return(FALSE);
  218. return(TRUE);
  219. }
  220. BOOLEAN binomial::operator!=(const binomial& b) const
  221. {
  222. if(this == &b)
  223. return(FALSE);
  224. #ifdef SUPPORT_DRIVEN_METHODS
  225. if(head_support!=b.head_support)
  226. return(TRUE);
  227. if(tail_support!=b.tail_support)
  228. return(TRUE);
  229. #endif // SUPPORT_DRIVEN_METHODS
  230. for(short i=0;i<_number_of_variables;i++)
  231. if(exponent_vector[i]!=b.exponent_vector[i])
  232. return(TRUE);
  233. return(FALSE);
  234. }
  235. // operators for efficient comparisons with the zero binomial (comp_value=0)
  236. BOOLEAN binomial::operator==(const Integer comp_value) const
  237. {
  238. #ifdef SUPPORT_DRIVEN_METHODS
  239. if(comp_value==0)
  240. {
  241. if(head_support!=0)
  242. return(FALSE);
  243. if(tail_support!=0)
  244. return(FALSE);
  245. }
  246. #endif // SUPPORT_DRIVEN_METHODS
  247. for(short i=0;i<_number_of_variables;i++)
  248. if(exponent_vector[i]!=comp_value)
  249. return(FALSE);
  250. return(TRUE);
  251. }
  252. BOOLEAN binomial::operator!=(const Integer comp_value) const
  253. {
  254. #ifdef SUPPORT_DRIVEN_METHODS
  255. if(comp_value==0)
  256. {
  257. if(head_support!=0)
  258. return(TRUE);
  259. if(tail_support!=0)
  260. return(TRUE);
  261. }
  262. #endif // SUPPORT_DRIVEN_METHODS
  263. for(short i=0;i<_number_of_variables;i++)
  264. if(exponent_vector[i]!=comp_value)
  265. return(TRUE);
  266. return(FALSE);
  267. }
  268. BOOLEAN binomial::operator<=(const Integer comp_value) const
  269. {
  270. #ifdef SUPPORT_DRIVEN_METHODS
  271. if(comp_value==0)
  272. if(head_support!=0)
  273. return(FALSE);
  274. #endif // SUPPORT_DRIVEN_METHODS
  275. for(short i=0;i<_number_of_variables;i++)
  276. if(exponent_vector[i]>comp_value)
  277. return(FALSE);
  278. return(TRUE);
  279. }
  280. BOOLEAN binomial::operator>=(const Integer comp_value) const
  281. {
  282. #ifdef SUPPORT_DRIVEN_METHODS
  283. if(comp_value==0)
  284. if(tail_support!=0)
  285. return(FALSE);
  286. #endif
  287. for(short i=0;i<_number_of_variables;i++)
  288. if(exponent_vector[i]<comp_value)
  289. return(FALSE);
  290. return(TRUE);
  291. }
  292. ////////////// basic routines for Buchbergers's algorithm //////////////////
  293. Integer binomial::head_reductions_by(const binomial& b) const
  294. // Returns the number of possible reductions of the actual binomial´s head
  295. // by the binomial b. This is the minimum of the quotients
  296. // exponent_vector[i]/b.exponent_vector[i]
  297. // where exponent_vector[i]>0 and b.exponent_vector[i]>0
  298. // (0 if there are no such quotients).
  299. // A negative return value means b=0 or head(b)=1.
  300. {
  301. #ifdef NO_SUPPORT_DRIVEN_METHODS
  302. Integer result=-1;
  303. Integer new_result=-1;
  304. // -1 stands for infinitely many reductions
  305. for(short i=0;i<_number_of_variables;i++)
  306. // explicit sign tests for all components
  307. {
  308. Integer actual_b_component=b.exponent_vector[i];
  309. if(actual_b_component>0)
  310. // else variable i is not involved in the head of b
  311. {
  312. Integer actual_component=exponent_vector[i];
  313. if(actual_component<actual_b_component)
  314. return 0;
  315. new_result=(Integer) (actual_component/actual_b_component);
  316. // new_result>=1
  317. if((new_result<result) || (result==-1))
  318. // new (or first) minimum
  319. result=new_result;
  320. }
  321. }
  322. #endif // NO_SUPPORT_DRIVEN_METHODS
  323. #ifdef SUPPORT_DRIVEN_METHODS
  324. if((head_support&b.head_support)!=b.head_support)
  325. // head support of b not contained in head support, no reduction possible
  326. return 0;
  327. Integer result=-1;
  328. Integer new_result=-1;
  329. // -1 stands for infinitely many reductions
  330. short size_of_support_vectors=CHAR_BIT*sizeof(long);
  331. // number of bits of a long int
  332. if(size_of_support_vectors>_number_of_variables)
  333. size_of_support_vectors=_number_of_variables;
  334. // number of components of the support vectors
  335. #ifdef SUPPORT_VARIABLES_FIRST
  336. for(short i=0;i<size_of_support_vectors;i++)
  337. // test support variables
  338. if(b.head_support&(1<<i))
  339. // bit i of b.head_support is 1
  340. {
  341. new_result=(Integer) (exponent_vector[i]/b.exponent_vector[i]);
  342. // remember that exponent_vector[i]>0 !
  343. // (head support contains that of b)
  344. if(new_result==0)
  345. // exponent_vector[i]<b.exponent_vector[i]
  346. return 0;
  347. // new_result>=1
  348. if((new_result<result) || (result==-1))
  349. // new (or first) minimum
  350. result=new_result;
  351. }
  352. for(short i=size_of_support_vectors;i<_number_of_variables;i++)
  353. // test non-support variables
  354. // from now on we need explicit sign tests
  355. {
  356. Integer actual_b_component=b.exponent_vector[i];
  357. if(actual_b_component>0)
  358. // else variable i is not involved in the head of b
  359. {
  360. Integer actual_component=exponent_vector[i];
  361. if(actual_component<actual_b_component)
  362. return 0;
  363. new_result=(Integer) (actual_component/actual_b_component);
  364. // new_result>=1
  365. if((new_result<result) || (result==-1))
  366. // new (or first) minimum
  367. result=new_result;
  368. }
  369. }
  370. #endif // SUPPORT_VARIABLES_FIRST
  371. #ifdef SUPPORT_VARIABLES_LAST
  372. for(short i=0;i<size_of_support_vectors;i++)
  373. // test support variables
  374. if(b.head_support&(1<<i))
  375. // bit i of b.head_support is 1
  376. {
  377. short j=_number_of_variables-1-i;
  378. new_result=(Integer) (exponent_vector[j]/ b.exponent_vector[j]);
  379. // remember that exponent_vector[_number_of_variables-1-i]>0 !
  380. // (head support contains that of b)
  381. if(new_result==0)
  382. // exponent_vector[_number_of_variables-1-i]
  383. // <b.exponent_vector[_number_of_variables-1-i]
  384. return 0;
  385. // new_result>=1
  386. if((new_result<result) || (result==-1))
  387. // new (or first) minimum
  388. result=new_result;
  389. }
  390. for(short i=size_of_support_vectors;i<_number_of_variables;i++)
  391. // test non-support variables
  392. // from now on we need explicit sign tests
  393. {
  394. short j=_number_of_variables-1-i;
  395. Integer actual_b_component=b.exponent_vector[j];
  396. if(actual_b_component>0)
  397. // else variable number_of_variables-1-i is not involved in the head of b
  398. {
  399. Integer actual_component=exponent_vector[j];
  400. if(actual_component<actual_b_component)
  401. return 0;
  402. new_result=(Integer) (actual_component/actual_b_component);
  403. // new_result>=1
  404. if((new_result<result) || (result==-1))
  405. // new (or first) minimum
  406. result=new_result;
  407. }
  408. }
  409. #endif // SUPPORT_VARIABLES_LAST
  410. #endif // SUPPORT_DRIVEN_METHODS
  411. return(result);
  412. }
  413. Integer binomial::tail_reductions_by(const binomial& b) const
  414. // Returns the number of possible reductions of the actual binomial´s tail
  415. // by the binomial b. This is the minimum of the quotients
  416. // - exponent_vector[i]/b.exponent_vector[i]
  417. // where exponent_vector[i]<0 and b.exponent_vector[i]>0
  418. // (0 if there are no such quotients).
  419. // A negative return value means b=0 or head(b)=1.
  420. {
  421. #ifdef NO_SUPPORT_DRIVEN_METHODS
  422. Integer result=-1;
  423. Integer new_result=-1;
  424. // -1 stands for infinitely many reductions
  425. for(short i=0;i<_number_of_variables;i++)
  426. // explicit sign tests for all components
  427. {
  428. Integer actual_b_component=b.exponent_vector[i];
  429. if(actual_b_component>0)
  430. // else variable i is not involved in the head of b
  431. {
  432. Integer actual_component=-exponent_vector[i];
  433. if(actual_component<actual_b_component)
  434. return 0;
  435. new_result=(Integer) (actual_component/actual_b_component);
  436. // new_result>=1
  437. if((new_result<result) || (result==-1))
  438. // new (or first) minimum
  439. result=new_result;
  440. }
  441. }
  442. #endif // NO_SUPPORT_DRIVEN_METHODS
  443. #ifdef SUPPORT_DRIVEN_METHODS
  444. if((tail_support&b.head_support)!=b.head_support)
  445. // head support of b not contained in tail support, no reduction possible
  446. return 0;
  447. Integer result=-1;
  448. Integer new_result=-1;
  449. // -1 stands for infinitely many reductions
  450. short size_of_support_vectors=CHAR_BIT*sizeof(long);
  451. // number of bits of a long int
  452. if(size_of_support_vectors>_number_of_variables)
  453. size_of_support_vectors=_number_of_variables;
  454. // number of components of the support vectors
  455. #ifdef SUPPORT_VARIABLES_FIRST
  456. for(short i=0;i<size_of_support_vectors;i++)
  457. // test support variables
  458. if(b.head_support&(1<<i))
  459. // bit i of b.head_support is 1
  460. {
  461. new_result=(Integer) (-exponent_vector[i]/b.exponent_vector[i]);
  462. // remember that exponent_vector[i]<0 !
  463. // (tail support contains the head support of b)
  464. if(new_result==0)
  465. // -exponent_vector[i]<b.exponent_vector[i]
  466. return 0;
  467. // new_result>=1
  468. if((new_result<result) || (result==-1))
  469. // new (or first) minimum
  470. result=new_result;
  471. }
  472. for(short i=size_of_support_vectors;i<_number_of_variables;i++)
  473. // test non-support variables
  474. // from now on we need explicit sign tests
  475. {
  476. Integer actual_b_component=b.exponent_vector[i];
  477. if(actual_b_component>0)
  478. // else variable i is not involved in the head of b
  479. {
  480. Integer actual_component=-exponent_vector[i];
  481. if(actual_component<actual_b_component)
  482. return 0;
  483. new_result=(Integer) (actual_component/actual_b_component);
  484. // new_result>=1
  485. if((new_result<result) || (result==-1))
  486. // new (or first) minimum
  487. result=new_result;
  488. }
  489. }
  490. #endif // SUPPORT_VARIABLES_FIRST
  491. #ifdef SUPPORT_VARIABLES_LAST
  492. for(short i=0;i<size_of_support_vectors;i++)
  493. // test support variables
  494. if(b.head_support&(1<<i))
  495. // bit i of b.head_support is 1
  496. {
  497. short j=_number_of_variables-1-i;
  498. new_result=(Integer) (-exponent_vector[j] / b.exponent_vector[j]);
  499. // remember that exponent_vector[_number_of_variables-1-i]<0 !
  500. // (tail support contains the head support of b)
  501. if(new_result==0)
  502. // -exponent_vector[_number_of_variables-1-i]
  503. // <b.exponent_vector[_number_of_variables-1-i]
  504. return 0;
  505. // new_result>=1
  506. if((new_result<result) || (result==-1))
  507. // new (or first) minimum
  508. result=new_result;
  509. }
  510. for(short i=size_of_support_vectors;i<_number_of_variables;i++)
  511. // test non-support variables
  512. // from now on we need explicit sign tests
  513. {
  514. short j=_number_of_variables-1-i;
  515. Integer actual_b_component=b.exponent_vector[j];
  516. if(actual_b_component>0)
  517. // else variable number_of_variables-1-i is not involved in the head of b
  518. {
  519. Integer actual_component=-exponent_vector[j];
  520. if(actual_component<actual_b_component)
  521. return 0;
  522. new_result=(Integer) (actual_component/actual_b_component);
  523. // new_result>=1
  524. if((new_result<result) || (result==-1))
  525. // new (or first) minimum
  526. result=new_result;
  527. }
  528. }
  529. #endif // SUPPORT_VARIABLES_LAST
  530. #endif // SUPPORT_DRIVEN_METHODS
  531. return(result);
  532. }
  533. int binomial::reduce_head_by(const binomial& b, const term_ordering& w)
  534. {
  535. Integer reduction_number=head_reductions_by(b);
  536. if(reduction_number<=0)
  537. return 0;
  538. for(short i=0;i<_number_of_variables;i++)
  539. exponent_vector[i]-=(reduction_number * b.exponent_vector[i]);
  540. // multiple reduction
  541. // reduction corresponds to subtraction of vectors
  542. short sign=w.compare_to_zero(exponent_vector);
  543. #ifdef NO_SUPPORT_DRIVEN_METHODS
  544. if(sign==0)
  545. // binomial reduced to zero
  546. return 2;
  547. for(short i=0;i<_number_of_variables;i++)
  548. exponent_vector[i]*=sign;
  549. #endif // NO_SUPPORT_DRIVEN_METHODS
  550. #ifdef SUPPORT_DRIVEN_METHODS
  551. head_support=0;
  552. tail_support=0;
  553. if(sign==0)
  554. // binomial reduced to zero
  555. return 2;
  556. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  557. // recompute the support vectors
  558. #ifdef SUPPORT_VARIABLES_FIRST
  559. for(short i=0;i<_number_of_variables;i++)
  560. {
  561. Integer& actual_entry=exponent_vector[i];
  562. // to avoid unnecessary pointer arithmetic
  563. actual_entry*=sign;
  564. if(i<size_of_support_vectors)
  565. if(actual_entry>0)
  566. head_support|=(1<<i);
  567. else
  568. if(actual_entry<0)
  569. tail_support|=(1<<i);
  570. }
  571. #endif // SUPPORT_VARIABLES_FIRST
  572. #ifdef SUPPORT_VARIABLES_LAST
  573. for(short i=0;i<_number_of_variables;i++)
  574. {
  575. Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
  576. // to avoid unneccessary pointer arithmetic
  577. actual_entry*=sign;
  578. if(i<size_of_support_vectors)
  579. if(actual_entry>0)
  580. head_support|=(1<<i);
  581. else
  582. if(actual_entry<0)
  583. tail_support|=(1<<i);
  584. }
  585. #endif // SUPPORT_VARIABLES_LAST
  586. #endif // SUPPORT_DRIVEN_METHODS
  587. return 1;
  588. }
  589. int binomial::reduce_tail_by(const binomial& b, const term_ordering& w)
  590. {
  591. Integer reduction_number=tail_reductions_by(b);
  592. if(reduction_number<=0)
  593. return 0;
  594. for(short i=0;i<_number_of_variables;i++)
  595. exponent_vector[i]+=(reduction_number * b.exponent_vector[i]);
  596. // multiple reduction
  597. // reduction corresponds to addition of vectors
  598. // a tail reduction does not require a sign check
  599. #ifdef SUPPORT_DRIVEN_METHODS
  600. head_support=0;
  601. tail_support=0;
  602. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  603. // recompute the support vectors
  604. #ifdef SUPPORT_VARIABLES_FIRST
  605. for(short i=0;i<_number_of_variables;i++)
  606. {
  607. Integer& actual_entry=exponent_vector[i];
  608. // to avoid unnecessary pointer arithmetic
  609. if(i<size_of_support_vectors)
  610. if(actual_entry>0)
  611. head_support|=(1<<i);
  612. else
  613. if(actual_entry<0)
  614. tail_support|=(1<<i);
  615. }
  616. #endif // SUPPORT_VARIABLES_FIRST
  617. #ifdef SUPPORT_VARIABLES_LAST
  618. for(short i=0;i<_number_of_variables;i++)
  619. {
  620. Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
  621. // to avoid unneccessary pointer arithmetic
  622. if(i<size_of_support_vectors)
  623. if(actual_entry>0)
  624. head_support|=(1<<i);
  625. else
  626. if(actual_entry<0)
  627. tail_support|=(1<<i);
  628. }
  629. #endif // SUPPORT_VARIABLES_LAST
  630. #endif // SUPPORT_DRIVEN_METHODS
  631. return 1;
  632. }
  633. binomial& S_binomial(const binomial& a, const binomial& b,
  634. const term_ordering& w)
  635. {
  636. binomial* S_bin=new binomial(a._number_of_variables);
  637. binomial& result=*S_bin;
  638. // Note that we allocate memory for the result binomial. We often use
  639. // pointers or references as argument and return types because the
  640. // generating binomials of an ideal are kept in lists. For the performance
  641. // of Buchberger's algorithm it it very important to avoid local copies
  642. // of binomials, so a lot of attention is paid on the choice of argument
  643. // and return types. As this choice is done in order to improve performance,
  644. // it might be a bad choice with respect to code reuse (there are some
  645. // dangerous constructions).
  646. for(short i=0;i<result._number_of_variables;i++)
  647. result.exponent_vector[i]=a.exponent_vector[i]-b.exponent_vector[i];
  648. // The S-binomial corresponds to the vector difference.
  649. // compute head and tail
  650. short sign=w.compare_to_zero(result.exponent_vector);
  651. #ifdef NO_SUPPORT_DRIVEN_METHODS
  652. if(sign==0)
  653. // binomial reduced to zero
  654. return result;
  655. for(short i=0;i<result._number_of_variables;i++)
  656. result.exponent_vector[i]*=sign;
  657. #endif // NO_SUPPORT_DRIVEN_METHODS
  658. #ifdef SUPPORT_DRIVEN_METHODS
  659. result.head_support=0;
  660. result.tail_support=0;
  661. if(sign==0)
  662. // binomial reduced to zero
  663. return result;
  664. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  665. // recompute the support vectors
  666. #ifdef SUPPORT_VARIABLES_FIRST
  667. for(short i=0;i<result._number_of_variables;i++)
  668. {
  669. Integer& actual_entry=result.exponent_vector[i];
  670. // to avoid unnecessary pointer arithmetic
  671. actual_entry*=sign;
  672. if(i<size_of_support_vectors)
  673. if(actual_entry>0)
  674. result.head_support|=(1<<i);
  675. else
  676. if(actual_entry<0)
  677. result.tail_support|=(1<<i);
  678. }
  679. #endif // SUPPORT_VARIABLES_FIRST
  680. #ifdef SUPPORT_VARIABLES_LAST
  681. for(short i=0;i<result._number_of_variables;i++)
  682. {
  683. Integer& actual_entry=result.exponent_vector
  684. [result._number_of_variables-1-i];
  685. // to avoid unneccessary pointer arithmetic
  686. actual_entry*=sign;
  687. if(i<size_of_support_vectors)
  688. if(actual_entry>0)
  689. result.head_support|=(1<<i);
  690. else
  691. if(actual_entry<0)
  692. result.tail_support|=(1<<i);
  693. }
  694. #endif // SUPPORT_VARIABLES_LAST
  695. #endif // SUPPORT_DRIVEN_METHODS
  696. return result;
  697. }
  698. ///////////// criteria for unnecessary S-pairs ///////////////////////////////
  699. // The criteria are programmed in a way that tries to minimize pointer
  700. // arithmetic. Therefore the code may appear a little bit inflated.
  701. BOOLEAN relatively_prime(const binomial& a, const binomial& b)
  702. {
  703. #ifdef NO_SUPPORT_DRIVEN_METHODS
  704. // look at all variables
  705. for(short i=0;i<a._number_of_variables;i++)
  706. if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
  707. return FALSE;
  708. return TRUE;
  709. #endif // NO_SUPPORT_DRIVEN_METHODS
  710. #ifdef SUPPORT_DRIVEN_METHODS
  711. if((a.head_support & b.head_support)!=0)
  712. // common support variable in the heads
  713. return FALSE;
  714. // no common support variable in the heads, look at remaining variables
  715. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  716. #ifdef SUPPORT_VARIABLES_FIRST
  717. for(short i=size_of_support_vectors;i<a._number_of_variables;i++)
  718. if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
  719. return FALSE;
  720. return TRUE;
  721. #endif // SUPPORT_VARIABLES_FIRST
  722. #ifdef SUPPORT_VARIABLES_LAST
  723. for(short i=a._number_of_variables-1-size_of_support_vectors;i>=0;i--)
  724. if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
  725. return FALSE;
  726. return TRUE;
  727. #endif // SUPPORT_VARIABLES_LAST
  728. #endif // SUPPORT_DRIVEN_METHODS
  729. }
  730. BOOLEAN M(const binomial& a, const binomial& b, const binomial& c)
  731. // Returns TRUE iff lcm(head(a),head(c)) divides properly lcm(head(b),head(c)).
  732. // This is checked by comparing the positive components of the exponent
  733. // vectors.
  734. {
  735. #ifdef SUPPORT_DRIVEN_METHODS
  736. long b_or_c=b.head_support|c.head_support;
  737. if((a.head_support|b_or_c) != b_or_c)
  738. return FALSE;
  739. // The support of lcm(head(a),head(c)) equals the union of the head supports
  740. // of a and c. The above condition verifies if the support of
  741. // lcm(head(a),head(c)) is contained in the support of lcm(head(b),head(c))
  742. // by checking if head a involves a variable that is not involved in
  743. // head(b) or head(c).
  744. #endif // SUPPORT_DRIVEN_METHODS
  745. BOOLEAN properly=FALSE;
  746. for(short i=0;i<a._number_of_variables;i++)
  747. {
  748. Integer a_exponent=a.exponent_vector[i];
  749. Integer b_exponent=b.exponent_vector[i];
  750. Integer c_exponent=c.exponent_vector[i];
  751. Integer m1=MAXIMUM(a_exponent,c_exponent);
  752. Integer m2=MAXIMUM(b_exponent,c_exponent);
  753. if(m1>0)
  754. {
  755. if(m1>m2)
  756. return FALSE;
  757. if(m1<m2)
  758. properly=TRUE;
  759. }
  760. }
  761. return properly;
  762. }
  763. BOOLEAN F(const binomial& a, const binomial& b, const binomial& c)
  764. // verifies if lcm(head(a),head(c))=lcm(head(b),head(c))
  765. {
  766. #ifdef SUPPORT_DRIVEN_METHODS
  767. if((a.head_support|c.head_support)!=(b.head_support|c.head_support))
  768. return FALSE;
  769. // The above condition verifies if the support of lcm(head(a),head(c))
  770. // equals the support of lcm(head(b),head(c)).
  771. #endif // SUPPORT_DRIVEN_METHODS
  772. for(short i=0;i<a._number_of_variables;i++)
  773. {
  774. Integer a_exponent=a.exponent_vector[i];
  775. Integer b_exponent=b.exponent_vector[i];
  776. Integer c_exponent=c.exponent_vector[i];
  777. Integer m1=MAXIMUM(a_exponent,c_exponent);
  778. Integer m2=MAXIMUM(b_exponent,c_exponent);
  779. if((m1!=m2) && (m1>0 || m2>0))
  780. return FALSE;
  781. }
  782. return TRUE;
  783. }
  784. BOOLEAN B(const binomial& a, const binomial& b, const binomial& c)
  785. // verifies if head(a) divides lcm(head(b),head(c)) and
  786. // lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c))
  787. {
  788. #ifdef SUPPORT_DRIVEN_METHODS
  789. long a_or_b=a.head_support|b.head_support;
  790. long a_or_c=a.head_support|c.head_support;
  791. long b_or_c=b.head_support|c.head_support;
  792. if((a.head_support & b_or_c)!=a.head_support)
  793. return FALSE;
  794. // The above condition verifies if the support of head(a) is contained in
  795. // the support of lcm(head(b),head(c)).
  796. if( (a_or_c != b_or_c) && (a_or_b != b_or_c))
  797. // Then the inequality conditions are guaranteed...
  798. {
  799. for(short i=0;i<a._number_of_variables;i++)
  800. {
  801. Integer b_exponent=b.exponent_vector[i];
  802. Integer c_exponent=c.exponent_vector[i];
  803. if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
  804. return FALSE;
  805. }
  806. return (TRUE);
  807. }
  808. if(a_or_b != b_or_c)
  809. // Then the first inequality conditions is guaranteed...
  810. // Verifie only the second.
  811. {
  812. BOOLEAN not_equal=FALSE;
  813. for(short i=0;i<a._number_of_variables;i++)
  814. {
  815. Integer a_exponent=a.exponent_vector[i];
  816. Integer b_exponent=b.exponent_vector[i];
  817. Integer c_exponent=c.exponent_vector[i];
  818. Integer m=MAXIMUM(b_exponent, c_exponent);
  819. if(a_exponent>m)
  820. return FALSE;
  821. if(MAXIMUM(a_exponent,c_exponent) != m)
  822. not_equal=TRUE;
  823. }
  824. return(not_equal);
  825. }
  826. if( a_or_c != b_or_c )
  827. // Then the second inequality conditions is guaranteed...
  828. // Verifie only the first.
  829. {
  830. BOOLEAN not_equal=FALSE;
  831. for(short i=0;i<a._number_of_variables;i++)
  832. {
  833. Integer a_exponent=a.exponent_vector[i];
  834. Integer b_exponent=b.exponent_vector[i];
  835. Integer c_exponent=c.exponent_vector[i];
  836. Integer m=MAXIMUM(b_exponent, c_exponent);
  837. if(a_exponent > m)
  838. return FALSE;
  839. if(MAXIMUM(a_exponent,b_exponent) != m)
  840. not_equal=TRUE;
  841. }
  842. return(not_equal);
  843. }
  844. #endif // SUPPORT_DRIVEN_METHODS
  845. BOOLEAN not_equal_1=FALSE;
  846. BOOLEAN not_equal_2=FALSE;
  847. for(short i=0;i<a._number_of_variables;i++)
  848. {
  849. Integer a_exponent=a.exponent_vector[i];
  850. Integer b_exponent=b.exponent_vector[i];
  851. Integer c_exponent=c.exponent_vector[i];
  852. Integer m=MAXIMUM(b_exponent, c_exponent);
  853. if(a_exponent > m)
  854. return FALSE;
  855. if(MAXIMUM(a_exponent,b_exponent) != m)
  856. not_equal_1=TRUE;
  857. if(MAXIMUM(a_exponent,c_exponent) != m)
  858. not_equal_2=TRUE;
  859. }
  860. return (not_equal_1 && not_equal_2);
  861. }
  862. BOOLEAN second_crit(const binomial& a, const binomial& b,
  863. const binomial& c)
  864. // verifies if head(a) divides lcm(head(b),head(c))
  865. {
  866. #ifdef SUPPORT_DRIVEN_METHODS
  867. if((a.head_support & (b.head_support|c.head_support))!=a.head_support)
  868. return FALSE;
  869. // The above condition verifies if the support of head(a) is contained in
  870. // the support of lcm(head(b),head(c))
  871. #endif // SUPPORT_DRIVEN_METHODS.
  872. for(short i=0;i<a._number_of_variables;i++)
  873. {
  874. Integer b_exponent=b.exponent_vector[i];
  875. Integer c_exponent=c.exponent_vector[i];
  876. if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
  877. return FALSE;
  878. }
  879. return (TRUE);
  880. }
  881. //////// special routines needed by the IP-algorithms ///////////////////////
  882. BOOLEAN binomial::involves_elimination_variables(const term_ordering& w)
  883. {
  884. // The use of support information would require the distinction of various
  885. // cases here (relation between the number of variables to eliminate
  886. // and the number of support variables) and be quite difficult.
  887. // It is doubtful if this would improve performance.
  888. // As this function is not used in Buchberger´s algorithm (and therefore
  889. // rather rarely), I renounce to implement this.
  890. for(short i=0;i<w.number_of_elimination_variables();i++)
  891. // elimination variables are always the last ones
  892. if(exponent_vector[_number_of_variables-1-i]!=0)
  893. return TRUE;
  894. return FALSE;
  895. }
  896. BOOLEAN binomial::drop_elimination_variables(const term_ordering& w)
  897. {
  898. _number_of_variables-=w.number_of_elimination_variables();
  899. // dangerous (no compatibility check)!!
  900. // copy components of interest to save memory
  901. // the leading term has to be recomputed!!
  902. Integer *aux=exponent_vector;
  903. exponent_vector=new Integer[_number_of_variables];
  904. if(w.weight(aux)>=0)
  905. for(short i=0;i<_number_of_variables;i++)
  906. exponent_vector[i]=aux[i];
  907. else
  908. for(short i=0;i<_number_of_variables;i++)
  909. exponent_vector[i]=-aux[i];
  910. delete[] aux;
  911. #ifdef SUPPORT_DRIVEN_METHODS
  912. // Recompute head and tail.
  913. // Normally, this routine is only called for binomials that do not involve
  914. // the variables to eliminate. But if SUPPORT_VARIABLES_LAST is enabled,
  915. // the support changes in spite of this. Therefore, the support is
  916. // recomputed... For the same reasons as mentionned in the preceeding
  917. // routine, the existing support information is not used.
  918. head_support=0;
  919. tail_support=0;
  920. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  921. if(size_of_support_vectors>_number_of_variables)
  922. size_of_support_vectors=_number_of_variables;
  923. #ifdef SUPPORT_VARIABLES_FIRST
  924. for(short i=0;i<size_of_support_vectors;i++)
  925. {
  926. Integer actual_entry=exponent_vector[i];
  927. if(actual_entry>0)
  928. head_support|=(1<<i);
  929. else
  930. if(actual_entry[i]<0)
  931. tail_support|=(1<<i);
  932. }
  933. #endif // SUPPORT_VARIABLES_FIRST
  934. #ifdef SUPPORT_VARIABLES_LAST
  935. for(short i=0;i<size_of_support_vectors;i++)
  936. {
  937. Integer actual_entry=exponent_vector[_number_of_variables-1-i];
  938. if(actual_entry>0)
  939. head_support|=(1<<i);
  940. else
  941. if(actual_entry<0)
  942. tail_support|=(1<<i);
  943. }
  944. #endif // SUPPORT_VARIABLES_LAST
  945. #endif // SUPPORT_DRIVEN_METHODS
  946. return TRUE;
  947. }
  948. BOOLEAN binomial::drop_last_weighted_variable(const term_ordering& w)
  949. {
  950. _number_of_variables--;
  951. // dangerous!!
  952. // copy components of interest to save memory
  953. // the leading term has to be recomputed!!
  954. Integer *aux=exponent_vector;
  955. exponent_vector=new Integer[_number_of_variables];
  956. short last_weighted_variable=w.number_of_weighted_variables()-1;
  957. aux[last_weighted_variable]=0;
  958. // set last component to zero, so it cannot influence the weight
  959. if(w.weight(aux)>=0)
  960. {
  961. for(short i=0;i<last_weighted_variable;i++)
  962. exponent_vector[i]=aux[i];
  963. for(short i=last_weighted_variable;i<_number_of_variables;i++)
  964. exponent_vector[i]=aux[i+1];
  965. }
  966. else
  967. {
  968. for(short i=0;i<last_weighted_variable;i++)
  969. exponent_vector[i]=-aux[i];
  970. for(short i=last_weighted_variable;i<_number_of_variables;i++)
  971. exponent_vector[i]=-aux[i+1];
  972. }
  973. delete[] aux;
  974. #ifdef SUPPORT_DRIVEN_METHODS
  975. // Recompute head and tail.
  976. // Normally, this routine is only called for binomials that do not involve
  977. // the variable to be dropped. But if SUPPORT_VARIABLES_LAST is enabled,
  978. // the support changes in spite of this. Therefore, the support is
  979. // recomputed... For the same reasons as mentionned in the preceeding
  980. // routines, the existing support information is not used.
  981. head_support=0;
  982. tail_support=0;
  983. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  984. if(size_of_support_vectors>_number_of_variables)
  985. size_of_support_vectors=_number_of_variables;
  986. #ifdef SUPPORT_VARIABLES_FIRST
  987. for(short i=0;i<size_of_support_vectors;i++)
  988. {
  989. Integer actual_entry=exponent_vector[i];
  990. if(actual_entry>0)
  991. head_support|=(1<<i);
  992. else
  993. if(actual_entry<0)
  994. tail_support|=(1<<i);
  995. }
  996. #endif // SUPPORT_VARIABLES_FIRST
  997. #ifdef SUPPORT_VARIABLES_LAST
  998. for(short i=0;i<size_of_support_vectors;i++)
  999. {
  1000. Integer actual_entry=exponent_vector[_number_of_variables-1-i];
  1001. if(actual_entry>0)
  1002. head_support|=(1<<i);
  1003. else
  1004. if(actual_entry<0)
  1005. tail_support|=(1<<i);
  1006. }
  1007. #endif // SUPPORT_VARIABLES_LAST
  1008. #endif // SUPPORT_DRIVEN_METHODS
  1009. return TRUE;
  1010. }
  1011. int binomial::adapt_to_term_ordering(const term_ordering& w)
  1012. {
  1013. if(w.compare_to_zero(exponent_vector)<0)
  1014. {
  1015. // then exchange head and tail
  1016. for(short i=0;i<_number_of_variables;i++)
  1017. exponent_vector[i]*=(-1);
  1018. #ifdef SUPPORT_DRIVEN_METHODS
  1019. unsigned long swap=head_support;
  1020. head_support=tail_support;
  1021. tail_support=swap;
  1022. #endif
  1023. return -1;
  1024. // binomial changed
  1025. }
  1026. else
  1027. return 1;
  1028. // binomial unchanged
  1029. }
  1030. binomial& binomial::swap_variables(const short& i, const short& j)
  1031. {
  1032. #ifdef SUPPORT_DRIVEN_METHODS
  1033. // First adjust head_support and tail_support.
  1034. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  1035. if(size_of_support_vectors>_number_of_variables)
  1036. size_of_support_vectors=_number_of_variables;
  1037. #ifdef SUPPORT_VARIABLES_FIRST
  1038. if(i<size_of_support_vectors)
  1039. // else i is no support variable
  1040. {
  1041. if(exponent_vector[j]>0)
  1042. // bit i will be 1 in the new head_support, 0 in the new tail_support
  1043. {
  1044. head_support|=(1<<i);
  1045. // bit i is set to 1
  1046. tail_support&=~(1<<i);
  1047. // bit i is set to 0
  1048. // (in the complement ~(1<<i) all bits are 1 except from bit i)
  1049. }
  1050. if(exponent_vector[j]==0)
  1051. // bit i will be 0 in the new head_support, 0 in the new tail_support
  1052. {
  1053. head_support&=~(1<<i);
  1054. // bit i is set to 0
  1055. tail_support&=~(1<<i);
  1056. // bit i is set to 0
  1057. }
  1058. if(exponent_vector[j]<0)
  1059. // bit i will be 0 in the new head_support, 1 in the new tail_support
  1060. {
  1061. head_support&=~(1<<i);
  1062. // bit i is set to 0
  1063. tail_support|=(1<<i);
  1064. // bit i is set to 1
  1065. }
  1066. }
  1067. if(j<size_of_support_vectors)
  1068. // else j is no support variable
  1069. {
  1070. if(exponent_vector[i]>0)
  1071. // bit j will be 1 in the new head_support, 0 in the new tail_support
  1072. {
  1073. head_support|=(1<<j);
  1074. // bit j is set to 1
  1075. tail_support&=~(1<<j);
  1076. // bit j is set to 0
  1077. // (in the complement ~(1<<j) all bits are 1 except from bit j)
  1078. }
  1079. if(exponent_vector[i]==0)
  1080. // bit j will be 0 in the new head_support, 0 in the new tail_support
  1081. {
  1082. head_support&=~(1<<j);
  1083. // bit j is set to 0
  1084. tail_support&=~(1<<j);
  1085. // bit j is set to 0
  1086. }
  1087. if(exponent_vector[i]<0)
  1088. // bit j will be 0 in the new head_support, 1 in the new tail_support
  1089. {
  1090. head_support&=~(1<<j);
  1091. // bit j is set to 0
  1092. tail_support|=(1<<j);
  1093. // bit j is set to 1
  1094. }
  1095. }
  1096. #endif // SUPPORT_VARIABLES_FIRST
  1097. #ifdef SUPPORT_VARIABLES_LAST
  1098. // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
  1099. // corresponds to exponent_vector[_number_of_variables-1-k],
  1100. // hence bit _number_of_variables-1-i to exponent_vector[i].
  1101. if(i>=_number_of_variables-size_of_support_vectors)
  1102. // else i is no support variable
  1103. {
  1104. if(exponent_vector[j]>0)
  1105. // bit _number_of_variables-1-i will be 1 in the new head_support,
  1106. // 0 in the new tail_support
  1107. {
  1108. short k=_number_of_variables-1-i;
  1109. head_support|=(1<<k);
  1110. // bit _number_of_variables-1-i is set to 1
  1111. tail_support&=~(1<<k);
  1112. // bit _number_of_variables-1-i is set to 0
  1113. // (in the complement ~(1<<(_number_of_variables-1-i)) all bits are 1
  1114. // except from bit _number_of_variables-1-i)
  1115. }
  1116. if(exponent_vector[j]==0)
  1117. // bit _number_of_variables-1-i will be 0 in the new head_support,
  1118. // 0 in the new tail_support
  1119. {
  1120. short k=_number_of_variables-1-i;
  1121. head_support&=~(1<<k);
  1122. // bit _number_of_variables-1-i is set to 0
  1123. tail_support&=~(1<<k);
  1124. // bit _number_of_variables-1-i is set to 0
  1125. }
  1126. if(exponent_vector[j]<0)
  1127. // bit _number_of_variables-1-i will be 0 in the new head_support,
  1128. // 1 in the new tail_support
  1129. {
  1130. short k=_number_of_variables-1-i;
  1131. head_support&=~(1<<k);
  1132. // bit _number_of_variables-1-i is set to 0
  1133. tail_support|=(1<<k);
  1134. // bit _number_of_variables-1-i is set to 1
  1135. }
  1136. }
  1137. if(j>=_number_of_variables-size_of_support_vectors)
  1138. // else j is no support variable
  1139. {
  1140. if(exponent_vector[i]>0)
  1141. // bit _number_of_variables-1-j will be 1 in the new head_support,
  1142. // 0 in the new tail_support
  1143. {
  1144. short k=_number_of_variables-1-j;
  1145. head_support|=(1<<k);
  1146. // bit _number_of_variables-1-j is set to 1
  1147. tail_support&=~(1<<k);
  1148. // bit _number_of_variables-1-j is set to 0
  1149. // (in the complement ~(1<<(_number_of_variables-1-j)) all bits are 1
  1150. // except from bit _number_of_variables-1-j)
  1151. }
  1152. if(exponent_vector[i]==0)
  1153. // bit _number_of_variables-1-j will be 0 in the new head_support,
  1154. // 0 in the new tail_support
  1155. {
  1156. short k=_number_of_variables-1-j;
  1157. head_support&=~(1<<k);
  1158. // bit _number_of_variables-1-j is set to 0
  1159. tail_support&=~(1<<k);
  1160. // bit _number_of_variables-1-j is set to 0
  1161. }
  1162. if(exponent_vector[i]<0)
  1163. // bit _number_of_variables-1-j will be 0 in the new head_support,
  1164. // 1 in the new tail_support
  1165. {
  1166. short k=_number_of_variables-1-j;
  1167. head_support&=~(1<<k);
  1168. // bit _number_of_variables-1-j is set to 0
  1169. tail_support|=(1<<k);
  1170. // bit _number_of_variables-1-j is set to 1
  1171. }
  1172. }
  1173. #endif // SUPPORT_VARIABLES_LAST
  1174. #endif // SUPPORT_DRIVEN_METHODS
  1175. // Now swap the components.
  1176. Integer swap=exponent_vector[j];
  1177. exponent_vector[j]=exponent_vector[i];
  1178. exponent_vector[i]=swap;
  1179. return *this;
  1180. }
  1181. binomial& binomial::flip_variable(const short& i)
  1182. {
  1183. if(exponent_vector[i]==0)
  1184. // binomial does not involve variable to flip
  1185. return *this;
  1186. #ifdef SUPPORT_DRIVEN_METHODS
  1187. // First adjust head_support and tail_support.
  1188. short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
  1189. if(size_of_support_vectors>_number_of_variables)
  1190. size_of_support_vectors=_number_of_variables;
  1191. #ifdef SUPPORT_VARIABLES_FIRST
  1192. if(i<size_of_support_vectors)
  1193. // else i is no support variable
  1194. {
  1195. if(exponent_vector[i]>0)
  1196. // variable i will be moved from head to tail
  1197. {
  1198. head_support&=~(1<<i);
  1199. // bit i is set to 0
  1200. tail_support|=(1<<i);
  1201. // bit i is set to 1
  1202. }
  1203. else
  1204. // variable i will be moved from tail to head
  1205. // remember that exponent_vector[i]!=0
  1206. {
  1207. tail_support&=~(1<<i);
  1208. // bit i is set to 0
  1209. head_support|=(1<<i);
  1210. // bit i is set to 1
  1211. }
  1212. }
  1213. #endif // SUPPORT_VARIABLES_FIRST
  1214. #ifdef SUPPORT_VARIABLES_LAST
  1215. // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
  1216. // corresponds to exponent_vector[_number_of_variables-1-k],
  1217. // hence bit _number_of_variables-1-i to exponent_vector[i].
  1218. if(i>=_number_of_variables-size_of_support_vectors)
  1219. // else i is no support variable
  1220. {
  1221. if(exponent_vector[i]>0)
  1222. // variable i will be moved from head to tail
  1223. {
  1224. short k=_number_of_variables-1-i;
  1225. head_support&=~(1<<k);
  1226. // bit _number_of_variables-1-i is set to 0
  1227. tail_support|=(1<<k);
  1228. // bit _number_of_variables-1-i is set to 1
  1229. }
  1230. else
  1231. // variable i will be moved from tail to head
  1232. {
  1233. short k=_number_of_variables-1-i;
  1234. tail_support&=~(1<<k);
  1235. // bit _number_of_variables-1-i is set to 0
  1236. head_support|=(1<<k);
  1237. // bit _number_of_variables-1-i is set to 1
  1238. }
  1239. }
  1240. #endif // SUPPORT_VARIABLES_LAST
  1241. #endif // SUPPORT_DRIVEN_METHODS
  1242. // Now flip the variable.
  1243. exponent_vector[i]*=-1;
  1244. }
  1245. ////////////////////////// output /////////////////////////////////////////
  1246. void binomial::print() const
  1247. {
  1248. printf("(");
  1249. for(short i=0;i<_number_of_variables-1;i++)
  1250. printf("%6d,",exponent_vector[i]);
  1251. printf("%6d)\n",exponent_vector[_number_of_variables-1]);
  1252. }
  1253. void binomial::print_all() const
  1254. {
  1255. print();
  1256. #ifdef SUPPORT_DRIVEN_METHODS
  1257. printf("head: %ld, tail %ld\n",head_support,tail_support);
  1258. #endif // SUPPORT_DRIVEN_METHODS
  1259. }
  1260. void binomial::print(FILE* output) const
  1261. {
  1262. fprintf(output,"(");
  1263. for(short i=0;i<_number_of_variables-1;i++)
  1264. fprintf(output,"%6d,",exponent_vector[i]);
  1265. fprintf(output,"%6d)\n",exponent_vector[_number_of_variables-1]);
  1266. }
  1267. void binomial::print_all(FILE* output) const
  1268. {
  1269. print(output);
  1270. #ifdef SUPPORT_DRIVEN_METHODS
  1271. fprintf(output,"head: %ld, tail %ld\n",head_support,tail_support);
  1272. #endif // SUPPORT_DRIVEN_METHODS
  1273. }
  1274. void binomial::print(ofstream& output) const
  1275. {
  1276. output<<"(";
  1277. for(short i=0;i<_number_of_variables-1;i++)
  1278. output<<setw(6)<<exponent_vector[i]<<",";
  1279. output<<setw(6)<<exponent_vector[_number_of_variables-1]<<")"<<endl;
  1280. }
  1281. void binomial::print_all(ofstream& output) const
  1282. {
  1283. print(output);
  1284. #ifdef SUPPORT_DRIVEN_METHODS
  1285. output<<"head: "<<setw(16)<<head_support<<", tail: "<<setw(16)
  1286. <<tail_support<<endl;
  1287. #endif // SUPPORT_DRIVEN_METHODS
  1288. }
  1289. void binomial::format_print(ofstream& output) const
  1290. {
  1291. for(short i=0;i<_number_of_variables;i++)
  1292. output<<setw(6)<<exponent_vector[i];
  1293. output<<endl;
  1294. }
  1295. #endif // BINOMIAL_CC