My Project
Loading...
Searching...
No Matches
algext.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/**
5 * ABSTRACT: numbers in an algebraic extension field K[a] / < f(a) >
6 * Assuming that we have a coeffs object cf, then these numbers
7 * are polynomials in the polynomial ring K[a] represented by
8 * cf->extRing.
9 * IMPORTANT ASSUMPTIONS:
10 * 1.) So far we assume that cf->extRing is a valid polynomial
11 * ring in exactly one variable, i.e., K[a], where K is allowed
12 0* to be any field (representable in SINGULAR and which may
13 * itself be some extension field, thus allowing for extension
14 * towers).
15 * 2.) Moreover, this implementation assumes that
16 * cf->extRing->qideal is not NULL but an ideal with at
17 * least one non-zero generator which may be accessed by
18 * cf->extRing->qideal->m[0] and which represents the minimal
19 * polynomial f(a) of the extension variable 'a' in K[a].
20 * 3.) As soon as an std method for polynomial rings becomes
21 * available, all reduction steps modulo f(a) should be replaced
22 * by a call to std. Moreover, in this situation one can finally
23 * move from K[a] / < f(a) > to
24 * K[a_1, ..., a_s] / I, with I some zero-dimensional ideal
25 * in K[a_1, ..., a_s] given by a lex
26 * Gröbner basis.
27 * The code in algext.h and algext.cc is then capable of
28 * computing in K[a_1, ..., a_s] / I.
29 **/
30
31#include "misc/auxiliary.h"
32
33#include "reporter/reporter.h"
34
35#include "coeffs/coeffs.h"
36#include "coeffs/numbers.h"
37#include "coeffs/longrat.h"
38
41#include "polys/simpleideals.h"
43
44#include "factory/factory.h"
45#include "polys/clapconv.h"
46#include "polys/clapsing.h"
47#include "polys/prCopy.h"
48
50#define TRANSEXT_PRIVATES 1
52
53#ifdef LDEBUG
54#define naTest(a) naDBTest(a,__FILE__,__LINE__,cf)
55static BOOLEAN naDBTest(number a, const char *f, const int l, const coeffs r);
56#else
57#define naTest(a) do {} while (0)
58#endif
59
60/* polynomial ring in which our numbers live */
61#define naRing cf->extRing
62
63/* coeffs object in which the coefficients of our numbers live;
64 * methods attached to naCoeffs may be used to compute with the
65 * coefficients of our numbers, e.g., use naCoeffs->nAdd to add
66 * coefficients of our numbers */
67#define naCoeffs cf->extRing->cf
68
69/* minimal polynomial */
70#define naMinpoly naRing->qideal->m[0]
71
72/// forward declarations
73static BOOLEAN naGreaterZero(number a, const coeffs cf);
74static BOOLEAN naGreater(number a, number b, const coeffs cf);
75static BOOLEAN naEqual(number a, number b, const coeffs cf);
76static BOOLEAN naIsOne(number a, const coeffs cf);
77static BOOLEAN naIsMOne(number a, const coeffs cf);
78static number naInit(long i, const coeffs cf);
79static number naNeg(number a, const coeffs cf);
80static number naInvers(number a, const coeffs cf);
81static number naAdd(number a, number b, const coeffs cf);
82static number naSub(number a, number b, const coeffs cf);
83static number naMult(number a, number b, const coeffs cf);
84static number naDiv(number a, number b, const coeffs cf);
85static void naPower(number a, int exp, number *b, const coeffs cf);
86static number naCopy(number a, const coeffs cf);
87static void naWriteLong(number a, const coeffs cf);
88static void naWriteShort(number a, const coeffs cf);
89static number naGcd(number a, number b, const coeffs cf);
90static void naDelete(number *a, const coeffs cf);
91static void naCoeffWrite(const coeffs cf, BOOLEAN details);
92//number naIntDiv(number a, number b, const coeffs cf);
93static const char * naRead(const char *s, number *a, const coeffs cf);
94
95static BOOLEAN naCoeffIsEqual(const coeffs cf, n_coeffType n, void * param);
96
97
98/// returns NULL if p == NULL, otherwise makes p monic by dividing
99/// by its leading coefficient (only done if this is not already 1);
100/// this assumes that we are over a ground field so that division
101/// is well-defined;
102/// modifies p
103// void p_Monic(poly p, const ring r);
104
105/// assumes that p and q are univariate polynomials in r,
106/// mentioning the same variable;
107/// assumes a global monomial ordering in r;
108/// assumes that not both p and q are NULL;
109/// returns the gcd of p and q;
110/// leaves p and q unmodified
111// poly p_Gcd(const poly p, const poly q, const ring r);
112
113/* returns NULL if p == NULL, otherwise makes p monic by dividing
114 by its leading coefficient (only done if this is not already 1);
115 this assumes that we are over a ground field so that division
116 is well-defined;
117 modifies p */
118static inline void p_Monic(poly p, const ring r)
119{
120 if (p == NULL) return;
121 number n = n_Init(1, r->cf);
122 if (p->next==NULL) { p_SetCoeff(p,n,r); return; }
123 poly pp = p;
124 number lc = p_GetCoeff(p, r);
125 if (n_IsOne(lc, r->cf)) return;
126 number lcInverse = n_Invers(lc, r->cf);
127 p_SetCoeff(p, n, r); // destroys old leading coefficient!
128 pIter(p);
129 while (p != NULL)
130 {
131 number n = n_Mult(p_GetCoeff(p, r), lcInverse, r->cf);
132 n_Normalize(n,r->cf);
133 p_SetCoeff(p, n, r); // destroys old leading coefficient!
134 pIter(p);
135 }
136 n_Delete(&lcInverse, r->cf);
137 p = pp;
138}
139
140/// see p_Gcd;
141/// additional assumption: deg(p) >= deg(q);
142/// must destroy p and q (unless one of them is returned)
143static inline poly p_GcdHelper(poly &p, poly &q, const ring r)
144{
145 while (q != NULL)
146 {
147 p_PolyDiv(p, q, FALSE, r);
148 // swap p and q:
149 poly& t = q;
150 q = p;
151 p = t;
152
153 }
154 return p;
155}
156
157/* assumes that p and q are univariate polynomials in r,
158 mentioning the same variable;
159 assumes a global monomial ordering in r;
160 assumes that not both p and q are NULL;
161 returns the gcd of p and q;
162 leaves p and q unmodified */
163static inline poly p_Gcd(const poly p, const poly q, const ring r)
164{
165 assume((p != NULL) || (q != NULL));
166
167 poly a = p; poly b = q;
168 if (p_Deg(a, r) < p_Deg(b, r)) { a = q; b = p; }
169 a = p_Copy(a, r); b = p_Copy(b, r);
170
171 /* We have to make p monic before we return it, so that if the
172 gcd is a unit in the ground field, we will actually return 1. */
173 a = p_GcdHelper(a, b, r);
174 p_Monic(a, r);
175 return a;
176}
177
178/* see p_ExtGcd;
179 additional assumption: deg(p) >= deg(q);
180 must destroy p and q (unless one of them is returned) */
181static inline poly p_ExtGcdHelper(poly &p, poly &pFactor, poly &q, poly &qFactor,
182 ring r)
183{
184 if (q == NULL)
185 {
186 qFactor = NULL;
187 pFactor = p_ISet(1, r);
188 p_SetCoeff(pFactor, n_Invers(p_GetCoeff(p, r), r->cf), r);
189 p_Monic(p, r);
190 return p;
191 }
192 else
193 {
194 poly pDivQ = p_PolyDiv(p, q, TRUE, r);
195 poly ppFactor = NULL; poly qqFactor = NULL;
196 poly theGcd = p_ExtGcdHelper(q, qqFactor, p, ppFactor, r);
197 pFactor = ppFactor;
198 qFactor = p_Add_q(qqFactor,
199 p_Neg(p_Mult_q(pDivQ, p_Copy(ppFactor, r), r), r),
200 r);
201 return theGcd;
202 }
203}
204
205
206/* assumes that p and q are univariate polynomials in r,
207 mentioning the same variable;
208 assumes a global monomial ordering in r;
209 assumes that not both p and q are NULL;
210 returns the gcd of p and q;
211 moreover, afterwards pFactor and qFactor contain appropriate
212 factors such that gcd(p, q) = p * pFactor + q * qFactor;
213 leaves p and q unmodified */
214poly p_ExtGcd(poly p, poly &pFactor, poly q, poly &qFactor, ring r)
215{
216 assume((p != NULL) || (q != NULL));
217 poly a = p; poly b = q; BOOLEAN aCorrespondsToP = TRUE;
218 if (p_Deg(a, r) < p_Deg(b, r))
219 { a = q; b = p; aCorrespondsToP = FALSE; }
220 a = p_Copy(a, r); b = p_Copy(b, r);
221 poly aFactor = NULL; poly bFactor = NULL;
222 poly theGcd = p_ExtGcdHelper(a, aFactor, b, bFactor, r);
223 if (aCorrespondsToP) { pFactor = aFactor; qFactor = bFactor; }
224 else { pFactor = bFactor; qFactor = aFactor; }
225 return theGcd;
226}
227
228
229
230#ifdef LDEBUG
231BOOLEAN naDBTest(number a, const char *f, const int l, const coeffs cf)
232{
233 if (a == NULL) return TRUE;
234 p_Test((poly)a, naRing);
236 {
237 if((((poly)a)!=naMinpoly)
239 && (p_Totaldegree((poly)a, naRing)> 1)) // allow to output par(1)
240 {
241 dReportError("deg >= deg(minpoly) in %s:%d\n",f,l);
242 return FALSE;
243 }
244 }
245 return TRUE;
246}
247#endif
248
249static void heuristicReduce(poly &p, poly reducer, const coeffs cf);
250static void definiteReduce(poly &p, poly reducer, const coeffs cf);
251
252/* returns the bottom field in this field extension tower; if the tower
253 is flat, i.e., if there is no extension, then r itself is returned;
254 as a side-effect, the counter 'height' is filled with the height of
255 the extension tower (in case the tower is flat, 'height' is zero) */
256static coeffs nCoeff_bottom(const coeffs r, int &height)
257{
258 assume(r != NULL);
259 coeffs cf = r;
260 height = 0;
261 while (nCoeff_is_Extension(cf))
262 {
263 assume(cf->extRing != NULL); assume(cf->extRing->cf != NULL);
264 cf = cf->extRing->cf;
265 height++;
266 }
267 return cf;
268}
269
270static BOOLEAN naIsZero(number a, const coeffs cf)
271{
272 naTest(a);
273 return (a == NULL);
274}
275
276static void naDelete(number * a, const coeffs cf)
277{
278 if (*a == NULL) return;
279 if (((poly)*a)==naMinpoly) { *a=NULL;return;}
280 poly aAsPoly = (poly)(*a);
281 p_Delete(&aAsPoly, naRing);
282 *a = NULL;
283}
284
285static BOOLEAN naEqual(number a, number b, const coeffs cf)
286{
287 naTest(a); naTest(b);
288 /// simple tests
289 if (a == NULL) return (b == NULL);
290 if (b == NULL) return (a == NULL);
291 return p_EqualPolys((poly)a,(poly)b,naRing);
292}
293
294static number naCopy(number a, const coeffs cf)
295{
296 naTest(a);
297 if (((poly)a)==naMinpoly) return a;
298 return (number)p_Copy((poly)a, naRing);
299}
300
301static BOOLEAN naIsOne(number a, const coeffs cf)
302{
303 naTest(a);
304 poly aAsPoly = (poly)a;
305 if ((a==NULL) || (!p_IsConstant(aAsPoly, naRing))) return FALSE;
306 return n_IsOne(p_GetCoeff(aAsPoly, naRing), naCoeffs);
307}
308
309static BOOLEAN naIsMOne(number a, const coeffs cf)
310{
311 naTest(a);
312 poly aAsPoly = (poly)a;
313 if ((a==NULL) || (!p_IsConstant(aAsPoly, naRing))) return FALSE;
314 return n_IsMOne(p_GetCoeff(aAsPoly, naRing), naCoeffs);
315}
316
317/// this is in-place, modifies a
318static number naNeg(number a, const coeffs cf)
319{
320 naTest(a);
321 if (a != NULL) a = (number)p_Neg((poly)a, naRing);
322 return a;
323}
324
325static number naInit(long i, const coeffs cf)
326{
327 if (i == 0) return NULL;
328 else return (number)p_ISet(i, naRing);
329}
330
331static number naInitMPZ(mpz_t m, const coeffs r)
332{
333 number n=n_InitMPZ(m,r->extRing->cf);
334 return (number)p_NSet(n,r->extRing);
335}
336
337static long naInt(number &a, const coeffs cf)
338{
339 naTest(a);
340 poly aAsPoly = (poly)a;
341 if(aAsPoly == NULL)
342 return 0;
343 if (!p_IsConstant(aAsPoly, naRing))
344 return 0;
345 assume( aAsPoly != NULL );
346 return n_Int(p_GetCoeff(aAsPoly, naRing), naCoeffs);
347}
348
349/* TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b) or (deg(a)==deg(b) && lc(a)>lc(b))) */
350static BOOLEAN naGreater(number a, number b, const coeffs cf)
351{
352 naTest(a); naTest(b);
353 if (naIsZero(a, cf))
354 {
355 if (naIsZero(b, cf)) return FALSE;
356 return !n_GreaterZero(pGetCoeff((poly)b),naCoeffs);
357 }
358 if (naIsZero(b, cf))
359 {
360 return n_GreaterZero(pGetCoeff((poly)a),naCoeffs);
361 }
362 int aDeg = p_Totaldegree((poly)a, naRing);
363 int bDeg = p_Totaldegree((poly)b, naRing);
364 if (aDeg>bDeg) return TRUE;
365 if (aDeg<bDeg) return FALSE;
366 return n_Greater(pGetCoeff((poly)a),pGetCoeff((poly)b),naCoeffs);
367}
368
369/* TRUE iff a != 0 and (LC(a) > 0 or deg(a) > 0) */
370static BOOLEAN naGreaterZero(number a, const coeffs cf)
371{
372 naTest(a);
373 if (a == NULL) return FALSE;
374 if (n_GreaterZero(p_GetCoeff((poly)a, naRing), naCoeffs)) return TRUE;
375 if (p_Totaldegree((poly)a, naRing) > 0) return TRUE;
376 return FALSE;
377}
378
379static void naCoeffWrite(const coeffs cf, BOOLEAN details)
380{
381 assume( cf != NULL );
382
383 const ring A = cf->extRing;
384
385 assume( A != NULL );
386 assume( A->cf != NULL );
387
388 n_CoeffWrite(A->cf, details);
389
390// rWrite(A);
391
392 const int P = rVar(A);
393 assume( P > 0 );
394
395 PrintS("[");
396
397 for (int nop=0; nop < P; nop ++)
398 {
399 Print("%s", rRingVar(nop, A));
400 if (nop!=P-1) PrintS(", ");
401 }
402
403 PrintS("]/(");
404
405 const ideal I = A->qideal;
406
407 assume( I != NULL );
408 assume( IDELEMS(I) == 1 );
409
410
411 if ( details )
412 {
413 p_Write0( I->m[0], A);
414 PrintS(")");
415 }
416 else
417 PrintS("...)");
418
419/*
420 char *x = rRingVar(0, A);
421
422 Print("// Coefficients live in the extension field K[%s]/<f(%s)>\n", x, x);
423 Print("// with the minimal polynomial f(%s) = %s\n", x,
424 p_String(A->qideal->m[0], A));
425 PrintS("// and K: ");
426*/
427}
428
429static number naAdd(number a, number b, const coeffs cf)
430{
431 naTest(a); naTest(b);
432 if (a == NULL) return naCopy(b, cf);
433 if (b == NULL) return naCopy(a, cf);
434 poly aPlusB = p_Add_q(p_Copy((poly)a, naRing),
435 p_Copy((poly)b, naRing), naRing);
436 //definiteReduce(aPlusB, naMinpoly, cf);
437 return (number)aPlusB;
438}
439
440static void naInpAdd(number &a, number b, const coeffs cf)
441{
442 naTest(a); naTest(b);
443 if (a == NULL) a=b;
444 else if (b != NULL)
445 {
446 poly aPlusB = p_Add_q((poly)a, p_Copy((poly)b, naRing), naRing);
447 a=(number)aPlusB;
448 }
449}
450
451static number naSub(number a, number b, const coeffs cf)
452{
453 naTest(a); naTest(b);
454 if (b == NULL) return naCopy(a, cf);
455 poly minusB = p_Neg(p_Copy((poly)b, naRing), naRing);
456 if (a == NULL) return (number)minusB;
457 poly aMinusB = p_Add_q(p_Copy((poly)a, naRing), minusB, naRing);
458 //definiteReduce(aMinusB, naMinpoly, cf);
459 return (number)aMinusB;
460}
461
462static number naMult(number a, number b, const coeffs cf)
463{
464 naTest(a); naTest(b);
465 if ((a == NULL)||(b == NULL)) return NULL;
466 poly aTimesB = pp_Mult_qq((poly)a, (poly)b, naRing);
467 definiteReduce(aTimesB, naMinpoly, cf);
468 p_Normalize(aTimesB,naRing);
469 return (number)aTimesB;
470}
471
472static void naInpMult(number &a, number b, const coeffs cf)
473{
474 naTest(a); naTest(b);
475 if ((a == NULL)||(b == NULL)) { a=NULL; return;}
476 poly aTimesB = p_Mult_q((poly)a, p_Copy((poly)b,naRing), naRing);
477 definiteReduce(aTimesB, naMinpoly, cf);
478 p_Normalize(aTimesB,naRing);
479 a=(number)aTimesB;
480}
481
482static number naDiv(number a, number b, const coeffs cf)
483{
484 naTest(a); naTest(b);
485 if (b == NULL) WerrorS(nDivBy0);
486 if (a == NULL) return NULL;
487 poly bInverse = (poly)naInvers(b, cf);
488 if(bInverse != NULL) // b is non-zero divisor!
489 {
490 poly aDivB = p_Mult_q(p_Copy((poly)a, naRing), bInverse, naRing);
491 definiteReduce(aDivB, naMinpoly, cf);
492 p_Normalize(aDivB,naRing);
493 return (number)aDivB;
494 }
495 return NULL;
496}
497
498/* 0^0 = 0;
499 for |exp| <= 7 compute power by a simple multiplication loop;
500 for |exp| >= 8 compute power along binary presentation of |exp|, e.g.
501 p^13 = p^1 * p^4 * p^8, where we utilise that
502 p^(2^(k+1)) = p^(2^k) * p^(2^k);
503 intermediate reduction modulo the minimal polynomial is controlled by
504 the in-place method heuristicReduce(poly, poly, coeffs); see there.
505*/
506static void naPower(number a, int exp, number *b, const coeffs cf)
507{
508 naTest(a);
509
510 /* special cases first */
511 if (a == NULL)
512 {
513 if (exp >= 0) *b = NULL;
514 else WerrorS(nDivBy0);
515 return;
516 }
517 else if (exp == 0) { *b = naInit(1, cf); return; }
518 else if (exp == 1) { *b = naCopy(a, cf); return; }
519 else if (exp == -1) { *b = naInvers(a, cf); return; }
520
521 int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
522
523 /* now compute a^expAbs */
524 poly pow; poly aAsPoly = (poly)a;
525 if (expAbs <= 7)
526 {
527 pow = p_Copy(aAsPoly, naRing);
528 for (int i = 2; i <= expAbs; i++)
529 {
530 pow = p_Mult_q(pow, p_Copy(aAsPoly, naRing), naRing);
532 }
534 }
535 else
536 {
537 pow = p_ISet(1, naRing);
538 poly factor = p_Copy(aAsPoly, naRing);
539 while (expAbs != 0)
540 {
541 if (expAbs & 1)
542 {
545 }
546 expAbs = expAbs / 2;
547 if (expAbs != 0)
548 {
551 }
552 }
555 }
556
557 /* invert if original exponent was negative */
558 number n = (number)pow;
559 if (exp < 0)
560 {
561 number m = naInvers(n, cf);
562 naDelete(&n, cf);
563 n = m;
564 }
565 *b = n;
566}
567
568/* may reduce p modulo the reducer by calling definiteReduce;
569 the decision is made based on the following heuristic
570 (which should also only be changed here in this method):
571 if (deg(p) > 10*deg(reducer) then perform reduction;
572 modifies p */
573static void heuristicReduce(poly &p, poly reducer, const coeffs cf)
574{
575 #ifdef LDEBUG
576 p_Test((poly)p, naRing);
577 p_Test((poly)reducer, naRing);
578 #endif
579 if (p_Totaldegree(p, naRing) > 10 * p_Totaldegree(reducer, naRing))
580 definiteReduce(p, reducer, cf);
581}
582
583static void naWriteLong(number a, const coeffs cf)
584{
585 naTest(a);
586 if (a == NULL)
587 StringAppendS("0");
588 else
589 {
590 poly aAsPoly = (poly)a;
591 /* basically, just write aAsPoly using p_Write,
592 but use brackets around the output, if a is not
593 a constant living in naCoeffs = cf->extRing->cf */
594 BOOLEAN useBrackets = !(p_IsConstant(aAsPoly, naRing));
595 if (useBrackets) StringAppendS("(");
596 p_String0Long(aAsPoly, naRing, naRing);
597 if (useBrackets) StringAppendS(")");
598 }
599}
600
601static void naWriteShort(number a, const coeffs cf)
602{
603 naTest(a);
604 if (a == NULL)
605 StringAppendS("0");
606 else
607 {
608 poly aAsPoly = (poly)a;
609 /* basically, just write aAsPoly using p_Write,
610 but use brackets around the output, if a is not
611 a constant living in naCoeffs = cf->extRing->cf */
612 BOOLEAN useBrackets = !(p_IsConstant(aAsPoly, naRing));
613 if (useBrackets) StringAppendS("(");
614 p_String0Short(aAsPoly, naRing, naRing);
615 if (useBrackets) StringAppendS(")");
616 }
617}
618
619static const char * naRead(const char *s, number *a, const coeffs cf)
620{
621 poly aAsPoly;
622 const char * result = p_Read(s, aAsPoly, naRing);
623 if (aAsPoly!=NULL) definiteReduce(aAsPoly, naMinpoly, cf);
624 *a = (number)aAsPoly;
625 return result;
626}
627
628#if 0
629/* implemented by the rule lcm(a, b) = a * b / gcd(a, b) */
630static number naLcm(number a, number b, const coeffs cf)
631{
632 naTest(a); naTest(b);
633 if (a == NULL) return NULL;
634 if (b == NULL) return NULL;
635 number theProduct = (number)pp_Mult_qq((poly)a, (poly)b, naRing);
636 /* note that theProduct needs not be reduced w.r.t. naMinpoly;
637 but the final division will take care of the necessary reduction */
638 number theGcd = naGcd(a, b, cf);
639 return naDiv(theProduct, theGcd, cf);
640}
641#endif
642static number napNormalizeHelper(number b, const coeffs cf)
643{
644 number h=n_Init(1,naRing->cf);
645 poly bb=(poly)b;
646 number d;
647 while(bb!=NULL)
648 {
650 n_Delete(&h,naRing->cf);
651 h=d;
652 pIter(bb);
653 }
654 return h;
655}
656static number naLcmContent(number a, number b, const coeffs cf)
657{
658 if (nCoeff_is_Zp(naRing->cf)) return naCopy(a,cf);
659#if 0
660 else {
661 number g = ndGcd(a, b, cf);
662 return g;
663 }
664#else
665 {
666 a=(number)p_Copy((poly)a,naRing);
667 number t=napNormalizeHelper(b,cf);
668 if(!n_IsOne(t,naRing->cf))
669 {
670 number bt, rr;
671 poly xx=(poly)a;
672 while (xx!=NULL)
673 {
674 bt = n_SubringGcd(t, pGetCoeff(xx), naRing->cf);
675 rr = n_Mult(t, pGetCoeff(xx), naRing->cf);
676 n_Delete(&pGetCoeff(xx),naRing->cf);
677 pGetCoeff(xx) = n_Div(rr, bt, naRing->cf);
679 n_Delete(&bt,naRing->cf);
680 n_Delete(&rr,naRing->cf);
681 pIter(xx);
682 }
683 }
684 n_Delete(&t,naRing->cf);
685 return (number) a;
686 }
687#endif
688}
689
690/* expects *param to be castable to AlgExtInfo */
691static BOOLEAN naCoeffIsEqual(const coeffs cf, n_coeffType n, void * param)
692{
693 if (n_algExt != n) return FALSE;
694 AlgExtInfo *e = (AlgExtInfo *)param;
695 /* for extension coefficient fields we expect the underlying
696 polynomial rings to be IDENTICAL, i.e. the SAME OBJECT;
697 this expectation is based on the assumption that we have properly
698 registered cf and perform reference counting rather than creating
699 multiple copies of the same coefficient field/domain/ring */
700 if (naRing == e->r)
701 return TRUE;
702 /* (Note that then also the minimal ideals will necessarily be
703 the same, as they are attached to the ring.) */
704
705 // NOTE: Q(a)[x] && Q(a)[y] should better share the _same_ Q(a)...
706 if( rEqual(naRing, e->r, TRUE) ) // also checks the equality of qideals
707 {
708 const ideal mi = naRing->qideal;
709 assume( IDELEMS(mi) == 1 );
710 const ideal ii = e->r->qideal;
711 assume( IDELEMS(ii) == 1 );
712
713 // TODO: the following should be extended for 2 *equal* rings...
714 assume( p_EqualPolys(mi->m[0], ii->m[0], naRing, e->r) );
715
716 rDelete(e->r);
717
718 return TRUE;
719 }
720
721 return FALSE;
722
723}
724
725static int naSize(number a, const coeffs cf)
726{
727 if (a == NULL) return 0;
728 poly aAsPoly = (poly)a;
729 int theDegree = 0; int noOfTerms = 0;
730 while (aAsPoly != NULL)
731 {
732 noOfTerms++;
733 int d = p_GetExp(aAsPoly, 1, naRing);
734 if (d > theDegree) theDegree = d;
735 pIter(aAsPoly);
736 }
737 return (theDegree +1) * noOfTerms;
738}
739
740/* performs polynomial division and overrides p by the remainder
741 of division of p by the reducer;
742 modifies p */
743static void definiteReduce(poly &p, poly reducer, const coeffs cf)
744{
745 #ifdef LDEBUG
746 p_Test((poly)p, naRing);
747 p_Test((poly)reducer, naRing);
748 #endif
749 if ((p!=NULL) && (p_GetExp(p,1,naRing)>=p_GetExp(reducer,1,naRing)))
750 {
751 p_PolyDiv(p, reducer, FALSE, naRing);
752 }
753}
754
755static void naNormalize(number &a, const coeffs cf)
756{
757 poly aa=(poly)a;
758 if (aa!=naMinpoly)
760 a=(number)aa;
761}
762
763static number naConvFactoryNSingN( const CanonicalForm n, const coeffs cf)
764{
765 if (n.isZero()) return NULL;
766 poly p=convFactoryPSingP(n,naRing);
767 return (number)p;
768}
769static CanonicalForm naConvSingNFactoryN( number n, BOOLEAN /*setChar*/, const coeffs cf )
770{
771 naTest(n);
772 if (n==NULL) return CanonicalForm(0);
773
774 return convSingPFactoryP((poly)n,naRing);
775}
776
777/* IMPORTANT NOTE: Since an algebraic field extension is again a field,
778 the gcd of two elements is not very interesting. (It
779 is actually any unit in the field, i.e., any non-
780 zero element.) Note that the below method does not operate
781 in this strong sense but rather computes the gcd of
782 two given elements in the underlying polynomial ring. */
783static number naGcd(number a, number b, const coeffs cf)
784{
785 if (a==NULL) return naCopy(b,cf);
786 if (b==NULL) return naCopy(a,cf);
787
788 poly ax=(poly)a;
789 poly bx=(poly)b;
790 if (pNext(ax)!=NULL)
791 return (number)p_Copy(ax, naRing);
792 else
793 {
794 if(nCoeff_is_Zp(naRing->cf))
795 return naInit(1,cf);
796 else
797 {
798 number x = n_Copy(pGetCoeff((poly)a),naRing->cf);
799 if (n_IsOne(x,naRing->cf))
800 return (number)p_NSet(x,naRing);
801 while (pNext(ax)!=NULL)
802 {
803 pIter(ax);
804 number y = n_SubringGcd(x, pGetCoeff(ax), naRing->cf);
805 n_Delete(&x,naRing->cf);
806 x = y;
807 if (n_IsOne(x,naRing->cf))
808 return (number)p_NSet(x,naRing);
809 }
810 do
811 {
812 number y = n_SubringGcd(x, pGetCoeff(bx), naRing->cf);
813 n_Delete(&x,naRing->cf);
814 x = y;
815 if (n_IsOne(x,naRing->cf))
816 return (number)p_NSet(x,naRing);
817 pIter(bx);
818 }
819 while (bx!=NULL);
820 return (number)p_NSet(x,naRing);
821 }
822 }
823#if 0
824 naTest(a); naTest(b);
825 const ring R = naRing;
826 return (number) singclap_gcd_r((poly)a, (poly)b, R);
827#endif
828// return (number)p_Gcd((poly)a, (poly)b, naRing);
829}
830
831static number naInvers(number a, const coeffs cf)
832{
833 naTest(a);
834 if (a == NULL) WerrorS(nDivBy0);
835
836 poly aFactor = NULL; poly mFactor = NULL; poly theGcd = NULL;
837// singclap_extgcd!
838 BOOLEAN ret=FALSE;
839 #if 0
840 //#ifdef HAVE_FLINT
841 // context for modulus
842 ring R=naRing;
843 fmpz_mod_ctx_t ctxp;
844 fmpz_t p;
845 fmpz_init(p); fmpz_init_set_ui(p,R->ch);
846 fmpz_mod_ctx_init(ctxp,p);
847 fmpz_clear(p);
848 // convert modulus
849 fmpz_mod_poly_t modulus;
850 poly p=R->qideal->m[0];
851 fmpz_mod_poly_init2(modulus,deg(p)+1,ctxp);
852 while(p!=NULL)
853 {
854 fmpz_mod_poly_set_coeff_ui(result,p_GetExp(p,1,R),(long)(pGetCoeff(p)));
855 pIter(p);
856 }
857 // ctx for ring r
858 fq_ctx_t ctx ctx;
859 fq_ctx_init_modulus(ctx,modulus,ctxp,"a");
860 fmpz_mod_poly_clear(modulus);
861 // convert a
862 poly ap=(poly)a;
863 fq_poly_t aa;
864 fq_poly_init2 (aa, p_GetExp(ap,1,R), ctx);
865 while(ap!=NULL)
866 {
867 fq_t buf;
868 fmpz_poly_init2(buf,fq_ctx_degree(ctx));
869 _fmpz_poly_set_length(buf, fq_ctx_degree(ctx));
870 fmpz_set_si (buf,(long)pGetCoeff(ap));
871 fq_poly_set_coeff (aa, p_GetExp(ap,1,R), buf, ctx);
872 fq_clear (buf, ctx);
873 pIter(ap);
874 }
875 // gcd
876 // convert res
877 // cleanup
878 fq_ctx_clear(ctx);
879 fmpz_mod_ctx_clear(ctxp);
880 // return result
881 // see fq_gcdinv
882
883
884 #else
885 ret = singclap_extgcd ((poly)a, naMinpoly, theGcd, aFactor, mFactor, naRing);
886 #endif
887
888 if (ret) return NULL;
889 // if( ret ) theGcd = p_ExtGcd((poly)a, aFactor, naMinpoly, mFactor, naRing);
890
891 naTest((number)theGcd); naTest((number)aFactor); naTest((number)mFactor);
892 p_Delete(&mFactor, naRing);
893
894 // /* the gcd must be 1 since naMinpoly is irreducible and a != NULL: */
895 // assume(naIsOne((number)theGcd, cf));
896
897 if( !naIsOne((number)theGcd, cf) )
898 {
899 WerrorS("zero divisor found - your minpoly is not irreducible");
900 p_Delete(&aFactor, naRing); aFactor = NULL;
901 }
902 p_Delete(&theGcd, naRing);
903
904 return (number)(aFactor);
905}
906
907/* assumes that src = Q or Z, dst = Q(a) */
908static number naMap00(number a, const coeffs src, const coeffs dst)
909{
910 if (n_IsZero(a, src)) return NULL;
911 assume(src->rep == dst->extRing->cf->rep);
912 poly result = p_One(dst->extRing);
913 p_SetCoeff(result, n_Copy(a, src), dst->extRing);
914 return (number)result;
915}
916
917/* assumes that src = Z, dst = K(a) */
918static number naMapZ0(number a, const coeffs src, const coeffs dst)
919{
920 if (n_IsZero(a, src)) return NULL;
921 poly result = p_One(dst->extRing);
922 nMapFunc nMap=n_SetMap(src,dst->extRing->cf);
923 p_SetCoeff(result, nMap(a, src, dst->extRing->cf), dst->extRing);
924 if (n_IsZero(pGetCoeff(result),dst->extRing->cf))
925 p_Delete(&result,dst->extRing);
926 return (number)result;
927}
928
929/* assumes that src = Z/p, dst = Q(a) */
930static number naMapP0(number a, const coeffs src, const coeffs dst)
931{
932 if (n_IsZero(a, src)) return NULL;
933 /* mapping via intermediate int: */
934 int n = n_Int(a, src);
935 number q = n_Init(n, dst->extRing->cf);
936 poly result = p_One(dst->extRing);
937 p_SetCoeff(result, q, dst->extRing);
938 return (number)result;
939}
940
941#if 0
942/* assumes that either src = Q(a), dst = Q(a), or
943 src = Z/p(a), dst = Z/p(a) */
944static number naCopyMap(number a, const coeffs src, const coeffs dst)
945{
946 return naCopy(a, dst);
947}
948#endif
949
950static number naCopyTrans2AlgExt(number a, const coeffs src, const coeffs dst)
951{
953 assume (nCoeff_is_algExt (dst));
954 fraction fa=(fraction)a;
955 poly p, q;
956 if (rSamePolyRep(src->extRing, dst->extRing))
957 {
958 p = p_Copy(NUM(fa),src->extRing);
959 if (!DENIS1(fa))
960 {
961 q = p_Copy(DEN(fa),src->extRing);
962 assume (q != NULL);
963 }
964 }
965 else
966 {
967 assume ((strcmp(rRingVar(0,src->extRing),rRingVar(0,dst->extRing))==0) && (rVar (src->extRing) == rVar (dst->extRing)));
968
969 nMapFunc nMap= n_SetMap (src->extRing->cf, dst->extRing->cf);
970
971 assume (nMap != NULL);
972 p= p_PermPoly (NUM (fa), NULL, src->extRing, dst->extRing,nMap, NULL,rVar (src->extRing));
973 if (!DENIS1(fa))
974 {
975 q= p_PermPoly (DEN (fa), NULL, src->extRing, dst->extRing,nMap, NULL,rVar (src->extRing));
976 assume (q != NULL);
977 }
978 }
979 definiteReduce(p, dst->extRing->qideal->m[0], dst);
980 p_Test (p, dst->extRing);
981 if (!DENIS1(fa))
982 {
983 definiteReduce(q, dst->extRing->qideal->m[0], dst);
984 p_Test (q, dst->extRing);
985 if (q != NULL)
986 {
987 number t= naDiv ((number)p,(number)q, dst);
988 p_Delete (&p, dst->extRing);
989 p_Delete (&q, dst->extRing);
990 return t;
991 }
992 WerrorS ("mapping denominator to zero");
993 }
994 return (number) p;
995}
996
997/* assumes that src = Q, dst = Z/p(a) */
998static number naMap0P(number a, const coeffs src, const coeffs dst)
999{
1000 if (n_IsZero(a, src)) return NULL;
1001 // int p = rChar(dst->extRing);
1002
1003 number q = nlModP(a, src, dst->extRing->cf); // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to pZ
1004
1005 poly result = p_NSet(q, dst->extRing);
1006
1007 return (number)result;
1008}
1009
1010/* assumes that src = Z/p, dst = Z/p(a) */
1011static number naMapPP(number a, const coeffs src, const coeffs dst)
1012{
1013 if (n_IsZero(a, src)) return NULL;
1014 assume(src == dst->extRing->cf);
1015 poly result = p_One(dst->extRing);
1016 p_SetCoeff(result, n_Copy(a, src), dst->extRing);
1017 return (number)result;
1018}
1019
1020/* assumes that src = Z/u, dst = Z/p(a), where u != p */
1021static number naMapUP(number a, const coeffs src, const coeffs dst)
1022{
1023 if (n_IsZero(a, src)) return NULL;
1024 /* mapping via intermediate int: */
1025 int n = n_Int(a, src);
1026 number q = n_Init(n, dst->extRing->cf);
1027 poly result = p_One(dst->extRing);
1028 p_SetCoeff(result, q, dst->extRing);
1029 return (number)result;
1030}
1031
1032static number naGenMap(number a, const coeffs cf, const coeffs dst)
1033{
1034 if (a==NULL) return NULL;
1035
1036 const ring rSrc = cf->extRing;
1037 const ring rDst = dst->extRing;
1038
1039 const nMapFunc nMap=n_SetMap(rSrc->cf,rDst->cf);
1040 poly f = (poly)a;
1041 poly g = prMapR(f, nMap, rSrc, rDst);
1042
1043 n_Test((number)g, dst);
1044 return (number)g;
1045}
1046
1047static number naGenTrans2AlgExt(number a, const coeffs cf, const coeffs dst)
1048{
1049 if (a==NULL) return NULL;
1050
1051 const ring rSrc = cf->extRing;
1052 const ring rDst = dst->extRing;
1053
1054 const nMapFunc nMap=n_SetMap(rSrc->cf,rDst->cf);
1055 fraction f = (fraction)a;
1056 poly g = prMapR(NUM(f), nMap, rSrc, rDst);
1057
1058 number result=NULL;
1059 poly h = NULL;
1060
1061 if (!DENIS1(f))
1062 h = prMapR(DEN(f), nMap, rSrc, rDst);
1063
1064 if (h!=NULL)
1065 {
1066 result=naDiv((number)g,(number)h,dst);
1067 p_Delete(&g,dst->extRing);
1068 p_Delete(&h,dst->extRing);
1069 }
1070 else
1071 result=(number)g;
1072
1073 n_Test((number)result, dst);
1074 return (number)result;
1075}
1076
1077nMapFunc naSetMap(const coeffs src, const coeffs dst)
1078{
1079 /* dst is expected to be an algebraic field extension */
1080 assume(getCoeffType(dst) == n_algExt);
1081
1082 int h = 0; /* the height of the extension tower given by dst */
1083 coeffs bDst = nCoeff_bottom(dst, h); /* the bottom field in the tower dst */
1084 coeffs bSrc = nCoeff_bottom(src, h); /* the bottom field in the tower src */
1085
1086 /* for the time being, we only provide maps if h = 1 or 0 */
1087 if (h==0)
1088 {
1089 if ((src->rep==n_rep_gap_rat) && nCoeff_is_Q(bDst))
1090 return naMap00; /// Q or Z --> Q(a)
1091 if ((src->rep==n_rep_gap_gmp) && nCoeff_is_Q(bDst))
1092 return naMapZ0; /// Z --> Q(a)
1093 if (nCoeff_is_Zp(src) && nCoeff_is_Q(bDst))
1094 return naMapP0; /// Z/p --> Q(a)
1095 if (nCoeff_is_Q_or_BI(src) && nCoeff_is_Zp(bDst))
1096 return naMap0P; /// Q --> Z/p(a)
1097 if ((src->rep==n_rep_gap_gmp) && nCoeff_is_Zp(bDst))
1098 return naMapZ0; /// Z --> Z/p(a)
1099 if (nCoeff_is_Zp(src) && nCoeff_is_Zp(bDst))
1100 {
1101 if (src->ch == dst->ch) return naMapPP; /// Z/p --> Z/p(a)
1102 else return naMapUP; /// Z/u --> Z/p(a)
1103 }
1104 }
1105 if (h != 1) return NULL;
1106 if ((!nCoeff_is_Zp(bDst)) && (!nCoeff_is_Q(bDst))) return NULL;
1107 if ((!nCoeff_is_Zp(bSrc)) && (!nCoeff_is_Q_or_BI(bSrc))) return NULL;
1108
1109 nMapFunc nMap=n_SetMap(src->extRing->cf,dst->extRing->cf);
1110 if (rSamePolyRep(src->extRing, dst->extRing) && (strcmp(rRingVar(0, src->extRing), rRingVar(0, dst->extRing)) == 0))
1111 {
1112 if (src->type==n_algExt)
1113 return ndCopyMap; // naCopyMap; /// K(a) --> K(a)
1114 else
1115 return naCopyTrans2AlgExt;
1116 }
1117 else if ((nMap!=NULL) && (strcmp(rRingVar(0,src->extRing),rRingVar(0,dst->extRing))==0) && (rVar (src->extRing) == rVar (dst->extRing)))
1118 {
1119 if (src->type==n_algExt)
1120 return naGenMap; // naCopyMap; /// K(a) --> K'(a)
1121 else
1122 return naGenTrans2AlgExt;
1123 }
1124
1125 return NULL; /// default
1126}
1127
1128static int naParDeg(number a, const coeffs cf)
1129{
1130 if (a == NULL) return -1;
1131 poly aa=(poly)a;
1132 return cf->extRing->pFDeg(aa,cf->extRing);
1133}
1134
1135/// return the specified parameter as a number in the given alg. field
1136static number naParameter(const int iParameter, const coeffs cf)
1137{
1139
1140 const ring R = cf->extRing;
1141 assume( R != NULL );
1142 assume( 0 < iParameter && iParameter <= rVar(R) );
1143
1144 poly p = p_One(R); p_SetExp(p, iParameter, 1, R); p_Setm(p, R);
1145
1146 return (number) p;
1147}
1148
1149
1150/// if m == var(i)/1 => return i,
1151int naIsParam(number m, const coeffs cf)
1152{
1154
1155 const ring R = cf->extRing;
1156 assume( R != NULL );
1157
1158 return p_Var( (poly)m, R );
1159}
1160
1161
1162static void naClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
1163{
1164 assume(cf != NULL);
1166 assume(nCoeff_is_Q_algExt(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) !
1167
1168 const ring R = cf->extRing;
1169 assume(R != NULL);
1170 const coeffs Q = R->cf;
1171 assume(Q != NULL);
1173
1174 numberCollectionEnumerator.Reset();
1175
1176 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
1177 {
1178 c = n_Init(1, cf);
1179 return;
1180 }
1181
1182 naTest(numberCollectionEnumerator.Current());
1183
1184 // part 1, find a small candidate for gcd
1185 int s1; int s=2147483647; // max. int
1186
1187 const BOOLEAN lc_is_pos=naGreaterZero(numberCollectionEnumerator.Current(),cf);
1188
1189 int normalcount = 0;
1190
1191 poly cand1, cand;
1192
1193 do
1194 {
1195 number& n = numberCollectionEnumerator.Current();
1196 naNormalize(n, cf); ++normalcount;
1197
1198 naTest(n);
1199
1200 cand1 = (poly)n;
1201
1202 s1 = p_Deg(cand1, R); // naSize?
1203 if (s>s1)
1204 {
1205 cand = cand1;
1206 s = s1;
1207 }
1208 } while (numberCollectionEnumerator.MoveNext() );
1209
1210// assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
1211
1212 cand = p_Copy(cand, R);
1213 // part 2: compute gcd(cand,all coeffs)
1214
1215 numberCollectionEnumerator.Reset();
1216
1217 int length = 0;
1218 while (numberCollectionEnumerator.MoveNext() )
1219 {
1220 number& n = numberCollectionEnumerator.Current();
1221 ++length;
1222
1223 if( (--normalcount) <= 0)
1224 naNormalize(n, cf);
1225
1226 naTest(n);
1227
1228// p_InpGcd(cand, (poly)n, R);
1229
1230 { // R->cf is QQ
1231 poly tmp=gcd_over_Q(cand,(poly)n,R);
1232 p_Delete(&cand,R);
1233 cand=tmp;
1234 }
1235
1236// cand1 = p_Gcd(cand,(poly)n, R); p_Delete(&cand, R); cand = cand1;
1237
1238 assume( naGreaterZero((number)cand, cf) ); // ???
1239/*
1240 if(p_IsConstant(cand,R))
1241 {
1242 c = cand;
1243
1244 if(!lc_is_pos)
1245 {
1246 // make the leading coeff positive
1247 c = nlNeg(c, cf);
1248 numberCollectionEnumerator.Reset();
1249
1250 while (numberCollectionEnumerator.MoveNext() )
1251 {
1252 number& nn = numberCollectionEnumerator.Current();
1253 nn = nlNeg(nn, cf);
1254 }
1255 }
1256 return;
1257 }
1258*/
1259
1260 }
1261
1262
1263 // part3: all coeffs = all coeffs / cand
1264 if (!lc_is_pos)
1265 cand = p_Neg(cand, R);
1266
1267 c = (number)cand; naTest(c);
1268
1269 poly cInverse = (poly)naInvers(c, cf);
1270 assume(cInverse != NULL); // c is non-zero divisor!?
1271
1272
1273 numberCollectionEnumerator.Reset();
1274
1275
1276 while (numberCollectionEnumerator.MoveNext() )
1277 {
1278 number& n = numberCollectionEnumerator.Current();
1279
1280 assume( length > 0 );
1281
1282 if( --length > 0 )
1283 {
1284 assume( cInverse != NULL );
1285 n = (number) p_Mult_q(p_Copy(cInverse, R), (poly)n, R);
1286 }
1287 else
1288 {
1289 n = (number) p_Mult_q(cInverse, (poly)n, R);
1290 cInverse = NULL;
1291 assume(length == 0);
1292 }
1293
1294 definiteReduce((poly &)n, naMinpoly, cf);
1295 }
1296
1297 assume(length == 0);
1298 assume(cInverse == NULL); // p_Delete(&cInverse, R);
1299
1300 // Quick and dirty fix for constant content clearing... !?
1301 CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys!
1302
1303 number cc;
1304
1305 n_ClearContent(itr, cc, Q); // TODO: get rid of (-LC) normalization!?
1306
1307 // over alg. ext. of Q // takes over the input number
1308 c = (number) __p_Mult_nn( (poly)c, cc, R);
1309// p_Mult_q(p_NSet(cc, R), , R);
1310
1311 n_Delete(&cc, Q);
1312
1313 // TODO: the above is not enough! need GCD's of polynomial coeffs...!
1314/*
1315 // old and wrong part of p_Content
1316 if (rField_is_Q_a(r) && !CLEARENUMERATORS) // should not be used anymore if CLEARENUMERATORS is 1
1317 {
1318 // we only need special handling for alg. ext.
1319 if (getCoeffType(r->cf)==n_algExt)
1320 {
1321 number hzz = n_Init(1, r->cf->extRing->cf);
1322 p=ph;
1323 while (p!=NULL)
1324 { // each monom: coeff in Q_a
1325 poly c_n_n=(poly)pGetCoeff(p);
1326 poly c_n=c_n_n;
1327 while (c_n!=NULL)
1328 { // each monom: coeff in Q
1329 d=n_NormalizeHelper(hzz,pGetCoeff(c_n),r->cf->extRing->cf);
1330 n_Delete(&hzz,r->cf->extRing->cf);
1331 hzz=d;
1332 pIter(c_n);
1333 }
1334 pIter(p);
1335 }
1336 // hzz contains the 1/lcm of all denominators in c_n_n
1337 h=n_Invers(hzz,r->cf->extRing->cf);
1338 n_Delete(&hzz,r->cf->extRing->cf);
1339 n_Normalize(h,r->cf->extRing->cf);
1340 if(!n_IsOne(h,r->cf->extRing->cf))
1341 {
1342 p=ph;
1343 while (p!=NULL)
1344 { // each monom: coeff in Q_a
1345 poly c_n=(poly)pGetCoeff(p);
1346 while (c_n!=NULL)
1347 { // each monom: coeff in Q
1348 d=n_Mult(h,pGetCoeff(c_n),r->cf->extRing->cf);
1349 n_Normalize(d,r->cf->extRing->cf);
1350 n_Delete(&pGetCoeff(c_n),r->cf->extRing->cf);
1351 pGetCoeff(c_n)=d;
1352 pIter(c_n);
1353 }
1354 pIter(p);
1355 }
1356 }
1357 n_Delete(&h,r->cf->extRing->cf);
1358 }
1359 }
1360*/
1361
1362
1363// c = n_Init(1, cf); assume(FALSE); // TODO: NOT YET IMPLEMENTED!!!
1364}
1365
1366
1367static void naClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
1368{
1369 assume(cf != NULL);
1371 assume(nCoeff_is_Q_algExt(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) !
1372
1373 assume(cf->extRing != NULL);
1374 const coeffs Q = cf->extRing->cf;
1375 assume(Q != NULL);
1377 number n;
1378 CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys!
1379 n_ClearDenominators(itr, n, Q); // this should probably be fine...
1380 c = (number)p_NSet(n, cf->extRing); // over alg. ext. of Q // takes over the input number
1381}
1382
1384{
1385 rDecRefCnt(cf->extRing);
1386 if(cf->extRing->ref<=0)
1387 rDelete(cf->extRing);
1388}
1389
1390char* naCoeffName(const coeffs r) // currently also for tranext.
1391{
1392 const char* const* p=n_ParameterNames(r);
1393 int l=0;
1394 int i;
1395 for(i=0; i<n_NumberOfParameters(r);i++)
1396 {
1397 l+=(strlen(p[i])+1);
1398 }
1399 STATIC_VAR char s[200];
1400 s[0]='\0';
1401 snprintf(s,10+1,"%d",r->ch); /* Fp(a) or Q(a) */
1402 char tt[2];
1403 tt[0]=',';
1404 tt[1]='\0';
1405 for(i=0; i<n_NumberOfParameters(r);i++)
1406 {
1407 strcat(s,tt);
1408 strcat(s,p[i]);
1409 }
1410 return s;
1411}
1412
1413static number naChineseRemainder(number *x, number *q,int rl, BOOLEAN /*sym*/,CFArray &inv_cache,const coeffs cf)
1414{
1415 poly *P=(poly*)omAlloc(rl*sizeof(poly*));
1416 number *X=(number *)omAlloc(rl*sizeof(number));
1417 int i;
1418 for(i=0;i<rl;i++) P[i]=p_Copy((poly)(x[i]),cf->extRing);
1419 poly result=p_ChineseRemainder(P,X,q,rl,inv_cache,cf->extRing);
1420 omFreeSize(X,rl*sizeof(number));
1421 omFreeSize(P,rl*sizeof(poly*));
1422 return ((number)result);
1423}
1424
1425static number naFarey(number p, number n, const coeffs cf)
1426{
1427 // n is really a bigint
1428 poly result=p_Farey(p_Copy((poly)p,cf->extRing),n,cf->extRing);
1429 return ((number)result);
1430}
1431
1432
1433BOOLEAN naInitChar(coeffs cf, void * infoStruct)
1434{
1435 assume( infoStruct != NULL );
1436
1437 AlgExtInfo *e = (AlgExtInfo *)infoStruct;
1438 /// first check whether cf->extRing != NULL and delete old ring???
1439
1440 assume(e->r != NULL); // extRing;
1441 assume(e->r->cf != NULL); // extRing->cf;
1442
1443 assume((e->r->qideal != NULL) && // minideal has one
1444 (IDELEMS(e->r->qideal) == 1) && // non-zero generator
1445 (e->r->qideal->m[0] != NULL) ); // at m[0];
1446
1447 assume( cf != NULL );
1448 assume(getCoeffType(cf) == n_algExt); // coeff type;
1449
1450 rIncRefCnt(e->r); // increase the ref.counter for the ground poly. ring!
1451 const ring R = e->r; // no copy!
1452 cf->extRing = R;
1453
1454 /* propagate characteristic up so that it becomes
1455 directly accessible in cf: */
1456 cf->ch = R->cf->ch;
1457
1458 cf->is_field=TRUE;
1459 cf->is_domain=TRUE;
1460 cf->rep=n_rep_poly;
1461
1462 #ifdef LDEBUG
1463 p_Test((poly)naMinpoly, naRing);
1464 #endif
1465
1466 cf->cfCoeffName = naCoeffName;
1467
1468 cf->cfGreaterZero = naGreaterZero;
1469 cf->cfGreater = naGreater;
1470 cf->cfEqual = naEqual;
1471 cf->cfIsZero = naIsZero;
1472 cf->cfIsOne = naIsOne;
1473 cf->cfIsMOne = naIsMOne;
1474 cf->cfInit = naInit;
1475 cf->cfInitMPZ = naInitMPZ;
1476 cf->cfFarey = naFarey;
1477 cf->cfChineseRemainder= naChineseRemainder;
1478 cf->cfInt = naInt;
1479 cf->cfInpNeg = naNeg;
1480 cf->cfAdd = naAdd;
1481 cf->cfSub = naSub;
1482 cf->cfMult = naMult;
1483 cf->cfInpMult = naInpMult;
1484 cf->cfDiv = naDiv;
1485 cf->cfExactDiv = naDiv;
1486 cf->cfPower = naPower;
1487 cf->cfCopy = naCopy;
1488
1489 cf->cfWriteLong = naWriteLong;
1490
1491 if( rCanShortOut(naRing) )
1492 cf->cfWriteShort = naWriteShort;
1493 else
1494 cf->cfWriteShort = naWriteLong;
1495
1496 cf->cfRead = naRead;
1497 cf->cfDelete = naDelete;
1498 cf->cfSetMap = naSetMap;
1499 cf->cfRePart = naCopy;
1500 cf->cfCoeffWrite = naCoeffWrite;
1501 cf->cfNormalize = naNormalize;
1502 cf->cfKillChar = naKillChar;
1503#ifdef LDEBUG
1504 cf->cfDBTest = naDBTest;
1505#endif
1506 cf->cfGcd = naGcd;
1507 cf->cfNormalizeHelper = naLcmContent;
1508 cf->cfSize = naSize;
1509 cf->nCoeffIsEqual = naCoeffIsEqual;
1510 cf->cfInvers = naInvers;
1511 cf->convFactoryNSingN=naConvFactoryNSingN;
1512 cf->convSingNFactoryN=naConvSingNFactoryN;
1513 cf->cfParDeg = naParDeg;
1514
1515 cf->iNumberOfParameters = rVar(R);
1516 cf->pParameterNames = (const char**)R->names;
1517 cf->cfParameter = naParameter;
1518 cf->has_simple_Inverse= R->cf->has_simple_Inverse;
1519 /* cf->has_simple_Alloc= FALSE; */
1520
1521 if( nCoeff_is_Q(R->cf) )
1522 {
1523 cf->cfClearContent = naClearContent;
1524 cf->cfClearDenominators = naClearDenominators;
1525 }
1526
1527 return FALSE;
1528}
1529
1531
1532template class IAccessor<snumber*>;
1533
1534/* --------------------------------------------------------------------*/
1535/****************************************
1536* Computer Algebra System SINGULAR *
1537****************************************/
1538/**
1539 * ABSTRACT: numbers as polys in the ring K[a]
1540 * Assuming that we have a coeffs object cf, then these numbers
1541 * are polynomials in the polynomial ring K[a] represented by
1542 * cf->extRing.
1543 * IMPORTANT ASSUMPTIONS:
1544 * 1.) So far we assume that cf->extRing is a valid polynomial
1545 * ring
1546 **/
1547
1548#ifdef LDEBUG
1549#define n2pTest(a) n2pDBTest(a,__FILE__,__LINE__,cf)
1550BOOLEAN n2pDBTest(number a, const char *f, const int l, const coeffs r);
1551#else
1552#define n2pTest(a) do {} while (0)
1553#endif
1554
1555/* polynomial ring in which our numbers live */
1556#define n2pRing cf->extRing
1557
1558/* coeffs object in which the coefficients of our numbers live;
1559 * methods attached to n2pCoeffs may be used to compute with the
1560 * coefficients of our numbers, e.g., use n2pCoeffs->nAdd to add
1561 * coefficients of our numbers */
1562#define n2pCoeffs cf->extRing->cf
1563
1564#ifdef LDEBUG
1565BOOLEAN n2pDBTest(number a, const char */*f*/, const int /*l*/, const coeffs cf)
1566{
1567 if (a == NULL) return TRUE;
1568 return p_Test((poly)a, n2pRing);
1569}
1570#endif
1571
1572void n2pNormalize(number &a, const coeffs cf)
1573{
1574 poly aa=(poly)a;
1575 p_Normalize(aa,n2pRing);
1576}
1577
1578/* TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b) or (deg(a)==deg(b) && lc(a)>lc(b))) */
1579number n2pMult(number a, number b, const coeffs cf)
1580{
1581 n2pTest(a); n2pTest(b);
1582 if ((a == NULL)||(b == NULL)) return NULL;
1583 poly aTimesB = pp_Mult_qq((poly)a, (poly)b, n2pRing);
1584 return (number)aTimesB;
1585}
1586
1587number n2pDiv(number a, number b, const coeffs cf)
1588{
1589 n2pTest(a); n2pTest(b);
1590 if (b == NULL) WerrorS(nDivBy0);
1591 if (a == NULL) return NULL;
1592 poly p=singclap_pdivide((poly)a,(poly)b,n2pRing);
1593 return (number)p;
1594}
1595
1596void n2pPower(number a, int exp, number *b, const coeffs cf)
1597{
1598 n2pTest(a);
1599
1600 *b= (number)p_Power((poly)a,exp,n2pRing);
1601}
1602
1603const char * n2pRead(const char *s, number *a, const coeffs cf)
1604{
1605 poly aAsPoly;
1606 const char * result = p_Read(s, aAsPoly, n2pRing);
1607 *a = (number)aAsPoly;
1608 return result;
1609}
1610
1611/* expects *param to be castable to AlgExtInfo */
1612static BOOLEAN n2pCoeffIsEqual(const coeffs cf, n_coeffType n, void * param)
1613{
1614 if (n_polyExt != n) return FALSE;
1615 AlgExtInfo *e = (AlgExtInfo *)param;
1616 /* for extension coefficient fields we expect the underlying
1617 polynomial rings to be IDENTICAL, i.e. the SAME OBJECT;
1618 this expectation is based on the assumption that we have properly
1619 registered cf and perform reference counting rather than creating
1620 multiple copies of the same coefficient field/domain/ring */
1621 if (n2pRing == e->r)
1622 return TRUE;
1623 // NOTE: Q(a)[x] && Q(a)[y] should better share the _same_ Q(a)...
1624 if( rEqual(n2pRing, e->r, TRUE) ) // also checks the equality of qideals
1625 {
1626 rDelete(e->r);
1627 return TRUE;
1628 }
1629 return FALSE;
1630}
1631
1633{
1634 const char* const* p=n_ParameterNames(cf);
1635 int l=0;
1636 int i;
1637 for(i=0; i<rVar(n2pRing);i++)
1638 {
1639 l+=(strlen(p[i])+1);
1640 }
1641 char *cf_s=nCoeffName(n2pRing->cf);
1642 STATIC_VAR char s[200];
1643 s[0]='\0';
1644 snprintf(s,strlen(cf_s)+2,"%s",cf_s);
1645 char tt[2];
1646 tt[0]='[';
1647 tt[1]='\0';
1648 strcat(s,tt);
1649 tt[0]=',';
1650 for(i=0; i<rVar(n2pRing);i++)
1651 {
1652 strcat(s,p[i]);
1653 if (i+1!=rVar(n2pRing)) strcat(s,tt);
1654 else { tt[0]=']'; strcat(s,tt); }
1655 }
1656 return s;
1657}
1658
1659void n2pCoeffWrite(const coeffs cf, BOOLEAN details)
1660{
1661 assume( cf != NULL );
1662
1663 const ring A = cf->extRing;
1664
1665 assume( A != NULL );
1666 PrintS("// polynomial ring as coefficient ring :\n");
1667 rWrite(A);
1668 PrintLn();
1669}
1670
1671number n2pInvers(number a, const coeffs cf)
1672{
1673 poly aa=(poly)a;
1674 if(p_IsConstant(aa, n2pRing))
1675 {
1676 poly p=p_Init(n2pRing);
1678 return (number)p;
1679 }
1680 else
1681 {
1682 WerrorS("not invertible");
1683 return NULL;
1684 }
1685}
1686
1687BOOLEAN n2pInitChar(coeffs cf, void * infoStruct)
1688{
1689 assume( infoStruct != NULL );
1690
1691 AlgExtInfo *e = (AlgExtInfo *)infoStruct;
1692 /// first check whether cf->extRing != NULL and delete old ring???
1693
1694 assume(e->r != NULL); // extRing;
1695 assume(e->r->cf != NULL); // extRing->cf;
1696
1697 assume( cf != NULL );
1698
1699 rIncRefCnt(e->r); // increase the ref.counter for the ground poly. ring!
1700 const ring R = e->r; // no copy!
1701 cf->extRing = R;
1702
1703 /* propagate characteristic up so that it becomes
1704 directly accessible in cf: */
1705 cf->ch = R->cf->ch;
1706 cf->is_field=FALSE;
1707 cf->is_domain=TRUE;
1708
1709 cf->cfCoeffName = n2pCoeffName;
1710
1711 cf->cfGreaterZero = naGreaterZero;
1712 cf->cfGreater = naGreater;
1713 cf->cfEqual = naEqual;
1714 cf->cfIsZero = naIsZero;
1715 cf->cfIsOne = naIsOne;
1716 cf->cfIsMOne = naIsMOne;
1717 cf->cfInit = naInit;
1718 cf->cfInitMPZ = naInitMPZ;
1719 cf->cfFarey = naFarey;
1720 cf->cfChineseRemainder= naChineseRemainder;
1721 cf->cfInt = naInt;
1722 cf->cfInpNeg = naNeg;
1723 cf->cfAdd = naAdd;
1724 cf->cfInpAdd = naInpAdd;
1725 cf->cfSub = naSub;
1726 cf->cfMult = n2pMult;
1727 cf->cfDiv = n2pDiv;
1728 cf->cfPower = n2pPower;
1729 cf->cfCopy = naCopy;
1730
1731 cf->cfWriteLong = naWriteLong;
1732
1733 if( rCanShortOut(n2pRing) )
1734 cf->cfWriteShort = naWriteShort;
1735 else
1736 cf->cfWriteShort = naWriteLong;
1737
1738 cf->cfRead = n2pRead;
1739 cf->cfDelete = naDelete;
1740 cf->cfSetMap = naSetMap;
1741 //cf->cfGetDenom = naGetDenom; // use nd*
1742 //cf->cfGetNumerator = naGetNumerator; // use nd*
1743 cf->cfRePart = naCopy;
1744 cf->cfCoeffWrite = n2pCoeffWrite;
1745 cf->cfNormalize = n2pNormalize;
1746 cf->cfKillChar = naKillChar;
1747#ifdef LDEBUG
1748 cf->cfDBTest = naDBTest;
1749#endif
1750 cf->cfGcd = naGcd;
1751 cf->cfNormalizeHelper = naLcmContent;
1752 cf->cfSize = naSize;
1753 cf->nCoeffIsEqual = n2pCoeffIsEqual;
1754 cf->cfInvers = n2pInvers;
1755 cf->convFactoryNSingN=naConvFactoryNSingN;
1756 cf->convSingNFactoryN=naConvSingNFactoryN;
1757 cf->cfParDeg = naParDeg;
1758
1759 cf->iNumberOfParameters = rVar(R);
1760 cf->pParameterNames = (const char**)R->names;
1761 cf->cfParameter = naParameter;
1762 cf->has_simple_Inverse=FALSE;
1763 /* cf->has_simple_Alloc= FALSE; */
1764
1765 if( nCoeff_is_Q(R->cf) )
1766 {
1767 cf->cfClearContent = naClearContent;
1768 cf->cfClearDenominators = naClearDenominators;
1769 }
1770
1771 return FALSE;
1772}
Rational pow(const Rational &a, int e)
Definition GMPrat.cc:411
Concrete implementation of enumerators over polynomials.
static number naInit(long i, const coeffs cf)
Definition algext.cc:325
number n2pDiv(number a, number b, const coeffs cf)
Definition algext.cc:1587
static number naSub(number a, number b, const coeffs cf)
Definition algext.cc:451
static BOOLEAN naEqual(number a, number b, const coeffs cf)
Definition algext.cc:285
static BOOLEAN naGreaterZero(number a, const coeffs cf)
forward declarations
Definition algext.cc:370
static CanonicalForm naConvSingNFactoryN(number n, BOOLEAN, const coeffs cf)
Definition algext.cc:769
static void naInpAdd(number &a, number b, const coeffs cf)
Definition algext.cc:440
static BOOLEAN naIsOne(number a, const coeffs cf)
Definition algext.cc:301
static void p_Monic(poly p, const ring r)
returns NULL if p == NULL, otherwise makes p monic by dividing by its leading coefficient (only done ...
Definition algext.cc:118
static number naFarey(number p, number n, const coeffs cf)
Definition algext.cc:1425
static number naInvers(number a, const coeffs cf)
Definition algext.cc:831
static void naPower(number a, int exp, number *b, const coeffs cf)
Definition algext.cc:506
static number naGenTrans2AlgExt(number a, const coeffs cf, const coeffs dst)
Definition algext.cc:1047
number n2pMult(number a, number b, const coeffs cf)
Definition algext.cc:1579
static void heuristicReduce(poly &p, poly reducer, const coeffs cf)
Definition algext.cc:573
const char * n2pRead(const char *s, number *a, const coeffs cf)
Definition algext.cc:1603
static number naChineseRemainder(number *x, number *q, int rl, BOOLEAN, CFArray &inv_cache, const coeffs cf)
Definition algext.cc:1413
#define naMinpoly
Definition algext.cc:70
static number naConvFactoryNSingN(const CanonicalForm n, const coeffs cf)
Definition algext.cc:763
static number naMult(number a, number b, const coeffs cf)
Definition algext.cc:462
static void naInpMult(number &a, number b, const coeffs cf)
Definition algext.cc:472
static number naGenMap(number a, const coeffs cf, const coeffs dst)
Definition algext.cc:1032
static BOOLEAN naDBTest(number a, const char *f, const int l, const coeffs r)
Definition algext.cc:231
static number naMapPP(number a, const coeffs src, const coeffs dst)
Definition algext.cc:1011
static void naClearContent(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition algext.cc:1162
static const char * naRead(const char *s, number *a, const coeffs cf)
Definition algext.cc:619
static number napNormalizeHelper(number b, const coeffs cf)
Definition algext.cc:642
static void naWriteShort(number a, const coeffs cf)
Definition algext.cc:601
static int naSize(number a, const coeffs cf)
Definition algext.cc:725
static number naAdd(number a, number b, const coeffs cf)
Definition algext.cc:429
poly p_ExtGcd(poly p, poly &pFactor, poly q, poly &qFactor, ring r)
assumes that p and q are univariate polynomials in r, mentioning the same variable; assumes a global ...
Definition algext.cc:214
static poly p_Gcd(const poly p, const poly q, const ring r)
Definition algext.cc:163
static number naMapZ0(number a, const coeffs src, const coeffs dst)
Definition algext.cc:918
static number naParameter(const int iParameter, const coeffs cf)
return the specified parameter as a number in the given alg. field
Definition algext.cc:1136
static number naMap0P(number a, const coeffs src, const coeffs dst)
Definition algext.cc:998
BOOLEAN n2pDBTest(number a, const char *f, const int l, const coeffs r)
Definition algext.cc:1565
#define n2pRing
Definition algext.cc:1556
static void definiteReduce(poly &p, poly reducer, const coeffs cf)
Definition algext.cc:743
static int naParDeg(number a, const coeffs cf)
Definition algext.cc:1128
static number naCopy(number a, const coeffs cf)
Definition algext.cc:294
static number naCopyTrans2AlgExt(number a, const coeffs src, const coeffs dst)
Definition algext.cc:950
#define n2pCoeffs
Definition algext.cc:1562
static void naClearDenominators(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition algext.cc:1367
static number naMapUP(number a, const coeffs src, const coeffs dst)
Definition algext.cc:1021
static number naInitMPZ(mpz_t m, const coeffs r)
Definition algext.cc:331
static BOOLEAN n2pCoeffIsEqual(const coeffs cf, n_coeffType n, void *param)
Definition algext.cc:1612
static long naInt(number &a, const coeffs cf)
Definition algext.cc:337
static number naLcmContent(number a, number b, const coeffs cf)
Definition algext.cc:656
char * n2pCoeffName(const coeffs cf)
Definition algext.cc:1632
static number naGcd(number a, number b, const coeffs cf)
Definition algext.cc:783
#define naCoeffs
Definition algext.cc:67
static BOOLEAN naCoeffIsEqual(const coeffs cf, n_coeffType n, void *param)
Definition algext.cc:691
char * naCoeffName(const coeffs r)
Definition algext.cc:1390
nMapFunc naSetMap(const coeffs src, const coeffs dst)
Get a mapping function from src into the domain of this type (n_algExt).
Definition algext.cc:1077
static poly p_ExtGcdHelper(poly &p, poly &pFactor, poly &q, poly &qFactor, ring r)
Definition algext.cc:181
static void naKillChar(coeffs cf)
Definition algext.cc:1383
static BOOLEAN naGreater(number a, number b, const coeffs cf)
Definition algext.cc:350
#define naRing
Definition algext.cc:61
BOOLEAN naInitChar(coeffs cf, void *infoStruct)
Initialize the coeffs object.
Definition algext.cc:1433
#define naTest(a)
Definition algext.cc:54
static void naNormalize(number &a, const coeffs cf)
Definition algext.cc:755
BOOLEAN n2pInitChar(coeffs cf, void *infoStruct)
Definition algext.cc:1687
static BOOLEAN naIsZero(number a, const coeffs cf)
Definition algext.cc:270
number n2pInvers(number a, const coeffs cf)
Definition algext.cc:1671
static number naMap00(number a, const coeffs src, const coeffs dst)
Definition algext.cc:908
static number naDiv(number a, number b, const coeffs cf)
Definition algext.cc:482
int naIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition algext.cc:1151
void n2pCoeffWrite(const coeffs cf, BOOLEAN details)
Definition algext.cc:1659
static void naDelete(number *a, const coeffs cf)
Definition algext.cc:276
#define n2pTest(a)
ABSTRACT: numbers as polys in the ring K[a] Assuming that we have a coeffs object cf,...
Definition algext.cc:1549
void n2pNormalize(number &a, const coeffs cf)
Definition algext.cc:1572
static number naMapP0(number a, const coeffs src, const coeffs dst)
Definition algext.cc:930
static coeffs nCoeff_bottom(const coeffs r, int &height)
Definition algext.cc:256
static void naCoeffWrite(const coeffs cf, BOOLEAN details)
Definition algext.cc:379
static void naWriteLong(number a, const coeffs cf)
Definition algext.cc:583
void n2pPower(number a, int exp, number *b, const coeffs cf)
Definition algext.cc:1596
static number naNeg(number a, const coeffs cf)
this is in-place, modifies a
Definition algext.cc:318
static BOOLEAN naIsMOne(number a, const coeffs cf)
Definition algext.cc:309
static poly p_GcdHelper(poly &p, poly &q, const ring r)
see p_Gcd; additional assumption: deg(p) >= deg(q); must destroy p and q (unless one of them is retur...
Definition algext.cc:143
ring r
Definition algext.h:37
struct for passing initialization parameters to naInitChar
Definition algext.h:37
All the auxiliary stuff.
int BOOLEAN
Definition auxiliary.h:88
#define TRUE
Definition auxiliary.h:101
#define FALSE
Definition auxiliary.h:97
CanonicalForm lc(const CanonicalForm &f)
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f ).
Definition cf_gcd.cc:676
Array< CanonicalForm > CFArray
int l
Definition cfEzgcd.cc:100
int m
Definition cfEzgcd.cc:128
int i
Definition cfEzgcd.cc:132
const CanonicalForm const CanonicalForm const CanonicalForm const CanonicalForm & cand
Definition cfModGcd.cc:70
Variable x
Definition cfModGcd.cc:4090
int p
Definition cfModGcd.cc:4086
g
Definition cfModGcd.cc:4098
CanonicalForm cf
Definition cfModGcd.cc:4091
CanonicalForm b
Definition cfModGcd.cc:4111
STATIC_VAR int theDegree
Definition cf_char.cc:26
FILE * f
Definition checklibs.c:9
CanonicalForm convSingPFactoryP(poly p, const ring r)
Definition clapconv.cc:138
poly convFactoryPSingP(const CanonicalForm &f, const ring r)
Definition clapconv.cc:40
poly singclap_pdivide(poly f, poly g, const ring r)
Definition clapsing.cc:649
BOOLEAN singclap_extgcd(poly f, poly g, poly &res, poly &pa, poly &pb, const ring r)
Definition clapsing.cc:505
poly singclap_gcd_r(poly f, poly g, const ring r)
Definition clapsing.cc:70
go into polynomials over an alg. extension recursively
factory's main class
CF_NO_INLINE bool isZero() const
Templated accessor interface for accessing individual data (for instance, of an enumerator).
Definition Enumerator.h:82
virtual reference Current()=0
Gets the current element in the collection (read and write).
virtual void Reset()=0
Sets the enumerator to its initial position: -1, which is before the first element in the collection.
virtual bool MoveNext()=0
Advances the enumerator to the next element of the collection. returns true if the enumerator was suc...
Coefficient rings, fields and other domains suitable for Singular polynomials.
static FORCE_INLINE number n_Mult(number a, number b, const coeffs r)
return the product of 'a' and 'b', i.e., a*b
Definition coeffs.h:639
IEnumerator< number > ICoeffsEnumerator
Abstract interface for an enumerator of number coefficients for an object, e.g. a polynomial.
Definition coeffs.h:85
static FORCE_INLINE long n_Int(number &n, const coeffs r)
conversion of n to an int; 0 if not possible in Z/pZ: the representing int lying in (-p/2 ....
Definition coeffs.h:550
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of 'n'
Definition coeffs.h:457
static FORCE_INLINE number n_NormalizeHelper(number a, number b, const coeffs r)
assume that r is a quotient field (otherwise, return 1) for arguments (a1/a2,b1/b2) return (lcm(a1,...
Definition coeffs.h:698
static FORCE_INLINE void n_CoeffWrite(const coeffs r, BOOLEAN details=TRUE)
output the coeff description
Definition coeffs.h:722
static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
Definition coeffs.h:844
number ndCopyMap(number a, const coeffs src, const coeffs dst)
Definition numbers.cc:293
#define n_Test(a, r)
BOOLEAN n_Test(number a, const coeffs r).
Definition coeffs.h:715
n_coeffType
Definition coeffs.h:27
@ n_polyExt
used to represent polys as coefficients
Definition coeffs.h:34
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition coeffs.h:35
static FORCE_INLINE number n_Invers(number a, const coeffs r)
return the multiplicative inverse of 'a'; raise an error if 'a' is not invertible
Definition coeffs.h:567
static FORCE_INLINE BOOLEAN n_GreaterZero(number n, const coeffs r)
ordered fields: TRUE iff 'n' is positive; in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2),...
Definition coeffs.h:500
static FORCE_INLINE BOOLEAN n_IsMOne(number n, const coeffs r)
TRUE iff 'n' represents the additive inverse of the one element, i.e. -1.
Definition coeffs.h:478
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition coeffs.h:703
static FORCE_INLINE char const ** n_ParameterNames(const coeffs r)
Returns a (const!) pointer to (const char*) names of parameters.
Definition coeffs.h:770
static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
return the quotient of 'a' and 'b', i.e., a/b; raises an error if 'b' is not invertible in r exceptio...
Definition coeffs.h:618
static FORCE_INLINE BOOLEAN nCoeff_is_Q(const coeffs r)
Definition coeffs.h:804
static FORCE_INLINE BOOLEAN n_Greater(number a, number b, const coeffs r)
ordered fields: TRUE iff 'a' is larger than 'b'; in Z/pZ: TRUE iff la > lb, where la and lb are the l...
Definition coeffs.h:517
static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
TRUE iff 'n' represents the zero element.
Definition coeffs.h:470
static FORCE_INLINE void n_ClearDenominators(ICoeffsEnumerator &numberCollectionEnumerator, number &d, const coeffs r)
(inplace) Clears denominators on a collection of numbers number d is the LCM of all the coefficient d...
Definition coeffs.h:937
static FORCE_INLINE BOOLEAN nCoeff_is_Q_or_BI(const coeffs r)
Definition coeffs.h:827
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition coeffs.h:431
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition coeffs.h:461
static FORCE_INLINE char * nCoeffName(const coeffs cf)
Definition coeffs.h:965
static FORCE_INLINE number n_InitMPZ(mpz_t n, const coeffs r)
conversion of a GMP integer to number
Definition coeffs.h:545
static FORCE_INLINE int n_NumberOfParameters(const coeffs r)
Returns the number of parameters.
Definition coeffs.h:766
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition coeffs.h:794
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition coeffs.h:541
static FORCE_INLINE void n_ClearContent(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs r)
Computes the content and (inplace) divides it out on a collection of numbers number c is the content ...
Definition coeffs.h:930
static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
TRUE iff r represents an algebraic extension field.
Definition coeffs.h:908
@ n_rep_gap_rat
(number), see longrat.h
Definition coeffs.h:118
@ n_rep_gap_gmp
(), see rinteger.h, new impl.
Definition coeffs.h:119
@ n_rep_poly
(poly), see algext.h
Definition coeffs.h:120
static FORCE_INLINE number n_SubringGcd(number a, number b, const coeffs r)
Definition coeffs.h:669
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition coeffs.h:80
static FORCE_INLINE void n_Normalize(number &n, const coeffs r)
inplace-normalization of n; produces some canonical representation of n;
Definition coeffs.h:581
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition coeffs.h:474
static FORCE_INLINE BOOLEAN nCoeff_is_transExt(const coeffs r)
TRUE iff r represents a transcendental extension field.
Definition coeffs.h:916
static FORCE_INLINE BOOLEAN nCoeff_is_Q_algExt(const coeffs r)
is it an alg. ext. of Q?
Definition coeffs.h:912
static BOOLEAN fa(leftv res, leftv args)
Definition cohomo.cc:3814
#define Print
Definition emacs.cc:80
return result
const CanonicalForm int s
Definition facAbsFact.cc:51
const CanonicalForm int const CFList const Variable & y
Definition facAbsFact.cc:53
CanonicalForm factor
Definition facAbsFact.cc:97
factory.h' is the user interface to Factory.
void WerrorS(const char *s)
Definition feFopen.cc:24
#define STATIC_VAR
Definition globaldefs.h:7
static BOOLEAN length(leftv result, leftv arg)
Definition interval.cc:257
STATIC_VAR Poly * h
Definition janet.cc:971
poly p_ChineseRemainder(poly *xx, mpz_ptr *x, mpz_ptr *q, int rl, mpz_ptr *C, const ring R)
number nlModP(number q, const coeffs, const coeffs Zp)
Definition longrat.cc:1573
#define assume(x)
Definition mod2.h:389
int dReportError(const char *fmt,...)
Definition dError.cc:44
#define p_SetCoeff0(p, n, r)
Definition monomials.h:60
#define pIter(p)
Definition monomials.h:37
#define pNext(p)
Definition monomials.h:36
#define p_GetCoeff(p, r)
Definition monomials.h:50
static number & pGetCoeff(poly p)
return an alias to the leading coefficient of p assumes that p != NULL NOTE: not copy
Definition monomials.h:44
gmp_float exp(const gmp_float &a)
The main handler for Singular numbers which are suitable for Singular polynomials.
Definition ap.h:40
number ndGcd(number, number, const coeffs r)
Definition numbers.cc:193
const char *const nDivBy0
Definition numbers.h:90
#define omFreeSize(addr, size)
#define omAlloc(size)
#define NULL
Definition omList.c:12
poly p_Farey(poly p, number N, const ring r)
Definition p_polys.cc:54
poly p_PolyDiv(poly &p, const poly divisor, const BOOLEAN needResult, const ring r)
assumes that p and divisor are univariate polynomials in r, mentioning the same variable; assumes div...
Definition p_polys.cc:1874
poly p_ISet(long i, const ring r)
returns the poly representing the integer i
Definition p_polys.cc:1298
poly p_PermPoly(poly p, const int *perm, const ring oldRing, const ring dst, nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
Definition p_polys.cc:4269
poly p_Power(poly p, int i, const ring r)
Definition p_polys.cc:2245
void p_Normalize(poly p, const ring r)
Definition p_polys.cc:3952
int p_Var(poly m, const ring r)
Definition p_polys.cc:4823
poly p_One(const ring r)
Definition p_polys.cc:1314
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition p_polys.cc:1474
long p_Deg(poly a, const ring r)
Definition p_polys.cc:586
const char * p_Read(const char *st, poly &rc, const ring r)
Definition p_polys.cc:1371
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition p_polys.cc:4679
static poly p_Neg(poly p, const ring r)
Definition p_polys.h:1114
static poly p_Add_q(poly p, poly q, const ring r)
Definition p_polys.h:938
static poly p_Mult_q(poly p, poly q, const ring r)
Definition p_polys.h:1125
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent @Note: VarOffset encodes the position in p->exp
Definition p_polys.h:490
void p_String0Long(const poly p, ring lmRing, ring tailRing)
print p in a long way
Definition polys0.cc:203
void p_String0Short(const poly p, ring lmRing, ring tailRing)
print p in a short way, if possible
Definition polys0.cc:184
static void p_Setm(poly p, const ring r)
Definition p_polys.h:235
static number p_SetCoeff(poly p, number n, ring r)
Definition p_polys.h:414
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent @Note: the integer VarOffset encodes:
Definition p_polys.h:471
static BOOLEAN p_IsConstant(const poly p, const ring r)
Definition p_polys.h:1985
static void p_Delete(poly *p, const ring r)
Definition p_polys.h:903
void p_Write0(poly p, ring lmRing, ring tailRing)
Definition polys0.cc:332
static poly pp_Mult_qq(poly p, poly q, const ring r)
Definition p_polys.h:1167
static poly p_Init(const ring r, omBin bin)
Definition p_polys.h:1341
static poly p_Copy(poly p, const ring r)
returns a copy of p
Definition p_polys.h:848
static long p_Totaldegree(poly p, const ring r)
Definition p_polys.h:1528
#define p_Test(p, r)
Definition p_polys.h:161
#define __p_Mult_nn(p, n, r)
Definition p_polys.h:973
poly prMapR(poly src, nMapFunc nMap, ring src_r, ring dest_r)
Definition prCopy.cc:45
#define NUM
Definition readcf.cc:180
void StringAppendS(const char *st)
Definition reporter.cc:107
void PrintS(const char *s)
Definition reporter.cc:288
void PrintLn()
Definition reporter.cc:314
void rWrite(ring r, BOOLEAN details)
Definition ring.cc:227
BOOLEAN rSamePolyRep(ring r1, ring r2)
returns TRUE, if r1 and r2 represents the monomials in the same way FALSE, otherwise this is an analo...
Definition ring.cc:1805
void rDelete(ring r)
unconditionally deletes fields in r
Definition ring.cc:454
BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
returns TRUE, if r1 equals r2 FALSE, otherwise Equality is determined componentwise,...
Definition ring.cc:1752
static ring rIncRefCnt(ring r)
Definition ring.h:854
static char * rRingVar(short i, const ring r)
Definition ring.h:588
static void rDecRefCnt(ring r)
Definition ring.h:855
static BOOLEAN rCanShortOut(const ring r)
Definition ring.h:597
static short rVar(const ring r)
define rVar(r) (r->N)
Definition ring.h:603
int status int void * buf
Definition si_signals.h:69
#define IDELEMS(i)
#define R
Definition sirandom.c:27
#define A
Definition sirandom.c:24
#define Q
Definition sirandom.c:26
poly gcd_over_Q(poly f, poly g, const ring r)
helper routine for calling singclap_gcd_r
Definition transext.cc:275