My Project
Loading...
Searching...
No Matches
p_polys.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/***************************************************************
5 * File: p_polys.cc
6 * Purpose: implementation of ring independent poly procedures?
7 * Author: obachman (Olaf Bachmann)
8 * Created: 8/00
9 *******************************************************************/
10
11#include <ctype.h>
12
13#include "misc/auxiliary.h"
14
15#include "misc/options.h"
16#include "misc/intvec.h"
17
18
19#include "coeffs/longrat.h" // snumber is needed...
20#include "coeffs/numbers.h" // ndCopyMap
21
23
24#define TRANSEXT_PRIVATES
25
28
29#include "polys/weight.h"
30#include "polys/simpleideals.h"
31
32#include "ring.h"
33#include "p_polys.h"
34
38
39
40#ifdef HAVE_PLURAL
41#include "nc/nc.h"
42#include "nc/sca.h"
43#endif
44
45#ifdef HAVE_SHIFTBBA
46#include "polys/shiftop.h"
47#endif
48
49#include "clapsing.h"
50
51/*
52 * lift ideal with coeffs over Z (mod N) to Q via Farey
53 */
54poly p_Farey(poly p, number N, const ring r)
55{
56 poly h=p_Copy(p,r);
57 poly hh=h;
58 while(h!=NULL)
59 {
60 number c=pGetCoeff(h);
61 pSetCoeff0(h,n_Farey(c,N,r->cf));
62 n_Delete(&c,r->cf);
63 pIter(h);
64 }
65 while((hh!=NULL)&&(n_IsZero(pGetCoeff(hh),r->cf)))
66 {
67 p_LmDelete(&hh,r);
68 }
69 h=hh;
70 while((h!=NULL) && (pNext(h)!=NULL))
71 {
72 if(n_IsZero(pGetCoeff(pNext(h)),r->cf))
73 {
74 p_LmDelete(&pNext(h),r);
75 }
76 else pIter(h);
77 }
78 return hh;
79}
80/*2
81* xx,q: arrays of length 0..rl-1
82* xx[i]: SB mod q[i]
83* assume: char=0
84* assume: q[i]!=0
85* x: work space
86* destroys xx
87*/
88poly p_ChineseRemainder(poly *xx, number *x,number *q, int rl, CFArray &inv_cache,const ring R)
89{
90 poly r,h,hh;
91 int j;
92 poly res_p=NULL;
93 loop
94 {
95 /* search the lead term */
96 r=NULL;
97 for(j=rl-1;j>=0;j--)
98 {
99 h=xx[j];
100 if ((h!=NULL)
101 &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
102 r=h;
103 }
104 /* nothing found -> return */
105 if (r==NULL) break;
106 /* create the monomial in h */
107 h=p_Head(r,R);
108 /* collect the coeffs in x[..]*/
109 for(j=rl-1;j>=0;j--)
110 {
111 hh=xx[j];
112 if ((hh!=NULL) && (p_LmCmp(h,hh,R)==0))
113 {
114 x[j]=pGetCoeff(hh);
115 hh=p_LmFreeAndNext(hh,R);
116 xx[j]=hh;
117 }
118 else
119 x[j]=n_Init(0, R->cf);
120 }
121 number n=n_ChineseRemainderSym(x,q,rl,TRUE,inv_cache,R->cf);
122 for(j=rl-1;j>=0;j--)
123 {
124 x[j]=NULL; // n_Init(0...) takes no memory
125 }
126 if (n_IsZero(n,R->cf)) p_Delete(&h,R);
127 else
128 {
129 //Print("new mon:");pWrite(h);
130 p_SetCoeff(h,n,R);
131 pNext(h)=res_p;
132 res_p=h; // building res_p in reverse order!
133 }
134 }
135 res_p=pReverse(res_p);
136 p_Test(res_p, R);
137 return res_p;
138}
139
140/***************************************************************
141 *
142 * Completing what needs to be set for the monomial
143 *
144 ***************************************************************/
145// this is special for the syz stuff
149
151
152#ifndef SING_NDEBUG
153# define MYTEST 0
154#else /* ifndef SING_NDEBUG */
155# define MYTEST 0
156#endif /* ifndef SING_NDEBUG */
157
158void p_Setm_General(poly p, const ring r)
159{
161 int pos=0;
162 if (r->typ!=NULL)
163 {
164 loop
165 {
166 unsigned long ord=0;
167 sro_ord* o=&(r->typ[pos]);
168 switch(o->ord_typ)
169 {
170 case ro_dp:
171 {
172 int a,e;
173 a=o->data.dp.start;
174 e=o->data.dp.end;
175 for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
176 p->exp[o->data.dp.place]=ord;
177 break;
178 }
179 case ro_wp_neg:
181 // no break;
182 case ro_wp:
183 {
184 int a,e;
185 a=o->data.wp.start;
186 e=o->data.wp.end;
187 int *w=o->data.wp.weights;
188#if 1
189 for(int i=a;i<=e;i++) ord+=((unsigned long)p_GetExp(p,i,r))*((unsigned long)w[i-a]);
190#else
191 long ai;
192 int ei,wi;
193 for(int i=a;i<=e;i++)
194 {
195 ei=p_GetExp(p,i,r);
196 wi=w[i-a];
197 ai=ei*wi;
198 if (ai/ei!=wi) pSetm_error=TRUE;
199 ord+=ai;
200 if (ord<ai) pSetm_error=TRUE;
201 }
202#endif
203 p->exp[o->data.wp.place]=ord;
204 break;
205 }
206 case ro_am:
207 {
209 const short a=o->data.am.start;
210 const short e=o->data.am.end;
211 const int * w=o->data.am.weights;
212#if 1
213 for(short i=a; i<=e; i++, w++)
214 ord += ((*w) * p_GetExp(p,i,r));
215#else
216 long ai;
217 int ei,wi;
218 for(short i=a;i<=e;i++)
219 {
220 ei=p_GetExp(p,i,r);
221 wi=w[i-a];
222 ai=ei*wi;
223 if (ai/ei!=wi) pSetm_error=TRUE;
224 ord += ai;
225 if (ord<ai) pSetm_error=TRUE;
226 }
227#endif
228 const int c = p_GetComp(p,r);
229
230 const short len_gen= o->data.am.len_gen;
231
232 if ((c > 0) && (c <= len_gen))
233 {
234 assume( w == o->data.am.weights_m );
235 assume( w[0] == len_gen );
236 ord += w[c];
237 }
238
239 p->exp[o->data.am.place] = ord;
240 break;
241 }
242 case ro_wp64:
243 {
244 int64 ord=0;
245 int a,e;
246 a=o->data.wp64.start;
247 e=o->data.wp64.end;
248 int64 *w=o->data.wp64.weights64;
249 int64 ei,wi,ai;
250 for(int i=a;i<=e;i++)
251 {
252 //Print("exp %d w %d \n",p_GetExp(p,i,r),(int)w[i-a]);
253 //ord+=((int64)p_GetExp(p,i,r))*w[i-a];
254 ei=(int64)p_GetExp(p,i,r);
255 wi=w[i-a];
256 ai=ei*wi;
257 if(ei!=0 && ai/ei!=wi)
258 {
260 #if SIZEOF_LONG == 4
261 Print("ai %lld, wi %lld\n",ai,wi);
262 #else
263 Print("ai %ld, wi %ld\n",ai,wi);
264 #endif
265 }
266 ord+=ai;
267 if (ord<ai)
268 {
270 #if SIZEOF_LONG == 4
271 Print("ai %lld, ord %lld\n",ai,ord);
272 #else
273 Print("ai %ld, ord %ld\n",ai,ord);
274 #endif
275 }
276 }
277 #if SIZEOF_LONG == 4
278 int64 mask=(int64)0x7fffffff;
279 long a_0=(long)(ord&mask); //2^31
280 long a_1=(long)(ord >>31 ); /*(ord/(mask+1));*/
281
282 //Print("mask: %x, ord: %d, a_0: %d, a_1: %d\n"
283 //,(int)mask,(int)ord,(int)a_0,(int)a_1);
284 //Print("mask: %d",mask);
285
286 p->exp[o->data.wp64.place]=a_1;
287 p->exp[o->data.wp64.place+1]=a_0;
288 #elif SIZEOF_LONG == 8
289 p->exp[o->data.wp64.place]=ord;
290 #endif
291// if(p_Setm_error) PrintS("***************************\n"
292// "***************************\n"
293// "**WARNING: overflow error**\n"
294// "***************************\n"
295// "***************************\n");
296 break;
297 }
298 case ro_cp:
299 {
300 int a,e;
301 a=o->data.cp.start;
302 e=o->data.cp.end;
303 int pl=o->data.cp.place;
304 for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
305 break;
306 }
307 case ro_syzcomp:
308 {
309 long c=__p_GetComp(p,r);
310 long sc = c;
311 int* Components = (_componentsExternal ? _components :
312 o->data.syzcomp.Components);
313 long* ShiftedComponents = (_componentsExternal ? _componentsShifted:
314 o->data.syzcomp.ShiftedComponents);
315 if (ShiftedComponents != NULL)
316 {
317 assume(Components != NULL);
318 assume(c == 0 || Components[c] != 0);
319 sc = ShiftedComponents[Components[c]];
320 assume(c == 0 || sc != 0);
321 }
322 p->exp[o->data.syzcomp.place]=sc;
323 break;
324 }
325 case ro_syz:
326 {
327 const unsigned long c = __p_GetComp(p, r);
328 const short place = o->data.syz.place;
329 const int limit = o->data.syz.limit;
330
331 if (c > (unsigned long)limit)
332 p->exp[place] = o->data.syz.curr_index;
333 else if (c > 0)
334 {
335 assume( (1 <= c) && (c <= (unsigned long)limit) );
336 p->exp[place]= o->data.syz.syz_index[c];
337 }
338 else
339 {
340 assume(c == 0);
341 p->exp[place]= 0;
342 }
343 break;
344 }
345 // Prefix for Induced Schreyer ordering
346 case ro_isTemp: // Do nothing?? (to be removed into suffix later on...?)
347 {
348 assume(p != NULL);
349
350#ifndef SING_NDEBUG
351#if MYTEST
352 Print("p_Setm_General: ro_isTemp ord: pos: %d, p: ", pos); p_wrp(p, r);
353#endif
354#endif
355 int c = p_GetComp(p, r);
356
357 assume( c >= 0 );
358
359 // Let's simulate case ro_syz above....
360 // Should accumulate (by Suffix) and be a level indicator
361 const int* const pVarOffset = o->data.isTemp.pVarOffset;
362
363 assume( pVarOffset != NULL );
364
365 // TODO: Can this be done in the suffix???
366 for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
367 {
368 const int vo = pVarOffset[i];
369 if( vo != -1) // TODO: optimize: can be done once!
370 {
371 // Hans! Please don't break it again! p_SetExp(p, ..., r, vo) is correct:
372 p_SetExp(p, p_GetExp(p, i, r), r, vo); // copy put them verbatim
373 // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
374 assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
375 }
376 }
377#ifndef SING_NDEBUG
378 for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
379 {
380 const int vo = pVarOffset[i];
381 if( vo != -1) // TODO: optimize: can be done once!
382 {
383 // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
384 assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
385 }
386 }
387#if MYTEST
388// if( p->exp[o->data.isTemp.start] > 0 )
389 PrintS("after Values: "); p_wrp(p, r);
390#endif
391#endif
392 break;
393 }
394
395 // Suffix for Induced Schreyer ordering
396 case ro_is:
397 {
398#ifndef SING_NDEBUG
399#if MYTEST
400 Print("p_Setm_General: ro_is ord: pos: %d, p: ", pos); p_wrp(p, r);
401#endif
402#endif
403
404 assume(p != NULL);
405
406 int c = p_GetComp(p, r);
407
408 assume( c >= 0 );
409 const ideal F = o->data.is.F;
410 const int limit = o->data.is.limit;
411 assume( limit >= 0 );
412 const int start = o->data.is.start;
413
414 if( F != NULL && c > limit )
415 {
416#ifndef SING_NDEBUG
417#if MYTEST
418 Print("p_Setm_General: ro_is : in rSetm: pos: %d, c: %d > limit: %d\n", c, pos, limit);
419 PrintS("preComputed Values: ");
420 p_wrp(p, r);
421#endif
422#endif
423// if( c > limit ) // BUG???
424 p->exp[start] = 1;
425// else
426// p->exp[start] = 0;
427
428
429 c -= limit;
430 assume( c > 0 );
431 c--;
432
433 if( c >= IDELEMS(F) )
434 break;
435
436 assume( c < IDELEMS(F) ); // What about others???
437
438 const poly pp = F->m[c]; // get reference monomial!!!
439
440 if(pp == NULL)
441 break;
442
443 assume(pp != NULL);
444
445#ifndef SING_NDEBUG
446#if MYTEST
447 Print("Respective F[c - %d: %d] pp: ", limit, c);
448 p_wrp(pp, r);
449#endif
450#endif
451
452 const int end = o->data.is.end;
453 assume(start <= end);
454
455
456// const int st = o->data.isTemp.start;
457
458#ifndef SING_NDEBUG
459#if MYTEST
460 Print("p_Setm_General: is(-Temp-) :: c: %d, limit: %d, [st:%d] ===>>> %ld\n", c, limit, start, p->exp[start]);
461#endif
462#endif
463
464 // p_ExpVectorAdd(p, pp, r);
465
466 for( int i = start; i <= end; i++) // v[0] may be here...
467 p->exp[i] += pp->exp[i]; // !!!!!!!! ADD corresponding LT(F)
468
469 // p_MemAddAdjust(p, ri);
470 if (r->NegWeightL_Offset != NULL)
471 {
472 for (int i=r->NegWeightL_Size-1; i>=0; i--)
473 {
474 const int _i = r->NegWeightL_Offset[i];
475 if( start <= _i && _i <= end )
476 p->exp[_i] -= POLY_NEGWEIGHT_OFFSET;
477 }
478 }
479
480
481#ifndef SING_NDEBUG
482 const int* const pVarOffset = o->data.is.pVarOffset;
483
484 assume( pVarOffset != NULL );
485
486 for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
487 {
488 const int vo = pVarOffset[i];
489 if( vo != -1) // TODO: optimize: can be done once!
490 // Hans! Please don't break it again! p_GetExp(p/pp, r, vo) is correct:
491 assume( p_GetExp(p, r, vo) == (p_GetExp(p, i, r) + p_GetExp(pp, r, vo)) );
492 }
493 // TODO: how to check this for computed values???
494#if MYTEST
495 PrintS("Computed Values: "); p_wrp(p, r);
496#endif
497#endif
498 } else
499 {
500 p->exp[start] = 0; //!!!!????? where?????
501
502 const int* const pVarOffset = o->data.is.pVarOffset;
503
504 // What about v[0] - component: it will be added later by
505 // suffix!!!
506 // TODO: Test it!
507 const int vo = pVarOffset[0];
508 if( vo != -1 )
509 p->exp[vo] = c; // initial component v[0]!
510
511#ifndef SING_NDEBUG
512#if MYTEST
513 Print("ELSE p_Setm_General: ro_is :: c: %d <= limit: %d, vo: %d, exp: %d\n", c, limit, vo, p->exp[vo]);
514 p_wrp(p, r);
515#endif
516#endif
517 }
518
519 break;
520 }
521 default:
522 dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
523 return;
524 }
525 pos++;
526 if (pos == r->OrdSize) return;
527 }
528 }
529}
530
531void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
532{
533 _components = Components;
534 _componentsShifted = ShiftedComponents;
536 p_Setm_General(p, r);
538}
539
540// dummy for lp, ls, etc
541void p_Setm_Dummy(poly p, const ring r)
542{
544}
545
546// for dp, Dp, ds, etc
547void p_Setm_TotalDegree(poly p, const ring r)
548{
550 p->exp[r->pOrdIndex] = p_Totaldegree(p, r);
551}
552
553// for wp, Wp, ws, etc
554void p_Setm_WFirstTotalDegree(poly p, const ring r)
555{
557 p->exp[r->pOrdIndex] = p_WFirstTotalDegree(p, r);
558}
559
561{
562 // covers lp, rp, ls,
563 if (r->typ == NULL) return p_Setm_Dummy;
564
565 if (r->OrdSize == 1)
566 {
567 if (r->typ[0].ord_typ == ro_dp &&
568 r->typ[0].data.dp.start == 1 &&
569 r->typ[0].data.dp.end == r->N &&
570 r->typ[0].data.dp.place == r->pOrdIndex)
571 return p_Setm_TotalDegree;
572 if (r->typ[0].ord_typ == ro_wp &&
573 r->typ[0].data.wp.start == 1 &&
574 r->typ[0].data.wp.end == r->N &&
575 r->typ[0].data.wp.place == r->pOrdIndex &&
576 r->typ[0].data.wp.weights == r->firstwv)
578 }
579 return p_Setm_General;
580}
581
582
583/* -------------------------------------------------------------------*/
584/* several possibilities for pFDeg: the degree of the head term */
585
586/* comptible with ordering */
587long p_Deg(poly a, const ring r)
588{
589 p_LmCheckPolyRing(a, r);
590// assume(p_GetOrder(a, r) == p_WTotaldegree(a, r)); // WRONG assume!
591 return p_GetOrder(a, r);
592}
593
594// p_WTotalDegree for weighted orderings
595// whose first block covers all variables
596long p_WFirstTotalDegree(poly p, const ring r)
597{
598 int i;
599 long sum = 0;
600
601 for (i=1; i<= r->firstBlockEnds; i++)
602 {
603 sum += p_GetExp(p, i, r)*r->firstwv[i-1];
604 }
605 return sum;
606}
607
608/*2
609* compute the degree of the leading monomial of p
610* with respect to weigths from the ordering
611* the ordering is not compatible with degree so do not use p->Order
612*/
613long p_WTotaldegree(poly p, const ring r)
614{
616 int i, k;
617 long j =0;
618
619 // iterate through each block:
620 for (i=0;r->order[i]!=0;i++)
621 {
622 int b0=r->block0[i];
623 int b1=r->block1[i];
624 switch(r->order[i])
625 {
626 case ringorder_M:
627 for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
628 { // in jedem block:
629 j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/]*r->OrdSgn;
630 }
631 break;
632 case ringorder_am:
633 b1=si_min(b1,r->N);
634 /* no break, continue as ringorder_a*/
635 case ringorder_a:
636 for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
637 { // only one line
638 j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/];
639 }
640 return j*r->OrdSgn;
641 case ringorder_wp:
642 case ringorder_ws:
643 case ringorder_Wp:
644 case ringorder_Ws:
645 for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
646 { // in jedem block:
647 j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/];
648 }
649 break;
650 case ringorder_lp:
651 case ringorder_ls:
652 case ringorder_rs:
653 case ringorder_dp:
654 case ringorder_ds:
655 case ringorder_Dp:
656 case ringorder_Ds:
657 case ringorder_rp:
658 for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
659 {
660 j+= p_GetExp(p,k,r);
661 }
662 break;
663 case ringorder_a64:
664 {
665 int64* w=(int64*)r->wvhdl[i];
666 for (k=0;k<=(b1 /*r->block1[i]*/ - b0 /*r->block0[i]*/);k++)
667 {
668 //there should be added a line which checks if w[k]>2^31
669 j+= p_GetExp(p,k+1, r)*(long)w[k];
670 }
671 //break;
672 return j;
673 }
674 case ringorder_c: /* nothing to do*/
675 case ringorder_C: /* nothing to do*/
676 case ringorder_S: /* nothing to do*/
677 case ringorder_s: /* nothing to do*/
678 case ringorder_IS: /* nothing to do */
679 case ringorder_unspec: /* to make clang happy, does not occur*/
680 case ringorder_no: /* to make clang happy, does not occur*/
681 case ringorder_L: /* to make clang happy, does not occur*/
682 case ringorder_aa: /* ignored by p_WTotaldegree*/
683 break;
684 /* no default: all orderings covered */
685 }
686 }
687 return j;
688}
689
690long p_DegW(poly p, const int *w, const ring R)
691{
692 p_Test(p, R);
693 assume( w != NULL );
694 long r=-LONG_MAX;
695
696 while (p!=NULL)
697 {
698 long t=totaldegreeWecart_IV(p,R,w);
699 if (t>r) r=t;
700 pIter(p);
701 }
702 return r;
703}
704
705int p_Weight(int i, const ring r)
706{
707 if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
708 {
709 return 1;
710 }
711 return r->firstwv[i-1];
712}
713
714long p_WDegree(poly p, const ring r)
715{
716 if (r->firstwv==NULL) return p_Totaldegree(p, r);
718 int i;
719 long j =0;
720
721 for(i=1;i<=r->firstBlockEnds;i++)
722 j+=p_GetExp(p, i, r)*r->firstwv[i-1];
723
724 for (;i<=rVar(r);i++)
725 j+=p_GetExp(p,i, r)*p_Weight(i, r);
726
727 return j;
728}
729
730
731/* ---------------------------------------------------------------------*/
732/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
733/* compute in l also the pLength of p */
734
735/*2
736* compute the length of a polynomial (in l)
737* and the degree of the monomial with maximal degree: the last one
738*/
739long pLDeg0(poly p,int *l, const ring r)
740{
741 p_CheckPolyRing(p, r);
742 long unsigned k= p_GetComp(p, r);
743 int ll=1;
744
745 if (k > 0)
746 {
747 while ((pNext(p)!=NULL) && (__p_GetComp(pNext(p), r)==k))
748 {
749 pIter(p);
750 ll++;
751 }
752 }
753 else
754 {
755 while (pNext(p)!=NULL)
756 {
757 pIter(p);
758 ll++;
759 }
760 }
761 *l=ll;
762 return r->pFDeg(p, r);
763}
764
765/*2
766* compute the length of a polynomial (in l)
767* and the degree of the monomial with maximal degree: the last one
768* but search in all components before syzcomp
769*/
770long pLDeg0c(poly p,int *l, const ring r)
771{
772 assume(p!=NULL);
773 p_Test(p,r);
774 p_CheckPolyRing(p, r);
775 long o;
776 int ll=1;
777
778 if (! rIsSyzIndexRing(r))
779 {
780 while (pNext(p) != NULL)
781 {
782 pIter(p);
783 ll++;
784 }
785 o = r->pFDeg(p, r);
786 }
787 else
788 {
789 long unsigned curr_limit = rGetCurrSyzLimit(r);
790 poly pp = p;
791 while ((p=pNext(p))!=NULL)
792 {
793 if (__p_GetComp(p, r)<=curr_limit/*syzComp*/)
794 ll++;
795 else break;
796 pp = p;
797 }
798 p_Test(pp,r);
799 o = r->pFDeg(pp, r);
800 }
801 *l=ll;
802 return o;
803}
804
805/*2
806* compute the length of a polynomial (in l)
807* and the degree of the monomial with maximal degree: the first one
808* this works for the polynomial case with degree orderings
809* (both c,dp and dp,c)
810*/
811long pLDegb(poly p,int *l, const ring r)
812{
813 p_CheckPolyRing(p, r);
814 long unsigned k= p_GetComp(p, r);
815 long o = r->pFDeg(p, r);
816 int ll=1;
817
818 if (k != 0)
819 {
820 while (((p=pNext(p))!=NULL) && (__p_GetComp(p, r)==k))
821 {
822 ll++;
823 }
824 }
825 else
826 {
827 while ((p=pNext(p)) !=NULL)
828 {
829 ll++;
830 }
831 }
832 *l=ll;
833 return o;
834}
835
836/*2
837* compute the length of a polynomial (in l)
838* and the degree of the monomial with maximal degree:
839* this is NOT the last one, we have to look for it
840*/
841long pLDeg1(poly p,int *l, const ring r)
842{
843 p_CheckPolyRing(p, r);
844 long unsigned k= p_GetComp(p, r);
845 int ll=1;
846 long t,max;
847
848 max=r->pFDeg(p, r);
849 if (k > 0)
850 {
851 while (((p=pNext(p))!=NULL) && (__p_GetComp(p, r)==k))
852 {
853 t=r->pFDeg(p, r);
854 if (t>max) max=t;
855 ll++;
856 }
857 }
858 else
859 {
860 while ((p=pNext(p))!=NULL)
861 {
862 t=r->pFDeg(p, r);
863 if (t>max) max=t;
864 ll++;
865 }
866 }
867 *l=ll;
868 return max;
869}
870
871/*2
872* compute the length of a polynomial (in l)
873* and the degree of the monomial with maximal degree:
874* this is NOT the last one, we have to look for it
875* in all components
876*/
877long pLDeg1c(poly p,int *l, const ring r)
878{
879 p_CheckPolyRing(p, r);
880 int ll=1;
881 long t,max;
882
883 max=r->pFDeg(p, r);
884 if (rIsSyzIndexRing(r))
885 {
886 long unsigned limit = rGetCurrSyzLimit(r);
887 while ((p=pNext(p))!=NULL)
888 {
889 if (__p_GetComp(p, r)<=limit)
890 {
891 if ((t=r->pFDeg(p, r))>max) max=t;
892 ll++;
893 }
894 else break;
895 }
896 }
897 else
898 {
899 while ((p=pNext(p))!=NULL)
900 {
901 if ((t=r->pFDeg(p, r))>max) max=t;
902 ll++;
903 }
904 }
905 *l=ll;
906 return max;
907}
908
909// like pLDeg1, only pFDeg == pDeg
910long pLDeg1_Deg(poly p,int *l, const ring r)
911{
912 assume(r->pFDeg == p_Deg);
913 p_CheckPolyRing(p, r);
914 long unsigned k= p_GetComp(p, r);
915 int ll=1;
916 long t,max;
917
918 max=p_GetOrder(p, r);
919 if (k > 0)
920 {
921 while (((p=pNext(p))!=NULL) && (__p_GetComp(p, r)==k))
922 {
923 t=p_GetOrder(p, r);
924 if (t>max) max=t;
925 ll++;
926 }
927 }
928 else
929 {
930 while ((p=pNext(p))!=NULL)
931 {
932 t=p_GetOrder(p, r);
933 if (t>max) max=t;
934 ll++;
935 }
936 }
937 *l=ll;
938 return max;
939}
940
941long pLDeg1c_Deg(poly p,int *l, const ring r)
942{
943 assume(r->pFDeg == p_Deg);
944 p_CheckPolyRing(p, r);
945 int ll=1;
946 long t,max;
947
948 max=p_GetOrder(p, r);
949 if (rIsSyzIndexRing(r))
950 {
951 long unsigned limit = rGetCurrSyzLimit(r);
952 while ((p=pNext(p))!=NULL)
953 {
954 if (__p_GetComp(p, r)<=limit)
955 {
956 if ((t=p_GetOrder(p, r))>max) max=t;
957 ll++;
958 }
959 else break;
960 }
961 }
962 else
963 {
964 while ((p=pNext(p))!=NULL)
965 {
966 if ((t=p_GetOrder(p, r))>max) max=t;
967 ll++;
968 }
969 }
970 *l=ll;
971 return max;
972}
973
974// like pLDeg1, only pFDeg == pTotoalDegree
975long pLDeg1_Totaldegree(poly p,int *l, const ring r)
976{
977 p_CheckPolyRing(p, r);
978 long unsigned k= p_GetComp(p, r);
979 int ll=1;
980 long t,max;
981
982 max=p_Totaldegree(p, r);
983 if (k > 0)
984 {
985 while (((p=pNext(p))!=NULL) && (__p_GetComp(p, r)==k))
986 {
987 t=p_Totaldegree(p, r);
988 if (t>max) max=t;
989 ll++;
990 }
991 }
992 else
993 {
994 while ((p=pNext(p))!=NULL)
995 {
996 t=p_Totaldegree(p, r);
997 if (t>max) max=t;
998 ll++;
999 }
1000 }
1001 *l=ll;
1002 return max;
1003}
1004
1005long pLDeg1c_Totaldegree(poly p,int *l, const ring r)
1006{
1007 p_CheckPolyRing(p, r);
1008 int ll=1;
1009 long t,max;
1010
1011 max=p_Totaldegree(p, r);
1012 if (rIsSyzIndexRing(r))
1013 {
1014 long unsigned limit = rGetCurrSyzLimit(r);
1015 while ((p=pNext(p))!=NULL)
1016 {
1017 if (__p_GetComp(p, r)<=limit)
1018 {
1019 if ((t=p_Totaldegree(p, r))>max) max=t;
1020 ll++;
1021 }
1022 else break;
1023 }
1024 }
1025 else
1026 {
1027 while ((p=pNext(p))!=NULL)
1028 {
1029 if ((t=p_Totaldegree(p, r))>max) max=t;
1030 ll++;
1031 }
1032 }
1033 *l=ll;
1034 return max;
1035}
1036
1037// like pLDeg1, only pFDeg == p_WFirstTotalDegree
1038long pLDeg1_WFirstTotalDegree(poly p,int *l, const ring r)
1039{
1040 p_CheckPolyRing(p, r);
1041 long unsigned k= p_GetComp(p, r);
1042 int ll=1;
1043 long t,max;
1044
1046 if (k > 0)
1047 {
1048 while (((p=pNext(p))!=NULL) && (__p_GetComp(p, r)==k))
1049 {
1050 t=p_WFirstTotalDegree(p, r);
1051 if (t>max) max=t;
1052 ll++;
1053 }
1054 }
1055 else
1056 {
1057 while ((p=pNext(p))!=NULL)
1058 {
1059 t=p_WFirstTotalDegree(p, r);
1060 if (t>max) max=t;
1061 ll++;
1062 }
1063 }
1064 *l=ll;
1065 return max;
1066}
1067
1068long pLDeg1c_WFirstTotalDegree(poly p,int *l, const ring r)
1069{
1070 p_CheckPolyRing(p, r);
1071 int ll=1;
1072 long t,max;
1073
1075 if (rIsSyzIndexRing(r))
1076 {
1077 long unsigned limit = rGetCurrSyzLimit(r);
1078 while ((p=pNext(p))!=NULL)
1079 {
1080 if (__p_GetComp(p, r)<=limit)
1081 {
1082 if ((t=p_Totaldegree(p, r))>max) max=t;
1083 ll++;
1084 }
1085 else break;
1086 }
1087 }
1088 else
1089 {
1090 while ((p=pNext(p))!=NULL)
1091 {
1092 if ((t=p_Totaldegree(p, r))>max) max=t;
1093 ll++;
1094 }
1095 }
1096 *l=ll;
1097 return max;
1098}
1099
1100/***************************************************************
1101 *
1102 * Maximal Exponent business
1103 *
1104 ***************************************************************/
1105
1106static inline unsigned long
1107p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r,
1108 unsigned long number_of_exp)
1109{
1110 const unsigned long bitmask = r->bitmask;
1111 unsigned long ml1 = l1 & bitmask;
1112 unsigned long ml2 = l2 & bitmask;
1113 unsigned long max = (ml1 > ml2 ? ml1 : ml2);
1114 unsigned long j = number_of_exp - 1;
1115
1116 if (j > 0)
1117 {
1118 unsigned long mask = bitmask << r->BitsPerExp;
1119 while (1)
1120 {
1121 ml1 = l1 & mask;
1122 ml2 = l2 & mask;
1123 max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
1124 j--;
1125 if (j == 0) break;
1126 mask = mask << r->BitsPerExp;
1127 }
1128 }
1129 return max;
1130}
1131
1132static inline unsigned long
1133p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r)
1134{
1135 return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
1136}
1137
1138poly p_GetMaxExpP(poly p, const ring r)
1139{
1140 p_CheckPolyRing(p, r);
1141 if (p == NULL) return p_Init(r);
1142 poly max = p_LmInit(p, r);
1143 pIter(p);
1144 if (p == NULL) return max;
1145 int i, offset;
1146 unsigned long l_p, l_max;
1147 unsigned long divmask = r->divmask;
1148
1149 do
1150 {
1151 offset = r->VarL_Offset[0];
1152 l_p = p->exp[offset];
1153 l_max = max->exp[offset];
1154 // do the divisibility trick to find out whether l has an exponent
1155 if (l_p > l_max ||
1156 (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1157 max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
1158
1159 for (i=1; i<r->VarL_Size; i++)
1160 {
1161 offset = r->VarL_Offset[i];
1162 l_p = p->exp[offset];
1163 l_max = max->exp[offset];
1164 // do the divisibility trick to find out whether l has an exponent
1165 if (l_p > l_max ||
1166 (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1167 max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
1168 }
1169 pIter(p);
1170 }
1171 while (p != NULL);
1172 return max;
1173}
1174
1175unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max)
1176{
1177 unsigned long l_p, divmask = r->divmask;
1178 int i;
1179
1180 while (p != NULL)
1181 {
1182 l_p = p->exp[r->VarL_Offset[0]];
1183 if (l_p > l_max ||
1184 (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1185 l_max = p_GetMaxExpL2(l_max, l_p, r);
1186 for (i=1; i<r->VarL_Size; i++)
1187 {
1188 l_p = p->exp[r->VarL_Offset[i]];
1189 // do the divisibility trick to find out whether l has an exponent
1190 if (l_p > l_max ||
1191 (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
1192 l_max = p_GetMaxExpL2(l_max, l_p, r);
1193 }
1194 pIter(p);
1195 }
1196 return l_max;
1197}
1198
1199
1200
1201
1202/***************************************************************
1203 *
1204 * Misc things
1205 *
1206 ***************************************************************/
1207// returns TRUE, if all monoms have the same component
1208BOOLEAN p_OneComp(poly p, const ring r)
1209{
1210 if(p!=NULL)
1211 {
1212 long i = p_GetComp(p, r);
1213 while (pNext(p)!=NULL)
1214 {
1215 pIter(p);
1216 if(i != p_GetComp(p, r)) return FALSE;
1217 }
1218 }
1219 return TRUE;
1220}
1221
1222/*2
1223*test if a monomial /head term is a pure power,
1224* i.e. depends on only one variable
1225*/
1226int p_IsPurePower(const poly p, const ring r)
1227{
1228 int i,k=0;
1229
1230 for (i=r->N;i;i--)
1231 {
1232 if (p_GetExp(p,i, r)!=0)
1233 {
1234 if(k!=0) return 0;
1235 k=i;
1236 }
1237 }
1238 return k;
1239}
1240
1241/*2
1242*test if a polynomial is univariate
1243* return -1 for constant,
1244* 0 for not univariate,s
1245* i if dep. on var(i)
1246*/
1247int p_IsUnivariate(poly p, const ring r)
1248{
1249 int i,k=-1;
1250
1251 while (p!=NULL)
1252 {
1253 for (i=r->N;i;i--)
1254 {
1255 if (p_GetExp(p,i, r)!=0)
1256 {
1257 if((k!=-1)&&(k!=i)) return 0;
1258 k=i;
1259 }
1260 }
1261 pIter(p);
1262 }
1263 return k;
1264}
1265
1266// set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0
1267int p_GetVariables(poly p, int * e, const ring r)
1268{
1269 int i;
1270 int n=0;
1271 while(p!=NULL)
1272 {
1273 n=0;
1274 for(i=r->N; i>0; i--)
1275 {
1276 if(e[i]==0)
1277 {
1278 if (p_GetExp(p,i,r)>0)
1279 {
1280 e[i]=1;
1281 n++;
1282 }
1283 }
1284 else
1285 n++;
1286 }
1287 if (n==r->N) break;
1288 pIter(p);
1289 }
1290 return n;
1291}
1292
1293
1294/*2
1295* returns a polynomial representing the integer i
1296*/
1297poly p_ISet(long i, const ring r)
1298{
1299 poly rc = NULL;
1300 if (i!=0)
1301 {
1302 rc = p_Init(r);
1303 pSetCoeff0(rc,n_Init(i,r->cf));
1304 if (n_IsZero(pGetCoeff(rc),r->cf))
1305 p_LmDelete(&rc,r);
1306 }
1307 return rc;
1308}
1309
1310/*2
1311* an optimized version of p_ISet for the special case 1
1312*/
1313poly p_One(const ring r)
1314{
1315 poly rc = p_Init(r);
1316 pSetCoeff0(rc,n_Init(1,r->cf));
1317 return rc;
1318}
1319
1320void p_Split(poly p, poly *h)
1321{
1322 *h=pNext(p);
1323 pNext(p)=NULL;
1324}
1325
1326/*2
1327* pair has no common factor ? or is no polynomial
1328*/
1329BOOLEAN p_HasNotCF(poly p1, poly p2, const ring r)
1330{
1331
1332 if (p_GetComp(p1,r) > 0 || p_GetComp(p2,r) > 0)
1333 return FALSE;
1334 int i = rVar(r);
1335 loop
1336 {
1337 if ((p_GetExp(p1, i, r) > 0) && (p_GetExp(p2, i, r) > 0))
1338 return FALSE;
1339 i--;
1340 if (i == 0)
1341 return TRUE;
1342 }
1343}
1344
1345BOOLEAN p_HasNotCFRing(poly p1, poly p2, const ring r)
1346{
1347
1348 if (p_GetComp(p1,r) > 0 || p_GetComp(p2,r) > 0)
1349 return FALSE;
1350 int i = rVar(r);
1351 loop
1352 {
1353 if ((p_GetExp(p1, i, r) > 0) && (p_GetExp(p2, i, r) > 0))
1354 return FALSE;
1355 i--;
1356 if (i == 0) {
1357 if (n_DivBy(pGetCoeff(p1), pGetCoeff(p2), r->cf) ||
1358 n_DivBy(pGetCoeff(p2), pGetCoeff(p1), r->cf)) {
1359 return FALSE;
1360 } else {
1361 return TRUE;
1362 }
1363 }
1364 }
1365}
1366
1367/*2
1368* convert monomial given as string to poly, e.g. 1x3y5z
1369*/
1370const char * p_Read(const char *st, poly &rc, const ring r)
1371{
1372 if (r==NULL) { rc=NULL;return st;}
1373 int i,j;
1374 rc = p_Init(r);
1375 const char *s = n_Read(st,&(p_GetCoeff(rc, r)),r->cf);
1376 if (s==st)
1377 /* i.e. it does not start with a coeff: test if it is a ringvar*/
1378 {
1379 j = r_IsRingVar(s,r->names,r->N);
1380 if (j >= 0)
1381 {
1382 p_IncrExp(rc,1+j,r);
1383 while (*s!='\0') s++;
1384 goto done;
1385 }
1386 }
1387 while (*s!='\0')
1388 {
1389 char ss[2];
1390 ss[0] = *s++;
1391 ss[1] = '\0';
1392 j = r_IsRingVar(ss,r->names,r->N);
1393 if (j >= 0)
1394 {
1395 const char *s_save=s;
1396 s = eati(s,&i);
1397 if (((unsigned long)i) > r->bitmask/2)
1398 {
1399 // exponent to large: it is not a monomial
1400 p_LmDelete(&rc,r);
1401 return s_save;
1402 }
1403 p_AddExp(rc,1+j, (long)i, r);
1404 }
1405 else
1406 {
1407 // 1st char of is not a varname
1408 // We return the parsed polynomial nevertheless. This is needed when
1409 // we are parsing coefficients in a rational function field.
1410 s--;
1411 break;
1412 }
1413 }
1414done:
1415 if (n_IsZero(pGetCoeff(rc),r->cf)) p_LmDelete(&rc,r);
1416 else
1417 {
1418#ifdef HAVE_PLURAL
1419 // in super-commutative ring
1420 // squares of anti-commutative variables are zeroes!
1421 if(rIsSCA(r))
1422 {
1423 const unsigned int iFirstAltVar = scaFirstAltVar(r);
1424 const unsigned int iLastAltVar = scaLastAltVar(r);
1425
1426 assume(rc != NULL);
1427
1428 for(unsigned int k = iFirstAltVar; k <= iLastAltVar; k++)
1429 if( p_GetExp(rc, k, r) > 1 )
1430 {
1431 p_LmDelete(&rc, r);
1432 goto finish;
1433 }
1434 }
1435#endif
1436
1437 p_Setm(rc,r);
1438 }
1439finish:
1440 return s;
1441}
1442poly p_mInit(const char *st, BOOLEAN &ok, const ring r)
1443{
1444 poly p;
1445 char *sst=(char*)st;
1446 BOOLEAN neg=FALSE;
1447 if (sst[0]=='-') { neg=TRUE; sst=sst+1; }
1448 const char *s=p_Read(sst,p,r);
1449 if (*s!='\0')
1450 {
1451 if ((s!=sst)&&isdigit(sst[0]))
1452 {
1454 }
1455 ok=FALSE;
1456 if (p!=NULL)
1457 {
1458 if (pGetCoeff(p)==NULL) p_LmFree(p,r);
1459 else p_LmDelete(p,r);
1460 }
1461 return NULL;
1462 }
1463 p_Test(p,r);
1464 ok=!errorreported;
1465 if (neg) p=p_Neg(p,r);
1466 return p;
1467}
1468
1469/*2
1470* returns a polynomial representing the number n
1471* destroys n
1472*/
1473poly p_NSet(number n, const ring r)
1474{
1475 if (n_IsZero(n,r->cf))
1476 {
1477 n_Delete(&n, r->cf);
1478 return NULL;
1479 }
1480 else
1481 {
1482 poly rc = p_Init(r);
1483 pSetCoeff0(rc,n);
1484 return rc;
1485 }
1486}
1487/*2
1488* assumes that LM(a) = LM(b)*m, for some monomial m,
1489* returns the multiplicant m,
1490* leaves a and b unmodified
1491*/
1492poly p_MDivide(poly a, poly b, const ring r)
1493{
1494 assume((p_GetComp(a,r)==p_GetComp(b,r)) || (p_GetComp(b,r)==0));
1495 int i;
1496 poly result = p_Init(r);
1497
1498 for(i=(int)r->N; i; i--)
1499 p_SetExp(result,i, p_GetExp(a,i,r)- p_GetExp(b,i,r),r);
1500 p_SetComp(result, p_GetComp(a,r) - p_GetComp(b,r),r);
1501 p_Setm(result,r);
1502 return result;
1503}
1504
1505poly p_Div_nn(poly p, const number n, const ring r)
1506{
1507 pAssume(!n_IsZero(n,r->cf));
1508 p_Test(p, r);
1509 poly result = p;
1510 poly prev = NULL;
1511 while (p!=NULL)
1512 {
1513 number nc = n_Div(pGetCoeff(p),n,r->cf);
1514 if (!n_IsZero(nc,r->cf))
1515 {
1516 p_SetCoeff(p,nc,r);
1517 prev=p;
1518 pIter(p);
1519 }
1520 else
1521 {
1522 if (prev==NULL)
1523 {
1524 p_LmDelete(&result,r);
1525 p=result;
1526 }
1527 else
1528 {
1529 p_LmDelete(&pNext(prev),r);
1530 p=pNext(prev);
1531 }
1532 }
1533 }
1534 p_Test(result,r);
1535 return(result);
1536}
1537
1538poly p_Div_mm(poly p, const poly m, const ring r)
1539{
1540 p_Test(p, r);
1541 p_Test(m, r);
1542 poly result = p;
1543 poly prev = NULL;
1544 number n=pGetCoeff(m);
1545 while (p!=NULL)
1546 {
1547 number nc = n_Div(pGetCoeff(p),n,r->cf);
1548 n_Normalize(nc,r->cf);
1549 if (!n_IsZero(nc,r->cf))
1550 {
1551 p_SetCoeff(p,nc,r);
1552 prev=p;
1553 p_ExpVectorSub(p,m,r);
1554 pIter(p);
1555 }
1556 else
1557 {
1558 if (prev==NULL)
1559 {
1560 p_LmDelete(&result,r);
1561 p=result;
1562 }
1563 else
1564 {
1565 p_LmDelete(&pNext(prev),r);
1566 p=pNext(prev);
1567 }
1568 }
1569 }
1570 p_Test(result,r);
1571 return(result);
1572}
1573
1574/*2
1575* divides a by the monomial b, ignores monomials which are not divisible
1576* assumes that b is not NULL, destroyes b
1577*/
1578poly p_DivideM(poly a, poly b, const ring r)
1579{
1580 if (a==NULL) { p_Delete(&b,r); return NULL; }
1581 poly result=a;
1582
1583 if(!p_IsConstant(b,r))
1584 {
1585 if (rIsNCRing(r))
1586 {
1587 WerrorS("p_DivideM not implemented for non-commuative rings");
1588 return NULL;
1589 }
1590 poly prev=NULL;
1591 while (a!=NULL)
1592 {
1593 if (p_DivisibleBy(b,a,r))
1594 {
1595 p_ExpVectorSub(a,b,r);
1596 prev=a;
1597 pIter(a);
1598 }
1599 else
1600 {
1601 if (prev==NULL)
1602 {
1603 p_LmDelete(&result,r);
1604 a=result;
1605 }
1606 else
1607 {
1608 p_LmDelete(&pNext(prev),r);
1609 a=pNext(prev);
1610 }
1611 }
1612 }
1613 }
1614 if (result!=NULL)
1615 {
1616 number inv=pGetCoeff(b);
1617 //if ((!rField_is_Ring(r)) || n_IsUnit(inv,r->cf))
1618 if (rField_is_Zp(r))
1619 {
1620 inv = n_Invers(inv,r->cf);
1621 __p_Mult_nn(result,inv,r);
1622 n_Delete(&inv, r->cf);
1623 }
1624 else
1625 {
1626 result = p_Div_nn(result,inv,r);
1627 }
1628 }
1629 p_Delete(&b, r);
1630 return result;
1631}
1632
1633poly pp_DivideM(poly a, poly b, const ring r)
1634{
1635 if (a==NULL) { return NULL; }
1636 // TODO: better implementation without copying a,b
1637 return p_DivideM(p_Copy(a,r),p_Head(b,r),r);
1638}
1639
1640#ifdef HAVE_RINGS
1641/* TRUE iff LT(f) | LT(g) */
1642BOOLEAN p_DivisibleByRingCase(poly f, poly g, const ring r)
1643{
1644 int exponent;
1645 for(int i = (int)rVar(r); i>0; i--)
1646 {
1647 exponent = p_GetExp(g, i, r) - p_GetExp(f, i, r);
1648 if (exponent < 0) return FALSE;
1649 }
1650 return n_DivBy(pGetCoeff(g), pGetCoeff(f), r->cf);
1651}
1652#endif
1653
1654// returns the LCM of the head terms of a and b in *m
1655void p_Lcm(const poly a, const poly b, poly m, const ring r)
1656{
1657 for (int i=r->N; i; --i)
1658 p_SetExp(m,i, si_max( p_GetExp(a,i,r), p_GetExp(b,i,r)),r);
1659
1660 p_SetComp(m, si_max(p_GetComp(a,r), p_GetComp(b,r)),r);
1661 /* Don't do a pSetm here, otherwise hres/lres chockes */
1662}
1663
1664poly p_Lcm(const poly a, const poly b, const ring r)
1665{
1666 poly m=p_Init(r);
1667 p_Lcm(a, b, m, r);
1668 p_Setm(m,r);
1669 return(m);
1670}
1671
1672#ifdef HAVE_RATGRING
1673/*2
1674* returns the rational LCM of the head terms of a and b
1675* without coefficient!!!
1676*/
1677poly p_LcmRat(const poly a, const poly b, const long lCompM, const ring r)
1678{
1679 poly m = // p_One( r);
1680 p_Init(r);
1681
1682// const int (currRing->N) = r->N;
1683
1684 // for (int i = (currRing->N); i>=r->real_var_start; i--)
1685 for (int i = r->real_var_end; i>=r->real_var_start; i--)
1686 {
1687 const int lExpA = p_GetExp (a, i, r);
1688 const int lExpB = p_GetExp (b, i, r);
1689
1690 p_SetExp (m, i, si_max(lExpA, lExpB), r);
1691 }
1692
1693 p_SetComp (m, lCompM, r);
1694 p_Setm(m,r);
1695 p_GetCoeff(m, r)=NULL;
1696
1697 return(m);
1698};
1699
1700void p_LmDeleteAndNextRat(poly *p, int ishift, ring r)
1701{
1702 /* modifies p*/
1703 // Print("start: "); Print(" "); p_wrp(*p,r);
1704 p_LmCheckPolyRing2(*p, r);
1705 poly q = p_Head(*p,r);
1706 const long cmp = p_GetComp(*p, r);
1707 while ( ( (*p)!=NULL ) && ( p_Comp_k_n(*p, q, ishift+1, r) ) && (p_GetComp(*p, r) == cmp) )
1708 {
1709 p_LmDelete(p,r);
1710 // Print("while: ");p_wrp(*p,r);Print(" ");
1711 }
1712 // p_wrp(*p,r);Print(" ");
1713 // PrintS("end\n");
1714 p_LmDelete(&q,r);
1715}
1716
1717
1718/* returns x-coeff of p, i.e. a poly in x, s.t. corresponding xd-monomials
1719have the same D-part and the component 0
1720does not destroy p
1721*/
1722poly p_GetCoeffRat(poly p, int ishift, ring r)
1723{
1724 poly q = pNext(p);
1725 poly res; // = p_Head(p,r);
1726 res = p_GetExp_k_n(p, ishift+1, r->N, r); // does pSetm internally
1727 p_SetCoeff(res,n_Copy(p_GetCoeff(p,r),r),r);
1728 poly s;
1729 long cmp = p_GetComp(p, r);
1730 while ( (q!= NULL) && (p_Comp_k_n(p, q, ishift+1, r)) && (p_GetComp(q, r) == cmp) )
1731 {
1732 s = p_GetExp_k_n(q, ishift+1, r->N, r);
1733 p_SetCoeff(s,n_Copy(p_GetCoeff(q,r),r),r);
1734 res = p_Add_q(res,s,r);
1735 q = pNext(q);
1736 }
1737 cmp = 0;
1738 p_SetCompP(res,cmp,r);
1739 return res;
1740}
1741
1742
1743
1744void p_ContentRat(poly &ph, const ring r)
1745// changes ph
1746// for rat coefficients in K(x1,..xN)
1747{
1748 // init array of RatLeadCoeffs
1749 // poly p_GetCoeffRat(poly p, int ishift, ring r);
1750
1751 int len=pLength(ph);
1752 poly *C = (poly *)omAlloc0((len+1)*sizeof(poly)); //rat coeffs
1753 poly *LM = (poly *)omAlloc0((len+1)*sizeof(poly)); // rat lead terms
1754 int *D = (int *)omAlloc0((len+1)*sizeof(int)); //degrees of coeffs
1755 int *L = (int *)omAlloc0((len+1)*sizeof(int)); //lengths of coeffs
1756 int k = 0;
1757 poly p = p_Copy(ph, r); // ph will be needed below
1758 int mintdeg = p_Totaldegree(p, r);
1759 int minlen = len;
1760 int dd = 0; int i;
1761 int HasConstantCoef = 0;
1762 int is = r->real_var_start - 1;
1763 while (p!=NULL)
1764 {
1765 LM[k] = p_GetExp_k_n(p,1,is, r); // need LmRat istead of p_HeadRat(p, is, currRing); !
1766 C[k] = p_GetCoeffRat(p, is, r);
1767 D[k] = p_Totaldegree(C[k], r);
1768 mintdeg = si_min(mintdeg,D[k]);
1769 L[k] = pLength(C[k]);
1770 minlen = si_min(minlen,L[k]);
1771 if (p_IsConstant(C[k], r))
1772 {
1773 // C[k] = const, so the content will be numerical
1774 HasConstantCoef = 1;
1775 // smth like goto cleanup and return(pContent(p));
1776 }
1777 p_LmDeleteAndNextRat(&p, is, r);
1778 k++;
1779 }
1780
1781 // look for 1 element of minimal degree and of minimal length
1782 k--;
1783 poly d;
1784 int mindeglen = len;
1785 if (k<=0) // this poly is not a ratgring poly -> pContent
1786 {
1787 p_Delete(&C[0], r);
1788 p_Delete(&LM[0], r);
1789 p_ContentForGB(ph, r);
1790 goto cleanup;
1791 }
1792
1793 int pmindeglen;
1794 for(i=0; i<=k; i++)
1795 {
1796 if (D[i] == mintdeg)
1797 {
1798 if (L[i] < mindeglen)
1799 {
1800 mindeglen=L[i];
1801 pmindeglen = i;
1802 }
1803 }
1804 }
1805 d = p_Copy(C[pmindeglen], r);
1806 // there are dd>=1 mindeg elements
1807 // and pmideglen is the coordinate of one of the smallest among them
1808
1809 // poly g = singclap_gcd(p_Copy(p,r),p_Copy(q,r));
1810 // return naGcd(d,d2,currRing);
1811
1812 // adjoin pContentRat here?
1813 for(i=0; i<=k; i++)
1814 {
1815 d=singclap_gcd(d,p_Copy(C[i], r), r);
1816 if (p_Totaldegree(d, r)==0)
1817 {
1818 // cleanup, pContent, return
1819 p_Delete(&d, r);
1820 for(;k>=0;k--)
1821 {
1822 p_Delete(&C[k], r);
1823 p_Delete(&LM[k], r);
1824 }
1825 p_ContentForGB(ph, r);
1826 goto cleanup;
1827 }
1828 }
1829 for(i=0; i<=k; i++)
1830 {
1831 poly h=singclap_pdivide(C[i],d, r);
1832 p_Delete(&C[i], r);
1833 C[i]=h;
1834 }
1835
1836 // zusammensetzen,
1837 p=NULL; // just to be sure
1838 for(i=0; i<=k; i++)
1839 {
1840 p = p_Add_q(p, p_Mult_q(C[i],LM[i], r), r);
1841 C[i]=NULL; LM[i]=NULL;
1842 }
1843 p_Delete(&ph, r); // do not need it anymore
1844 ph = p;
1845 // aufraeumen, return
1846cleanup:
1847 omFree(C);
1848 omFree(LM);
1849 omFree(D);
1850 omFree(L);
1851}
1852
1853
1854#endif
1855
1856
1857/* assumes that p and divisor are univariate polynomials in r,
1858 mentioning the same variable;
1859 assumes divisor != NULL;
1860 p may be NULL;
1861 assumes a global monomial ordering in r;
1862 performs polynomial division of p by divisor:
1863 - afterwards p contains the remainder of the division, i.e.,
1864 p_before = result * divisor + p_afterwards;
1865 - if needResult == TRUE, then the method computes and returns 'result',
1866 otherwise NULL is returned (This parametrization can be used when
1867 one is only interested in the remainder of the division. In this
1868 case, the method will be slightly faster.)
1869 leaves divisor unmodified */
1870poly p_PolyDiv(poly &p, const poly divisor, const BOOLEAN needResult, const ring r)
1871{
1872 assume(divisor != NULL);
1873 if (p == NULL) return NULL;
1874
1875 poly result = NULL;
1876 number divisorLC = p_GetCoeff(divisor, r);
1877 int divisorLE = p_GetExp(divisor, 1, r);
1878 while ((p != NULL) && (p_Deg(p, r) >= p_Deg(divisor, r)))
1879 {
1880 /* determine t = LT(p) / LT(divisor) */
1881 poly t = p_ISet(1, r);
1882 number c = n_Div(p_GetCoeff(p, r), divisorLC, r->cf);
1883 n_Normalize(c,r->cf);
1884 p_SetCoeff(t, c, r);
1885 int e = p_GetExp(p, 1, r) - divisorLE;
1886 p_SetExp(t, 1, e, r);
1887 p_Setm(t, r);
1888 if (needResult) result = p_Add_q(result, p_Copy(t, r), r);
1889 p = p_Add_q(p, p_Neg(p_Mult_q(t, p_Copy(divisor, r), r), r), r);
1890 }
1891 return result;
1892}
1893
1894/*2
1895* returns the partial differentiate of a by the k-th variable
1896* does not destroy the input
1897*/
1898poly p_Diff(poly a, int k, const ring r)
1899{
1900 poly res, f, last;
1901 number t;
1902
1903 last = res = NULL;
1904 while (a!=NULL)
1905 {
1906 if (p_GetExp(a,k,r)!=0)
1907 {
1908 f = p_LmInit(a,r);
1909 t = n_Init(p_GetExp(a,k,r),r->cf);
1910 pSetCoeff0(f,n_Mult(t,pGetCoeff(a),r->cf));
1911 n_Delete(&t,r->cf);
1912 if (n_IsZero(pGetCoeff(f),r->cf))
1913 p_LmDelete(&f,r);
1914 else
1915 {
1916 p_DecrExp(f,k,r);
1917 p_Setm(f,r);
1918 if (res==NULL)
1919 {
1920 res=last=f;
1921 }
1922 else
1923 {
1924 pNext(last)=f;
1925 last=f;
1926 }
1927 }
1928 }
1929 pIter(a);
1930 }
1931 return res;
1932}
1933
1934static poly p_DiffOpM(poly a, poly b,BOOLEAN multiply, const ring r)
1935{
1936 int i,j,s;
1937 number n,h,hh;
1938 poly p=p_One(r);
1939 n=n_Mult(pGetCoeff(a),pGetCoeff(b),r->cf);
1940 for(i=rVar(r);i>0;i--)
1941 {
1942 s=p_GetExp(b,i,r);
1943 if (s<p_GetExp(a,i,r))
1944 {
1945 n_Delete(&n,r->cf);
1946 p_LmDelete(&p,r);
1947 return NULL;
1948 }
1949 if (multiply)
1950 {
1951 for(j=p_GetExp(a,i,r); j>0;j--)
1952 {
1953 h = n_Init(s,r->cf);
1954 hh=n_Mult(n,h,r->cf);
1955 n_Delete(&h,r->cf);
1956 n_Delete(&n,r->cf);
1957 n=hh;
1958 s--;
1959 }
1960 p_SetExp(p,i,s,r);
1961 }
1962 else
1963 {
1964 p_SetExp(p,i,s-p_GetExp(a,i,r),r);
1965 }
1966 }
1967 p_Setm(p,r);
1968 /*if (multiply)*/ p_SetCoeff(p,n,r);
1969 if (n_IsZero(n,r->cf)) p=p_LmDeleteAndNext(p,r); // return NULL as p is a monomial
1970 return p;
1971}
1972
1973poly p_DiffOp(poly a, poly b,BOOLEAN multiply, const ring r)
1974{
1975 poly result=NULL;
1976 poly h;
1977 for(;a!=NULL;pIter(a))
1978 {
1979 for(h=b;h!=NULL;pIter(h))
1980 {
1981 result=p_Add_q(result,p_DiffOpM(a,h,multiply,r),r);
1982 }
1983 }
1984 return result;
1985}
1986/*2
1987* subtract p2 from p1, p1 and p2 are destroyed
1988* do not put attention on speed: the procedure is only used in the interpreter
1989*/
1990poly p_Sub(poly p1, poly p2, const ring r)
1991{
1992 return p_Add_q(p1, p_Neg(p2,r),r);
1993}
1994
1995/*3
1996* compute for a monomial m
1997* the power m^exp, exp > 1
1998* destroys p
1999*/
2000static poly p_MonPower(poly p, int exp, const ring r)
2001{
2002 int i;
2003
2004 if(!n_IsOne(pGetCoeff(p),r->cf))
2005 {
2006 number x, y;
2007 y = pGetCoeff(p);
2008 n_Power(y,exp,&x,r->cf);
2009 n_Delete(&y,r->cf);
2010 pSetCoeff0(p,x);
2011 }
2012 for (i=rVar(r); i!=0; i--)
2013 {
2014 p_MultExp(p,i, exp,r);
2015 }
2016 p_Setm(p,r);
2017 return p;
2018}
2019
2020/*3
2021* compute for monomials p*q
2022* destroys p, keeps q
2023*/
2024static void p_MonMult(poly p, poly q, const ring r)
2025{
2026 number x, y;
2027
2028 y = pGetCoeff(p);
2029 x = n_Mult(y,pGetCoeff(q),r->cf);
2030 n_Delete(&y,r->cf);
2031 pSetCoeff0(p,x);
2032 //for (int i=pVariables; i!=0; i--)
2033 //{
2034 // pAddExp(p,i, pGetExp(q,i));
2035 //}
2036 //p->Order += q->Order;
2037 p_ExpVectorAdd(p,q,r);
2038}
2039
2040/*3
2041* compute for monomials p*q
2042* keeps p, q
2043*/
2044static poly p_MonMultC(poly p, poly q, const ring rr)
2045{
2046 number x;
2047 poly r = p_Init(rr);
2048
2049 x = n_Mult(pGetCoeff(p),pGetCoeff(q),rr->cf);
2050 pSetCoeff0(r,x);
2051 p_ExpVectorSum(r,p, q, rr);
2052 return r;
2053}
2054
2055/*3
2056* create binomial coef.
2057*/
2058static number* pnBin(int exp, const ring r)
2059{
2060 int e, i, h;
2061 number x, y, *bin=NULL;
2062
2063 x = n_Init(exp,r->cf);
2064 if (n_IsZero(x,r->cf))
2065 {
2066 n_Delete(&x,r->cf);
2067 return bin;
2068 }
2069 h = (exp >> 1) + 1;
2070 bin = (number *)omAlloc0(h*sizeof(number));
2071 bin[1] = x;
2072 if (exp < 4)
2073 return bin;
2074 i = exp - 1;
2075 for (e=2; e<h; e++)
2076 {
2077 x = n_Init(i,r->cf);
2078 i--;
2079 y = n_Mult(x,bin[e-1],r->cf);
2080 n_Delete(&x,r->cf);
2081 x = n_Init(e,r->cf);
2082 bin[e] = n_ExactDiv(y,x,r->cf);
2083 n_Delete(&x,r->cf);
2084 n_Delete(&y,r->cf);
2085 }
2086 return bin;
2087}
2088
2089static void pnFreeBin(number *bin, int exp,const coeffs r)
2090{
2091 int e, h = (exp >> 1) + 1;
2092
2093 if (bin[1] != NULL)
2094 {
2095 for (e=1; e<h; e++)
2096 n_Delete(&(bin[e]),r);
2097 }
2098 omFreeSize((ADDRESS)bin, h*sizeof(number));
2099}
2100
2101/*
2102* compute for a poly p = head+tail, tail is monomial
2103* (head + tail)^exp, exp > 1
2104* with binomial coef.
2105*/
2106static poly p_TwoMonPower(poly p, int exp, const ring r)
2107{
2108 int eh, e;
2109 long al;
2110 poly *a;
2111 poly tail, b, res, h;
2112 number x;
2113 number *bin = pnBin(exp,r);
2114
2115 tail = pNext(p);
2116 if (bin == NULL)
2117 {
2118 p_MonPower(p,exp,r);
2119 p_MonPower(tail,exp,r);
2120 p_Test(p,r);
2121 return p;
2122 }
2123 eh = exp >> 1;
2124 al = (exp + 1) * sizeof(poly);
2125 a = (poly *)omAlloc(al);
2126 a[1] = p;
2127 for (e=1; e<exp; e++)
2128 {
2129 a[e+1] = p_MonMultC(a[e],p,r);
2130 }
2131 res = a[exp];
2132 b = p_Head(tail,r);
2133 for (e=exp-1; e>eh; e--)
2134 {
2135 h = a[e];
2136 x = n_Mult(bin[exp-e],pGetCoeff(h),r->cf);
2137 p_SetCoeff(h,x,r);
2138 p_MonMult(h,b,r);
2139 res = pNext(res) = h;
2140 p_MonMult(b,tail,r);
2141 }
2142 for (e=eh; e!=0; e--)
2143 {
2144 h = a[e];
2145 x = n_Mult(bin[e],pGetCoeff(h),r->cf);
2146 p_SetCoeff(h,x,r);
2147 p_MonMult(h,b,r);
2148 res = pNext(res) = h;
2149 p_MonMult(b,tail,r);
2150 }
2151 p_LmDelete(&tail,r);
2152 pNext(res) = b;
2153 pNext(b) = NULL;
2154 res = a[exp];
2155 omFreeSize((ADDRESS)a, al);
2156 pnFreeBin(bin, exp, r->cf);
2157// tail=res;
2158// while((tail!=NULL)&&(pNext(tail)!=NULL))
2159// {
2160// if(nIsZero(pGetCoeff(pNext(tail))))
2161// {
2162// pLmDelete(&pNext(tail));
2163// }
2164// else
2165// pIter(tail);
2166// }
2167 p_Test(res,r);
2168 return res;
2169}
2170
2171static poly p_Pow(poly p, int i, const ring r)
2172{
2173 poly rc = p_Copy(p,r);
2174 i -= 2;
2175 do
2176 {
2177 rc = p_Mult_q(rc,p_Copy(p,r),r);
2178 p_Normalize(rc,r);
2179 i--;
2180 }
2181 while (i != 0);
2182 return p_Mult_q(rc,p,r);
2183}
2184
2185static poly p_Pow_charp(poly p, int i, const ring r)
2186{
2187 //assume char_p == i
2188 poly h=p;
2189 while(h!=NULL) { p_MonPower(h,i,r);pIter(h);}
2190 return p;
2191}
2192
2193/*2
2194* returns the i-th power of p
2195* p will be destroyed
2196*/
2197poly p_Power(poly p, int i, const ring r)
2198{
2199 poly rc=NULL;
2200
2201 if (i==0)
2202 {
2203 p_Delete(&p,r);
2204 return p_One(r);
2205 }
2206
2207 if(p!=NULL)
2208 {
2209 if ( (i > 0) && ((unsigned long ) i > (r->bitmask))
2210 #ifdef HAVE_SHIFTBBA
2211 && (!rIsLPRing(r))
2212 #endif
2213 )
2214 {
2215 Werror("exponent %d is too large, max. is %ld",i,r->bitmask);
2216 return NULL;
2217 }
2218 switch (i)
2219 {
2220// cannot happen, see above
2221// case 0:
2222// {
2223// rc=pOne();
2224// pDelete(&p);
2225// break;
2226// }
2227 case 1:
2228 rc=p;
2229 break;
2230 case 2:
2231 rc=p_Mult_q(p_Copy(p,r),p,r);
2232 break;
2233 default:
2234 if (i < 0)
2235 {
2236 p_Delete(&p,r);
2237 return NULL;
2238 }
2239 else
2240 {
2241#ifdef HAVE_PLURAL
2242 if (rIsNCRing(r)) /* in the NC case nothing helps :-( */
2243 {
2244 int j=i;
2245 rc = p_Copy(p,r);
2246 while (j>1)
2247 {
2248 rc = p_Mult_q(p_Copy(p,r),rc,r);
2249 j--;
2250 }
2251 p_Delete(&p,r);
2252 return rc;
2253 }
2254#endif
2255 rc = pNext(p);
2256 if (rc == NULL)
2257 return p_MonPower(p,i,r);
2258 /* else: binom ?*/
2259 int char_p=rInternalChar(r);
2260 if ((char_p>0) && (i>char_p)
2261 && ((rField_is_Zp(r,char_p)
2262 || (rField_is_Zp_a(r,char_p)))))
2263 {
2264 poly h=p_Pow_charp(p_Copy(p,r),char_p,r);
2265 int rest=i-char_p;
2266 while (rest>=char_p)
2267 {
2268 rest-=char_p;
2269 h=p_Mult_q(h,p_Pow_charp(p_Copy(p,r),char_p,r),r);
2270 }
2271 poly res=h;
2272 if (rest>0)
2273 res=p_Mult_q(p_Power(p_Copy(p,r),rest,r),h,r);
2274 p_Delete(&p,r);
2275 return res;
2276 }
2277 if ((pNext(rc) != NULL)
2278 || rField_is_Ring(r)
2279 )
2280 return p_Pow(p,i,r);
2281 if ((char_p==0) || (i<=char_p))
2282 return p_TwoMonPower(p,i,r);
2283 return p_Pow(p,i,r);
2284 }
2285 /*end default:*/
2286 }
2287 }
2288 return rc;
2289}
2290
2291/* --------------------------------------------------------------------------------*/
2292/* content suff */
2293//number p_InitContent(poly ph, const ring r);
2294
2295void p_Content(poly ph, const ring r)
2296{
2297 if (ph==NULL) return;
2298 const coeffs cf=r->cf;
2299 if (pNext(ph)==NULL)
2300 {
2301 p_SetCoeff(ph,n_Init(1,cf),r);
2302 return;
2303 }
2304 if ((cf->cfSubringGcd==ndGcd)
2305 || (cf->cfGcd==ndGcd)) /* trivial gcd*/
2306 return;
2307 number h;
2308 if ((rField_is_Q(r))
2309 || (rField_is_Q_a(r))
2310 || (rField_is_Zp_a)(r)
2311 || (rField_is_Z(r))
2312 )
2313 {
2314 h=p_InitContent(ph,r); /* first guess of a gcd of all coeffs */
2315 }
2316 else
2317 {
2318 h=n_Copy(pGetCoeff(ph),cf);
2319 }
2320 poly p;
2321 if(n_IsOne(h,cf))
2322 {
2323 goto content_finish;
2324 }
2325 p=ph;
2326 // take the SubringGcd of all coeffs
2327 while (p!=NULL)
2328 {
2330 number d=n_SubringGcd(h,pGetCoeff(p),cf);
2331 n_Delete(&h,cf);
2332 h = d;
2333 if(n_IsOne(h,cf))
2334 {
2335 goto content_finish;
2336 }
2337 pIter(p);
2338 }
2339 // if found<>1, divide by it
2340 p = ph;
2341 while (p!=NULL)
2342 {
2343 number d = n_ExactDiv(pGetCoeff(p),h,cf);
2344 p_SetCoeff(p,d,r);
2345 pIter(p);
2346 }
2347content_finish:
2348 n_Delete(&h,r->cf);
2349 // and last: check leading sign:
2350 if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2351}
2352
2353#define CLEARENUMERATORS 1
2354
2355void p_ContentForGB(poly ph, const ring r)
2356{
2357 if(TEST_OPT_CONTENTSB) return;
2358 assume( ph != NULL );
2359
2360 assume( r != NULL ); assume( r->cf != NULL );
2361
2362
2363#if CLEARENUMERATORS
2364 if( 0 )
2365 {
2366 const coeffs C = r->cf;
2367 // experimentall (recursive enumerator treatment) of alg. Ext!
2368 CPolyCoeffsEnumerator itr(ph);
2369 n_ClearContent(itr, r->cf);
2370
2371 p_Test(ph, r); n_Test(pGetCoeff(ph), C);
2372 assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
2373
2374 // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2375 return;
2376 }
2377#endif
2378
2379
2380#ifdef HAVE_RINGS
2381 if (rField_is_Ring(r))
2382 {
2383 if (rField_has_Units(r))
2384 {
2385 number k = n_GetUnit(pGetCoeff(ph),r->cf);
2386 if (!n_IsOne(k,r->cf))
2387 {
2388 number tmpGMP = k;
2389 k = n_Invers(k,r->cf);
2390 n_Delete(&tmpGMP,r->cf);
2391 poly h = pNext(ph);
2392 p_SetCoeff(ph, n_Mult(pGetCoeff(ph), k,r->cf),r);
2393 while (h != NULL)
2394 {
2395 p_SetCoeff(h, n_Mult(pGetCoeff(h), k,r->cf),r);
2396 pIter(h);
2397 }
2398// assume( n_GreaterZero(pGetCoeff(ph),r->cf) );
2399// if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2400 }
2401 n_Delete(&k,r->cf);
2402 }
2403 return;
2404 }
2405#endif
2406 number h,d;
2407 poly p;
2408
2409 if(pNext(ph)==NULL)
2410 {
2411 p_SetCoeff(ph,n_Init(1,r->cf),r);
2412 }
2413 else
2414 {
2415 assume( pNext(ph) != NULL );
2416#if CLEARENUMERATORS
2417 if( nCoeff_is_Q(r->cf) )
2418 {
2419 // experimentall (recursive enumerator treatment) of alg. Ext!
2420 CPolyCoeffsEnumerator itr(ph);
2421 n_ClearContent(itr, r->cf);
2422
2423 p_Test(ph, r); n_Test(pGetCoeff(ph), r->cf);
2424 assume(n_GreaterZero(pGetCoeff(ph), r->cf)); // ??
2425
2426 // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2427 return;
2428 }
2429#endif
2430
2431 n_Normalize(pGetCoeff(ph),r->cf);
2432 if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2433 if (rField_is_Q(r)||(getCoeffType(r->cf)==n_transExt)) // should not be used anymore if CLEARENUMERATORS is 1
2434 {
2435 h=p_InitContent(ph,r);
2436 p=ph;
2437 }
2438 else
2439 {
2440 h=n_Copy(pGetCoeff(ph),r->cf);
2441 p = pNext(ph);
2442 }
2443 while (p!=NULL)
2444 {
2445 n_Normalize(pGetCoeff(p),r->cf);
2446 d=n_SubringGcd(h,pGetCoeff(p),r->cf);
2447 n_Delete(&h,r->cf);
2448 h = d;
2449 if(n_IsOne(h,r->cf))
2450 {
2451 break;
2452 }
2453 pIter(p);
2454 }
2455 //number tmp;
2456 if(!n_IsOne(h,r->cf))
2457 {
2458 p = ph;
2459 while (p!=NULL)
2460 {
2461 //d = nDiv(pGetCoeff(p),h);
2462 //tmp = nExactDiv(pGetCoeff(p),h);
2463 //if (!nEqual(d,tmp))
2464 //{
2465 // StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
2466 // nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
2467 // nWrite(tmp);Print(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
2468 //}
2469 //nDelete(&tmp);
2470 d = n_ExactDiv(pGetCoeff(p),h,r->cf);
2471 p_SetCoeff(p,d,r);
2472 pIter(p);
2473 }
2474 }
2475 n_Delete(&h,r->cf);
2476 if (rField_is_Q_a(r))
2477 {
2478 // special handling for alg. ext.:
2479 if (getCoeffType(r->cf)==n_algExt)
2480 {
2481 h = n_Init(1, r->cf->extRing->cf);
2482 p=ph;
2483 while (p!=NULL)
2484 { // each monom: coeff in Q_a
2485 poly c_n_n=(poly)pGetCoeff(p);
2486 poly c_n=c_n_n;
2487 while (c_n!=NULL)
2488 { // each monom: coeff in Q
2489 d=n_NormalizeHelper(h,pGetCoeff(c_n),r->cf->extRing->cf);
2490 n_Delete(&h,r->cf->extRing->cf);
2491 h=d;
2492 pIter(c_n);
2493 }
2494 pIter(p);
2495 }
2496 /* h contains the 1/lcm of all denominators in c_n_n*/
2497 //n_Normalize(h,r->cf->extRing->cf);
2498 if(!n_IsOne(h,r->cf->extRing->cf))
2499 {
2500 p=ph;
2501 while (p!=NULL)
2502 { // each monom: coeff in Q_a
2503 poly c_n=(poly)pGetCoeff(p);
2504 while (c_n!=NULL)
2505 { // each monom: coeff in Q
2506 d=n_Mult(h,pGetCoeff(c_n),r->cf->extRing->cf);
2507 n_Normalize(d,r->cf->extRing->cf);
2508 n_Delete(&pGetCoeff(c_n),r->cf->extRing->cf);
2509 pGetCoeff(c_n)=d;
2510 pIter(c_n);
2511 }
2512 pIter(p);
2513 }
2514 }
2515 n_Delete(&h,r->cf->extRing->cf);
2516 }
2517 /*else
2518 {
2519 // special handling for rat. functions.:
2520 number hzz =NULL;
2521 p=ph;
2522 while (p!=NULL)
2523 { // each monom: coeff in Q_a (Z_a)
2524 fraction f=(fraction)pGetCoeff(p);
2525 poly c_n=NUM(f);
2526 if (hzz==NULL)
2527 {
2528 hzz=n_Copy(pGetCoeff(c_n),r->cf->extRing->cf);
2529 pIter(c_n);
2530 }
2531 while ((c_n!=NULL)&&(!n_IsOne(hzz,r->cf->extRing->cf)))
2532 { // each monom: coeff in Q (Z)
2533 d=n_Gcd(hzz,pGetCoeff(c_n),r->cf->extRing->cf);
2534 n_Delete(&hzz,r->cf->extRing->cf);
2535 hzz=d;
2536 pIter(c_n);
2537 }
2538 pIter(p);
2539 }
2540 // hzz contains the gcd of all numerators in f
2541 h=n_Invers(hzz,r->cf->extRing->cf);
2542 n_Delete(&hzz,r->cf->extRing->cf);
2543 n_Normalize(h,r->cf->extRing->cf);
2544 if(!n_IsOne(h,r->cf->extRing->cf))
2545 {
2546 p=ph;
2547 while (p!=NULL)
2548 { // each monom: coeff in Q_a (Z_a)
2549 fraction f=(fraction)pGetCoeff(p);
2550 NUM(f)=__p_Mult_nn(NUM(f),h,r->cf->extRing);
2551 p_Normalize(NUM(f),r->cf->extRing);
2552 pIter(p);
2553 }
2554 }
2555 n_Delete(&h,r->cf->extRing->cf);
2556 }*/
2557 }
2558 }
2559 if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2560}
2561
2562// Not yet?
2563#if 1 // currently only used by Singular/janet
2564void p_SimpleContent(poly ph, int smax, const ring r)
2565{
2566 if(TEST_OPT_CONTENTSB) return;
2567 if (ph==NULL) return;
2568 if (pNext(ph)==NULL)
2569 {
2570 p_SetCoeff(ph,n_Init(1,r->cf),r);
2571 return;
2572 }
2573 if (pNext(pNext(ph))==NULL)
2574 {
2575 return;
2576 }
2577 if (!(rField_is_Q(r))
2578 && (!rField_is_Q_a(r))
2579 && (!rField_is_Zp_a(r))
2580 && (!rField_is_Z(r))
2581 )
2582 {
2583 return;
2584 }
2585 number d=p_InitContent(ph,r);
2586 number h=d;
2587 if (n_Size(d,r->cf)<=smax)
2588 {
2589 n_Delete(&h,r->cf);
2590 //if (TEST_OPT_PROT) PrintS("G");
2591 return;
2592 }
2593
2594 poly p=ph;
2595 if (smax==1) smax=2;
2596 while (p!=NULL)
2597 {
2598#if 1
2599 d=n_SubringGcd(h,pGetCoeff(p),r->cf);
2600 n_Delete(&h,r->cf);
2601 h = d;
2602#else
2603 n_InpGcd(h,pGetCoeff(p),r->cf);
2604#endif
2605 if(n_Size(h,r->cf)<smax)
2606 {
2607 //if (TEST_OPT_PROT) PrintS("g");
2608 n_Delete(&h,r->cf);
2609 return;
2610 }
2611 pIter(p);
2612 }
2613 p = ph;
2614 if (!n_GreaterZero(pGetCoeff(p),r->cf)) h=n_InpNeg(h,r->cf);
2615 if(n_IsOne(h,r->cf))
2616 {
2617 n_Delete(&h,r->cf);
2618 return;
2619 }
2620 if (TEST_OPT_PROT) PrintS("c");
2621 while (p!=NULL)
2622 {
2623#if 1
2624 d = n_ExactDiv(pGetCoeff(p),h,r->cf);
2625 p_SetCoeff(p,d,r);
2626#else
2627 STATISTIC(n_ExactDiv); nlInpExactDiv(pGetCoeff(p),h,r->cf); // no such function... ?
2628#endif
2629 pIter(p);
2630 }
2631 n_Delete(&h,r->cf);
2632}
2633#endif
2634
2635number p_InitContent(poly ph, const ring r)
2636// only for coefficients in Q and rational functions
2637#if 0
2638{
2640 assume(ph!=NULL);
2641 assume(pNext(ph)!=NULL);
2642 assume(rField_is_Q(r));
2643 if (pNext(pNext(ph))==NULL)
2644 {
2645 return n_GetNumerator(pGetCoeff(pNext(ph)),r->cf);
2646 }
2647 poly p=ph;
2648 number n1=n_GetNumerator(pGetCoeff(p),r->cf);
2649 pIter(p);
2650 number n2=n_GetNumerator(pGetCoeff(p),r->cf);
2651 pIter(p);
2652 number d;
2653 number t;
2654 loop
2655 {
2656 nlNormalize(pGetCoeff(p),r->cf);
2657 t=n_GetNumerator(pGetCoeff(p),r->cf);
2658 if (nlGreaterZero(t,r->cf))
2659 d=nlAdd(n1,t,r->cf);
2660 else
2661 d=nlSub(n1,t,r->cf);
2662 nlDelete(&t,r->cf);
2663 nlDelete(&n1,r->cf);
2664 n1=d;
2665 pIter(p);
2666 if (p==NULL) break;
2667 nlNormalize(pGetCoeff(p),r->cf);
2668 t=n_GetNumerator(pGetCoeff(p),r->cf);
2669 if (nlGreaterZero(t,r->cf))
2670 d=nlAdd(n2,t,r->cf);
2671 else
2672 d=nlSub(n2,t,r->cf);
2673 nlDelete(&t,r->cf);
2674 nlDelete(&n2,r->cf);
2675 n2=d;
2676 pIter(p);
2677 if (p==NULL) break;
2678 }
2679 d=nlGcd(n1,n2,r->cf);
2680 nlDelete(&n1,r->cf);
2681 nlDelete(&n2,r->cf);
2682 return d;
2683}
2684#else
2685{
2686 /* ph has al least 2 terms */
2687 number d=pGetCoeff(ph);
2688 int s=n_Size(d,r->cf);
2689 pIter(ph);
2690 number d2=pGetCoeff(ph);
2691 int s2=n_Size(d2,r->cf);
2692 pIter(ph);
2693 if (ph==NULL)
2694 {
2695 if (s<s2) return n_Copy(d,r->cf);
2696 else return n_Copy(d2,r->cf);
2697 }
2698 do
2699 {
2700 number nd=pGetCoeff(ph);
2701 int ns=n_Size(nd,r->cf);
2702 if (ns<=2)
2703 {
2704 s2=s;
2705 d2=d;
2706 d=nd;
2707 s=ns;
2708 break;
2709 }
2710 else if (ns<s)
2711 {
2712 s2=s;
2713 d2=d;
2714 d=nd;
2715 s=ns;
2716 }
2717 pIter(ph);
2718 }
2719 while(ph!=NULL);
2720 return n_SubringGcd(d,d2,r->cf);
2721}
2722#endif
2723
2724//void pContent(poly ph)
2725//{
2726// number h,d;
2727// poly p;
2728//
2729// p = ph;
2730// if(pNext(p)==NULL)
2731// {
2732// pSetCoeff(p,nInit(1));
2733// }
2734// else
2735// {
2736//#ifdef PDEBUG
2737// if (!pTest(p)) return;
2738//#endif
2739// nNormalize(pGetCoeff(p));
2740// if(!nGreaterZero(pGetCoeff(ph)))
2741// {
2742// ph = pNeg(ph);
2743// nNormalize(pGetCoeff(p));
2744// }
2745// h=pGetCoeff(p);
2746// pIter(p);
2747// while (p!=NULL)
2748// {
2749// nNormalize(pGetCoeff(p));
2750// if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
2751// pIter(p);
2752// }
2753// h=nCopy(h);
2754// p=ph;
2755// while (p!=NULL)
2756// {
2757// d=n_Gcd(h,pGetCoeff(p));
2758// nDelete(&h);
2759// h = d;
2760// if(nIsOne(h))
2761// {
2762// break;
2763// }
2764// pIter(p);
2765// }
2766// p = ph;
2767// //number tmp;
2768// if(!nIsOne(h))
2769// {
2770// while (p!=NULL)
2771// {
2772// d = nExactDiv(pGetCoeff(p),h);
2773// pSetCoeff(p,d);
2774// pIter(p);
2775// }
2776// }
2777// nDelete(&h);
2778// if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
2779// {
2780// pTest(ph);
2781// singclap_divide_content(ph);
2782// pTest(ph);
2783// }
2784// }
2785//}
2786#if 0
2787void p_Content(poly ph, const ring r)
2788{
2789 number h,d;
2790 poly p;
2791
2792 if(pNext(ph)==NULL)
2793 {
2794 p_SetCoeff(ph,n_Init(1,r->cf),r);
2795 }
2796 else
2797 {
2798 n_Normalize(pGetCoeff(ph),r->cf);
2799 if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
2800 h=n_Copy(pGetCoeff(ph),r->cf);
2801 p = pNext(ph);
2802 while (p!=NULL)
2803 {
2804 n_Normalize(pGetCoeff(p),r->cf);
2805 d=n_Gcd(h,pGetCoeff(p),r->cf);
2806 n_Delete(&h,r->cf);
2807 h = d;
2808 if(n_IsOne(h,r->cf))
2809 {
2810 break;
2811 }
2812 pIter(p);
2813 }
2814 p = ph;
2815 //number tmp;
2816 if(!n_IsOne(h,r->cf))
2817 {
2818 while (p!=NULL)
2819 {
2820 //d = nDiv(pGetCoeff(p),h);
2821 //tmp = nExactDiv(pGetCoeff(p),h);
2822 //if (!nEqual(d,tmp))
2823 //{
2824 // StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
2825 // nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
2826 // nWrite(tmp);Print(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
2827 //}
2828 //nDelete(&tmp);
2829 d = n_ExactDiv(pGetCoeff(p),h,r->cf);
2830 p_SetCoeff(p,d,r->cf);
2831 pIter(p);
2832 }
2833 }
2834 n_Delete(&h,r->cf);
2835 //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
2836 //{
2837 // singclap_divide_content(ph);
2838 // if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
2839 //}
2840 }
2841}
2842#endif
2843/* ---------------------------------------------------------------------------*/
2844/* cleardenom suff */
2845poly p_Cleardenom(poly p, const ring r)
2846{
2847 if( p == NULL )
2848 return NULL;
2849
2850 assume( r != NULL );
2851 assume( r->cf != NULL );
2852 const coeffs C = r->cf;
2853
2854#if CLEARENUMERATORS
2855 if( 0 )
2856 {
2858 n_ClearDenominators(itr, C);
2859 n_ClearContent(itr, C); // divide out the content
2860 p_Test(p, r); n_Test(pGetCoeff(p), C);
2861 assume(n_GreaterZero(pGetCoeff(p), C)); // ??
2862// if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
2863 return p;
2864 }
2865#endif
2866
2867 number d, h;
2868
2869 if (rField_is_Ring(r))
2870 {
2871 if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
2872 return p;
2873 }
2874
2876 {
2877 if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
2878 return p;
2879 }
2880
2881 assume(p != NULL);
2882
2883 if(pNext(p)==NULL)
2884 {
2885 if (!TEST_OPT_CONTENTSB)
2886 p_SetCoeff(p,n_Init(1,C),r);
2887 else if(!n_GreaterZero(pGetCoeff(p),C))
2888 p = p_Neg(p,r);
2889 return p;
2890 }
2891
2892 assume(pNext(p)!=NULL);
2893 poly start=p;
2894
2895#if 0 && CLEARENUMERATORS
2896//CF: does not seem to work that well..
2897
2898 if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) )
2899 {
2901 n_ClearDenominators(itr, C);
2902 n_ClearContent(itr, C); // divide out the content
2903 p_Test(p, r); n_Test(pGetCoeff(p), C);
2904 assume(n_GreaterZero(pGetCoeff(p), C)); // ??
2905// if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
2906 return start;
2907 }
2908#endif
2909
2910 if(1)
2911 {
2912 // get lcm of all denominators ----------------------------------
2913 h = n_Init(1,C);
2914 while (p!=NULL)
2915 {
2918 n_Delete(&h,C);
2919 h=d;
2920 pIter(p);
2921 }
2922 /* h now contains the 1/lcm of all denominators */
2923 if(!n_IsOne(h,C))
2924 {
2925 // multiply by the lcm of all denominators
2926 p = start;
2927 while (p!=NULL)
2928 {
2929 d=n_Mult(h,pGetCoeff(p),C);
2930 n_Normalize(d,C);
2931 p_SetCoeff(p,d,r);
2932 pIter(p);
2933 }
2934 }
2935 n_Delete(&h,C);
2936 p=start;
2937
2938 p_ContentForGB(p,r);
2939#ifdef HAVE_RATGRING
2940 if (rIsRatGRing(r))
2941 {
2942 /* quick unit detection in the rational case is done in gr_nc_bba */
2943 p_ContentRat(p, r);
2944 start=p;
2945 }
2946#endif
2947 }
2948
2949 if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
2950
2951 return start;
2952}
2953
2954void p_Cleardenom_n(poly ph,const ring r,number &c)
2955{
2956 const coeffs C = r->cf;
2957 number d, h;
2958
2959 assume( ph != NULL );
2960
2961 poly p = ph;
2962
2963#if CLEARENUMERATORS
2964 if( 0 )
2965 {
2966 CPolyCoeffsEnumerator itr(ph);
2967
2968 n_ClearDenominators(itr, d, C); // multiply with common denom. d
2969 n_ClearContent(itr, h, C); // divide by the content h
2970
2971 c = n_Div(d, h, C); // d/h
2972
2973 n_Delete(&d, C);
2974 n_Delete(&h, C);
2975
2976 n_Test(c, C);
2977
2978 p_Test(ph, r); n_Test(pGetCoeff(ph), C);
2979 assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
2980/*
2981 if(!n_GreaterZero(pGetCoeff(ph),C))
2982 {
2983 ph = p_Neg(ph,r);
2984 c = n_InpNeg(c, C);
2985 }
2986*/
2987 return;
2988 }
2989#endif
2990
2991
2992 if( pNext(p) == NULL )
2993 {
2995 {
2996 c=n_Invers(pGetCoeff(p), C);
2997 p_SetCoeff(p, n_Init(1, C), r);
2998 }
2999 else
3000 {
3001 c=n_Init(1,C);
3002 }
3003
3004 if(!n_GreaterZero(pGetCoeff(ph),C))
3005 {
3006 ph = p_Neg(ph,r);
3007 c = n_InpNeg(c, C);
3008 }
3009
3010 return;
3011 }
3012 if (TEST_OPT_CONTENTSB) { c=n_Init(1,C); return; }
3013
3014 assume( pNext(p) != NULL );
3015
3016#if CLEARENUMERATORS
3017 if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) )
3018 {
3019 CPolyCoeffsEnumerator itr(ph);
3020
3021 n_ClearDenominators(itr, d, C); // multiply with common denom. d
3022 n_ClearContent(itr, h, C); // divide by the content h
3023
3024 c = n_Div(d, h, C); // d/h
3025
3026 n_Delete(&d, C);
3027 n_Delete(&h, C);
3028
3029 n_Test(c, C);
3030
3031 p_Test(ph, r); n_Test(pGetCoeff(ph), C);
3032 assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
3033/*
3034 if(!n_GreaterZero(pGetCoeff(ph),C))
3035 {
3036 ph = p_Neg(ph,r);
3037 c = n_InpNeg(c, C);
3038 }
3039*/
3040 return;
3041 }
3042#endif
3043
3044
3045
3046
3047 if(1)
3048 {
3049 h = n_Init(1,C);
3050 while (p!=NULL)
3051 {
3054 n_Delete(&h,C);
3055 h=d;
3056 pIter(p);
3057 }
3058 c=h;
3059 /* contains the 1/lcm of all denominators */
3060 if(!n_IsOne(h,C))
3061 {
3062 p = ph;
3063 while (p!=NULL)
3064 {
3065 /* should be: // NOTE: don't use ->coef!!!!
3066 * number hh;
3067 * nGetDenom(p->coef,&hh);
3068 * nMult(&h,&hh,&d);
3069 * nNormalize(d);
3070 * nDelete(&hh);
3071 * nMult(d,p->coef,&hh);
3072 * nDelete(&d);
3073 * nDelete(&(p->coef));
3074 * p->coef =hh;
3075 */
3076 d=n_Mult(h,pGetCoeff(p),C);
3077 n_Normalize(d,C);
3078 p_SetCoeff(p,d,r);
3079 pIter(p);
3080 }
3081 if (rField_is_Q_a(r))
3082 {
3083 loop
3084 {
3085 h = n_Init(1,C);
3086 p=ph;
3087 while (p!=NULL)
3088 {
3090 n_Delete(&h,C);
3091 h=d;
3092 pIter(p);
3093 }
3094 /* contains the 1/lcm of all denominators */
3095 if(!n_IsOne(h,C))
3096 {
3097 p = ph;
3098 while (p!=NULL)
3099 {
3100 /* should be: // NOTE: don't use ->coef!!!!
3101 * number hh;
3102 * nGetDenom(p->coef,&hh);
3103 * nMult(&h,&hh,&d);
3104 * nNormalize(d);
3105 * nDelete(&hh);
3106 * nMult(d,p->coef,&hh);
3107 * nDelete(&d);
3108 * nDelete(&(p->coef));
3109 * p->coef =hh;
3110 */
3111 d=n_Mult(h,pGetCoeff(p),C);
3112 n_Normalize(d,C);
3113 p_SetCoeff(p,d,r);
3114 pIter(p);
3115 }
3116 number t=n_Mult(c,h,C);
3117 n_Delete(&c,C);
3118 c=t;
3119 }
3120 else
3121 {
3122 break;
3123 }
3124 n_Delete(&h,C);
3125 }
3126 }
3127 }
3128 }
3129
3130 if(!n_GreaterZero(pGetCoeff(ph),C))
3131 {
3132 ph = p_Neg(ph,r);
3133 c = n_InpNeg(c, C);
3134 }
3135
3136}
3137
3138 // normalization: for poly over Q: make poly primitive, integral
3139 // Qa make poly integral with leading
3140 // coefficient minimal in N
3141 // Q(t) make poly primitive, integral
3142
3143void p_ProjectiveUnique(poly ph, const ring r)
3144{
3145 if( ph == NULL )
3146 return;
3147
3148 const coeffs C = r->cf;
3149
3150 number h;
3151 poly p;
3152
3153 if (nCoeff_is_Ring(C))
3154 {
3155 p_ContentForGB(ph,r);
3156 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r);
3157 assume( n_GreaterZero(pGetCoeff(ph),C) );
3158 return;
3159 }
3160
3162 {
3163 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r);
3164 return;
3165 }
3166 p = ph;
3167
3168 assume(p != NULL);
3169
3170 if(pNext(p)==NULL) // a monomial
3171 {
3172 p_SetCoeff(p, n_Init(1, C), r);
3173 return;
3174 }
3175
3176 assume(pNext(p)!=NULL);
3177
3178 if(!nCoeff_is_Q(C) && !nCoeff_is_transExt(C))
3179 {
3180 h = p_GetCoeff(p, C);
3181 number hInv = n_Invers(h, C);
3182 pIter(p);
3183 while (p!=NULL)
3184 {
3185 p_SetCoeff(p, n_Mult(p_GetCoeff(p, C), hInv, C), r);
3186 pIter(p);
3187 }
3188 n_Delete(&hInv, C);
3189 p = ph;
3190 p_SetCoeff(p, n_Init(1, C), r);
3191 }
3192
3193 p_Cleardenom(ph, r); //removes also Content
3194
3195
3196 /* normalize ph over a transcendental extension s.t.
3197 lead (ph) is > 0 if extRing->cf == Q
3198 or lead (ph) is monic if extRing->cf == Zp*/
3199 if (nCoeff_is_transExt(C))
3200 {
3201 p= ph;
3202 h= p_GetCoeff (p, C);
3203 fraction f = (fraction) h;
3204 number n=p_GetCoeff (NUM (f),C->extRing->cf);
3205 if (rField_is_Q (C->extRing))
3206 {
3207 if (!n_GreaterZero(n,C->extRing->cf))
3208 {
3209 p=p_Neg (p,r);
3210 }
3211 }
3212 else if (rField_is_Zp(C->extRing))
3213 {
3214 if (!n_IsOne (n, C->extRing->cf))
3215 {
3216 n=n_Invers (n,C->extRing->cf);
3217 nMapFunc nMap;
3218 nMap= n_SetMap (C->extRing->cf, C);
3219 number ninv= nMap (n,C->extRing->cf, C);
3220 p=__p_Mult_nn (p, ninv, r);
3221 n_Delete (&ninv, C);
3222 n_Delete (&n, C->extRing->cf);
3223 }
3224 }
3225 p= ph;
3226 }
3227
3228 return;
3229}
3230
3231#if 0 /*unused*/
3232number p_GetAllDenom(poly ph, const ring r)
3233{
3234 number d=n_Init(1,r->cf);
3235 poly p = ph;
3236
3237 while (p!=NULL)
3238 {
3239 number h=n_GetDenom(pGetCoeff(p),r->cf);
3240 if (!n_IsOne(h,r->cf))
3241 {
3242 number dd=n_Mult(d,h,r->cf);
3243 n_Delete(&d,r->cf);
3244 d=dd;
3245 }
3246 n_Delete(&h,r->cf);
3247 pIter(p);
3248 }
3249 return d;
3250}
3251#endif
3252
3253int p_Size(poly p, const ring r)
3254{
3255 int count = 0;
3256 if (r->cf->has_simple_Alloc)
3257 return pLength(p);
3258 while ( p != NULL )
3259 {
3260 count+= n_Size( pGetCoeff( p ), r->cf );
3261 pIter( p );
3262 }
3263 return count;
3264}
3265
3266/*2
3267*make p homogeneous by multiplying the monomials by powers of x_varnum
3268*assume: deg(var(varnum))==1
3269*/
3270poly p_Homogen (poly p, int varnum, const ring r)
3271{
3272 pFDegProc deg;
3273 if (r->pLexOrder && (r->order[0]==ringorder_lp))
3274 deg=p_Totaldegree;
3275 else
3276 deg=r->pFDeg;
3277
3278 poly q=NULL, qn;
3279 int o,ii;
3280 sBucket_pt bp;
3281
3282 if (p!=NULL)
3283 {
3284 if ((varnum < 1) || (varnum > rVar(r)))
3285 {
3286 return NULL;
3287 }
3288 o=deg(p,r);
3289 q=pNext(p);
3290 while (q != NULL)
3291 {
3292 ii=deg(q,r);
3293 if (ii>o) o=ii;
3294 pIter(q);
3295 }
3296 q = p_Copy(p,r);
3297 bp = sBucketCreate(r);
3298 while (q != NULL)
3299 {
3300 ii = o-deg(q,r);
3301 if (ii!=0)
3302 {
3303 p_AddExp(q,varnum, (long)ii,r);
3304 p_Setm(q,r);
3305 }
3306 qn = pNext(q);
3307 pNext(q) = NULL;
3308 sBucket_Add_m(bp, q);
3309 q = qn;
3310 }
3311 sBucketDestroyAdd(bp, &q, &ii);
3312 }
3313 return q;
3314}
3315
3316/*2
3317*tests if p is homogeneous with respect to the actual weigths
3318*/
3319BOOLEAN p_IsHomogeneous (poly p, const ring r)
3320{
3321 poly qp=p;
3322 int o;
3323
3324 if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
3325 pFDegProc d;
3326 if (r->pLexOrder && (r->order[0]==ringorder_lp))
3327 d=p_Totaldegree;
3328 else
3329 d=r->pFDeg;
3330 o = d(p,r);
3331 do
3332 {
3333 if (d(qp,r) != o) return FALSE;
3334 pIter(qp);
3335 }
3336 while (qp != NULL);
3337 return TRUE;
3338}
3339
3340/*2
3341*tests if p is homogeneous with respect to the given weigths
3342*/
3343BOOLEAN p_IsHomogeneousW (poly p, const intvec *w, const ring r)
3344{
3345 poly qp=p;
3346 long o;
3347
3348 if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
3349 pIter(qp);
3350 o = totaldegreeWecart_IV(p,r,w->ivGetVec());
3351 do
3352 {
3353 if (totaldegreeWecart_IV(qp,r,w->ivGetVec()) != o) return FALSE;
3354 pIter(qp);
3355 }
3356 while (qp != NULL);
3357 return TRUE;
3358}
3359
3360BOOLEAN p_IsHomogeneousW (poly p, const intvec *w, const intvec *module_w, const ring r)
3361{
3362 poly qp=p;
3363 long o;
3364
3365 if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
3366 pIter(qp);
3367 o = totaldegreeWecart_IV(p,r,w->ivGetVec())+(*module_w)[p_GetComp(p,r)];
3368 do
3369 {
3370 long oo=totaldegreeWecart_IV(qp,r,w->ivGetVec())+(*module_w)[p_GetComp(qp,r)];
3371 if (oo != o) return FALSE;
3372 pIter(qp);
3373 }
3374 while (qp != NULL);
3375 return TRUE;
3376}
3377
3378/*----------utilities for syzygies--------------*/
3379BOOLEAN p_VectorHasUnitB(poly p, int * k, const ring r)
3380{
3381 poly q=p,qq;
3382 long unsigned i;
3383
3384 while (q!=NULL)
3385 {
3386 if (p_LmIsConstantComp(q,r))
3387 {
3388 i = __p_GetComp(q,r);
3389 qq = p;
3390 while ((qq != q) && (__p_GetComp(qq,r) != i)) pIter(qq);
3391 if (qq == q)
3392 {
3393 *k = i;
3394 return TRUE;
3395 }
3396 }
3397 pIter(q);
3398 }
3399 return FALSE;
3400}
3401
3402void p_VectorHasUnit(poly p, int * k, int * len, const ring r)
3403{
3404 poly q=p,qq;
3405 int j=0;
3406 long unsigned i;
3407
3408 *len = 0;
3409 while (q!=NULL)
3410 {
3411 if (p_LmIsConstantComp(q,r))
3412 {
3413 i = __p_GetComp(q,r);
3414 qq = p;
3415 while ((qq != q) && (__p_GetComp(qq,r) != i)) pIter(qq);
3416 if (qq == q)
3417 {
3418 j = 0;
3419 while (qq!=NULL)
3420 {
3421 if (__p_GetComp(qq,r)==i) j++;
3422 pIter(qq);
3423 }
3424 if ((*len == 0) || (j<*len))
3425 {
3426 *len = j;
3427 *k = i;
3428 }
3429 }
3430 }
3431 pIter(q);
3432 }
3433}
3434
3435poly p_TakeOutComp(poly * p, int k, const ring r)
3436{
3437 poly q = *p,qq=NULL,result = NULL;
3438
3439 if (q==NULL) return NULL;
3440 BOOLEAN use_setmcomp=rOrd_SetCompRequiresSetm(r);
3441 if (__p_GetComp(q,r)==k)
3442 {
3443 result = q;
3444 do
3445 {
3446 p_SetComp(q,0,r);
3447 if (use_setmcomp) p_SetmComp(q,r);
3448 qq = q;
3449 pIter(q);
3450 }
3451 while ((q!=NULL) && (__p_GetComp(q,r)==k));
3452 *p = q;
3453 pNext(qq) = NULL;
3454 }
3455 if (q==NULL) return result;
3456 if (__p_GetComp(q,r) > k)
3457 {
3458 p_SubComp(q,1,r);
3459 if (use_setmcomp) p_SetmComp(q,r);
3460 }
3461 poly pNext_q;
3462 while ((pNext_q=pNext(q))!=NULL)
3463 {
3464 if (__p_GetComp(pNext_q,r)==k)
3465 {
3466 if (result==NULL)
3467 {
3468 result = pNext_q;
3469 qq = result;
3470 }
3471 else
3472 {
3473 pNext(qq) = pNext_q;
3474 pIter(qq);
3475 }
3476 pNext(q) = pNext(pNext_q);
3477 pNext(qq) =NULL;
3478 p_SetComp(qq,0,r);
3479 if (use_setmcomp) p_SetmComp(qq,r);
3480 }
3481 else
3482 {
3483 /*pIter(q);*/ q=pNext_q;
3484 if (__p_GetComp(q,r) > k)
3485 {
3486 p_SubComp(q,1,r);
3487 if (use_setmcomp) p_SetmComp(q,r);
3488 }
3489 }
3490 }
3491 return result;
3492}
3493
3494// Splits *p into two polys: *q which consists of all monoms with
3495// component == comp and *p of all other monoms *lq == pLength(*q)
3496void p_TakeOutComp(poly *r_p, long comp, poly *r_q, int *lq, const ring r)
3497{
3498 spolyrec pp, qq;
3499 poly p, q, p_prev;
3500 int l = 0;
3501
3502#ifndef SING_NDEBUG
3503 int lp = pLength(*r_p);
3504#endif
3505
3506 pNext(&pp) = *r_p;
3507 p = *r_p;
3508 p_prev = &pp;
3509 q = &qq;
3510
3511 while(p != NULL)
3512 {
3513 while (__p_GetComp(p,r) == comp)
3514 {
3515 pNext(q) = p;
3516 pIter(q);
3517 p_SetComp(p, 0,r);
3518 p_SetmComp(p,r);
3519 pIter(p);
3520 l++;
3521 if (p == NULL)
3522 {
3523 pNext(p_prev) = NULL;
3524 goto Finish;
3525 }
3526 }
3527 pNext(p_prev) = p;
3528 p_prev = p;
3529 pIter(p);
3530 }
3531
3532 Finish:
3533 pNext(q) = NULL;
3534 *r_p = pNext(&pp);
3535 *r_q = pNext(&qq);
3536 *lq = l;
3537#ifndef SING_NDEBUG
3538 assume(pLength(*r_p) + pLength(*r_q) == (unsigned)lp);
3539#endif
3540 p_Test(*r_p,r);
3541 p_Test(*r_q,r);
3542}
3543
3544void p_DeleteComp(poly * p,int k, const ring r)
3545{
3546 poly q;
3547 long unsigned kk=k;
3548
3549 while ((*p!=NULL) && (__p_GetComp(*p,r)==kk)) p_LmDelete(p,r);
3550 if (*p==NULL) return;
3551 q = *p;
3552 if (__p_GetComp(q,r)>kk)
3553 {
3554 p_SubComp(q,1,r);
3555 p_SetmComp(q,r);
3556 }
3557 while (pNext(q)!=NULL)
3558 {
3559 if (__p_GetComp(pNext(q),r)==kk)
3560 p_LmDelete(&(pNext(q)),r);
3561 else
3562 {
3563 pIter(q);
3564 if (__p_GetComp(q,r)>kk)
3565 {
3566 p_SubComp(q,1,r);
3567 p_SetmComp(q,r);
3568 }
3569 }
3570 }
3571}
3572
3573poly p_Vec2Poly(poly v, int k, const ring r)
3574{
3575 poly h;
3576 poly res=NULL;
3577 long unsigned kk=k;
3578
3579 while (v!=NULL)
3580 {
3581 if (__p_GetComp(v,r)==kk)
3582 {
3583 h=p_Head(v,r);
3584 p_SetComp(h,0,r);
3585 pNext(h)=res;res=h;
3586 }
3587 pIter(v);
3588 }
3589 if (res!=NULL) res=pReverse(res);
3590 return res;
3591}
3592
3593/// vector to already allocated array (len>=p_MaxComp(v,r))
3594// also used for p_Vec2Polys
3595void p_Vec2Array(poly v, poly *p, int len, const ring r)
3596{
3597 poly h;
3598 int k;
3599
3600 for(int i=len-1;i>=0;i--) p[i]=NULL;
3601 while (v!=NULL)
3602 {
3603 h=p_Head(v,r);
3604 k=__p_GetComp(h,r);
3605 if (k>len) { Werror("wrong rank:%d, should be %d",len,k); }
3606 else
3607 {
3608 p_SetComp(h,0,r);
3609 p_Setm(h,r);
3610 pNext(h)=p[k-1];p[k-1]=h;
3611 }
3612 pIter(v);
3613 }
3614 for(int i=len-1;i>=0;i--)
3615 {
3616 if (p[i]!=NULL) p[i]=pReverse(p[i]);
3617 }
3618}
3619
3620/*2
3621* convert a vector to a set of polys,
3622* allocates the polyset, (entries 0..(*len)-1)
3623* the vector will not be changed
3624*/
3625void p_Vec2Polys(poly v, poly* *p, int *len, const ring r)
3626{
3627 *len=p_MaxComp(v,r);
3628 if (*len==0) *len=1;
3629 *p=(poly*)omAlloc((*len)*sizeof(poly));
3630 p_Vec2Array(v,*p,*len,r);
3631}
3632
3633//
3634// resets the pFDeg and pLDeg: if pLDeg is not given, it is
3635// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
3636// only uses pFDeg (and not p_Deg, or pTotalDegree, etc)
3637void pSetDegProcs(ring r, pFDegProc new_FDeg, pLDegProc new_lDeg)
3638{
3639 assume(new_FDeg != NULL);
3640 r->pFDeg = new_FDeg;
3641
3642 if (new_lDeg == NULL)
3643 new_lDeg = r->pLDegOrig;
3644
3645 r->pLDeg = new_lDeg;
3646}
3647
3648// restores pFDeg and pLDeg:
3649void pRestoreDegProcs(ring r, pFDegProc old_FDeg, pLDegProc old_lDeg)
3650{
3651 assume(old_FDeg != NULL && old_lDeg != NULL);
3652 r->pFDeg = old_FDeg;
3653 r->pLDeg = old_lDeg;
3654}
3655
3656/*-------- several access procedures to monomials -------------------- */
3657/*
3658* the module weights for std
3659*/
3663
3664static long pModDeg(poly p, ring r)
3665{
3666 long d=pOldFDeg(p, r);
3667 int c=__p_GetComp(p, r);
3668 if ((c>0) && ((r->pModW)->range(c-1))) d+= (*(r->pModW))[c-1];
3669 return d;
3670 //return pOldFDeg(p, r)+(*pModW)[p_GetComp(p, r)-1];
3671}
3672
3673void p_SetModDeg(intvec *w, ring r)
3674{
3675 if (w!=NULL)
3676 {
3677 r->pModW = w;
3678 pOldFDeg = r->pFDeg;
3679 pOldLDeg = r->pLDeg;
3680 pOldLexOrder = r->pLexOrder;
3682 r->pLexOrder = TRUE;
3683 }
3684 else
3685 {
3686 r->pModW = NULL;
3688 r->pLexOrder = pOldLexOrder;
3689 }
3690}
3691
3692/*2
3693* handle memory request for sets of polynomials (ideals)
3694* l is the length of *p, increment is the difference (may be negative)
3695*/
3696void pEnlargeSet(poly* *p, int l, int increment)
3697{
3698 poly* h;
3699
3700 if (increment==0) return;
3701 if (*p==NULL)
3702 {
3703 h=(poly*)omAlloc0(increment*sizeof(poly));
3704 }
3705 else
3706 {
3707 h=(poly*)omReallocSize((poly*)*p,l*sizeof(poly),(l+increment)*sizeof(poly));
3708 if (increment>0)
3709 {
3710 memset(&(h[l]),0,increment*sizeof(poly));
3711 }
3712 }
3713 *p=h;
3714}
3715
3716/*2
3717*divides p1 by its leading coefficient
3718*/
3719void p_Norm(poly p1, const ring r)
3720{
3721 if (LIKELY(rField_is_Ring(r)))
3722 {
3723 if(!n_GreaterZero(pGetCoeff(p1),r->cf)) p1 = p_Neg(p1,r);
3724 if (!n_IsUnit(pGetCoeff(p1), r->cf)) return;
3725 // Werror("p_Norm not possible in the case of coefficient rings.");
3726 }
3727 else if (LIKELY(p1!=NULL))
3728 {
3729 if (UNLIKELY(pNext(p1)==NULL))
3730 {
3731 p_SetCoeff(p1,n_Init(1,r->cf),r);
3732 return;
3733 }
3734 if (!n_IsOne(pGetCoeff(p1),r->cf))
3735 {
3736 number k = pGetCoeff(p1);
3737 pSetCoeff0(p1,n_Init(1,r->cf));
3738 poly h = pNext(p1);
3739 if (LIKELY(rField_is_Zp(r)))
3740 {
3741 if (r->cf->ch>32003)
3742 {
3743 number inv=n_Invers(k,r->cf);
3744 while (h!=NULL)
3745 {
3746 number c=n_Mult(pGetCoeff(h),inv,r->cf);
3747 // no need to normalize
3748 p_SetCoeff(h,c,r);
3749 pIter(h);
3750 }
3751 // no need for n_Delete for Zp: n_Delete(&inv,r->cf);
3752 }
3753 else
3754 {
3755 while (h!=NULL)
3756 {
3757 number c=n_Div(pGetCoeff(h),k,r->cf);
3758 // no need to normalize
3759 p_SetCoeff(h,c,r);
3760 pIter(h);
3761 }
3762 }
3763 }
3764 else if(getCoeffType(r->cf)==n_algExt)
3765 {
3766 n_Normalize(k,r->cf);
3767 number inv=n_Invers(k,r->cf);
3768 while (h!=NULL)
3769 {
3770 number c=n_Mult(pGetCoeff(h),inv,r->cf);
3771 // no need to normalize
3772 // normalize already in nMult: Zp_a, Q_a
3773 p_SetCoeff(h,c,r);
3774 pIter(h);
3775 }
3776 n_Delete(&inv,r->cf);
3777 n_Delete(&k,r->cf);
3778 }
3779 else
3780 {
3781 n_Normalize(k,r->cf);
3782 while (h!=NULL)
3783 {
3784 number c=n_Div(pGetCoeff(h),k,r->cf);
3785 // no need to normalize: Z/p, R
3786 // remains: Q
3787 if (rField_is_Q(r)) n_Normalize(c,r->cf);
3788 p_SetCoeff(h,c,r);
3789 pIter(h);
3790 }
3791 n_Delete(&k,r->cf);
3792 }
3793 }
3794 else
3795 {
3796 //if (r->cf->cfNormalize != nDummy2) //TODO: OPTIMIZE
3797 if (rField_is_Q(r))
3798 {
3799 poly h = pNext(p1);
3800 while (h!=NULL)
3801 {
3802 n_Normalize(pGetCoeff(h),r->cf);
3803 pIter(h);
3804 }
3805 }
3806 }
3807 }
3808}
3809
3810/*2
3811*normalize all coefficients
3812*/
3813void p_Normalize(poly p,const ring r)
3814{
3815 const coeffs cf=r->cf;
3816 /* Z/p, GF(p,n), R, long R/C, Nemo rings */
3817 if (cf->cfNormalize==ndNormalize)
3818 return;
3819 while (p!=NULL)
3820 {
3821 // no test befor n_Normalize: n_Normalize should fix problems
3823 pIter(p);
3824 }
3825}
3826
3827// splits p into polys with Exp(n) == 0 and Exp(n) != 0
3828// Poly with Exp(n) != 0 is reversed
3829static void p_SplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero, const ring r)
3830{
3831 if (p == NULL)
3832 {
3833 *non_zero = NULL;
3834 *zero = NULL;
3835 return;
3836 }
3837 spolyrec sz;
3838 poly z, n_z, next;
3839 z = &sz;
3840 n_z = NULL;
3841
3842 while(p != NULL)
3843 {
3844 next = pNext(p);
3845 if (p_GetExp(p, n,r) == 0)
3846 {
3847 pNext(z) = p;
3848 pIter(z);
3849 }
3850 else
3851 {
3852 pNext(p) = n_z;
3853 n_z = p;
3854 }
3855 p = next;
3856 }
3857 pNext(z) = NULL;
3858 *zero = pNext(&sz);
3859 *non_zero = n_z;
3860}
3861/*3
3862* substitute the n-th variable by 1 in p
3863* destroy p
3864*/
3865static poly p_Subst1 (poly p,int n, const ring r)
3866{
3867 poly qq=NULL, result = NULL;
3868 poly zero=NULL, non_zero=NULL;
3869
3870 // reverse, so that add is likely to be linear
3871 p_SplitAndReversePoly(p, n, &non_zero, &zero,r);
3872
3873 while (non_zero != NULL)
3874 {
3875 assume(p_GetExp(non_zero, n,r) != 0);
3876 qq = non_zero;
3877 pIter(non_zero);
3878 qq->next = NULL;
3879 p_SetExp(qq,n,0,r);
3880 p_Setm(qq,r);
3881 result = p_Add_q(result,qq,r);
3882 }
3883 p = p_Add_q(result, zero,r);
3884 p_Test(p,r);
3885 return p;
3886}
3887
3888/*3
3889* substitute the n-th variable by number e in p
3890* destroy p
3891*/
3892static poly p_Subst2 (poly p,int n, number e, const ring r)
3893{
3894 assume( ! n_IsZero(e,r->cf) );
3895 poly qq,result = NULL;
3896 number nn, nm;
3897 poly zero, non_zero;
3898
3899 // reverse, so that add is likely to be linear
3900 p_SplitAndReversePoly(p, n, &non_zero, &zero,r);
3901
3902 while (non_zero != NULL)
3903 {
3904 assume(p_GetExp(non_zero, n, r) != 0);
3905 qq = non_zero;
3906 pIter(non_zero);
3907 qq->next = NULL;
3908 n_Power(e, p_GetExp(qq, n, r), &nn,r->cf);
3909 nm = n_Mult(nn, pGetCoeff(qq),r->cf);
3910#ifdef HAVE_RINGS
3911 if (n_IsZero(nm,r->cf))
3912 {
3913 p_LmFree(&qq,r);
3914 n_Delete(&nm,r->cf);
3915 }
3916 else
3917#endif
3918 {
3919 p_SetCoeff(qq, nm,r);
3920 p_SetExp(qq, n, 0,r);
3921 p_Setm(qq,r);
3922 result = p_Add_q(result,qq,r);
3923 }
3924 n_Delete(&nn,r->cf);
3925 }
3926 p = p_Add_q(result, zero,r);
3927 p_Test(p,r);
3928 return p;
3929}
3930
3931
3932/* delete monoms whose n-th exponent is different from zero */
3933static poly p_Subst0(poly p, int n, const ring r)
3934{
3935 spolyrec res;
3936 poly h = &res;
3937 pNext(h) = p;
3938
3939 while (pNext(h)!=NULL)
3940 {
3941 if (p_GetExp(pNext(h),n,r)!=0)
3942 {
3943 p_LmDelete(&pNext(h),r);
3944 }
3945 else
3946 {
3947 pIter(h);
3948 }
3949 }
3950 p_Test(pNext(&res),r);
3951 return pNext(&res);
3952}
3953
3954/*2
3955* substitute the n-th variable by e in p
3956* destroy p
3957*/
3958poly p_Subst(poly p, int n, poly e, const ring r)
3959{
3960#ifdef HAVE_SHIFTBBA
3961 // also don't even use p_Subst0 for Letterplace
3962 if (rIsLPRing(r))
3963 {
3964 poly subst = p_LPSubst(p, n, e, r);
3965 p_Delete(&p, r);
3966 return subst;
3967 }
3968#endif
3969
3970 if (e == NULL) return p_Subst0(p, n,r);
3971
3972 if (p_IsConstant(e,r))
3973 {
3974 if (n_IsOne(pGetCoeff(e),r->cf)) return p_Subst1(p,n,r);
3975 else return p_Subst2(p, n, pGetCoeff(e),r);
3976 }
3977
3978#ifdef HAVE_PLURAL
3979 if (rIsPluralRing(r))
3980 {
3981 return nc_pSubst(p,n,e,r);
3982 }
3983#endif
3984
3985 int exponent,i;
3986 poly h, res, m;
3987 int *me,*ee;
3988 number nu,nu1;
3989
3990 me=(int *)omAlloc((rVar(r)+1)*sizeof(int));
3991 ee=(int *)omAlloc((rVar(r)+1)*sizeof(int));
3992 if (e!=NULL) p_GetExpV(e,ee,r);
3993 res=NULL;
3994 h=p;
3995 while (h!=NULL)
3996 {
3997 if ((e!=NULL) || (p_GetExp(h,n,r)==0))
3998 {
3999 m=p_Head(h,r);
4000 p_GetExpV(m,me,r);
4001 exponent=me[n];
4002 me[n]=0;
4003 for(i=rVar(r);i>0;i--)
4004 me[i]+=exponent*ee[i];
4005 p_SetExpV(m,me,r);
4006 if (e!=NULL)
4007 {
4008 n_Power(pGetCoeff(e),exponent,&nu,r->cf);
4009 nu1=n_Mult(pGetCoeff(m),nu,r->cf);
4010 n_Delete(&nu,r->cf);
4011 p_SetCoeff(m,nu1,r);
4012 }
4013 res=p_Add_q(res,m,r);
4014 }
4015 p_LmDelete(&h,r);
4016 }
4017 omFreeSize((ADDRESS)me,(rVar(r)+1)*sizeof(int));
4018 omFreeSize((ADDRESS)ee,(rVar(r)+1)*sizeof(int));
4019 return res;
4020}
4021
4022/*2
4023 * returns a re-ordered convertion of a number as a polynomial,
4024 * with permutation of parameters
4025 * NOTE: this only works for Frank's alg. & trans. fields
4026 */
4027poly n_PermNumber(const number z, const int *par_perm, const int , const ring src, const ring dst)
4028{
4029#if 0
4030 PrintS("\nSource Ring: \n");
4031 rWrite(src);
4032
4033 if(0)
4034 {
4035 number zz = n_Copy(z, src->cf);
4036 PrintS("z: "); n_Write(zz, src);
4037 n_Delete(&zz, src->cf);
4038 }
4039
4040 PrintS("\nDestination Ring: \n");
4041 rWrite(dst);
4042
4043 /*Print("\nOldPar: %d\n", OldPar);
4044 for( int i = 1; i <= OldPar; i++ )
4045 {
4046 Print("par(%d) -> par/var (%d)\n", i, par_perm[i-1]);
4047 }*/
4048#endif
4049 if( z == NULL )
4050 return NULL;
4051
4052 const coeffs srcCf = src->cf;
4053 assume( srcCf != NULL );
4054
4055 assume( !nCoeff_is_GF(srcCf) );
4056 assume( src->cf->extRing!=NULL );
4057
4058 poly zz = NULL;
4059
4060 const ring srcExtRing = srcCf->extRing;
4061 assume( srcExtRing != NULL );
4062
4063 const coeffs dstCf = dst->cf;
4064 assume( dstCf != NULL );
4065
4066 if( nCoeff_is_algExt(srcCf) ) // nCoeff_is_GF(srcCf)?
4067 {
4068 zz = (poly) z;
4069 if( zz == NULL ) return NULL;
4070 }
4071 else if (nCoeff_is_transExt(srcCf))
4072 {
4073 assume( !IS0(z) );
4074
4075 zz = NUM((fraction)z);
4076 p_Test (zz, srcExtRing);
4077
4078 if( zz == NULL ) return NULL;
4079 if( !DENIS1((fraction)z) )
4080 {
4081 if (!p_IsConstant(DEN((fraction)z),srcExtRing))
4082 WarnS("Not defined: Cannot map a rational fraction and make a polynomial out of it! Ignoring the denominator.");
4083 }
4084 }
4085 else
4086 {
4087 assume (FALSE);
4088 WerrorS("Number permutation is not implemented for this data yet!");
4089 return NULL;
4090 }
4091
4092 assume( zz != NULL );
4093 p_Test (zz, srcExtRing);
4094
4095 nMapFunc nMap = n_SetMap(srcExtRing->cf, dstCf);
4096
4097 assume( nMap != NULL );
4098
4099 poly qq;
4100 if ((par_perm == NULL) && (rPar(dst) != 0 && rVar (srcExtRing) > 0))
4101 {
4102 int* perm;
4103 perm=(int *)omAlloc0((rVar(srcExtRing)+1)*sizeof(int));
4104 for(int i=si_min(rVar(srcExtRing),rPar(dst));i>0;i--)
4105 perm[i]=-i;
4106 qq = p_PermPoly(zz, perm, srcExtRing, dst, nMap, NULL, rVar(srcExtRing)-1);
4107 omFreeSize ((ADDRESS)perm, (rVar(srcExtRing)+1)*sizeof(int));
4108 }
4109 else
4110 qq = p_PermPoly(zz, par_perm-1, srcExtRing, dst, nMap, NULL, rVar (srcExtRing)-1);
4111
4112 if(nCoeff_is_transExt(srcCf)
4113 && (!DENIS1((fraction)z))
4114 && p_IsConstant(DEN((fraction)z),srcExtRing))
4115 {
4116 number n=nMap(pGetCoeff(DEN((fraction)z)),srcExtRing->cf, dstCf);
4117 qq=p_Div_nn(qq,n,dst);
4118 n_Delete(&n,dstCf);
4119 p_Normalize(qq,dst);
4120 }
4121 p_Test (qq, dst);
4122
4123 return qq;
4124}
4125
4126
4127/*2
4128*returns a re-ordered copy of a polynomial, with permutation of the variables
4129*/
4130poly p_PermPoly (poly p, const int * perm, const ring oldRing, const ring dst,
4131 nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
4132{
4133#if 0
4134 p_Test(p, oldRing);
4135 PrintS("p_PermPoly::p: "); p_Write(p, oldRing, oldRing);
4136#endif
4137 const int OldpVariables = rVar(oldRing);
4138 poly result = NULL;
4139 poly result_last = NULL;
4140 poly aq = NULL; /* the map coefficient */
4141 poly qq; /* the mapped monomial */
4142 assume(dst != NULL);
4143 assume(dst->cf != NULL);
4144 #ifdef HAVE_PLURAL
4145 poly tmp_mm=p_One(dst);
4146 #endif
4147 while (p != NULL)
4148 {
4149 // map the coefficient
4150 if ( ((OldPar == 0) || (par_perm == NULL) || rField_is_GF(oldRing) || (nMap==ndCopyMap))
4151 && (nMap != NULL) )
4152 {
4153 qq = p_Init(dst);
4154 assume( nMap != NULL );
4155 number n = nMap(p_GetCoeff(p, oldRing), oldRing->cf, dst->cf);
4156 n_Test (n,dst->cf);
4157 if ( nCoeff_is_algExt(dst->cf) )
4158 n_Normalize(n, dst->cf);
4159 p_GetCoeff(qq, dst) = n;// Note: n can be a ZERO!!!
4160 }
4161 else
4162 {
4163 qq = p_One(dst);
4164// aq = naPermNumber(p_GetCoeff(p, oldRing), par_perm, OldPar, oldRing); // no dst???
4165// poly n_PermNumber(const number z, const int *par_perm, const int P, const ring src, const ring dst)
4166 aq = n_PermNumber(p_GetCoeff(p, oldRing), par_perm, OldPar, oldRing, dst);
4167 p_Test(aq, dst);
4168 if ( nCoeff_is_algExt(dst->cf) )
4169 p_Normalize(aq,dst);
4170 if (aq == NULL)
4171 p_SetCoeff(qq, n_Init(0, dst->cf),dst); // Very dirty trick!!!
4172 p_Test(aq, dst);
4173 }
4174 if (rRing_has_Comp(dst))
4175 p_SetComp(qq, p_GetComp(p, oldRing), dst);
4176 if ( n_IsZero(pGetCoeff(qq), dst->cf) )
4177 {
4178 p_LmDelete(&qq,dst);
4179 qq = NULL;
4180 }
4181 else
4182 {
4183 // map pars:
4184 int mapped_to_par = 0;
4185 for(int i = 1; i <= OldpVariables; i++)
4186 {
4187 int e = p_GetExp(p, i, oldRing);
4188 if (e != 0)
4189 {
4190 if (perm==NULL)
4191 p_SetExp(qq, i, e, dst);
4192 else if (perm[i]>0)
4193 {
4194 #ifdef HAVE_PLURAL
4195 if(use_mult)
4196 {
4197 p_SetExp(tmp_mm,perm[i],e,dst);
4198 p_Setm(tmp_mm,dst);
4199 qq=p_Mult_mm(qq,tmp_mm,dst);
4200 p_SetExp(tmp_mm,perm[i],0,dst);
4201
4202 }
4203 else
4204 #endif
4205 p_AddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/, dst);
4206 }
4207 else if (perm[i]<0)
4208 {
4209 number c = p_GetCoeff(qq, dst);
4210 if (rField_is_GF(dst))
4211 {
4212 assume( dst->cf->extRing == NULL );
4213 number ee = n_Param(1, dst);
4214 number eee;
4215 n_Power(ee, e, &eee, dst->cf); //nfDelete(ee,dst);
4216 ee = n_Mult(c, eee, dst->cf);
4217 //nfDelete(c,dst);nfDelete(eee,dst);
4218 pSetCoeff0(qq,ee);
4219 }
4220 else if (nCoeff_is_Extension(dst->cf))
4221 {
4222 const int par = -perm[i];
4223 assume( par > 0 );
4224// WarnS("longalg missing 3");
4225#if 1
4226 const coeffs C = dst->cf;
4227 assume( C != NULL );
4228 const ring R = C->extRing;
4229 assume( R != NULL );
4230 assume( par <= rVar(R) );
4231 poly pcn; // = (number)c
4232 assume( !n_IsZero(c, C) );
4233 if( nCoeff_is_algExt(C) )
4234 pcn = (poly) c;
4235 else // nCoeff_is_transExt(C)
4236 pcn = NUM((fraction)c);
4237 if (pNext(pcn) == NULL) // c->z
4238 p_AddExp(pcn, -perm[i], e, R);
4239 else /* more difficult: we have really to multiply: */
4240 {
4241 poly mmc = p_ISet(1, R);
4242 p_SetExp(mmc, -perm[i], e, R);
4243 p_Setm(mmc, R);
4244 number nnc;
4245 // convert back to a number: number nnc = mmc;
4246 if( nCoeff_is_algExt(C) )
4247 nnc = (number) mmc;
4248 else // nCoeff_is_transExt(C)
4249 nnc = ntInit(mmc, C);
4250 p_GetCoeff(qq, dst) = n_Mult((number)c, nnc, C);
4251 n_Delete((number *)&c, C);
4252 n_Delete((number *)&nnc, C);
4253 }
4254 mapped_to_par=1;
4255#endif
4256 }
4257 }
4258 else
4259 {
4260 /* this variable maps to 0 !*/
4261 p_LmDelete(&qq, dst);
4262 break;
4263 }
4264 }
4265 }
4266 if ( mapped_to_par && (qq!= NULL) && nCoeff_is_algExt(dst->cf) )
4267 {
4268 number n = p_GetCoeff(qq, dst);
4269 n_Normalize(n, dst->cf);
4270 p_GetCoeff(qq, dst) = n;
4271 }
4272 }
4273 pIter(p);
4274
4275#if 0
4276 p_Test(aq,dst);
4277 PrintS("aq: "); p_Write(aq, dst, dst);
4278#endif
4279
4280
4281#if 1
4282 if (qq!=NULL)
4283 {
4284 p_Setm(qq,dst);
4285
4286 p_Test(aq,dst);
4287 p_Test(qq,dst);
4288
4289#if 0
4290 PrintS("qq: "); p_Write(qq, dst, dst);
4291#endif
4292
4293 if (aq!=NULL)
4294 qq=p_Mult_q(aq,qq,dst);
4295 aq = qq;
4296 while (pNext(aq) != NULL) pIter(aq);
4297 if (result_last==NULL)
4298 {
4299 result=qq;
4300 }
4301 else
4302 {
4303 pNext(result_last)=qq;
4304 }
4305 result_last=aq;
4306 aq = NULL;
4307 }
4308 else if (aq!=NULL)
4309 {
4310 p_Delete(&aq,dst);
4311 }
4312 }
4313 result=p_SortAdd(result,dst);
4314#else
4315 // if (qq!=NULL)
4316 // {
4317 // pSetm(qq);
4318 // pTest(qq);
4319 // pTest(aq);
4320 // if (aq!=NULL) qq=pMult(aq,qq);
4321 // aq = qq;
4322 // while (pNext(aq) != NULL) pIter(aq);
4323 // pNext(aq) = result;
4324 // aq = NULL;
4325 // result = qq;
4326 // }
4327 // else if (aq!=NULL)
4328 // {
4329 // pDelete(&aq);
4330 // }
4331 //}
4332 //p = result;
4333 //result = NULL;
4334 //while (p != NULL)
4335 //{
4336 // qq = p;
4337 // pIter(p);
4338 // qq->next = NULL;
4339 // result = pAdd(result, qq);
4340 //}
4341#endif
4342 p_Test(result,dst);
4343#if 0
4344 p_Test(result,dst);
4345 PrintS("result: "); p_Write(result,dst,dst);
4346#endif
4347 #ifdef HAVE_PLURAL
4348 p_LmDelete(&tmp_mm,dst);
4349 #endif
4350 return result;
4351}
4352/**************************************************************
4353 *
4354 * Jet
4355 *
4356 **************************************************************/
4357
4358poly pp_Jet(poly p, int m, const ring R)
4359{
4360 poly r=NULL;
4361 poly t=NULL;
4362
4363 while (p!=NULL)
4364 {
4365 if (p_Totaldegree(p,R)<=m)
4366 {
4367 if (r==NULL)
4368 r=p_Head(p,R);
4369 else
4370 if (t==NULL)
4371 {
4372 pNext(r)=p_Head(p,R);
4373 t=pNext(r);
4374 }
4375 else
4376 {
4377 pNext(t)=p_Head(p,R);
4378 pIter(t);
4379 }
4380 }
4381 pIter(p);
4382 }
4383 return r;
4384}
4385
4386poly p_Jet(poly p, int m,const ring R)
4387{
4388 while((p!=NULL) && (p_Totaldegree(p,R)>m)) p_LmDelete(&p,R);
4389 if (p==NULL) return NULL;
4390 poly r=p;
4391 while (pNext(p)!=NULL)
4392 {
4393 if (p_Totaldegree(pNext(p),R)>m)
4394 {
4395 p_LmDelete(&pNext(p),R);
4396 }
4397 else
4398 pIter(p);
4399 }
4400 return r;
4401}
4402
4403poly pp_JetW(poly p, int m, int *w, const ring R)
4404{
4405 poly r=NULL;
4406 poly t=NULL;
4407 while (p!=NULL)
4408 {
4409 if (totaldegreeWecart_IV(p,R,w)<=m)
4410 {
4411 if (r==NULL)
4412 r=p_Head(p,R);
4413 else
4414 if (t==NULL)
4415 {
4416 pNext(r)=p_Head(p,R);
4417 t=pNext(r);
4418 }
4419 else
4420 {
4421 pNext(t)=p_Head(p,R);
4422 pIter(t);
4423 }
4424 }
4425 pIter(p);
4426 }
4427 return r;
4428}
4429
4430poly p_JetW(poly p, int m, int *w, const ring R)
4431{
4432 while((p!=NULL) && (totaldegreeWecart_IV(p,R,w)>m)) p_LmDelete(&p,R);
4433 if (p==NULL) return NULL;
4434 poly r=p;
4435 while (pNext(p)!=NULL)
4436 {
4438 {
4439 p_LmDelete(&pNext(p),R);
4440 }
4441 else
4442 pIter(p);
4443 }
4444 return r;
4445}
4446
4447/*************************************************************/
4448int p_MinDeg(poly p,intvec *w, const ring R)
4449{
4450 if(p==NULL)
4451 return -1;
4452 int d=-1;
4453 while(p!=NULL)
4454 {
4455 int d0=0;
4456 for(int j=0;j<rVar(R);j++)
4457 if(w==NULL||j>=w->length())
4458 d0+=p_GetExp(p,j+1,R);
4459 else
4460 d0+=(*w)[j]*p_GetExp(p,j+1,R);
4461 if(d0<d||d==-1)
4462 d=d0;
4463 pIter(p);
4464 }
4465 return d;
4466}
4467
4468/***************************************************************/
4469static poly p_Invers(int n,poly u,intvec *w, const ring R)
4470{
4471 if(n<0)
4472 return NULL;
4473 number u0=n_Invers(pGetCoeff(u),R->cf);
4474 poly v=p_NSet(u0,R);
4475 if(n==0)
4476 return v;
4477 int *ww=iv2array(w,R);
4478 poly u1=p_JetW(p_Sub(p_One(R),__p_Mult_nn(u,u0,R),R),n,ww,R);
4479 if(u1==NULL)
4480 {
4481 omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(int));
4482 return v;
4483 }
4484 poly v1=__p_Mult_nn(p_Copy(u1,R),u0,R);
4485 v=p_Add_q(v,p_Copy(v1,R),R);
4486 for(int i=n/p_MinDeg(u1,w,R);i>1;i--)
4487 {
4488 v1=p_JetW(p_Mult_q(v1,p_Copy(u1,R),R),n,ww,R);
4489 v=p_Add_q(v,p_Copy(v1,R),R);
4490 }
4491 p_Delete(&u1,R);
4492 p_Delete(&v1,R);
4493 omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(int));
4494 return v;
4495}
4496
4497
4498poly p_Series(int n,poly p,poly u, intvec *w, const ring R)
4499{
4500 int *ww=iv2array(w,R);
4501 if(p!=NULL)
4502 {
4503 if(u==NULL)
4504 p=p_JetW(p,n,ww,R);
4505 else
4506 p=p_JetW(p_Mult_q(p,p_Invers(n-p_MinDeg(p,w,R),u,w,R),R),n,ww,R);
4507 }
4508 omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(int));
4509 return p;
4510}
4511
4512BOOLEAN p_EqualPolys(poly p1,poly p2, const ring r)
4513{
4514 while ((p1 != NULL) && (p2 != NULL))
4515 {
4516 if (! p_LmEqual(p1, p2,r))
4517 return FALSE;
4518 if (! n_Equal(p_GetCoeff(p1,r), p_GetCoeff(p2,r),r->cf ))
4519 return FALSE;
4520 pIter(p1);
4521 pIter(p2);
4522 }
4523 return (p1==p2);
4524}
4525
4526static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r1, const ring r2)
4527{
4528 assume( r1 == r2 || rSamePolyRep(r1, r2) );
4529
4530 p_LmCheckPolyRing1(p1, r1);
4531 p_LmCheckPolyRing1(p2, r2);
4532
4533 int i = r1->ExpL_Size;
4534
4535 assume( r1->ExpL_Size == r2->ExpL_Size );
4536
4537 unsigned long *ep = p1->exp;
4538 unsigned long *eq = p2->exp;
4539
4540 do
4541 {
4542 i--;
4543 if (ep[i] != eq[i]) return FALSE;
4544 }
4545 while (i);
4546
4547 return TRUE;
4548}
4549
4550BOOLEAN p_EqualPolys(poly p1,poly p2, const ring r1, const ring r2)
4551{
4552 assume( r1 == r2 || rSamePolyRep(r1, r2) ); // will be used in rEqual!
4553 assume( r1->cf == r2->cf );
4554
4555 while ((p1 != NULL) && (p2 != NULL))
4556 {
4557 // returns 1 if ExpVector(p)==ExpVector(q): does not compare numbers !!
4558 // #define p_LmEqual(p1, p2, r) p_ExpVectorEqual(p1, p2, r)
4559
4560 if (! p_ExpVectorEqual(p1, p2, r1, r2))
4561 return FALSE;
4562
4563 if (! n_Equal(p_GetCoeff(p1,r1), p_GetCoeff(p2,r2), r1->cf ))
4564 return FALSE;
4565
4566 pIter(p1);
4567 pIter(p2);
4568 }
4569 return (p1==p2);
4570}
4571
4572/*2
4573*returns TRUE if p1 is a skalar multiple of p2
4574*assume p1 != NULL and p2 != NULL
4575*/
4576BOOLEAN p_ComparePolys(poly p1,poly p2, const ring r)
4577{
4578 number n,nn;
4579 pAssume(p1 != NULL && p2 != NULL);
4580
4581 if (!p_LmEqual(p1,p2,r)) //compare leading mons
4582 return FALSE;
4583 if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
4584 return FALSE;
4585 if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
4586 return FALSE;
4587 if (pLength(p1) != pLength(p2))
4588 return FALSE;
4589 #ifdef HAVE_RINGS
4590 if (rField_is_Ring(r))
4591 {
4592 if (!n_DivBy(pGetCoeff(p1), pGetCoeff(p2), r->cf)) return FALSE;
4593 }
4594 #endif
4595 n=n_Div(pGetCoeff(p1),pGetCoeff(p2),r->cf);
4596 while ((p1 != NULL) /*&& (p2 != NULL)*/)
4597 {
4598 if ( ! p_LmEqual(p1, p2,r))
4599 {
4600 n_Delete(&n, r->cf);
4601 return FALSE;
4602 }
4603 if (!n_Equal(pGetCoeff(p1), nn = n_Mult(pGetCoeff(p2),n, r->cf), r->cf))
4604 {
4605 n_Delete(&n, r->cf);
4606 n_Delete(&nn, r->cf);
4607 return FALSE;
4608 }
4609 n_Delete(&nn, r->cf);
4610 pIter(p1);
4611 pIter(p2);
4612 }
4613 n_Delete(&n, r->cf);
4614 return TRUE;
4615}
4616
4617/*2
4618* returns the length of a (numbers of monomials)
4619* respect syzComp
4620*/
4621poly p_Last(const poly p, int &l, const ring r)
4622{
4623 if (p == NULL)
4624 {
4625 l = 0;
4626 return NULL;
4627 }
4628 l = 1;
4629 poly a = p;
4630 if (! rIsSyzIndexRing(r))
4631 {
4632 poly next = pNext(a);
4633 while (next!=NULL)
4634 {
4635 a = next;
4636 next = pNext(a);
4637 l++;
4638 }
4639 }
4640 else
4641 {
4642 long unsigned curr_limit = rGetCurrSyzLimit(r);
4643 poly pp = a;
4644 while ((a=pNext(a))!=NULL)
4645 {
4646 if (__p_GetComp(a,r)<=curr_limit/*syzComp*/)
4647 l++;
4648 else break;
4649 pp = a;
4650 }
4651 a=pp;
4652 }
4653 return a;
4654}
4655
4656int p_Var(poly m,const ring r)
4657{
4658 if (m==NULL) return 0;
4659 if (pNext(m)!=NULL) return 0;
4660 int i,e=0;
4661 for (i=rVar(r); i>0; i--)
4662 {
4663 int exp=p_GetExp(m,i,r);
4664 if (exp==1)
4665 {
4666 if (e==0) e=i;
4667 else return 0;
4668 }
4669 else if (exp!=0)
4670 {
4671 return 0;
4672 }
4673 }
4674 return e;
4675}
4676
4677/*2
4678*the minimal index of used variables - 1
4679*/
4680int p_LowVar (poly p, const ring r)
4681{
4682 int k,l,lex;
4683
4684 if (p == NULL) return -1;
4685
4686 k = 32000;/*a very large dummy value*/
4687 while (p != NULL)
4688 {
4689 l = 1;
4690 lex = p_GetExp(p,l,r);
4691 while ((l < (rVar(r))) && (lex == 0))
4692 {
4693 l++;
4694 lex = p_GetExp(p,l,r);
4695 }
4696 l--;
4697 if (l < k) k = l;
4698 pIter(p);
4699 }
4700 return k;
4701}
4702
4703/*2
4704* verschiebt die Indizees der Modulerzeugenden um i
4705*/
4706void p_Shift (poly * p,int i, const ring r)
4707{
4708 poly qp1 = *p,qp2 = *p;/*working pointers*/
4709 int j = p_MaxComp(*p,r),k = p_MinComp(*p,r);
4710
4711 if (j+i < 0) return ;
4712 BOOLEAN toPoly= ((j == -i) && (j == k));
4713 while (qp1 != NULL)
4714 {
4715 if (toPoly || (__p_GetComp(qp1,r)+i > 0))
4716 {
4717 p_AddComp(qp1,i,r);
4718 p_SetmComp(qp1,r);
4719 qp2 = qp1;
4720 pIter(qp1);
4721 }
4722 else
4723 {
4724 if (qp2 == *p)
4725 {
4726 pIter(*p);
4727 p_LmDelete(&qp2,r);
4728 qp2 = *p;
4729 qp1 = *p;
4730 }
4731 else
4732 {
4733 qp2->next = qp1->next;
4734 if (qp1!=NULL) p_LmDelete(&qp1,r);
4735 qp1 = qp2->next;
4736 }
4737 }
4738 }
4739}
4740
4741/***************************************************************
4742 *
4743 * Storage Managament Routines
4744 *
4745 ***************************************************************/
4746
4747
4748static inline unsigned long GetBitFields(const long e,
4749 const unsigned int s, const unsigned int n)
4750{
4751 unsigned int i = 0;
4752 unsigned long ev = 0L;
4753 assume(n > 0 && s < BIT_SIZEOF_LONG);
4754 do
4755 {
4757 if (e > (long) i) ev |= Sy_bitL(s+i);
4758 else break;
4759 i++;
4760 }
4761 while (i < n);
4762 return ev;
4763}
4764
4765// Short Exponent Vectors are used for fast divisibility tests
4766// ShortExpVectors "squeeze" an exponent vector into one word as follows:
4767// Let n = BIT_SIZEOF_LONG / pVariables.
4768// If n == 0 (i.e. pVariables > BIT_SIZE_OF_LONG), let m == the number
4769// of non-zero exponents. If (m>BIT_SIZEOF_LONG), then sev = ~0, else
4770// first m bits of sev are set to 1.
4771// Otherwise (i.e. pVariables <= BIT_SIZE_OF_LONG)
4772// represented by a bit-field of length n (resp. n+1 for some
4773// exponents). If the value of an exponent is greater or equal to n, then
4774// all of its respective n bits are set to 1. If the value of an exponent
4775// is smaller than n, say m, then only the first m bits of the respective
4776// n bits are set to 1, the others are set to 0.
4777// This way, we have:
4778// exp1 / exp2 ==> (ev1 & ~ev2) == 0, i.e.,
4779// if (ev1 & ~ev2) then exp1 does not divide exp2
4780unsigned long p_GetShortExpVector(const poly p, const ring r)
4781{
4782 assume(p != NULL);
4783 unsigned long ev = 0; // short exponent vector
4784 unsigned int n = BIT_SIZEOF_LONG / r->N; // number of bits per exp
4785 unsigned int m1; // highest bit which is filled with (n+1)
4786 unsigned int i=0;
4787 int j=1;
4788
4789 if (n == 0)
4790 {
4791 if (r->N <2*BIT_SIZEOF_LONG)
4792 {
4793 n=1;
4794 m1=0;
4795 }
4796 else
4797 {
4798 for (; j<=r->N; j++)
4799 {
4800 if (p_GetExp(p,j,r) > 0) i++;
4801 if (i == BIT_SIZEOF_LONG) break;
4802 }
4803 if (i>0)
4804 ev = ~(0UL) >> (BIT_SIZEOF_LONG - i);
4805 return ev;
4806 }
4807 }
4808 else
4809 {
4810 m1 = (n+1)*(BIT_SIZEOF_LONG - n*r->N);
4811 }
4812
4813 n++;
4814 while (i<m1)
4815 {
4816 ev |= GetBitFields(p_GetExp(p, j,r), i, n);
4817 i += n;
4818 j++;
4819 }
4820
4821 n--;
4822 while (i<BIT_SIZEOF_LONG)
4823 {
4824 ev |= GetBitFields(p_GetExp(p, j,r), i, n);
4825 i += n;
4826 j++;
4827 }
4828 return ev;
4829}
4830
4831/***************************************************************
4832 *
4833 * p_ShallowDelete
4834 *
4835 ***************************************************************/
4836#undef LINKAGE
4837#define LINKAGE
4838#undef p_Delete__T
4839#define p_Delete__T p_ShallowDelete
4840#undef n_Delete__T
4841#define n_Delete__T(n, r) do {} while (0)
4842
4844
4845/***************************************************************/
4846/*
4847* compare a and b
4848*/
4849int p_Compare(const poly a, const poly b, const ring R)
4850{
4851 int r=p_Cmp(a,b,R);
4852 if ((r==0)&&(a!=NULL))
4853 {
4854 number h=n_Sub(pGetCoeff(a),pGetCoeff(b),R->cf);
4855 /* compare lead coeffs */
4856 r = -1+n_IsZero(h,R->cf)+2*n_GreaterZero(h,R->cf); /* -1: <, 0:==, 1: > */
4857 n_Delete(&h,R->cf);
4858 }
4859 else if (a==NULL)
4860 {
4861 if (b==NULL)
4862 {
4863 /* compare 0, 0 */
4864 r=0;
4865 }
4866 else if(p_IsConstant(b,R))
4867 {
4868 /* compare 0, const */
4869 r = 1-2*n_GreaterZero(pGetCoeff(b),R->cf); /* -1: <, 1: > */
4870 }
4871 }
4872 else if (b==NULL)
4873 {
4874 if (p_IsConstant(a,R))
4875 {
4876 /* compare const, 0 */
4877 r = -1+2*n_GreaterZero(pGetCoeff(a),R->cf); /* -1: <, 1: > */
4878 }
4879 }
4880 return(r);
4881}
4882
4883poly p_GcdMon(poly f, poly g, const ring r)
4884{
4885 assume(f!=NULL);
4886 assume(g!=NULL);
4887 assume(pNext(f)==NULL);
4888 poly G=p_Head(f,r);
4889 poly h=g;
4890 int *mf=(int*)omAlloc((r->N+1)*sizeof(int));
4891 p_GetExpV(f,mf,r);
4892 int *mh=(int*)omAlloc((r->N+1)*sizeof(int));
4893 BOOLEAN const_mon;
4894 BOOLEAN one_coeff=n_IsOne(pGetCoeff(G),r->cf);
4895 loop
4896 {
4897 if (h==NULL) break;
4898 if(!one_coeff)
4899 {
4900 number n=n_SubringGcd(pGetCoeff(G),pGetCoeff(h),r->cf);
4901 one_coeff=n_IsOne(n,r->cf);
4902 p_SetCoeff(G,n,r);
4903 }
4904 p_GetExpV(h,mh,r);
4905 const_mon=TRUE;
4906 for(unsigned j=r->N;j!=0;j--)
4907 {
4908 if (mh[j]<mf[j]) mf[j]=mh[j];
4909 if (mf[j]>0) const_mon=FALSE;
4910 }
4911 if (one_coeff && const_mon) break;
4912 pIter(h);
4913 }
4914 mf[0]=0;
4915 p_SetExpV(G,mf,r); // included is p_SetComp, p_Setm
4916 omFreeSize(mf,(r->N+1)*sizeof(int));
4917 omFreeSize(mh,(r->N+1)*sizeof(int));
4918 return G;
4919}
4920
4921poly p_CopyPowerProduct0(const poly p, number n, const ring r)
4922{
4924 poly np;
4925 omTypeAllocBin(poly, np, r->PolyBin);
4926 p_SetRingOfLm(np, r);
4927 memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
4928 pNext(np) = NULL;
4929 pSetCoeff0(np, n);
4930 return np;
4931}
4932
4933poly p_CopyPowerProduct(const poly p, const ring r)
4934{
4935 if (p == NULL) return NULL;
4936 return p_CopyPowerProduct0(p,n_Init(1,r->cf),r);
4937}
4938
4939poly p_Head0(const poly p, const ring r)
4940{
4941 if (p==NULL) return NULL;
4942 if (pGetCoeff(p)==NULL) return p_CopyPowerProduct0(p,NULL,r);
4943 return p_Head(p,r);
4944}
4945int p_MaxExpPerVar(poly p, int i, const ring r)
4946{
4947 int m=0;
4948 while(p!=NULL)
4949 {
4950 int mm=p_GetExp(p,i,r);
4951 if (mm>m) m=mm;
4952 pIter(p);
4953 }
4954 return m;
4955}
4956
Concrete implementation of enumerators over polynomials.
All the auxiliary stuff.
long int64
Definition: auxiliary.h:68
static int si_max(const int a, const int b)
Definition: auxiliary.h:124
#define BIT_SIZEOF_LONG
Definition: auxiliary.h:80
#define UNLIKELY(X)
Definition: auxiliary.h:404
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
#define LIKELY(X)
Definition: auxiliary.h:403
void * ADDRESS
Definition: auxiliary.h:119
static int si_min(const int a, const int b)
Definition: auxiliary.h:125
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f )
Definition: cf_gcd.cc:676
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:56
int l
Definition: cfEzgcd.cc:100
int m
Definition: cfEzgcd.cc:128
int i
Definition: cfEzgcd.cc:132
int k
Definition: cfEzgcd.cc:99
return
Definition: cfGcdAlgExt.cc:218
Variable x
Definition: cfModGcd.cc:4082
int p
Definition: cfModGcd.cc:4078
g
Definition: cfModGcd.cc:4090
CanonicalForm cf
Definition: cfModGcd.cc:4083
CanonicalForm b
Definition: cfModGcd.cc:4103
FILE * f
Definition: checklibs.c:9
poly singclap_pdivide(poly f, poly g, const ring r)
Definition: clapsing.cc:624
This is a polynomial enumerator for simple iteration over coefficients of polynomials.
Definition: intvec.h:23
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:633
static FORCE_INLINE number n_Param(const int iParameter, const coeffs r)
return the (iParameter^th) parameter as a NEW number NOTE: parameter numbering: 1....
Definition: coeffs.h:780
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of 'n'
Definition: coeffs.h:448
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:692
static FORCE_INLINE number n_GetDenom(number &n, const coeffs r)
return the denominator of n (if elements of r are by nature not fractional, result is 1)
Definition: coeffs.h:600
static FORCE_INLINE BOOLEAN nCoeff_is_GF(const coeffs r)
Definition: coeffs.h:836
static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
Definition: coeffs.h:843
number ndCopyMap(number a, const coeffs src, const coeffs dst)
Definition: numbers.cc:291
#define n_Test(a, r)
BOOLEAN n_Test(number a, const coeffs r)
Definition: coeffs.h:709
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition: coeffs.h:35
@ n_transExt
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition: coeffs.h:38
static FORCE_INLINE number n_Gcd(number a, number b, const coeffs r)
in Z: return the gcd of 'a' and 'b' in Z/nZ, Z/2^kZ: computed as in the case Z in Z/pZ,...
Definition: coeffs.h:661
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:561
static FORCE_INLINE BOOLEAN n_IsUnit(number n, const coeffs r)
TRUE iff n has a multiplicative inverse in the given coeff field/ring r.
Definition: coeffs.h:512
static FORCE_INLINE number n_ExactDiv(number a, number b, const coeffs r)
assume that there is a canonical subring in cf and we know that division is possible for these a and ...
Definition: coeffs.h:619
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:491
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:697
static FORCE_INLINE number n_InpNeg(number n, const coeffs r)
in-place negation of n MUST BE USED: n = n_InpNeg(n) (no copy is returned)
Definition: coeffs.h:554
static FORCE_INLINE void n_Power(number a, int b, number *res, const coeffs r)
fill res with the power a^b
Definition: coeffs.h:629
static FORCE_INLINE number n_Farey(number a, number b, const coeffs r)
Definition: coeffs.h:764
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:612
static FORCE_INLINE BOOLEAN nCoeff_is_Q(const coeffs r)
Definition: coeffs.h:803
static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
TRUE iff 'n' represents the zero element.
Definition: coeffs.h:461
static FORCE_INLINE int n_Size(number n, const coeffs r)
return a non-negative measure for the complexity of n; return 0 only when n represents zero; (used fo...
Definition: coeffs.h:567
static FORCE_INLINE number n_GetUnit(number n, const coeffs r)
in Z: 1 in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that is co-prime with k i...
Definition: coeffs.h:529
static FORCE_INLINE number n_Sub(number a, number b, const coeffs r)
return the difference of 'a' and 'b', i.e., a-b
Definition: coeffs.h:652
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:932
static FORCE_INLINE BOOLEAN nCoeff_is_Ring(const coeffs r)
Definition: coeffs.h:727
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:422
static FORCE_INLINE number n_ChineseRemainderSym(number *a, number *b, int rl, BOOLEAN sym, CFArray &inv_cache, const coeffs r)
Definition: coeffs.h:761
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:452
static FORCE_INLINE void n_Write(number n, const coeffs r, const BOOLEAN bShortOut=TRUE)
Definition: coeffs.h:588
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition: coeffs.h:797
static FORCE_INLINE BOOLEAN nCoeff_is_Q_a(const coeffs r)
Definition: coeffs.h:882
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:535
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:925
static FORCE_INLINE BOOLEAN n_DivBy(number a, number b, const coeffs r)
test whether 'a' is divisible 'b'; for r encoding a field: TRUE iff 'b' does not represent zero in Z:...
Definition: coeffs.h:750
static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
TRUE iff r represents an algebraic extension field.
Definition: coeffs.h:907
static FORCE_INLINE const char * n_Read(const char *s, number *a, const coeffs r)
!!! Recommendation: This method is too cryptic to be part of the user- !!! interface....
Definition: coeffs.h:595
static FORCE_INLINE BOOLEAN n_Equal(number a, number b, const coeffs r)
TRUE iff 'a' and 'b' represent the same number; they may have different representations.
Definition: coeffs.h:457
static FORCE_INLINE number n_GetNumerator(number &n, const coeffs r)
return the numerator of n (if elements of r are by nature not fractional, result is n)
Definition: coeffs.h:605
static FORCE_INLINE number n_SubringGcd(number a, number b, const coeffs r)
Definition: coeffs.h:663
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
static FORCE_INLINE void n_Normalize(number &n, const coeffs r)
inplace-normalization of n; produces some canonical representation of n;
Definition: coeffs.h:575
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition: coeffs.h:465
static FORCE_INLINE BOOLEAN nCoeff_is_transExt(const coeffs r)
TRUE iff r represents a transcendental extension field.
Definition: coeffs.h:915
#define Print
Definition: emacs.cc:80
#define WarnS
Definition: emacs.cc:78
return result
Definition: facAbsBiFact.cc:75
const CanonicalForm int s
Definition: facAbsFact.cc:51
const CanonicalForm int const CFList const Variable & y
Definition: facAbsFact.cc:53
CanonicalForm res
Definition: facAbsFact.cc:60
const CanonicalForm & w
Definition: facAbsFact.cc:51
CanonicalForm subst(const CanonicalForm &f, const CFList &a, const CFList &b, const CanonicalForm &Rstar, bool isFunctionField)
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
for(j=0;j< factors.length();j++)
Definition: facHensel.cc:129
int j
Definition: facHensel.cc:110
int comp(const CanonicalForm &A, const CanonicalForm &B)
compare polynomials
static int max(int a, int b)
Definition: fast_mult.cc:264
VAR short errorreported
Definition: feFopen.cc:23
void WerrorS(const char *s)
Definition: feFopen.cc:24
if(!FE_OPT_NO_SHELL_FLAG)(void) system(sys)
const char * eati(const char *s, int *i)
Definition: reporter.cc:373
#define D(A)
Definition: gentable.cc:131
#define STATIC_VAR
Definition: globaldefs.h:7
#define VAR
Definition: globaldefs.h:5
STATIC_VAR poly last
Definition: hdegree.cc:1173
#define exponent
STATIC_VAR int offset
Definition: janet.cc:29
STATIC_VAR TreeM * G
Definition: janet.cc:31
STATIC_VAR Poly * h
Definition: janet.cc:971
ListNode * next
Definition: janet.h:31
static bool rIsSCA(const ring r)
Definition: nc.h:190
poly nc_pSubst(poly p, int n, poly e, const ring r)
substitute the n-th variable by e in p destroy p e is not a constant
Definition: old.gring.cc:3211
LINLINE number nlAdd(number la, number li, const coeffs r)
Definition: longrat.cc:2701
LINLINE number nlSub(number la, number li, const coeffs r)
Definition: longrat.cc:2767
LINLINE void nlDelete(number *a, const coeffs r)
Definition: longrat.cc:2666
BOOLEAN nlGreaterZero(number za, const coeffs r)
Definition: longrat.cc:1308
number nlGcd(number a, number b, const coeffs r)
Definition: longrat.cc:1345
void nlNormalize(number &x, const coeffs r)
Definition: longrat.cc:1486
#define assume(x)
Definition: mod2.h:389
int dReportError(const char *fmt,...)
Definition: dError.cc:44
#define p_GetComp(p, r)
Definition: monomials.h:64
#define pIter(p)
Definition: monomials.h:37
#define pNext(p)
Definition: monomials.h:36
#define p_LmCheckPolyRing1(p, r)
Definition: monomials.h:177
#define p_LmCheckPolyRing2(p, r)
Definition: monomials.h:199
#define pSetCoeff0(p, n)
Definition: monomials.h:59
#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
#define POLY_NEGWEIGHT_OFFSET
Definition: monomials.h:236
#define __p_GetComp(p, r)
Definition: monomials.h:63
#define p_SetRingOfLm(p, r)
Definition: monomials.h:144
#define rRing_has_Comp(r)
Definition: monomials.h:266
#define pAssume(cond)
Definition: monomials.h:90
gmp_float exp(const gmp_float &a)
Definition: mpr_complex.cc:357
The main handler for Singular numbers which are suitable for Singular polynomials.
Definition: lq.h:40
number ndGcd(number, number, const coeffs r)
Definition: numbers.cc:189
void ndNormalize(number &, const coeffs)
Definition: numbers.cc:187
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
#define omAlloc(size)
Definition: omAllocDecl.h:210
#define omReallocSize(addr, o_size, size)
Definition: omAllocDecl.h:220
#define omTypeAllocBin(type, addr, bin)
Definition: omAllocDecl.h:203
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omAlloc0(size)
Definition: omAllocDecl.h:211
#define NULL
Definition: omList.c:12
#define TEST_OPT_INTSTRATEGY
Definition: options.h:111
#define Sy_bitL(x)
Definition: options.h:32
#define TEST_OPT_PROT
Definition: options.h:104
#define TEST_OPT_CONTENTSB
Definition: options.h:128
poly p_Diff(poly a, int k, const ring r)
Definition: p_polys.cc:1898
poly p_GetMaxExpP(poly p, const ring r)
return monomial r such that GetExp(r,i) is maximum of all monomials in p; coeff == 0,...
Definition: p_polys.cc:1138
poly p_DivideM(poly a, poly b, const ring r)
Definition: p_polys.cc:1578
int p_IsPurePower(const poly p, const ring r)
return i, if head depends only on var(i)
Definition: p_polys.cc:1226
void p_Setm_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:554
poly pp_Jet(poly p, int m, const ring R)
Definition: p_polys.cc:4358
STATIC_VAR pLDegProc pOldLDeg
Definition: p_polys.cc:3661
void p_Cleardenom_n(poly ph, const ring r, number &c)
Definition: p_polys.cc:2954
long pLDegb(poly p, int *l, const ring r)
Definition: p_polys.cc:811
long pLDeg1_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:975
long p_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:596
poly p_Farey(poly p, number N, const ring r)
Definition: p_polys.cc:54
long pLDeg1_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1038
void pRestoreDegProcs(ring r, pFDegProc old_FDeg, pLDegProc old_lDeg)
Definition: p_polys.cc:3649
long pLDeg1c_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1068
poly n_PermNumber(const number z, const int *par_perm, const int, const ring src, const ring dst)
Definition: p_polys.cc:4027
static poly p_DiffOpM(poly a, poly b, BOOLEAN multiply, const ring r)
Definition: p_polys.cc:1934
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:1870
int p_Size(poly p, const ring r)
Definition: p_polys.cc:3253
void p_Setm_Dummy(poly p, const ring r)
Definition: p_polys.cc:541
static poly p_Invers(int n, poly u, intvec *w, const ring R)
Definition: p_polys.cc:4469
poly p_GcdMon(poly f, poly g, const ring r)
polynomial gcd for f=mon
Definition: p_polys.cc:4883
BOOLEAN p_ComparePolys(poly p1, poly p2, const ring r)
returns TRUE if p1 is a skalar multiple of p2 assume p1 != NULL and p2 != NULL
Definition: p_polys.cc:4576
int p_LowVar(poly p, const ring r)
the minimal index of used variables - 1
Definition: p_polys.cc:4680
BOOLEAN p_DivisibleByRingCase(poly f, poly g, const ring r)
divisibility check over ground ring (which may contain zero divisors); TRUE iff LT(f) divides LT(g),...
Definition: p_polys.cc:1642
poly p_Homogen(poly p, int varnum, const ring r)
Definition: p_polys.cc:3270
poly p_Subst(poly p, int n, poly e, const ring r)
Definition: p_polys.cc:3958
static BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r1, const ring r2)
Definition: p_polys.cc:4526
BOOLEAN p_HasNotCF(poly p1, poly p2, const ring r)
Definition: p_polys.cc:1329
void p_Content(poly ph, const ring r)
Definition: p_polys.cc:2295
int p_Weight(int i, const ring r)
Definition: p_polys.cc:705
void p_Setm_TotalDegree(poly p, const ring r)
Definition: p_polys.cc:547
poly p_CopyPowerProduct(const poly p, const ring r)
like p_Head, but with coefficient 1
Definition: p_polys.cc:4933
poly pp_DivideM(poly a, poly b, const ring r)
Definition: p_polys.cc:1633
STATIC_VAR int _componentsExternal
Definition: p_polys.cc:148
void p_SimpleContent(poly ph, int smax, const ring r)
Definition: p_polys.cc:2564
poly p_ISet(long i, const ring r)
returns the poly representing the integer i
Definition: p_polys.cc:1297
STATIC_VAR long * _componentsShifted
Definition: p_polys.cc:147
void p_Vec2Polys(poly v, poly **p, int *len, const ring r)
Definition: p_polys.cc:3625
static poly p_Subst0(poly p, int n, const ring r)
Definition: p_polys.cc:3933
poly p_DiffOp(poly a, poly b, BOOLEAN multiply, const ring r)
Definition: p_polys.cc:1973
static unsigned long p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r, unsigned long number_of_exp)
Definition: p_polys.cc:1107
poly p_Jet(poly p, int m, const ring R)
Definition: p_polys.cc:4386
poly p_TakeOutComp(poly *p, int k, const ring r)
Definition: p_polys.cc:3435
long pLDeg1c_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:941
long pLDeg1(poly p, int *l, const ring r)
Definition: p_polys.cc:841
static number * pnBin(int exp, const ring r)
Definition: p_polys.cc:2058
void p_Shift(poly *p, int i, const ring r)
shifts components of the vector p by i
Definition: p_polys.cc:4706
static void pnFreeBin(number *bin, int exp, const coeffs r)
Definition: p_polys.cc:2089
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:4130
poly p_Power(poly p, int i, const ring r)
Definition: p_polys.cc:2197
poly p_Div_nn(poly p, const number n, const ring r)
Definition: p_polys.cc:1505
void p_Normalize(poly p, const ring r)
Definition: p_polys.cc:3813
void p_DeleteComp(poly *p, int k, const ring r)
Definition: p_polys.cc:3544
poly p_mInit(const char *st, BOOLEAN &ok, const ring r)
Definition: p_polys.cc:1442
poly p_MDivide(poly a, poly b, const ring r)
Definition: p_polys.cc:1492
void p_ContentRat(poly &ph, const ring r)
Definition: p_polys.cc:1744
void p_Norm(poly p1, const ring r)
Definition: p_polys.cc:3719
poly p_Div_mm(poly p, const poly m, const ring r)
divide polynomial by monomial
Definition: p_polys.cc:1538
int p_GetVariables(poly p, int *e, const ring r)
set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0 return #(e[i]>0)
Definition: p_polys.cc:1267
int p_MinDeg(poly p, intvec *w, const ring R)
Definition: p_polys.cc:4448
int p_MaxExpPerVar(poly p, int i, const ring r)
max exponent of variable x_i in p
Definition: p_polys.cc:4945
STATIC_VAR BOOLEAN pOldLexOrder
Definition: p_polys.cc:3662
int p_Compare(const poly a, const poly b, const ring R)
Definition: p_polys.cc:4849
void p_Setm_Syz(poly p, ring r, int *Components, long *ShiftedComponents)
Definition: p_polys.cc:531
STATIC_VAR pFDegProc pOldFDeg
Definition: p_polys.cc:3660
void p_LmDeleteAndNextRat(poly *p, int ishift, ring r)
Definition: p_polys.cc:1700
unsigned long p_GetShortExpVector(const poly p, const ring r)
Definition: p_polys.cc:4780
BOOLEAN p_IsHomogeneousW(poly p, const intvec *w, const ring r)
Definition: p_polys.cc:3343
VAR BOOLEAN pSetm_error
Definition: p_polys.cc:150
long pLDeg1_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:910
poly p_Series(int n, poly p, poly u, intvec *w, const ring R)
Definition: p_polys.cc:4498
void p_ProjectiveUnique(poly ph, const ring r)
Definition: p_polys.cc:3143
long p_WTotaldegree(poly p, const ring r)
Definition: p_polys.cc:613
long p_DegW(poly p, const int *w, const ring R)
Definition: p_polys.cc:690
p_SetmProc p_GetSetmProc(const ring r)
Definition: p_polys.cc:560
void p_Setm_General(poly p, const ring r)
Definition: p_polys.cc:158
BOOLEAN p_OneComp(poly p, const ring r)
return TRUE if all monoms have the same component
Definition: p_polys.cc:1208
poly p_Cleardenom(poly p, const ring r)
Definition: p_polys.cc:2845
long pLDeg1c(poly p, int *l, const ring r)
Definition: p_polys.cc:877
void p_Split(poly p, poly *h)
Definition: p_polys.cc:1320
long pLDeg1c_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1005
poly p_GetCoeffRat(poly p, int ishift, ring r)
Definition: p_polys.cc:1722
BOOLEAN p_VectorHasUnitB(poly p, int *k, const ring r)
Definition: p_polys.cc:3379
long pLDeg0c(poly p, int *l, const ring r)
Definition: p_polys.cc:770
poly p_Vec2Poly(poly v, int k, const ring r)
Definition: p_polys.cc:3573
poly p_LcmRat(const poly a, const poly b, const long lCompM, const ring r)
Definition: p_polys.cc:1677
unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max)
return the maximal exponent of p in form of the maximal long var
Definition: p_polys.cc:1175
static poly p_TwoMonPower(poly p, int exp, const ring r)
Definition: p_polys.cc:2106
void p_SetModDeg(intvec *w, ring r)
Definition: p_polys.cc:3673
BOOLEAN p_HasNotCFRing(poly p1, poly p2, const ring r)
Definition: p_polys.cc:1345
long pLDeg0(poly p, int *l, const ring r)
Definition: p_polys.cc:739
int p_Var(poly m, const ring r)
Definition: p_polys.cc:4656
poly p_One(const ring r)
Definition: p_polys.cc:1313
poly p_Sub(poly p1, poly p2, const ring r)
Definition: p_polys.cc:1990
void p_VectorHasUnit(poly p, int *k, int *len, const ring r)
Definition: p_polys.cc:3402
static void p_SplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero, const ring r)
Definition: p_polys.cc:3829
int p_IsUnivariate(poly p, const ring r)
return i, if poly depends only on var(i)
Definition: p_polys.cc:1247
STATIC_VAR int * _components
Definition: p_polys.cc:146
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition: p_polys.cc:1473
void pSetDegProcs(ring r, pFDegProc new_FDeg, pLDegProc new_lDeg)
Definition: p_polys.cc:3637
void pEnlargeSet(poly **p, int l, int increment)
Definition: p_polys.cc:3696
long p_WDegree(poly p, const ring r)
Definition: p_polys.cc:714
static long pModDeg(poly p, ring r)
Definition: p_polys.cc:3664
BOOLEAN p_IsHomogeneous(poly p, const ring r)
Definition: p_polys.cc:3319
poly p_Head0(const poly p, const ring r)
like p_Head, but allow NULL coeff
Definition: p_polys.cc:4939
static poly p_MonMultC(poly p, poly q, const ring rr)
Definition: p_polys.cc:2044
static poly p_Pow_charp(poly p, int i, const ring r)
Definition: p_polys.cc:2185
poly pp_JetW(poly p, int m, int *w, const ring R)
Definition: p_polys.cc:4403
long p_Deg(poly a, const ring r)
Definition: p_polys.cc:587
static poly p_Subst1(poly p, int n, const ring r)
Definition: p_polys.cc:3865
poly p_Last(const poly p, int &l, const ring r)
Definition: p_polys.cc:4621
poly p_CopyPowerProduct0(const poly p, number n, const ring r)
like p_Head, but with coefficient n
Definition: p_polys.cc:4921
static void p_MonMult(poly p, poly q, const ring r)
Definition: p_polys.cc:2024
number p_InitContent(poly ph, const ring r)
Definition: p_polys.cc:2635
void p_Vec2Array(poly v, poly *p, int len, const ring r)
vector to already allocated array (len>=p_MaxComp(v,r))
Definition: p_polys.cc:3595
static poly p_MonPower(poly p, int exp, const ring r)
Definition: p_polys.cc:2000
void p_ContentForGB(poly ph, const ring r)
Definition: p_polys.cc:2355
static poly p_Subst2(poly p, int n, number e, const ring r)
Definition: p_polys.cc:3892
void p_Lcm(const poly a, const poly b, poly m, const ring r)
Definition: p_polys.cc:1655
static unsigned long GetBitFields(const long e, const unsigned int s, const unsigned int n)
Definition: p_polys.cc:4748
poly p_ChineseRemainder(poly *xx, number *x, number *q, int rl, CFArray &inv_cache, const ring R)
Definition: p_polys.cc:88
const char * p_Read(const char *st, poly &rc, const ring r)
Definition: p_polys.cc:1370
poly p_JetW(poly p, int m, int *w, const ring R)
Definition: p_polys.cc:4430
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition: p_polys.cc:4512
static poly p_Pow(poly p, int i, const ring r)
Definition: p_polys.cc:2171
static poly p_Neg(poly p, const ring r)
Definition: p_polys.h:1105
static int pLength(poly a)
Definition: p_polys.h:188
static void p_ExpVectorSum(poly pr, poly p1, poly p2, const ring r)
Definition: p_polys.h:1423
static poly p_Add_q(poly p, poly q, const ring r)
Definition: p_polys.h:934
static void p_LmDelete(poly p, const ring r)
Definition: p_polys.h:721
static poly p_Mult_q(poly p, poly q, const ring r)
Definition: p_polys.h:1112
BOOLEAN p_LmCheckPolyRing(poly p, ring r)
Definition: pDebug.cc:123
static void p_ExpVectorAdd(poly p1, poly p2, const ring r)
Definition: p_polys.h:1409
static unsigned long p_SubComp(poly p, unsigned long v, ring r)
Definition: p_polys.h:451
static long p_AddExp(poly p, int v, long ee, ring r)
Definition: p_polys.h:604
static poly p_LmInit(poly p, const ring r)
Definition: p_polys.h:1333
#define p_LmEqual(p1, p2, r)
Definition: p_polys.h:1721
static int p_Cmp(poly p1, poly p2, ring r)
Definition: p_polys.h:1725
void p_Write(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:342
static void p_SetExpV(poly p, int *ev, const ring r)
Definition: p_polys.h:1542
static int p_Comp_k_n(poly a, poly b, int k, ring r)
Definition: p_polys.h:638
static void p_SetCompP(poly p, int i, ring r)
Definition: p_polys.h:252
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:486
static long p_MinComp(poly p, ring lmRing, ring tailRing)
Definition: p_polys.h:311
static unsigned long p_SetComp(poly p, unsigned long c, ring r)
Definition: p_polys.h:245
static long p_IncrExp(poly p, int v, ring r)
Definition: p_polys.h:589
static void p_ExpVectorSub(poly p1, poly p2, const ring r)
Definition: p_polys.h:1438
static unsigned long p_AddComp(poly p, unsigned long v, ring r)
Definition: p_polys.h:445
static void p_Setm(poly p, const ring r)
Definition: p_polys.h:231
#define p_SetmComp
Definition: p_polys.h:242
static number p_SetCoeff(poly p, number n, ring r)
Definition: p_polys.h:410
static poly pReverse(poly p)
Definition: p_polys.h:333
static BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
Definition: p_polys.h:1004
static poly p_Head(const poly p, const ring r)
copy the (leading) term of p
Definition: p_polys.h:858
static int p_LmCmp(poly p, poly q, const ring r)
Definition: p_polys.h:1578
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:467
static long p_MultExp(poly p, int v, long ee, ring r)
Definition: p_polys.h:619
static BOOLEAN p_IsConstant(const poly p, const ring r)
Definition: p_polys.h:1962
static poly p_GetExp_k_n(poly p, int l, int k, const ring r)
Definition: p_polys.h:1370
static BOOLEAN p_DivisibleBy(poly a, poly b, const ring r)
Definition: p_polys.h:1898
static long p_MaxComp(poly p, ring lmRing, ring tailRing)
Definition: p_polys.h:290
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:899
static long p_DecrExp(poly p, int v, ring r)
Definition: p_polys.h:596
static void p_GetExpV(poly p, int *ev, const ring r)
Definition: p_polys.h:1518
BOOLEAN p_CheckPolyRing(poly p, ring r)
Definition: pDebug.cc:115
static long p_GetOrder(poly p, ring r)
Definition: p_polys.h:419
static poly p_LmFreeAndNext(poly p, ring)
Definition: p_polys.h:709
static poly p_Mult_mm(poly p, poly m, const ring r)
Definition: p_polys.h:1049
static void p_LmFree(poly p, ring)
Definition: p_polys.h:681
static poly p_Init(const ring r, omBin bin)
Definition: p_polys.h:1318
static poly p_LmDeleteAndNext(poly p, const ring r)
Definition: p_polys.h:753
static poly p_SortAdd(poly p, const ring r, BOOLEAN revert=FALSE)
Definition: p_polys.h:1217
static poly p_Copy(poly p, const ring r)
returns a copy of p
Definition: p_polys.h:844
static long p_Totaldegree(poly p, const ring r)
Definition: p_polys.h:1505
#define p_Test(p, r)
Definition: p_polys.h:159
#define __p_Mult_nn(p, n, r)
Definition: p_polys.h:969
void p_wrp(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:373
poly singclap_gcd(poly f, poly g, const ring r)
polynomial gcd via singclap_gcd_r resp. idSyzygies destroys f and g
Definition: polys.cc:380
void PrintS(const char *s)
Definition: reporter.cc:284
void Werror(const char *fmt,...)
Definition: reporter.cc:189
BOOLEAN rOrd_SetCompRequiresSetm(const ring r)
return TRUE if p_SetComp requires p_Setm
Definition: ring.cc:1993
void rWrite(ring r, BOOLEAN details)
Definition: ring.cc:226
int r_IsRingVar(const char *n, char **names, int N)
Definition: ring.cc:212
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:1799
static BOOLEAN rField_is_Zp_a(const ring r)
Definition: ring.h:529
static BOOLEAN rField_is_Z(const ring r)
Definition: ring.h:509
static BOOLEAN rField_is_Zp(const ring r)
Definition: ring.h:500
void(* p_SetmProc)(poly p, const ring r)
Definition: ring.h:39
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition: ring.h:400
ro_typ ord_typ
Definition: ring.h:220
long(* pFDegProc)(poly p, ring r)
Definition: ring.h:38
static int rGetCurrSyzLimit(const ring r)
Definition: ring.h:723
long(* pLDegProc)(poly p, int *length, ring r)
Definition: ring.h:37
static BOOLEAN rIsRatGRing(const ring r)
Definition: ring.h:427
static int rPar(const ring r)
(r->cf->P)
Definition: ring.h:599
@ ro_wp64
Definition: ring.h:55
@ ro_syz
Definition: ring.h:60
@ ro_cp
Definition: ring.h:58
@ ro_dp
Definition: ring.h:52
@ ro_is
Definition: ring.h:61
@ ro_wp_neg
Definition: ring.h:56
@ ro_wp
Definition: ring.h:53
@ ro_isTemp
Definition: ring.h:61
@ ro_am
Definition: ring.h:54
@ ro_syzcomp
Definition: ring.h:59
static int rInternalChar(const ring r)
Definition: ring.h:689
static BOOLEAN rIsLPRing(const ring r)
Definition: ring.h:411
@ ringorder_lp
Definition: ring.h:77
@ ringorder_a
Definition: ring.h:70
@ ringorder_am
Definition: ring.h:88
@ ringorder_a64
for int64 weights
Definition: ring.h:71
@ ringorder_rs
opposite of ls
Definition: ring.h:92
@ ringorder_C
Definition: ring.h:73
@ ringorder_S
S?
Definition: ring.h:75
@ ringorder_ds
Definition: ring.h:84
@ ringorder_Dp
Definition: ring.h:80
@ ringorder_unspec
Definition: ring.h:94
@ ringorder_L
Definition: ring.h:89
@ ringorder_Ds
Definition: ring.h:85
@ ringorder_dp
Definition: ring.h:78
@ ringorder_c
Definition: ring.h:72
@ ringorder_rp
Definition: ring.h:79
@ ringorder_aa
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition: ring.h:91
@ ringorder_no
Definition: ring.h:69
@ ringorder_Wp
Definition: ring.h:82
@ ringorder_ws
Definition: ring.h:86
@ ringorder_Ws
Definition: ring.h:87
@ ringorder_IS
Induced (Schreyer) ordering.
Definition: ring.h:93
@ ringorder_ls
Definition: ring.h:83
@ ringorder_s
s?
Definition: ring.h:76
@ ringorder_wp
Definition: ring.h:81
@ ringorder_M
Definition: ring.h:74
static BOOLEAN rField_is_Q_a(const ring r)
Definition: ring.h:539
static BOOLEAN rField_is_Q(const ring r)
Definition: ring.h:506
static BOOLEAN rField_has_Units(const ring r)
Definition: ring.h:490
static BOOLEAN rIsNCRing(const ring r)
Definition: ring.h:421
static BOOLEAN rIsSyzIndexRing(const ring r)
Definition: ring.h:720
static BOOLEAN rField_is_GF(const ring r)
Definition: ring.h:521
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition: ring.h:592
union sro_ord::@1 data
#define rField_is_Ring(R)
Definition: ring.h:485
Definition: ring.h:219
void sBucket_Add_m(sBucket_pt bucket, poly p)
Definition: sbuckets.cc:173
sBucket_pt sBucketCreate(const ring r)
Definition: sbuckets.cc:96
void sBucketDestroyAdd(sBucket_pt bucket, poly *p, int *length)
Definition: sbuckets.h:68
static short scaLastAltVar(ring r)
Definition: sca.h:25
static short scaFirstAltVar(ring r)
Definition: sca.h:18
poly p_LPSubst(poly p, int n, poly e, const ring r)
Definition: shiftop.cc:912
int status int void size_t count
Definition: si_signals.h:59
#define IDELEMS(i)
Definition: simpleideals.h:23
#define R
Definition: sirandom.c:27
#define loop
Definition: structs.h:75
number ntInit(long i, const coeffs cf)
Definition: transext.cc:704
int * iv2array(intvec *iv, const ring R)
Definition: weight.cc:200
long totaldegreeWecart_IV(poly p, ring r, const int *w)
Definition: weight.cc:231