/IntegerProgramming/term_ordering.cc

https://github.com/burcin/Singular · C++ · 1457 lines · 1034 code · 342 blank · 81 comment · 266 complexity · dbec150a09e21765db5208ba33732756 MD5 · raw file

  1. // term_ordering.cc
  2. // implementation of class term ordering
  3. #ifndef TERM_ORDERING_CC
  4. #define TERM_ORDERING_CC
  5. #include "binomial__term_ordering.h"
  6. /////////////// constructors and destructor ///////////////////////////////////
  7. term_ordering::term_ordering(const BOOLEAN& _homogeneous)
  8. :homogeneous(_homogeneous)
  9. {
  10. weight_vector=NULL;
  11. weighted_block_size=0;
  12. elimination_block_size=0;
  13. }
  14. term_ordering::term_ordering(const short& number_of_weighted_variables,
  15. const float* weights,
  16. const short& _weighted_ordering,
  17. const BOOLEAN& _homogeneous)
  18. :weighted_block_size(number_of_weighted_variables),
  19. homogeneous(_homogeneous)
  20. {
  21. if((_weighted_ordering<4) || (_weighted_ordering>7))
  22. // unknown ordering refining the weight, set "error flag"
  23. weighted_block_size=-1;
  24. else
  25. weighted_ordering=_weighted_ordering;
  26. if(weighted_block_size<0)
  27. // argument out of range, set "error flag"
  28. weighted_block_size=-1;
  29. if(weighted_block_size>0)
  30. {
  31. weight_vector=new float[weighted_block_size];
  32. BOOLEAN negative_weight=FALSE;
  33. BOOLEAN zero_weight=FALSE;
  34. // for checking the input
  35. for(short i=0;i<weighted_block_size;i++)
  36. {
  37. weight_vector[i]=weights[i];
  38. // initialize weight vector with weights
  39. if(weight_vector[i]<0)
  40. negative_weight=TRUE;
  41. if(weight_vector[i]==0)
  42. zero_weight=TRUE;
  43. }
  44. if(negative_weight==TRUE)
  45. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
  46. "const float*, const short&):\nWeight vector with negative components"
  47. " does not define a well ordering"<<endl;
  48. if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
  49. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
  50. "const float*, const short&):\nZero weights refined by a reverse "
  51. "lexicographical ordering do not define a well ordering"<<endl;
  52. }
  53. else
  54. if(weighted_block_size<0)
  55. cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
  56. "const float*, const short&):\nBad input in term ordering "
  57. "constructor"<<endl;
  58. elimination_block_size=0;
  59. }
  60. term_ordering::term_ordering(const short& number_of_weighted_variables,
  61. const float* weights,
  62. const short& _weighted_ordering,
  63. const short& number_of_elimination_variables,
  64. const short& _elimination_ordering,
  65. const BOOLEAN& _homogeneous)
  66. :weighted_block_size(number_of_weighted_variables),
  67. elimination_block_size(number_of_elimination_variables),
  68. homogeneous(_homogeneous)
  69. {
  70. if((_weighted_ordering<4) || (_weighted_ordering>7))
  71. // unknown ordering refining the weight, set "error flag"
  72. weighted_block_size=-1;
  73. else
  74. weighted_ordering=_weighted_ordering;
  75. if((_elimination_ordering<1) || (_elimination_ordering>3))
  76. // unknown ordering on the elimination variables, set "error flag"
  77. weighted_block_size=-1;
  78. else
  79. elimination_ordering=_elimination_ordering;
  80. if((weighted_block_size<0)||(elimination_block_size<0))
  81. // argument out of range, set "error flag"
  82. weighted_block_size=-1;
  83. if(weighted_block_size>0)
  84. {
  85. weight_vector=new float[weighted_block_size];
  86. BOOLEAN negative_weight=FALSE;
  87. BOOLEAN zero_weight=FALSE;
  88. // for checking the input
  89. for(short i=0;i<weighted_block_size;i++)
  90. {
  91. weight_vector[i]=weights[i];
  92. // initialize weight vector with weights
  93. if(weight_vector[i]<0)
  94. negative_weight=TRUE;
  95. if(weight_vector[i]==0)
  96. zero_weight=TRUE;
  97. }
  98. if(negative_weight==TRUE)
  99. cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
  100. "const float*, const short&, const short&, const short&):\n"
  101. "Weight vector with negative components does not define "
  102. "a well ordering"<<endl;
  103. if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
  104. cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
  105. "const float*, const short&, const short&, const short&):\n"
  106. "Zero weights refined by a reverse lexicographical "
  107. "ordering do not define a well ordering"<<endl;
  108. }
  109. else
  110. if(weighted_block_size<0)
  111. cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
  112. "const float*, const short&, const short&, const short&):\n"
  113. "Bad input in term ordering constructor"<<endl;
  114. }
  115. term_ordering::term_ordering(ifstream& input, const short& _weighted_ordering,
  116. const BOOLEAN& _homogeneous)
  117. :homogeneous(_homogeneous)
  118. {
  119. if((_weighted_ordering<4) || (_weighted_ordering>7))
  120. // unknown ordering refining the weight, set "error flag"
  121. weighted_block_size=-1;
  122. else
  123. weighted_ordering=_weighted_ordering;
  124. input>>weighted_block_size;
  125. if(!input)
  126. // input failure, set "error flag"
  127. weighted_block_size=-2;
  128. if(weighted_block_size<0)
  129. // input out of range, set error flag
  130. weighted_block_size=-1;
  131. if(weighted_block_size>0)
  132. {
  133. weight_vector=new float[weighted_block_size];
  134. BOOLEAN negative_weight=FALSE;
  135. BOOLEAN zero_weight=FALSE;
  136. // for checking the input
  137. for(short i=0;i<weighted_block_size;i++)
  138. {
  139. input>>weight_vector[i];
  140. if(!input)
  141. // input failure, set "error flag"
  142. {
  143. weighted_block_size=-2;
  144. cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const "
  145. "short&):\nInput failed reading term ordering from ofstream"<<endl;
  146. break;
  147. }
  148. if(weight_vector[i]<0)
  149. negative_weight=TRUE;
  150. if(weight_vector[i]==0)
  151. zero_weight=TRUE;
  152. }
  153. if(negative_weight==TRUE)
  154. cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
  155. ":\nWeight vector with negative components does not define "
  156. "a well ordering"<<endl;
  157. if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
  158. cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
  159. ":\nZero weights refined by a reverse lexicographical "
  160. "ordering do not define a well ordering"<<endl;
  161. }
  162. else
  163. if(weighted_block_size<0)
  164. cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
  165. ":\nBuilding a term ordering from a corrupt one"<<endl;
  166. elimination_block_size=0;
  167. }
  168. term_ordering::term_ordering(const short& n, ifstream& input,
  169. const short& _weighted_ordering,
  170. const BOOLEAN& _homogeneous)
  171. :homogeneous(_homogeneous)
  172. {
  173. if((_weighted_ordering<4) || (_weighted_ordering>7))
  174. // unknown ordering refining the weight, set "error flag"
  175. weighted_block_size=-1;
  176. else
  177. weighted_ordering=_weighted_ordering;
  178. if(n<0)
  179. // input out of range, set error flag
  180. weighted_block_size=-1;
  181. else
  182. weighted_block_size=n;
  183. if(weighted_block_size>0)
  184. {
  185. weight_vector=new float[weighted_block_size];
  186. BOOLEAN negative_weight=FALSE;
  187. BOOLEAN zero_weight=FALSE;
  188. // for checking the input
  189. for(short i=0;i<weighted_block_size;i++)
  190. {
  191. input>>weight_vector[i];
  192. if(!input)
  193. // input failure, set "error flag"
  194. {
  195. weighted_block_size=-2;
  196. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
  197. "ifstream&, const short&):\nInput failed reading term ordering "
  198. "from ofstream"<<endl;
  199. break;
  200. }
  201. if(weight_vector[i]<0)
  202. {
  203. cout << "neg found at i="<<i<<":" <<weight_vector[i] <<"\n";
  204. negative_weight=TRUE;
  205. }
  206. if(weight_vector[i]==0)
  207. zero_weight=TRUE;
  208. }
  209. if(negative_weight==TRUE)
  210. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
  211. "const short&):\nWeight vector with negative components does not "
  212. "define a well ordering"<<endl;
  213. if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
  214. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
  215. "const short&):\nZero weights refined by a reverse lexicographical "
  216. "ordering do not define a well ordering"<<endl;
  217. }
  218. else
  219. if(weighted_block_size<0)
  220. cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
  221. "const short&):\n Building a term ordering from a corrupt one"<<endl;
  222. elimination_block_size=0;
  223. }
  224. term_ordering::term_ordering(const term_ordering& w)
  225. :weighted_block_size(w.weighted_block_size),
  226. weighted_ordering(w.weighted_ordering),
  227. elimination_block_size(w.elimination_block_size),
  228. elimination_ordering(w.elimination_ordering),
  229. homogeneous(w.homogeneous)
  230. {
  231. if(weighted_block_size>0)
  232. {
  233. weight_vector=new float[weighted_block_size];
  234. for(short i=0;i<weighted_block_size;i++)
  235. weight_vector[i]=w.weight_vector[i];
  236. }
  237. else
  238. if(weighted_block_size<0)
  239. cerr<<"\nWARNING: term_ordering::term_ordering(const term_ordering&):\n"
  240. "Building a term ordering from a corrupt one"<<endl;
  241. }
  242. term_ordering::~term_ordering()
  243. {
  244. if(weighted_block_size>0)
  245. delete[] weight_vector;
  246. }
  247. /////////////// object properties /////////////////////////////////////////
  248. short term_ordering::number_of_weighted_variables() const
  249. {
  250. return weighted_block_size;
  251. }
  252. short term_ordering::weight_refinement() const
  253. {
  254. return weighted_ordering;
  255. }
  256. short term_ordering::number_of_elimination_variables() const
  257. {
  258. return elimination_block_size;
  259. }
  260. short term_ordering::elimination_refinement() const
  261. {
  262. return elimination_ordering;
  263. }
  264. BOOLEAN term_ordering::is_homogeneous() const
  265. {
  266. return homogeneous;
  267. }
  268. short term_ordering::error_status() const
  269. {
  270. if(weighted_block_size<0)
  271. return weighted_block_size;
  272. return 0;
  273. }
  274. BOOLEAN term_ordering::is_nonnegative() const
  275. {
  276. for(int i=0;i<weighted_block_size;i++)
  277. if(weight_vector[i]<0)
  278. return FALSE;
  279. return TRUE;
  280. }
  281. BOOLEAN term_ordering::is_positive() const
  282. {
  283. for(int i=0;i<weighted_block_size;i++)
  284. if(weight_vector[i]<=0)
  285. return FALSE;
  286. return TRUE;
  287. }
  288. /////////////// frequently used comparison functions //////////////////////
  289. double term_ordering::weight(const Integer* v) const
  290. {
  291. double result=0;
  292. for(short i=0;i<weighted_block_size;i++)
  293. result+=(weight_vector[i]*v[i]);
  294. return(result);
  295. }
  296. short term_ordering::compare_to_zero(const Integer* v) const
  297. {
  298. unsigned short last_index=weighted_block_size+elimination_block_size;
  299. double w=0;
  300. // First check the elimination variables.
  301. if(elimination_block_size>0)
  302. switch(elimination_ordering)
  303. {
  304. case LEX:
  305. for(short i=weighted_block_size;i<last_index;i++)
  306. {
  307. Integer actual_component=v[i];
  308. if(actual_component>0)
  309. return 1;
  310. if(actual_component<0)
  311. return -1;
  312. }
  313. break;
  314. case DEG_LEX:
  315. // compute the degree
  316. for(short i=weighted_block_size;i<last_index;i++)
  317. w+=v[i];
  318. if(w>0)
  319. return 1;
  320. if(w<0)
  321. return -1;
  322. // if the degree is zero:
  323. // tie breaking with the lexicographical ordering
  324. for(short i=weighted_block_size;i<last_index;i++)
  325. {
  326. Integer actual_component=v[i];
  327. if(actual_component>0)
  328. return 1;
  329. if(actual_component<0)
  330. return -1;
  331. }
  332. break;
  333. case DEG_REV_LEX:
  334. //compute the degree
  335. for(short i=weighted_block_size;i<last_index;i++)
  336. w+=v[i];
  337. if(w>0)
  338. return 1;
  339. if(w<0)
  340. return -1;
  341. // if the degree is zero:
  342. // tie breaking with the reverse lexicographical ordering
  343. for(short i=last_index-1;i>=weighted_block_size;i--)
  344. {
  345. Integer actual_component=v[i];
  346. if(actual_component<0)
  347. return 1;
  348. if(actual_component>0)
  349. return -1;
  350. }
  351. }
  352. // When reaching this line, the vector components corresponding to
  353. // elimination variables are all zero.
  354. // Compute the weight.
  355. // If the term ordering is a homogeneous one, this is superfluous.
  356. if(!homogeneous)
  357. {
  358. w=weight(v);
  359. if(w>0)
  360. return 1;
  361. if(w<0)
  362. return -1;
  363. }
  364. // When reaching this line, the weight of the vector components corresponding
  365. // to weighted variables is zero.
  366. // Tie breaking with the term ordering refining the weight.
  367. switch(weighted_ordering)
  368. {
  369. case W_LEX:
  370. for(short i=0;i<weighted_block_size;i++)
  371. {
  372. Integer actual_component=v[i];
  373. if(actual_component>0)
  374. return 1;
  375. if(actual_component<0)
  376. return -1;
  377. }
  378. break;
  379. case W_REV_LEX:
  380. for(short i=weighted_block_size-1;i>=0;i--)
  381. {
  382. Integer actual_component=v[i];
  383. if(actual_component<0)
  384. return 1;
  385. if(actual_component>0)
  386. return -1;
  387. }
  388. break;
  389. case W_DEG_LEX:
  390. for(short i=0;i<weighted_block_size;i++)
  391. w+=v[i];
  392. if(w>0)
  393. return 1;
  394. if(w<0)
  395. return -1;
  396. for(short i=0;i<weighted_block_size;i++)
  397. {
  398. Integer actual_component=v[i];
  399. if(actual_component>0)
  400. return 1;
  401. if(actual_component<0)
  402. return -1;
  403. }
  404. break;
  405. case W_DEG_REV_LEX:
  406. for(short i=0;i<weighted_block_size;i++)
  407. w+=v[i];
  408. if(w>0)
  409. return 1;
  410. if(w<0)
  411. return -1;
  412. for(short i=weighted_block_size-1;i>=0;i--)
  413. {
  414. Integer actual_component=v[i];
  415. if(actual_component<0)
  416. return 1;
  417. if(actual_component>0)
  418. return -1;
  419. }
  420. }
  421. // When reaching this line, the argument vector is the zero vector.
  422. return 0;
  423. }
  424. short term_ordering::compare(const binomial& bin1, const binomial& bin2) const
  425. {
  426. unsigned short last_index=weighted_block_size+elimination_block_size;
  427. double w1=0;
  428. double w2=0;
  429. Integer* v1=bin1.exponent_vector;
  430. Integer* v2=bin2.exponent_vector;
  431. // First compare the heads of the input binomials.
  432. // The code is analogous to the routine compare_to_zero(...), except
  433. // from the fact that we must consider the sign of the vector components.
  434. // First check the elimination variables.
  435. if(elimination_block_size>0)
  436. switch(elimination_ordering)
  437. {
  438. case LEX:
  439. for(short i=weighted_block_size;i<last_index;i++)
  440. {
  441. Integer comp1=v1[i];
  442. Integer comp2=v2[i];
  443. if(comp1>0 || comp2>0)
  444. {
  445. if(comp1>comp2)
  446. return 1;
  447. if(comp1<comp2)
  448. return -1;
  449. }
  450. }
  451. break;
  452. case DEG_LEX:
  453. // compute the degree of the heads in the elimination variables
  454. for(short i=weighted_block_size;i<last_index;i++)
  455. {
  456. Integer comp1=v1[i];
  457. Integer comp2=v2[i];
  458. if(comp1>0)
  459. w1+=comp1;
  460. if(comp2>0)
  461. w2+=comp2;
  462. }
  463. if(w1>w2)
  464. return 1;
  465. if(w1<w2)
  466. return -1;
  467. // if the degree is equal:
  468. // tie breaking with the lexicographical ordering
  469. for(short i=weighted_block_size;i<last_index;i++)
  470. {
  471. Integer comp1=v1[i];
  472. Integer comp2=v2[i];
  473. if(comp1>0 || comp2>0)
  474. {
  475. if(comp1>comp2)
  476. return 1;
  477. if(comp1<comp2)
  478. return -1;
  479. }
  480. }
  481. break;
  482. case DEG_REV_LEX:
  483. //compute the degree of the heads in the elimination variables
  484. for(short i=weighted_block_size;i<last_index;i++)
  485. {
  486. Integer comp1=v1[i];
  487. Integer comp2=v2[i];
  488. if(comp1>0)
  489. w1+=comp1;
  490. if(comp2>0)
  491. w2+=comp2;
  492. }
  493. if(w1>w2)
  494. return 1;
  495. if(w1<w2)
  496. return -1;
  497. // if the degree is equal:
  498. // tie breaking with the reverse lexicographical ordering
  499. for(short i=last_index-1;i>=weighted_block_size;i--)
  500. {
  501. Integer comp1=v1[i];
  502. Integer comp2=v2[i];
  503. if(comp1>0 || comp2>0)
  504. {
  505. if(comp1<comp2)
  506. return 1;
  507. if(comp1>comp2)
  508. return -1;
  509. }
  510. }
  511. }
  512. // When reaching this line, the heads are equal in the elimination
  513. // variables.
  514. // Compute the weight of the heads.
  515. w1=0;
  516. for(short i=0;i<weighted_block_size;i++)
  517. {
  518. Integer actual_component=v1[i];
  519. if(actual_component>0)
  520. w1+=actual_component*weight_vector[i];
  521. }
  522. w2=0;
  523. for(short i=0;i<weighted_block_size;i++)
  524. {
  525. Integer actual_component=v2[i];
  526. if(actual_component>0)
  527. w2+=actual_component*weight_vector[i];
  528. }
  529. if(w1>w2)
  530. return 1;
  531. if(w1<w2)
  532. return -1;
  533. // When reaching this line, the weight of the heads in the weighted
  534. // variables are equal.
  535. // Tie breaking with the term ordering refining the weight.
  536. switch(weighted_ordering)
  537. {
  538. case W_LEX:
  539. for(short i=0;i<weighted_block_size;i++)
  540. {
  541. Integer comp1=v1[i];
  542. Integer comp2=v2[i];
  543. if(comp1>0 || comp2>0)
  544. {
  545. if(comp1>comp2)
  546. return 1;
  547. if(comp1<comp2)
  548. return -1;
  549. }
  550. }
  551. break;
  552. case W_REV_LEX:
  553. for(short i=weighted_block_size-1;i>=0;i--)
  554. {
  555. Integer comp1=v1[i];
  556. Integer comp2=v2[i];
  557. if(comp1>0 || comp2>0)
  558. {
  559. if(comp1<comp2)
  560. return 1;
  561. if(comp1>comp2)
  562. return -1;
  563. }
  564. }
  565. break;
  566. case W_DEG_LEX:
  567. for(short i=0;i<weighted_block_size;i++)
  568. {
  569. Integer comp1=v1[i];
  570. Integer comp2=v2[i];
  571. if(comp1>0)
  572. w1+=comp1;
  573. if(comp2>0)
  574. w2+=comp2;
  575. }
  576. if(w1>w2)
  577. return 1;
  578. if(w1<w2)
  579. return -1;
  580. for(short i=0;i<weighted_block_size;i++)
  581. {
  582. Integer comp1=v1[i];
  583. Integer comp2=v2[i];
  584. if(comp1>0 || comp2>0)
  585. {
  586. if(comp1>comp2)
  587. return 1;
  588. if(comp1<comp2)
  589. return -1;
  590. }
  591. }
  592. break;
  593. case W_DEG_REV_LEX:
  594. for(short i=0;i<weighted_block_size;i++)
  595. {
  596. Integer comp1=v1[i];
  597. Integer comp2=v2[i];
  598. if(comp1>0)
  599. w1+=comp1;
  600. if(comp2>0)
  601. w2+=comp2;
  602. }
  603. if(w1>w2)
  604. return 1;
  605. if(w1<w2)
  606. return -1;
  607. for(short i=weighted_block_size-1;i>=0;i--)
  608. {
  609. Integer comp1=v1[i];
  610. Integer comp2=v2[i];
  611. if(comp1>0 || comp2>0)
  612. {
  613. if(comp1<comp2)
  614. return 1;
  615. if(comp1>comp2)
  616. return -1;
  617. }
  618. }
  619. }
  620. // When reaching this line, the heads of the binomials are equal.
  621. // Now we decide by the tails.
  622. // This part of the code could also be omitted in the current context:
  623. // The compare(...)-function is only called when dealing with ordered
  624. // lists. This is done in two cases:
  625. // - When computing with ordered S-pair lists, it doesn't really matter
  626. // if such similar binomials are in the right order.
  627. // - When outputting a reduced Groebner basis, it cannot happen that two
  628. // heads are equal.
  629. w1=0;
  630. w2=0;
  631. // First check the elimination variables.
  632. if(elimination_block_size>0)
  633. switch(elimination_ordering)
  634. {
  635. case LEX:
  636. for(short i=weighted_block_size;i<last_index;i++)
  637. {
  638. Integer comp1=-v1[i];
  639. Integer comp2=-v2[i];
  640. if(comp1>0 || comp2>0)
  641. {
  642. if(comp1>comp2)
  643. return 1;
  644. if(comp1<comp2)
  645. return -1;
  646. }
  647. }
  648. break;
  649. case DEG_LEX:
  650. // compute the degree of the tails in the elimination variables
  651. for(short i=weighted_block_size;i<last_index;i++)
  652. {
  653. Integer comp1=-v1[i];
  654. Integer comp2=-v2[i];
  655. if(comp1>0)
  656. w1+=comp1;
  657. if(comp2>0)
  658. w2+=comp2;
  659. }
  660. if(w1>w2)
  661. return 1;
  662. if(w1<w2)
  663. return -1;
  664. // if the degree is equal:
  665. // tie breaking with the lexicographical ordering
  666. for(short i=weighted_block_size;i<last_index;i++)
  667. {
  668. Integer comp1=-v1[i];
  669. Integer comp2=-v2[i];
  670. if(comp1>0 || comp2>0)
  671. {
  672. if(comp1>comp2)
  673. return 1;
  674. if(comp1<comp2)
  675. return -1;
  676. }
  677. }
  678. break;
  679. case DEG_REV_LEX:
  680. // compute the degree of the tails in the elimination variables
  681. for(short i=weighted_block_size;i<last_index;i++)
  682. {
  683. Integer comp1=-v1[i];
  684. Integer comp2=-v2[i];
  685. if(comp1>0)
  686. w1+=comp1;
  687. if(comp2>0)
  688. w2+=comp2;
  689. }
  690. if(w1>w2)
  691. return 1;
  692. if(w1<w2)
  693. return -1;
  694. // if the degree is equal:
  695. // tie breaking with the reverse lexicographical ordering
  696. for(short i=last_index-1;i>=weighted_block_size;i--)
  697. {
  698. Integer comp1=-v1[i];
  699. Integer comp2=-v2[i];
  700. if(comp1>0 || comp2>0)
  701. {
  702. if(comp1<comp2)
  703. return 1;
  704. if(comp1>comp2)
  705. return -1;
  706. }
  707. }
  708. }
  709. // When reaching this line, the tails are equal in the elimination
  710. // variables.
  711. // Compute the weight of the tails.
  712. w1=0;
  713. for(short i=0;i<weighted_block_size;i++)
  714. {
  715. Integer actual_component=-v1[i];
  716. if(actual_component>0)
  717. w1+=actual_component*weight_vector[i];
  718. }
  719. w2=0;
  720. for(short i=0;i<weighted_block_size;i++)
  721. {
  722. Integer actual_component=-v2[i];
  723. if(actual_component>0)
  724. w2+=actual_component*weight_vector[i];
  725. }
  726. if(w1>w2)
  727. return 1;
  728. if(w1<w2)
  729. return -1;
  730. // When reaching this line, the weight of the tails in the weighted
  731. // variables are equal.
  732. // Tie breaking with the term ordering refining the weight.
  733. switch(weighted_ordering)
  734. {
  735. case W_LEX:
  736. for(short i=0;i<weighted_block_size;i++)
  737. {
  738. Integer comp1=-v1[i];
  739. Integer comp2=-v2[i];
  740. if(comp1>0 || comp2>0)
  741. {
  742. if(comp1>comp2)
  743. return 1;
  744. if(comp1<comp2)
  745. return -1;
  746. }
  747. }
  748. break;
  749. case W_REV_LEX:
  750. for(short i=weighted_block_size-1;i>=0;i--)
  751. {
  752. Integer comp1=-v1[i];
  753. Integer comp2=-v2[i];
  754. if(comp1>0 || comp2>0)
  755. {
  756. if(comp1<comp2)
  757. return 1;
  758. if(comp1>comp2)
  759. return -1;
  760. }
  761. }
  762. break;
  763. case W_DEG_LEX:
  764. for(short i=0;i<weighted_block_size;i++)
  765. {
  766. Integer comp1=-v1[i];
  767. Integer comp2=-v2[i];
  768. if(comp1>0)
  769. w1+=comp1;
  770. if(comp2>0)
  771. w2+=comp2;
  772. }
  773. if(w1>w2)
  774. return 1;
  775. if(w1<w2)
  776. return -1;
  777. for(short i=0;i<weighted_block_size;i++)
  778. {
  779. Integer comp1=-v1[i];
  780. Integer comp2=-v2[i];
  781. if(comp1>0 || comp2>0)
  782. {
  783. if(comp1>comp2)
  784. return 1;
  785. if(comp1<comp2)
  786. return -1;
  787. }
  788. }
  789. break;
  790. case W_DEG_REV_LEX:
  791. for(short i=0;i<weighted_block_size;i++)
  792. {
  793. Integer comp1=-v1[i];
  794. Integer comp2=-v2[i];
  795. if(comp1>0)
  796. w1+=comp1;
  797. if(comp2>0)
  798. w2+=comp2;
  799. }
  800. if(w1>w2)
  801. return 1;
  802. if(w1<w2)
  803. return -1;
  804. for(short i=weighted_block_size-1;i>=0;i--)
  805. {
  806. Integer comp1=-v1[i];
  807. Integer comp2=-v2[i];
  808. if(comp1>0 || comp2>0)
  809. {
  810. if(comp1<comp2)
  811. return 1;
  812. if(comp1>comp2)
  813. return -1;
  814. }
  815. }
  816. }
  817. return 0;
  818. }
  819. ///////// operators and routines needed by the IP-algorithms ////////////////
  820. ///////// to manipulate the term ordering ////////////////////////////////
  821. term_ordering& term_ordering::operator=(const term_ordering& w)
  822. {
  823. if(&w==this)
  824. return *this;
  825. if(weighted_block_size>0)
  826. delete[] weight_vector;
  827. weighted_block_size=w.weighted_block_size;
  828. weighted_ordering=w.weighted_ordering;
  829. elimination_block_size=w.elimination_block_size;
  830. elimination_ordering=w.elimination_ordering;
  831. homogeneous=w.homogeneous;
  832. if(weighted_block_size>0)
  833. {
  834. weight_vector=new float[weighted_block_size];
  835. for(short i=0;i<weighted_block_size;i++)
  836. weight_vector[i]=w.weight_vector[i];
  837. }
  838. else
  839. if(weighted_block_size<0)
  840. cerr<<"\nWARNING: term_ordering& term_ordering::"
  841. "operator=(const term_ordering&):\n"
  842. "assignment from corrupt term ordering"<<endl;
  843. return(*this);
  844. }
  845. float term_ordering::operator[](const short& i) const
  846. {
  847. if((i<0) || (i>=weighted_block_size))
  848. {
  849. cerr<<"\nWARNING: float term_ordering::operator[](const short& i):\n"
  850. "access to invalid weight vector component"<<endl;
  851. return FLT_MAX;
  852. }
  853. else
  854. return weight_vector[i];
  855. }
  856. term_ordering& term_ordering::convert_to_weighted_ordering()
  857. {
  858. elimination_block_size=0;
  859. return(*this);
  860. }
  861. term_ordering& term_ordering::convert_to_elimination_ordering
  862. (const short& number_of_elimination_variables,
  863. const short& _elimination_ordering)
  864. {
  865. if((_elimination_ordering<1) || (_elimination_ordering>3))
  866. // unknown ordering on the elimination variables, set "error flag"
  867. weighted_block_size=-1;
  868. else
  869. elimination_ordering=_elimination_ordering;
  870. if(number_of_elimination_variables<0)
  871. // argument out of range, set error flag
  872. weighted_block_size=-1;
  873. else
  874. elimination_block_size=number_of_elimination_variables;
  875. if(weighted_block_size<0)
  876. cerr<<"\nWARNING: term_ordering& term_ordering::"
  877. "convert_to_elimination_ordering(const short&, const short&):\n"
  878. "argument out of range"<<endl;
  879. return(*this);
  880. }
  881. term_ordering& term_ordering::append_weighted_variable(const float& weight)
  882. {
  883. if(weighted_block_size>=0)
  884. {
  885. float *aux=weight_vector;
  886. weight_vector=new float[weighted_block_size+1];
  887. for(short i=0;i<weighted_block_size;i++)
  888. weight_vector[i]=aux[i];
  889. weight_vector[weighted_block_size]=weight;
  890. if(weighted_block_size>0)
  891. delete[] aux;
  892. weighted_block_size++;
  893. }
  894. else
  895. cerr<<"\nWARNING: term_ordering& term_ordering::append_weighted_variable"
  896. "(const float&):\n"
  897. "called for a corrupt term ordering, term ordering not changed"
  898. <<endl;
  899. return(*this);
  900. }
  901. term_ordering& term_ordering::delete_last_weighted_variable()
  902. {
  903. if(weighted_block_size>0)
  904. {
  905. float *aux=weight_vector;
  906. if(weighted_block_size>1)
  907. weight_vector=new float[weighted_block_size-1];
  908. for(short i=0;i<weighted_block_size-1;i++)
  909. weight_vector[i]=aux[i];
  910. weighted_block_size--;
  911. delete[] aux;
  912. }
  913. else
  914. cerr<<"\nWARNING: term_ordering& term_ordering::"
  915. "delete_last_weighted_variable():\n"
  916. "called for a maybe corrupt term ordering without weighted variables,\n"
  917. "term ordering not changed"<<endl;
  918. return(*this);
  919. }
  920. term_ordering& term_ordering::swap_weights(const short& i, const short& j)
  921. {
  922. if((i<0) || (i>=weighted_block_size) || (j<0) || (j>=weighted_block_size))
  923. {
  924. cout<<"\nWARNING: term_ordering& termordering::swap_weights"
  925. "(const short, const short):\nindex out of range"<<endl;
  926. return *this;
  927. }
  928. float swap=weight_vector[j];
  929. weight_vector[j]=weight_vector[i];
  930. weight_vector[i]=swap;
  931. return *this;
  932. }
  933. /////////////////// output ///////////////////////////////////////////////
  934. void term_ordering::print_weight_vector() const
  935. {
  936. if(weighted_block_size<0)
  937. {
  938. printf("\nWARNING: void term_ordering::print_weight_vector():\n"
  939. "cannot print corrupt term ordering\n");
  940. return;
  941. }
  942. printf("(");
  943. for(short i=0;i<weighted_block_size-1;i++)
  944. printf("%6.2f,",weight_vector[i]);
  945. printf("%6.2f)\n",weight_vector[weighted_block_size-1]);
  946. }
  947. void term_ordering::print() const
  948. {
  949. if(weighted_block_size<0)
  950. {
  951. printf("\n\nWARNING: void term_ordering::print():\n"
  952. "cannot print corrupt term ordering\n");
  953. return;
  954. }
  955. printf("\nelimination variables:%4d\n",elimination_block_size);
  956. printf("weighted variables: %4d\n",weighted_block_size);
  957. printf("weight vector:\n");
  958. print_weight_vector();
  959. if(elimination_block_size>0)
  960. {
  961. printf("ordering on elimination variables: ");
  962. switch(elimination_ordering)
  963. {
  964. case LEX:
  965. printf("LEX\n");
  966. break;
  967. case DEG_LEX:
  968. printf("DEG_LEX\n");
  969. break;
  970. case DEG_REV_LEX:
  971. printf("DEG_REV_LEX\n");
  972. break;
  973. }
  974. }
  975. printf("ordering refining the weight: ");
  976. switch(weighted_ordering)
  977. {
  978. case W_LEX:
  979. printf("W_LEX\n\n");
  980. break;
  981. case W_REV_LEX:
  982. printf("W_REV_LEX\n\n");
  983. break;
  984. case W_DEG_LEX:
  985. printf("W_DEG_LEX\n\n");
  986. break;
  987. case W_DEG_REV_LEX:
  988. printf("W_DEG_REV_LEX\n\n");
  989. break;
  990. }
  991. }
  992. void term_ordering::print_weight_vector(FILE* output) const
  993. {
  994. if(weighted_block_size<0)
  995. {
  996. fprintf(output,"\nWARNING: void term_ordering::print_weight_vector(FILE*)"
  997. ":\ncannot print corrupt term ordering\n");
  998. return;
  999. }
  1000. fprintf(output,"(");
  1001. for(short i=0;i<weighted_block_size-1;i++)
  1002. fprintf(output,"%6.2f,",weight_vector[i]);
  1003. fprintf(output,"%6.2f)\n",weight_vector[weighted_block_size-1]);
  1004. }
  1005. void term_ordering::print(FILE* output) const
  1006. {
  1007. if(weighted_block_size<0)
  1008. {
  1009. fprintf(output,"\n\nWARNING: void term_ordering::print(FILE*):\n"
  1010. "cannot print corrupt term ordering\n");
  1011. return;
  1012. }
  1013. fprintf(output,"\nelimination variables:%4d\n",elimination_block_size);
  1014. fprintf(output,"weighted variables: %4d\n",weighted_block_size);
  1015. fprintf(output,"weight_vector:\n");
  1016. print_weight_vector(output);
  1017. if(elimination_block_size>0)
  1018. {
  1019. fprintf(output,"ordering on elimination variables: ");
  1020. switch(elimination_ordering)
  1021. {
  1022. case LEX:
  1023. fprintf(output,"LEX\n");
  1024. break;
  1025. case DEG_LEX:
  1026. fprintf(output,"DEG_LEX\n");
  1027. break;
  1028. case DEG_REV_LEX:
  1029. fprintf(output,"DEG_REV_LEX\n");
  1030. break;
  1031. }
  1032. }
  1033. fprintf(output,"ordering refining the weight: ");
  1034. switch(weighted_ordering)
  1035. {
  1036. case W_LEX:
  1037. fprintf(output,"W_LEX\n\n");
  1038. break;
  1039. case W_REV_LEX:
  1040. fprintf(output,"W_REV_LEX\n\n");
  1041. break;
  1042. case W_DEG_LEX:
  1043. fprintf(output,"W_DEG_LEX\n\n");
  1044. break;
  1045. case W_DEG_REV_LEX:
  1046. fprintf(output,"W_DEG_REV_LEX\n\n");
  1047. break;
  1048. }
  1049. }
  1050. void term_ordering::print_weight_vector(ofstream& output) const
  1051. {
  1052. if(weighted_block_size<0)
  1053. {
  1054. output<<"\nWARNING: void term_ordering::print_weight_vector(ofstream&):\n"
  1055. "cannot print corrupt term ordering"<<endl;
  1056. return;
  1057. }
  1058. output<<"(";
  1059. for(short i=0;i<weighted_block_size-1;i++)
  1060. output<<setw(6)<<setprecision(2)<<weight_vector[i]<<",";
  1061. output<<setw(6)<<setprecision(2)<<weight_vector[weighted_block_size-1]
  1062. <<")"<<endl<<endl;
  1063. }
  1064. void term_ordering::print(ofstream& output) const
  1065. {
  1066. if(weighted_block_size<0)
  1067. {
  1068. output<<"\nWARNING: void term_ordering::print(ofstream&):\n"
  1069. "cannot print corrupt term ordering"<<endl;
  1070. return;
  1071. }
  1072. output<<"\nelimination variables:"<<setw(4)<<elimination_block_size<<endl
  1073. <<"weighted variables: "<<setw(4)<<weighted_block_size<<endl;
  1074. output<<"weight_vector:"<<endl;
  1075. print_weight_vector(output);
  1076. if(elimination_block_size>0)
  1077. {
  1078. output<<"ordering on elimination variables: ";
  1079. switch(elimination_ordering)
  1080. {
  1081. case LEX:
  1082. output<<"LEX\n"<<endl;
  1083. break;
  1084. case DEG_LEX:
  1085. output<<"DEG_LEX\n"<<endl;
  1086. break;
  1087. case DEG_REV_LEX:
  1088. output<<"DEG_REV_LEX\n"<<endl;
  1089. break;
  1090. }
  1091. }
  1092. output<<"ordering refining the weight: ";
  1093. switch(weighted_ordering)
  1094. {
  1095. case W_LEX:
  1096. output<<"W_LEX\n"<<endl;
  1097. break;
  1098. case W_REV_LEX:
  1099. output<<"W_REV_LEX\n"<<endl;
  1100. break;
  1101. case W_DEG_LEX:
  1102. output<<"W_DEG_LEX\n"<<endl;
  1103. break;
  1104. case W_DEG_REV_LEX:
  1105. output<<"W_DEG_REV_LEX\n"<<endl;
  1106. break;
  1107. }
  1108. }
  1109. void term_ordering::format_print_weight_vector(ofstream& output) const
  1110. {
  1111. for(short i=0;i<weighted_block_size;i++)
  1112. output<<setw(6)<<setprecision(2)<<weight_vector[i];
  1113. output<<endl;
  1114. }
  1115. #endif // TERM_ORDERING_CC