Macaulay2 Engine
Loading...
Searching...
No Matches
localring.cpp
Go to the documentation of this file.
1/* Copyright 2017 Mahrud Sayrafi and Michael E. Stillman
2 Mahrud Sayrafi's code in this file is in the public domain. */
3
4#include "localring.hpp"
5
6#include "interface/factory.h"
7#include "text-io.hpp"
8#include "ringmap.hpp"
9#include "monoid.hpp"
10#include "gbring.hpp"
11#include "relem.hpp"
12#include "debug.hpp"
13#include "matrix.hpp"
14#include "matrix-con.hpp"
15#include "mutablecomplex.hpp"
16#include "exceptions.hpp"
17
19{
21 result->initialize_local(R, P);
22 return result;
23}
24
26{
29
30 mRing = R;
31 mPrime = P;
32
33 oneV = from_long(1);
34 zeroV = from_long(0);
36
37 /*
38 if (R->n_quotients() > 0 ||
39 R->getCoefficients()
40 ->cast_to_LocalRing() // disallowed in x-relem.cpp
41 ||
42 R->getMonoid()->numNonTermOrderVariables() >
43 0) // disallowed in x-relem.cpp
44 use_gcd_simplify = false;
45 else
46 use_gcd_simplify = true;
47 */
48
49 return true;
50}
51
53{
55 result->numer = a;
56 result->denom = b;
58 return result;
59}
60
62
64{
65 MatrixConstructor mat(mRing->make_FreeModule(1), 1);
66 mat.set_entry(0, 0, f);
67 Matrix *M = mat.to_matrix();
68 bool res = (mPrime->contains(M) == -1);
69 delete M;
70 return res;
71}
72
74{
75 ring_elem x, y;
77 {
78 y = f->denom;
79 if (mRing->is_equal(y, mRing->one())) return;
80 x = f->numer;
83 const RingElement *c = rawGCDRingElement(a, b, nullptr, false);
84
85#if 0
86 // Debugging code
87 buffer o;
88 o << newline;
89 o << "a = ";
90 a->text_out(o);
91 o << " b = ";
92 b->text_out(o);
93 o << " gcd = ";
94 c->text_out(o);
95 o << newline;
96 emit(o.str());
97#endif
98 if (!mRing->is_equal(c->get_value(), mRing->one()))
99 {
100 f->numer = mRing->divide(f->numer, c->get_value());
101 f->denom = mRing->divide(f->denom, c->get_value());
102 }
103 // Now, let's take the content of the denominator, and divide the
104 // numerator
105 // and denominator by this value.
106 ring_elem ct = mRing->content(
107 f->denom, f->numer); // result is in mRing->getCoefficients()
108
109#if 0
110 o.reset();
111 o << "f->numer = ";
112 mRing->elem_text_out(o,f->numer);
113 o << " f->denom = ";
114 mRing->elem_text_out(o,f->denom);
115 o << " ass= ";
116 mRing->getCoefficients()->elem_text_out(o,ct);
117 o << newline;
118 emit(o.str());
119#endif
120
121 if (!mRing->getCoefficients()->is_equal(ct,
122 mRing->getCoefficients()->one()))
123 {
124 f->numer = mRing->divide_by_given_content(f->numer, ct);
125 f->denom = mRing->divide_by_given_content(f->denom, ct);
126 }
127 }
128 else
129 {
130 mRing->syzygy(f->numer, f->denom, x, y);
131 if (mRing->is_zero(x))
132 {
133 mRing->remove(x);
135 f->numer = mRing->zero();
136 f->denom = mRing->one();
137 return;
138 }
139 mRing->negate_to(y);
140 mRing->remove(f->numer);
141 mRing->remove(f->denom);
142 f->numer = y;
143 f->denom = x;
144 }
145}
146
148{
149 // Sets the non unit to be top/1 (which flags an error)
150 // flags an error
151 // returns 0/1
152
153 std::cout << "set_non_unit_frac is called!" << std::endl;
154
156 f->numer = top;
157 f->denom = mRing->one();
159 return zero();
160}
161
163{
164 const PolynomialRing *A = mRing->cast_to_PolynomialRing();
165 assert(A != 0);
166 const Ring *K = A->getCoefficientRing();
167 if (K->coefficient_type() == COEFF_ZZ) return COEFF_QQ;
168 return K->coefficient_type();
169}
170
171// TODO: extend to arbitrary multiplicative sets
172bool LocalRing::is_unit(const ring_elem f) const
173{
174 // TODO: make sure f is a local ring element
175 return (!is_in_prime(f.get_local_elem()->numer));
176}
177
178bool LocalRing::is_zero(const ring_elem f) const
179{
180 return (mRing->is_zero(f.get_local_elem()->numer));
181}
182
183bool LocalRing::is_equal(const ring_elem a, const ring_elem b) const
184{
185 const local_elem *f = a.get_local_elem();
186 const local_elem *g = b.get_local_elem();
187 if (mRing->is_equal(f->denom, g->denom))
188 {
189 return mRing->is_equal(f->numer, g->numer);
190 }
191 else
192 {
193 ring_elem h = subtract(a, b);
194 bool result = is_zero(h);
195 remove(h);
196 return result;
197 }
198}
199
201{
202 const local_elem *f = a.get_local_elem();
203 const local_elem *g = b.get_local_elem();
204 int cmp = mRing->compare_elems(f->numer, g->numer);
205 if (cmp != 0) return cmp;
206 return mRing->compare_elems(f->denom, g->denom);
207}
208
210{
211 const local_elem *g = f.get_local_elem();
212 return mRing->copy(g->numer);
213}
214
216{
217 const local_elem *g = f.get_local_elem();
218 return mRing->copy(g->denom);
219}
220
221ring_elem LocalRing::fraction(const ring_elem top, const ring_elem bottom) const
222{
223 return ring_elem(make_elem(mRing->copy(top), mRing->copy(bottom)));
224}
225
226// TODO: implement for MutableMatrix
227void LocalRing::lift_up(const Ring *R, const Matrix *m, Matrix *&result) const
228{
229 (void) R;
230 const RingElement *a, *b, *d;
231 MatrixConstructor mat(mRing->make_FreeModule(m->n_rows()), m->n_cols());
232 Matrix::column_iterator i(m), end(m);
233 for (int c = 0; c < m->n_cols(); c++)
234 {
235 // TODO: make this into a routine for vector LCM
236 a = RingElement::make_raw(mRing, mRing->from_long(1));
237 for (i = Matrix::column_iterator(m, c); i != end; ++i)
238 {
239 const local_elem * f = ((*i)->coeff).get_local_elem();
241 d = rawGCDRingElement(a, b, nullptr, false);
242#if 0 // FIXME: GCD(8,2)=1 apparently ...
243 // see https://github.com/Macaulay2/M2/issues/1958
244 drelem(a);
245 std::cout<<" ";
246 drelem(b);
247 std::cout<<" ";
248 drelem(d);
249 std::cout<<std::endl;
250#endif
251 d = *b / *d;
252 a = *a * *d;
253 }
254 for (i = Matrix::column_iterator(m, c); i != end; ++i)
255 {
256 const local_elem * f = ((*i)->coeff).get_local_elem();
257 mat.set_entry(
258 (*i)->comp,
259 c,
260 mRing->mult(f->numer, mRing->divide(a->get_value(), f->denom)));
261 }
262 }
264 result = mat.to_matrix();
265}
266
267bool LocalRing::lift(const Ring *Rg, const ring_elem f, ring_elem &result) const
268{
269 // Rg = R ---> frac R
270 // f is an element of frac R.
271
273 hdenom; // used in the case when the denominator can be a unit, but not 1
274 // e.g. when this = frac (QQ[x,y,z]). Is an element of
275 if (Rg == mRing)
276 {
277 const local_elem *h = f.get_local_elem();
278 if (mRing->is_equal(h->denom, mRing->one()))
279 {
280 result = mRing->copy(h->numer);
281 return true;
282 }
283 else
284 {
285 if (mRing->is_field())
286 {
287 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
288 // try to lift denominator. If can, can lift, otherwise not.
289 if (mRing->lift(mRing, h->denom, hdenom))
290 {
291 ring_elem hinv = mRing->invert(hdenom);
292 result = mRing->mult(hinv, h->numer);
293 return true;
294 }
295 }
296 }
297 }
298 return false;
299}
300
302 const ring_elem f,
303 ring_elem &result) const
304{
305 // Rf = R ---> frac R
306 if (Rf == mRing)
307 {
309 g->numer = mRing->copy(f);
310 g->denom = mRing->from_long(1);
311 result = ring_elem(g);
312 return true;
313 }
314
315 return false;
316}
317
318bool LocalRing::from_rational(mpq_srcptr n, ring_elem &result) const
319{
321 f->numer = mRing->from_int(mpq_numref(n));
322 f->denom = mRing->from_int(mpq_denref(n));
323 bool ok = not mRing->is_zero(f->denom);
324 if (ok) result = ring_elem(f);
325 return ok;
326}
327
329{
331 f->numer = mRing->from_long(n);
332 f->denom = mRing->from_long(1);
333 return ring_elem(f);
334}
335
337{
339 f->numer = mRing->from_int(n);
340 f->denom = mRing->from_long(1);
341 return ring_elem(f);
342}
343
345{
347 f->numer = mRing->var(v);
348 f->denom = mRing->from_long(1);
349 return ring_elem(f);
350}
351
353{
354 const local_elem *f = a.get_local_elem();
355 if (!mRing->is_unit(f->denom))
356 // If so, a cannot be a variable, otherwise, by 'simplify', f->denom == 1.
357 return -1;
358 return mRing->index_of_var(f->numer);
359}
360
362{
363 const local_elem *f = a.get_local_elem();
364 M2_arrayint result1 = mRing->support(f->numer);
365 M2_arrayint result2 = mRing->support(f->denom);
366 M2_arrayint result = M2_makearrayint(result1->len + result2->len);
367 for (int i = 0; i < result1->len; i++) result->array[i] = result1->array[i];
368 for (int i = 0; i < result2->len; i++)
369 result->array[result1->len + i] = result2->array[i];
370 return result;
371}
372
374{
375 if (!use_gcd_simplify) return;
376 if (is_zero(c))
377 {
378 c = g;
379 return;
380 }
381
382 const local_elem *cf = c.get_local_elem();
383 const local_elem *gf = g.get_local_elem();
388
389 c1 = rawGCDRingElement(c1, g1, nullptr, false);
390
391 const RingElement *cc2 = rawGCDRingElement(c2, g2, nullptr, false);
392 const RingElement *cc3 = (*c2) * (*g2);
393 const RingElement *cc4 = (*cc3) / (*cc2);
394
396 result->numer = c1->get_value();
397 result->denom = cc4->get_value();
398
399 c = ring_elem(result);
400}
401
403{
404 if (is_zero(a)) return true;
405 const local_elem *f = a.get_local_elem();
406 if (!mRing->is_homogeneous(f->numer) || !mRing->is_homogeneous(f->denom))
407 return false;
408 return true;
409}
410
412{
413 const local_elem *f = a.get_local_elem();
414 bool tophom = mRing->multi_degree(f->numer, d);
416 bool bottomhom = mRing->multi_degree(f->denom, e);
417 degree_monoid()->divide(d, e, d);
418 degree_monoid()->remove(e);
419 return tophom && bottomhom;
420}
421
423 const std::vector<int> &,
424 int &lo,
425 int &hi) const
426{
427 assert(0);
428 // MES: what should this do?
429 lo = hi = 0;
430}
431
433 int v,
434 int deg,
435 const std::vector<int> &wts) const
436{
437 int d1, d2, lo1, lo2;
438 ring_elem top, bottom;
439 const local_elem *f = a.get_local_elem();
440 mRing->degree_weights(f->numer, wts, lo1, d1);
441 mRing->degree_weights(f->denom, wts, lo2, d2);
442 if (deg >= d1 - d2)
443 {
444 top = mRing->homogenize(f->numer, v, deg + d2, wts);
445 bottom = mRing->homogenize(f->denom, v, d2, wts);
446 }
447 else
448 {
449 top = mRing->homogenize(f->numer, v, d1, wts);
450 bottom = mRing->homogenize(f->denom, v, -deg + d1, wts);
451 }
452 local_elem *result = make_elem(top, bottom);
453 return ring_elem(result);
454}
455
457 int v,
458 const std::vector<int> &wts) const
459{
460 const local_elem *f = a.get_local_elem();
461 ring_elem top = mRing->homogenize(f->numer, v, wts);
462 ring_elem bottom = mRing->homogenize(f->denom, v, wts);
463 local_elem *result = make_elem(top, bottom);
464 return ring_elem(result);
465}
466
468{
469 const local_elem *f = a.get_local_elem();
471 g->numer = mRing->copy(f->numer);
472 g->denom = mRing->copy(f->denom);
473 return ring_elem(g);
474}
475
476void LocalRing::remove(ring_elem &a) const { (void) a; }
477
479{
480 const local_elem *f = a.get_local_elem();
482 result->numer = mRing->negate(f->numer);
483 result->denom = mRing->copy(f->denom);
484 return ring_elem(result);
485}
486
488{
489 const local_elem *f = a.get_local_elem();
490 const local_elem *g = b.get_local_elem();
491 ring_elem top, bottom;
492
493 if (mRing->is_equal(f->denom, g->denom))
494 {
495 top = mRing->add(f->numer, g->numer);
496 bottom = mRing->copy(f->denom);
497 }
498 else
499 {
500 top = mRing->mult(f->numer, g->denom);
501 ring_elem tmp = mRing->mult(f->denom, g->numer);
502 mRing->add_to(top, tmp);
503 bottom = mRing->mult(f->denom, g->denom);
504 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->denom);
505 }
506 local_elem *result = make_elem(top, bottom);
507 return ring_elem(result);
508}
509
511{
512 const local_elem *f = a.get_local_elem();
513 const local_elem *g = b.get_local_elem();
514 ring_elem top, bottom;
515
516 if (mRing->is_equal(f->denom, g->denom))
517 {
518 top = mRing->subtract(f->numer, g->numer);
519 bottom = mRing->copy(f->denom);
520 }
521 else
522 {
523 top = mRing->mult(f->numer, g->denom);
524 ring_elem tmp = mRing->mult(f->denom, g->numer);
525 mRing->subtract_to(top, tmp);
526 bottom = mRing->mult(f->denom, g->denom);
527 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->denom);
528 }
529 local_elem *result = make_elem(top, bottom);
530 return ring_elem(result);
531}
532
534{
535 const local_elem *f = a.get_local_elem();
536 const local_elem *g = b.get_local_elem();
537 ring_elem top = mRing->mult(f->numer, g->numer);
538 ring_elem bottom = mRing->mult(f->denom, g->denom);
539 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->denom);
540 return ring_elem(make_elem(top, bottom));
541}
542
544{
545 const local_elem *f = a.get_local_elem();
546 ring_elem top, bottom;
547 if (n >= 0)
548 {
549 top = mRing->power(f->numer, n);
550 bottom = mRing->power(f->denom, n);
551
552 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->denom);
553 }
554 else
555 {
556 if (is_unit(a))
557 {
558 top = mRing->power(f->denom, -n);
559 bottom = mRing->power(f->numer, -n);
560 }
561 else
562 {
563 throw exc::engine_error("attempt to divide by a non-unit");
564 }
565
566 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->numer);
567 }
568 return ring_elem(make_elem(top, bottom));
569}
570ring_elem LocalRing::power(const ring_elem a, mpz_srcptr n) const
571{
572 const local_elem *f = a.get_local_elem();
573 ring_elem top, bottom;
574 if (mpz_sgn(n) >= 0)
575 {
576 top = mRing->power(f->numer, n);
577 bottom = mRing->power(f->denom, n);
578
579 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->denom);
580 }
581 else
582 {
583 mpz_t negative_n;
584 mpz_init(negative_n);
585 mpz_neg(negative_n, n);
586 if (not is_unit(a))
587 {
588 throw exc::engine_error("attempt to divide by a non-unit");
589 }
590 top = mRing->power(f->denom, negative_n);
591 bottom = mRing->power(f->numer, negative_n);
592 mpz_clear(negative_n);
593
594 if (mRing->is_zero(bottom)) return set_non_unit_frac(f->numer);
595 }
596 return ring_elem(make_elem(top, bottom));
597}
598
600{
601 const local_elem *f = a.get_local_elem();
602 if (mRing->is_zero(f->numer) || !is_unit(a))
603 {
604 throw exc::engine_error("attempt to invert a non-unit");
605 }
606 ring_elem top = mRing->copy(f->denom);
607 ring_elem bottom = mRing->copy(f->numer);
608 return ring_elem(make_elem(top, bottom));
609}
610
612{
613 const local_elem *f = a.get_local_elem();
614 const local_elem *g = b.get_local_elem();
615 ring_elem top, bottom;
616 if (is_unit(b))
617 {
618 top = mRing->mult(f->numer, g->denom);
619 bottom = mRing->mult(f->denom, g->numer);
620 }
621 else
622 {
623 throw exc::engine_error("attempt to divide by a non-unit");
624 }
625 return ring_elem(make_elem(top, bottom));
626}
627
629 const ring_elem b,
630 ring_elem &x,
631 ring_elem &y) const
632{
634 y = LocalRing::divide(a, b);
635 y = LocalRing::negate(y);
636}
637
639{
640 ring_elem a = mRing->random();
641 ring_elem b = mRing->random();
642 if (mRing->is_zero(b))
643 {
644 mRing->remove(b);
645 b = mRing->from_long(1);
646 }
647 return ring_elem(make_elem(a, b));
648}
649
651 const ring_elem a,
652 int first_var) const
653{
654 ring_elem top, bottom, result;
655 const Ring *S = map->get_ring();
656 const local_elem *f = a.get_local_elem();
657 top = mRing->eval(map, f->numer, first_var);
658 if (S->is_zero(top)) return top;
659 bottom = mRing->eval(map, f->denom, first_var);
660 if (S->is_unit(bottom))
661 result = S->divide(top, bottom);
662 else
663 {
664 throw exc::engine_error("attempt to divide by a non-unit");
665 }
666 S->remove(top);
667 S->remove(bottom);
668 return result;
669}
670
671int LocalRing::n_fraction_vars() const { return mRing->n_vars(); }
673{
674 return mRing->n_terms(a.get_local_elem()->numer);
675}
676ring_elem LocalRing::term(const ring_elem a, const int *) const
677{
678 return copy(a);
679}
680ring_elem LocalRing::lead_coeff(const ring_elem f) const { return f; }
681ring_elem LocalRing::get_coeff(const ring_elem f, const int *) const
682{
683 return f;
684}
685ring_elem LocalRing::get_terms(int nvars0, const ring_elem f, int, int) const
686{
687 (void) nvars0;
688 (void) f;
689 return f;
690}
691
693{
694 o << "LocalRing(";
695 mRing->text_out(o);
696 o << ", Prime ideal => ";
697 mPrime->get_mingens()->text_out(o);
698 o << ")";
699}
700
702 const ring_elem a,
703 bool p_one,
704 bool p_plus,
705 bool p_parens) const
706{
707 const local_elem *f = a.get_local_elem();
708 int denom_one = mRing->is_equal(f->denom, mRing->one());
709
710 p_one = p_one || !denom_one;
711 p_parens = p_parens || !denom_one;
712 mRing->elem_text_out(o, f->numer, p_one, p_plus, p_parens);
713 if (!denom_one)
714 {
715 o << "/";
716 p_plus = false;
717 mRing->elem_text_out(o, f->denom, p_one, p_plus, p_parens);
718 }
719}
720
721unsigned int LocalRing::computeHashValue(const ring_elem f) const
722{
723 const local_elem *g = f.get_local_elem();
724 return (16473 * mRing->computeHashValue(g->numer) +
725 7698908 * mRing->computeHashValue(g->denom));
726}
727
728/********************************************************************************/
729/* Global functions */
730/********************************************************************************/
731
732extern "C" { // TODO: remove when this function is in e/interface
733
735{
736 const LocalRing *L = f->get_ring()->cast_to_LocalRing();
737 if (L == nullptr)
738 {
739 ERROR("expected an object over a local ring");
740 return nullptr;
741 }
742 // TODO: Check that f is over a localization of R
743 if (R != L->get_ring())
744 {
745 ERROR("expected an object over a localization of the first argument");
746 return nullptr;
747 }
748 Matrix *result;
749 L->lift_up(R, f, result);
750 return result;
751}
752
754{
755 const LocalRing *L = f->get_ring()->cast_to_LocalRing();
756 if (L == nullptr)
757 {
758 ERROR("expected an object over a local ring");
759 return false;
760 }
761 return L->is_unit(f->get_value());
762}
763
764} // TODO: remove when this function is in e/interface
765
766// Local Variables:
767// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
768// indent-tabs-mode: nil
769// End:
base class for Groebner basis computations.
Definition comp-gb.hpp:69
virtual ring_elem add(const ring_elem f, const ring_elem g) const
ring_elem set_non_unit_frac(ring_elem top) const
virtual void text_out(buffer &o) const
virtual bool is_homogeneous(const ring_elem f) const
virtual ring_elem copy(const ring_elem f) const
virtual ring_elem eval(const RingMap *map, const ring_elem f, int first_var) const
virtual ring_elem homogenize(const ring_elem f, int v, int deg, const std::vector< int > &wts) const
virtual int index_of_var(const ring_elem a) const
ring_elem numerator(ring_elem f) const
virtual void lift_up(const Ring *R, const Matrix *m, Matrix *&result) const
virtual ring_elem from_long(long n) const
virtual ring_elem var(int v) const
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
local_elem * make_elem(ring_elem a, ring_elem b) const
Definition localring.cpp:52
virtual ring_elem negate(const ring_elem f) const
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const
virtual ring_elem get_coeff(const ring_elem f, const_monomial m) const
virtual ring_elem term(const ring_elem a, const_monomial m) const
GBComputation * mPrime
Definition localring.hpp:70
virtual bool multi_degree(const ring_elem f, monomial d) const
virtual ring_elem invert(const ring_elem f) const
virtual bool promote(const Ring *R, const ring_elem f, ring_elem &result) const
ring_elem fraction(const ring_elem top, const ring_elem bottom) const
virtual CoefficientType coefficient_type() const
virtual void syzygy(const ring_elem a, const ring_elem b, ring_elem &x, ring_elem &y) const
virtual ring_elem lead_coeff(const ring_elem f) const
virtual ring_elem power(const ring_elem f, mpz_srcptr n) const
Exponentiation. This is the default function, if a class doesn't define this.
virtual bool is_unit(const ring_elem f) const
ring_elem denominator(ring_elem f) const
virtual unsigned int computeHashValue(const ring_elem a) const
virtual ring_elem get_terms(int nvars0, const ring_elem f, int lo, int hi) const
const PolyRing * mRing
Definition localring.hpp:69
virtual int n_terms(const ring_elem f) const
const PolyRing * get_ring() const
Definition localring.hpp:90
bool is_in_prime(const ring_elem f) const
Definition localring.cpp:63
virtual bool is_equal(const ring_elem f, const ring_elem g) const
virtual void remove(ring_elem &f) const
virtual ring_elem from_int(mpz_srcptr n) const
virtual ring_elem random() const
virtual int compare_elems(const ring_elem f, const ring_elem g) const
virtual void degree_weights(const ring_elem f, const std::vector< int > &wts, int &lo, int &hi) const
virtual M2_arrayint support(const ring_elem a) const
void lower_content(ring_elem &c, const ring_elem g) const
virtual ring_elem divide(const ring_elem f, const ring_elem g) const
virtual bool from_rational(mpq_srcptr n, ring_elem &result) const
static LocalRing * create(const PolyRing *R, GBComputation *P)
Definition localring.cpp:18
virtual bool is_zero(const ring_elem f) const
bool initialize_local(const PolyRing *R, GBComputation *P)
Definition localring.cpp:25
virtual int n_fraction_vars() const
bool use_gcd_simplify
Definition localring.hpp:83
virtual ring_elem subtract(const ring_elem f, const ring_elem g) const
local_elem * new_local_elem() const
Definition localring.cpp:61
virtual bool lift(const Ring *R, const ring_elem f, ring_elem &result) const
void simplify(local_elem *f) const
Definition localring.cpp:73
Engine-side localisation of a polynomial ring at a prime ideal.
Definition localring.hpp:67
const Ring * get_ring() const
Definition matrix.hpp:134
int n_cols() const
Definition matrix.hpp:147
int n_rows() const
Definition matrix.hpp:146
Matrix * to_matrix()
void compute_column_degrees()
void set_entry(int r, int c, ring_elem a)
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
monomial make_one() const
Definition monoid.cpp:455
void remove(monomial d) const
Definition monoid.cpp:462
void divide(const_monomial m, const_monomial n, monomial result) const
Definition monoid.hpp:331
Concrete PolyRingFlat subclass implementing ordinary commutative polynomial rings K[x_1,...
Definition poly.hpp:64
const Ring * getCoefficientRing() const
Definition polyring.hpp:200
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual void remove(ring_elem &f) const =0
void set_non_unit(ring_elem zero_div) const
Definition ring.cpp:88
virtual ring_elem divide(const ring_elem f, const ring_elem g) const =0
virtual bool is_unit(const ring_elem f) const =0
ring_elem minus_oneV
Definition ring.hpp:131
ring_elem zero() const
Definition ring.hpp:359
void initialize_ring(long charac, const PolynomialRing *DR=nullptr, const std::vector< int > &heft_vec={})
Definition ring.cpp:30
long characteristic() const
Definition ring.hpp:159
virtual const LocalRing * cast_to_LocalRing() const
Definition ring.hpp:253
ring_elem oneV
Definition ring.hpp:130
CoefficientType
Definition ring.hpp:222
@ COEFF_QQ
Definition ring.hpp:222
@ COEFF_ZZ
Definition ring.hpp:222
virtual bool is_zero(const ring_elem f) const =0
const PolynomialRing * get_degree_ring() const
Definition ring.hpp:161
virtual CoefficientType coefficient_type() const
Definition ring.hpp:223
const Monoid * degree_monoid() const
Definition ring.cpp:13
const std::vector< int > & get_heft_vector() const
Definition ring.hpp:162
ring_elem zeroV
Definition ring.hpp:129
Ring()
Definition ring.hpp:136
void text_out(buffer &o) const
Definition relem.cpp:142
ring_elem get_value() const
Definition relem.hpp:79
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
const Ring * get_ring() const
Definition relem.hpp:81
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
xxx xxx xxx
Definition ring.hpp:102
const Ring * get_ring() const
Definition ringmap.hpp:111
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
char * str()
Definition buffer.hpp:72
void reset()
Definition buffer.hpp:69
void drelem(const RingElement *f)
Definition debug.cpp:59
Debugger-callable d* helpers that pretty-print engine values to stderr.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
#define Matrix
Definition factory.cpp:14
const RingElement * rawGCDRingElement(const RingElement *f, const RingElement *g, const RingElement *mipo, const M2_bool inExtension)
Definition factory.cpp:488
Engine-boundary C API for polynomial GCD, factorisation, and root finding.
#define monomial
Definition gb-toric.cpp:11
GBRing and gbvector — the GB-tuned polynomial-ring view used by classical Buchberger code.
M2_bool rawIsLocalUnit(const RingElement *f)
Matrix * rawLiftLocalMatrix(const Ring *R, const Matrix *f)
LocalRing — localisation of a polynomial ring at a prime ideal P.
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
char newline[]
Definition m2-types.cpp:49
char M2_bool
Definition m2-types.h:82
MatrixConstructor — the mutable builder that produces an immutable Matrix.
Matrix — the engine's immutable homomorphism F -> G between free modules.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
MutableComplex — in-place chain complex of MutableMatrix differentials.
#define newitem(T)
Definition newdelete.hpp:86
volatile int x
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
RingMap — engine representation of a ring homomorphism.
ring_elem numer
Definition localring.hpp:48
ring_elem denom
Definition localring.hpp:49
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
const local_elem * get_local_elem() const
Definition ringelem.hpp:136