source: git/kernel/polys1.cc @ 5a9e7b

spielwiese
Last change on this file since 5a9e7b was 7f5219, checked in by Hans Schönemann <hannes@…>, 18 years ago
*hannes: fixed gcd/cleardenom handling git-svn-id: file:///usr/local/Singular/svn/trunk@9449 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.22 2006-10-06 16:39:43 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/*-------- several access procedures to monomials -------------------- */
31/*
32* the module weights for std
33*/
34static pFDegProc pOldFDeg;
35static pLDegProc pOldLDeg;
36static intvec * pModW;
37static BOOLEAN pOldLexOrder;
38
39static long pModDeg(poly p, ring r = currRing)
40{
41  long d=pOldFDeg(p, r);
42  int c=p_GetComp(p, r);
43  if ((c>0) && (pModW->range(c-1))) d+= (*pModW)[c-1];
44  return d;
45  //return pOldFDeg(p, r)+(*pModW)[p_GetComp(p, r)-1];
46}
47
48void pSetModDeg(intvec *w)
49{
50  if (w!=NULL)
51  {
52    pModW = w;
53    pOldFDeg = pFDeg;
54    pOldLDeg = pLDeg;
55    pOldLexOrder = pLexOrder;
56    pSetDegProcs(pModDeg);
57    pLexOrder = TRUE;
58  }
59  else
60  {
61    pModW = NULL;
62    pRestoreDegProcs(pOldFDeg, pOldLDeg);
63    pLexOrder = pOldLexOrder;
64  }
65}
66
67
68/*2
69* subtract p2 from p1, p1 and p2 are destroyed
70* do not put attention on speed: the procedure is only used in the interpreter
71*/
72poly pSub(poly p1, poly p2)
73{
74  return pAdd(p1, pNeg(p2));
75}
76
77/*3
78*  create binomial coef.
79*/
80static number* pnBin(int exp)
81{
82  int e, i, h;
83  number x, y, *bin=NULL;
84
85  x = nInit(exp);
86  if (nIsZero(x))
87  {
88    nDelete(&x);
89    return bin;
90  }
91  h = (exp >> 1) + 1;
92  bin = (number *)omAlloc0(h*sizeof(number));
93  bin[1] = x;
94  if (exp < 4)
95    return bin;
96  i = exp - 1;
97  for (e=2; e<h; e++)
98  {
99      x = nInit(i);
100      i--;
101      y = nMult(x,bin[e-1]);
102      nDelete(&x);
103      x = nInit(e);
104      bin[e] = nIntDiv(y,x);
105      nDelete(&x);
106      nDelete(&y);
107  }
108  return bin;
109}
110
111static void pnFreeBin(number *bin, int exp)
112{
113  int e, h = (exp >> 1) + 1;
114
115  if (bin[1] != NULL)
116  {
117    for (e=1; e<h; e++)
118      nDelete(&(bin[e]));
119  }
120  omFreeSize((ADDRESS)bin, h*sizeof(number));
121}
122
123/*3
124* compute for a monomial m
125* the power m^exp, exp > 1
126* destroys p
127*/
128static poly pMonPower(poly p, int exp)
129{
130  int i;
131
132  if(!nIsOne(pGetCoeff(p)))
133  {
134    number x, y;
135    y = pGetCoeff(p);
136    nPower(y,exp,&x);
137    nDelete(&y);
138    pSetCoeff0(p,x);
139  }
140  for (i=pVariables; i!=0; i--)
141  {
142    pMultExp(p,i, exp);
143  }
144  pSetm(p);
145  return p;
146}
147
148/*3
149* compute for monomials p*q
150* destroys p, keeps q
151*/
152static void pMonMult(poly p, poly q)
153{
154  number x, y;
155  int i;
156
157  y = pGetCoeff(p);
158  x = nMult(y,pGetCoeff(q));
159  nDelete(&y);
160  pSetCoeff0(p,x);
161  //for (i=pVariables; i!=0; i--)
162  //{
163  //  pAddExp(p,i, pGetExp(q,i));
164  //}
165  //p->Order += q->Order;
166  pExpVectorAdd(p,q);
167}
168
169/*3
170* compute for monomials p*q
171* keeps p, q
172*/
173static poly pMonMultC(poly p, poly q)
174{
175  number x;
176  int i;
177  poly r = pInit();
178
179  x = nMult(pGetCoeff(p),pGetCoeff(q));
180  pSetCoeff0(r,x);
181  pExpVectorSum(r,p, q);
182  return r;
183}
184
185/*
186*  compute for a poly p = head+tail, tail is monomial
187*          (head + tail)^exp, exp > 1
188*          with binomial coef.
189*/
190static poly pTwoMonPower(poly p, int exp)
191{
192  int eh, e;
193  long al;
194  poly *a;
195  poly tail, b, res, h;
196  number x;
197  number *bin = pnBin(exp);
198
199  tail = pNext(p);
200  if (bin == NULL)
201  {
202    pMonPower(p,exp);
203    pMonPower(tail,exp);
204#ifdef PDEBUG
205    pTest(p);
206#endif
207    return p;
208  }
209  eh = exp >> 1;
210  al = (exp + 1) * sizeof(poly);
211  a = (poly *)omAlloc(al);
212  a[1] = p;
213  for (e=1; e<exp; e++)
214  {
215    a[e+1] = pMonMultC(a[e],p);
216  }
217  res = a[exp];
218  b = pHead(tail);
219  for (e=exp-1; e>eh; e--)
220  {
221    h = a[e];
222    x = nMult(bin[exp-e],pGetCoeff(h));
223    pSetCoeff(h,x);
224    pMonMult(h,b);
225    res = pNext(res) = h;
226    pMonMult(b,tail);
227  }
228  for (e=eh; e!=0; e--)
229  {
230    h = a[e];
231    x = nMult(bin[e],pGetCoeff(h));
232    pSetCoeff(h,x);
233    pMonMult(h,b);
234    res = pNext(res) = h;
235    pMonMult(b,tail);
236  }
237  pDeleteLm(&tail);
238  pNext(res) = b;
239  pNext(b) = NULL;
240  res = a[exp];
241  omFreeSize((ADDRESS)a, al);
242  pnFreeBin(bin, exp);
243//  tail=res;
244// while((tail!=NULL)&&(pNext(tail)!=NULL))
245// {
246//   if(nIsZero(pGetCoeff(pNext(tail))))
247//   {
248//     pDeleteLm(&pNext(tail));
249//   }
250//   else
251//     pIter(tail);
252// }
253#ifdef PDEBUG
254  pTest(res);
255#endif
256  return res;
257}
258
259static poly pPow(poly p, int i)
260{
261  poly rc = pCopy(p);
262  i -= 2;
263  do
264  {
265    rc = pMult(rc,pCopy(p));
266    pNormalize(rc);
267    i--;
268  }
269  while (i != 0);
270  return pMult(rc,p);
271}
272
273/*2
274* returns the i-th power of p
275* p will be destroyed
276*/
277poly pPower(poly p, int i)
278{
279  poly rc=NULL;
280
281  if (i==0)
282  {
283    pDelete(&p);
284    return pOne();
285  }
286
287  if(p!=NULL)
288  {
289    if ( (i > 0) && ((unsigned long ) i > (currRing->bitmask)))
290    {
291      Werror("exponent %d is too large, max. is %d",i,currRing->bitmask);
292      return NULL;
293    }
294    switch (i)
295    {
296// cannot happen, see above
297//      case 0:
298//      {
299//        rc=pOne();
300//#ifdef DRING
301//        if ((pDRING) && (pdDFlag(p)==1))
302//        {
303//          pdSetDFlag(rc,1);
304//        }
305//#endif
306//        pDelete(&p);
307//        break;
308//      }
309      case 1:
310        rc=p;
311        break;
312      case 2:
313        rc=pMult(pCopy(p),p);
314        break;
315      default:
316        if (i < 0)
317        {
318          pDelete(&p);
319          return NULL;
320        }
321        else
322        {
323#ifdef HAVE_PLURAL
324          if (rIsPluralRing(currRing)) /* in the NC case nothing helps :-( */
325          {
326            int j=i;
327            rc = pCopy(p);
328            while (j>1)
329            {
330              rc = pMult(pCopy(p),rc);
331              j--;
332            }
333            pDelete(&p);
334            return rc;
335          }
336#endif
337          rc = pNext(p);
338          if (rc == NULL)
339            return pMonPower(p,i);
340          /* else: binom ?*/
341          int char_p=rChar(currRing);
342          if (pNext(rc) != NULL)
343            return pPow(p,i);
344          if ((char_p==0) || (i<=char_p))
345            return pTwoMonPower(p,i);
346          poly p_p=pTwoMonPower(pCopy(p),char_p);
347          return pMult(pPower(p,i-char_p),p_p);
348        }
349      /*end default:*/
350    }
351  }
352  return rc;
353}
354
355/*2
356* returns the partial differentiate of a by the k-th variable
357* does not destroy the input
358*/
359poly pDiff(poly a, int k)
360{
361  poly res, f, last;
362  number t;
363
364  last = res = NULL;
365  while (a!=NULL)
366  {
367    if (pGetExp(a,k)!=0)
368    {
369      f = pLmInit(a);
370      t = nInit(pGetExp(a,k));
371      pSetCoeff0(f,nMult(t,pGetCoeff(a)));
372      nDelete(&t);
373      if (nIsZero(pGetCoeff(f)))
374        pDeleteLm(&f);
375      else
376      {
377        pDecrExp(f,k);
378        pSetm(f);
379        if (res==NULL)
380        {
381          res=last=f;
382        }
383        else
384        {
385          pNext(last)=f;
386          last=f;
387        }
388      }
389    }
390    pIter(a);
391  }
392  return res;
393}
394
395static poly pDiffOpM(poly a, poly b,BOOLEAN multiply)
396{
397  int i,j,s;
398  number n,h,hh;
399  poly p=pOne();
400  n=nMult(pGetCoeff(a),pGetCoeff(b));
401  for(i=pVariables;i>0;i--)
402  {
403    s=pGetExp(b,i);
404    if (s<pGetExp(a,i))
405    {
406      nDelete(&n);
407      pDeleteLm(&p);
408      return NULL;
409    }
410    if (multiply)
411    {
412      for(j=pGetExp(a,i); j>0;j--)
413      {
414        h = nInit(s);
415        hh=nMult(n,h);
416        nDelete(&h);
417        nDelete(&n);
418        n=hh;
419        s--;
420      }
421      pSetExp(p,i,s);
422    }
423    else
424    {
425      pSetExp(p,i,s-pGetExp(a,i));
426    }
427  }
428  pSetm(p);
429  /*if (multiply)*/ pSetCoeff(p,n);
430  return p;
431}
432
433poly pDiffOp(poly a, poly b,BOOLEAN multiply)
434{
435  poly result=NULL;
436  poly h;
437  for(;a!=NULL;pIter(a))
438  {
439    for(h=b;h!=NULL;pIter(h))
440    {
441      result=pAdd(result,pDiffOpM(a,h,multiply));
442    }
443  }
444  return result;
445}
446
447
448void pSplit(poly p, poly *h)
449{
450  *h=pNext(p);
451  pNext(p)=NULL;
452}
453
454
455
456int pMaxCompProc(poly p)
457{
458  return pMaxComp(p);
459}
460
461/*2
462* handle memory request for sets of polynomials (ideals)
463* l is the length of *p, increment is the difference (may be negative)
464*/
465void pEnlargeSet(polyset *p, int l, int increment)
466{
467  int i;
468  polyset h;
469
470  h=(polyset)omReallocSize((poly*)*p,l*sizeof(poly),(l+increment)*sizeof(poly));
471  if (increment>0)
472  {
473    //for (i=l; i<l+increment; i++)
474    //  h[i]=NULL;
475    memset(&(h[l]),0,increment*sizeof(poly));
476  }
477  *p=h;
478}
479
480number pInitContent(poly ph);
481number pInitContent_a(poly ph);
482
483void pContent(poly ph)
484{
485#ifdef HAVE_RING2TOM
486  if (currRing->cring != 0) {
487    if (ph!=NULL)
488    {
489      number k = nGetUnit(pGetCoeff(ph));
490      poly h;
491      if (!nIsOne(k))
492      {
493        k = nGetUnit(pGetCoeff(ph));
494        pSetCoeff0(ph, nDiv(pGetCoeff(ph), k));
495        h = pNext(ph);
496        while (h != NULL)
497        {
498          pSetCoeff(h, nDiv(pGetCoeff(h), k));
499          pIter(h);
500        }
501        nDelete(&k);
502      }
503     return;
504    }
505    return;  //TODO OLIVER
506  }
507#endif
508  number h,d;
509  poly p;
510
511  if(TEST_OPT_CONTENTSB) return;
512  if(pNext(ph)==NULL)
513  {
514    pSetCoeff(ph,nInit(1));
515  }
516  else
517  {
518    nNormalize(pGetCoeff(ph));
519    if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
520    if (rField_is_Q_a())
521    {
522      h = nlInit(1);
523      p=ph;
524      while (p!=NULL)
525      { // each monom: coeff in Q_a
526        lnumber c_n_n=(lnumber)pGetCoeff(p);
527        napoly c_n=c_n_n->z;
528        while (c_n!=NULL)
529        { // each monom: coeff in Q
530          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
531          n_Delete(&h,currRing->algring);
532          h=d;
533          pIter(c_n);
534        }
535        pIter(p);
536      }
537      /* contains the 1/lcm of all denominators in c_n_n->z*/
538      number hz=h;
539      h = nlInit(1);
540      p=ph;
541      while (p!=NULL)
542      { // each monom: coeff in Q_a
543        lnumber c_n_n=(lnumber)pGetCoeff(p);
544        napoly c_n=c_n_n->n;
545        while (c_n!=NULL)
546        { // each monom: coeff in Q
547          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
548          n_Delete(&h,currRing->algring);
549          h=d;
550          pIter(c_n);
551        }
552        pIter(p);
553      }
554      /* contains the 1/lcm of all denominators in c_n_n->n*/
555      number htmp=nlInvers(h);
556      number hztmp=nlInvers(hz);
557      number hh=nlMult(hz,h);
558      nlDelete(&hz,currRing->algring);
559      nlDelete(&h,currRing->algring);
560      number hg=nlGcd(hztmp,htmp,currRing->algring);
561      nlDelete(&hztmp,currRing->algring);
562      nlDelete(&htmp,currRing->algring);
563      h=nlMult(hh,hg);
564      nlDelete(&hg,currRing->algring);
565      nlDelete(&hh,currRing->algring);
566      if(!nlIsOne(h))
567      {
568        p=ph;
569        while (p!=NULL)
570        { // each monom: coeff in Q_a
571          lnumber c_n_n=(lnumber)pGetCoeff(p);
572          napoly c_n=c_n_n->z;
573          while (c_n!=NULL)
574          { // each monom: coeff in Q
575            d=nlMult(h,pGetCoeff(c_n));
576            nlNormalize(d);
577            nlDelete(&pGetCoeff(c_n),currRing->algring);
578            pGetCoeff(c_n)=d;
579            pIter(c_n);
580          }
581          pIter(p);
582        }
583        p=ph;
584        while (p!=NULL)
585        { // each monom: coeff in Q_a
586          lnumber c_n_n=(lnumber)pGetCoeff(p);
587          napoly c_n=c_n_n->n;
588          while (c_n!=NULL)
589          { // each monom: coeff in Q
590            d=nlMult(h,pGetCoeff(c_n));
591            nlNormalize(d);
592            nlDelete(&pGetCoeff(c_n),currRing->algring);
593            pGetCoeff(c_n)=d;
594            pIter(c_n);
595          }
596          pIter(p);
597        }
598      }
599      nlDelete(&h,currRing->algring);
600    }
601    if (rField_is_Q())
602    {
603      h=pInitContent(ph);
604      p=ph;
605    }
606    else if ((rField_is_Extension())
607    && ((rPar(currRing)>1)||(currRing->minpoly==NULL)))
608    {
609      h=pInitContent_a(ph);
610      p=ph;
611    }
612    else
613    {
614      h=nCopy(pGetCoeff(ph));
615      p = pNext(ph);
616    }
617    while (p!=NULL)
618    {
619      nNormalize(pGetCoeff(p));
620      d=nGcd(h,pGetCoeff(p),currRing);
621      nDelete(&h);
622      h = d;
623      if(nIsOne(h))
624      {
625        break;
626      }
627      pIter(p);
628    }
629    p = ph;
630    //number tmp;
631    if(!nIsOne(h))
632    {
633      while (p!=NULL)
634      {
635        //d = nDiv(pGetCoeff(p),h);
636        //tmp = nIntDiv(pGetCoeff(p),h);
637        //if (!nEqual(d,tmp))
638        //{
639        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
640        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
641        //  nWrite(tmp);Print(StringAppendS("\n"));
642        //}
643        //nDelete(&tmp);
644        d = nIntDiv(pGetCoeff(p),h);
645        pSetCoeff(p,d);
646        pIter(p);
647      }
648    }
649    nDelete(&h);
650#ifdef HAVE_FACTORY
651    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
652    {
653      singclap_divide_content(ph);
654      if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
655    }
656#endif
657    if (rField_is_Q_a())
658    {
659      h = nlInit(1);
660      p=ph;
661      while (p!=NULL)
662      { // each monom: coeff in Q_a
663        lnumber c_n_n=(lnumber)pGetCoeff(p);
664        napoly c_n=c_n_n->z;
665        while (c_n!=NULL)
666        { // each monom: coeff in Q
667          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
668          n_Delete(&h,currRing->algring);
669          h=d;
670          pIter(c_n);
671        }
672        pIter(p);
673      }
674      /* contains the 1/lcm of all denominators in c_n_n->z*/
675      number hz=h;
676      h = nlInit(1);
677      p=ph;
678      while (p!=NULL)
679      { // each monom: coeff in Q_a
680        lnumber c_n_n=(lnumber)pGetCoeff(p);
681        napoly c_n=c_n_n->n;
682        while (c_n!=NULL)
683        { // each monom: coeff in Q
684          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
685          n_Delete(&h,currRing->algring);
686          h=d;
687          pIter(c_n);
688        }
689        pIter(p);
690      }
691      /* contains the 1/lcm of all denominators in c_n_n->n*/
692      number htmp=nlInvers(h);
693      number hztmp=nlInvers(hz);
694      number hh=nlMult(hz,h);
695      nlDelete(&hz,currRing->algring);
696      nlDelete(&h,currRing->algring);
697      number hg=nlGcd(hztmp,htmp,currRing->algring);
698      nlDelete(&hztmp,currRing->algring);
699      nlDelete(&htmp,currRing->algring);
700      h=nlMult(hh,hg);
701      nlDelete(&hg,currRing->algring);
702      nlDelete(&hh,currRing->algring);
703      if(!nlIsOne(h))
704      {
705        p=ph;
706        while (p!=NULL)
707        { // each monom: coeff in Q_a
708          lnumber c_n_n=(lnumber)pGetCoeff(p);
709          napoly c_n=c_n_n->z;
710          while (c_n!=NULL)
711          { // each monom: coeff in Q
712            d=nlMult(h,pGetCoeff(c_n));
713            nlNormalize(d);
714            nlDelete(&pGetCoeff(c_n),currRing->algring);
715            pGetCoeff(c_n)=d;
716            pIter(c_n);
717          }
718          pIter(p);
719        }
720        p=ph;
721        while (p!=NULL)
722        { // each monom: coeff in Q_a
723          lnumber c_n_n=(lnumber)pGetCoeff(p);
724          napoly c_n=c_n_n->n;
725          while (c_n!=NULL)
726          { // each monom: coeff in Q
727            d=nlMult(h,pGetCoeff(c_n));
728            nlNormalize(d);
729            nlDelete(&pGetCoeff(c_n),currRing->algring);
730            pGetCoeff(c_n)=d;
731            pIter(c_n);
732          }
733          pIter(p);
734        }
735      }
736      nlDelete(&h,currRing->algring);
737    }
738  }
739}
740void pSimpleContent(poly ph,int smax)
741{
742  if(TEST_OPT_CONTENTSB) return;
743  if (ph==NULL) return;
744  if (pNext(ph)==NULL)
745  {
746    pSetCoeff(ph,nInit(1));
747    return;
748  }
749  if ((pNext(pNext(ph))==NULL)||(!rField_is_Q()))
750  {
751    return;
752  }
753  number d=pInitContent(ph);
754  if (nlSize(d)<=smax)
755  {
756    //if (TEST_OPT_PROT) PrintS("G");
757    return;
758  }
759  poly p=ph;
760  number h=d;
761  if (smax==1) smax=2;
762  while (p!=NULL)
763  {
764#if 0
765    d=nlGcd(h,pGetCoeff(p),currRing);
766    nlDelete(&h,currRing);
767    h = d;
768#else
769    nlInpGcd(h,pGetCoeff(p),currRing);
770#endif
771    if(nlSize(h)<smax)
772    {
773      //if (TEST_OPT_PROT) PrintS("g");
774      return;
775    }
776    pIter(p);
777  }
778  p = ph;
779  if (!nlGreaterZero(pGetCoeff(p))) h=nlNeg(h);
780  if(nlIsOne(h)) return;
781  //if (TEST_OPT_PROT) PrintS("c");
782  while (p!=NULL)
783  {
784#if 1
785    d = nlIntDiv(pGetCoeff(p),h);
786    pSetCoeff(p,d);
787#else
788    nlInpIntDiv(pGetCoeff(p),h,currRing);
789#endif
790    pIter(p);
791  }
792  nlDelete(&h,currRing);
793}
794
795number pInitContent(poly ph)
796// only for coefficients in Q
797#if 0
798{
799  assume(!TEST_OPT_CONTENTSB);
800  assume(ph!=NULL);
801  assume(pNext(ph)!=NULL);
802  assume(rField_is_Q());
803  if (pNext(pNext(ph))==NULL)
804  {
805    return nlGetNom(pGetCoeff(pNext(ph)),currRing);
806  }
807  poly p=ph;
808  number n1=nlGetNom(pGetCoeff(p),currRing);
809  pIter(p);
810  number n2=nlGetNom(pGetCoeff(p),currRing);
811  pIter(p);
812  number d;
813  number t;
814  loop
815  {
816    nlNormalize(pGetCoeff(p));
817    t=nlGetNom(pGetCoeff(p),currRing);
818    if (nlGreaterZero(t))
819      d=nlAdd(n1,t);
820    else
821      d=nlSub(n1,t);
822    nlDelete(&t,currRing);
823    nlDelete(&n1,currRing);
824    n1=d;
825    pIter(p);
826    if (p==NULL) break;
827    nlNormalize(pGetCoeff(p));
828    t=nlGetNom(pGetCoeff(p),currRing);
829    if (nlGreaterZero(t))
830      d=nlAdd(n2,t);
831    else
832      d=nlSub(n2,t);
833    nlDelete(&t,currRing);
834    nlDelete(&n2,currRing);
835    n2=d;
836    pIter(p);
837    if (p==NULL) break;
838  }
839  d=nlGcd(n1,n2,currRing);
840  nlDelete(&n1,currRing);
841  nlDelete(&n2,currRing);
842  return d;
843}
844#else
845{
846  number d=pGetCoeff(ph);
847  if(SR_HDL(d)&SR_INT) return d;
848  int s=mpz_size1(&d->z);
849  int s2=-1;
850  number d2;
851  loop
852  {
853    pIter(ph);
854    if(ph==NULL)
855    {
856      if (s2==-1) return nlCopy(d);
857      break;
858    }
859    if (SR_HDL(pGetCoeff(ph))&SR_INT)
860    {
861      s2=s;
862      d2=d;
863      s=0;
864      d=pGetCoeff(ph);
865      if (s2==0) break;
866    }
867    else
868    if (mpz_size1(&(pGetCoeff(ph)->z))<=s)
869    {
870      s2=s;
871      d2=d;
872      d=pGetCoeff(ph);
873      s=mpz_size1(&d->z);
874    }
875  }
876  return nlGcd(d,d2,currRing);
877}
878#endif
879
880number pInitContent_a(poly ph)
881// only for coefficients in K(a) anf K(a,...)
882{
883  number d=pGetCoeff(ph);
884  int s=naParDeg(d);
885  if (s /* naParDeg(d)*/ <=1) return naCopy(d);
886  int s2=-1;
887  number d2;
888  int ss;
889  loop
890  {
891    pIter(ph);
892    if(ph==NULL)
893    {
894      if (s2==-1) return naCopy(d);
895      break;
896    }
897    if ((ss=naParDeg(pGetCoeff(ph)))<s)
898    {
899      s2=s;
900      d2=d;
901      s=ss;
902      d=pGetCoeff(ph);
903      if (s2<=1) break;
904    }
905  }
906  return naGcd(d,d2,currRing);
907}
908
909
910//void pContent(poly ph)
911//{
912//  number h,d;
913//  poly p;
914//
915//  p = ph;
916//  if(pNext(p)==NULL)
917//  {
918//    pSetCoeff(p,nInit(1));
919//  }
920//  else
921//  {
922//#ifdef PDEBUG
923//    if (!pTest(p)) return;
924//#endif
925//    nNormalize(pGetCoeff(p));
926//    if(!nGreaterZero(pGetCoeff(ph)))
927//    {
928//      ph = pNeg(ph);
929//      nNormalize(pGetCoeff(p));
930//    }
931//    h=pGetCoeff(p);
932//    pIter(p);
933//    while (p!=NULL)
934//    {
935//      nNormalize(pGetCoeff(p));
936//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
937//      pIter(p);
938//    }
939//    h=nCopy(h);
940//    p=ph;
941//    while (p!=NULL)
942//    {
943//      d=nGcd(h,pGetCoeff(p));
944//      nDelete(&h);
945//      h = d;
946//      if(nIsOne(h))
947//      {
948//        break;
949//      }
950//      pIter(p);
951//    }
952//    p = ph;
953//    //number tmp;
954//    if(!nIsOne(h))
955//    {
956//      while (p!=NULL)
957//      {
958//        d = nIntDiv(pGetCoeff(p),h);
959//        pSetCoeff(p,d);
960//        pIter(p);
961//      }
962//    }
963//    nDelete(&h);
964//#ifdef HAVE_FACTORY
965//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
966//    {
967//      pTest(ph);
968//      singclap_divide_content(ph);
969//      pTest(ph);
970//    }
971//#endif
972//  }
973//}
974void p_Content(poly ph, ring r)
975{
976  number h,d;
977  poly p;
978
979  if(pNext(ph)==NULL)
980  {
981    pSetCoeff(ph,n_Init(1,r));
982  }
983  else
984  {
985    n_Normalize(pGetCoeff(ph),r);
986    if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
987    h=n_Copy(pGetCoeff(ph),r);
988    p = pNext(ph);
989    while (p!=NULL)
990    {
991      n_Normalize(pGetCoeff(p),r);
992      d=n_Gcd(h,pGetCoeff(p),r);
993      n_Delete(&h,r);
994      h = d;
995      if(n_IsOne(h,r))
996      {
997        break;
998      }
999      pIter(p);
1000    }
1001    p = ph;
1002    //number tmp;
1003    if(!n_IsOne(h,r))
1004    {
1005      while (p!=NULL)
1006      {
1007        //d = nDiv(pGetCoeff(p),h);
1008        //tmp = nIntDiv(pGetCoeff(p),h);
1009        //if (!nEqual(d,tmp))
1010        //{
1011        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
1012        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
1013        //  nWrite(tmp);Print(StringAppendS("\n"));
1014        //}
1015        //nDelete(&tmp);
1016        d = n_IntDiv(pGetCoeff(p),h,r);
1017        p_SetCoeff(p,d,r);
1018        pIter(p);
1019      }
1020    }
1021    n_Delete(&h,r);
1022#ifdef HAVE_FACTORY
1023    //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
1024    //{
1025    //  singclap_divide_content(ph);
1026    //  if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
1027    //}
1028#endif
1029  }
1030}
1031
1032void pCleardenom(poly ph)
1033{
1034  number d, h;
1035  poly p;
1036
1037#ifdef HAVE_RING2TOM
1038  if (currRing->cring == 1)
1039  {
1040    pContent(ph);
1041    return;
1042  }
1043#endif
1044  if (rField_is_Zp() && TEST_OPT_INTSTRATEGY) return;
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.