source: git/kernel/polys1.cc @ 661c214

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