1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
|
// binomial.h
// The binomials considered here are differences of power-products of a
// special kind. The initial monomial or head (with respect to a given
// term ordering as described in term_ordering.h) has coefficient 1, the other
// monomial (the tail) has coefficient -1. The head and the tail of a
// binomial are always relatively prime, i.e., they do not involve common
// variables.
// Such a binomial in n variables is represented as an Integer vector of
// size n: If the i-th variable is involved in the head with exponent k,
// the i-th component of the vector is set to k. If the i-th variable is
// involved in the tail with exponent k, the i-th component of the vector
// is set to -k.
// The members head_support and tail_support of type unsigned long have to be
// understood as bit-vectors with m components, where m is the number of
// bits in a long integer. The i-th bit of head_support tells us if the i-th
// variable is involved in the head of the binomial (for i<=m): it is 1
// iff this variable appears in the head. Analogously for tail_support.
// Using these vectors, the question if a binomial can be reduced by another
// can often be answered by performing a simple bitwise operation.
// To avoid global variables, the number of variables is taken by the
// constructors. But as it is the same for all appearing binomials during
// the run of our algorithms (unless some elimination is done), the member
// functions do not perform any range checks. This makes the algorithms
// more efficient.
// Most of the constructors do not perform sign checks on their arguments.
// The reason is simple: Unlike the matrix or term ordering constructors, some
// binomial constructors are frequently called during computation. As the
// new binomials are build from the input binomials, it is sufficient to do
// these checks on the input.
#ifndef BINOMIAL_H
#define BINOMIAL_H
class term_ordering;
class binomial
{
private:
Integer* exponent_vector;
short _number_of_variables;
#ifdef SUPPORT_DRIVEN_METHODS
unsigned long head_support;
unsigned long tail_support;
#endif // SUPPORT_DRIVEN_METHODS
public:
// constructors and destructor
binomial(const short& number_of_variables);
// Allocates memory for a binomial of size number_of_variables
// without initialization.
// No range check on the argument!
binomial(const short& number_of_variables, const Integer* exponents);
binomial(const short& number_of_variables, const Integer* exponents,
const term_ordering&);
// These constructors build a binomial from its exponent vector/array.
// The first one takes the positive components as its head, the negative
// ones as its tail; the second one determines its head and tail with
// respect to the given term ordering.
// The array "exponents" is always copied. It would be faster to set
// only pointers on it. However, this is very dangerous, and as these
// constructors are only used at the beginning of the algorithm, it would
// not really improve performance.
// The Integer pointer exponents is declared as "const" to suggest that
// the referenced array is not changed (although the "const"-declaration
// does not assert this).
// These constructor check the range (sign) of their argument
// number_of_variables because it is not frequently called, but at a
// critical point (ideal constructors).
binomial(const binomial&);
// copy-constructor
// No check if the copied binomial is corrupt!
~binomial();
// destructor
// object information
short number_of_variables() const;
// Returns the number of variables.
short error_status() const;
// Returns _number_of_variables iff _number_of_variables<0
// (this is the "error flag").
// assignment and access operators
binomial& operator=(const binomial&);
// assignment operator with memory control
Integer operator[](const short& i) const;
// Access operator for reading exponent_vector[i]
// (cannot be used to overwrite exponent_vector[i]);
// no range check on i!
// comparison operators
BOOLEAN operator==(const binomial& v) const;
BOOLEAN operator!=(const binomial& v) const;
// comparison of binomials
BOOLEAN operator==(const Integer comp_value) const;
BOOLEAN operator!=(const Integer comp_value) const;
BOOLEAN operator<=(const Integer comp_value) const;
BOOLEAN operator>=(const Integer comp_value) const;
// operators for an efficient comparison with the zero binomial
// (comp_value=0)
// basic routines for Buchbergers's algorithm
Integer head_reductions_by(const binomial& b) const;
// Returns the number of possible reductions of the actual binomial's head
// by the binomial b.
// The return value -1 means that b==0 or head(b)==1; one should not try
// reduce by such a binomial (reduction is undefined or does not terminate).
// The procedure reduce_tail_by(...) returns the unchanged binomial in such
// a case without a warning. This is done in view of the application:
// If a generator of an ideal is reduced to zero during a Groebner basis
// calculation and one forgets to delete it, this generator is ignored
// (else it would probably cause a fatal error).
Integer tail_reductions_by(const binomial& b) const;
// Returns the number of possible reductions of the actual binomial's tail
// by the binomial b.
// For the return value -1 see above.
int reduce_head_by(const binomial& b, const term_ordering& w);
// Performs a multiple reduction of the actual binomial's head by the
// binomial b and computes the new head and tail with respect to the term
// ordering w.
// The return value is 1 if the binomial has really been reduced, 2 if
// the binomial has been reduced to zero, 0 if the binomial has not been
// changed.
int reduce_tail_by(const binomial& b, const term_ordering& w);
// Performs a multiple reduction of the actual binomial's tail by the
// binomial b and computes the new head and tail with respect to the term
// ordering w.
// The return value is 1 if the binomial has really been reduced, else 0.
// (By a tail reduction, the binomial cannot be reduced to zero if the
// binomial itself and b are consistent with w, i.e. if head and tail are
// correct.)
friend binomial& S_binomial(const binomial& a, const binomial& b,
const term_ordering& w);
// Computes the S-binomial of a and b with respect to the term ordering w
// and returns a reference on it (the necessary memory is allocated during
// the computation).
// criteria for unnecessary S-Pairs
friend BOOLEAN relatively_prime(const binomial& a, const binomial& b);
// Returns TRUE iff the leading terms of a and b are relatively prime.
friend BOOLEAN M(const binomial& a,const binomial& b,const binomial& c);
// Verifies if lcm(head(a),head(c)) divides properly lcm(head(b),head(c)).
friend BOOLEAN F(const binomial& a, const binomial& b, const binomial& c);
// Verifies if lcm(head(a),head(c))=lcm(head(b),head(c)).
friend BOOLEAN B(const binomial& a, const binomial& b, const binomial& c);
// Verifies if head(a) divides lcm(head(b),head(c)) and
// lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c)).
friend BOOLEAN second_crit(const binomial& a, const binomial& b,
const binomial& c);
// Verifies if head(a) divides lcm(head(b),head(c)).
// special routines needed by the IP-algorithms
// All this routines are not very frequently used (especially not in
// Buchberger's algorithm), so I haven't spent much time in optimization.
// None of them performs range checks on their arguments.
BOOLEAN involves_elimination_variables(const term_ordering& w);
// Verifies if the binomial involves elimination variables with respect
// to w.
// UNCHECKED PRECONDITION: w and the binomial are compatible, i.e.
// involve the same number of variables.
BOOLEAN drop_elimination_variables(const term_ordering& w);
// Cuts the elimination variables (with respect to w) from the binomial
// and adapts the member _number_of_variables as well as the head and the
// tail.
// UNCHECKED PRECONDITION: w and the binomial are compatible.
// The interesting part of the binomial (ot its additive inverse) is copied
// hereby to be able to free the memory needed by the dropped components.
BOOLEAN drop_last_weighted_variable(const term_ordering& w);
// Cuts the last variable from the binomial and adapts the member
// _number_of_variables as well as head and tail (the last two to the given
// term_ordering)
// UNCHECKED PRECONDITION: w is a weighted termordering (without elimination
// variables) that is compatible to the actual binomial.
// The interesting part of the binomial (ot its additive inverse) is copied
// hereby to be able to free the memory needed by the dropped components.
int adapt_to_term_ordering(const term_ordering&);
// Determines head and tail of the binomial with respect to the given term
// ordering; i.e. multiplies the exponent vector with -1 and exchanges
// head_support and tail_support, if necessary.
// Returns -1 if head and tail were exchanged, 1 else.
// UNCHECKED PRECONDITION: w and the binomial are compatible.
binomial& swap_variables(const short& i,const short& j);
// Swaps the components i and j of the exponent vector and actualizes
// head_support and tail_support.
// No range check on the arguments!
binomial& flip_variable(const short& i);
// Inverts component i of the exponent vector and actualizes head_support
// and tail_support.
// No range check on i!
// output
void print() const;
void print_all() const;
// Writes the actual binomial to the standard output medium.
// The first routine only prints the exponent vector, the second prints
// the head and tail support, too (if SUPPORT_DRIVEN_METHODS are used).
void print(FILE* output) const;
void print_all(FILE* output) const;
// Writes the actual binomial to the referenced file which must have
// been opened for writing before.
void print(ofstream&) const;
void print_all(ofstream&) const;
// Writes the actual binomial to the given ofstream.
void format_print(ofstream&) const;
// Writes the given binomial to the actual ofstream in the format needed
// by the IP-algorithms.
friend class ideal;
// The class ideal is declared as a friend for efficiency reasons:
// This avoids many unnecessary function calls for inspecting members
// like head_support and tail_support.
// The class ideal does not change any members of the binomial class.
friend short term_ordering::compare(const binomial&, const binomial&) const;
};
#endif // BINOMIAL_H
|