source: git/kernel/polys1.cc @ d772c3

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