source: git/kernel/polys1.cc @ 376fc2

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