source: git/kernel/polys1.cc @ c57134

spielwiese
Last change on this file since c57134 was 2318f07, checked in by Hans Schönemann <hannes@…>, 18 years ago
*hannes: 64bit and pDegW git-svn-id: file:///usr/local/Singular/svn/trunk@9045 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 37.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys1.cc,v 1.19 2006-03-28 12:56:06 Singular Exp $ */
5
6/*
7* ABSTRACT - all basic methods to manipulate polynomials:
8* independent of representation
9*/
10
11/* includes */
12#include <string.h>
13#include "mod2.h"
14#include "structs.h"
15#include "numbers.h"
16#include "ffields.h"
17#include "omalloc.h"
18#include "febase.h"
19#include "weight.h"
20#include "intvec.h"
21#include "longalg.h"
22#include "ring.h"
23#include "ideals.h"
24#include "polys.h"
25//#include "ipid.h"
26#ifdef HAVE_FACTORY
27#include "clapsing.h"
28#endif
29
30#define SR_HDL(A) ((long)A)
31/*-------- several access procedures to monomials -------------------- */
32/*
33* the module weights for std
34*/
35static pFDegProc pOldFDeg;
36static pLDegProc pOldLDeg;
37static intvec * pModW;
38static BOOLEAN pOldLexOrder;
39
40static long pModDeg(poly p, ring r = currRing)
41{
42  long d=pOldFDeg(p, r);
43  int c=p_GetComp(p, r);
44  if ((c>0) && (pModW->range(c-1))) d+= (*pModW)[c-1];
45  return d;
46  //return pOldFDeg(p, r)+(*pModW)[p_GetComp(p, r)-1];
47}
48
49void pSetModDeg(intvec *w)
50{
51  if (w!=NULL)
52  {
53    pModW = w;
54    pOldFDeg = pFDeg;
55    pOldLDeg = pLDeg;
56    pOldLexOrder = pLexOrder;
57    pSetDegProcs(pModDeg);
58    pLexOrder = TRUE;
59  }
60  else
61  {
62    pModW = NULL;
63    pRestoreDegProcs(pOldFDeg, pOldLDeg);
64    pLexOrder = pOldLexOrder;
65  }
66}
67
68
69/*2
70* subtract p2 from p1, p1 and p2 are destroyed
71* do not put attention on speed: the procedure is only used in the interpreter
72*/
73poly pSub(poly p1, poly p2)
74{
75  return pAdd(p1, pNeg(p2));
76}
77
78/*3
79*  create binomial coef.
80*/
81static number* pnBin(int exp)
82{
83  int e, i, h;
84  number x, y, *bin=NULL;
85
86  x = nInit(exp);
87  if (nIsZero(x))
88  {
89    nDelete(&x);
90    return bin;
91  }
92  h = (exp >> 1) + 1;
93  bin = (number *)omAlloc0(h*sizeof(number));
94  bin[1] = x;
95  if (exp < 4)
96    return bin;
97  i = exp - 1;
98  for (e=2; e<h; e++)
99  {
100      x = nInit(i);
101      i--;
102      y = nMult(x,bin[e-1]);
103      nDelete(&x);
104      x = nInit(e);
105      bin[e] = nIntDiv(y,x);
106      nDelete(&x);
107      nDelete(&y);
108  }
109  return bin;
110}
111
112static void pnFreeBin(number *bin, int exp)
113{
114  int e, h = (exp >> 1) + 1;
115
116  if (bin[1] != NULL)
117  {
118    for (e=1; e<h; e++)
119      nDelete(&(bin[e]));
120  }
121  omFreeSize((ADDRESS)bin, h*sizeof(number));
122}
123
124/*3
125* compute for a monomial m
126* the power m^exp, exp > 1
127* destroys p
128*/
129static poly pMonPower(poly p, int exp)
130{
131  int i;
132
133  if(!nIsOne(pGetCoeff(p)))
134  {
135    number x, y;
136    y = pGetCoeff(p);
137    nPower(y,exp,&x);
138    nDelete(&y);
139    pSetCoeff0(p,x);
140  }
141  for (i=pVariables; i!=0; i--)
142  {
143    pMultExp(p,i, exp);
144  }
145  pSetm(p);
146  return p;
147}
148
149/*3
150* compute for monomials p*q
151* destroys p, keeps q
152*/
153static void pMonMult(poly p, poly q)
154{
155  number x, y;
156  int i;
157
158  y = pGetCoeff(p);
159  x = nMult(y,pGetCoeff(q));
160  nDelete(&y);
161  pSetCoeff0(p,x);
162  //for (i=pVariables; i!=0; i--)
163  //{
164  //  pAddExp(p,i, pGetExp(q,i));
165  //}
166  //p->Order += q->Order;
167  pExpVectorAdd(p,q);
168}
169
170/*3
171* compute for monomials p*q
172* keeps p, q
173*/
174static poly pMonMultC(poly p, poly q)
175{
176  number x;
177  int i;
178  poly r = pInit();
179
180  x = nMult(pGetCoeff(p),pGetCoeff(q));
181  pSetCoeff0(r,x);
182  pExpVectorSum(r,p, q);
183  return r;
184}
185
186/*
187*  compute for a poly p = head+tail, tail is monomial
188*          (head + tail)^exp, exp > 1
189*          with binomial coef.
190*/
191static poly pTwoMonPower(poly p, int exp)
192{
193  int eh, e;
194  long al;
195  poly *a;
196  poly tail, b, res, h;
197  number x;
198  number *bin = pnBin(exp);
199
200  tail = pNext(p);
201  if (bin == NULL)
202  {
203    pMonPower(p,exp);
204    pMonPower(tail,exp);
205#ifdef PDEBUG
206    pTest(p);
207#endif
208    return p;
209  }
210  eh = exp >> 1;
211  al = (exp + 1) * sizeof(poly);
212  a = (poly *)omAlloc(al);
213  a[1] = p;
214  for (e=1; e<exp; e++)
215  {
216    a[e+1] = pMonMultC(a[e],p);
217  }
218  res = a[exp];
219  b = pHead(tail);
220  for (e=exp-1; e>eh; e--)
221  {
222    h = a[e];
223    x = nMult(bin[exp-e],pGetCoeff(h));
224    pSetCoeff(h,x);
225    pMonMult(h,b);
226    res = pNext(res) = h;
227    pMonMult(b,tail);
228  }
229  for (e=eh; e!=0; e--)
230  {
231    h = a[e];
232    x = nMult(bin[e],pGetCoeff(h));
233    pSetCoeff(h,x);
234    pMonMult(h,b);
235    res = pNext(res) = h;
236    pMonMult(b,tail);
237  }
238  pDeleteLm(&tail);
239  pNext(res) = b;
240  pNext(b) = NULL;
241  res = a[exp];
242  omFreeSize((ADDRESS)a, al);
243  pnFreeBin(bin, exp);
244//  tail=res;
245// while((tail!=NULL)&&(pNext(tail)!=NULL))
246// {
247//   if(nIsZero(pGetCoeff(pNext(tail))))
248//   {
249//     pDeleteLm(&pNext(tail));
250//   }
251//   else
252//     pIter(tail);
253// }
254#ifdef PDEBUG
255  pTest(res);
256#endif
257  return res;
258}
259
260static poly pPow(poly p, int i)
261{
262  poly rc = pCopy(p);
263  i -= 2;
264  do
265  {
266    rc = pMult(rc,pCopy(p));
267    pNormalize(rc);
268    i--;
269  }
270  while (i != 0);
271  return pMult(rc,p);
272}
273
274/*2
275* returns the i-th power of p
276* p will be destroyed
277*/
278poly pPower(poly p, int i)
279{
280  poly rc=NULL;
281
282  if (i==0)
283  {
284    pDelete(&p);
285    return pOne();
286  }
287
288  if(p!=NULL)
289  {
290    if ( (i > 0) && ((unsigned long ) i > (currRing->bitmask)))
291    {
292      Werror("exponent %d is too large, max. is %d",i,currRing->bitmask);
293      return NULL;
294    }
295    switch (i)
296    {
297// cannot happen, see above
298//      case 0:
299//      {
300//        rc=pOne();
301//#ifdef DRING
302//        if ((pDRING) && (pdDFlag(p)==1))
303//        {
304//          pdSetDFlag(rc,1);
305//        }
306//#endif
307//        pDelete(&p);
308//        break;
309//      }
310      case 1:
311        rc=p;
312        break;
313      case 2:
314        rc=pMult(pCopy(p),p);
315        break;
316      default:
317        if (i < 0)
318        {
319          pDelete(&p);
320          return NULL;
321        }
322        else
323        {
324#ifdef HAVE_PLURAL
325          if (rIsPluralRing(currRing)) /* in the NC case nothing helps :-( */
326          {
327            int j=i;
328            rc = pCopy(p);
329            while (j>1)
330            {
331              rc = pMult(pCopy(p),rc);
332              j--;
333            }
334            pDelete(&p);
335            return rc;
336          }
337#endif
338          rc = pNext(p);
339          if (rc == NULL)
340            return pMonPower(p,i);
341          /* else: binom ?*/
342          int char_p=rChar(currRing);
343          if (pNext(rc) != NULL)
344            return pPow(p,i);
345          if ((char_p==0) || (i<=char_p))
346            return pTwoMonPower(p,i);
347          poly p_p=pTwoMonPower(pCopy(p),char_p);
348          return pMult(pPower(p,i-char_p),p_p);
349        }
350      /*end default:*/
351    }
352  }
353  return rc;
354}
355
356/*2
357* returns the partial differentiate of a by the k-th variable
358* does not destroy the input
359*/
360poly pDiff(poly a, int k)
361{
362  poly res, f, last;
363  number t;
364
365  last = res = NULL;
366  while (a!=NULL)
367  {
368    if (pGetExp(a,k)!=0)
369    {
370      f = pLmInit(a);
371      t = nInit(pGetExp(a,k));
372      pSetCoeff0(f,nMult(t,pGetCoeff(a)));
373      nDelete(&t);
374      if (nIsZero(pGetCoeff(f)))
375        pDeleteLm(&f);
376      else
377      {
378        pDecrExp(f,k);
379        pSetm(f);
380        if (res==NULL)
381        {
382          res=last=f;
383        }
384        else
385        {
386          pNext(last)=f;
387          last=f;
388        }
389      }
390    }
391    pIter(a);
392  }
393  return res;
394}
395
396static poly pDiffOpM(poly a, poly b,BOOLEAN multiply)
397{
398  int i,j,s;
399  number n,h,hh;
400  poly p=pOne();
401  n=nMult(pGetCoeff(a),pGetCoeff(b));
402  for(i=pVariables;i>0;i--)
403  {
404    s=pGetExp(b,i);
405    if (s<pGetExp(a,i))
406    {
407      nDelete(&n);
408      pDeleteLm(&p);
409      return NULL;
410    }
411    if (multiply)
412    {
413      for(j=pGetExp(a,i); j>0;j--)
414      {
415        h = nInit(s);
416        hh=nMult(n,h);
417        nDelete(&h);
418        nDelete(&n);
419        n=hh;
420        s--;
421      }
422      pSetExp(p,i,s);
423    }
424    else
425    {
426      pSetExp(p,i,s-pGetExp(a,i));
427    }
428  }
429  pSetm(p);
430  /*if (multiply)*/ pSetCoeff(p,n);
431  return p;
432}
433
434poly pDiffOp(poly a, poly b,BOOLEAN multiply)
435{
436  poly result=NULL;
437  poly h;
438  for(;a!=NULL;pIter(a))
439  {
440    for(h=b;h!=NULL;pIter(h))
441    {
442      result=pAdd(result,pDiffOpM(a,h,multiply));
443    }
444  }
445  return result;
446}
447
448
449void pSplit(poly p, poly *h)
450{
451  *h=pNext(p);
452  pNext(p)=NULL;
453}
454
455
456
457int pMaxCompProc(poly p)
458{
459  return pMaxComp(p);
460}
461
462/*2
463* handle memory request for sets of polynomials (ideals)
464* l is the length of *p, increment is the difference (may be negative)
465*/
466void pEnlargeSet(polyset *p, int l, int increment)
467{
468  int i;
469  polyset h;
470
471  h=(polyset)omReallocSize((poly*)*p,l*sizeof(poly),(l+increment)*sizeof(poly));
472  if (increment>0)
473  {
474    //for (i=l; i<l+increment; i++)
475    //  h[i]=NULL;
476    memset(&(h[l]),0,increment*sizeof(poly));
477  }
478  *p=h;
479}
480
481number pInitContent(poly ph);
482number pInitContent_a(poly ph);
483
484void pContent(poly ph)
485{
486#ifdef HAVE_RING2TOM
487  if (currRing->cring != 0) {
488    if (ph!=NULL)
489    {
490      number k = nGetUnit(pGetCoeff(ph));
491      poly h;
492      if (!nIsOne(k))
493      {
494        k = nGetUnit(pGetCoeff(ph));
495        pSetCoeff0(ph, nDiv(pGetCoeff(ph), k));
496        h = pNext(ph);
497        while (h != NULL)
498        {
499          pSetCoeff(h, nDiv(pGetCoeff(h), k));
500          pIter(h);
501        }
502        nDelete(&k);
503      }
504     return;
505    }
506    return;  //TODO OLIVER
507  }
508#endif
509  number h,d;
510  poly p;
511
512  if(TEST_OPT_CONTENTSB) return;
513  if(pNext(ph)==NULL)
514  {
515    pSetCoeff(ph,nInit(1));
516  }
517  else
518  {
519    nNormalize(pGetCoeff(ph));
520    if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
521    if (rField_is_Q_a())
522    {
523      h = nlInit(1);
524      p=ph;
525      while (p!=NULL)
526      { // each monom: coeff in Q_a
527        lnumber c_n_n=(lnumber)pGetCoeff(p);
528        napoly c_n=c_n_n->z;
529        while (c_n!=NULL)
530        { // each monom: coeff in Q
531          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
532          n_Delete(&h,currRing->algring);
533          h=d;
534          pIter(c_n);
535        }
536        pIter(p);
537      }
538      /* contains the 1/lcm of all denominators in c_n_n->z*/
539      number hz=h;
540      h = nlInit(1);
541      p=ph;
542      while (p!=NULL)
543      { // each monom: coeff in Q_a
544        lnumber c_n_n=(lnumber)pGetCoeff(p);
545        napoly c_n=c_n_n->n;
546        while (c_n!=NULL)
547        { // each monom: coeff in Q
548          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
549          n_Delete(&h,currRing->algring);
550          h=d;
551          pIter(c_n);
552        }
553        pIter(p);
554      }
555      /* contains the 1/lcm of all denominators in c_n_n->n*/
556      number htmp=nlInvers(h);
557      number hztmp=nlInvers(hz);
558      number hh=nlMult(hz,h);
559      nlDelete(&hz,currRing->algring);
560      nlDelete(&h,currRing->algring);
561      number hg=nlGcd(hztmp,htmp,currRing->algring);
562      nlDelete(&hztmp,currRing->algring);
563      nlDelete(&htmp,currRing->algring);
564      h=nlMult(hh,hg);
565      nlDelete(&hg,currRing->algring);
566      nlDelete(&hh,currRing->algring);
567      if(!nlIsOne(h))
568      {
569        p=ph;
570        while (p!=NULL)
571        { // each monom: coeff in Q_a
572          lnumber c_n_n=(lnumber)pGetCoeff(p);
573          napoly c_n=c_n_n->z;
574          while (c_n!=NULL)
575          { // each monom: coeff in Q
576            d=nlMult(h,pGetCoeff(c_n));
577            nlNormalize(d);
578            nlDelete(&pGetCoeff(c_n),currRing->algring);
579            pGetCoeff(c_n)=d;
580            pIter(c_n);
581          }
582          pIter(p);
583        }
584        p=ph;
585        while (p!=NULL)
586        { // each monom: coeff in Q_a
587          lnumber c_n_n=(lnumber)pGetCoeff(p);
588          napoly c_n=c_n_n->n;
589          while (c_n!=NULL)
590          { // each monom: coeff in Q
591            d=nlMult(h,pGetCoeff(c_n));
592            nlNormalize(d);
593            nlDelete(&pGetCoeff(c_n),currRing->algring);
594            pGetCoeff(c_n)=d;
595            pIter(c_n);
596          }
597          pIter(p);
598        }
599      }
600      nlDelete(&h,currRing->algring);
601    }
602    if (rField_is_Q())
603    {
604      h=pInitContent(ph);
605      p=ph;
606    }
607    else if ((rField_is_Extension())
608    && ((rPar(currRing)>1)||(currRing->minpoly==NULL)))
609    {
610      h=pInitContent_a(ph);
611      p=ph;
612    }
613    else
614    {
615      h=nCopy(pGetCoeff(ph));
616      p = pNext(ph);
617    }
618    while (p!=NULL)
619    {
620      nNormalize(pGetCoeff(p));
621      d=nGcd(h,pGetCoeff(p),currRing);
622      nDelete(&h);
623      h = d;
624      if(nIsOne(h))
625      {
626        break;
627      }
628      pIter(p);
629    }
630    p = ph;
631    //number tmp;
632    if(!nIsOne(h))
633    {
634      while (p!=NULL)
635      {
636        //d = nDiv(pGetCoeff(p),h);
637        //tmp = nIntDiv(pGetCoeff(p),h);
638        //if (!nEqual(d,tmp))
639        //{
640        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
641        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
642        //  nWrite(tmp);Print(StringAppendS("\n"));
643        //}
644        //nDelete(&tmp);
645        d = nIntDiv(pGetCoeff(p),h);
646        pSetCoeff(p,d);
647        pIter(p);
648      }
649    }
650    nDelete(&h);
651#ifdef HAVE_FACTORY
652    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
653    {
654      singclap_divide_content(ph);
655      if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
656    }
657#endif
658    if (rField_is_Q_a())
659    {
660      h = nlInit(1);
661      p=ph;
662      while (p!=NULL)
663      { // each monom: coeff in Q_a
664        lnumber c_n_n=(lnumber)pGetCoeff(p);
665        napoly c_n=c_n_n->z;
666        while (c_n!=NULL)
667        { // each monom: coeff in Q
668          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
669          n_Delete(&h,currRing->algring);
670          h=d;
671          pIter(c_n);
672        }
673        pIter(p);
674      }
675      /* contains the 1/lcm of all denominators in c_n_n->z*/
676      number hz=h;
677      h = nlInit(1);
678      p=ph;
679      while (p!=NULL)
680      { // each monom: coeff in Q_a
681        lnumber c_n_n=(lnumber)pGetCoeff(p);
682        napoly c_n=c_n_n->n;
683        while (c_n!=NULL)
684        { // each monom: coeff in Q
685          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
686          n_Delete(&h,currRing->algring);
687          h=d;
688          pIter(c_n);
689        }
690        pIter(p);
691      }
692      /* contains the 1/lcm of all denominators in c_n_n->n*/
693      number htmp=nlInvers(h);
694      number hztmp=nlInvers(hz);
695      number hh=nlMult(hz,h);
696      nlDelete(&hz,currRing->algring);
697      nlDelete(&h,currRing->algring);
698      number hg=nlGcd(hztmp,htmp,currRing->algring);
699      nlDelete(&hztmp,currRing->algring);
700      nlDelete(&htmp,currRing->algring);
701      h=nlMult(hh,hg);
702      nlDelete(&hg,currRing->algring);
703      nlDelete(&hh,currRing->algring);
704      if(!nlIsOne(h))
705      {
706        p=ph;
707        while (p!=NULL)
708        { // each monom: coeff in Q_a
709          lnumber c_n_n=(lnumber)pGetCoeff(p);
710          napoly c_n=c_n_n->z;
711          while (c_n!=NULL)
712          { // each monom: coeff in Q
713            d=nlMult(h,pGetCoeff(c_n));
714            nlNormalize(d);
715            nlDelete(&pGetCoeff(c_n),currRing->algring);
716            pGetCoeff(c_n)=d;
717            pIter(c_n);
718          }
719          pIter(p);
720        }
721        p=ph;
722        while (p!=NULL)
723        { // each monom: coeff in Q_a
724          lnumber c_n_n=(lnumber)pGetCoeff(p);
725          napoly c_n=c_n_n->n;
726          while (c_n!=NULL)
727          { // each monom: coeff in Q
728            d=nlMult(h,pGetCoeff(c_n));
729            nlNormalize(d);
730            nlDelete(&pGetCoeff(c_n),currRing->algring);
731            pGetCoeff(c_n)=d;
732            pIter(c_n);
733          }
734          pIter(p);
735        }
736      }
737      nlDelete(&h,currRing->algring);
738    }
739  }
740}
741void pSimpleContent(poly ph,int smax)
742{
743  if(TEST_OPT_CONTENTSB) return;
744  if (ph==NULL) return;
745  if (pNext(ph)==NULL)
746  {
747    pSetCoeff(ph,nInit(1));
748    return;
749  }
750  if ((pNext(pNext(ph))==NULL)||(!rField_is_Q()))
751  {
752    return;
753  }
754  number d=pInitContent(ph);
755  if (nlSize(d)<=smax)
756  {
757    //if (TEST_OPT_PROT) PrintS("G");
758    return;
759  }
760  poly p=ph;
761  number h=d;
762  if (smax==1) smax=2;
763  while (p!=NULL)
764  {
765#if 0
766    d=nlGcd(h,pGetCoeff(p),currRing);
767    nlDelete(&h,currRing);
768    h = d;
769#else
770    nlInpGcd(h,pGetCoeff(p),currRing);
771#endif
772    if(nlSize(h)<smax)
773    {
774      //if (TEST_OPT_PROT) PrintS("g");
775      return;
776    }
777    pIter(p);
778  }
779  p = ph;
780  if (!nlGreaterZero(pGetCoeff(p))) h=nlNeg(h);
781  if(nlIsOne(h)) return;
782  //if (TEST_OPT_PROT) PrintS("c");
783  while (p!=NULL)
784  {
785#if 1
786    d = nlIntDiv(pGetCoeff(p),h);
787    pSetCoeff(p,d);
788#else
789    nlInpIntDiv(pGetCoeff(p),h,currRing);
790#endif
791    pIter(p);
792  }
793  nlDelete(&h,currRing);
794}
795
796number pInitContent(poly ph)
797// only for coefficients in Q
798#if 0
799{
800  assume(!TEST_OPT_CONTENTSB);
801  assume(ph!=NULL);
802  assume(pNext(ph)!=NULL);
803  assume(rField_is_Q());
804  if (pNext(pNext(ph))==NULL)
805  {
806    return nlGetNom(pGetCoeff(pNext(ph)),currRing);
807  }
808  poly p=ph;
809  number n1=nlGetNom(pGetCoeff(p),currRing);
810  pIter(p);
811  number n2=nlGetNom(pGetCoeff(p),currRing);
812  pIter(p);
813  number d;
814  number t;
815  loop
816  {
817    nlNormalize(pGetCoeff(p));
818    t=nlGetNom(pGetCoeff(p),currRing);
819    if (nlGreaterZero(t))
820      d=nlAdd(n1,t);
821    else
822      d=nlSub(n1,t);
823    nlDelete(&t,currRing);
824    nlDelete(&n1,currRing);
825    n1=d;
826    pIter(p);
827    if (p==NULL) break;
828    nlNormalize(pGetCoeff(p));
829    t=nlGetNom(pGetCoeff(p),currRing);
830    if (nlGreaterZero(t))
831      d=nlAdd(n2,t);
832    else
833      d=nlSub(n2,t);
834    nlDelete(&t,currRing);
835    nlDelete(&n2,currRing);
836    n2=d;
837    pIter(p);
838    if (p==NULL) break;
839  }
840  d=nlGcd(n1,n2,currRing);
841  nlDelete(&n1,currRing);
842  nlDelete(&n2,currRing);
843  return d;
844}
845#else
846{
847  number d=pGetCoeff(ph);
848  if(SR_HDL(d)&SR_INT) return d;
849  int s=mpz_size1(&d->z);
850  int s2=-1;
851  number d2;
852  loop
853  {
854    pIter(ph);
855    if(ph==NULL)
856    {
857      if (s2==-1) return nlCopy(d);
858      break;
859    }
860    if (SR_HDL(pGetCoeff(ph))&SR_INT)
861    {
862      s2=s;
863      d2=d;
864      s=0;
865      d=pGetCoeff(ph);
866      if (s2==0) break;
867    }
868    else
869    if (mpz_size1(&(pGetCoeff(ph)->z))<=s)
870    {
871      s2=s;
872      d2=d;
873      d=pGetCoeff(ph);
874      s=mpz_size1(&d->z);
875    }
876  }
877  return nlGcd(d,d2,currRing);
878}
879#endif
880
881number pInitContent_a(poly ph)
882// only for coefficients in K(a) anf K(a,...)
883{
884  number d=pGetCoeff(ph);
885  int s=naParDeg(d);
886  if (s /* naParDeg(d)*/ <=1) return naCopy(d);
887  int s2=-1;
888  number d2;
889  int ss;
890  loop
891  {
892    pIter(ph);
893    if(ph==NULL)
894    {
895      if (s2==-1) return naCopy(d);
896      break;
897    }
898    if ((ss=naParDeg(pGetCoeff(ph)))<s)
899    {
900      s2=s;
901      d2=d;
902      s=ss;
903      d=pGetCoeff(ph);
904      if (s2<=1) break;
905    }
906  }
907  return naGcd(d,d2,currRing);
908}
909
910
911//void pContent(poly ph)
912//{
913//  number h,d;
914//  poly p;
915//
916//  p = ph;
917//  if(pNext(p)==NULL)
918//  {
919//    pSetCoeff(p,nInit(1));
920//  }
921//  else
922//  {
923//#ifdef PDEBUG
924//    if (!pTest(p)) return;
925//#endif
926//    nNormalize(pGetCoeff(p));
927//    if(!nGreaterZero(pGetCoeff(ph)))
928//    {
929//      ph = pNeg(ph);
930//      nNormalize(pGetCoeff(p));
931//    }
932//    h=pGetCoeff(p);
933//    pIter(p);
934//    while (p!=NULL)
935//    {
936//      nNormalize(pGetCoeff(p));
937//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
938//      pIter(p);
939//    }
940//    h=nCopy(h);
941//    p=ph;
942//    while (p!=NULL)
943//    {
944//      d=nGcd(h,pGetCoeff(p));
945//      nDelete(&h);
946//      h = d;
947//      if(nIsOne(h))
948//      {
949//        break;
950//      }
951//      pIter(p);
952//    }
953//    p = ph;
954//    //number tmp;
955//    if(!nIsOne(h))
956//    {
957//      while (p!=NULL)
958//      {
959//        d = nIntDiv(pGetCoeff(p),h);
960//        pSetCoeff(p,d);
961//        pIter(p);
962//      }
963//    }
964//    nDelete(&h);
965//#ifdef HAVE_FACTORY
966//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
967//    {
968//      pTest(ph);
969//      singclap_divide_content(ph);
970//      pTest(ph);
971//    }
972//#endif
973//  }
974//}
975void p_Content(poly ph, ring r)
976{
977  number h,d;
978  poly p;
979
980  if(pNext(ph)==NULL)
981  {
982    pSetCoeff(ph,n_Init(1,r));
983  }
984  else
985  {
986    n_Normalize(pGetCoeff(ph),r);
987    if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
988    h=n_Copy(pGetCoeff(ph),r);
989    p = pNext(ph);
990    while (p!=NULL)
991    {
992      n_Normalize(pGetCoeff(p),r);
993      d=n_Gcd(h,pGetCoeff(p),r);
994      n_Delete(&h,r);
995      h = d;
996      if(n_IsOne(h,r))
997      {
998        break;
999      }
1000      pIter(p);
1001    }
1002    p = ph;
1003    //number tmp;
1004    if(!n_IsOne(h,r))
1005    {
1006      while (p!=NULL)
1007      {
1008        //d = nDiv(pGetCoeff(p),h);
1009        //tmp = nIntDiv(pGetCoeff(p),h);
1010        //if (!nEqual(d,tmp))
1011        //{
1012        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
1013        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
1014        //  nWrite(tmp);Print(StringAppendS("\n"));
1015        //}
1016        //nDelete(&tmp);
1017        d = n_IntDiv(pGetCoeff(p),h,r);
1018        p_SetCoeff(p,d,r);
1019        pIter(p);
1020      }
1021    }
1022    n_Delete(&h,r);
1023#ifdef HAVE_FACTORY
1024    //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
1025    //{
1026    //  singclap_divide_content(ph);
1027    //  if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
1028    //}
1029#endif
1030  }
1031}
1032
1033void pCleardenom(poly ph)
1034{
1035  number d, h;
1036  poly p;
1037
1038#ifdef HAVE_RING2TOM
1039  if (currRing->cring == 1)
1040  {
1041    pContent(ph);
1042    return;
1043  }
1044#endif
1045  p = ph;
1046  if(pNext(p)==NULL)
1047  {
1048    if (TEST_OPT_CONTENTSB)
1049    {
1050      number n=nGetDenom(pGetCoeff(p));
1051      if (!nIsOne(n))
1052      {
1053        number nn=nMult(pGetCoeff(p),n);
1054        nNormalize(nn);
1055        pSetCoeff(p,nn);
1056      }
1057      nDelete(&n);
1058    }
1059    else
1060      pSetCoeff(p,nInit(1));
1061  }
1062  else
1063  {
1064    h = nInit(1);
1065    while (p!=NULL)
1066    {
1067      nNormalize(pGetCoeff(p));
1068      d=nLcm(h,pGetCoeff(p),currRing);
1069      nDelete(&h);
1070      h=d;
1071      pIter(p);
1072    }
1073    /* contains the 1/lcm of all denominators */
1074    if(!nIsOne(h))
1075    {
1076      p = ph;
1077      while (p!=NULL)
1078      {
1079        /* should be:
1080        * number hh;
1081        * nGetDenom(p->coef,&hh);
1082        * nMult(&h,&hh,&d);
1083        * nNormalize(d);
1084        * nDelete(&hh);
1085        * nMult(d,p->coef,&hh);
1086        * nDelete(&d);
1087        * nDelete(&(p->coef));
1088        * p->coef =hh;
1089        */
1090        d=nMult(h,pGetCoeff(p));
1091        nNormalize(d);
1092        pSetCoeff(p,d);
1093        pIter(p);
1094      }
1095      nDelete(&h);
1096      if (nGetChar()==1)
1097      {
1098        loop
1099        {
1100          h = nInit(1);
1101          p=ph;
1102          while (p!=NULL)
1103          {
1104            d=nLcm(h,pGetCoeff(p),currRing);
1105            nDelete(&h);
1106            h=d;
1107            pIter(p);
1108          }
1109          /* contains the 1/lcm of all denominators */
1110          if(!nIsOne(h))
1111          {
1112            p = ph;
1113            while (p!=NULL)
1114            {
1115              /* should be:
1116              * number hh;
1117              * nGetDenom(p->coef,&hh);
1118              * nMult(&h,&hh,&d);
1119              * nNormalize(d);
1120              * nDelete(&hh);
1121              * nMult(d,p->coef,&hh);
1122              * nDelete(&d);
1123              * nDelete(&(p->coef));
1124              * p->coef =hh;
1125              */
1126              d=nMult(h,pGetCoeff(p));
1127              nNormalize(d);
1128              pSetCoeff(p,d);
1129              pIter(p);
1130            }
1131            nDelete(&h);
1132          }
1133          else
1134          {
1135            nDelete(&h);
1136            break;
1137          }
1138        }
1139      }
1140    }
1141    if (h!=NULL) nDelete(&h);
1142    pContent(ph);
1143  }
1144}
1145
1146void pCleardenom_n(poly ph,number &c)
1147{
1148  number d, h;
1149  poly p;
1150
1151  p = ph;
1152  if(pNext(p)==NULL)
1153  {
1154    c=nInvers(pGetCoeff(p));
1155    pSetCoeff(p,nInit(1));
1156  }
1157  else
1158  {
1159    h = nInit(1);
1160    while (p!=NULL)
1161    {
1162      nNormalize(pGetCoeff(p));
1163      d=nLcm(h,pGetCoeff(p),currRing);
1164      nDelete(&h);
1165      h=d;
1166      pIter(p);
1167    }
1168    c=h;
1169    /* contains the 1/lcm of all denominators */
1170    if(!nIsOne(h))
1171    {
1172      p = ph;
1173      while (p!=NULL)
1174      {
1175        /* should be:
1176        * number hh;
1177        * nGetDenom(p->coef,&hh);
1178        * nMult(&h,&hh,&d);
1179        * nNormalize(d);
1180        * nDelete(&hh);
1181        * nMult(d,p->coef,&hh);
1182        * nDelete(&d);
1183        * nDelete(&(p->coef));
1184        * p->coef =hh;
1185        */
1186        d=nMult(h,pGetCoeff(p));
1187        nNormalize(d);
1188        pSetCoeff(p,d);
1189        pIter(p);
1190      }
1191      if (nGetChar()==1)
1192      {
1193        loop
1194        {
1195          h = nInit(1);
1196          p=ph;
1197          while (p!=NULL)
1198          {
1199            d=nLcm(h,pGetCoeff(p),currRing);
1200            nDelete(&h);
1201            h=d;
1202            pIter(p);
1203          }
1204          /* contains the 1/lcm of all denominators */
1205          if(!nIsOne(h))
1206          {
1207            p = ph;
1208            while (p!=NULL)
1209            {
1210              /* should be:
1211              * number hh;
1212              * nGetDenom(p->coef,&hh);
1213              * nMult(&h,&hh,&d);
1214              * nNormalize(d);
1215              * nDelete(&hh);
1216              * nMult(d,p->coef,&hh);
1217              * nDelete(&d);
1218              * nDelete(&(p->coef));
1219              * p->coef =hh;
1220              */
1221              d=nMult(h,pGetCoeff(p));
1222              nNormalize(d);
1223              pSetCoeff(p,d);
1224              pIter(p);
1225            }
1226            number t=nMult(c,h);
1227            nDelete(&c);
1228            c=t;
1229          }
1230          else
1231          {
1232            break;
1233          }
1234          nDelete(&h);
1235        }
1236      }
1237    }
1238  }
1239}
1240
1241/*2
1242*tests if p is homogeneous with respect to the actual weigths
1243*/
1244BOOLEAN pIsHomogeneous (poly p)
1245{
1246  poly qp=p;
1247  int o;
1248
1249  if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
1250  pFDegProc d=(pLexOrder ? pTotaldegree : pFDeg );
1251  o = d(p,currRing);
1252  do
1253  {
1254    if (d(qp,currRing) != o) return FALSE;
1255    pIter(qp);
1256  }
1257  while (qp != NULL);
1258  return TRUE;
1259}
1260
1261// orders monoms of poly using merge sort (ususally faster than
1262// insertion sort). ASSUMES that pSetm was performed on monoms
1263poly pOrdPolyMerge(poly p)
1264{
1265  poly qq,pp,result=NULL;
1266
1267  if (p == NULL) return NULL;
1268
1269  loop
1270  {
1271    qq = p;
1272    loop
1273    {
1274      if (pNext(p) == NULL)
1275      {
1276        result=pAdd(result, qq);
1277        pTest(result);
1278        return result;
1279      }
1280      if (pLmCmp(p,pNext(p)) != 1)
1281      {
1282        pp = p;
1283        pIter(p);
1284        pNext(pp) = NULL;
1285        result = pAdd(result, qq);
1286        break;
1287      }
1288      pIter(p);
1289    }
1290  }
1291}
1292
1293// orders monoms of poly using insertion sort, performs pSetm on each monom
1294poly pOrdPolyInsertSetm(poly p)
1295{
1296  poly qq,result = NULL;
1297
1298#if 0
1299  while (p != NULL)
1300  {
1301    qq = p;
1302    pIter(p);
1303    qq->next = NULL;
1304    pSetm(qq);
1305    result = pAdd(result,qq);
1306    pTest(result);
1307  }
1308#else
1309  while (p != NULL)
1310  {
1311    qq = p;
1312    pIter(p);
1313    qq->next = result;
1314    result = qq;
1315    pSetm(qq);
1316  }
1317  p = result;
1318  result = NULL;
1319  while (p != NULL)
1320  {
1321    qq = p;
1322    pIter(p);
1323    qq->next = NULL;
1324    result = pAdd(result, qq);
1325  }
1326  pTest(result);
1327#endif
1328  return result;
1329}
1330
1331/*2
1332*returns a re-ordered copy of a polynomial, with permutation of the variables
1333*/
1334poly pPermPoly (poly p, int * perm, ring oldRing, nMapFunc nMap,
1335   int *par_perm, int OldPar)
1336{
1337  int OldpVariables = oldRing->N;
1338  poly result = NULL;
1339  poly result_last = NULL;
1340  poly aq=NULL; /* the map coefficient */
1341  poly qq; /* the mapped monomial */
1342
1343  while (p != NULL)
1344  {
1345    if ((OldPar==0)||(rField_is_GF(oldRing)))
1346    {
1347      qq = pInit();
1348      number n=nMap(pGetCoeff(p));
1349      if ((currRing->minpoly!=NULL)
1350      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1351      {
1352        nNormalize(n);
1353      }
1354      pGetCoeff(qq)=n;
1355    // coef may be zero:  pTest(qq);
1356    }
1357    else
1358    {
1359      qq=pOne();
1360      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
1361      if ((currRing->minpoly!=NULL)
1362      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1363      {
1364        poly tmp=aq;
1365        while (tmp!=NULL)
1366        {
1367          number n=pGetCoeff(tmp);
1368          nNormalize(n);
1369          pGetCoeff(tmp)=n;
1370          pIter(tmp);
1371        }
1372      }
1373      pTest(aq);
1374    }
1375    if (rRing_has_Comp(currRing)) pSetComp(qq, p_GetComp(p,oldRing));
1376    if (nIsZero(pGetCoeff(qq)))
1377    {
1378      pDeleteLm(&qq);
1379    }
1380    else
1381    {
1382      int i;
1383      int mapped_to_par=0;
1384      for(i=1; i<=OldpVariables; i++)
1385      {
1386        int e=p_GetExp(p,i,oldRing);
1387        if (e!=0)
1388        {
1389          if (perm==NULL)
1390          {
1391            pSetExp(qq,i, e);
1392          }
1393          else if (perm[i]>0)
1394            pAddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/);
1395          else if (perm[i]<0)
1396          {
1397            if (rField_is_GF())
1398            {
1399              number c=pGetCoeff(qq);
1400              number ee=nfPar(1);
1401              number eee;nfPower(ee,e,&eee); //nfDelete(ee,currRing);
1402              ee=nfMult(c,eee);
1403              //nfDelete(c,currRing);nfDelete(eee,currRing);
1404              pSetCoeff0(qq,ee);
1405            }
1406            else
1407            {
1408              lnumber c=(lnumber)pGetCoeff(qq);
1409              if (c->z->next==NULL)
1410                napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1411              else /* more difficult: we have really to multiply: */
1412              {
1413                lnumber mmc=(lnumber)naInit(1);
1414                napSetExp(mmc->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1415                napSetm(mmc->z);
1416                pGetCoeff(qq)=naMult((number)c,(number)mmc);
1417                nDelete((number *)&c);
1418                nDelete((number *)&mmc); 
1419              }
1420              mapped_to_par=1;
1421            }
1422          }
1423          else
1424          {
1425            /* this variable maps to 0 !*/
1426            pDeleteLm(&qq);
1427            break;
1428          }
1429        }
1430      }
1431      if (mapped_to_par
1432      && (currRing->minpoly!=NULL))
1433      {
1434        number n=pGetCoeff(qq);
1435        nNormalize(n);
1436        pGetCoeff(qq)=n;
1437      }
1438    }
1439    pIter(p);
1440#if 1
1441    if (qq!=NULL)
1442    {
1443      pSetm(qq);
1444      pTest(aq);
1445      pTest(qq);
1446      if (aq!=NULL) qq=pMult(aq,qq);
1447      aq = qq;
1448      while (pNext(aq) != NULL) pIter(aq);
1449      if (result_last==NULL)
1450      {
1451        result=qq;
1452      }
1453      else
1454      {
1455        pNext(result_last)=qq;
1456      }
1457      result_last=aq;
1458      aq = NULL;
1459    }
1460    else if (aq!=NULL)
1461    {
1462      pDelete(&aq);
1463    }
1464  }
1465  result=pSortAdd(result);
1466#else
1467  //  if (qq!=NULL)
1468  //  {
1469  //    pSetm(qq);
1470  //    pTest(qq);
1471  //    pTest(aq);
1472  //    if (aq!=NULL) qq=pMult(aq,qq);
1473  //    aq = qq;
1474  //    while (pNext(aq) != NULL) pIter(aq);
1475  //    pNext(aq) = result;
1476  //    aq = NULL;
1477  //    result = qq;
1478  //  }
1479  //  else if (aq!=NULL)
1480  //  {
1481  //    pDelete(&aq);
1482  //  }
1483  //}
1484  //p = result;
1485  //result = NULL;
1486  //while (p != NULL)
1487  //{
1488  //  qq = p;
1489  //  pIter(p);
1490  //  qq->next = NULL;
1491  //  result = pAdd(result, qq);
1492  //}
1493#endif
1494  pTest(result);
1495  return result;
1496}
1497
1498#if 0
1499/*2
1500*returns a re-ordered copy of a polynomial, with permutation of the variables
1501*/
1502poly p_PermPoly (poly p, int * perm, ring oldRing,
1503   int *par_perm, int OldPar, ring newRing)
1504{
1505  int OldpVariables = oldRing->N;
1506  poly result = NULL;
1507  poly result_last = NULL;
1508  poly aq=NULL; /* the map coefficient */
1509  poly qq; /* the mapped monomial */
1510
1511  while (p != NULL)
1512  {
1513    if (OldPar==0)
1514    {
1515      qq = pInit();
1516      number n=newRing->cf->nMap(pGetCoeff(p));
1517      if ((newRing->minpoly!=NULL)
1518      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
1519      {
1520        newRing->cf->nNormalize(n);
1521      }
1522      pGetCoeff(qq)=n;
1523    // coef may be zero:  pTest(qq);
1524    }
1525    else
1526    {
1527      qq=p_ISet(1, newRing);
1528      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
1529      if ((newRing->minpoly!=NULL)
1530      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
1531      {
1532        poly tmp=aq;
1533        while (tmp!=NULL)
1534        {
1535          number n=pGetCoeff(tmp);
1536          newRing->cf->nNormalize(n);
1537          pGetCoeff(tmp)=n;
1538          pIter(tmp);
1539        }
1540      }
1541      //pTest(aq);
1542    }
1543    p_SetComp(qq, p_GetComp(p,oldRing), newRing);
1544    if (newRing->cf->nIsZero(pGetCoeff(qq)))
1545    {
1546      p_DeleteLm(&qq, newRing);
1547    }
1548    else
1549    {
1550      int i;
1551      int mapped_to_par=0;
1552      for(i=1; i<=OldpVariables; i++)
1553      {
1554        int e=p_GetExp(p,i,oldRing);
1555        if (e!=0)
1556        {
1557          if (perm==NULL)
1558          {
1559            p_SetExp(qq,i, e, newRing);
1560          }
1561          else if (perm[i]>0)
1562            p_AddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/, newRing);
1563          else if (perm[i]<0)
1564          {
1565            lnumber c=(lnumber)pGetCoeff(qq);
1566            napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1567            mapped_to_par=1;
1568          }
1569          else
1570          {
1571            /* this variable maps to 0 !*/
1572            p_DeleteLm(&qq, newRing);
1573            break;
1574          }
1575        }
1576      }
1577      if (mapped_to_par
1578      && (newRing->minpoly!=NULL))
1579      {
1580        number n=pGetCoeff(qq);
1581        newRing->cf->nNormalize(n);
1582        pGetCoeff(qq)=n;
1583      }
1584    }
1585    pIter(p);
1586    if (qq!=NULL)
1587    {
1588      p_Setm(qq, newRing);
1589      //pTest(aq);
1590      //pTest(qq);
1591      if (aq!=NULL) qq=pMult(aq,qq);
1592      aq = qq;
1593      while (pNext(aq) != NULL) pIter(aq);
1594      if (result_last==NULL)
1595      {
1596        result=qq;
1597      }
1598      else
1599      {
1600        pNext(result_last)=qq;
1601      }
1602      result_last=aq;
1603      aq = NULL;
1604    }
1605    else if (aq!=NULL)
1606    {
1607      p_Delete(&aq, newRing);
1608    }
1609  }
1610  result=pOrdPolyMerge(result);
1611  //pTest(result);
1612  return result;
1613}
1614#endif
1615
1616poly ppJet(poly p, int m)
1617{
1618  poly r=NULL;
1619  poly t=NULL;
1620
1621  while (p!=NULL)
1622  {
1623    if (pTotaldegree(p)<=m)
1624    {
1625      if (r==NULL)
1626        r=pHead(p);
1627      else
1628      if (t==NULL)
1629      {
1630        pNext(r)=pHead(p);
1631        t=pNext(r);
1632      }
1633      else
1634      {
1635        pNext(t)=pHead(p);
1636        pIter(t);
1637      }
1638    }
1639    pIter(p);
1640  }
1641  return r;
1642}
1643
1644poly pJet(poly p, int m)
1645{
1646  poly t=NULL;
1647
1648  while((p!=NULL) && (pTotaldegree(p)>m)) pLmDelete(&p);
1649  if (p==NULL) return NULL;
1650  poly r=p;
1651  while (pNext(p)!=NULL)
1652  {
1653    if (pTotaldegree(pNext(p))>m)
1654    {
1655      pLmDelete(&pNext(p));
1656    }
1657    else
1658      pIter(p);
1659  }
1660  return r;
1661}
1662
1663poly ppJetW(poly p, int m, short *w)
1664{
1665  poly r=NULL;
1666  poly t=NULL;
1667  while (p!=NULL)
1668  {
1669    if (totaldegreeWecart_IV(p,currRing,w)<=m)
1670    {
1671      if (r==NULL)
1672        r=pHead(p);
1673      else
1674      if (t==NULL)
1675      {
1676        pNext(r)=pHead(p);
1677        t=pNext(r);
1678      }
1679      else
1680      {
1681        pNext(t)=pHead(p);
1682        pIter(t);
1683      }
1684    }
1685    pIter(p);
1686  }
1687  return r;
1688}
1689
1690poly pJetW(poly p, int m, short *w)
1691{
1692  poly t=NULL;
1693  while((p!=NULL) && (totaldegreeWecart_IV(p,currRing,w)>m)) pLmDelete(&p);
1694  if (p==NULL) return NULL;
1695  poly r=p;
1696  while (pNext(p)!=NULL)
1697  {
1698    if (totaldegreeWecart_IV(pNext(p),currRing,w)>m)
1699    {
1700      pLmDelete(&pNext(p));
1701    }
1702    else
1703      pIter(p);
1704  }
1705  return r;
1706}
1707
1708int pMinDeg(poly p,intvec *w)
1709{
1710  if(p==NULL)
1711    return -1;
1712  int d=-1;
1713  while(p!=NULL)
1714  {
1715    int d0=0;
1716    for(int j=0;j<pVariables;j++)
1717      if(w==NULL||j>=w->length())
1718        d0+=pGetExp(p,j+1);
1719      else
1720        d0+=(*w)[j]*pGetExp(p,j+1);
1721    if(d0<d||d==-1)
1722      d=d0;
1723    pIter(p);
1724  }
1725  return d;
1726}
1727
1728poly pSeries(int n,poly p,poly u, intvec *w)
1729{
1730  short *ww=iv2array(w);
1731  if(p!=NULL)
1732  {
1733    if(u==NULL)
1734      p=pJetW(p,n,ww);
1735    else
1736      p=pJetW(pMult(p,pInvers(n-pMinDeg(p,w),u,w)),n,ww);
1737  }
1738  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1739  return p;
1740}
1741
1742poly pInvers(int n,poly u,intvec *w)
1743{
1744  short *ww=iv2array(w);
1745  if(n<0)
1746    return NULL;
1747  number u0=nInvers(pGetCoeff(u));
1748  poly v=pNSet(u0);
1749  if(n==0)
1750    return v;
1751  poly u1=pJetW(pSub(pOne(),pMult_nn(u,u0)),n,ww);
1752  if(u1==NULL)
1753    return v;
1754  poly v1=pMult_nn(pCopy(u1),u0);
1755  v=pAdd(v,pCopy(v1));
1756  for(int i=n/pMinDeg(u1,w);i>1;i--)
1757  {
1758    v1=pJetW(pMult(v1,pCopy(u1)),n,ww);
1759    v=pAdd(v,pCopy(v1));
1760  }
1761  pDelete(&u1);
1762  pDelete(&v1);
1763  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1764  return v;
1765}
1766
1767long pDegW(poly p, const short *w)
1768{
1769  long r=-LONG_MAX;
1770
1771  while (p!=NULL)
1772  {
1773    long t=totaldegreeWecart_IV(p,currRing,w);
1774    if (t>r) r=t;
1775    pIter(p);
1776  }
1777  return r;
1778}
1779
1780/*-----------type conversions ----------------------------*/
1781/*2
1782* input: a set of polys (len elements: p[0]..p[len-1])
1783* output: a vector
1784* p will not be changed
1785*/
1786poly  pPolys2Vec(polyset p, int len)
1787{
1788  poly v=NULL;
1789  poly h;
1790  int i;
1791
1792  for (i=len-1; i>=0; i--)
1793  {
1794    if (p[i])
1795    {
1796      h=pCopy(p[i]);
1797      pSetCompP(h,i+1);
1798      v=pAdd(v,h);
1799    }
1800  }
1801 return v;
1802}
1803
1804/*2
1805* convert a vector to a set of polys,
1806* allocates the polyset, (entries 0..(*len)-1)
1807* the vector will not be changed
1808*/
1809void  pVec2Polys(poly v, polyset *p, int *len)
1810{
1811  poly h;
1812  int k;
1813
1814  *len=pMaxComp(v);
1815  if (*len==0) *len=1;
1816  *p=(polyset)omAlloc0((*len)*sizeof(poly));
1817  while (v!=NULL)
1818  {
1819    h=pHead(v);
1820    k=pGetComp(h);
1821    pSetComp(h,0);
1822    (*p)[k-1]=pAdd((*p)[k-1],h);
1823    pIter(v);
1824  }
1825}
1826
1827int p_Var(poly m,const ring r)
1828{
1829  if (m==NULL) return 0;
1830  if (pNext(m)!=NULL) return 0;
1831  int i,e=0;
1832  for (i=r->N; i>0; i--)
1833  {
1834    if (p_GetExp(m,i,r)==1)
1835    {
1836      if (e==0) e=i;
1837      else return 0;
1838    }
1839  }
1840  return e;
1841}
1842
1843/*----------utilities for syzygies--------------*/
1844//BOOLEAN   pVectorHasUnitM(poly p, int * k)
1845//{
1846//  while (p!=NULL)
1847//  {
1848//    if (pLmIsConstantComp(p))
1849//    {
1850//      *k = pGetComp(p);
1851//      return TRUE;
1852//    }
1853//    else pIter(p);
1854//  }
1855//  return FALSE;
1856//}
1857
1858BOOLEAN   pVectorHasUnitB(poly p, int * k)
1859{
1860  poly q=p,qq;
1861  int i;
1862
1863  while (q!=NULL)
1864  {
1865    if (pLmIsConstantComp(q))
1866    {
1867      i = pGetComp(q);
1868      qq = p;
1869      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1870      if (qq == q)
1871      {
1872        *k = i;
1873        return TRUE;
1874      }
1875      else
1876        pIter(q);
1877    }
1878    else pIter(q);
1879  }
1880  return FALSE;
1881}
1882
1883void   pVectorHasUnit(poly p, int * k, int * len)
1884{
1885  poly q=p,qq;
1886  int i,j=0;
1887
1888  *len = 0;
1889  while (q!=NULL)
1890  {
1891    if (pLmIsConstantComp(q))
1892    {
1893      i = pGetComp(q);
1894      qq = p;
1895      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1896      if (qq == q)
1897      {
1898       j = 0;
1899       while (qq!=NULL)
1900       {
1901         if (pGetComp(qq)==i) j++;
1902        pIter(qq);
1903       }
1904       if ((*len == 0) || (j<*len))
1905       {
1906         *len = j;
1907         *k = i;
1908       }
1909      }
1910    }
1911    pIter(q);
1912  }
1913}
1914
1915/*2
1916* returns TRUE if p1 = p2
1917*/
1918BOOLEAN p_EqualPolys(poly p1,poly p2, ring r)
1919{
1920  while ((p1 != NULL) && (p2 != NULL))
1921  {
1922    if (! p_LmEqual(p1, p2,r))
1923      return FALSE;
1924    if (! n_Equal(p_GetCoeff(p1,r), p_GetCoeff(p2,r),r ))
1925      return FALSE;
1926    pIter(p1);
1927    pIter(p2);
1928  }
1929  return (p1==p2);
1930}
1931
1932/*2
1933*returns TRUE if p1 is a skalar multiple of p2
1934*assume p1 != NULL and p2 != NULL
1935*/
1936BOOLEAN pComparePolys(poly p1,poly p2)
1937{
1938  number n,nn;
1939  int i;
1940  pAssume(p1 != NULL && p2 != NULL);
1941
1942  if (!pLmEqual(p1,p2)) //compare leading mons
1943      return FALSE;
1944  if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
1945     return FALSE;
1946  if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
1947     return FALSE;
1948  if (pLength(p1) != pLength(p2))
1949    return FALSE;
1950  n=nDiv(pGetCoeff(p1),pGetCoeff(p2));
1951  while ((p1 != NULL) /*&& (p2 != NULL)*/)
1952  {
1953    if ( ! pLmEqual(p1, p2))
1954    {
1955        nDelete(&n);
1956        return FALSE;
1957    }
1958    if (!nEqual(pGetCoeff(p1),nn=nMult(pGetCoeff(p2),n)))
1959    {
1960      nDelete(&n);
1961      nDelete(&nn);
1962      return FALSE;
1963    }
1964    nDelete(&nn);
1965    pIter(p1);
1966    pIter(p2);
1967  }
1968  nDelete(&n);
1969  return TRUE;
1970}
Note: See TracBrowser for help on using the repository browser.