Macaulay2 Engine
Loading...
Searching...
No Matches
FreeAlgebra.cpp
Go to the documentation of this file.
1#include "FreeAlgebra.hpp"
2
3#include "NCAlgebras/FreeMonoid.hpp" // for FreeMonoid
4#include "NCAlgebras/Word.hpp" // for Word
5#include "Polynomial.hpp" // for Poly, Polynomial<>::const_iterator
6#include "ZZ.hpp" // for RingZZ
7#include "buffer.hpp" // for buffer
8#include "error.h" // for ERROR
9#include "monoid.hpp" // for Monoid
10#include "ringmap.hpp" // for RingMap
11
12#include <cassert> // for assert
13#include <ostream> // for operator<<, ostream, string
14#include <type_traits> // for swap
15#include <utility> // for make_pair, pair
16
17class PolynomialRing; // lines 14-14
18
19std::ostream& operator<<(std::ostream& o, const FreeAlgebraElement& f)
20{
21 buffer b;
22 f.ring().elem_text_out(b, *f, true, false, false);
23 o << b.str();
24 return o;
25}
26
27// FreeAlgebraHeap functions
28
33
35{
36 // The user of this class must insure that the heap has been reset.
37 // i.e. call value() routine.
38}
39
41{
42 auto len = p.numTerms();
43 int i = 0;
44 while (len >= heap_size[i]) i++;
45
46 Poly tmp1;
47 F.init(tmp1);
48 F.add(tmp1, heap[i], p);
49 std::swap(heap[i], tmp1);
50 F.setZero(tmp1);
51
52 len = heap[i].numTerms();
53 while (len >= heap_size[i])
54 {
55 i++;
56 F.add(tmp1, heap[i], heap[i-1]);
57 std::swap(heap[i], tmp1);
58 F.setZero(tmp1);
59 F.setZero(heap[i-1]);
60
61 len = heap[i].numTerms();
62 }
63 if (i > top_of_heap) top_of_heap = i;
64}
65
67{
68 Poly tmp1;
69 F.init(tmp1);
70 for (int i = 0; i <= top_of_heap; i++)
71 {
72 if (heap[i].numTerms() == 0) continue;
73 F.add(tmp1, result, heap[i]);
74 std::swap(result, tmp1);
75 F.setZero(tmp1);
76 F.setZero(heap[i]);
77 }
78 top_of_heap = -1;
79 F.clear(tmp1);
80}
81
82// SumCollector functions
83
88
89// FreeAlgebra starts here
90
92 const std::vector<std::string>& names,
94 const std::vector<int>& degrees,
95 const std::vector<int>& wtvecs,
96 const std::vector<int>& heftVector
97 )
98{
99 assert(K != nullptr);
100 std::shared_ptr<FreeMonoid> M (new FreeMonoid(names, degreeRing, degrees, wtvecs, heftVector));
101 FreeAlgebra* result = new FreeAlgebra(K, M);
102
103 return result;
104}
105
107 std::shared_ptr<FreeMonoid> M
108 )
109 : mCoefficientRing(*K),
110 mMonoid(M)
111{
112}
113
115{
116 // TODO: need Polynomial type to allow us access, or have a clear function itself.
117 setZero(f);
118}
119
121{
122 for (auto a : f.mCoefficients)
124
125 f.mCoefficients.clear();
126 f.mMonomials.clear();
127}
128
130{
131 if (not coefficientRing()->is_zero(a))
132 {
133 result.getCoeffInserter().push_back(a);
134 monoid().one(result.getMonomInserter());
135 }
136}
137
142
143void FreeAlgebra::from_int(Poly& result, mpz_srcptr n) const
144{
146}
147
148bool FreeAlgebra::from_rational(Poly& result, const mpq_srcptr q) const
149{
150 ring_elem cq; // in coeff ring.
151 bool worked = coefficientRing()->from_rational(q, cq);
152 if (!worked) return false;
154 return true;
155}
156
157void FreeAlgebra::copy(Poly& result, Poly::const_iterator fBegin, Poly::const_iterator fEnd) const
158{
159 clear(result);
160 auto& resultCoeff = result.getCoeffInserter();
161 auto& resultMonom = result.getMonomInserter();
162 resultCoeff.insert(resultCoeff.end(),
163 fBegin.cCoeffIterator(),
164 fEnd.cCoeffIterator());
165 resultMonom.insert(resultMonom.end(),
166 fBegin.cMonomIterator(),
167 fEnd.cMonomIterator());
168}
169void FreeAlgebra::copy(Poly& result, const Poly& f) const
170{
171 copy(result, f.cbegin(), f.cend());
172}
173
174void FreeAlgebra::swap(Poly& f, Poly& g) const
175{
176 auto& fCoeff = f.getCoeffInserter();
177 auto& fMonom = f.getMonomInserter();
178 auto& gCoeff = g.getCoeffInserter();
179 auto& gMonom = g.getMonomInserter();
180 std::swap(fCoeff,gCoeff);
181 std::swap(fMonom,gMonom);
182}
183
184void FreeAlgebra::var(Poly& result, int v) const
185{
186 result.getCoeffInserter().push_back(coefficientRing()->from_long(1));
187 monoid().var(v, result.getMonomInserter());
188}
189
190// the below was copied over from poly.cpp. Working on adding
191// support to the freeAlgebra class. WIP
193{
194 int numVarsFound = 0;
195 std::vector<int> exp, exp2;
196 auto fIt = f.cbegin();
197 auto fEnd = f.cend();
198
199 for (auto i = 0; i < numVars(); i++)
200 exp2.push_back(0);
201
202 for ( ; fIt != fEnd; fIt++)
203 {
204 monoid().support(fIt.monom(),exp);
205 for (auto i : exp)
206 {
207 if (exp2[i] == 0)
208 {
209 exp2[i]++;
210 numVarsFound++;
211 }
212 }
213 if (numVarsFound == numVars()) break;
214 }
215
216 exp.clear();
217 for (int i = 0; i < numVars(); i++)
218 if (exp2[i] > 0) exp.push_back(i);
219
220 M2_arrayint result = M2_makearrayint(exp.size());
221 int next = 0;
222 for (auto i : exp)
223 result->array[next++] = i;
224 return result;
225}
226
227void FreeAlgebra::from_word(Poly& result, ring_elem coeff, const std::vector<int>& word) const
228{
229 Word tmpWord;
230 tmpWord.init(word.data(),word.data() + word.size());
231 from_word(result,coeff,tmpWord);
232}
233
235{
236 auto& resultCoeff = result.getCoeffInserter();
237 auto& resultMonom = result.getMonomInserter();
238 resultCoeff.push_back(coeff);
239
240 monoid().monomInsertFromWord(resultMonom,word);
241}
242
243void FreeAlgebra::from_word(Poly& result, const std::vector<int>& word) const
244{
246}
247
252
253bool FreeAlgebra::is_unit(const Poly& f) const
254{
255 if (f.numTerms() != 1) return false;
256 auto i = f.cbegin();
257 return monoid().is_one(i.monom()) && coefficientRing()->is_unit(i.coeff());
258}
259
260int FreeAlgebra::compare_elems(const Poly& f, const Poly& g) const
261{
262 auto fIt = f.cbegin();
263 auto gIt = g.cbegin();
264 auto fEnd = f.cend();
265 auto gEnd = g.cend();
266 int cmp;
267 for ( ; ; fIt++, gIt++)
268 {
269 if (fIt == fEnd)
270 {
271 if (gIt == gEnd) return EQ;
272 return LT;
273 }
274 if (gIt == gEnd) return GT;
275 // TODO: can we remove the following block? Make sure monoid can handle zero variables...
276 if (numVars() > 0)
277 {
278 cmp = monoid().compare(fIt.monom(),gIt.monom());
279 if (cmp != 0) return cmp;
280 }
281 // if we are here, then the monomials are the same and we compare coefficients.
282 // for example if a,b are in the base and a > b then ax > bx.
283 cmp = coefficientRing()->compare_elems(fIt.coeff(), fIt.coeff());
284 if (cmp != 0) return cmp;
285 }
286}
287
288bool FreeAlgebra::is_equal(const Poly& f, const Poly& g) const
289{
290 if (f.numTerms() != g.numTerms()) return false;
291 if (f.getMonomVector() != g.getMonomVector()) return false;
292 auto fCoeffIt = f.cbeginCoeff();
293 auto gCoeffIt = g.cbeginCoeff();
294 auto fEnd = f.cendCoeff();
295 for ( ; fCoeffIt != fEnd ; fCoeffIt++, gCoeffIt++)
296 {
297 bool cmp = coefficientRing()->is_equal(*fCoeffIt, *gCoeffIt);
298 if (!cmp) return false;
299 }
300 return true;
301}
302
303void FreeAlgebra::negate(Poly& result, const Poly& f) const
304{
305 auto& outmonom = result.getMonomInserter();
306 auto& outcoeff = result.getCoeffInserter();
307
308 for (auto i = f.cbeginMonom(); i != f.cendMonom(); ++i)
309 outmonom.push_back(*i);
310
311 for (auto i=f.cbeginCoeff(); i != f.cendCoeff(); ++i)
312 outcoeff.push_back(coefficientRing()->negate(*i));
313}
314
316 Poly::const_iterator fBegin,
317 Poly::const_iterator fEnd,
318 Poly::const_iterator gBegin,
319 Poly::const_iterator gEnd,
320 ring_elem coeff) const
321{
322 auto& outcoeff = result.getCoeffInserter();
323 auto& outmonom = result.getMonomInserter();
324
325 // loop over the iterators for f and g, adding the bigger of the two to
326 // the back of the monomial and coefficient vectors of the result. If a tie, add the coefficients.
327 while ((fBegin != fEnd) && (gBegin != gEnd))
328 {
329 auto fMon = fBegin.monom();
330 auto gMon = gBegin.monom();
331 auto fCoeff = fBegin.coeff();
332 auto gCoeff = gBegin.coeff();
333 ring_elem coeffResult;
334 switch(monoid().compare(fMon,gMon))
335 {
336 case LT:
337 coeffResult = coefficientRing()->mult(coeff,gCoeff);
338 if (!coefficientRing()->is_zero(coeffResult))
339 {
340 outcoeff.push_back(coeffResult);
341 monoid().copy(gMon, outmonom);
342 }
343 gBegin++;
344 break;
345 case GT:
346 outcoeff.push_back(fCoeff);
347 monoid().copy(fMon, outmonom);
348 fBegin++;
349 break;
350 case EQ:
351 ring_elem tempResult = coefficientRing()->mult(coeff,gCoeff);
352 coeffResult = coefficientRing()->add(fCoeff,tempResult);
353 if (!coefficientRing()->is_zero(coeffResult))
354 {
355 outcoeff.push_back(coeffResult);
356 monoid().copy(gMon, outmonom);
357 }
358 fBegin++;
359 gBegin++;
360 }
361 }
362 if (fBegin == fEnd)
363 {
364 for ( ; gBegin != gEnd; gBegin++)
365 {
366 auto gMon = gBegin.monom();
367 auto gCoeff = gBegin.coeff();
368 ring_elem coeffResult = coefficientRing()->mult(coeff,gCoeff);
369 if (!coefficientRing()->is_zero(coeffResult))
370 {
371 outcoeff.push_back(coeffResult);
372 monoid().copy(gMon, outmonom);
373 }
374 }
375 }
376 if (gBegin == gEnd)
377 {
378 for ( ; fBegin != fEnd; fBegin++)
379 {
380 auto fMon = fBegin.monom();
381 auto fCoeff = fBegin.coeff();
382 outcoeff.push_back(fCoeff);
383 monoid().copy(fMon, outmonom);
384 }
385 }
386}
387
388void FreeAlgebra::add(Poly& result, const Poly& f, const Poly& g) const
389{
391 f.cbegin(),
392 f.cend(),
393 g.cbegin(),
394 g.cend(),
395 coefficientRing()->one());
396}
397
399 Poly::const_iterator fBegin,
400 Poly::const_iterator fEnd,
401 Poly::const_iterator gBegin,
402 Poly::const_iterator gEnd) const
403{
405 fBegin,
406 fEnd,
407 gBegin,
408 gEnd,
409 coefficientRing()->one());
410}
411
412
414 const Poly& f,
415 const Poly& g) const
416{
418 f.cbegin(),
419 f.cend(),
420 g.cbegin(),
421 g.cend(),
423}
424
426 const Poly& f,
427 const Poly& g,
428 ring_elem coeff) const
429{
431 f.cbegin(),
432 f.cend(),
433 g.cbegin(),
434 g.cend(),
435 coefficientRing()->negate(coeff));
436}
437
438/*
439 auto fIt = f.cbegin();
440 auto gIt = g.cbegin();
441 auto fEnd = f.cend();
442 auto gEnd = g.cend();
443
444 auto& outcoeff = result.getCoeffInserter();
445 auto& outmonom = result.getMonomInserter();
446
447 // loop over the iterators for f and g, adding the bigger of the two to
448 // the back of the monomial and coefficient vectors of the result.
449 // If a tie, subtract the coefficients.
450 // If the result is zero, do not insert the monomial
451 while ((fIt != fEnd) && (gIt != gEnd))
452 {
453 auto fMon = fIt.monom();
454 auto gMon = gIt.monom();
455 auto fCoeff = fIt.coeff();
456 auto gCoeff = gIt.coeff();
457 switch(monoid().compare(fMon,gMon))
458 {
459 case LT:
460 outcoeff.push_back(coefficientRing()->negate(gCoeff));
461 monoid().copy(gMon, outmonom);
462 gIt++;
463 break;
464 case GT:
465 outcoeff.push_back(fCoeff);
466 monoid().copy(fMon, outmonom);
467 fIt++;
468 break;
469 case EQ:
470 ring_elem coeffResult = coefficientRing()->subtract(fCoeff,gCoeff);
471 if (!coefficientRing()->is_zero(coeffResult))
472 {
473 outcoeff.push_back(coeffResult);
474 monoid().copy(gMon, outmonom);
475 }
476 fIt++;
477 gIt++;
478 }
479 }
480 if (fIt == fEnd)
481 {
482 for ( ; gIt != gEnd; gIt++)
483 {
484 auto gMon = gIt.monom();
485 auto gCoeff = gIt.coeff();
486 outcoeff.push_back(coefficientRing()->negate(gCoeff));
487 monoid().copy(gMon, outmonom);
488 }
489 }
490 if (gIt == gEnd)
491 {
492 for ( ; fIt != fEnd; fIt++)
493 {
494 auto fMon = fIt.monom();
495 auto fCoeff = fIt.coeff();
496 outcoeff.push_back(fCoeff);
497 monoid().copy(fMon, outmonom);
498 }
499 }
500}
501*/
502
503void FreeAlgebra::mult(Poly& result, const Poly& f, const Poly& g) const
504{
505 FreeAlgebraHeap H {*this};
506 Poly tmp;
507 init(tmp);
508 if (f.numTerms() <= g.numTerms())
509 {
510 for (auto fIt = f.cbegin(); fIt != f.cend(); fIt++)
511 {
512 mult_by_term_left(tmp, g, fIt.coeff(), fIt.monom());
513 H.add(tmp);
514 setZero(tmp);
515 }
516 }
517 else
518 {
519 for (auto gIt = g.cbegin(); gIt != g.cend(); gIt++)
520 {
521 mult_by_term_right(tmp,f, gIt.coeff(), gIt.monom());
522 H.add(tmp);
523 setZero(tmp);
524 }
525 }
526 H.value(result);
527 clear(tmp);
528}
529
531 const Poly& f,
532 const ring_elem c,
533 const Monom m) const
534 {
535 // return f*c*m
536 auto& outcoeff = result.getCoeffInserter();
537 auto& outmonom = result.getMonomInserter();
538 for(auto i=f.cbegin(); i != f.cend(); i++)
539 {
540 // multiply the coefficients
541 ring_elem d = coefficientRing()->mult(i.coeff(),c);
542 if (coefficientRing()->is_zero(d))
543 continue;
544
545 outcoeff.push_back(d);
546 monoid().mult(i.monom(), m, outmonom);
547 }
548}
549
550
552 const Poly& f,
553 const ring_elem c,
554 const Word& w) const
555{
556 gc_vector<int> tmp;
558 Monom tmpMonom(tmp.data());
559 mult_by_term_right(result,f,c,tmpMonom);
560 tmp.clear();
561}
562
564 const Poly& f,
565 const ring_elem c,
566 const Monom m) const
567{
568 // return (c*m)*f
569 auto& outcoeff = result.getCoeffInserter();
570 auto& outmonom = result.getMonomInserter();
571 for(auto i=f.cbegin(); i != f.cend(); i++)
572 {
573 ring_elem d = coefficientRing()->mult(c, i.coeff());
574 if (coefficientRing()->is_zero(d))
575 continue;
576
577 outcoeff.push_back(d);
578 monoid().mult(m, i.monom(), outmonom);
579 }
580}
581
583 const Poly& f,
584 const ring_elem c,
585 const Word& w) const
586{
587 gc_vector<int> tmp;
589 Monom tmpMonom(tmp.data());
590 mult_by_term_left(result,f,c,tmpMonom);
591 tmp.clear();
592}
593
595 const Poly& f,
596 const ring_elem c,
597 const Monom leftM,
598 const Monom rightM) const
599{
600 // return (c*leftM)*f*rightM
601 auto& outcoeff = result.getCoeffInserter();
602 auto& outmonom = result.getMonomInserter();
603 for(auto i=f.cbegin(); i != f.cend(); i++)
604 {
605 ring_elem d = coefficientRing()->mult(c, i.coeff());
606 if (coefficientRing()->is_zero(d))
607 continue;
608 outcoeff.push_back(d);
609 monoid().mult3(leftM, i.monom(), rightM, outmonom);
610 }
611}
612
614 const Poly& f,
615 const Monom leftM,
616 const Monom rightM) const
617{
618 // return (c*leftM)*f*rightM
619 auto& outcoeff = result.getCoeffInserter();
620 auto& outmonom = result.getMonomInserter();
621 for(auto i=f.cbegin(); i != f.cend(); i++)
622 {
623 outcoeff.push_back(i.coeff());
624 monoid().mult3(leftM, i.monom(), rightM, outmonom);
625 }
626}
627
629 const Poly& f,
630 const ring_elem c,
631 const Word& leftW,
632 const Word& rightW) const
633{
634 gc_vector<int> leftTmp, rightTmp;
635 monoid().monomInsertFromWord(leftTmp,leftW);
636 monoid().monomInsertFromWord(rightTmp,rightW);
637 Monom leftTmpMonom(leftTmp.data());
638 Monom rightTmpMonom(rightTmp.data());
639 mult_by_term_left_and_right(result,f,c,leftTmpMonom,rightTmpMonom);
640 leftTmp.clear();
641 rightTmp.clear();
642}
643
645 const Poly& f,
646 const Word& leftW,
647 const Word& rightW) const
648{
649 gc_vector<int> leftTmp, rightTmp;
650 monoid().monomInsertFromWord(leftTmp,leftW);
651 monoid().monomInsertFromWord(rightTmp,rightW);
652 Monom leftTmpMonom(leftTmp.data());
653 Monom rightTmpMonom(rightTmp.data());
654 mult_by_term_left_and_right(result,f,leftTmpMonom,rightTmpMonom);
655 leftTmp.clear();
656 rightTmp.clear();
657}
658
659void FreeAlgebra::mult_by_coeff(Poly& result, const Poly& f, const ring_elem c) const
660{
661 // return c*f -- perhaps make this in place later, but for now
662 // create a new element
663 Poly tmp;
664 from_coefficient(tmp,c);
665 mult(result, f, tmp);
666 clear(tmp);
667}
668
670{
671 if (is_zero(f)) return;
672 auto& outcoeff = result.getCoeffInserter();
673 auto& outmonom = result.getMonomInserter();
674 outcoeff.insert(outcoeff.end(),f.cbeginCoeff(),f.cbeginCoeff()+1);
675 outmonom.insert(outmonom.end(),f.cbeginMonom(),f.cbeginMonom()+*(f.cbeginMonom()));
676}
677
678void FreeAlgebra::add_to_end(Poly& f, const Poly& g) const
679{
680 if (is_zero(g)) return;
681 auto& outcoeff = f.getCoeffInserter();
682 auto& outmonom = f.getMonomInserter();
683 outcoeff.insert(outcoeff.end(),g.cbeginCoeff(),g.cendCoeff());
684 outmonom.insert(outmonom.end(),g.cbeginMonom(),g.cendMonom());
685}
686
687void FreeAlgebra::add_to_end(Poly& f, ring_elem coeff, const Monom& monom) const
688{
689 if (coefficientRing()->is_zero(coeff)) return;
690 auto& outcoeff = f.getCoeffInserter();
691 auto& outmonom = f.getMonomInserter();
692 outcoeff.push_back(coeff);
693 outmonom.insert(outmonom.end(),monom.begin(), monom.end());
694}
695
696void FreeAlgebra::power(Poly& result, const Poly& f, int n) const
697{
698 from_long(result, 1);
699 Poly tmp;
700 for (int i=0; i<n; i++)
701 {
702 mult(tmp, result, f);
703 result = tmp;
704 setZero(tmp);
705 }
706}
707
708void FreeAlgebra::power(Poly& result, const Poly& f, mpz_srcptr n) const
709{
710 if (mpz_sgn(n) == 0) from_long(result, 1);
711 else if (is_zero(f)) from_long(result, 0);
712 else if (is_unit(f)) // really want a routine 'is_scalar'...
713 {
714 ring_elem coeff = f.cbegin().coeff();
715 ring_elem a = coefficientRing()->power(coeff, n);
717 }
718 else
719 {
720 std::pair<bool, int> n1 = RingZZ::get_si(n);
721 if (mpz_sgn(n) > 0 and n1.first)
722 power(result, f, n1.second);
723 else
724 {
725 ERROR("exponent too large");
726 from_long(result, 0);
727 }
728 }
729}
730
732 const Poly& f,
733 int first_var) const
734{
735 // map: R --> S, this = R.
736 // f is an element in R
737 // return an element of S - we don't know anything about S
738
739 // plan: do it as in polyring:
740 // cast f to a Poly
741 // loop through the terms of f
742 // for each term: call map->eval_term, need varpower monomial here.
743 // add to a heap object
744 // return value of the heap object
745
746 const Ring* target = map->get_ring();
747 SumCollector *H = target->make_SumCollector();
748
749 std::vector<int> vp;
750 for (auto i = f.cbegin(); i != f.cend(); ++i)
751 {
752 vp.clear();
753 monoid().getMonomialReversed(i.monom(), vp);
754 ring_elem g = map->eval_term(coefficientRing(), i.coeff(), vp.data(), first_var, numVars());
755 H->add(g);
756 }
758 return result;
759}
760
762{
763 auto& outmonom = result.getMonomInserter();
764 auto& outcoeff = result.getCoeffInserter();
765
766 for (auto i = f.cbeginMonom(); i != f.cendMonom(); ++i)
767 outmonom.push_back(*i);
768
769 for (auto i=f.cbeginCoeff(); i != f.cendCoeff(); ++i)
770 outcoeff.push_back(coefficientRing()->divide(*i,f.cbegin().coeff()));
771}
772
774{
775 ring_elem c = f.cbegin().coeff();
776 for (auto iter = f.beginCoeff(); iter != f.endCoeff(); ++iter)
777 *iter = coefficientRing()->divide(*iter,c);
778}
779
781 const Poly& f,
782 bool p_one,
783 bool p_plus,
784 bool p_parens) const
785{
786 if (f.numTerms() == 0)
787 {
788 o << "0";
789 return;
790 }
791
792 bool two_terms = (f.numTerms() > 1);
793 bool needs_parens = p_parens && two_terms;
794 if (needs_parens)
795 {
796 if (p_plus) o << '+';
797 o << '(';
798 p_plus = false;
799 }
800
801 for (auto i = f.cbegin(); i != f.cend(); i++)
802 {
803 bool is_one = monoid().is_one(i.monom());
804 p_parens = !is_one;
805 bool p_one_this = (is_one && needs_parens) || (is_one && p_one);
806 coefficientRing()->elem_text_out(o, i.coeff(), p_one_this, p_plus, p_parens);
807 if (!is_one)
808 monoid().elem_text_out(o, i.monom());
809 p_plus = true;
810 }
811
812 if (needs_parens) o << ')';
813}
814
816{
817 bool result = true;
818 if (f.numTerms() <= 1) return true;
820 monomial degf = degreeMonoid().make_one();
821 auto i = f.cbegin();
822 auto end = f.cend();
823 monoid().multi_degree(i.monom(), degf); // sets degf.
824 for (++i; i != end; ++i)
825 {
826 monoid().multi_degree(i.monom(), e);
827 if (not degreeMonoid().is_equal(e, degf))
828 {
829 result = false;
830 break;
831 }
832 }
833 degreeMonoid().remove(e);
834 degreeMonoid().remove(degf);
835 return result;
836}
837
839 monomial already_allocated_degree_vector) const
840{
841 monomial degVec = already_allocated_degree_vector;
842 bool ishomog = true;
843 auto i = f.cbegin();
844 monoid().multi_degree(i.monom(), degVec);
846 for (++i; i != f.cend(); ++i)
847 {
848 monoid().multi_degree(i.monom(), e);
849 if (not degreeMonoid().is_equal(degVec, e))
850 {
851 ishomog = false;
852 degreeMonoid().lcm(degVec, e, degVec);
853 }
854 }
855 degreeMonoid().remove(e);
856 return ishomog;
857}
858
859std::pair<int, bool> FreeAlgebra::heft_degree(const Poly& f) const
860{
861 bool ishomog = true;
862 Word tmp;
863 auto i = f.cbegin();
864 if (i == f.cend()) return std::make_pair(0, true);
865 monoid().wordFromMonom(tmp, i.monom());
866 int maxheft = monoid().wordHeft(tmp);
867 for (++i; i != f.cend(); ++i)
868 {
869 monoid().wordFromMonom(tmp, i.monom());
870 int thisheft = monoid().wordHeft(tmp);
871 if (thisheft != maxheft)
872 {
873 ishomog = false;
874 if (thisheft > maxheft)
875 maxheft = thisheft;
876 }
877 }
878 return std::make_pair(maxheft, ishomog);
879}
880
882{
883 Word result;
884 monoid().wordFromMonom(result,f.cbegin().monom());
885 return result;
886}
887
888Word FreeAlgebra::lead_word_prefix(const Poly& f, int endIndex) const
889{
890 Word result;
891 monoid().wordPrefixFromMonom(result,f.cbegin().monom(),endIndex);
892 return result;
893}
894
895Word FreeAlgebra::lead_word_suffix(const Poly& f, int beginIndex) const
896{
897 Word result;
898 monoid().wordSuffixFromMonom(result,f.cbegin().monom(),beginIndex);
899 return result;
900}
901
902// Local Variables:
903// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
904// indent-tabs-mode: nil
905// End:
std::ostream & operator<<(std::ostream &o, const FreeAlgebraElement &f)
Free associative algebra k<x_1,...,x_n> over an arbitrary coefficient ring.
FreeMonoid — monoid of length-prefixed non-commutative words with weight-vector prefix.
std::vector< int > word
Polynomial< CoefficientRingType > Poly
Modern Monom / Polynomial value types shared by NC algebras and the refactored F4.
Word and WordWithData — non-owning views over the flat-int encoding of a non-commutative word.
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
Append-only GC-backed byte buffer used throughout the engine for text output.
const Ring * coefficientRing() const
void add(Poly &result, Poly::const_iterator fBegin, Poly::const_iterator fEnd, Poly::const_iterator gBegin, Poly::const_iterator gEnd) const
void power(Poly &result, const Poly &f, int n) const
void negate(Poly &result, const Poly &f) const
bool is_unit(const Poly &f) const
void subtract(Poly &result, const Poly &f, const Poly &g) const
void copy(Poly &result, Poly::const_iterator fBegin, Poly::const_iterator fEnd) const
void mult_by_term_right(Poly &result, const Poly &f, const ring_elem c, const Monom m) const
void add_to_end(Poly &f, const Poly &g) const
void from_long(Poly &result, long n) const
void mult_by_term_left(Poly &result, const Poly &f, const ring_elem c, const Monom m) const
void init(Poly &f) const
void makeMonicInPlace(Poly &f) const
std::pair< int, bool > heft_degree(const Poly &f) const
void from_coefficient(Poly &result, const ring_elem a) const
bool is_homogeneous(const Poly &f) const
void subtractScalarMultipleOf(Poly &result, const Poly &f, const Poly &g, ring_elem coeff) const
void mult(Poly &result, const Poly &f, const Poly &g) const
bool from_rational(Poly &result, const mpq_srcptr q) const
M2_arrayint support(const Poly &f) const
bool multi_degree(const Poly &f, monomial already_allocated_degree_vector) const
void mult_by_coeff(Poly &result, const Poly &f, const ring_elem c) const
void clear(Poly &f) const
void var(Poly &result, int v) const
const Monoid & degreeMonoid() const
int numVars() const
Word lead_word_prefix(const Poly &f, int endIndex) const
const Ring & mCoefficientRing
SumCollector * make_SumCollector() const
FreeAlgebra(const Ring *K, std::shared_ptr< FreeMonoid > M)
Word lead_word(const Poly &f) const
const FreeMonoid & monoid() const
void lead_term_as_poly(Poly &result, const Poly &f) const
bool is_zero(const Poly &f) const
static FreeAlgebra * create(const Ring *K, const std::vector< std::string > &names, const PolynomialRing *degreeRing, const std::vector< int > &degrees, const std::vector< int > &wtvecs, const std::vector< int > &heftVector)
void makeMonic(Poly &result, Poly &f) const
void mult_by_term_left_and_right(Poly &result, const Poly &f, const ring_elem c, const Monom leftM, const Monom rightM) const
void from_word(Poly &result, const Word &word) const
void swap(Poly &f, Poly &g) const
void elem_text_out(buffer &o, const Poly &f, bool p_one, bool p_plus, bool p_parens) const
bool is_equal(const Poly &f, const Poly &g) const
std::shared_ptr< FreeMonoid > mMonoid
ring_elem eval(const RingMap *map, const Poly &f, int first_var) const
void from_int(Poly &result, mpz_srcptr n) const
int compare_elems(const Poly &f, const Poly &g) const
Word lead_word_suffix(const Poly &f, int beginIndex) const
void addScalarMultipleOf(Poly &result, Poly::const_iterator fBegin, Poly::const_iterator fEnd, Poly::const_iterator gBegin, Poly::const_iterator gEnd, ring_elem coeff) const
void setZero(Poly &f) const
const FreeAlgebra & ring() const
Owned Poly value paired with its FreeAlgebra*, providing natural operator-overloaded arithmetic.
FreeAlgebraHeap(const FreeAlgebra &F)
void value(Poly &result)
Poly heap[GEOHEAP_SIZE]
const FreeAlgebra & F
void add(const Poly &f)
Geobucket-style accumulator for many Poly summands in the free associative algebra.
Free associative algebra over a coefficient ring: the non-commutative analogue of PolynomialRing.
void getMonomialReversed(Monom monom, std::vector< int > &result) const
void mult3(const Monom &m1, const Monom &m2, const Monom &m3, MonomialInserter &result) const
int wordHeft(Word &word) const
void support(const Monom &m, std::vector< int > &result) const
int compare(const Monom &m1, const Monom &m2) const
void monomInsertFromWord(MonomialInserter &result, const Word &w) const
void copy(const Monom &m, MonomialInserter &result) const
void elem_text_out(buffer &o, const Monom &m1) const
void wordFromMonom(Word &result, const Monom &m) const
void mult(const Monom &m1, const Monom &m2, MonomialInserter &result) const
void multi_degree(const Monom &m, monomial already_allocated_degree_vector) const
void one(MonomialInserter &m) const
void var(int v, MonomialInserter &result) const
void wordPrefixFromMonom(Word &result, const Monom &m, int endIndex) const
void wordSuffixFromMonom(Word &result, const Monom &m, int beginIndex) const
bool is_one(const Monom &m) const
The free non-commutative monoid on a set of named variables, with monomial ordering and degree / weig...
void lcm(const_monomial m, const_monomial n, monomial result) const
Definition monoid.cpp:561
monomial make_one() const
Definition monoid.cpp:455
void remove(monomial d) const
Definition monoid.cpp:462
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual void remove(ring_elem &f) const =0
virtual ring_elem divide(const ring_elem f, const ring_elem g) const =0
virtual bool is_unit(const ring_elem f) const =0
virtual ring_elem add(const ring_elem f, const ring_elem g) const =0
virtual bool is_equal(const ring_elem f, const ring_elem g) const =0
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const =0
virtual int compare_elems(const ring_elem f, const ring_elem g) const =0
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.
Definition ring.cpp:109
virtual ring_elem mult(const ring_elem f, const ring_elem g) const =0
virtual bool from_rational(const mpq_srcptr q, ring_elem &result) const =0
virtual SumCollector * make_SumCollector() const
Definition ring.cpp:486
xxx xxx xxx
Definition ring.hpp:102
const Ring * get_ring() const
Definition ringmap.hpp:111
ring_elem eval_term(const Ring *coeff_ring, const ring_elem coeff, const int *vp, int first_var, int nvars_in_source) const
Definition ringmap.cpp:140
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
static std::pair< bool, int > get_si(mpz_srcptr n)
Definition ZZ.cpp:46
virtual ring_elem getValue()=0
virtual void add(ring_elem f)=0
SumCollector adapter that funnels engine-side ring_elem adds into a FreeAlgebraHeap.
Abstract incremental accumulator that builds a ring_elem from many add(f) calls.
Definition ring.hpp:669
void init(const int *begin, const int *end)
Definition Word.hpp:68
Non-owning view of a non-commutative word: [begin, end) of int variable indices.
Definition Word.hpp:56
char * str()
Definition buffer.hpp:72
MPREAL_MSVC_DEBUGVIEW_DATA void clear(::mpfr_ptr)
Definition mpreal.h:770
const int heap_size[GEOHEAP_SIZE]
Definition engine.cpp:53
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
#define monomial
Definition gb-toric.cpp:11
static int compare(const vecterm *t, const vecterm *s)
Definition geovec.hpp:112
int minus_one
int 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
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition mpreal.h:3244
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
Definition newdelete.hpp:76
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
RingMap — engine representation of a ring homomorphism.
const int * end() const
const int * begin() const
Non-owning view onto a [length, degree, v1, v2, ..., vn] packed monomial in some externally managed b...
const int EQ
Definition style.hpp:40
const int GT
Definition style.hpp:41
const int LT
Definition style.hpp:39
const PolynomialRing * degreeRing(const std::vector< std::string > &names)