source: git/Singular/polys1.cc @ c4bbf1f

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