source: git/kernel/polys1.cc @ cafd4ff

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