source: git/kernel/polys1.cc @ c58b53

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