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 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
|
// Copyright 2004 Michael E. Stillman
#ifndef _polyring_hpp_
#define _polyring_hpp_
#include "ringelem.hpp"
#include <vector>
#include "interface/computation.h"
#include "skew.hpp"
class buffer;
class Monoid;
class Ring;
class MonomialIdeal;
class MonomialTable;
class MonomialTableZZ;
class PolynomialRing;
class PolyRingFlat;
class PolyRing;
class PolyRingSkew;
class PolyRingWeyl;
class PolyRingNC;
class PolyQuotient;
class GBRing;
class GBRingSkew;
class GBComputation;
#include "ring.hpp"
#include "qring.hpp"
/**
* \ingroup polynomialrings
*/
class PolynomialRing : public Ring
{
bool is_graded_;
protected:
// Most skew-mult specific poly code is in skewpoly.{hpp,cpp}. However, var,
// homogenize,
// and diff_term all have a small amount of skew commutative specific code.
bool is_skew_;
SkewMultiplication skew_; // Completely ignored if is_skew_ is false.
bool is_weyl_; // true iff numerR_ is a Weyl algebra.
bool is_solvable_; // true iff numerR_ is a solvable algebra.
Ring::CoefficientType coeff_type_;
bool overZZ_; // true iff this is a quotient over ZZ.
QRingInfo *qinfo_;
bool is_ZZ_quotient_; // true if this is a quotient of a polynomial ring over
// ZZ, AND
// there is an integer in the factored ideal.
ring_elem ZZ_quotient_value_; // This is the integer in the factor ideal, if
// is_ZZ_quotient is set.
size_t poly_size_;
int nvars_;
int exp_size; // in bytes, only used for local stack storage for exponent
// vectors
const Ring *K_;
const Monoid *M_;
const PolyRing *numerR_; // numerator ring, possibly 'this'
// This is always a PolyRing, with no quotient elements
// If ring is basic[M]/I, then numerR is basic[M]
// If ring is QQ[M]/I, then numerR is ZZ[M].
// skew and weyl multiplication is determined by this ring.
// initialize_PolynomialRing will set these values,
// if numerR_ != this.
const Ring *denomR_; // denominator ring, or NULL
// If ring is basic[M]/I, this is NULL
// If ring is QQ[M]/I, this is ZZ
const PolynomialRing
*ambientR_; // ambient ring (i.e. no quotients), possibly 'this'.
// If ring is basic[M]/I, then ambientR_ is same as numerR_
// If ring is QQ[M]/I, then ambientR_ is QQ[M].
GBRing *gb_ring_;
void setIsGraded(bool new_val) { is_graded_ = new_val; }
void setQuotientInfo(QRingInfo *qinfo0);
void initialize_PolynomialRing(const Ring *K,
const Monoid *M,
const PolyRing *numeratorR,
const PolynomialRing *ambientR,
const Ring *denomR);
virtual ~PolynomialRing();
PolynomialRing() : is_graded_(true), is_skew_(false), qinfo_(new QRingInfo) {}
static PolynomialRing *create_quotient(const PolynomialRing *R,
VECTOR(Nterm *) & elems);
// Grabs 'elems'. Each element of 'elems' should be in the ring R.
// They should also form a GB.
public:
static PolynomialRing *create_quotient(const PolynomialRing *R,
const Matrix *M);
static PolynomialRing *create_quotient(const PolynomialRing *R,
const PolynomialRing *B);
// R should be an ambient poly ring
// B should have: ambient of B is the logical coeff ring of R
// i.e. R = A[x], B = A/I
// return A[x]/I.
virtual void clear() { qinfo_->destroy(gb_ring_); }
// Removes all space associated with 'this', at least the part
// that is stashed: gb_ring_ (if it was created by this ring), qinfo_.
Matrix *getPresentation() const;
unsigned long get_precision() const { return K_->get_precision(); }
bool is_basic_ring() const
{
return false;
} // The default is to be a basic ring.
bool is_poly_ring() const { return true; }
// Returns true if this is a polynomial ring, possibly with fractions
// and possibly with quotient ideal, and possibly with non-commutative
// multiplication. Equivalent to (cast_to_PolynomialRing() != 0).
bool is_graded() const { return is_graded_; }
// Is this ring graded, with the given grading?
// polynomial rings are graded
// Weyl algebras can be graded or not
// quotient polynomial rings can be graded or not.
CoefficientType coefficient_type() const { return coeff_type_; }
// What the ultimate coefficient type is. ZZ, QQ, finite fields return these
// three values. Fraction fields return their ultimate value, as do poly
// rings.
int n_vars() const { return nvars_; }
static PolynomialRing *create_quotient_ring(const Matrix *M);
QRingInfo *get_quotient_info() const { return qinfo_; }
const Ring *getCoefficientRing() const { return getCoefficients(); }
// getCoefficientRing needs to be totally removed.
// Quotient ring information
MonomialTable *get_quotient_MonomialTable() const
{
return qinfo_->get_quotient_MonomialTable();
}
const MonomialIdeal *get_quotient_monomials() const
{
return qinfo_->get_quotient_monomials();
}
const MonomialTableZZ *get_quotient_MonomialTableZZ() const
{
return qinfo_->get_quotient_MonomialTableZZ();
}
int n_quotients() const { return qinfo_->n_quotients(); }
Nterm *quotient_element(int i) const { return qinfo_->quotient_element(i); }
const gbvector *quotient_gbvector(int i) const
{
return qinfo_->quotient_gbvector(i);
}
const MonomialIdeal *make_basis_MonomialIdeal() const
{
return get_quotient_monomials();
}
// Returns the monomial ideal consisting of monomials which are initial terms
// in this quotient ring. IE, the set of all monomials outside of this
// ideal form a generating set for the ring as a
// module over the ring getLogicalCoefficients().
bool is_quotient_ring() const { return n_quotients() > 0; }
// skew commutativity
bool is_skew_commutative() const { return is_skew_; }
int n_skew_commutative_vars() const { return skew_.n_skew_vars(); }
int skew_variable(int i) const { return skew_.skew_variable(i); }
bool is_skew_var(int v) const { return skew_.is_skew_var(v); }
const SkewMultiplication &getSkewInfo() const { return skew_; }
virtual bool is_commutative_ring() const
{
return !is_weyl_ && !is_skew_ && !is_solvable_;
}
// Returns true iff this is a commutative ring.
virtual bool is_weyl_algebra() const { return is_weyl_; }
// Returns true if this is a polynomial ring (possibly with quotient)
// (possibly with ZZ fractions, or other commutative fractions)
// but with Weyl algebra multiplication on some of the variables.
virtual bool is_skew_commutative_ring() const { return is_skew_; }
// Returns true if this is a polynomial ring (possibly with quotient)
// (possibly with ZZ fractions, or other commutative fractions)
// but with some variables anti-commuting.
virtual bool is_solvable_algebra() const { return is_solvable_; }
virtual const PolyRing *getNumeratorRing() const { return numerR_; }
virtual const PolynomialRing *getAmbientRing() const { return ambientR_; }
// Yields the ambient PolyRing corresponding to this polynomial ring
// This ring has no quotients, no fractions (not even QQ), but may have
// skew, weyl, or solvable multiplication, or even (later) be an associative
// free algebra.
virtual const Ring /* or null */ *getDenominatorRing() const
{
return denomR_;
}
// If this ring has no denominators, NULL is returned. Otherwise the ring
// which
// implements denominators is returned. When one asks for a denominator for
// elements of
// 'this', the result value is its ring.
virtual GBRing *get_gb_ring() const { return gb_ring_; }
virtual const Ring *getCoefficients() const { return K_; }
// The implementation coeff ring of 'this'. This is either a basic ring
// (field, ZZ), or
// is another PolyRing.
virtual const Monoid *getMonoid() const { return M_; }
// The implementation monoid of this ring.
virtual bool is_fraction_poly_ring() const
{
return getDenominatorRing() != 0;
}
// returns true if this ring has fractions. This includes
// polynomial rings over QQ, polynomial rings over fraction fields,
// fraction rings, and localizations.
// If this returns true, then 'get_denominator_ring()' returns non-NULL value.
//
virtual int n_fraction_vars() const
{
const Ring *D = getDenominatorRing();
if (D == 0) return 0;
const PolynomialRing *DR = D->cast_to_PolynomialRing();
if (DR == 0) return 0;
return DR->n_vars();
}
virtual const PolynomialRing *cast_to_PolynomialRing() const { return this; }
virtual PolynomialRing *cast_to_PolynomialRing() { return this; }
SumCollector *make_SumCollector() const;
////////////////////////////////
// To possibly be over-ridded //
////////////////////////////////
virtual void text_out(buffer &o) const = 0;
////////////////////////
// Arithmetic //////////
////////////////////////
virtual unsigned int computeHashValue(const ring_elem a) const;
virtual ring_elem var(int v) const = 0;
/////////////////////////
// Polynomial routines //
/////////////////////////
virtual int index_of_var(const ring_elem a) const = 0;
virtual M2_arrayint support(const ring_elem a) const = 0;
virtual bool is_homogeneous(const ring_elem f) const = 0;
virtual void degree(const ring_elem f, int *d) const = 0;
virtual bool multi_degree(const ring_elem f, int *d) const = 0;
virtual void degree_weights(const ring_elem f,
M2_arrayint wts,
int &lo,
int &hi) const = 0;
virtual ring_elem homogenize(const ring_elem f,
int v,
int deg,
M2_arrayint wts) const = 0;
virtual ring_elem homogenize(const ring_elem f,
int v,
M2_arrayint wts) const = 0;
virtual ring_elem mult_by_term(const ring_elem f,
const ring_elem c,
const int *m) const = 0;
virtual int n_flat_terms(const ring_elem f) const = 0;
virtual int n_logical_terms(int nvars0, const ring_elem f) const = 0;
virtual engine_RawArrayPairOrNull list_form(const Ring *coeffR,
const ring_elem f) const = 0;
virtual ring_elem *get_parts(const M2_arrayint wts,
const ring_elem f,
long &result_len) const = 0;
virtual ring_elem get_part(const M2_arrayint wts,
const ring_elem f,
bool lobound_given,
bool hibound_given,
long lobound,
long hibound) const = 0;
int n_terms(const ring_elem f) const { return n_flat_terms(f); }
// This is here mainly because geopoly requires n_terms.
virtual ring_elem make_flat_term(const ring_elem a, const int *m) const = 0;
virtual ring_elem make_logical_term(const Ring *coeffR,
const ring_elem a,
const int *exp) const = 0;
// virtual ring_elem term(const ring_elem a, const int *m) const = 0;
virtual ring_elem lead_flat_coeff(const ring_elem f) const = 0;
virtual ring_elem lead_logical_coeff(const Ring *coeffR,
const ring_elem f) const = 0;
virtual ring_elem get_coeff(const Ring *coeffR,
const ring_elem f,
const int *vp) const = 0;
// vp is a varpower monomial, in the logical monoid.
// The result will be an element in the logical coefficient ring.
virtual ring_elem get_terms(int nvars0,
const ring_elem f,
int lo,
int hi) const = 0;
// get the (logical) terms from lo to hi in f. A negative value means count
// from
// the end. get_terms(--,f,0,0) is the logical lead term of f.
virtual const int *lead_flat_monomial(const ring_elem f) const = 0;
virtual void lead_logical_exponents(int nvars0,
const ring_elem f,
int *result_exp) const = 0;
virtual void mult_coeff_to(ring_elem a, ring_elem &f) const = 0;
virtual void divide_coeff_to(ring_elem &f, ring_elem a) const = 0;
virtual void monomial_divisor(const ring_elem a, int *exp) const = 0;
virtual ring_elem diff(ring_elem a, ring_elem b, int use_coeff) const = 0;
virtual bool in_subring(int nslots, const ring_elem a) const = 0;
virtual void degree_of_var(int n,
const ring_elem a,
int &lo,
int &hi) const = 0;
virtual ring_elem divide_by_var(int n, int d, const ring_elem a) const = 0;
virtual ring_elem divide_by_expvector(const int *exp,
const ring_elem a) const = 0;
virtual Nterm *numerator(ring_elem f) const = 0;
protected:
void sort(Nterm *&f) const;
public:
virtual const vecterm *vec_locate_lead_term(const FreeModule *F,
vec v) const = 0;
// Returns a pointer to the vector term of v which contains the lead term (of
// the
// numerator).
// If result = R->vec_locate_lead_term(F,v), (if v is non-zero)
// To get the lead coeff, use result->comp
// To get the lead flat monomial (of numerator), use
// R->lead_flat_monomial(result->coeff).
virtual vec vec_lead_term(int nparts, const FreeModule *F, vec v) const = 0;
virtual vec vec_top_coefficient(const vec v, int &var, int &exp) const = 0;
virtual gbvector *translate_gbvector_from_ringelem(ring_elem coeff) const = 0;
virtual gbvector *translate_gbvector_from_vec(
const FreeModule *F,
const vec v,
ring_elem &result_denominator) const = 0;
// result/denom == v.
// result_denom will be an element in getDenominatorRing() (if non-NULL).
virtual vec translate_gbvector_to_vec(const FreeModule *F,
const gbvector *v) const = 0;
virtual vec translate_gbvector_to_vec_denom(const FreeModule *F,
const gbvector *v,
const ring_elem denom) const = 0;
// Translate v/denom to a vector in F. denom does not need to be positive,
// although it had better be non-zero.
// denom should be an element of getDenominatorRing() (if non-NULL, otherwise
// 'denom'
// is ignored).
};
/**
* \ingroup polynomialrings
*/
class PolyRingFlat : public PolynomialRing
// The class of polynomial rings implemented as a pointer (single value).
{
public:
virtual Nterm *numerator(ring_elem f) const { return f.poly_val; }
virtual const PolyRingFlat *cast_to_PolyRingFlat() const { return this; }
virtual PolyRingFlat *cast_to_PolyRingFlat() { return this; }
};
#endif
// Local Variables:
// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
// indent-tabs-mode: nil
// End:
|