source: git/kernel/polys1.cc @ 0b301e

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