source: git/IntegerProgramming/ideal.cc @ 3e0c94f

spielwiese
Last change on this file since 3e0c94f was 10b7a4, checked in by Hans Schönemann <hannes@…>, 16 years ago
*sage/hannes: gcc 4.3 git-svn-id: file:///usr/local/Singular/svn/trunk@10499 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 29.2 KB
Line 
1// ideal.cc
2
3// implementation of some general ideal functions
4
5#ifndef IDEAL_CC
6#define IDEAL_CC
7
8#include <climits>
9#include "ideal.h"
10
11/////////////////////////////////////////////////////////////////////////////
12////////////////// private member functions /////////////////////////////////
13/////////////////////////////////////////////////////////////////////////////
14
15///////////// subset_tree data structure ////////////////////////////////////
16
17#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
18
19void ideal::create_subset_tree()
20{
21  for(short i=0;i<Number_of_Lists;i++)
22  {
23
24// First determine the number of binary vectors whose support is a subset
25// of the support of i (i read as binary vector).
26// The support of i is a set of cardinality s, where s is the number of
27// bits in i that are 1. Hence the desired number is 2^s.
28
29    short s=0;
30
31    for(short k=0;k<List_Support_Variables;k++)
32      if( (i&(1<<k)) == (1<<k) )
33        // bit k of i is 1
34        s++;
35
36    S.number_of_subsets[i]=(1<<s);
37    // (1<<s) == 2^s
38
39// Now determine the concrete binary vectors whose support is a subset
40// of that of i. This is done in a very simple manner by comparing
41// the support of each number between 0 and i (read as binary vector)
42// with that of i. (Efficiency considerations are absolutely unimportant
43// in this function.)
44
45    S.subsets_of_support[i]=new short[S.number_of_subsets[i]];
46    // memory allocation for subsets_of_support[i]
47
48    short index=0;
49    for(short j=0;j<Number_of_Lists;j++)
50      if((i&j)==j)
51        // If the support of j as a bit vector is contained in the support of
52        // i as a bit vector, j is saved in the list subsets_of_support[i].
53          {
54            S.subsets_of_support[i][index]=j;
55            index++;
56          }
57  }
58}
59
60void ideal::destroy_subset_tree()
61{
62  for(short i=0;i<Number_of_Lists;i++)
63    delete[] S.subsets_of_support[i];
64  // The arrays number_of_subsets and subsets_of_support (the (short*)-array)
65  // are not dynamically allocated and do not have to be deleted.
66}
67#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
68
69/////////// subroutines for BuchbergerŽs algorithm //////////////////////////
70
71ideal& ideal::add_new_generator(binomial& bin)
72{
73#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
74
75  new_generators[(bin.head_support)%Number_of_Lists].insert(bin);
76  // insert the bin according to its support,
77  // considering only the first List_Support_Variables variables.
78
79#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
80
81#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
82
83  new_generators.insert(bin);
84
85#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
86
87  return(*this);
88}
89
90ideal& ideal::add_generator(binomial& bin)
91{
92// Beside its function as a auxiliary routine for a shorter code, this routine
93// offers a good way to hide if SUPPORT_DRIVEN_METHODS_EXTENDED are used or
94// not. So the constructors do not have to care about this.
95
96#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
97
98  generators[(bin.head_support)%Number_of_Lists].insert(bin);
99  // insert the bin according to its support,
100  // considering only the first List_Support_Variables variables.
101
102#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
103
104#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
105
106  generators.insert(bin);
107
108#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
109
110  size++;
111  number_of_new_binomials++;
112
113  return(*this);
114}
115
116//////////////////// constructor subroutines ////////////////////////////////
117
118ideal& ideal::Conti_Traverso_ideal(matrix& A,const term_ordering& _w)
119{
120
121  // A may have negative entries; to model this with binomials, we need an
122  // inversion variable.
123
124  w=_w;
125  // The argument term ordering should be given by the objective function.
126
127  w.convert_to_elimination_ordering(A.rows+1,LEX);
128  // extend term ordering into an elimination ordering of the appropriate
129  // size
130
131  Integer *generator=new Integer[A.columns+A.rows+1];
132  // A.columns + A.rows +1 is the number of variables for the Conti-Traverso
133  // algorithm with "inversion variable".
134
135  // build initial ideal generators
136  for(short j=0;j<A.columns;j++)
137  {
138    for(short k=0;k<A.columns;k++)
139      // original variables
140      if(j==k)
141        generator[k]=-1;
142      else
143        generator[k]=0;
144
145    for(short i=0;i<A.rows;i++)
146      // elimination variables
147      generator[A.columns+i]=A.coefficients[i][j];
148
149    generator[A.columns+A.rows]=0;
150    // inversion variable
151
152    // Note that the relative order of the variables is important:
153    // If the elimination variables do not follow the other variables,
154    // the conversion of the term ordering has not the desired effect.
155
156    binomial* bin=new binomial(A.rows+1+A.columns,generator,w);
157    add_generator(*bin);
158  }
159
160  // now add the "inversion generator"
161  for(short j=0;j<A.columns;j++)
162    generator[j]=0;
163  for(short i=0;i<A.rows+1;i++)
164    generator[A.columns+i]=1;
165  binomial* bin=new binomial(A.rows+1+A.columns,generator,w);
166  add_generator(*bin);
167
168  delete[] generator;
169  return *this;
170}
171
172ideal& ideal::Positive_Conti_Traverso_ideal(matrix& A,const term_ordering& _w)
173{
174
175  // A is assumed to have only nonnegative entries;then we need no
176  // "inversion variable".
177
178  w=_w;
179  // The argument term ordering should be given by the objective function.
180
181  w.convert_to_elimination_ordering(A.rows, LEX);
182  // extend term ordering into an elimination ordering of the appropriate
183  // size
184
185  Integer *generator=new Integer[A.columns+A.rows];
186  // A.columns + A.rows is the number of variables for the Conti-Traverso
187  // algorithm without "inversion variable".
188
189  // build the initial ideal generators
190  for(short j=0;j<A.columns;j++)
191  {
192    for(short k=0;k<A.columns;k++)
193      // original variables
194      if(j==k)
195        generator[k]=-1;
196      else
197        generator[k]=0;
198
199    for(short i=0;i<A.rows;i++)
200      // elimination variables
201      generator[A.columns+i]=A.coefficients[i][j];
202
203    // Note that the relative order of the variables is important:
204    // If the elimination variables do not follow the other variables,
205    // the conversion of the term ordering has not the desired effect.
206
207    binomial* bin=new binomial(A.rows+A.columns,generator,w);
208    add_generator(*bin);
209  }
210  delete[] generator;
211  return *this;
212}
213
214ideal& ideal::Pottier_ideal(matrix& A, const term_ordering& _w)
215{
216
217  w=_w;
218  // The argument term_ordering should be given by the objective function.
219
220  w.convert_to_elimination_ordering(1,LEX);
221  // add one elimination variable used to saturate the ideal
222
223  if(A._kernel_dimension==-2)
224    // kernel of A not yet computed, do this now
225    A.LLL_kernel_basis();
226
227  if((A._kernel_dimension==-1) &&  (A.columns<0))
228    // error occurred in kernel computation or matrix corrupt
229  {
230    cout<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
231      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
232    size=-1;
233    return *this;
234  }
235
236  Integer *generator=new Integer[A.columns+1];
237  // This is the number of variables needed for Pottier's algorithm.
238
239
240  // compute initial generating system from the kernel of A
241  for(short j=0;j<A._kernel_dimension;j++)
242  {
243
244    for(short k=0;k<A.columns;k++)
245    {
246
247      // We should first verifie if the components of the LLL-reduced lattice
248      // basis fit into the basic data type (Integer as defined in globals.h).
249      // This overflow control does of course not detect overflows in the
250      // course of the LLL-algorithm!
251
252#ifdef _SHORT_
253
254      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
255      {
256        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
257          "term_ordering&):\n"
258          "LLL-reduced kernel basis does not fit into the used "
259          "basic data type short."<<endl;
260        size=-3;
261        delete[] generator;
262        return *this;
263      }
264
265#endif // _SHORT_
266
267#ifdef _INT_
268
269      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
270      {
271        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
272          "term_ordering&):\n"
273          "LLL-reduced kernel basis does not fit into the used "
274          "basic data type int."<<endl;
275        size=-3;
276        delete[] generator;
277        return *this;
278      }
279
280#endif  // _INT_
281
282#ifdef _LONG_
283
284      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
285      {
286        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
287          "term_ordering&):\n"
288          "LLL-reduced kernel basis does not fit into the used "
289          "basic data type long."<<endl;
290        size=-3;
291        delete[] generator;
292        return *this;
293      }
294
295#endif  // _LONG_
296
297      generator[k]=(A.H)[j][k];
298    }
299
300    generator[A.columns]=0;
301    // elimination variable
302
303    // Note that the relative order of the variables is important:
304    // If the elimination variable does not follow the other variables,
305    // the conversion of the term ordering has not the desired effect.
306
307    binomial* bin=new binomial(A.columns+1,generator,w);
308    add_generator(*bin);
309  }
310
311  // build "saturation generator"
312
313  // The use of the hosten_shapiro procedure is useful here because the head
314  // of the computed saturation generator is smaller if less variables are
315  // involved.
316  short* sat_var;
317  short number_of_sat_var=A.hosten_shapiro(sat_var);
318
319  for(short j=0;j<A.columns;j++)
320    generator[j]=0;
321
322  for(short k=0;k<number_of_sat_var;k++)
323    generator[sat_var[k]]=1;
324
325  generator[A.columns]=1;
326
327  binomial* bin=new binomial(A.columns+1,generator,w);
328  add_generator(*bin);
329  // The "saturation generator" seems to be a monomial, but is interpreted
330  // as a binomial with tail 1 by the designed data structures.
331
332  delete[] sat_var;
333  delete[] generator;
334
335  return *this;
336}
337
338ideal& ideal::Hosten_Sturmfels_ideal(matrix& A, const term_ordering& _w)
339{
340
341  // check term ordering
342  if((_w.weight_refinement()!=W_REV_LEX) && (_w.is_positive()==FALSE))
343    cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
344      "term_ordering&):\nargument term ordering should be a weighted reverse"
345      "lexicographical \nwith positive weights"<<endl;
346
347  w=_w;
348  // The argument term_ordering should be given by a homogenous grading.
349
350  if(A._kernel_dimension==-2)
351    // kernel of A not yet computed, do this now
352    A.LLL_kernel_basis();
353
354  if((A._kernel_dimension==-1) &&  (A.columns<0))
355    // error occurred in kernel computation or matrix corrupt
356  {
357    cout<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
358      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
359    size=-1;
360    return *this;
361  }
362
363  Integer * generator=new Integer[A.columns];
364  // The algorithm of Hosten and Sturmfels does not need supplementary
365  // variables.
366
367
368  // compute initial generating system from the kernel of A
369  for(short j=0;j<A._kernel_dimension;j++)
370  {
371
372    for(short k=0;k<A.columns;k++)
373    {
374
375      // We should first verifie if the components of the LLL-reduced lattice
376      // basis fit into the basic data type (Integer as defined in globals.h).
377      // This overflow control does of course not detect overflows in the
378      // course of the LLL-algorithm!
379
380#ifdef _SHORT_
381
382      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
383      {
384        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
385          "term_ordering&):\nLLL-reduced kernel basis does not fit "
386          "into the used basic data type short."<<endl;
387        size=-3;
388        delete[] generator;
389        return *this;
390      }
391
392#endif // _SHORT_
393
394#ifdef _INT_
395
396      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
397      {
398        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
399          "term_ordering&):\nLLL-reduced kernel basis does not fit "
400          "into the used basic data type int."<<endl;
401        size=-3;
402        delete[] generator;
403        return *this;
404      }
405
406#endif  // _INT_
407
408#ifdef _LONG_
409
410      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
411      {
412        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
413          "term_ordering&):\nLLL-reduced kernel basis does not fit "
414          "into the used basic data type long."<<endl;
415        size=-3;
416        delete[] generator;
417        return *this;
418      }
419
420#endif  // _LONG_
421
422      generator[k]=(A.H)[j][k];
423    }
424
425    // verifie term ordering
426    if(w.weight(generator)!=0)
427      cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, "
428        "const term_ordering&):\nInvalid row space vector does not induce "
429        "homogenous grading."<<endl;
430
431    binomial* bin=new binomial(A.columns,generator,w);
432    add_generator(*bin);
433  }
434
435  delete[] generator;
436  return *this;
437}
438
439ideal& ideal::DiBiase_Urbanke_ideal(matrix& A, const term_ordering& _w)
440{
441  w=_w;
442
443  if(A._kernel_dimension==-2)
444    // kernel of A not yet computed, do this now
445    A.LLL_kernel_basis();
446
447  if((A._kernel_dimension==-1) &&  (A.columns<0))
448    // error occurred in kernel computation or matrix corrupt
449  {
450    cout<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
451      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
452    size=-1;
453    return *this;
454  }
455
456  // now compute flip variables
457
458  short* F;
459  // set of flip variables
460  // If F[i]==j, x_j will be flipped.
461
462  short r=A.compute_flip_variables(F);
463  // number of flip variables
464
465  if(r<0)
466  {
467    cout<<"Kernel of the input matrix contains no vector with nonzero "
468      "components.\nPlease use another algorithm."<<endl;
469    size=-1;
470    return *this;
471  }
472
473  // check term ordering (as far as possible)
474  BOOLEAN ordering_okay=TRUE;
475
476  if(_w.weight_refinement()!=W_LEX)
477    ordering_okay=FALSE;
478
479  if(r>0)
480  {
481    for(short i=0;i<_w.number_of_weighted_variables();i++)
482      if((_w[i]!=0) && (i!=F[0]))
483        ordering_okay=FALSE;
484  }
485
486  if(ordering_okay==FALSE)
487    cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
488      "term_ordering&):\nargument term ordering might be inappropriate"<<endl;
489
490  Integer *generator=new Integer[A.columns];
491  // The algorithm of DiBiase and Urbanke does not need supplementary
492  // variables.
493
494  // compute initial generating system from the kernel of A
495  for(short j=0;j<A._kernel_dimension;j++)
496  {
497
498    for(short k=0;k<A.columns;k++)
499    {
500
501      // We should first verifie if the components of the LLL-reduced lattice
502      // basis fit into the basic data type (Integer as defined in globals.h).
503      // This overflow control does of course not detect overflows in the
504      // course of the LLL-algorithm!
505
506#ifdef _SHORT_
507
508      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
509      {
510        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
511          "term_ordering&):\nLLL-reduced kernel basis does not fit "
512          "into the used basic data type short."<<endl;
513        size=-3;
514        delete[] generator;
515        return *this;
516      }
517
518#endif // _SHORT_
519
520#ifdef _INT_
521
522      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
523      {
524        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
525          "term_ordering&):\nLLL-reduced kernel basis does not fit "
526          "into the used basic data type int."<<endl;
527        size=-3;
528        delete[] generator;
529        return *this;
530      }
531
532#endif  // _INT_
533
534#ifdef _LONG_
535
536      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
537      {
538        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
539          "term_ordering&):\nLLL-reduced kernel basis does not fit "
540          "into the used basic data type long."<<endl;
541        size=-3;
542        delete[] generator;
543        return *this;
544      }
545
546#endif  // _LONG_
547      generator[k]=(A.H)[j][k];
548    }
549
550    // flip variables
551    for(short l=0;l<r;l++)
552      generator[F[l]]*=-1;
553
554    binomial* bin=new binomial(A.columns,generator,w);
555    add_generator(*bin);
556  }
557  delete[] F;
558  delete[] generator;
559  return *this;
560}
561
562ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix& A,const term_ordering& _w)
563{
564
565  // check term ordering
566  if((_w.weight_refinement()!=W_REV_LEX) && (_w.is_positive()==FALSE))
567    cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
568      "const term_ordering&):\nargument term ordering should be a weighted  "
569      "reverse lexicographical \nwith positive weights"<<endl;
570
571  w=_w;
572  // The argument term_ordering should be given by a homogenous grading.
573
574  if(A._kernel_dimension==-2)
575    // kernel of A not yet computed, do this now
576    A.LLL_kernel_basis();
577
578  if((A._kernel_dimension==-1) &&  (A.columns<0))
579    // error occurred in kernel computation or matrix corrupt
580  {
581    cout<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
582      "const term_ordering&):\n"
583      "cannot build ideal from a corrupt input matrix"<<endl;
584    size=-1;
585    return *this;
586  }
587
588  // now compute saturation variables
589
590  // The techniques for computing a small set of saturation variables are
591  // useful here for the following two reasons:
592  // - The head of the saturation generator involves less variables, is
593  //   smaller in term ordering.
594  // - The weight of the pseudo-elimination variable is smaller.
595  short* sat_var;
596  short number_of_sat_var=A.hosten_shapiro(sat_var);
597
598  float weight=0;
599  for(short i=0;i<number_of_sat_var;i++)
600    weight+=w[sat_var[i]];
601
602  w.append_weighted_variable(weight);
603  // one supplementary variable used to saturate the ideal
604
605  Integer *generator=new Integer[A.columns+1];
606  // The algorithm of Bigatti, LaScala and Robbiano needs one supplementary
607  // weighted variable.
608
609  // first build "saturation generator"
610  for(short k=0;k<A.columns;k++)
611    generator[k]=0;
612  for(short i=0;i<number_of_sat_var;i++)
613    generator[sat_var[i]]=1;
614  generator[A.columns]=-1;
615
616  delete[] sat_var;
617
618  binomial* bin=new binomial(A.columns+1,generator,w);
619  add_generator(*bin);
620
621  // compute initial generating system from the kernel of A
622  for(short j=0;j<A._kernel_dimension;j++)
623  {
624    for(short k=0;k<A.columns;k++)
625    {
626      // We should first verifie if the components of the LLL-reduced lattice
627      // basis fit into the basic data type (Integer as defined in globals.h).
628      // This overflow control does of course not detect overflows in the
629      // course of the LLL-algorithm!
630
631#ifdef _SHORT_
632
633      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
634      {
635        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
636          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
637          "not fit into the used basic data type short."<<endl;
638        size=-3;
639        delete[] generator;
640        return *this;
641      }
642
643#endif // _SHORT_
644
645#ifdef _INT_
646
647      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
648      {
649        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
650          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
651          "not fit into the used basic data type int."<<endl;
652        size=-3;
653        delete[] generator;
654        return *this;
655      }
656
657#endif  // _INT_
658
659#ifdef _LONG_
660
661      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
662      {
663        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
664          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
665          "not fit into the used basic data type long."<<endl;
666        size=-3;
667        return *this;
668      }
669
670#endif  // _LONG_
671      generator[k]=(A.H)[j][k];
672    }
673    generator[A.columns]=0;
674    // saturation variable
675    // Note that the relative order of the variables is important (because
676    // of the reverse lexicographical refinement of the weight).
677
678    if(w.weight(generator)!=0)
679      cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
680        "const term_ordering&):\nInvalid row space vector does not induce "
681        "homogenous grading."<<endl;
682
683    binomial* bin=new binomial(A.columns+1,generator,w);
684    add_generator(*bin);
685    // insert generator
686  }
687  delete[] generator;
688  return *this;
689}
690
691/////////////////////////////////////////////////////////////////////////////
692//////////////// public member functions ////////////////////////////////////
693/////////////////////////////////////////////////////////////////////////////
694
695/////////////////// constructors and destructor /////////////////////////////
696
697ideal::ideal(matrix& A, const term_ordering& _w, const short& algorithm)
698{
699
700  // check arguments as far as possible
701
702  if(A.error_status()<0)
703  {
704    cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
705      "short&):\ncannot create ideal from a corrupt input matrix"<<endl;
706    size=-1;
707    return;
708  }
709
710  if(_w.error_status()<0)
711  {
712    cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
713      "short&):\ncannot create ideal with a corrupt input ordering"<<endl;
714    size=-1;
715    return;
716  }
717
718  if((_w.number_of_elimination_variables()!=0) &&
719     (_w.number_of_weighted_variables()!=A.columns))
720    cerr<<"\nWARNING: ideal& ideal::ideal(matrix&, const term_ordering&):\n"
721      "argument term ordering might be inappropriate"<<endl;
722
723#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
724
725  create_subset_tree();
726
727#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
728
729  size=0;
730
731  // initialize the S-pair flags with the default value
732  // (this is not really necessray, but looks nicer when outputting the
733  // ideal without having computed a Groebner basis)
734  rel_primeness=1;
735  M_criterion=2;
736  F_criterion=0;
737  B_criterion=8;
738  second_criterion=0;
739
740  interreduction_percentage=12.0;
741
742  // construct the ideal according to the algorithm
743  switch(algorithm)
744  {
745      case CONTI_TRAVERSO:
746        Conti_Traverso_ideal(A,_w);
747        break;
748      case POSITIVE_CONTI_TRAVERSO:
749        Positive_Conti_Traverso_ideal(A,_w);
750        break;
751      case POTTIER:
752        Pottier_ideal(A,_w);
753        break;
754      case HOSTEN_STURMFELS:
755        Hosten_Sturmfels_ideal(A,_w);
756        break;
757      case DIBIASE_URBANKE:
758        DiBiase_Urbanke_ideal(A,_w);
759        break;
760      case BIGATTI_LASCALA_ROBBIANO:
761        Bigatti_LaScala_Robbiano_ideal(A,_w);
762        break;
763      default:
764        cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
765          "short&):\nunknown algorithm for ideal construction"<<endl;
766        size=-1;
767        return;
768  }
769  number_of_new_binomials=size;
770}
771
772ideal::ideal(const ideal& I)
773{
774
775  if(I.error_status()<0)
776    cerr<<"\nWARNING: ideal::ideal(const ideal&):\n"
777      "trying to create ideal from a corrupt one"<<endl;
778
779  size=0;
780  // the size is automatically incremented when copying the generators
781
782  w=I.w;
783
784  rel_primeness=I.rel_primeness;
785  M_criterion=I.M_criterion;
786  F_criterion=I.F_criterion;
787  B_criterion=I.B_criterion;
788  second_criterion=I.second_criterion;
789
790  interreduction_percentage=I.interreduction_percentage;
791
792  // copy generators
793  // To be sure to get a real copy of the argument ideal, the lists
794  // aux_list and new_generators are also copied.
795  list_iterator iter;
796
797
798#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
799
800  iter.set_to_list(I.generators);
801
802  while(iter.is_at_end()==FALSE)
803  {
804    binomial* bin=new binomial(iter.get_element());
805    add_generator(*bin);
806    iter.next();
807  }
808
809  iter.set_to_list(I.new_generators);
810
811  while(iter.is_at_end()==FALSE)
812  {
813    binomial* bin=new binomial(iter.get_element());
814    add_new_generator(*bin);
815    iter.next();
816  }
817
818#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
819
820#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
821
822  create_subset_tree();
823
824  for(short i=0;i<Number_of_Lists;i++)
825  {
826    iter.set_to_list(I.generators[i]);
827
828    while(iter.is_at_end()==FALSE)
829    {
830      binomial* bin=new binomial(iter.get_element());
831      add_generator(*bin);
832      iter.next();
833    }
834  }
835
836  for(short i=0;i<Number_of_Lists;i++)
837  {
838    iter.set_to_list(I.new_generators[i]);
839
840    while(iter.is_at_end()==FALSE)
841    {
842      binomial* bin=new binomial(iter.get_element());
843      add_new_generator(*bin);
844      iter.next();
845    }
846  }
847
848#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
849
850  iter.set_to_list(I.aux_list);
851
852  while(iter.is_at_end()==FALSE)
853  {
854    binomial* bin=new binomial(iter.get_element());
855    aux_list._insert(*bin);
856    iter.next();
857  }
858  number_of_new_binomials=size;
859}
860
861ideal::ideal(ifstream& input, const term_ordering& _w, const short&
862             number_of_generators)
863{
864  if(_w.error_status()<0)
865  {
866    cerr<<"\nWARNING: ideal::ideal(ifstream&, const term_ordering&, const "
867      "short&):\ncannot create ideal with a corrupt input ordering"<<endl;
868    size=-1;
869    return;
870  }
871
872  w=_w;
873
874  // initialize the S-pair flags with the default value
875  // (this is not really necessray, but looks nicer when outputting the
876  // ideal without having computed a Groebner basis)
877  rel_primeness=1;
878  M_criterion=2;
879  F_criterion=0;
880  B_criterion=8;
881  second_criterion=0;
882
883  interreduction_percentage=12.0;
884
885#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
886
887  create_subset_tree();
888
889#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
890
891  short number_of_variables=
892    w.number_of_elimination_variables()+w.number_of_weighted_variables();
893  Integer* generator=new Integer[number_of_variables];
894
895  for(long i=0;i<number_of_generators;i++)
896  {
897    for(short j=0;j<number_of_variables;j++)
898    {
899      input>>generator[j];
900
901      if(!input)
902        // input failure, set "error flag"
903      {
904        cerr<<"\nWARNING: ideal::ideal(ifstream&, const term_ordering&, "
905          "const short&): \ninput failure when reading generator "<<i<<endl;
906        size=-2;
907        delete[] generator;
908        return;
909      }
910    }
911    binomial* bin=new binomial(number_of_variables,generator,w);
912    add_generator(*bin);
913  }
914  size=number_of_generators;
915  number_of_new_binomials=size;
916  delete[] generator;
917}
918
919ideal::~ideal()
920{
921
922#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
923
924  destroy_subset_tree();
925
926#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
927
928  // The destructor of the lists is automatically called.
929}
930
931///////////////////// object information ////////////////////////////////////
932
933long ideal::number_of_generators() const
934{
935  return size;
936}
937
938short ideal::error_status() const
939{
940  if(size<0)
941    return -1;
942  else
943    return 0;
944}
945
946//////////////////////////// output /////////////////////////////////////////
947
948void ideal::print() const
949{
950  printf("\nterm ordering:\n");
951  w.print();
952
953  printf("\ngenerators:\n");
954
955#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
956
957  for(short i=0;i<Number_of_Lists;i++)
958    generators[i].ordered_print(w);
959
960#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
961
962#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
963
964    generators.ordered_print(w);
965
966#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
967
968  printf("\nnumber of generators: %ld\n",size);
969}
970
971void ideal::print_all() const
972{
973  print();
974  cout<<"\nCurrently used S-pair criteria:"<<endl;
975  if(rel_primeness)
976    cout<<"relatively prime leading terms"<<endl;
977  if(M_criterion)
978    cout<<"criterion M"<<endl;
979  if(F_criterion)
980    cout<<"criterion F"<<endl;
981  if(B_criterion)
982    cout<<"criterion B"<<endl;
983  if(second_criterion)
984    cout<<"second criterion"<<endl;
985  cout<<"\nInterreduction frequency:  "<<setprecision(1)
986      <<interreduction_percentage<<" %"<<endl;
987}
988
989void ideal::print(FILE *output) const
990{
991  fprintf(output,"\nterm ordering:\n");
992  w.print(output);
993
994  fprintf(output,"\ngenerators:\n");
995
996#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
997
998  for(short i=0;i<Number_of_Lists;i++)
999    generators[i].ordered_print(output,w);
1000
1001#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
1002
1003#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1004
1005    generators.ordered_print(output,w);
1006
1007#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1008
1009  fprintf(output,"\nnumber of generators: %ld\n",size);
1010
1011  fprintf(output,"\nInterreduction frequency:  %.1f %\n",
1012          interreduction_percentage);
1013}
1014
1015void ideal::print_all(FILE* output) const
1016{
1017  print(output);
1018  fprintf(output,"\nCurrently used S-pair criteria:\n");
1019  if(rel_primeness)
1020    fprintf(output,"relatively prime leading terms\n");
1021  if(M_criterion)
1022    fprintf(output,"criterion M\n");
1023  if(F_criterion)
1024    fprintf(output,"criterion F\n");
1025  if(B_criterion)
1026    fprintf(output,"criterion B\n");
1027  if(second_criterion)
1028    fprintf(output,"second criterion\n");
1029}
1030
1031void ideal::print(ofstream& output) const
1032{
1033  output<<"\nterm ordering:\n"<<endl;
1034  w.print(output);
1035
1036  output<<"\ngenerators:\n"<<endl;
1037
1038#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
1039
1040  for(short i=0;i<Number_of_Lists;i++)
1041    generators[i].ordered_print(output,w);
1042
1043#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
1044
1045#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1046
1047    generators.ordered_print(output,w);
1048
1049#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1050
1051    output<<"\nnumber of generators: "<<size<<endl;
1052}
1053
1054void ideal::print_all(ofstream& output) const
1055{
1056  print(output);
1057  output<<"\nCurrently used S-pair criteria:"<<endl;
1058  if(rel_primeness)
1059    output<<"relatively prime leading terms"<<endl;
1060  if(M_criterion)
1061    output<<"criterion M"<<endl;
1062  if(F_criterion)
1063    output<<"criterion F"<<endl;
1064  if(B_criterion)
1065    output<<"criterion B"<<endl;
1066  if(second_criterion)
1067    output<<"second_criterion"<<endl;
1068  output<<"\nInterreduction frequency:  "<<setprecision(1)
1069        <<interreduction_percentage<<" %"<<endl;
1070}
1071
1072void ideal::format_print(ofstream& output) const
1073{
1074#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
1075
1076  for(short i=0;i<Number_of_Lists;i++)
1077    generators[i].ordered_format_print(output,w);
1078
1079#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
1080
1081#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1082
1083    generators.ordered_format_print(output,w);
1084
1085#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
1086}
1087#endif  // IDEAL_CC
Note: See TracBrowser for help on using the repository browser.