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

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