source: git/Singular/polys.cc @ 512a2b

spielwiese
Last change on this file since 512a2b was 512a2b, checked in by Olaf Bachmann <obachman@…>, 24 years ago
p_polys.h git-svn-id: file:///usr/local/Singular/svn/trunk@4606 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 33.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys.cc,v 1.62 2000-09-18 09:19:29 obachman Exp $ */
5
6/*
7* ABSTRACT - all basic methods to manipulate polynomials
8*/
9
10/* includes */
11#include <stdio.h>
12#include <string.h>
13#include <ctype.h>
14#include "mod2.h"
15#include "tok.h"
16#include "omalloc.h"
17#include "febase.h"
18#include "numbers.h"
19#include "polys.h"
20#include "ring.h"
21
22/* ----------- global variables, set by pSetGlobals --------------------- */
23/* initializes the internal data from the exp vector */
24pSetmProc pSetm;
25/* computes length and maximal degree of a POLYnomial */
26pLDegProc pLDeg;
27/* computes the degree of the initial term, used for std */
28pFDegProc pFDeg;
29/* the monomial ordering of the head monomials a and b */
30/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
31
32int pVariables;     // number of variables
33//int pVariablesW;    // number of words of pVariables exponents
34//int pVariables1W;   // number of words of (pVariables+1) exponents
35int pMonomSize;     // size of monom (in bytes)
36int pMonomSizeW;    // size of monom (in words)
37int *pVarOffset;    // controls the way exponents are stored in a vector
38//int pVarLowIndex;   // lowest exponent index
39//int pVarHighIndex;  // highest exponent index
40//int pVarCompIndex;  // Location of component in exponent vector
41
42/* 1 for polynomial ring, -1 otherwise */
43int     pOrdSgn;
44/* TRUE for momomial output as x2y, FALSE for x^2*y */
45int pShortOut = (int)TRUE;
46// it is of type int, not BOOLEAN because it is also in ip
47/* TRUE if the monomial ordering is not compatible with pFDeg */
48BOOLEAN pLexOrder;
49/* TRUE if the monomial ordering has polynomial and power series blocks */
50BOOLEAN pMixedOrder;
51/* 1 for c ordering, -1 otherwise (i.e. for C ordering) */
52int  pComponentOrder;
53
54/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
55/* the highest monomial below pHEdge */
56poly      ppNoether = NULL;
57
58/* -------------- static variables --------------------------------------- */
59/*is the basic comparing procedure during a computation of syzygies*/
60//static pCompProc pCompOld;
61
62/*contains the headterms for the Schreyer orderings*/
63static int* SchreyerOrd;
64static int maxSchreyer=0;
65static int indexShift=0;
66static pLDegProc pLDegOld;
67
68static int**   polys_wv;
69static short *   firstwv;
70static int * block0;
71static int * block1;
72static int firstBlockEnds;
73static int * order;
74
75/*0 implementation*/
76/*-------- the several possibilities for pSetm:-----------------------*/
77
78void p_Setm(poly p, ring r)
79{
80  int pos=0;
81  if (r->typ!=NULL)
82  {
83    loop
84    {
85      sro_ord* o=&(r->typ[pos]);
86      switch(o->ord_typ)
87      {
88        case ro_dp:
89        {
90          int a,e;
91          a=o->data.dp.start;
92          e=o->data.dp.end;
93          long ord=0; //0x40000000;
94          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
95          p->exp[o->data.dp.place]=ord;
96          break;
97        }
98        case ro_wp:
99        {
100          int a,e;
101          a=o->data.wp.start;
102          e=o->data.wp.end;
103          int *w=o->data.wp.weights;
104          long ord=0; //0x40000000;
105          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r)*w[i-a];
106          p->exp[o->data.wp.place]=ord;
107          break;
108        }
109        case ro_cp:
110        {
111          int a,e;
112          a=o->data.cp.start;
113          e=o->data.cp.end;
114          int pl=o->data.cp.place;
115          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
116          break;
117        }
118        case ro_syzcomp:
119        {
120          int c=p_GetComp(p,r);
121          long sc = c;
122          if (o->data.syzcomp.ShiftedComponents != NULL)
123          {
124            assume(o->data.syzcomp.Components != NULL);
125            assume(c == 0 || o->data.syzcomp.Components[c] != 0);
126            sc =
127              o->data.syzcomp.ShiftedComponents[o->data.syzcomp.Components[c]];
128            assume(c == 0 || sc != 0);
129          }
130          p->exp[o->data.syzcomp.place]=sc;
131          break;
132        }
133        case ro_syz:
134        {
135          int c=pGetComp(p);
136          if (c > o->data.syz.limit)
137            p->exp[o->data.syz.place] = o->data.syz.curr_index;
138          else if (c > 0)
139            p->exp[o->data.syz.place]= o->data.syz.syz_index[c];
140          else
141          {
142            assume(c == 0);
143            p->exp[o->data.syz.place]= 0;
144          }
145          break;
146        }
147        default:
148          Print("wrong ord in rSetm:%d\n",o->ord_typ);
149          return;
150      }
151      pos++;
152      if(pos==currRing->OrdSize) return;
153    }
154  }
155}
156
157void rSetmS(poly p, int* Components, long* ShiftedComponents)
158{
159  int pos=0;
160  assume(Components != NULL && ShiftedComponents != NULL);
161  if (currRing->typ!=NULL)
162  {
163    loop
164    {
165      sro_ord* o=&(currRing->typ[pos]);
166      switch(o->ord_typ)
167      {
168        case ro_dp:
169        {
170          int a,e;
171          a=o->data.dp.start;
172          e=o->data.dp.end;
173          long ord=0;
174          for(int i=a;i<=e;i++) ord+=pGetExp(p,i);
175          p->exp[o->data.dp.place]=ord;
176          break;
177        }
178        case ro_wp:
179        {
180          int a,e;
181          a=o->data.wp.start;
182          e=o->data.wp.end;
183          int *w=o->data.wp.weights;
184          long ord=0;
185          for(int i=a;i<=e;i++) ord+=pGetExp(p,i)*w[i-a];
186          p->exp[o->data.wp.place]=ord;
187          break;
188        }
189        case ro_cp:
190        {
191          int a,e;
192          a=o->data.cp.start;
193          e=o->data.cp.end;
194          int pl=o->data.cp.place;
195          for(int i=a;i<=e;i++) { p->exp[pl]=pGetExp(p,i); pl++; }
196          break;
197        }
198        case ro_syzcomp:
199        {
200          int c=pGetComp(p);
201          long sc  = ShiftedComponents[Components[c]];
202          assume(c == 0 || Components[c] != 0);
203          assume(c == 0 || sc != 0);
204          p->exp[o->data.syzcomp.place]=sc;
205          break;
206        }
207        default:
208          Print("wrong ord in rSetm:%d\n",o->ord_typ);
209          return;
210      }
211      pos++;
212      if(pos==currRing->OrdSize) return;
213    }
214  }
215}
216
217/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
218
219
220#define NonZeroR(l, actionG, actionS)           \
221do                                              \
222{                                               \
223  long _l = l;                                  \
224  if (_l)                                       \
225  {                                             \
226    if (_l > 0) actionG;                        \
227    actionS;                                    \
228  }                                             \
229}                                               \
230while(0)
231
232#define Mreturn(d, multiplier)                      \
233{                                                   \
234  if (d > 0) return multiplier;                     \
235  return -multiplier;                               \
236}
237
238
239
240
241/*----------pComp handling for syzygies---------------------*/
242static void newHeadsB(polyset actHeads,int length)
243{
244  int i;
245  int* newOrder=(int*)omAlloc(length*sizeof(int));
246
247  for (i=0;i<length;i++)
248  {
249    if (actHeads[i]!=NULL)
250    {
251      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
252    }
253    else
254    {
255      newOrder[i]=0;
256    }
257  }
258  omFreeSize((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
259  SchreyerOrd = newOrder;
260  maxSchreyer = length;
261/*
262*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
263*PrintLn();
264*/
265}
266
267int mcompSchrB(poly p1,poly p2)
268{
269  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
270      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
271
272  //if (CompP1==CompP2) return pCompOld(p1,p2);
273  if (CompP1==CompP2) return pLmCmp(p1,p2);
274  pSetComp(p1,cP1);
275  pSetComp(p2,cP2);
276  //result = pCompOld(p1,p2);
277  result = pLmCmp(p1,p2);
278  pSetComp(p1,CompP1);
279  pSetComp(p2,CompP2);
280  if (!result)
281  {
282    if (CompP1>CompP2)
283      return -1;
284    else if (CompP1<CompP2)
285      return 1;
286  }
287  return result;
288}
289
290
291static void newHeadsM(polyset actHeads,int length)
292{
293  int i;
294  int* newOrder=
295    (int*)omAlloc0((length+maxSchreyer-indexShift)*sizeof(int));
296
297  //for (i=0;i<length+maxSchreyer-indexShift;i++)
298  //  newOrder[i]=0;
299  for (i=indexShift;i<maxSchreyer;i++)
300  {
301    newOrder[i-indexShift] = SchreyerOrd[i];
302    SchreyerOrd[i] = 0;
303  }
304  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
305    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
306  omFreeSize((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
307  SchreyerOrd = newOrder;
308  indexShift = maxSchreyer-indexShift;
309  maxSchreyer = length+indexShift;
310}
311
312/*2
313* compute the length of a polynomial (in l)
314* and the degree of the monomial with maximal degree:
315* this is NOT the last one and the module component
316* has to be <= indexShift
317*/
318static int ldegSchrM(poly p,int *l)
319{
320  int  t,max;
321
322  (*l)=1;
323  max=pFDeg(p);
324  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
325  {
326    pIter(p);
327    t=pFDeg(p);
328    if (t>max) max=t;
329    (*l)++;
330  }
331  return max;
332}
333
334int mcompSchrM(poly p1,poly p2)
335{
336  if ( pGetComp(p1)<=indexShift)
337  {
338    if ( pGetComp(p2)>indexShift) return 1;
339  }
340  else if ( pGetComp(p2)<=indexShift)  return -1;
341  return mcompSchrB(p1,p2);
342}
343
344void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
345{
346  int i;
347
348  if (length!=0)
349  {
350    if (maxSchreyer!=0)
351      newHeadsM(nextOrder, length);
352    else
353    {
354      indexShift = comps;
355      if (indexShift==0) indexShift = 1;
356      SchreyerOrd = (int*)omAlloc((indexShift+length)*sizeof(int));
357      maxSchreyer = length+indexShift;
358      for (i=0;i<indexShift;i++)
359        SchreyerOrd[i] = i;
360      for (i=indexShift;i<maxSchreyer;i++)
361        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
362      //pCompOld = pLmCmp;
363      //pLmCmp = mcompSchrM;
364      pLDegOld = pLDeg;
365      pLDeg = ldegSchrM;
366    }
367  }
368  else
369  {
370    if (maxSchreyer!=0)
371    {
372      omFreeSize((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
373      maxSchreyer = 0;
374      indexShift = 0;
375      //pLmCmp = pCompOld;
376      pLDeg = pLDegOld;
377    }
378  }
379}
380
381/*2
382* the type of the module ordering: C: -1, c: 1
383*/
384int pModuleOrder()
385{
386  return pComponentOrder;
387}
388
389/* -------------------------------------------------------------------*/
390/* several possibilities for pFDeg: the degree of the head term       */
391/*2
392* compute the degree of the leading monomial of p
393* the ordering is compatible with degree, use a->order
394*/
395int pDeg(poly a)
396{
397  return pGetOrder(a);
398}
399
400/*2
401* compute the degree of the leading monomial of p
402* with respect to weigths 1
403* (all are 1 so save multiplications or they are of different signs)
404* the ordering is not compatible with degree so do not use p->Order
405*/
406int pTotaldegree(poly p)
407{
408  return (int) pExpVectorQuerSum(p);
409}
410
411/*2
412* compute the degree of the leading monomial of p
413* with respect to weigths from the ordering
414* the ordering is not compatible with degree so do not use p->Order
415*/
416int pWTotaldegree(poly p)
417{
418  assume(p != NULL);
419  int i, k;
420  int j =0;
421
422  // iterate through each block:
423  for (i=0;order[i]!=0;i++)
424  {
425    switch(order[i])
426    {
427      case ringorder_wp:
428      case ringorder_ws:
429      case ringorder_Wp:
430      case ringorder_Ws:
431        for (k=block0[i];k<=block1[i];k++)
432        { // in jedem block:
433          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
434        }
435        break;
436      case ringorder_M:
437      case ringorder_lp:
438      case ringorder_dp:
439      case ringorder_ds:
440      case ringorder_Dp:
441      case ringorder_Ds:
442        for (k=block0[i];k<=block1[i];k++)
443        {
444          j+= pGetExp(p,k);
445        }
446        break;
447      case ringorder_c:
448      case ringorder_C:
449      case ringorder_S:
450      case ringorder_s:
451        break;
452      case ringorder_a:
453        for (k=block0[i];k<=block1[i];k++)
454        { // only one line
455          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
456        }
457        return j;
458    }
459  }
460  return  j;
461}
462int pWDegree(poly p)
463{
464  int i, k;
465  int j =0;
466
467  for(i=1;i<=pVariables;i++)
468    j+=pGetExp(p,i)*pWeight(i);
469  return j;
470}
471
472/* ---------------------------------------------------------------------*/
473/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
474/*  compute in l also the pLength of p                                   */
475
476/*2
477* compute the length of a polynomial (in l)
478* and the degree of the monomial with maximal degree: the last one
479*/
480static int ldeg0(poly p,int *l)
481{
482  Exponent_t k= pGetComp(p);
483  int ll=1;
484
485  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
486  {
487    pIter(p);
488    ll++;
489  }
490  *l=ll;
491  return pGetOrder(p);
492}
493
494/*2
495* compute the length of a polynomial (in l)
496* and the degree of the monomial with maximal degree: the last one
497* but search in all components before syzcomp
498*/
499static int ldeg0c(poly p,int *l)
500{
501  int o=pFDeg(p);
502  int ll=1;
503
504  if (! rIsSyzIndexRing(currRing))
505  {
506    while ((p=pNext(p))!=NULL)
507    {
508      o=pFDeg(p);
509      ll++;
510    }
511  }
512  else
513  {
514    int curr_limit = rGetCurrSyzLimit();
515    while ((p=pNext(p))!=NULL)
516    {
517      if (pGetComp(p)<=curr_limit/*syzComp*/)
518      {
519        o=pFDeg(p);
520        ll++;
521      }
522      else break;
523    }
524  }
525  *l=ll;
526  return o;
527}
528
529/*2
530* compute the length of a polynomial (in l)
531* and the degree of the monomial with maximal degree: the first one
532* this works for the polynomial case with degree orderings
533* (both c,dp and dp,c)
534*/
535static int ldegb(poly p,int *l)
536{
537  Exponent_t k= pGetComp(p);
538  int o = pFDeg(p);
539  int ll=1;
540
541  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
542  {
543    ll++;
544  }
545  *l=ll;
546  return o;
547}
548
549/*2
550* compute the length of a polynomial (in l)
551* and the degree of the monomial with maximal degree:
552* this is NOT the last one, we have to look for it
553*/
554static int ldeg1(poly p,int *l)
555{
556  Exponent_t k= pGetComp(p);
557  int ll=1;
558  int  t,max;
559
560  max=pFDeg(p);
561  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
562  {
563    t=pFDeg(p);
564    if (t>max) max=t;
565    ll++;
566  }
567  *l=ll;
568  return max;
569}
570
571/*2
572* compute the length of a polynomial (in l)
573* and the degree of the monomial with maximal degree:
574* this is NOT the last one, we have to look for it
575* in all components
576*/
577static int ldeg1c(poly p,int *l)
578{
579  int ll=1;
580  int  t,max;
581
582  max=pFDeg(p);
583  while ((p=pNext(p))!=NULL)
584  {
585    if (! rIsSyzIndexRing(currRing) ||
586        (pGetComp(p)<=rGetCurrSyzLimit()))
587    {
588       if ((t=pFDeg(p))>max) max=t;
589       ll++;
590    }
591    else break;
592  }
593  *l=ll;
594  return max;
595}
596
597/* -------------------------------------------------------- */
598/* set the variables for a choosen ordering                 */
599
600
601/*2
602* sets the comparision routine for monomials: for all but the first
603* block of variables (ip is the block number, o_r the number of the ordering)
604*/
605static void HighSet(int ip, int o_r)
606{
607  switch(o_r)
608  {
609    case ringorder_lp:
610    case ringorder_dp:
611    case ringorder_Dp:
612    case ringorder_wp:
613    case ringorder_Wp:
614    case ringorder_a:
615      if (pOrdSgn==-1) pMixedOrder=TRUE;
616      break;
617    case ringorder_ls:
618    case ringorder_ds:
619    case ringorder_Ds:
620    case ringorder_ws:
621    case ringorder_Ws:
622    case ringorder_s:
623      break;
624    case ringorder_c:
625      pComponentOrder=1;
626      break;
627    case ringorder_C:
628    case ringorder_S:
629      pComponentOrder=-1;
630      break;
631    case ringorder_M:
632      pMixedOrder=TRUE;
633      break;
634#ifdef TEST
635    default:
636      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
637#endif
638  }
639}
640
641/* -------------------------------------------------------- */
642/*2
643* change all variables to fit the description of the new ring
644*/
645
646//void pChangeRing(ring newRing)
647//{
648//  rComplete(newRing);
649//  pSetGlobals(newRing);
650//}
651
652void pSetGlobals(ring r, BOOLEAN complete)
653{
654  int i;
655  pComponentOrder=1;
656  if (ppNoether!=NULL) pDelete(&ppNoether);
657  pVariables = r->N;
658
659  // set the various size parameters and initialize memory
660  pMonomSize = POLYSIZE + r->ExpLSize * sizeof(long);
661  pMonomSizeW = pMonomSize/sizeof(void*);
662
663  // Initialize memory management
664  currPolyBin = r->PolyBin;
665
666  pVarOffset = r->VarOffset;
667
668  pOrdSgn = r->OrdSgn;
669  pVectorOut=(r->order[0]==ringorder_c);
670  order=r->order;
671  block0=r->block0;
672  block1=r->block1;
673  firstwv=NULL;
674  polys_wv=r->wvhdl;
675  if (order[0]==ringorder_S ||order[0]==ringorder_s)
676  {
677    order++;
678    block0++;
679    block1++;
680    polys_wv++;
681  }
682  pFDeg=pTotaldegree;
683  /*------- only one real block ----------------------*/
684  pLexOrder=FALSE;
685  pMixedOrder=FALSE;
686  if (pOrdSgn == 1) pLDeg = ldegb;
687  else              pLDeg = ldeg0;
688  /*======== ordering type is (_,c) =========================*/
689  if ((order[0]==ringorder_unspec)
690      ||(
691    ((order[1]==ringorder_c)||(order[1]==ringorder_C)
692     ||(order[1]==ringorder_S)
693     ||(order[1]==ringorder_s))
694    && (order[0]!=ringorder_M)
695    && (order[2]==0))
696    )
697  {
698    if ((order[0]!=ringorder_unspec)
699    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)||
700        (order[1]==ringorder_s)))
701      pComponentOrder=-1;
702    if (pOrdSgn == -1) pLDeg = ldeg0c;
703    if ((order[0] == ringorder_lp) || (order[0] == ringorder_ls))
704    {
705      pLexOrder=TRUE;
706      pLDeg = ldeg1c;
707    }
708    if (order[0] == ringorder_wp || order[0] == ringorder_Wp ||
709        order[0] == ringorder_ws || order[0] == ringorder_Ws)
710      pFDeg = pWTotaldegree;
711    firstBlockEnds=block1[0];
712  }
713  /*======== ordering type is (c,_) =========================*/
714  else if (((order[0]==ringorder_c)
715            ||(order[0]==ringorder_C)
716            ||(order[0]==ringorder_S)
717            ||(order[0]==ringorder_s))
718  && (order[1]!=ringorder_M)
719  &&  (order[2]==0))
720  {
721    /* pLDeg = ldeg0; is standard*/
722    if ((order[0]==ringorder_C)||(order[0]==ringorder_S)||
723        order[0]==ringorder_s)
724      pComponentOrder=-1;
725    if ((order[1] == ringorder_lp) || (order[1] == ringorder_ls))
726    {
727      pLexOrder=TRUE;
728      pLDeg = ldeg1c;
729    }
730    firstBlockEnds=block1[1];
731    if (order[1] == ringorder_wp || order[1] == ringorder_Wp ||
732        order[1] == ringorder_ws || order[1] == ringorder_Ws)
733      pFDeg = pWTotaldegree;
734  }
735  /*------- more than one block ----------------------*/
736  else
737  {
738    //pGetVarIndicies(pVariables, pVarOffset, pVarCompIndex, pVarLowIndex,
739    //                pVarHighIndex);
740    //pLexOrder=TRUE;
741    pVectorOut=order[0]==ringorder_c;
742    if ((pVectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
743    {
744      if(block1[1]!=pVariables) pLexOrder=TRUE;
745      firstBlockEnds=block1[1];
746    }
747    else
748    {
749      if(block1[0]!=pVariables) pLexOrder=TRUE;
750      firstBlockEnds=block1[0];
751    }
752    /*the number of orderings:*/
753    i = 0;
754    while (order[++i] != 0);
755    do
756    {
757      i--;
758      HighSet(i, order[i]);/*sets also pMixedOrder to TRUE, if...*/
759    }
760    while (i != 0);
761
762    if ((order[0]!=ringorder_c)
763        && (order[0]!=ringorder_C)
764        && (order[0]!=ringorder_S)
765        && (order[0]!=ringorder_s))
766    {
767      pLDeg = ldeg1c;
768    }
769    else
770    {
771      pLDeg = ldeg1;
772    }
773    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
774  }
775  if (complete)
776  {
777    if ((pLexOrder) || (pOrdSgn==-1))
778    {
779      test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
780    }
781  }
782  if (pFDeg!=pWTotaldegree) pFDeg=pTotaldegree;
783}
784
785
786/*2
787* assumes that the head term of b is a multiple of the head term of a
788* and return the multiplicant *m
789*/
790poly pDivide(poly a, poly b)
791{
792  int i;
793  poly result = pInit();
794
795  for(i=(int)pVariables; i; i--)
796    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
797  pSetComp(result, pGetComp(a) - pGetComp(b));
798  pSetm(result);
799  return result;
800}
801
802/*2
803* divides a by the monomial b, ignores monomials wihich are not divisible
804* assumes that b is not NULL
805*/
806poly pDivideM(poly a, poly b)
807{
808  if (a==NULL) return NULL;
809  poly result=a;
810  poly prev=NULL;
811  int i;
812  number inv=nInvers(pGetCoeff(b));
813
814  while (a!=NULL)
815  {
816    if (pDivisibleBy(b,a))
817    {
818      for(i=(int)pVariables; i; i--)
819         pSubExp(a,i, pGetExp(b,i));
820      pSubComp(a, pGetComp(b));
821      pSetm(a);
822      prev=a;
823      pIter(a);
824    }
825    else
826    {
827      if (prev==NULL)
828      {
829        pDeleteLm(&result);
830        a=result;
831      }
832      else
833      {
834        pDeleteLm(&pNext(prev));
835        a=pNext(prev);
836      }
837    }
838  }
839  pMult_nn(result,inv);
840  nDelete(&inv);
841  pDelete(&b);
842  return result;
843}
844
845/*2
846* returns the LCM of the head terms of a and b in *m
847*/
848void pLcm(poly a, poly b, poly m)
849{
850  int i;
851  for (i=pVariables; i; i--)
852  {
853    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
854  }
855  pSetComp(m, max(pGetComp(a), pGetComp(b)));
856  /* Don't do a pSetm here, otherwise hres/lres chockes */
857}
858
859/*2
860* convert monomial given as string to poly, e.g. 1x3y5z
861*/
862poly pmInit(char *st, BOOLEAN &ok)
863{
864  int i,j;
865  ok=FALSE;
866  BOOLEAN b=FALSE;
867  poly rc = pInit();
868  char *s = nRead(st,&(rc->coef));
869  if (s==st)
870  /* i.e. it does not start with a coeff: test if it is a ringvar*/
871  {
872    j = rIsRingVar(s);
873    if (j >= 0)
874    {
875      pIncrExp(rc,1+j);
876      goto done;
877    }
878  }
879  else
880    b=TRUE;
881  while (*s!='\0')
882  {
883    char ss[2];
884    ss[0] = *s++;
885    ss[1] = '\0';
886    j = rIsRingVar(ss);
887    if (j >= 0)
888    {
889      s = eati(s,&i);
890      pAddExp(rc,1+j, (Exponent_t)i);
891    }
892    else
893    {
894      if ((s!=st)&&isdigit(st[0]))
895      {
896        errorreported=TRUE;
897      }
898      pDelete(&rc);
899      return NULL;
900    }
901  }
902done:
903  ok=!errorreported;
904  if (nIsZero(pGetCoeff(rc))) pDeleteLm(&rc);
905  else
906  {
907    pSetm(rc);
908  }
909  return rc;
910}
911
912/*2
913*make p homgeneous by multiplying the monomials by powers of x_varnum
914*/
915poly pHomogen (poly p, int varnum)
916{
917  poly q=NULL;
918  poly res;
919  int  o,ii;
920
921  if (p!=NULL)
922  {
923    if ((varnum < 1) || (varnum > pVariables))
924    {
925      return NULL;
926    }
927    o=pWTotaldegree(p);
928    q=pNext(p);
929    while (q != NULL)
930    {
931      ii=pWTotaldegree(q);
932      if (ii>o) o=ii;
933      pIter(q);
934    }
935    q = pCopy(p);
936    res = q;
937    while (q != NULL)
938    {
939      ii = o-pWTotaldegree(q);
940      if (ii!=0)
941      {
942        pAddExp(q,varnum, (Exponent_t)ii);
943        pSetm(q);
944      }
945      pIter(q);
946    }
947    q = pOrdPolyInsertSetm(res);
948  }
949  return q;
950}
951
952
953/*2
954*replaces the maximal powers of the leading monomial of p2 in p1 by
955*the same powers of n, utility for dehomogenization
956*/
957poly pDehomogen (poly p1,poly p2,number n)
958{
959  polyset P;
960  int     SizeOfSet=5;
961  int     i;
962  poly    p;
963  number  nn;
964
965  P = (polyset)omAlloc0(5*sizeof(poly));
966  //for (i=0; i<5; i++)
967  //{
968  //  P[i] = NULL;
969  //}
970  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
971  p = P[0];
972  //P[0] = NULL ;// for safety, may be remoeved later
973  for (i=1; i<SizeOfSet; i++)
974  {
975    if (P[i] != NULL)
976    {
977      nPower(n,i,&nn);
978      pMult_nn(P[i],nn);
979      p = pAdd(p,P[i]);
980      //P[i] =NULL; // for safety, may be removed later
981      nDelete(&nn);
982    }
983  }
984  omFreeSize((ADDRESS)P,SizeOfSet*sizeof(poly));
985  return p;
986}
987
988/*4
989*Returns the exponent of the maximal power of the leading monomial of
990*p2 in that of p1
991*/
992static int pGetMaxPower (poly p1,poly p2)
993{
994  int     i,k,res = 32000; /*a very large integer*/
995
996  if (p1 == NULL) return 0;
997  for (i=1; i<=pVariables; i++)
998  {
999    if ( pGetExp(p2,i) != 0)
1000    {
1001      k =  pGetExp(p1,i) /  pGetExp(p2,i);
1002      if (k < res) res = k;
1003    }
1004  }
1005  return res;
1006}
1007
1008/*2
1009*Returns as i-th entry of P the coefficient of the (i-1) power of
1010*the leading monomial of p2 in p1
1011*/
1012void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
1013{
1014  int   maxPow;
1015  poly  p,qp,Coeff;
1016
1017  if (*P == NULL)
1018  {
1019    *P = (polyset) omAlloc(5*sizeof(poly));
1020    *SizeOfSet = 5;
1021  }
1022  p = pCopy(p1);
1023  while (p != NULL)
1024  {
1025    qp = p->next;
1026    p->next = NULL;
1027    maxPow = pGetMaxPower(p,p2);
1028    Coeff = pDivByMonom(p,p2);
1029    if (maxPow > *SizeOfSet)
1030    {
1031      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
1032      *SizeOfSet = maxPow+1;
1033    }
1034    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
1035    pDelete(&p);
1036    p = qp;
1037  }
1038}
1039
1040/*2
1041*returns the leading monomial of p1 divided by the maximal power of that
1042*of p2
1043*/
1044poly pDivByMonom (poly p1,poly p2)
1045{
1046  int     k, i;
1047
1048  if (p1 == NULL) return NULL;
1049  k = pGetMaxPower(p1,p2);
1050  if (k == 0)
1051    return pHead(p1);
1052  else
1053  {
1054    number n;
1055    poly p = pInit();
1056
1057    p->next = NULL;
1058    for (i=1; i<=pVariables; i++)
1059    {
1060       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
1061    }
1062    nPower(p2->coef,k,&n);
1063    pSetCoeff0(p,nDiv(p1->coef,n));
1064    nDelete(&n);
1065    pSetm(p);
1066    return p;
1067  }
1068}
1069/*----------utilities for syzygies--------------*/
1070poly pTakeOutComp(poly * p, int k)
1071{
1072  poly q = *p,qq=NULL,result = NULL;
1073
1074  if (q==NULL) return NULL;
1075  if (pGetComp(q)==k)
1076  {
1077    result = q;
1078    while ((q!=NULL) && (pGetComp(q)==k))
1079    {
1080      pSetComp(q,0);
1081      pSetmComp(q);
1082      qq = q;
1083      pIter(q);
1084    }
1085    *p = q;
1086    pNext(qq) = NULL;
1087  }
1088  if (q==NULL) return result;
1089  if (pGetComp(q) > k)
1090  {
1091    pDecrComp(q);
1092    pSetmComp(q);
1093  }
1094  poly pNext_q;
1095  while ((pNext_q=pNext(q))!=NULL)
1096  {
1097    if (pGetComp(pNext_q)==k)
1098    {
1099      if (result==NULL)
1100      {
1101        result = pNext_q;
1102        qq = result;
1103      }
1104      else
1105      {
1106        pNext(qq) = pNext_q;
1107        pIter(qq);
1108      }
1109      pNext(q) = pNext(pNext_q);
1110      pNext(qq) =NULL;
1111      pSetComp(qq,0);
1112      pSetmComp(qq);
1113    }
1114    else
1115    {
1116      /*pIter(q);*/ q=pNext_q;
1117      if (pGetComp(q) > k)
1118      {
1119        pDecrComp(q);
1120        pSetmComp(q);
1121      }
1122    }
1123  }
1124  return result;
1125}
1126
1127// Splits *p into two polys: *q which consists of all monoms with
1128// component == comp and *p of all other monoms *lq == pLength(*q)
1129void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
1130{
1131  spolyrec pp, qq;
1132  poly p, q, p_prev;
1133  int l = 0;
1134
1135#ifdef HAVE_ASSUME
1136  int lp = pLength(*r_p);
1137#endif
1138
1139  pNext(&pp) = *r_p;
1140  p = *r_p;
1141  p_prev = &pp;
1142  q = &qq;
1143
1144  while(p != NULL)
1145  {
1146    while (pGetComp(p) == comp)
1147    {
1148      pNext(q) = p;
1149      pIter(q);
1150      pSetComp(p, 0);
1151      pSetmComp(p);
1152      pIter(p);
1153      l++;
1154      if (p == NULL)
1155      {
1156        pNext(p_prev) = NULL;
1157        goto Finish;
1158      }
1159    }
1160    pNext(p_prev) = p;
1161    p_prev = p;
1162    pIter(p);
1163  }
1164
1165  Finish:
1166  pNext(q) = NULL;
1167  *r_p = pNext(&pp);
1168  *r_q = pNext(&qq);
1169  *lq = l;
1170#ifdef HAVE_ASSUME
1171  assume(pLength(*r_p) + pLength(*r_q) == lp);
1172#endif
1173  pTest(*r_p);
1174  pTest(*r_q);
1175}
1176
1177void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
1178                         poly *r_q, int *lq)
1179{
1180  spolyrec pp, qq;
1181  poly p, q, p_prev;
1182  int l = 0;
1183
1184  pNext(&pp) = *r_p;
1185  p = *r_p;
1186  p_prev = &pp;
1187  q = &qq;
1188
1189#ifdef HAVE_ASSUME
1190  if (p != NULL)
1191  {
1192    while (pNext(p) != NULL)
1193    {
1194      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
1195      pIter(p);
1196    }
1197  }
1198  p = *r_p;
1199#endif
1200
1201  while (p != NULL && pGetOrder(p) > order) pIter(p);
1202
1203  while(p != NULL && pGetOrder(p) == order)
1204  {
1205    while (pGetComp(p) == comp)
1206    {
1207      pNext(q) = p;
1208      pIter(q);
1209      pIter(p);
1210      pSetComp(p, 0);
1211      pSetmComp(p);
1212      l++;
1213      if (p == NULL || pGetOrder(p) != order)
1214      {
1215        pNext(p_prev) = p;
1216        goto Finish;
1217      }
1218    }
1219    pNext(p_prev) = p;
1220    p_prev = p;
1221    pIter(p);
1222  }
1223
1224  Finish:
1225  pNext(q) = NULL;
1226  *r_p = pNext(&pp);
1227  *r_q = pNext(&qq);
1228  *lq = l;
1229}
1230
1231#if 1
1232poly pTakeOutComp1(poly * p, int k)
1233{
1234  poly q = *p;
1235
1236  if (q==NULL) return NULL;
1237
1238  poly qq=NULL,result = NULL;
1239
1240  if (pGetComp(q)==k)
1241  {
1242    result = q; /* *p */
1243    while ((q!=NULL) && (pGetComp(q)==k))
1244    {
1245      pSetComp(q,0);
1246      pSetmComp(q);
1247      qq = q;
1248      pIter(q);
1249    }
1250    *p = q;
1251    pNext(qq) = NULL;
1252  }
1253  if (q==NULL) return result;
1254//  if (pGetComp(q) > k) pGetComp(q)--;
1255  while (pNext(q)!=NULL)
1256  {
1257    if (pGetComp(pNext(q))==k)
1258    {
1259      if (result==NULL)
1260      {
1261        result = pNext(q);
1262        qq = result;
1263      }
1264      else
1265      {
1266        pNext(qq) = pNext(q);
1267        pIter(qq);
1268      }
1269      pNext(q) = pNext(pNext(q));
1270      pNext(qq) =NULL;
1271      pSetComp(qq,0);
1272      pSetmComp(qq);
1273    }
1274    else
1275    {
1276      pIter(q);
1277//      if (pGetComp(q) > k) pGetComp(q)--;
1278    }
1279  }
1280  return result;
1281}
1282#endif
1283
1284void pDeleteComp(poly * p,int k)
1285{
1286  poly q;
1287
1288  while ((*p!=NULL) && (pGetComp(*p)==k)) pDeleteLm(p);
1289  if (*p==NULL) return;
1290  q = *p;
1291  if (pGetComp(q)>k)
1292  {
1293    pDecrComp(q);
1294    pSetmComp(q);
1295  }
1296  while (pNext(q)!=NULL)
1297  {
1298    if (pGetComp(pNext(q))==k)
1299      pDeleteLm(&(pNext(q)));
1300    else
1301    {
1302      pIter(q);
1303      if (pGetComp(q)>k)
1304      {
1305        pDecrComp(q);
1306        pSetmComp(q);
1307      }
1308    }
1309  }
1310}
1311/*----------end of utilities for syzygies--------------*/
1312
1313/*2
1314* pair has no common factor ? or is no polynomial
1315*/
1316BOOLEAN pHasNotCF(poly p1, poly p2)
1317{
1318
1319  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
1320    return FALSE;
1321  int i = 1;
1322  loop
1323  {
1324    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
1325    if (i == pVariables)                                return TRUE;
1326    i++;
1327  }
1328}
1329
1330
1331/*2
1332*divides p1 by its leading monomial
1333*/
1334void pNorm(poly p1)
1335{
1336  poly h;
1337  number k, c;
1338
1339  if (p1!=NULL)
1340  {
1341    if (!nIsOne(pGetCoeff(p1)))
1342    {
1343      nNormalize(pGetCoeff(p1));
1344      k=pGetCoeff(p1);
1345      c = nInit(1);
1346      pSetCoeff0(p1,c);
1347      h = pNext(p1);
1348      while (h!=NULL)
1349      {
1350        c=nDiv(pGetCoeff(h),k);
1351        if (!nIsOne(c)) nNormalize(c);
1352        pSetCoeff(h,c);
1353        pIter(h);
1354      }
1355      nDelete(&k);
1356    }
1357    else
1358    {
1359      h = pNext(p1);
1360      while (h!=NULL)
1361      {
1362        nNormalize(pGetCoeff(h));
1363        pIter(h);
1364      }
1365    }
1366  }
1367}
1368
1369/*2
1370*normalize all coeffizients
1371*/
1372void pNormalize(poly p)
1373{
1374  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
1375  while (p!=NULL)
1376  {
1377    nTest(pGetCoeff(p));
1378    nNormalize(pGetCoeff(p));
1379    pIter(p);
1380  }
1381}
1382
1383// splits p into polys with Exp(n) == 0 and Exp(n) != 0
1384// Poly with Exp(n) != 0 is reversed
1385static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
1386{
1387  if (p == NULL)
1388  {
1389    *non_zero = NULL;
1390    *zero = NULL;
1391    return;
1392  }
1393  spolyrec sz;
1394  poly z, n_z, next;
1395  z = &sz;
1396  n_z = NULL;
1397
1398  while(p != NULL)
1399  {
1400    next = pNext(p);
1401    if (pGetExp(p, n) == 0)
1402    {
1403      pNext(z) = p;
1404      pIter(z);
1405    }
1406    else
1407    {
1408      pNext(p) = n_z;
1409      n_z = p;
1410    }
1411    p = next;
1412  }
1413  pNext(z) = NULL;
1414  *zero = pNext(&sz);
1415  *non_zero = n_z;
1416  return;
1417}
1418
1419/*3
1420* substitute the n-th variable by 1 in p
1421* destroy p
1422*/
1423static poly pSubst1 (poly p,int n)
1424{
1425  poly qq,result = NULL;
1426  poly zero, non_zero;
1427
1428  // reverse, so that add is likely to be linear
1429  pSplitAndReversePoly(p, n, &non_zero, &zero);
1430
1431  while (non_zero != NULL)
1432  {
1433    assume(pGetExp(non_zero, n) != 0);
1434    qq = non_zero;
1435    pIter(non_zero);
1436    qq->next = NULL;
1437    pSetExp(qq,n,0);
1438    pSetm(qq);
1439    result = pAdd(result,qq);
1440  }
1441  p = pAdd(result, zero);
1442  pTest(p);
1443  return p;
1444}
1445
1446/*3
1447* substitute the n-th variable by number e in p
1448* destroy p
1449*/
1450static poly pSubst2 (poly p,int n, number e)
1451{
1452  assume( ! nIsZero(e) );
1453  poly qq,result = NULL;
1454  number nn, nm;
1455  poly zero, non_zero;
1456
1457  // reverse, so that add is likely to be linear
1458  pSplitAndReversePoly(p, n, &non_zero, &zero);
1459
1460  while (non_zero != NULL)
1461  {
1462    assume(pGetExp(non_zero, n) != 0);
1463    qq = non_zero;
1464    pIter(non_zero);
1465    qq->next = NULL;
1466    nPower(e, pGetExp(qq, n), &nn);
1467    nm = nMult(nn, pGetCoeff(qq));
1468    pSetCoeff(qq, nm);
1469    nDelete(&nn);
1470    pSetExp(qq, n, 0);
1471    pSetm(qq);
1472    result = pAdd(result,qq);
1473  }
1474  p = pAdd(result, zero);
1475  pTest(p);
1476  return p;
1477}
1478
1479
1480/* delete monoms whose n-th exponent is different from zero */
1481poly pSubst0(poly p, int n)
1482{
1483  spolyrec res;
1484  poly h = &res;
1485  pNext(h) = p;
1486
1487  while (pNext(h)!=NULL)
1488  {
1489    if (pGetExp(pNext(h),n)!=0)
1490    {
1491      pDeleteLm(&pNext(h));
1492    }
1493    else
1494    {
1495      pIter(h);
1496    }
1497  }
1498  pTest(pNext(&res));
1499  return pNext(&res);
1500}
1501
1502/*2
1503* substitute the n-th variable by e in p
1504* destroy p
1505*/
1506poly pSubst(poly p, int n, poly e)
1507{
1508  if (e == NULL) return pSubst0(p, n);
1509
1510  if (pIsConstant(e))
1511  {
1512    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
1513    else return pSubst2(p, n, pGetCoeff(e));
1514  }
1515
1516  int exponent,i;
1517  poly h, res, m;
1518  Exponent_t *me,*ee;
1519  number nu,nu1;
1520
1521  me=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
1522  ee=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
1523  if (e!=NULL) pGetExpV(e,ee);
1524  res=NULL;
1525  h=p;
1526  while (h!=NULL)
1527  {
1528    if ((e!=NULL) || (pGetExp(h,n)==0))
1529    {
1530      m=pHead(h);
1531      pGetExpV(m,me);
1532      exponent=me[n];
1533      me[n]=0;
1534      for(i=pVariables;i>0;i--)
1535        me[i]+=exponent*ee[i];
1536      pSetExpV(m,me);
1537      if (e!=NULL)
1538      {
1539        nPower(pGetCoeff(e),exponent,&nu);
1540        nu1=nMult(pGetCoeff(m),nu);
1541        nDelete(&nu);
1542        pSetCoeff(m,nu1);
1543      }
1544      res=pAdd(res,m);
1545    }
1546    pDeleteLm(&h);
1547  }
1548  omFreeSize((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
1549  omFreeSize((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
1550  return res;
1551}
1552
1553BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
1554{
1555  int k, j;
1556
1557  if (lcm==NULL) return FALSE;
1558
1559  for (j=pVariables; j; j--)
1560    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
1561  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
1562  for (j=pVariables; j; j--)
1563  {
1564    if (pGetExp(p1,j)!=pGetExp(lcm,j))
1565    {
1566      if (pGetExp(p,j)!=pGetExp(lcm,j))
1567      {
1568        for (k=pVariables; k>j; k--)
1569        {
1570          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1571          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
1572            return TRUE;
1573        }
1574        for (k=j-1; k; k--)
1575        {
1576          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1577          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
1578            return TRUE;
1579        }
1580        return FALSE;
1581      }
1582    }
1583    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
1584    {
1585      if (pGetExp(p,j)!=pGetExp(lcm,j))
1586      {
1587        for (k=pVariables; k>j; k--)
1588        {
1589          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1590          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
1591            return TRUE;
1592        }
1593        for (k=j-1; k!=0 ; k--)
1594        {
1595          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1596          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
1597            return TRUE;
1598        }
1599        return FALSE;
1600      }
1601    }
1602  }
1603  return FALSE;
1604}
1605
1606int pWeight(int i)
1607{
1608  if ((firstwv==NULL) || (i>firstBlockEnds))
1609  {
1610    return 1;
1611  }
1612  return firstwv[i-1];
1613}
1614
Note: See TracBrowser for help on using the repository browser.