source: git/kernel/polys1.cc @ 042111

spielwiese
Last change on this file since 042111 was 042111, checked in by Hans Schönemann <hannes@…>, 19 years ago
*hannes: pContent for Q_a improved git-svn-id: file:///usr/local/Singular/svn/trunk@8523 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 37.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys1.cc,v 1.14 2005-08-17 13:54:36 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, 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  number h,d;
486  poly p;
487
488  if(TEST_OPT_CONTENTSB) return;
489  if(pNext(ph)==NULL)
490  {
491    pSetCoeff(ph,nInit(1));
492  }
493  else
494  {
495    nNormalize(pGetCoeff(ph));
496    if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
497    if (rField_is_Q_a())
498    {
499      h = nlInit(1);
500      p=ph;
501      while (p!=NULL)
502      { // each monom: coeff in Q_a
503        lnumber c_n_n=(lnumber)pGetCoeff(p);
504        napoly c_n=c_n_n->z;
505        while (c_n!=NULL)
506        { // each monom: coeff in Q
507          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
508          n_Delete(&h,currRing->algring);
509          h=d;
510          pIter(c_n);
511        }
512        pIter(p);
513      }
514      /* contains the 1/lcm of all denominators in c_n_n->z*/
515      number hz=h;
516      h = nlInit(1);
517      p=ph;
518      while (p!=NULL)
519      { // each monom: coeff in Q_a
520        lnumber c_n_n=(lnumber)pGetCoeff(p);
521        napoly c_n=c_n_n->n;
522        while (c_n!=NULL)
523        { // each monom: coeff in Q
524          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
525          n_Delete(&h,currRing->algring);
526          h=d;
527          pIter(c_n);
528        }
529        pIter(p);
530      }
531      /* contains the 1/lcm of all denominators in c_n_n->n*/
532      number htmp=nlInvers(h);
533      number hztmp=nlInvers(hz);
534      number hh=nlMult(hz,h);
535      nlDelete(&hz,currRing->algring);
536      nlDelete(&h,currRing->algring);
537      number hg=nlGcd(hztmp,htmp,currRing->algring);
538      nlDelete(&hztmp,currRing->algring);
539      nlDelete(&htmp,currRing->algring);
540      h=nlMult(hh,hg);
541      nlDelete(&hg,currRing->algring);
542      nlDelete(&hh,currRing->algring);
543      if(!nlIsOne(h))
544      {
545        p=ph;
546        while (p!=NULL)
547        { // each monom: coeff in Q_a
548          lnumber c_n_n=(lnumber)pGetCoeff(p);
549          napoly c_n=c_n_n->z;
550          while (c_n!=NULL)
551          { // each monom: coeff in Q
552            d=nlMult(h,pGetCoeff(c_n));
553            nlNormalize(d);
554            nlDelete(&pGetCoeff(c_n),currRing->algring);
555            pGetCoeff(c_n)=d;
556            pIter(c_n);
557          }
558          pIter(p);
559        }
560        p=ph;
561        while (p!=NULL)
562        { // each monom: coeff in Q_a
563          lnumber c_n_n=(lnumber)pGetCoeff(p);
564          napoly c_n=c_n_n->n;
565          while (c_n!=NULL)
566          { // each monom: coeff in Q
567            d=nlMult(h,pGetCoeff(c_n));
568            nlNormalize(d);
569            nlDelete(&pGetCoeff(c_n),currRing->algring);
570            pGetCoeff(c_n)=d;
571            pIter(c_n);
572          }
573          pIter(p);
574        }
575      }
576      nlDelete(&h,currRing->algring);
577    }
578    if (rField_is_Q())
579    {
580      h=pInitContent(ph);
581      p=ph;
582    }
583    else if ((rField_is_Extension())
584    && ((rPar(currRing)>1)||(currRing->minpoly==NULL)))
585    {
586      h=pInitContent_a(ph);
587      p=ph;
588    }
589    else
590    {
591      h=nCopy(pGetCoeff(ph));
592      p = pNext(ph);
593    }
594    while (p!=NULL)
595    {
596      nNormalize(pGetCoeff(p));
597      d=nGcd(h,pGetCoeff(p),currRing);
598      nDelete(&h);
599      h = d;
600      if(nIsOne(h))
601      {
602        break;
603      }
604      pIter(p);
605    }
606    p = ph;
607    //number tmp;
608    if(!nIsOne(h))
609    {
610      while (p!=NULL)
611      {
612        //d = nDiv(pGetCoeff(p),h);
613        //tmp = nIntDiv(pGetCoeff(p),h);
614        //if (!nEqual(d,tmp))
615        //{
616        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
617        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
618        //  nWrite(tmp);Print(StringAppendS("\n"));
619        //}
620        //nDelete(&tmp);
621        d = nIntDiv(pGetCoeff(p),h);
622        pSetCoeff(p,d);
623        pIter(p);
624      }
625    }
626    nDelete(&h);
627#ifdef HAVE_FACTORY
628    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
629    {
630      singclap_divide_content(ph);
631      if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
632    }
633#endif
634    if (rField_is_Q_a())
635    {
636      h = nlInit(1);
637      p=ph;
638      while (p!=NULL)
639      { // each monom: coeff in Q_a
640        lnumber c_n_n=(lnumber)pGetCoeff(p);
641        napoly c_n=c_n_n->z;
642        while (c_n!=NULL)
643        { // each monom: coeff in Q
644          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
645          n_Delete(&h,currRing->algring);
646          h=d;
647          pIter(c_n);
648        }
649        pIter(p);
650      }
651      /* contains the 1/lcm of all denominators in c_n_n->z*/
652      number hz=h;
653      h = nlInit(1);
654      p=ph;
655      while (p!=NULL)
656      { // each monom: coeff in Q_a
657        lnumber c_n_n=(lnumber)pGetCoeff(p);
658        napoly c_n=c_n_n->n;
659        while (c_n!=NULL)
660        { // each monom: coeff in Q
661          d=nlLcm(h,pGetCoeff(c_n),currRing->algring);
662          n_Delete(&h,currRing->algring);
663          h=d;
664          pIter(c_n);
665        }
666        pIter(p);
667      }
668      /* contains the 1/lcm of all denominators in c_n_n->n*/
669      number htmp=nlInvers(h);
670      number hztmp=nlInvers(hz);
671      number hh=nlMult(hz,h);
672      nlDelete(&hz,currRing->algring);
673      nlDelete(&h,currRing->algring);
674      number hg=nlGcd(hztmp,htmp,currRing->algring);
675      nlDelete(&hztmp,currRing->algring);
676      nlDelete(&htmp,currRing->algring);
677      h=nlMult(hh,hg);
678      nlDelete(&hg,currRing->algring);
679      nlDelete(&hh,currRing->algring);
680      if(!nlIsOne(h))
681      {
682        p=ph;
683        while (p!=NULL)
684        { // each monom: coeff in Q_a
685          lnumber c_n_n=(lnumber)pGetCoeff(p);
686          napoly c_n=c_n_n->z;
687          while (c_n!=NULL)
688          { // each monom: coeff in Q
689            d=nlMult(h,pGetCoeff(c_n));
690            nlNormalize(d);
691            nlDelete(&pGetCoeff(c_n),currRing->algring);
692            pGetCoeff(c_n)=d;
693            pIter(c_n);
694          }
695          pIter(p);
696        }
697        p=ph;
698        while (p!=NULL)
699        { // each monom: coeff in Q_a
700          lnumber c_n_n=(lnumber)pGetCoeff(p);
701          napoly c_n=c_n_n->n;
702          while (c_n!=NULL)
703          { // each monom: coeff in Q
704            d=nlMult(h,pGetCoeff(c_n));
705            nlNormalize(d);
706            nlDelete(&pGetCoeff(c_n),currRing->algring);
707            pGetCoeff(c_n)=d;
708            pIter(c_n);
709          }
710          pIter(p);
711        }
712      }
713      nlDelete(&h,currRing->algring);
714    }
715  }
716}
717void pSimpleContent(poly ph,int smax)
718{
719  if(TEST_OPT_CONTENTSB) return;
720  if (ph==NULL) return;
721  if (pNext(ph)==NULL)
722  {
723    pSetCoeff(ph,nInit(1));
724    return;
725  }
726  if ((pNext(pNext(ph))==NULL)||(!rField_is_Q()))
727  {
728    return;
729  }
730  number d=pInitContent(ph);
731  if (nlSize(d)<=smax)
732  {
733    //if (TEST_OPT_PROT) PrintS("G");
734    return;
735  }
736  poly p=ph;
737  number h=d;
738  if (smax==1) smax=2;
739  while (p!=NULL)
740  {
741#if 0
742    d=nlGcd(h,pGetCoeff(p),currRing);
743    nlDelete(&h,currRing);
744    h = d;
745#else
746    nlInpGcd(h,pGetCoeff(p),currRing);
747#endif
748    if(nlSize(h)<smax)
749    {
750      //if (TEST_OPT_PROT) PrintS("g");
751      return;
752    }
753    pIter(p);
754  }
755  p = ph;
756  if (!nlGreaterZero(pGetCoeff(p))) h=nlNeg(h);
757  if(nlIsOne(h)) return;
758  //if (TEST_OPT_PROT) PrintS("c");
759  while (p!=NULL)
760  {
761#if 1
762    d = nlIntDiv(pGetCoeff(p),h);
763    pSetCoeff(p,d);
764#else
765    nlInpIntDiv(pGetCoeff(p),h,currRing);
766#endif
767    pIter(p);
768  }
769  nlDelete(&h,currRing);
770}
771
772number pInitContent(poly ph)
773// only for coefficients in Q
774#if 0
775{
776  assume(!TEST_OPT_CONTENTSB);
777  assume(ph!=NULL);
778  assume(pNext(ph)!=NULL);
779  assume(rField_is_Q());
780  if (pNext(pNext(ph))==NULL)
781  {
782    return nlGetNom(pGetCoeff(pNext(ph)),currRing);
783  }
784  poly p=ph;
785  number n1=nlGetNom(pGetCoeff(p),currRing);
786  pIter(p);
787  number n2=nlGetNom(pGetCoeff(p),currRing);
788  pIter(p);
789  number d;
790  number t;
791  loop
792  {
793    nlNormalize(pGetCoeff(p));
794    t=nlGetNom(pGetCoeff(p),currRing);
795    if (nlGreaterZero(t))
796      d=nlAdd(n1,t);
797    else
798      d=nlSub(n1,t);
799    nlDelete(&t,currRing);
800    nlDelete(&n1,currRing);
801    n1=d;
802    pIter(p);
803    if (p==NULL) break;
804    nlNormalize(pGetCoeff(p));
805    t=nlGetNom(pGetCoeff(p),currRing);
806    if (nlGreaterZero(t))
807      d=nlAdd(n2,t);
808    else
809      d=nlSub(n2,t);
810    nlDelete(&t,currRing);
811    nlDelete(&n2,currRing);
812    n2=d;
813    pIter(p);
814    if (p==NULL) break;
815  }
816  d=nlGcd(n1,n2,currRing);
817  nlDelete(&n1,currRing);
818  nlDelete(&n2,currRing);
819  return d;
820}
821#else
822{
823  number d=pGetCoeff(ph);
824  if(SR_HDL(d)&SR_INT) return d;
825  int s=mpz_size1(&d->z);
826  int s2=-1;
827  number d2;
828  loop
829  {
830    pIter(ph);
831    if(ph==NULL)
832    {
833      if (s2==-1) return nlCopy(d);
834      break;
835    }
836    if (SR_HDL(pGetCoeff(ph))&SR_INT)
837    {
838      s2=s;
839      d2=d;
840      s=0;
841      d=pGetCoeff(ph);
842      if (s2==0) break;
843    }
844    else
845    if (mpz_size1(&(pGetCoeff(ph)->z))<=s)
846    {
847      s2=s;
848      d2=d;
849      d=pGetCoeff(ph);
850      s=mpz_size1(&d->z);
851    }
852  }
853  return nlGcd(d,d2,currRing);
854}
855#endif
856
857number pInitContent_a(poly ph)
858// only for coefficients in K(a) anf K(a,...)
859{
860  number d=pGetCoeff(ph);
861  int s=naParDeg(d);
862  if (s /* naParDeg(d)*/ <=1) return naCopy(d);
863  int s2=-1;
864  number d2;
865  int ss;
866  loop
867  {
868    pIter(ph);
869    if(ph==NULL)
870    {
871      if (s2==-1) return naCopy(d);
872      break;
873    }
874    if ((ss=naParDeg(pGetCoeff(ph)))<s)
875    {
876      s2=s;
877      d2=d;
878      s=ss;
879      d=pGetCoeff(ph);
880      if (s2<=1) break;
881    }
882  }
883  return naGcd(d,d2,currRing);
884}
885
886
887//void pContent(poly ph)
888//{
889//  number h,d;
890//  poly p;
891//
892//  p = ph;
893//  if(pNext(p)==NULL)
894//  {
895//    pSetCoeff(p,nInit(1));
896//  }
897//  else
898//  {
899//#ifdef PDEBUG
900//    if (!pTest(p)) return;
901//#endif
902//    nNormalize(pGetCoeff(p));
903//    if(!nGreaterZero(pGetCoeff(ph)))
904//    {
905//      ph = pNeg(ph);
906//      nNormalize(pGetCoeff(p));
907//    }
908//    h=pGetCoeff(p);
909//    pIter(p);
910//    while (p!=NULL)
911//    {
912//      nNormalize(pGetCoeff(p));
913//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
914//      pIter(p);
915//    }
916//    h=nCopy(h);
917//    p=ph;
918//    while (p!=NULL)
919//    {
920//      d=nGcd(h,pGetCoeff(p));
921//      nDelete(&h);
922//      h = d;
923//      if(nIsOne(h))
924//      {
925//        break;
926//      }
927//      pIter(p);
928//    }
929//    p = ph;
930//    //number tmp;
931//    if(!nIsOne(h))
932//    {
933//      while (p!=NULL)
934//      {
935//        d = nIntDiv(pGetCoeff(p),h);
936//        pSetCoeff(p,d);
937//        pIter(p);
938//      }
939//    }
940//    nDelete(&h);
941//#ifdef HAVE_FACTORY
942//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
943//    {
944//      pTest(ph);
945//      singclap_divide_content(ph);
946//      pTest(ph);
947//    }
948//#endif
949//  }
950//}
951void p_Content(poly ph, ring r)
952{
953  number h,d;
954  poly p;
955
956  if(pNext(ph)==NULL)
957  {
958    pSetCoeff(ph,n_Init(1,r));
959  }
960  else
961  {
962    n_Normalize(pGetCoeff(ph),r);
963    if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
964    h=n_Copy(pGetCoeff(ph),r);
965    p = pNext(ph);
966    while (p!=NULL)
967    {
968      n_Normalize(pGetCoeff(p),r);
969      d=n_Gcd(h,pGetCoeff(p),r);
970      n_Delete(&h,r);
971      h = d;
972      if(n_IsOne(h,r))
973      {
974        break;
975      }
976      pIter(p);
977    }
978    p = ph;
979    //number tmp;
980    if(!n_IsOne(h,r))
981    {
982      while (p!=NULL)
983      {
984        //d = nDiv(pGetCoeff(p),h);
985        //tmp = nIntDiv(pGetCoeff(p),h);
986        //if (!nEqual(d,tmp))
987        //{
988        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
989        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
990        //  nWrite(tmp);Print(StringAppendS("\n"));
991        //}
992        //nDelete(&tmp);
993        d = n_IntDiv(pGetCoeff(p),h,r);
994        p_SetCoeff(p,d,r);
995        pIter(p);
996      }
997    }
998    n_Delete(&h,r);
999#ifdef HAVE_FACTORY
1000    //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
1001    //{
1002    //  singclap_divide_content(ph);
1003    //  if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
1004    //}
1005#endif
1006  }
1007}
1008
1009void pCleardenom(poly ph)
1010{
1011  number d, h;
1012  poly p;
1013
1014  p = ph;
1015  if(pNext(p)==NULL)
1016  {
1017    if (TEST_OPT_CONTENTSB)
1018    {
1019      number n=nGetDenom(pGetCoeff(p));
1020      if (!nIsOne(n))
1021      {
1022        number nn=nMult(pGetCoeff(p),n);
1023        nNormalize(nn);
1024        pSetCoeff(p,nn);
1025      }
1026      nDelete(&n);
1027    }
1028    else
1029      pSetCoeff(p,nInit(1));
1030  }
1031  else
1032  {
1033    h = nInit(1);
1034    while (p!=NULL)
1035    {
1036      nNormalize(pGetCoeff(p));
1037      d=nLcm(h,pGetCoeff(p),currRing);
1038      nDelete(&h);
1039      h=d;
1040      pIter(p);
1041    }
1042    /* contains the 1/lcm of all denominators */
1043    if(!nIsOne(h))
1044    {
1045      p = ph;
1046      while (p!=NULL)
1047      {
1048        /* should be:
1049        * number hh;
1050        * nGetDenom(p->coef,&hh);
1051        * nMult(&h,&hh,&d);
1052        * nNormalize(d);
1053        * nDelete(&hh);
1054        * nMult(d,p->coef,&hh);
1055        * nDelete(&d);
1056        * nDelete(&(p->coef));
1057        * p->coef =hh;
1058        */
1059        d=nMult(h,pGetCoeff(p));
1060        nNormalize(d);
1061        pSetCoeff(p,d);
1062        pIter(p);
1063      }
1064      nDelete(&h);
1065      if (nGetChar()==1)
1066      {
1067        loop
1068        {
1069          h = nInit(1);
1070          p=ph;
1071          while (p!=NULL)
1072          {
1073            d=nLcm(h,pGetCoeff(p),currRing);
1074            nDelete(&h);
1075            h=d;
1076            pIter(p);
1077          }
1078          /* contains the 1/lcm of all denominators */
1079          if(!nIsOne(h))
1080          {
1081            p = ph;
1082            while (p!=NULL)
1083            {
1084              /* should be:
1085              * number hh;
1086              * nGetDenom(p->coef,&hh);
1087              * nMult(&h,&hh,&d);
1088              * nNormalize(d);
1089              * nDelete(&hh);
1090              * nMult(d,p->coef,&hh);
1091              * nDelete(&d);
1092              * nDelete(&(p->coef));
1093              * p->coef =hh;
1094              */
1095              d=nMult(h,pGetCoeff(p));
1096              nNormalize(d);
1097              pSetCoeff(p,d);
1098              pIter(p);
1099            }
1100            nDelete(&h);
1101          }
1102          else
1103          {
1104            nDelete(&h);
1105            break;
1106          }
1107        }
1108      }
1109    }
1110    if (h!=NULL) nDelete(&h);
1111    pContent(ph);
1112  }
1113}
1114
1115void pCleardenom_n(poly ph,number &c)
1116{
1117  number d, h;
1118  poly p;
1119
1120  p = ph;
1121  if(pNext(p)==NULL)
1122  {
1123    c=nInvers(pGetCoeff(p));
1124    pSetCoeff(p,nInit(1));
1125  }
1126  else
1127  {
1128    h = nInit(1);
1129    while (p!=NULL)
1130    {
1131      nNormalize(pGetCoeff(p));
1132      d=nLcm(h,pGetCoeff(p),currRing);
1133      nDelete(&h);
1134      h=d;
1135      pIter(p);
1136    }
1137    c=h;
1138    /* contains the 1/lcm of all denominators */
1139    if(!nIsOne(h))
1140    {
1141      p = ph;
1142      while (p!=NULL)
1143      {
1144        /* should be:
1145        * number hh;
1146        * nGetDenom(p->coef,&hh);
1147        * nMult(&h,&hh,&d);
1148        * nNormalize(d);
1149        * nDelete(&hh);
1150        * nMult(d,p->coef,&hh);
1151        * nDelete(&d);
1152        * nDelete(&(p->coef));
1153        * p->coef =hh;
1154        */
1155        d=nMult(h,pGetCoeff(p));
1156        nNormalize(d);
1157        pSetCoeff(p,d);
1158        pIter(p);
1159      }
1160      if (nGetChar()==1)
1161      {
1162        loop
1163        {
1164          h = nInit(1);
1165          p=ph;
1166          while (p!=NULL)
1167          {
1168            d=nLcm(h,pGetCoeff(p),currRing);
1169            nDelete(&h);
1170            h=d;
1171            pIter(p);
1172          }
1173          /* contains the 1/lcm of all denominators */
1174          if(!nIsOne(h))
1175          {
1176            p = ph;
1177            while (p!=NULL)
1178            {
1179              /* should be:
1180              * number hh;
1181              * nGetDenom(p->coef,&hh);
1182              * nMult(&h,&hh,&d);
1183              * nNormalize(d);
1184              * nDelete(&hh);
1185              * nMult(d,p->coef,&hh);
1186              * nDelete(&d);
1187              * nDelete(&(p->coef));
1188              * p->coef =hh;
1189              */
1190              d=nMult(h,pGetCoeff(p));
1191              nNormalize(d);
1192              pSetCoeff(p,d);
1193              pIter(p);
1194            }
1195            number t=nMult(c,h);
1196            nDelete(&c);
1197            c=t;
1198          }
1199          else
1200          {
1201            break;
1202          }
1203          nDelete(&h);
1204        }
1205      }
1206    }
1207  }
1208}
1209
1210/*2
1211*tests if p is homogeneous with respect to the actual weigths
1212*/
1213BOOLEAN pIsHomogeneous (poly p)
1214{
1215  poly qp=p;
1216  int o;
1217
1218  if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
1219  pFDegProc d=(pLexOrder ? pTotaldegree : pFDeg );
1220  o = d(p,currRing);
1221  do
1222  {
1223    if (d(qp,currRing) != o) return FALSE;
1224    pIter(qp);
1225  }
1226  while (qp != NULL);
1227  return TRUE;
1228}
1229
1230// orders monoms of poly using merge sort (ususally faster than
1231// insertion sort). ASSUMES that pSetm was performed on monoms
1232poly pOrdPolyMerge(poly p)
1233{
1234  poly qq,pp,result=NULL;
1235
1236  if (p == NULL) return NULL;
1237
1238  loop
1239  {
1240    qq = p;
1241    loop
1242    {
1243      if (pNext(p) == NULL)
1244      {
1245        result=pAdd(result, qq);
1246        pTest(result);
1247        return result;
1248      }
1249      if (pLmCmp(p,pNext(p)) != 1)
1250      {
1251        pp = p;
1252        pIter(p);
1253        pNext(pp) = NULL;
1254        result = pAdd(result, qq);
1255        break;
1256      }
1257      pIter(p);
1258    }
1259  }
1260}
1261
1262// orders monoms of poly using insertion sort, performs pSetm on each monom
1263poly pOrdPolyInsertSetm(poly p)
1264{
1265  poly qq,result = NULL;
1266
1267#if 0
1268  while (p != NULL)
1269  {
1270    qq = p;
1271    pIter(p);
1272    qq->next = NULL;
1273    pSetm(qq);
1274    result = pAdd(result,qq);
1275    pTest(result);
1276  }
1277#else
1278  while (p != NULL)
1279  {
1280    qq = p;
1281    pIter(p);
1282    qq->next = result;
1283    result = qq;
1284    pSetm(qq);
1285  }
1286  p = result;
1287  result = NULL;
1288  while (p != NULL)
1289  {
1290    qq = p;
1291    pIter(p);
1292    qq->next = NULL;
1293    result = pAdd(result, qq);
1294  }
1295  pTest(result);
1296#endif
1297  return result;
1298}
1299
1300/*2
1301*returns a re-ordered copy of a polynomial, with permutation of the variables
1302*/
1303poly pPermPoly (poly p, int * perm, ring oldRing, nMapFunc nMap,
1304   int *par_perm, int OldPar)
1305{
1306  int OldpVariables = oldRing->N;
1307  poly result = NULL;
1308  poly result_last = NULL;
1309  poly aq=NULL; /* the map coefficient */
1310  poly qq; /* the mapped monomial */
1311
1312  while (p != NULL)
1313  {
1314    if ((OldPar==0)||(rField_is_GF(oldRing)))
1315    {
1316      qq = pInit();
1317      number n=nMap(pGetCoeff(p));
1318      if ((currRing->minpoly!=NULL)
1319      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1320      {
1321        nNormalize(n);
1322      }
1323      pGetCoeff(qq)=n;
1324    // coef may be zero:  pTest(qq);
1325    }
1326    else
1327    {
1328      qq=pOne();
1329      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
1330      if ((currRing->minpoly!=NULL)
1331      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1332      {
1333        poly tmp=aq;
1334        while (tmp!=NULL)
1335        {
1336          number n=pGetCoeff(tmp);
1337          nNormalize(n);
1338          pGetCoeff(tmp)=n;
1339          pIter(tmp);
1340        }
1341      }
1342      pTest(aq);
1343    }
1344    if (rRing_has_Comp(currRing)) pSetComp(qq, p_GetComp(p,oldRing));
1345    if (nIsZero(pGetCoeff(qq)))
1346    {
1347      pDeleteLm(&qq);
1348    }
1349    else
1350    {
1351      int i;
1352      int mapped_to_par=0;
1353      for(i=1; i<=OldpVariables; i++)
1354      {
1355        int e=p_GetExp(p,i,oldRing);
1356        if (e!=0)
1357        {
1358          if (perm==NULL)
1359          {
1360            pSetExp(qq,i, e);
1361          }
1362          else if (perm[i]>0)
1363            pAddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/);
1364          else if (perm[i]<0)
1365          {
1366            if (rField_is_GF())
1367            {
1368              number c=pGetCoeff(qq);
1369              number ee=nfPar(1);
1370              number eee;nfPower(ee,e,&eee); //nfDelete(ee,currRing);
1371              ee=nfMult(c,eee);
1372              //nfDelete(c,currRing);nfDelete(eee,currRing);
1373              pSetCoeff0(qq,ee);
1374            }
1375            else
1376            {
1377              lnumber c=(lnumber)pGetCoeff(qq);
1378              if (c->z->next==NULL)
1379                napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1380              else /* more difficult: we have really to multiply: */
1381              {
1382                lnumber mmc=(lnumber)naInit(1);
1383                napSetExp(mmc->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1384                napSetm(mmc->z);
1385                pGetCoeff(qq)=naMult((number)c,(number)mmc);
1386                nDelete((number *)&c);
1387                nDelete((number *)&mmc); 
1388              }
1389              mapped_to_par=1;
1390            }
1391          }
1392          else
1393          {
1394            /* this variable maps to 0 !*/
1395            pDeleteLm(&qq);
1396            break;
1397          }
1398        }
1399      }
1400      if (mapped_to_par
1401      && (currRing->minpoly!=NULL))
1402      {
1403        number n=pGetCoeff(qq);
1404        nNormalize(n);
1405        pGetCoeff(qq)=n;
1406      }
1407    }
1408    pIter(p);
1409#if 1
1410    if (qq!=NULL)
1411    {
1412      pSetm(qq);
1413      pTest(aq);
1414      pTest(qq);
1415      if (aq!=NULL) qq=pMult(aq,qq);
1416      aq = qq;
1417      while (pNext(aq) != NULL) pIter(aq);
1418      if (result_last==NULL)
1419      {
1420        result=qq;
1421      }
1422      else
1423      {
1424        pNext(result_last)=qq;
1425      }
1426      result_last=aq;
1427      aq = NULL;
1428    }
1429    else if (aq!=NULL)
1430    {
1431      pDelete(&aq);
1432    }
1433  }
1434  result=pSortAdd(result);
1435#else
1436  //  if (qq!=NULL)
1437  //  {
1438  //    pSetm(qq);
1439  //    pTest(qq);
1440  //    pTest(aq);
1441  //    if (aq!=NULL) qq=pMult(aq,qq);
1442  //    aq = qq;
1443  //    while (pNext(aq) != NULL) pIter(aq);
1444  //    pNext(aq) = result;
1445  //    aq = NULL;
1446  //    result = qq;
1447  //  }
1448  //  else if (aq!=NULL)
1449  //  {
1450  //    pDelete(&aq);
1451  //  }
1452  //}
1453  //p = result;
1454  //result = NULL;
1455  //while (p != NULL)
1456  //{
1457  //  qq = p;
1458  //  pIter(p);
1459  //  qq->next = NULL;
1460  //  result = pAdd(result, qq);
1461  //}
1462#endif
1463  pTest(result);
1464  return result;
1465}
1466
1467#if 0
1468/*2
1469*returns a re-ordered copy of a polynomial, with permutation of the variables
1470*/
1471poly p_PermPoly (poly p, int * perm, ring oldRing,
1472   int *par_perm, int OldPar, ring newRing)
1473{
1474  int OldpVariables = oldRing->N;
1475  poly result = NULL;
1476  poly result_last = NULL;
1477  poly aq=NULL; /* the map coefficient */
1478  poly qq; /* the mapped monomial */
1479
1480  while (p != NULL)
1481  {
1482    if (OldPar==0)
1483    {
1484      qq = pInit();
1485      number n=newRing->cf->nMap(pGetCoeff(p));
1486      if ((newRing->minpoly!=NULL)
1487      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
1488      {
1489        newRing->cf->nNormalize(n);
1490      }
1491      pGetCoeff(qq)=n;
1492    // coef may be zero:  pTest(qq);
1493    }
1494    else
1495    {
1496      qq=p_ISet(1, newRing);
1497      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
1498      if ((newRing->minpoly!=NULL)
1499      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
1500      {
1501        poly tmp=aq;
1502        while (tmp!=NULL)
1503        {
1504          number n=pGetCoeff(tmp);
1505          newRing->cf->nNormalize(n);
1506          pGetCoeff(tmp)=n;
1507          pIter(tmp);
1508        }
1509      }
1510      //pTest(aq);
1511    }
1512    p_SetComp(qq, p_GetComp(p,oldRing), newRing);
1513    if (newRing->cf->nIsZero(pGetCoeff(qq)))
1514    {
1515      p_DeleteLm(&qq, newRing);
1516    }
1517    else
1518    {
1519      int i;
1520      int mapped_to_par=0;
1521      for(i=1; i<=OldpVariables; i++)
1522      {
1523        int e=p_GetExp(p,i,oldRing);
1524        if (e!=0)
1525        {
1526          if (perm==NULL)
1527          {
1528            p_SetExp(qq,i, e, newRing);
1529          }
1530          else if (perm[i]>0)
1531            p_AddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/, newRing);
1532          else if (perm[i]<0)
1533          {
1534            lnumber c=(lnumber)pGetCoeff(qq);
1535            napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1536            mapped_to_par=1;
1537          }
1538          else
1539          {
1540            /* this variable maps to 0 !*/
1541            p_DeleteLm(&qq, newRing);
1542            break;
1543          }
1544        }
1545      }
1546      if (mapped_to_par
1547      && (newRing->minpoly!=NULL))
1548      {
1549        number n=pGetCoeff(qq);
1550        newRing->cf->nNormalize(n);
1551        pGetCoeff(qq)=n;
1552      }
1553    }
1554    pIter(p);
1555    if (qq!=NULL)
1556    {
1557      p_Setm(qq, newRing);
1558      //pTest(aq);
1559      //pTest(qq);
1560      if (aq!=NULL) qq=pMult(aq,qq);
1561      aq = qq;
1562      while (pNext(aq) != NULL) pIter(aq);
1563      if (result_last==NULL)
1564      {
1565        result=qq;
1566      }
1567      else
1568      {
1569        pNext(result_last)=qq;
1570      }
1571      result_last=aq;
1572      aq = NULL;
1573    }
1574    else if (aq!=NULL)
1575    {
1576      p_Delete(&aq, newRing);
1577    }
1578  }
1579  result=pOrdPolyMerge(result);
1580  //pTest(result);
1581  return result;
1582}
1583#endif
1584
1585poly ppJet(poly p, int m)
1586{
1587  poly r=NULL;
1588  poly t=NULL;
1589
1590  while (p!=NULL)
1591  {
1592    if (pTotaldegree(p)<=m)
1593    {
1594      if (r==NULL)
1595        r=pHead(p);
1596      else
1597      if (t==NULL)
1598      {
1599        pNext(r)=pHead(p);
1600        t=pNext(r);
1601      }
1602      else
1603      {
1604        pNext(t)=pHead(p);
1605        pIter(t);
1606      }
1607    }
1608    pIter(p);
1609  }
1610  return r;
1611}
1612
1613poly pJet(poly p, int m)
1614{
1615  poly t=NULL;
1616
1617  while((p!=NULL) && (pTotaldegree(p)>m)) pLmDelete(&p);
1618  if (p==NULL) return NULL;
1619  poly r=p;
1620  while (pNext(p)!=NULL)
1621  {
1622    if (pTotaldegree(pNext(p))>m)
1623    {
1624      pLmDelete(&pNext(p));
1625    }
1626    else
1627      pIter(p);
1628  }
1629  return r;
1630}
1631
1632poly ppJetW(poly p, int m, short *w)
1633{
1634  poly r=NULL;
1635  poly t=NULL;
1636  while (p!=NULL)
1637  {
1638    if (totaldegreeWecart_IV(p,currRing,w)<=m)
1639    {
1640      if (r==NULL)
1641        r=pHead(p);
1642      else
1643      if (t==NULL)
1644      {
1645        pNext(r)=pHead(p);
1646        t=pNext(r);
1647      }
1648      else
1649      {
1650        pNext(t)=pHead(p);
1651        pIter(t);
1652      }
1653    }
1654    pIter(p);
1655  }
1656  return r;
1657}
1658
1659poly pJetW(poly p, int m, short *w)
1660{
1661  poly t=NULL;
1662  while((p!=NULL) && (totaldegreeWecart_IV(p,currRing,w)>m)) pLmDelete(&p);
1663  if (p==NULL) return NULL;
1664  poly r=p;
1665  while (pNext(p)!=NULL)
1666  {
1667    if (totaldegreeWecart_IV(pNext(p),currRing,w)>m)
1668    {
1669      pLmDelete(&pNext(p));
1670    }
1671    else
1672      pIter(p);
1673  }
1674  return r;
1675}
1676
1677int pMinDeg(poly p,intvec *w)
1678{
1679  if(p==NULL)
1680    return -1;
1681  int d=-1;
1682  while(p!=NULL)
1683  {
1684    int d0=0;
1685    for(int j=0;j<pVariables;j++)
1686      if(w==NULL||j>=w->length())
1687        d0+=pGetExp(p,j+1);
1688      else
1689        d0+=(*w)[j]*pGetExp(p,j+1);
1690    if(d0<d||d==-1)
1691      d=d0;
1692    pIter(p);
1693  }
1694  return d;
1695}
1696
1697poly pSeries(int n,poly p,poly u, intvec *w)
1698{
1699  short *ww=iv2array(w);
1700  if(p!=NULL)
1701  {
1702    if(u==NULL)
1703      p=pJetW(p,n,ww);
1704    else
1705      p=pJetW(pMult(p,pInvers(n-pMinDeg(p,w),u,w)),n,ww);
1706  }
1707  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1708  return p;
1709}
1710
1711poly pInvers(int n,poly u,intvec *w)
1712{
1713  short *ww=iv2array(w);
1714  if(n<0)
1715    return NULL;
1716  number u0=nInvers(pGetCoeff(u));
1717  poly v=pNSet(u0);
1718  if(n==0)
1719    return v;
1720  poly u1=pJetW(pSub(pOne(),pMult_nn(u,u0)),n,ww);
1721  if(u1==NULL)
1722    return v;
1723  poly v1=pMult_nn(pCopy(u1),u0);
1724  v=pAdd(v,pCopy(v1));
1725  for(int i=n/pMinDeg(u1,w);i>1;i--)
1726  {
1727    v1=pJetW(pMult(v1,pCopy(u1)),n,ww);
1728    v=pAdd(v,pCopy(v1));
1729  }
1730  pDelete(&u1);
1731  pDelete(&v1);
1732  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1733  return v;
1734}
1735
1736long pDegW(poly p, short *w)
1737{
1738  long r=-LONG_MAX;
1739
1740  while (p!=NULL)
1741  {
1742    r=si_max(r, totaldegreeWecart_IV(p,currRing,w));
1743    pIter(p);
1744  }
1745  return r;
1746}
1747
1748/*-----------type conversions ----------------------------*/
1749/*2
1750* input: a set of polys (len elements: p[0]..p[len-1])
1751* output: a vector
1752* p will not be changed
1753*/
1754poly  pPolys2Vec(polyset p, int len)
1755{
1756  poly v=NULL;
1757  poly h;
1758  int i;
1759
1760  for (i=len-1; i>=0; i--)
1761  {
1762    if (p[i])
1763    {
1764      h=pCopy(p[i]);
1765      pSetCompP(h,i+1);
1766      v=pAdd(v,h);
1767    }
1768  }
1769 return v;
1770}
1771
1772/*2
1773* convert a vector to a set of polys,
1774* allocates the polyset, (entries 0..(*len)-1)
1775* the vector will not be changed
1776*/
1777void  pVec2Polys(poly v, polyset *p, int *len)
1778{
1779  poly h;
1780  int k;
1781
1782  *len=pMaxComp(v);
1783  if (*len==0) *len=1;
1784  *p=(polyset)omAlloc0((*len)*sizeof(poly));
1785  while (v!=NULL)
1786  {
1787    h=pHead(v);
1788    k=pGetComp(h);
1789    pSetComp(h,0);
1790    (*p)[k-1]=pAdd((*p)[k-1],h);
1791    pIter(v);
1792  }
1793}
1794
1795int p_Var(poly m,const ring r)
1796{
1797  if (m==NULL) return 0;
1798  if (pNext(m)!=NULL) return 0;
1799  int i,e=0;
1800  for (i=r->N; i>0; i--)
1801  {
1802    if (p_GetExp(m,i,r)==1)
1803    {
1804      if (e==0) e=i;
1805      else return 0;
1806    }
1807  }
1808  return e;
1809}
1810
1811/*----------utilities for syzygies--------------*/
1812//BOOLEAN   pVectorHasUnitM(poly p, int * k)
1813//{
1814//  while (p!=NULL)
1815//  {
1816//    if (pLmIsConstantComp(p))
1817//    {
1818//      *k = pGetComp(p);
1819//      return TRUE;
1820//    }
1821//    else pIter(p);
1822//  }
1823//  return FALSE;
1824//}
1825
1826BOOLEAN   pVectorHasUnitB(poly p, int * k)
1827{
1828  poly q=p,qq;
1829  int i;
1830
1831  while (q!=NULL)
1832  {
1833    if (pLmIsConstantComp(q))
1834    {
1835      i = pGetComp(q);
1836      qq = p;
1837      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1838      if (qq == q)
1839      {
1840        *k = i;
1841        return TRUE;
1842      }
1843      else
1844        pIter(q);
1845    }
1846    else pIter(q);
1847  }
1848  return FALSE;
1849}
1850
1851void   pVectorHasUnit(poly p, int * k, int * len)
1852{
1853  poly q=p,qq;
1854  int i,j=0;
1855
1856  *len = 0;
1857  while (q!=NULL)
1858  {
1859    if (pLmIsConstantComp(q))
1860    {
1861      i = pGetComp(q);
1862      qq = p;
1863      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1864      if (qq == q)
1865      {
1866       j = 0;
1867       while (qq!=NULL)
1868       {
1869         if (pGetComp(qq)==i) j++;
1870        pIter(qq);
1871       }
1872       if ((*len == 0) || (j<*len))
1873       {
1874         *len = j;
1875         *k = i;
1876       }
1877      }
1878    }
1879    pIter(q);
1880  }
1881}
1882
1883/*2
1884* returns TRUE if p1 = p2
1885*/
1886BOOLEAN pEqualPolys(poly p1,poly p2)
1887{
1888  while ((p1 != NULL) && (p2 != NULL))
1889  {
1890    if (! pLmEqual(p1, p2))
1891      return FALSE;
1892    if (! nEqual(pGetCoeff(p1), pGetCoeff(p2)))
1893      return FALSE;
1894    pIter(p1);
1895    pIter(p2);
1896  }
1897  return (p1==p2);
1898}
1899
1900/*2
1901*returns TRUE if p1 is a skalar multiple of p2
1902*assume p1 != NULL and p2 != NULL
1903*/
1904BOOLEAN pComparePolys(poly p1,poly p2)
1905{
1906  number n,nn;
1907  int i;
1908  pAssume(p1 != NULL && p2 != NULL);
1909
1910  if (!pLmEqual(p1,p2)) //compare leading mons
1911      return FALSE;
1912  if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
1913     return FALSE;
1914  if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
1915     return FALSE;
1916  if (pLength(p1) != pLength(p2))
1917    return FALSE;
1918  n=nDiv(pGetCoeff(p1),pGetCoeff(p2));
1919  while ((p1 != NULL) /*&& (p2 != NULL)*/)
1920  {
1921    if ( ! pLmEqual(p1, p2))
1922    {
1923        nDelete(&n);
1924        return FALSE;
1925    }
1926    if (!nEqual(pGetCoeff(p1),nn=nMult(pGetCoeff(p2),n)))
1927    {
1928      nDelete(&n);
1929      nDelete(&nn);
1930      return FALSE;
1931    }
1932    nDelete(&nn);
1933    pIter(p1);
1934    pIter(p2);
1935  }
1936  nDelete(&n);
1937  return TRUE;
1938}
Note: See TracBrowser for help on using the repository browser.