source: git/kernel/polys1.cc @ f9e6d7

spielwiese
Last change on this file since f9e6d7 was f9e6d7, checked in by Frank Seelisch <seelisch@…>, 12 years ago
fixes ticket #331 git-svn-id: file:///usr/local/Singular/svn/trunk@14117 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 32.7 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        d = nIntDiv(pGetCoeff(p),h);
570        pSetCoeff(p,d);
571        pIter(p);
572      }
573    }
574    nDelete(&h);
575#ifdef HAVE_FACTORY
576    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
577    {
578      singclap_divide_content(ph);
579      if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
580    }
581#endif
582    if (rField_is_Q_a(r))
583    {
584      number hzz = nlInit(1, r);
585      h = nlInit(1, r);
586      p=ph;
587      while (p!=NULL)
588      { // each monom: coeff in Q_a
589        lnumber c_n_n=(lnumber)pGetCoeff(p);
590        napoly c_n=c_n_n->z;
591        while (c_n!=NULL)
592        { // each monom: coeff in Q
593          d=nlLcm(hzz,pGetCoeff(c_n),r->algring);
594          n_Delete(&hzz,r->algring);
595          hzz=d;
596          pIter(c_n);
597        }
598        c_n=c_n_n->n;
599        while (c_n!=NULL)
600        { // each monom: coeff in Q
601          d=nlLcm(h,pGetCoeff(c_n),r->algring);
602          n_Delete(&h,r->algring);
603          h=d;
604          pIter(c_n);
605        }
606        pIter(p);
607      }
608      /* hzz contains the 1/lcm of all denominators in c_n_n->z*/
609      /* h contains the 1/lcm of all denominators in c_n_n->n*/
610      number htmp=nlInvers(h);
611      number hzztmp=nlInvers(hzz);
612      number hh=nlMult(hzz,h);
613      nlDelete(&hzz,r->algring);
614      nlDelete(&h,r->algring);
615      number hg=nlGcd(hzztmp,htmp,r->algring);
616      nlDelete(&hzztmp,r->algring);
617      nlDelete(&htmp,r->algring);
618      h=nlMult(hh,hg);
619      nlDelete(&hg,r->algring);
620      nlDelete(&hh,r->algring);
621      nlNormalize(h);
622      if(!nlIsOne(h))
623      {
624        p=ph;
625        while (p!=NULL)
626        { // each monom: coeff in Q_a
627          lnumber c_n_n=(lnumber)pGetCoeff(p);
628          napoly c_n=c_n_n->z;
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),r->algring);
634            pGetCoeff(c_n)=d;
635            pIter(c_n);
636          }
637          c_n=c_n_n->n;
638          while (c_n!=NULL)
639          { // each monom: coeff in Q
640            d=nlMult(h,pGetCoeff(c_n));
641            nlNormalize(d);
642            nlDelete(&pGetCoeff(c_n),r->algring);
643            pGetCoeff(c_n)=d;
644            pIter(c_n);
645          }
646          pIter(p);
647        }
648      }
649      nlDelete(&h,r->algring);
650    }
651  }
652}
653
654void pSimpleContent(poly ph,int smax)
655{
656  if(TEST_OPT_CONTENTSB) return;
657  if (ph==NULL) return;
658  if (pNext(ph)==NULL)
659  {
660    pSetCoeff(ph,nInit(1));
661    return;
662  }
663  if ((pNext(pNext(ph))==NULL)||(!rField_is_Q()))
664  {
665    return;
666  }
667  number d=pInitContent(ph);
668  if (nlSize(d)<=smax)
669  {
670    //if (TEST_OPT_PROT) PrintS("G");
671    return;
672  }
673  poly p=ph;
674  number h=d;
675  if (smax==1) smax=2;
676  while (p!=NULL)
677  {
678#if 0
679    d=nlGcd(h,pGetCoeff(p),currRing);
680    nlDelete(&h,currRing);
681    h = d;
682#else
683    nlInpGcd(h,pGetCoeff(p),currRing);
684#endif
685    if(nlSize(h)<smax)
686    {
687      //if (TEST_OPT_PROT) PrintS("g");
688      return;
689    }
690    pIter(p);
691  }
692  p = ph;
693  if (!nlGreaterZero(pGetCoeff(p))) h=nlNeg(h);
694  if(nlIsOne(h)) return;
695  //if (TEST_OPT_PROT) PrintS("c");
696  while (p!=NULL)
697  {
698#if 1
699    d = nlIntDiv(pGetCoeff(p),h);
700    pSetCoeff(p,d);
701#else
702    nlInpIntDiv(pGetCoeff(p),h,currRing);
703#endif
704    pIter(p);
705  }
706  nlDelete(&h,currRing);
707}
708
709number pInitContent(poly ph)
710// only for coefficients in Q
711#if 0
712{
713  assume(!TEST_OPT_CONTENTSB);
714  assume(ph!=NULL);
715  assume(pNext(ph)!=NULL);
716  assume(rField_is_Q());
717  if (pNext(pNext(ph))==NULL)
718  {
719    return nlGetNom(pGetCoeff(pNext(ph)),currRing);
720  }
721  poly p=ph;
722  number n1=nlGetNom(pGetCoeff(p),currRing);
723  pIter(p);
724  number n2=nlGetNom(pGetCoeff(p),currRing);
725  pIter(p);
726  number d;
727  number t;
728  loop
729  {
730    nlNormalize(pGetCoeff(p));
731    t=nlGetNom(pGetCoeff(p),currRing);
732    if (nlGreaterZero(t))
733      d=nlAdd(n1,t);
734    else
735      d=nlSub(n1,t);
736    nlDelete(&t,currRing);
737    nlDelete(&n1,currRing);
738    n1=d;
739    pIter(p);
740    if (p==NULL) break;
741    nlNormalize(pGetCoeff(p));
742    t=nlGetNom(pGetCoeff(p),currRing);
743    if (nlGreaterZero(t))
744      d=nlAdd(n2,t);
745    else
746      d=nlSub(n2,t);
747    nlDelete(&t,currRing);
748    nlDelete(&n2,currRing);
749    n2=d;
750    pIter(p);
751    if (p==NULL) break;
752  }
753  d=nlGcd(n1,n2,currRing);
754  nlDelete(&n1,currRing);
755  nlDelete(&n2,currRing);
756  return d;
757}
758#else
759{
760  number d=pGetCoeff(ph);
761  if(SR_HDL(d)&SR_INT) return d;
762  int s=mpz_size1(d->z);
763  int s2=-1;
764  number d2;
765  loop
766  {
767    pIter(ph);
768    if(ph==NULL)
769    {
770      if (s2==-1) return nlCopy(d);
771      break;
772    }
773    if (SR_HDL(pGetCoeff(ph))&SR_INT)
774    {
775      s2=s;
776      d2=d;
777      s=0;
778      d=pGetCoeff(ph);
779      if (s2==0) break;
780    }
781    else
782    if (mpz_size1((pGetCoeff(ph)->z))<=s)
783    {
784      s2=s;
785      d2=d;
786      d=pGetCoeff(ph);
787      s=mpz_size1(d->z);
788    }
789  }
790  return nlGcd(d,d2,currRing);
791}
792#endif
793
794number pInitContent_a(poly ph)
795// only for coefficients in K(a) anf K(a,...)
796{
797  number d=pGetCoeff(ph);
798  int s=naParDeg(d);
799  if (s /* naParDeg(d)*/ <=1) return naCopy(d);
800  int s2=-1;
801  number d2;
802  int ss;
803  loop
804  {
805    pIter(ph);
806    if(ph==NULL)
807    {
808      if (s2==-1) return naCopy(d);
809      break;
810    }
811    if ((ss=naParDeg(pGetCoeff(ph)))<s)
812    {
813      s2=s;
814      d2=d;
815      s=ss;
816      d=pGetCoeff(ph);
817      if (s2<=1) break;
818    }
819  }
820  return naGcd(d,d2,currRing);
821}
822
823
824//void pContent(poly ph)
825//{
826//  number h,d;
827//  poly p;
828//
829//  p = ph;
830//  if(pNext(p)==NULL)
831//  {
832//    pSetCoeff(p,nInit(1));
833//  }
834//  else
835//  {
836//#ifdef PDEBUG
837//    if (!pTest(p)) return;
838//#endif
839//    nNormalize(pGetCoeff(p));
840//    if(!nGreaterZero(pGetCoeff(ph)))
841//    {
842//      ph = pNeg(ph);
843//      nNormalize(pGetCoeff(p));
844//    }
845//    h=pGetCoeff(p);
846//    pIter(p);
847//    while (p!=NULL)
848//    {
849//      nNormalize(pGetCoeff(p));
850//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
851//      pIter(p);
852//    }
853//    h=nCopy(h);
854//    p=ph;
855//    while (p!=NULL)
856//    {
857//      d=nGcd(h,pGetCoeff(p));
858//      nDelete(&h);
859//      h = d;
860//      if(nIsOne(h))
861//      {
862//        break;
863//      }
864//      pIter(p);
865//    }
866//    p = ph;
867//    //number tmp;
868//    if(!nIsOne(h))
869//    {
870//      while (p!=NULL)
871//      {
872//        d = nIntDiv(pGetCoeff(p),h);
873//        pSetCoeff(p,d);
874//        pIter(p);
875//      }
876//    }
877//    nDelete(&h);
878//#ifdef HAVE_FACTORY
879//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
880//    {
881//      pTest(ph);
882//      singclap_divide_content(ph);
883//      pTest(ph);
884//    }
885//#endif
886//  }
887//}
888#if 0
889void p_Content(poly ph, ring r)
890{
891  number h,d;
892  poly p;
893
894  if(pNext(ph)==NULL)
895  {
896    pSetCoeff(ph,n_Init(1,r));
897  }
898  else
899  {
900    n_Normalize(pGetCoeff(ph),r);
901    if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
902    h=n_Copy(pGetCoeff(ph),r);
903    p = pNext(ph);
904    while (p!=NULL)
905    {
906      n_Normalize(pGetCoeff(p),r);
907      d=n_Gcd(h,pGetCoeff(p),r);
908      n_Delete(&h,r);
909      h = d;
910      if(n_IsOne(h,r))
911      {
912        break;
913      }
914      pIter(p);
915    }
916    p = ph;
917    //number tmp;
918    if(!n_IsOne(h,r))
919    {
920      while (p!=NULL)
921      {
922        //d = nDiv(pGetCoeff(p),h);
923        //tmp = nIntDiv(pGetCoeff(p),h);
924        //if (!nEqual(d,tmp))
925        //{
926        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
927        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
928        //  nWrite(tmp);Print(StringAppendS("\n"));
929        //}
930        //nDelete(&tmp);
931        d = n_IntDiv(pGetCoeff(p),h,r);
932        p_SetCoeff(p,d,r);
933        pIter(p);
934      }
935    }
936    n_Delete(&h,r);
937#ifdef HAVE_FACTORY
938    //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
939    //{
940    //  singclap_divide_content(ph);
941    //  if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
942    //}
943#endif
944  }
945}
946#endif
947
948poly p_Cleardenom(poly ph, const ring r)
949{
950  poly start=ph;
951  number d, h;
952  poly p;
953
954#ifdef HAVE_RINGS
955  if (rField_is_Ring(r))
956  {
957    p_Content(ph,r);
958    return start;
959  }
960#endif
961  if (rField_is_Zp(r) && TEST_OPT_INTSTRATEGY) return start;
962  p = ph;
963  if(pNext(p)==NULL)
964  {
965    if (TEST_OPT_CONTENTSB)
966    {
967      number n=nGetDenom(pGetCoeff(p));
968      if (!nIsOne(n))
969      {
970        number nn=nMult(pGetCoeff(p),n);
971        nNormalize(nn);
972        pSetCoeff(p,nn);
973      }
974      nDelete(&n);
975    }
976    else
977      pSetCoeff(p,nInit(1));
978  }
979  else
980  {
981    h = nInit(1);
982    while (p!=NULL)
983    {
984      nNormalize(pGetCoeff(p));
985      d=nLcm(h,pGetCoeff(p),currRing);
986      nDelete(&h);
987      h=d;
988      pIter(p);
989    }
990    /* contains the 1/lcm of all denominators */
991    if(!nIsOne(h))
992    {
993      p = ph;
994      while (p!=NULL)
995      {
996        /* should be:
997        * number hh;
998        * nGetDenom(p->coef,&hh);
999        * nMult(&h,&hh,&d);
1000        * nNormalize(d);
1001        * nDelete(&hh);
1002        * nMult(d,p->coef,&hh);
1003        * nDelete(&d);
1004        * nDelete(&(p->coef));
1005        * p->coef =hh;
1006        */
1007        d=nMult(h,pGetCoeff(p));
1008        nNormalize(d);
1009        pSetCoeff(p,d);
1010        pIter(p);
1011      }
1012      nDelete(&h);
1013      if (nGetChar()==1)
1014      {
1015        loop
1016        {
1017          h = nInit(1);
1018          p=ph;
1019          while (p!=NULL)
1020          {
1021            d=nLcm(h,pGetCoeff(p),currRing);
1022            nDelete(&h);
1023            h=d;
1024            pIter(p);
1025          }
1026          /* contains the 1/lcm of all denominators */
1027          if(!nIsOne(h))
1028          {
1029            p = ph;
1030            while (p!=NULL)
1031            {
1032              /* should be:
1033              * number hh;
1034              * nGetDenom(p->coef,&hh);
1035              * nMult(&h,&hh,&d);
1036              * nNormalize(d);
1037              * nDelete(&hh);
1038              * nMult(d,p->coef,&hh);
1039              * nDelete(&d);
1040              * nDelete(&(p->coef));
1041              * p->coef =hh;
1042              */
1043              d=nMult(h,pGetCoeff(p));
1044              nNormalize(d);
1045              pSetCoeff(p,d);
1046              pIter(p);
1047            }
1048            nDelete(&h);
1049          }
1050          else
1051          {
1052            nDelete(&h);
1053            break;
1054          }
1055        }
1056      }
1057    }
1058    if (h!=NULL) nDelete(&h);
1059 
1060    p_Content(ph,r);
1061#ifdef HAVE_RATGRING
1062    if (rIsRatGRing(r))
1063    {
1064      /* quick unit detection in the rational case is done in gr_nc_bba */
1065      pContentRat(ph);
1066      start=ph;
1067    }
1068#endif
1069  }
1070  return start;
1071}
1072
1073void p_Cleardenom_n(poly ph,const ring r,number &c)
1074{
1075  number d, h;
1076  poly p;
1077
1078  p = ph;
1079  if(pNext(p)==NULL)
1080  {
1081    c=nInvers(pGetCoeff(p));
1082    pSetCoeff(p,nInit(1));
1083  }
1084  else
1085  {
1086    h = nInit(1);
1087    while (p!=NULL)
1088    {
1089      nNormalize(pGetCoeff(p));
1090      d=nLcm(h,pGetCoeff(p),r);
1091      nDelete(&h);
1092      h=d;
1093      pIter(p);
1094    }
1095    c=h;
1096    /* contains the 1/lcm of all denominators */
1097    if(!nIsOne(h))
1098    {
1099      p = ph;
1100      while (p!=NULL)
1101      {
1102        /* should be:
1103        * number hh;
1104        * nGetDenom(p->coef,&hh);
1105        * nMult(&h,&hh,&d);
1106        * nNormalize(d);
1107        * nDelete(&hh);
1108        * nMult(d,p->coef,&hh);
1109        * nDelete(&d);
1110        * nDelete(&(p->coef));
1111        * p->coef =hh;
1112        */
1113        d=nMult(h,pGetCoeff(p));
1114        nNormalize(d);
1115        pSetCoeff(p,d);
1116        pIter(p);
1117      }
1118      if (nGetChar()==1)
1119      {
1120        loop
1121        {
1122          h = nInit(1);
1123          p=ph;
1124          while (p!=NULL)
1125          {
1126            d=nLcm(h,pGetCoeff(p),r);
1127            nDelete(&h);
1128            h=d;
1129            pIter(p);
1130          }
1131          /* contains the 1/lcm of all denominators */
1132          if(!nIsOne(h))
1133          {
1134            p = ph;
1135            while (p!=NULL)
1136            {
1137              /* should be:
1138              * number hh;
1139              * nGetDenom(p->coef,&hh);
1140              * nMult(&h,&hh,&d);
1141              * nNormalize(d);
1142              * nDelete(&hh);
1143              * nMult(d,p->coef,&hh);
1144              * nDelete(&d);
1145              * nDelete(&(p->coef));
1146              * p->coef =hh;
1147              */
1148              d=nMult(h,pGetCoeff(p));
1149              nNormalize(d);
1150              pSetCoeff(p,d);
1151              pIter(p);
1152            }
1153            number t=nMult(c,h);
1154            nDelete(&c);
1155            c=t;
1156          }
1157          else
1158          {
1159            break;
1160          }
1161          nDelete(&h);
1162        }
1163      }
1164    }
1165  }
1166}
1167
1168number p_GetAllDenom(poly ph, const ring r)
1169{
1170  number d=n_Init(1,r);
1171  poly p = ph;
1172
1173  while (p!=NULL)
1174  {
1175    number h=n_GetDenom(pGetCoeff(p),r);
1176    if (!n_IsOne(h,r))
1177    {
1178      number dd=n_Mult(d,h,r);
1179      n_Delete(&d,r);
1180      d=dd;
1181    }
1182    n_Delete(&h,r);
1183    pIter(p);
1184  }
1185  return d;
1186}
1187
1188/*2
1189*tests if p is homogeneous with respect to the actual weigths
1190*/
1191BOOLEAN pIsHomogeneous (poly p)
1192{
1193  poly qp=p;
1194  int o;
1195
1196  if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
1197  pFDegProc d;
1198  if (pLexOrder && (currRing->order[0]==ringorder_lp))
1199    d=p_Totaldegree;
1200  else 
1201    d=pFDeg;
1202  o = d(p,currRing);
1203  do
1204  {
1205    if (d(qp,currRing) != o) return FALSE;
1206    pIter(qp);
1207  }
1208  while (qp != NULL);
1209  return TRUE;
1210}
1211
1212/*2
1213*returns a re-ordered copy of a polynomial, with permutation of the variables
1214*/
1215poly pPermPoly (poly p, int * perm, const ring oldRing, nMapFunc nMap,
1216   int *par_perm, int OldPar)
1217{
1218  int OldpVariables = oldRing->N;
1219  poly result = NULL;
1220  poly result_last = NULL;
1221  poly aq=NULL; /* the map coefficient */
1222  poly qq; /* the mapped monomial */
1223
1224  while (p != NULL)
1225  {
1226    if ((OldPar==0)||(rField_is_GF(oldRing)))
1227    {
1228      qq = pInit();
1229      number n=nMap(pGetCoeff(p));
1230      if ((currRing->minpoly!=NULL)
1231      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1232      {
1233        nNormalize(n);
1234      }
1235      pGetCoeff(qq)=n;
1236    // coef may be zero:  pTest(qq);
1237    }
1238    else
1239    {
1240      qq=pOne();
1241      aq=napPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
1242      if ((currRing->minpoly!=NULL)
1243      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
1244      {
1245        poly tmp=aq;
1246        while (tmp!=NULL)
1247        {
1248          number n=pGetCoeff(tmp);
1249          nNormalize(n);
1250          pGetCoeff(tmp)=n;
1251          pIter(tmp);
1252        }
1253      }
1254      pTest(aq);
1255    }
1256    if (rRing_has_Comp(currRing)) pSetComp(qq, p_GetComp(p,oldRing));
1257    if (nIsZero(pGetCoeff(qq)))
1258    {
1259      pLmDelete(&qq);
1260    }
1261    else
1262    {
1263      int i;
1264      int mapped_to_par=0;
1265      for(i=1; i<=OldpVariables; i++)
1266      {
1267        int e=p_GetExp(p,i,oldRing);
1268        if (e!=0)
1269        {
1270          if (perm==NULL)
1271          {
1272            pSetExp(qq,i, e);
1273          }
1274          else if (perm[i]>0)
1275            pAddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/);
1276          else if (perm[i]<0)
1277          {
1278            if (rField_is_GF())
1279            {
1280              number c=pGetCoeff(qq);
1281              number ee=nfPar(1);
1282              number eee;nfPower(ee,e,&eee); //nfDelete(ee,currRing);
1283              ee=nfMult(c,eee);
1284              //nfDelete(c,currRing);nfDelete(eee,currRing);
1285              pSetCoeff0(qq,ee);
1286            }
1287            else
1288            {
1289              lnumber c=(lnumber)pGetCoeff(qq);
1290              if (c->z->next==NULL)
1291                napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1292              else /* more difficult: we have really to multiply: */
1293              {
1294                lnumber mmc=(lnumber)naInit(1,currRing);
1295                napSetExp(mmc->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
1296                napSetm(mmc->z);
1297                pGetCoeff(qq)=naMult((number)c,(number)mmc);
1298                nDelete((number *)&c);
1299                nDelete((number *)&mmc); 
1300              }
1301              mapped_to_par=1;
1302            }
1303          }
1304          else
1305          {
1306            /* this variable maps to 0 !*/
1307            pLmDelete(&qq);
1308            break;
1309          }
1310        }
1311      }
1312      if (mapped_to_par
1313      && (currRing->minpoly!=NULL))
1314      {
1315        number n=pGetCoeff(qq);
1316        nNormalize(n);
1317        pGetCoeff(qq)=n;
1318      }
1319    }
1320    pIter(p);
1321#if 1
1322    if (qq!=NULL)
1323    {
1324      pSetm(qq);
1325      pTest(aq);
1326      pTest(qq);
1327      if (aq!=NULL) qq=pMult(aq,qq);
1328      aq = qq;
1329      while (pNext(aq) != NULL) pIter(aq);
1330      if (result_last==NULL)
1331      {
1332        result=qq;
1333      }
1334      else
1335      {
1336        pNext(result_last)=qq;
1337      }
1338      result_last=aq;
1339      aq = NULL;
1340    }
1341    else if (aq!=NULL)
1342    {
1343      pDelete(&aq);
1344    }
1345  }
1346  result=pSortAdd(result);
1347#else
1348  //  if (qq!=NULL)
1349  //  {
1350  //    pSetm(qq);
1351  //    pTest(qq);
1352  //    pTest(aq);
1353  //    if (aq!=NULL) qq=pMult(aq,qq);
1354  //    aq = qq;
1355  //    while (pNext(aq) != NULL) pIter(aq);
1356  //    pNext(aq) = result;
1357  //    aq = NULL;
1358  //    result = qq;
1359  //  }
1360  //  else if (aq!=NULL)
1361  //  {
1362  //    pDelete(&aq);
1363  //  }
1364  //}
1365  //p = result;
1366  //result = NULL;
1367  //while (p != NULL)
1368  //{
1369  //  qq = p;
1370  //  pIter(p);
1371  //  qq->next = NULL;
1372  //  result = pAdd(result, qq);
1373  //}
1374#endif
1375  pTest(result);
1376  return result;
1377}
1378
1379poly ppJet(poly p, int m)
1380{
1381  poly r=NULL;
1382  poly t=NULL;
1383
1384  while (p!=NULL)
1385  {
1386    if (p_Totaldegree(p,currRing)<=m)
1387    {
1388      if (r==NULL)
1389        r=pHead(p);
1390      else
1391      if (t==NULL)
1392      {
1393        pNext(r)=pHead(p);
1394        t=pNext(r);
1395      }
1396      else
1397      {
1398        pNext(t)=pHead(p);
1399        pIter(t);
1400      }
1401    }
1402    pIter(p);
1403  }
1404  return r;
1405}
1406
1407poly pJet(poly p, int m)
1408{
1409  poly t=NULL;
1410
1411  while((p!=NULL) && (p_Totaldegree(p,currRing)>m)) pLmDelete(&p);
1412  if (p==NULL) return NULL;
1413  poly r=p;
1414  while (pNext(p)!=NULL)
1415  {
1416    if (p_Totaldegree(pNext(p),currRing)>m)
1417    {
1418      pLmDelete(&pNext(p));
1419    }
1420    else
1421      pIter(p);
1422  }
1423  return r;
1424}
1425
1426poly ppJetW(poly p, int m, short *w)
1427{
1428  poly r=NULL;
1429  poly t=NULL;
1430  while (p!=NULL)
1431  {
1432    if (totaldegreeWecart_IV(p,currRing,w)<=m)
1433    {
1434      if (r==NULL)
1435        r=pHead(p);
1436      else
1437      if (t==NULL)
1438      {
1439        pNext(r)=pHead(p);
1440        t=pNext(r);
1441      }
1442      else
1443      {
1444        pNext(t)=pHead(p);
1445        pIter(t);
1446      }
1447    }
1448    pIter(p);
1449  }
1450  return r;
1451}
1452
1453poly pJetW(poly p, int m, short *w)
1454{
1455  poly t=NULL;
1456  while((p!=NULL) && (totaldegreeWecart_IV(p,currRing,w)>m)) pLmDelete(&p);
1457  if (p==NULL) return NULL;
1458  poly r=p;
1459  while (pNext(p)!=NULL)
1460  {
1461    if (totaldegreeWecart_IV(pNext(p),currRing,w)>m)
1462    {
1463      pLmDelete(&pNext(p));
1464    }
1465    else
1466      pIter(p);
1467  }
1468  return r;
1469}
1470
1471int pMinDeg(poly p,intvec *w)
1472{
1473  if(p==NULL)
1474    return -1;
1475  int d=-1;
1476  while(p!=NULL)
1477  {
1478    int d0=0;
1479    for(int j=0;j<pVariables;j++)
1480      if(w==NULL||j>=w->length())
1481        d0+=pGetExp(p,j+1);
1482      else
1483        d0+=(*w)[j]*pGetExp(p,j+1);
1484    if(d0<d||d==-1)
1485      d=d0;
1486    pIter(p);
1487  }
1488  return d;
1489}
1490
1491poly pSeries(int n,poly p,poly u, intvec *w)
1492{
1493  short *ww=iv2array(w);
1494  if(p!=NULL)
1495  {
1496    if(u==NULL)
1497      p=pJetW(p,n,ww);
1498    else
1499      p=pJetW(pMult(p,pInvers(n-pMinDeg(p,w),u,w)),n,ww);
1500  }
1501  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1502  return p;
1503}
1504
1505poly pInvers(int n,poly u,intvec *w)
1506{
1507  short *ww=iv2array(w);
1508  if(n<0)
1509    return NULL;
1510  number u0=nInvers(pGetCoeff(u));
1511  poly v=pNSet(u0);
1512  if(n==0)
1513    return v;
1514  poly u1=pJetW(pSub(pOne(),pMult_nn(u,u0)),n,ww);
1515  if(u1==NULL)
1516    return v;
1517  poly v1=pMult_nn(pCopy(u1),u0);
1518  v=pAdd(v,pCopy(v1));
1519  for(int i=n/pMinDeg(u1,w);i>1;i--)
1520  {
1521    v1=pJetW(pMult(v1,pCopy(u1)),n,ww);
1522    v=pAdd(v,pCopy(v1));
1523  }
1524  pDelete(&u1);
1525  pDelete(&v1);
1526  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
1527  return v;
1528}
1529
1530long pDegW(poly p, const short *w)
1531{
1532  long r=-LONG_MAX;
1533
1534  while (p!=NULL)
1535  {
1536    long t=totaldegreeWecart_IV(p,currRing,w);
1537    if (t>r) r=t;
1538    pIter(p);
1539  }
1540  return r;
1541}
1542
1543/*-----------type conversions ----------------------------*/
1544#if 0
1545/*2
1546* input: a set of polys (len elements: p[0]..p[len-1])
1547* output: a vector
1548* p will not be changed
1549*/
1550poly  pPolys2Vec(polyset p, int len)
1551{
1552  poly v=NULL;
1553  poly h;
1554  int i;
1555
1556  for (i=len-1; i>=0; i--)
1557  {
1558    if (p[i])
1559    {
1560      h=pCopy(p[i]);
1561      pSetCompP(h,i+1);
1562      v=pAdd(v,h);
1563    }
1564  }
1565 return v;
1566}
1567#endif
1568
1569/*2
1570* convert a vector to a set of polys,
1571* allocates the polyset, (entries 0..(*len)-1)
1572* the vector will not be changed
1573*/
1574void  pVec2Polys(poly v, polyset *p, int *len)
1575{
1576  poly h;
1577  int k;
1578
1579  *len=pMaxComp(v);
1580  if (*len==0) *len=1;
1581  *p=(polyset)omAlloc0((*len)*sizeof(poly));
1582  while (v!=NULL)
1583  {
1584    h=pHead(v);
1585    k=pGetComp(h);
1586    pSetComp(h,0);
1587    (*p)[k-1]=pAdd((*p)[k-1],h);
1588    pIter(v);
1589  }
1590}
1591
1592int p_Var(poly m,const ring r)
1593{
1594  if (m==NULL) return 0;
1595  if (pNext(m)!=NULL) return 0;
1596  int i,e=0;
1597  for (i=r->N; i>0; i--)
1598  {
1599    int exp=p_GetExp(m,i,r);
1600    if (exp==1)
1601    {
1602      if (e==0) e=i;
1603      else return 0;
1604    }
1605    else if (exp!=0)
1606    {
1607      return 0;
1608    }
1609  }
1610  return e;
1611}
1612
1613/*----------utilities for syzygies--------------*/
1614//BOOLEAN   pVectorHasUnitM(poly p, int * k)
1615//{
1616//  while (p!=NULL)
1617//  {
1618//    if (pLmIsConstantComp(p))
1619//    {
1620//      *k = pGetComp(p);
1621//      return TRUE;
1622//    }
1623//    else pIter(p);
1624//  }
1625//  return FALSE;
1626//}
1627
1628BOOLEAN   pVectorHasUnitB(poly p, int * k)
1629{
1630  poly q=p,qq;
1631  int i;
1632
1633  while (q!=NULL)
1634  {
1635    if (pLmIsConstantComp(q))
1636    {
1637      i = pGetComp(q);
1638      qq = p;
1639      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1640      if (qq == q)
1641      {
1642        *k = i;
1643        return TRUE;
1644      }
1645      else
1646        pIter(q);
1647    }
1648    else pIter(q);
1649  }
1650  return FALSE;
1651}
1652
1653void   pVectorHasUnit(poly p, int * k, int * len)
1654{
1655  poly q=p,qq;
1656  int i,j=0;
1657
1658  *len = 0;
1659  while (q!=NULL)
1660  {
1661    if (pLmIsConstantComp(q))
1662    {
1663      i = pGetComp(q);
1664      qq = p;
1665      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
1666      if (qq == q)
1667      {
1668       j = 0;
1669       while (qq!=NULL)
1670       {
1671         if (pGetComp(qq)==i) j++;
1672        pIter(qq);
1673       }
1674       if ((*len == 0) || (j<*len))
1675       {
1676         *len = j;
1677         *k = i;
1678       }
1679      }
1680    }
1681    pIter(q);
1682  }
1683}
1684
1685/*2
1686* returns TRUE if p1 = p2
1687*/
1688BOOLEAN p_EqualPolys(poly p1,poly p2, const ring r)
1689{
1690  while ((p1 != NULL) && (p2 != NULL))
1691  {
1692    if (! p_LmEqual(p1, p2,r))
1693      return FALSE;
1694    if (! n_Equal(p_GetCoeff(p1,r), p_GetCoeff(p2,r),r ))
1695      return FALSE;
1696    pIter(p1);
1697    pIter(p2);
1698  }
1699  return (p1==p2);
1700}
1701
1702/*2
1703*returns TRUE if p1 is a skalar multiple of p2
1704*assume p1 != NULL and p2 != NULL
1705*/
1706BOOLEAN pComparePolys(poly p1,poly p2)
1707{
1708  number n,nn;
1709  int i;
1710  pAssume(p1 != NULL && p2 != NULL);
1711
1712  if (!pLmEqual(p1,p2)) //compare leading mons
1713      return FALSE;
1714  if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
1715     return FALSE;
1716  if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
1717     return FALSE;
1718  if (pLength(p1) != pLength(p2))
1719    return FALSE;
1720#ifdef HAVE_RINGS
1721  if (rField_is_Ring(currRing))
1722  {
1723    if (!nDivBy(pGetCoeff(p1), pGetCoeff(p2))) return FALSE;
1724  }
1725#endif
1726  n=nDiv(pGetCoeff(p1),pGetCoeff(p2));
1727  while ((p1 != NULL) /*&& (p2 != NULL)*/)
1728  {
1729    if ( ! pLmEqual(p1, p2))
1730    {
1731        nDelete(&n);
1732        return FALSE;
1733    }
1734    if (!nEqual(pGetCoeff(p1),nn=nMult(pGetCoeff(p2),n)))
1735    {
1736      nDelete(&n);
1737      nDelete(&nn);
1738      return FALSE;
1739    }
1740    nDelete(&nn);
1741    pIter(p1);
1742    pIter(p2);
1743  }
1744  nDelete(&n);
1745  return TRUE;
1746}
Note: See TracBrowser for help on using the repository browser.