File: polyring.hpp

package info (click to toggle)
macaulay2 1.21%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 133,096 kB
  • sloc: cpp: 110,377; ansic: 16,306; javascript: 4,193; makefile: 3,821; sh: 3,580; lisp: 764; yacc: 590; xml: 177; python: 140; perl: 114; lex: 65; awk: 3
file content (409 lines) | stat: -rw-r--r-- 15,442 bytes parent folder | download | duplicates (2)
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: