Macaulay2 Engine
Loading...
Searching...
No Matches
factory.cpp
Go to the documentation of this file.
1// copyright Daniel R. Grayson, 1995
2
3#include "interface/factory.h"
4#include "interface/matrix.h"
6
7#include <algorithm>
8#include <cassert>
9#include <cstdio>
10#include <iostream>
11#include <utility>
12#include <vector>
13
14#define Matrix FactoryMatrix
15#include <factory/factory.h> // from Messollen's libfac
16#undef Matrix
17
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wconversion"
20#include <NTL/ZZ.h>
21#pragma GCC diagnostic pop
22
23#include "buffer.hpp"
24#include "error.h"
25#include "exceptions.hpp"
26#include "matrix.hpp"
27#include "monoid.hpp"
28#include "poly.hpp"
29#include "polyring.hpp"
30#include "relem.hpp"
31#include "ring.hpp"
32#include "ringelem.hpp"
33#include "text-io.hpp"
34#include "tower.hpp"
35#include "util.hpp"
36
37const bool notInExtension = false;
38
39#define REVERSE_VARIABLES \
40 1 // did we have a good reason for reversing the variables before? probably
41 // so the ideal reordering of Messollen would work...
42
52{
53 const Ring *F = P->getCoefficientRing();
54 // if (F->cast_to_QQ()) return modeQQ;
55 if (F->is_QQ()) return modeQQ;
56 if (F->cast_to_RingZZ()) return modeZZ;
57 // factory will abort if the characteristic is too large
58 if (F->characteristic() > 536870909) {
59 ERROR("characteristic is too large (max is 2^29)");
60 return modeError;
61 }
62 if (F->isFinitePrimeField()) return modeZn;
63 if (F->isGaloisField()) return modeGF;
64 ERROR("expected coefficient ring of the form ZZ/n, ZZ, QQ, or GF");
65 return modeError;
66}
67
68// int debugging
69// #ifndef NDEBUG
70// = true
71// #endif
72// ;
73
74static void init_seeds()
75{
76 NTL::SetSeed(NTL::ZZ::zero()); // NTL
77 factoryseed(0); // factory (which uses NTL, as we've compiled it)
78}
79
82
84{
90 const Ring *Zn;
91 void enter();
92 void exit();
93
94 enter_factory() : mode(modeUnknown), Zn(nullptr) { enter(); }
96 : mode(coeffMode(P)),
98 ? static_cast<int>(P->characteristic())
99 : 0),
100 Zn(mode == modeZn ? P->getCoefficientRing() : nullptr)
101 {
102 enter();
103 }
104
106};
107
109{
110 oldcharac = getCharacteristic();
111 oldRatlState = isOn(SW_RATIONAL);
112 // needed for factory 4.1.1; already turned on by default in factory >= 4.1.2
113 On(SW_USE_EZGCD_P);
114 switch (mode)
115 {
116 case modeZZ:
117 newRatlState = 0;
118 Off(SW_RATIONAL);
119 newcharac = 0;
120 setCharacteristic(0);
121 break;
122 case modeGF:
123 case modeZn:
124 newRatlState = 0;
125 Off(SW_RATIONAL);
126 setCharacteristic(newcharac);
127 break;
128 case modeQQ:
129 newRatlState = 1;
130 On(SW_RATIONAL);
131 newcharac = 0;
132 setCharacteristic(0);
133 break;
134 default:
137 break;
138 }
139 // if (debugging)
140 // {
141 // if (oldRatlState != newRatlState)
142 // printf(newRatlState ? "--setting factory rational mode on\n"
143 // : "--setting factory rational mode off\n");
144 // if (oldcharac != newcharac)
145 // printf("--changing factory characteristic from %d to %d\n",
146 // oldcharac,
147 // newcharac);
148 // }
149}
150
152{
153 if (oldRatlState)
154 On(SW_RATIONAL);
155 else
156 Off(SW_RATIONAL);
157 setCharacteristic(oldcharac);
158 // if (debugging)
159 // {
160 // if (oldcharac != newcharac)
161 // printf("--changing factory characteristic back from %d to %d\n",
162 // newcharac,
163 // oldcharac);
164 // if (oldRatlState != newRatlState)
165 // printf(oldRatlState ? "--setting factory rational mode back on\n"
166 // : "--setting factory rational mode back off\n");
167 // }
168}
169
170static __mpz_struct toInteger(CanonicalForm h)
171{
174 // struct enter_factory foo;
175 // assert(h.inZ());
176 // InternalCF *value = h.getval();
177 // MP_INT y = value->MPI();
178 // mpz_t x;
179 // mpz_init(x);
180 // mpz_set(x,y);
181 // return *x;
182 static const unsigned int base = 1 << 16;
183 gc_vector<int> vec;
184 int sign;
185 {
186 struct enter_factory foo;
187 int RationalMode = isOn(SW_RATIONAL) ? (Off(SW_RATIONAL), 1) : 0;
188 if (h < 0)
189 {
190 sign = -1;
191 h = -h;
192 }
193 else
194 sign = 1;
195 while (h != 0)
196 {
197 CanonicalForm k = h % (int)base;
198 vec.push_back(static_cast<int>(k.intval()));
199 h = h / (int)base;
200 }
201 if (RationalMode) On(SW_RATIONAL);
202 }
203 mpz_t x;
204 mpz_init(x);
205 for (int i = vec.size() - 1; i >= 0; i--)
206 {
207 mpz_mul_ui(x, x, base); // x = x * base;
208 mpz_add_ui(x, x, static_cast<unsigned>(vec[i]));
209 }
210 if (sign == -1) mpz_neg(x, x); // x = -x;
211 return x[0];
212}
213
214static const RingElement *convertToM2(const PolynomialRing *R, CanonicalForm h)
215{
216 // this seems not to handle polynomials with rational coefficients at all!!
217 const int n = R->n_vars();
218 if (h.inCoeffDomain())
219 {
220 if (h.inZ())
221 {
222 mpz_t x = {toInteger(h)};
223 ring_elem ret = R->from_int(x);
224 mpz_clear(x);
225 return RingElement::make_raw(R, ret);
226 }
227 else if (h.inQ())
228 {
229 struct enter_factory c;
230 __mpq_struct z = {toInteger(h.num()), toInteger(h.den())};
231 ring_elem val;
232 bool ok = R->from_rational(&z, val);
233 if (not ok)
234 {
235 std::cout << "internal error: unexpected failure to lift "
236 "rational number to ring"
237 << std::endl;
238 val = R->from_long(0);
239 }
240 RingElement *ret = RingElement::make_raw(R, val);
241 mpq_clear(&z);
242 return ret;
243 }
244 else if (h.inFF())
245 return RingElement::make_raw(R, R->from_long(h.intval()));
246 else if (h.inExtension())
247 {
248 assert(algebraicElement_M2 != NULL);
249 ring_elem result = R->from_long(0);
250 for (int j = h.taildegree(); j <= h.degree(); j++)
251 {
252 const RingElement *r = convertToM2(R, h[j]);
253 if (error()) return RingElement::make_raw(R, R->one());
254 ring_elem r1 = r->get_value();
255 ring_elem v = algebraicElement_M2->get_value();
256 v = R->power(v, j);
257 r1 = R->mult(r1, v);
258 R->add_to(result, r1);
259 }
260 return RingElement::make_raw(R, result);
261 }
262 else
263 {
264 ERROR("conversion from factory over unknown type");
265 return RingElement::make_raw(R, R->one());
266 }
267 }
268 ring_elem result = R->from_long(0);
269 for (int j = h.taildegree(); j <= h.degree(); j++)
270 {
271 const RingElement *r = convertToM2(R, h[j]);
272 if (error()) return RingElement::make_raw(R, R->one());
273 ring_elem r1 = r->get_value();
274 int var =
275#if REVERSE_VARIABLES
276 (n - 1) -
277#endif
278 (h.level() - 1);
279 ring_elem v = R->var(var);
280 v = R->power(v, j);
281 r1 = R->mult(r1, v);
282 R->add_to(result, r1);
283 }
284 return RingElement::make_raw(R, result);
285}
286
287static struct enter_factory foo1;
288static int base_set = 0;
289static CanonicalForm base;
290
291// debugging display routines to be called from gdb
292// needs factory to be configured without option --disable-streamio
293#if FACTORY_STREAMIO
294void showvar(Variable &t) { std::cout << t << std::endl; }
295void showcf(CanonicalForm &t) { std::cout << t << std::endl; }
296void showcfl(CFList &t) { std::cout << t << std::endl; }
297void showcffl(CFFList &t) { std::cout << t << std::endl; }
298void showmpint(gmp_ZZ p)
299{
300 mpz_out_str(stdout, 10, p);
301 std::cout << std::endl;
302}
303void showmpz(mpz_srcptr p)
304{
305 mpz_out_str(stdout, 10, p);
306 std::cout << std::endl;
307}
308#endif
309
310static struct enter_factory foo2;
311
312static CanonicalForm convertToFactory(mpz_srcptr p)
313{
314 struct enter_factory foo;
315 int size = p->_mp_size;
316 int sign = size < 0 ? -1 : 1;
317 if (size < 0) size = -size;
318 if (!base_set)
319 {
320 base_set = 1;
321 base = 1;
322 for (int i = 0; i < mp_bits_per_limb; i++) base *= 2;
323 }
324 CanonicalForm m = 0;
325 for (int i = size - 1; i >= 0; i--)
326 {
327 mp_limb_t digit = p->_mp_d[i];
328 for (int j = mp_bits_per_limb; j > 0;)
329 {
330 int k = j - 16;
331 if (k < 0) k = 0;
332 int n = j - k;
333 int subbase = 1 << n;
334 m = subbase * m + (static_cast<int>(digit >> k) & (subbase - 1));
335 j = k;
336 }
337 }
338 m = m * sign;
339 return m;
340}
341
342static CanonicalForm convertToFactory(const RingElement &g, bool inExtension);
343
345// Code to convert GF elements to/from factory CanonicalForm elements //
347static Variable set_GF_minimal_poly(const PolynomialRing *P)
348{
349 assert(P->getCoefficientRing()->isGaloisField());
350 const Ring *kk = P->getCoefficientRing();
351 assert(kk != 0);
352 RingElement F = RingElement(kk, kk->var(0));
353 F.promote(P, algebraicElement_M2); // sets algebraicElement_M2
354 Variable a = rootOf(
357 return a;
358}
359static void getGFRepresentation(const Ring *kk1,
360 const ring_elem &a,
361 std::vector<long> &result_rep)
362{
363 assert(kk1->isGaloisField());
364 // const GF* kk = kk1->cast_to_GF();
365 // assert(kk != 0);
366 const RingElement *F = kk1->getRepresentation(a);
367 // RingElement F(kk->originalR(), kk->get_rep(a));
368 F->getSmallIntegerCoefficients(result_rep);
369}
370static CanonicalForm convertGFToFactory(const std::vector<long> &repr)
371{
372 // Uses algebraicElement_Fac as the element
373 CanonicalForm f = 0;
374 for (int i = 0; i < repr.size(); i++)
375 {
376 if (repr[i] == 0) continue;
377 CanonicalForm m = CanonicalForm(repr[i]);
378 m *= power(algebraicElement_Fac, i);
379 f += m;
380 }
381 return f;
382}
383static CanonicalForm convertGFToFactory(const ring_elem &q,
384 const PolynomialRing *P)
385// use algebraicElement_Fac for converting this galois field element
386// SO: one needs to have called set_GF_minimal_poly first!
387{
388 std::vector<long> poly;
390 return convertGFToFactory(poly);
391}
392
393
394#if 0
395static CanonicalForm convertToFactory(const ring_elem &q, const GF *k) { // use algebraicElement_Fac for converting this galois field element
396 const PolynomialRing *A = k->originalR();
399 const Monoid *M = A->getMonoid();
400 const Ring *Zn = k->originalR()->getCoefficientRing();
401 CanonicalForm f = 0;
402 for (Nterm *t = g->get_value(); t != NULL; t = t->next) {
403 M->to_varpower(t->monom, vp);
404
405 std::pair<bool,long> res = Zn->coerceToLongInteger(t->coeff);
406 assert(res.first);
407 int coef = static_cast<int>(res.second);
408
409 CanonicalForm m = CanonicalForm(coef);
410 for (index_varpower l = vp.data(); l.valid(); ++l)
411 m *= power( algebraicElement_Fac, l.exponent() );
412 f += m;
413 }
414 return f;
415}
416#endif
417
418static CanonicalForm convertToFactory(const RingElement &g, bool inExtension)
419{
420 const Ring *R = g.get_ring();
422 if (P == nullptr)
423 {
424 ERROR("expected a polynomial ring");
425 return 0;
426 }
427 const int n = P->n_vars();
428 const Monoid *M = P->getMonoid();
430 struct enter_factory foo(P);
431 if (foo.mode == modeError) return 0;
432 CanonicalForm f = 0;
433 for (Nterm *t = g.get_value(); t != nullptr; t = t->next)
434 {
435 int coef = 0;
436 M->to_varpower(t->monom, vp);
437 if (foo.mode == modeZn)
438 {
439 std::pair<bool, long> res = foo.Zn->coerceToLongInteger(t->coeff);
440 assert(res.first);
441 coef = static_cast<int>(res.second);
442 }
443 CanonicalForm m =
444 (foo.mode == modeZn
445 ? CanonicalForm(coef)
446 : foo.mode == modeGF
447 ? convertGFToFactory(t->coeff, P)
448 : foo.mode == modeZZ
449 ? convertToFactory(t->coeff.get_mpz())
450 : foo.mode == modeQQ
452 mpq_numref(MPQ_VAL(t->coeff))) /
454 mpq_denref(MPQ_VAL(t->coeff))))
455 : CanonicalForm(0) // shouldn't happen
456 );
457 for (index_varpower l = vp.data(); l.valid(); ++l)
458 {
459 int index = 1 +
460#if REVERSE_VARIABLES
461 (n - 1) -
462#endif
463 l.var();
464 m *= power(index == 1 && inExtension ? algebraicElement_Fac
465 : Variable(index),
466 l.exponent());
467 }
468 f += m;
469 }
470 return f;
471}
472
473void displayCF(const PolynomialRing *R, const CanonicalForm &h) // for debugging
474{
475 buffer o;
476 const RingElement *g = convertToM2(R, h);
477 o << IM2_RingElement_to_string(g) << "\n";
478 emit(o.str());
479}
480
481// TODO: figure out where this should be used
483{
484 struct enter_factory foo(P);
485 return foo.mode != modeError;
486}
487
488const RingElement /* or null */ *rawGCDRingElement(const RingElement *f,
489 const RingElement *g,
490 const RingElement *mipo,
491 const M2_bool inExtension)
492{
493 const RingElement *ret = nullptr;
496 if (P == nullptr)
497 {
498 if (f->get_ring()->cast_to_Tower() != nullptr) return towerGCD(f, g);
499 // else we really do have an error:
500 ERROR("expected polynomial ring");
501 return nullptr;
502 }
503 if (P != P2)
504 {
505 ERROR("encountered different rings");
506 return nullptr;
507 }
508 {
509 struct enter_factory foo(P);
510 if (foo.mode == modeError)
511 {
512 algebraicElement_M2 = nullptr;
513 return nullptr;
514 }
515 if (foo.mode == modeGF)
516 {
517 assert(!inExtension);
518 set_GF_minimal_poly(P);
519 }
520 if (inExtension)
521 {
522 CanonicalForm minp = convertToFactory(*mipo, false);
523 algebraicElement_Fac = rootOf(minp, 'a');
524 }
525 CanonicalForm p = convertToFactory(*f, inExtension);
526 CanonicalForm q = convertToFactory(*g, inExtension);
527 CanonicalForm h = gcd(p, q);
528 if (inExtension)
529 {
530 assert(foo.mode != modeGF);
532 P, P->var(P->n_vars() - 1)); // the algebraic generator is always
533 // the last variable in M2, the first
534 // one in factory
535 }
536 ret = convertToM2(P, h);
537 if (error())
538 {
539 algebraicElement_M2 = nullptr;
540 return nullptr;
541 }
542 }
543 if (ret->is_zero()) return ret;
545 ret->get_value()); // an element in the coeff ring
546 ring_elem b = P->getCoefficients()->invert(a);
547 ring_elem r = ret->get_value();
548 P->mult_coeff_to(b, r);
549 algebraicElement_M2 = nullptr;
550 return RingElement::make_raw(P, r);
551}
552
554 const RingElement *f,
555 const RingElement *g,
556 const RingElement **A,
557 const RingElement **B)
558{
559 const bool inExtension = false;
560 const RingElement *ret;
563 *A = nullptr;
564 *B = nullptr;
565 if (P == nullptr)
566 {
567 if (f->get_ring()->cast_to_Tower() != nullptr)
568 return towerExtendedGCD(f, g, A, B);
569 // else we really do have an error:
570 ERROR("expected polynomial ring");
571 return nullptr;
572 }
573 if (P != P2)
574 {
575 ERROR("encountered different rings");
576 return nullptr;
577 }
578
579 if (f->is_zero())
580 {
581 *A = RingElement::make_raw(P, P->zero());
582 *B = RingElement::make_raw(P, P->one());
583 return g;
584 }
585
586 if (g->is_zero())
587 {
588 *A = RingElement::make_raw(P, P->one());
589 *B = RingElement::make_raw(P, P->zero());
590 return f;
591 }
592
593 struct enter_factory foo(P);
594 if (foo.mode == modeError) return nullptr;
595 if (foo.mode == modeGF)
596 {
597 set_GF_minimal_poly(P);
598 }
599 CanonicalForm p = convertToFactory(*f, inExtension);
600 CanonicalForm q = convertToFactory(*g, inExtension);
601 CanonicalForm a, b;
602 CanonicalForm h = extgcd(p, q, a, b);
603 ret = convertToM2(P, h);
604 if (error())
605 {
606 algebraicElement_M2 = nullptr;
607 return nullptr;
608 }
609 *A = convertToM2(P, a);
610 if (error())
611 {
612 algebraicElement_M2 = nullptr;
613 return nullptr;
614 }
615 *B = convertToM2(P, b);
616 if (error())
617 {
618 algebraicElement_M2 = nullptr;
619 return nullptr;
620 }
621 algebraicElement_M2 = nullptr;
622 return ret;
623}
624
625const RingElement /* or null */ *rawPseudoRemainder(const RingElement *f,
626 const RingElement *g)
627{
628 const bool inExtension = false;
631 if (P == nullptr)
632 {
633 ERROR("expected polynomial ring");
634 return nullptr;
635 }
636 if (P != P2)
637 {
638 ERROR("encountered different rings");
639 return nullptr;
640 }
641
642 struct enter_factory foo(P);
643 if (foo.mode == modeError) return nullptr;
644 if (foo.mode == modeGF)
645 {
646 set_GF_minimal_poly(P);
647 }
648 CanonicalForm p = convertToFactory(*f, inExtension);
649 CanonicalForm q = convertToFactory(*g, inExtension);
650 CanonicalForm h = Prem(p, q);
651 const RingElement *r = convertToM2(P, h);
652 if (error())
653 {
654 algebraicElement_M2 = nullptr;
655 return nullptr;
656 }
657 algebraicElement_M2 = nullptr;
658 return r;
659}
660
662 engine_RawRingElementArrayOrNull *result_factors,
663 M2_arrayintOrNull *result_powers,
664 const RingElement *mipo = nullptr // minimal polynomial of
665 // generator of field
666 // extension, if any;
667 // generator is last variable
668 )
669{
670 bool inExtension = mipo != nullptr;
671 try
672 {
674 *result_factors = nullptr;
675 *result_powers = nullptr;
676 if (P == nullptr)
677 {
678 ERROR("expected polynomial ring");
679 return;
680 }
681 struct enter_factory foo(P);
682 if (foo.mode == modeError) return;
683
684 CFFList q;
685 init_seeds();
686
687 if (foo.mode == modeGF)
688 {
689 inExtension = true;
690 Variable a = set_GF_minimal_poly(P);
691 CanonicalForm h = convertToFactory(*g, notInExtension);
692 q = factorize(h, a);
693 }
694 else if (mipo != nullptr)
695 {
696 CanonicalForm mipocf = convertToFactory(*mipo, notInExtension);
697 Variable a = rootOf(mipocf, 'a');
699 CanonicalForm h = convertToFactory(*g, inExtension);
700 // displayCF(P,h);
701 q = factorize(h, a);
703 P, P->var(P->n_vars() - 1)); // the algebraic generator is always
704 // the last variable in M2, the
705 // first one in factory
706 }
707 else
708 {
709 CanonicalForm h = convertToFactory(*g, inExtension);
710 // displayCF(P,h);
711 q = factorize(h);
712 algebraicElement_M2 = nullptr;
713 }
714
715 int nfactors = q.length();
716
717 *result_factors = getmemarraytype(engine_RawRingElementArray, nfactors);
718 (*result_factors)->len = nfactors;
719
720 *result_powers = M2_makearrayint(nfactors);
721
722 int next = 0;
723 for (CFFListIterator i = q; i.hasItem(); i++)
724 {
725 (*result_factors)->array[next] = convertToM2(P, i.getItem().factor());
726 (*result_powers)->array[next++] = i.getItem().exp();
727 }
728 algebraicElement_M2 = nullptr;
729 if (error()) *result_factors = nullptr, *result_powers = nullptr;
730 } catch (const exc::engine_error& e)
731 {
732 ERROR(e.what());
733 return;
734 }
735}
736
737void rawFactor(const RingElement *g,
738 engine_RawRingElementArrayOrNull *result_factors,
739 M2_arrayintOrNull *result_powers)
740{
741 rawFactorBase(g, result_factors, result_powers);
742}
743
745 const RingElement *minpoly,
746 engine_RawRingElementArrayOrNull *result_factors,
747 M2_arrayintOrNull *result_powers)
748{
749 rawFactorBase(g, result_factors, result_powers, minpoly);
750}
751
753{
754 const bool inExtension = false;
755 try
756 {
757 init_seeds();
759 if (P == nullptr)
760 {
761 ERROR("expected polynomial ring");
762 return nullptr;
763 }
764 const int N = P->n_vars();
765
766 struct enter_factory foo(P);
767 if (foo.mode == modeError) return nullptr;
768 if (foo.mode == modeGF)
769 {
770 ERROR("not implemented yet");
771 return nullptr;
772 }
773
774 CFList I;
775 int i;
776 for (i = 0; i < M->n_rows(); i++)
777 {
778 for (int j = 0; j < M->n_cols(); j++)
779 {
780 const RingElement *g;
781 {
782 g = RingElement::make_raw(P, M->elem(i, j));
783 }
784 I.append(convertToFactory(*g, inExtension));
785 }
786 }
787
788 if (I.length() == 0) {
789 ERROR("expected at least one generator");
790 return nullptr;
791 }
792
793 List<int> t = neworderint(I);
794
795 int n = t.length();
796 gc_vector<int> u(N);
797 ListIterator<int> ii(t);
798 for (i = 0; ii.hasItem(); ii++, i++)
799 u[i] = (n - 1) - (ii.getItem() - 1); // REVERSE!
800 std::reverse(u.begin(), u.begin() + n);
801 for (i = n; i < N; i++) u[i] = i;
803 } catch (const exc::engine_error& e)
804 {
805 ERROR(e.what());
806 return nullptr;
807 }
808}
809
811{
812 const bool inExtension = false;
813 try
814 {
816 if (P == nullptr)
817 {
818 ERROR("expected polynomial ring");
819 return nullptr;
820 }
821
822 init_seeds();
823
824 struct enter_factory foo(P);
825 if (foo.mode == modeError) return nullptr;
826 if (foo.mode == modeGF)
827 {
828 ERROR("not implemented yet");
829 return nullptr;
830 }
831
832 CFList I;
833 for (int i = 0; i < M->n_rows(); i++)
834 {
835 for (int j = 0; j < M->n_cols(); j++)
836 {
837 const RingElement *g;
838 {
839 g = RingElement::make_raw(P, M->elem(i, j));
840 }
841 I.append(convertToFactory(*g, inExtension));
842 }
843 }
844
845 List<CFList> t = irrCharSeries(I);
846
847 engine_RawMatrixArray result =
848 getmemarraytype(engine_RawMatrixArray, t.length());
849 result->len = t.length();
850
851 int next = 0;
852 for (ListIterator<List<CanonicalForm> > ii = t; ii.hasItem(); ii++)
853 {
854 CFList u = ii.getItem();
855 engine_RawRingElementArray result1 =
856 getmemarraytype(engine_RawRingElementArray, u.length());
857 result1->len = u.length();
858 int next1 = 0;
859 for (ListIterator<CanonicalForm> j = u; j.hasItem(); j++)
860 {
861 result1->array[next1++] = convertToM2(P, j.getItem());
862 if (error()) return nullptr;
863 }
864 result->array[next++] =
865 IM2_Matrix_make1(M->rows(), u.length(), result1, false);
866 }
867
868 return result;
869 } catch (const exc::engine_error& e)
870 {
871 ERROR(e.what());
872 return nullptr;
873 }
874}
875
876CFList convertToCFList(const Matrix &M, bool inExtension)
877{
878 CFList I;
879 for (int i = 0; i < M.n_rows(); i++)
880 {
881 for (int j = 0; j < M.n_cols(); j++)
882 {
883 const RingElement *g;
884 {
885 g = RingElement::make_raw(M.get_ring(), M.elem(i, j));
886 }
887 I.append(convertToFactory(*g, inExtension));
888 }
889 }
890 return I;
891}
892
893// Local Variables:
894// indent-tabs-mode: nil
895// End:
ExponentListIterator< int, true > index_varpower
Append-only GC-backed byte buffer used throughout the engine for text output.
ring_elem get_rep(ring_elem f) const
Definition GF.cpp:156
const PolynomialRing * originalR() const
Definition GF.hpp:86
Engine-side finite field GF(p^n) built on top of (Z/p)[t] / f(t) for a primitive element of the resul...
Definition GF.hpp:62
const Ring * get_ring() const
Definition matrix.hpp:134
ring_elem elem(int i, int j) const
Definition matrix.cpp:307
int n_cols() const
Definition matrix.hpp:147
int n_rows() const
Definition matrix.hpp:146
const FreeModule * rows() const
Definition matrix.hpp:144
void to_varpower(const_monomial m, gc_vector< int > &result_vp) const
Definition monoid.cpp:735
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
Definition monoid.hpp:89
ring_elem preferred_associate_divisor(ring_elem ff) const
Definition poly.cpp:459
const Ring * getCoefficientRing() const
Definition polyring.hpp:200
virtual ring_elem var(int v) const =0
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
virtual void mult_coeff_to(ring_elem a, ring_elem &f) const =0
virtual const Ring * getCoefficients() const
Definition polyring.hpp:277
virtual const PolyRing * getNumeratorRing() const
Definition polyring.hpp:259
int n_vars() const
Definition polyring.hpp:196
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual ring_elem var(int v) const
Definition ring.cpp:97
virtual const RingElement * getMinimalPolynomial() const
Definition ring.hpp:301
virtual bool isGaloisField() const
Definition ring.hpp:170
virtual std::pair< bool, long > coerceToLongInteger(ring_elem a) const
Definition ring.cpp:236
ring_elem one() const
Definition ring.hpp:357
ring_elem zero() const
Definition ring.hpp:359
virtual ring_elem invert(const ring_elem f) const =0
virtual ring_elem from_long(long n) const =0
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
long characteristic() const
Definition ring.hpp:159
virtual const RingZZ * cast_to_RingZZ() const
Definition ring.hpp:235
virtual const RingElement * getRepresentation(const ring_elem &a) const
Definition ring.hpp:326
virtual bool is_QQ() const
Definition ring.hpp:172
void add_to(ring_elem &f, const ring_elem &g) const
Definition ring.cpp:205
virtual ring_elem from_int(mpz_srcptr n) 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 isFinitePrimeField() const
Definition ring.hpp:169
virtual bool from_rational(const mpq_srcptr q, ring_elem &result) const =0
virtual const Tower * cast_to_Tower() const
Definition ring.hpp:241
ring_elem get_value() const
Definition relem.hpp:79
bool promote(const Ring *S, const RingElement *&result) const
Definition relem.cpp:305
bool is_zero() const
Definition relem.hpp:167
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
bool getSmallIntegerCoefficients(std::vector< long > &result_coeffs) const
Definition relem.cpp:421
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
char * str()
Definition buffer.hpp:72
int error()
Definition error.c:48
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
void rawFactor2(const RingElement *g, const RingElement *minpoly, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers)
Definition factory.cpp:744
const RingElement * rawExtendedGCDRingElement(const RingElement *f, const RingElement *g, const RingElement **A, const RingElement **B)
Definition factory.cpp:553
static struct enter_factory foo2
Definition factory.cpp:310
engine_RawMatrixArrayOrNull rawCharSeries(const Matrix *M)
Definition factory.cpp:810
static CanonicalForm base
Definition factory.cpp:289
void rawFactorBase(const RingElement *g, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers, const RingElement *mipo=nullptr)
Definition factory.cpp:661
static void getGFRepresentation(const Ring *kk1, const ring_elem &a, std::vector< long > &result_rep)
Definition factory.cpp:359
factoryCoeffMode
Definition factory.cpp:43
@ modeQQ
Definition factory.cpp:45
@ modeGF
Definition factory.cpp:48
@ modeUnknown
Definition factory.cpp:49
@ modeZZ
Definition factory.cpp:46
@ modeZn
Definition factory.cpp:47
@ modeError
Definition factory.cpp:44
const RingElement * rawPseudoRemainder(const RingElement *f, const RingElement *g)
Definition factory.cpp:625
static const RingElement * convertToM2(const PolynomialRing *R, CanonicalForm h)
Definition factory.cpp:214
void rawFactor(const RingElement *g, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers)
Definition factory.cpp:737
static int base_set
Definition factory.cpp:288
CFList convertToCFList(const Matrix &M, bool inExtension)
Definition factory.cpp:876
#define Matrix
Definition factory.cpp:14
const bool notInExtension
Definition factory.cpp:37
static __mpz_struct toInteger(CanonicalForm h)
Definition factory.cpp:170
static enum factoryCoeffMode coeffMode(const PolynomialRing *P)
Definition factory.cpp:51
M2_arrayintOrNull rawIdealReorder(const Matrix *M)
Definition factory.cpp:752
static CanonicalForm convertToFactory(mpz_srcptr p)
Definition factory.cpp:312
static Variable set_GF_minimal_poly(const PolynomialRing *P)
Definition factory.cpp:347
static CanonicalForm convertGFToFactory(const std::vector< long > &repr)
Definition factory.cpp:370
CanonicalForm algebraicElement_Fac
Definition factory.cpp:80
const RingElement * algebraicElement_M2
Definition factory.cpp:81
void displayCF(const PolynomialRing *R, const CanonicalForm &h)
Definition factory.cpp:473
const RingElement * rawGCDRingElement(const RingElement *f, const RingElement *g, const RingElement *mipo, const M2_bool inExtension)
Definition factory.cpp:488
static void init_seeds()
Definition factory.cpp:74
bool factoryGoodRing(const PolynomialRing *P)
Definition factory.cpp:482
static struct enter_factory foo1
Definition factory.cpp:287
Engine-boundary C API for polynomial GCD, factorisation, and root finding.
int p
const Matrix * IM2_Matrix_make1(const FreeModule *target, int ncols, const engine_RawRingElementArray M, int preference)
Definition matrix.cpp:159
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemarraytype(S, len)
Definition m2-mem.h:142
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
engine_RawMatrixArray engine_RawMatrixArrayOrNull
Definition m2-types.h:196
engine_RawRingElementArray engine_RawRingElementArrayOrNull
Definition m2-types.h:176
char M2_bool
Definition m2-types.h:82
mpz_srcptr gmp_ZZ
Definition m2-types.h:141
Engine-boundary C API for constructing, transforming, and inspecting immutable Matrix objects.
Matrix — the engine's immutable homomorphism F -> G between free modules.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
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
volatile int x
Concrete commutative PolyRing — standard polynomial ring inheriting from PolyRingFlat.
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
Ring — the legacy abstract base class for every coefficient and polynomial ring.
#define MPQ_VAL(f)
Definition ringelem.hpp:206
ring_elem — the universal value type carried by every Ring* in the engine.
M2_string IM2_RingElement_to_string(const RingElement *f)
Engine-boundary C API for constructing, querying, and operating on RingElement values.
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
enter_factory(const PolynomialRing *P)
Definition factory.cpp:95
const Ring * Zn
Definition factory.cpp:90
enum factoryCoeffMode mode
Definition factory.cpp:85
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 RingElement * towerExtendedGCD(const RingElement *F, const RingElement *G, const RingElement **A, const RingElement **B)
Definition tower.cpp:446
const RingElement * towerGCD(const RingElement *F, const RingElement *G)
Definition tower.cpp:433
Legacy Tower — Ring-derived iterated extension of Z/p (pre-aring).
M2_arrayint stdvector_to_M2_arrayint(const std::vector< T > &v)
Definition util.hpp:79
Conversion helpers between M2 boundary types and standard C++ containers.