source: git/Singular/polys.cc @ 6959c4

fieker-DuValspielwiese
Last change on this file since 6959c4 was 8c8bea, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* preparation for buckets git-svn-id: file:///usr/local/Singular/svn/trunk@3063 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys.cc,v 1.39 1999-05-26 16:23:59 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 "mmemory.h"
17#include "febase.h"
18#include "numbers.h"
19#include "polys.h"
20#include "ring.h"
21#include "binom.h"
22#include "ipid.h"
23#include "polys-comp.h"
24
25/* ----------- global variables, set by pChangeRing --------------------- */
26/* initializes the internal data from the exp vector */
27pSetmProc pSetm;
28/* computes length and maximal degree of a POLYnomial */
29pLDegProc pLDeg;
30/* computes the degree of the initial term, used for std */
31pFDegProc pFDeg;
32/* the monomial ordering of the head monomials a and b */
33/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
34pCompProc pComp0;
35
36int pVariables;     // number of variables
37int pVariablesW;    // number of words of pVariables exponents
38int pVariables1W;   // number of words of (pVariables+1) exponents
39int pMonomSize;     // size of monom (in bytes)
40int pMonomSizeW;    // size of monom (in words)
41int pLexSgn;        // 1, for lex monom comps; -1 otherwise (exception: ls)
42int *pVarOffset;     // controls the way exponents are stored in a vector
43int pVarLowIndex;   // lowest exponent index
44int pVarHighIndex;  // highest exponent index
45int pVarCompIndex;  // Location of component in exponent vector
46
47/* 1 for polynomial ring, -1 otherwise */
48int     pOrdSgn;
49/* TRUE for momomial output as x2y, FALSE for x^2*y */
50int pShortOut = (int)TRUE;
51// it is of type int, not BOOLEAN because it is also in ip
52/* TRUE if the monomial ordering is not compatible with pFDeg */
53BOOLEAN pLexOrder;
54/* TRUE if the monomial ordering has polynomial and power series blocks */
55BOOLEAN pMixedOrder;
56/* 1 for c ordering, -1 otherwise (i.e. for C ordering) */
57int  pComponentOrder;
58
59#ifdef DRING
60int      p2;
61BOOLEAN  pDRING=FALSE;
62#endif
63
64#ifdef SRING
65int      pAltVars;
66BOOLEAN  pSRING=FALSE;
67#endif
68
69#ifdef SDRING
70BOOLEAN  pSDRING=FALSE;
71#include "polys.inc"
72#endif
73
74/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
75/* the highest monomial below pHEdge */
76poly      ppNoether = NULL;
77
78/* -------------- static variables --------------------------------------- */
79/*is the basic comparing procedure during a computation of syzygies*/
80static pCompProc pCompOld;
81/*for grouping module indicies during computations*/
82int pMaxBound = 0;
83
84/*contains the headterms for the Schreyer orderings*/
85static int* SchreyerOrd;
86static int maxSchreyer=0;
87static int indexShift=0;
88static pLDegProc pLDegOld;
89
90typedef int (*bcompProc)(poly p1, poly p2, int i1, int i2, short * w);
91static bcompProc bcomph[20];
92static short**   polys_wv;
93static short *   firstwv;
94static int * block0;
95static int * block1;
96static int firstBlockEnds;
97static int * order;
98
99/*0 implementation*/
100/*-------- the several possibilities for pSetm:-----------------------*/
101
102/* Remark: These could be made more efficient by avoiding using pGetExp */
103
104/*2
105* define the order of p with respect to lex. ordering, N=1
106*/
107static void setlex1(poly p)
108{
109  p->Order = (Order_t)pGetExp(p,1);
110}
111
112/*2
113* define the order of p with respect to lex. ordering, N>1
114*/
115static void setlex2(poly p)
116{
117  p->Order = (((Order_t)pGetExp(p,1))<<(sizeof(Exponent_t)*8))
118    + (Order_t)pGetExp(p,2);
119}
120
121/*2
122* define the order of p with respect to a degree ordering
123*/
124static void setdeg1(poly p)
125{
126  p->Order = pExpQuerSum1(p, firstBlockEnds);
127}
128
129/*2
130* define the order of p with respect to a degree ordering
131* with weigthts
132*/
133static void setdeg1w(poly p)
134{
135  Order_t i, j = 0;
136
137  for (i = firstBlockEnds; i>0; i--)
138  {
139     j += ((Order_t) pGetExp(p,i))*firstwv[i-1];
140  }
141  p->Order = j;
142}
143
144
145/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
146
147
148#define NonZeroR(l, actionG, actionS)           \
149do                                              \
150{                                               \
151  long _l = l;                                  \
152  if (_l)                                       \
153  {                                             \
154    if (_l > 0) actionG;                        \
155    actionS;                                    \
156  }                                             \
157}                                               \
158while(0)
159
160#define Mreturn(d, multiplier)                      \
161{                                                   \
162  if (d > 0) return multiplier;                     \
163  return -multiplier;                               \
164}
165
166
167static int pComp_otEXP(poly p1, poly p2);
168static int pComp_otCOMPEXP(poly p1, poly p2);
169static int pComp_otEXPCOMP(poly p1, poly p2);
170
171static int pComp_otEXP(poly p1, poly p2)
172{
173  register long d = pGetOrder(p1) - pGetOrder(p2);
174  if (d) Mreturn(d, pOrdSgn);
175
176  _pMonComp_otEXP_nwGEN(p1, p2,  pVariables1W, d, goto NotEqual , return 0);
177
178  NotEqual:
179  Mreturn(d, pLexSgn);
180}
181
182static int pComp_otCOMPEXP(poly p1, poly p2)
183{
184  register long d = pGetComp(p2) - pGetComp(p1);
185  if (d) Mreturn(d, pComponentOrder);
186
187  d = pGetOrder(p1) - pGetOrder(p2);
188  if (d) Mreturn(d, pOrdSgn);
189
190  _pMonComp_otEXP_nwGEN(p1, p2,  pVariablesW, d, goto NotEqual , return 0);
191
192  NotEqual:
193  Mreturn(d, pLexSgn);
194}
195
196static int pComp_otEXPCOMP(poly p1, poly p2)
197{
198  register long d = pGetOrder(p1) - pGetOrder(p2);
199  if (d) Mreturn(d, pOrdSgn);
200
201  _pMonComp_otEXPCOMP_nwGEN(p1, p2,  pVariables1W, d, goto NotEqual , return 0);
202
203  NotEqual:
204  Mreturn(d, pLexSgn);
205}
206
207/*---------------------------------------------------*/
208
209/*2
210* compare the head monomial of p1 and p2 with weight vector
211*/
212static int comp1a  ( poly p1, poly p2, int f, int l, short * w )
213{
214  int d= pGetOrder(p1) - pGetOrder(p2);
215  if ( d > 0 /*p1->Order > p2->Order*/ )
216    return 1;
217  else if ( d < 0 /*p1->Order < p2->Order*/ )
218    return -1;
219  return 0;
220}
221
222
223/* These functions could be made faster if you use pointers to the
224* exponent vectors and pointer arithmetic instead of using the
225* macro pGetExp !!!
226*/
227
228/*2
229* compare the head monomial of p1 and p2 with lexicographic ordering
230*/
231static int comp_lp ( poly p1, poly p2, int f, int l, short * w )
232{
233  int i = f;
234  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
235    i++;
236  if ( i > l )
237    return 0;
238  if ( pGetExp(p1,i) > pGetExp(p2,i) )
239    return 1;
240  return -1;
241}
242
243/*2
244* compare the head monomial of p1 and p2 with degree reverse lexicographic
245* ordering
246*/
247static int comp_dp ( poly p1, poly p2, int f, int l, short * w )
248{
249  int i, s1 = 0, s2 = 0;
250
251  for ( i = f; i <= l; i++ )
252  {
253    s1 += pGetExp(p1,i);
254    s2 += pGetExp(p2,i);
255  }
256  if ( s1 == s2 )
257  {
258    i = l;
259    while ( (i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
260      i--;
261    if ( i < f )
262      return 0;
263    if ( pGetExp(p1,i) > pGetExp(p2,i) )
264      return -1;
265    return 1;
266  }
267  if ( s1 > s2 )
268    return 1;
269  return -1;
270}
271
272/*2
273* compare the head monomial of p1 and p2 with degree lexicographic ordering
274*/
275static int comp_Dp ( poly p1, poly p2, int f, int l, short * w )
276{
277  int i, s1 = 0, s2 = 0;
278
279  for ( i = f; i <= l; i++ )
280  {
281    s1 += pGetExp(p1,i);
282    s2 += pGetExp(p2,i);
283  }
284  if ( s1 == s2 )
285  {
286    i = f;
287    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
288      i++;
289    if ( i > l )
290      return 0;
291    if ( pGetExp(p1,i) > pGetExp(p2,i) )
292      return 1;
293    return -1;
294  }
295  if ( s1 > s2 )
296    return 1;
297  return -1;
298}
299
300/*2
301* compare the head monomial of p1 and p2 with weighted degree reverse
302* lexicographic ordering
303*/
304static int comp_wp ( poly p1, poly p2, int f, int l, short * w )
305{
306  int i, s1 = 0, s2 = 0;
307
308  for ( i = f; i <= l; i++, w++ )
309  {
310    s1 += (int)pGetExp(p1,i)*(*w);
311    s2 += (int)pGetExp(p2,i)*(*w);
312  }
313  if ( s1 == s2 )
314  {
315    i = l;
316    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
317      i--;
318    if ( i < f )
319      return 0;
320    if ( pGetExp(p1,i) > pGetExp(p2,i) )
321      return -1;
322    return 1;
323  }
324  if ( s1 > s2 )
325    return 1;
326  return -1;
327}
328
329/*2
330* compare the head monomial of p1 and p2 with weighted degree lexicographic
331* ordering
332*/
333static int comp_Wp ( poly p1, poly p2, int f, int l, short * w )
334{
335  int i, s1 = 0, s2 = 0;
336
337  for ( i = f; i <= l; i++, w++ )
338  {
339    s1 += (int)pGetExp(p1,i)*(*w);
340    s2 += (int)pGetExp(p2,i)*(*w);
341  }
342  if ( s1 == s2 )
343  {
344    i = f;
345    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
346      i++;
347    if ( i > l )
348      return 0;
349    if ( pGetExp(p1,i) > pGetExp(p2,i) )
350      return 1;
351    return -1;
352  }
353  if ( s1 > s2 )
354    return 1;
355  return -1;
356}
357
358/*2
359* compare the head monomial of p1 and p2 with lexicographic ordering
360* (power series case)
361*/
362static int comp_ls ( poly p1, poly p2, int f, int l, short * w )
363{
364  int i;
365
366  i = f;
367  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
368    i++;
369  if ( i > l )
370    return 0;
371  if ( pGetExp(p1,i) < pGetExp(p2,i) )
372    return 1;
373  return -1;
374}
375
376/*2
377* compare the head monomial of p1 and p2 with degree reverse lexicographic
378* ordering (power series case)
379*/
380static int comp_ds ( poly p1, poly p2, int f, int l, short * w )
381{
382  int i, s1 = 0, s2 = 0;
383
384  for ( i = f; i <= l; i++ )
385  {
386    s1 += pGetExp(p1,i);
387    s2 += pGetExp(p2,i);
388  }
389  if ( s1 == s2 )
390  {
391    i = l;
392    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
393      i--;
394    if ( i < f )
395      return 0;
396    if ( pGetExp(p1,i) < pGetExp(p2,i) )
397      return 1;
398    return -1;
399  }
400  if ( s1 < s2 )
401    return 1;
402  return -1;
403}
404
405/*2
406* compare the head monomial of p1 and p2 with degree lexicographic ordering
407* (power series case)
408*/
409static int comp_Ds ( poly p1, poly p2, int f, int l, short * w )
410{
411  int i, s1 = 0, s2 = 0;
412
413  for ( i = f; i <= l; i++ )
414  {
415    s1 += pGetExp(p1,i);
416    s2 += pGetExp(p2,i);
417  }
418  if ( s1 == s2 )
419  {
420    i = f;
421    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
422      i++;
423    if ( i > l )
424      return 0;
425    if ( pGetExp(p1,i) < pGetExp(p2,i) )
426      return -1;
427    return 1;
428  }
429  if ( s1 < s2 )
430    return 1;
431  return -1;
432}
433
434/*2
435* compare the head monomial of p1 and p2 with weighted degree reverse
436* lexicographic ordering (power series case)
437*/
438static int comp_ws ( poly p1, poly p2, int f, int l, short * w )
439{
440  int i, s1 = 0, s2 = 0;
441
442  for ( i = f; i <= l; i++, w++ )
443  {
444    s1 += (int)pGetExp(p1,i)*(*w);
445    s2 += (int)pGetExp(p2,i)*(*w);
446  }
447  if ( s1 == s2 )
448  {
449    i = l;
450    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
451      i--;
452    if ( i < f )
453      return 0;
454    if ( pGetExp(p1,i) < pGetExp(p2,i) )
455      return 1;
456    return -1;
457  }
458  if ( s1 < s2 )
459    return 1;
460  return -1;
461}
462
463/*2
464* compare the head monomial of p1 and p2 with weighted degree lexicographic
465* ordering (power series case)
466*/
467static int comp_Ws ( poly p1, poly p2, int f, int l, short * w )
468{
469  int i, s1 = 0, s2 = 0;
470
471  for ( i = f; i <= l; i++, w++ )
472  {
473    s1 += (int)pGetExp(p1,i)*(*w);
474    s2 += (int)pGetExp(p2,i)*(*w);
475  }
476  if ( s1 == s2 )
477  {
478    i = f;
479    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
480      i++;
481    if ( i > l )
482      return 0;
483    if ( pGetExp(p1,i) < pGetExp(p2,i) )
484      return -1;
485    return 1;
486  }
487  if ( s1 < s2 )
488    return 1;
489  return -1;
490}
491
492/*2
493* compare the head monomial of p1 and p2 with matrix order
494* w contains a series of l-f+1 lines
495*/
496static int comp_M ( poly p1, poly p2, int f, int l, short * w )
497{
498  int i, j, s1, s2;
499
500  for ( i = f; i <= l; i++ )
501  {
502    s1 = s2 = 0;
503    for ( j = f; j <= l; j++, w++ )
504    {
505      s1 += (int)pGetExp(p1,j)*(int)(*w);
506      s2 += (int)pGetExp(p2,j)*(int)(*w);
507    }
508    if ( s1 < s2 )
509      return -1;
510    if ( s1 > s2 )
511      return 1;
512    /* now w points to the last element of the current row, the next w++ */
513    /* moves on to the first element of the next row ! */
514  }
515  return 0;
516}
517
518/*2
519* compare the head monomial of p1 and p2 with weight vector
520*/
521static int comp_a  ( poly p1, poly p2, int f, int l, short * w )
522{
523  int i, s1 = 0, s2 = 0;
524
525  for ( i = f; i <= l; i++, w++ )
526  {
527    s1 += (int)pGetExp(p1,i)*(*w);
528    s2 += (int)pGetExp(p2,i)*(*w);
529  }
530  if ( s1 > s2 )
531    return 1;
532  if ( s1 < s2 )
533    return -1;
534  return 0;
535}
536
537/*2
538* compare the head monomial of p1 and p2 with module component
539*/
540static int comp_c  ( poly p1, poly p2, int f, int l, short * w )
541{
542  if ( pGetComp(p1) > pGetComp(p2) )
543    return -pComponentOrder;
544  if ( pGetComp(p1) < pGetComp(p2) )
545    return pComponentOrder;
546  return 0;
547}
548
549/*---------------------------------------------------------------*/
550
551/*2
552* compare p1 and p2 by a block ordering
553* uses (*bcomph[])() to do the real work
554*/
555static int BlockComp(poly p1, poly p2)
556{
557  int res, i, e, a;
558
559  /*4 compare in all blocks,*
560  * each block has var numbers a(=block0[i]) to e (=block1[i])*
561  * the block number starts with 0*/
562  e = 0;
563  i = 0;
564  loop
565  {
566    a = block0[i];
567    e = block1[i];
568    res = (*bcomph[i])(p1, p2, a, e , polys_wv[i]);
569    if (res)
570      return res;
571    i++;
572    if (order[i]==0)
573      break;
574  }
575  return 0;
576}
577
578int pComp(poly p1, poly p2)
579{
580  if (p2==NULL)
581    return 1;
582  if (p1==NULL)
583    return -1;
584  return pComp0(p1,p2);
585}
586
587/*----------pComp handling for syzygies---------------------*/
588static void newHeadsB(polyset actHeads,int length)
589{
590  int i;
591  int* newOrder=(int*)Alloc(length*sizeof(int));
592
593  for (i=0;i<length;i++)
594  {
595    if (actHeads[i]!=NULL)
596    {
597      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
598    }
599    else
600    {
601      newOrder[i]=0;
602    }
603  }
604  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
605  SchreyerOrd = newOrder;
606  maxSchreyer = length;
607/*
608*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
609*PrintLn();
610*/
611}
612
613int mcompSchrB(poly p1,poly p2)
614{
615  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
616      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
617
618  if (CompP1==CompP2) return pCompOld(p1,p2);
619  pSetComp(p1,cP1);
620  pSetComp(p2,cP2);
621  result = pCompOld(p1,p2);
622  pSetComp(p1,CompP1);
623  pSetComp(p2,CompP2);
624  if (!result)
625  {
626    if (CompP1>CompP2)
627      return -1;
628    else if (CompP1<CompP2)
629      return 1;
630  }
631  return result;
632}
633
634
635static void newHeadsM(polyset actHeads,int length)
636{
637  int i;
638  int* newOrder=
639    (int*)Alloc0((length+maxSchreyer-indexShift)*sizeof(int));
640
641  //for (i=0;i<length+maxSchreyer-indexShift;i++)
642  //  newOrder[i]=0;
643  for (i=indexShift;i<maxSchreyer;i++)
644  {
645    newOrder[i-indexShift] = SchreyerOrd[i];
646    SchreyerOrd[i] = 0;
647  }
648  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
649    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
650  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
651  SchreyerOrd = newOrder;
652  indexShift = maxSchreyer-indexShift;
653  maxSchreyer = length+indexShift;
654}
655
656/*2
657* compute the length of a polynomial (in l)
658* and the degree of the monomial with maximal degree:
659* this is NOT the last one and the module component
660* has to be <= indexShift
661*/
662static int ldegSchrM(poly p,int *l)
663{
664  int  t,max;
665
666  (*l)=1;
667  max=pFDeg(p);
668  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
669  {
670    pIter(p);
671    t=pFDeg(p);
672    if (t>max) max=t;
673    (*l)++;
674  }
675  return max;
676}
677
678int mcompSchrM(poly p1,poly p2)
679{
680  if ( pGetComp(p1)<=indexShift)
681  {
682    if ( pGetComp(p2)>indexShift) return 1;
683  }
684  else if ( pGetComp(p2)<=indexShift)  return -1;
685  return mcompSchrB(p1,p2);
686}
687
688void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
689{
690  int i;
691
692  if (length!=0)
693  {
694    if (maxSchreyer!=0)
695      newHeadsM(nextOrder, length);
696    else
697    {
698      indexShift = comps;
699      if (indexShift==0) indexShift = 1;
700      SchreyerOrd = (int*)Alloc((indexShift+length)*sizeof(int));
701      maxSchreyer = length+indexShift;
702      for (i=0;i<indexShift;i++)
703        SchreyerOrd[i] = i;
704      for (i=indexShift;i<maxSchreyer;i++)
705        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
706      pCompOld = pComp0;
707      pComp0 = mcompSchrM;
708      pLDegOld = pLDeg;
709      pLDeg = ldegSchrM;
710    }
711  }
712  else
713  {
714    if (maxSchreyer!=0)
715    {
716      Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
717      maxSchreyer = 0;
718      indexShift = 0;
719      pComp0 = pCompOld;
720      pLDeg = pLDegOld;
721    }
722  }
723}
724
725/*2
726*the pComp0 for normal syzygies
727*compares monomials in the usual ring order (pCompOld)
728*but groups module indecees according indexBounds befor
729*/
730static int mcompSyz(poly p1,poly p2)
731{
732  if (pGetComp(p1)<=pMaxBound)
733  {
734    if (pGetComp(p2)>pMaxBound) return 1;
735  }
736  else if (pGetComp(p2)<=pMaxBound)
737  {
738    return -1;
739  }
740  return pCompOld(p1,p2);
741}
742
743void pSetSyzComp(int k)
744{
745  if (k!=0)
746  {
747    if (pMaxBound==0)
748    {
749      pCompOld = pComp0;
750      pComp0 = mcompSyz;
751    }
752    pMaxBound = k;
753  }
754  else
755  {
756    if (pMaxBound!=0)
757    {
758      pComp0 = pCompOld;
759      pMaxBound = 0;
760    }
761  }
762}
763
764/*2
765* the type of the module ordering: C: -1, c: 1
766*/
767int pModuleOrder()
768{
769  return pComponentOrder;
770}
771
772/* -------------------------------------------------------------------*/
773/* several possibilities for pFDeg: the degree of the head term       */
774/*2
775* compute the degree of the leading monomial of p
776* the ordering is compatible with degree, use a->order
777*/
778int pDeg(poly a)
779{
780  return (a->Order);
781}
782
783/*2
784* compute the degree of the leading monomial of p
785* with respect to weigths 1
786* (all are 1 so save multiplications or they are of different signs)
787* the ordering is not compatible with degree so do not use p->Order
788*/
789int pTotaldegree(poly p)
790{
791  return pExpQuerSum(p);
792}
793
794/*2
795* compute the degree of the leading monomial of p
796* with respect to weigths from the ordering
797* the ordering is not compatible with degree so do not use p->Order
798*/
799int pWTotaldegree(poly p)
800{
801  assume(p != NULL);
802  int i, k;
803  int j =0;
804
805  // iterate through each block:
806  for (i=0;order[i]!=0;i++)
807  {
808    switch(order[i])
809    {
810      case ringorder_wp:
811      case ringorder_ws:
812      case ringorder_Wp:
813      case ringorder_Ws:
814        for (k=block0[i];k<=block1[i];k++)
815        { // in jedem block:
816          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
817        }
818        break;
819      case ringorder_M:
820      case ringorder_lp:
821      case ringorder_dp:
822      case ringorder_ds:
823      case ringorder_Dp:
824      case ringorder_Ds:
825        for (k=block0[i];k<=block1[i];k++)
826        {
827          j+= pGetExp(p,k);
828        }
829        break;
830      case ringorder_c:
831      case ringorder_C:
832        break;
833      case ringorder_a:
834        for (k=block0[i];k<=block1[i];k++)
835        { // only one line
836          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
837        }
838        return j;
839    }
840  }
841  return  j;
842}
843int pWDegree(poly p)
844{
845  int i, k;
846  int j =0;
847
848  for(i=1;i<=pVariables;i++)
849    j+=pGetExp(p,i)*pWeight(i);
850  return j;
851}
852
853/* ---------------------------------------------------------------------*/
854/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
855/*  compute in l also the pLength of p                                   */
856
857/*2
858* compute the length of a polynomial (in l)
859* and the degree of the monomial with maximal degree: the last one
860*/
861static int ldeg0(poly p,int *l)
862{
863  Exponent_t k= pGetComp(p);
864  int ll=1;
865
866  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
867  {
868    pIter(p);
869    ll++;
870  }
871  *l=ll;
872  return (p->Order);
873}
874
875/*2
876* compute the length of a polynomial (in l)
877* and the degree of the monomial with maximal degree: the last one
878* but search in all components before syzcomp
879*/
880static int ldeg0c(poly p,int *l)
881{
882  int o=pFDeg(p);
883  int ll=1;
884
885  if (pMaxBound/*syzComp*/==0)
886  {
887    while ((p=pNext(p))!=NULL)
888    {
889      o=pFDeg(p);
890      ll++;
891    }
892  }
893  else
894  {
895    while ((p=pNext(p))!=NULL)
896    {
897      if (pGetComp(p)<=pMaxBound/*syzComp*/)
898      {
899        o=pFDeg(p);
900        ll++;
901      }
902      else break;
903    }
904  }
905  *l=ll;
906  return o;
907}
908
909/*2
910* compute the length of a polynomial (in l)
911* and the degree of the monomial with maximal degree: the first one
912* this works for the polynomial case with degree orderings
913* (both c,dp and dp,c)
914*/
915static int ldegb(poly p,int *l)
916{
917  Exponent_t k= pGetComp(p);
918  int o = p->Order;
919  int ll=1;
920
921  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
922  {
923    ll++;
924  }
925  *l=ll;
926  return o;
927}
928
929/*2
930* compute the length of a polynomial (in l)
931* and the degree of the monomial with maximal degree:
932* this is NOT the last one, we have to look for it
933*/
934static int ldeg1(poly p,int *l)
935{
936  Exponent_t k= pGetComp(p);
937  int ll=1;
938  int  t,max;
939
940  max=pFDeg(p);
941  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
942  {
943    t=pFDeg(p);
944    if (t>max) max=t;
945    ll++;
946  }
947  *l=ll;
948  return max;
949}
950
951/*2
952* compute the length of a polynomial (in l)
953* and the degree of the monomial with maximal degree:
954* this is NOT the last one, we have to look for it
955* in all components
956*/
957static int ldeg1c(poly p,int *l)
958{
959  int ll=1;
960  int  t,max;
961
962  max=pFDeg(p);
963  while ((p=pNext(p))!=NULL)
964  {
965    if ((pMaxBound/*syzComp*/==0) || (pGetComp(p)<=pMaxBound/*syzComp*/))
966    {
967       if ((t=pFDeg(p))>max) max=t;
968       ll++;
969    }
970    else break;
971  }
972  *l=ll;
973  return max;
974}
975
976/* -------------------------------------------------------- */
977/* set the variables for a choosen ordering                 */
978
979
980/*
981* sets the comparision routine for monomials: for simple monomial orderings
982* Priority is given to exponent vector
983*/
984static void SimpleChoose(int o_r, int comp_order, pCompProc *p)
985{
986  switch(o_r)
987  {
988      case ringorder_dp:
989      case ringorder_wp:
990      case ringorder_ds:
991      case ringorder_ws:
992      case ringorder_ls:
993      case ringorder_unspec:
994        pGetVarIndicies_RevLex(pVariables, pVarOffset, pVarCompIndex,
995                               pVarLowIndex, pVarHighIndex);
996        pLexSgn = -1;
997        if (comp_order == ringorder_C || o_r == ringorder_unspec)
998        {
999          *p = pComp_otEXPCOMP;
1000        }
1001        else
1002        {
1003          // component is compatible with exponent vector
1004          *p = pComp_otEXP;
1005        }
1006        break;
1007
1008#ifdef PDEBUG
1009      case ringorder_lp:
1010      case ringorder_Dp:
1011      case ringorder_Wp:
1012      case ringorder_Ds:
1013      case ringorder_Ws:
1014#else
1015      default:
1016#endif
1017        pGetVarIndicies_Lex(pVariables, pVarOffset, pVarCompIndex,
1018                            pVarLowIndex, pVarHighIndex);
1019        pLexSgn = 1;
1020        if (comp_order == ringorder_c)
1021        {
1022          *p = pComp_otEXPCOMP;
1023        }
1024        else
1025        {
1026          // component is compatible with exponent vector
1027          *p = pComp_otEXP;
1028        }
1029#ifdef PDEBUG
1030        break;
1031      default:
1032        Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1033#endif
1034  }
1035
1036  if (o_r == ringorder_lp || o_r == ringorder_ls)
1037  {
1038    pLexOrder=TRUE;
1039    pFDeg = pTotaldegree;
1040    pLDeg = ldeg1c;
1041    if (o_r == ringorder_ls)
1042      pGetVarIndicies_Lex(pVariables, pVarOffset, pVarCompIndex,
1043                          pVarLowIndex, pVarHighIndex);
1044
1045  }
1046}
1047
1048/*
1049* sets the comparision routine for monomials: for simple monomial orderings
1050* Priority is given to component
1051*/
1052static void SimpleChooseC(int o_r, pCompProc *p)
1053{
1054  switch(o_r)
1055  {
1056      case ringorder_dp:
1057      case ringorder_wp:
1058      case ringorder_ds:
1059      case ringorder_ls:
1060      case ringorder_ws:
1061        pGetVarIndicies_RevLex(pVariables, pVarOffset, pVarCompIndex,
1062                               pVarLowIndex, pVarHighIndex);
1063        pLexSgn = -1;
1064        *p = pComp_otCOMPEXP;
1065        break;
1066
1067#ifdef PDEBUG
1068      case ringorder_lp:
1069      case ringorder_Dp:
1070      case ringorder_Wp:
1071      case ringorder_Ds:
1072      case ringorder_Ws:
1073#else
1074      default:
1075#endif
1076        pGetVarIndicies_Lex(pVariables, pVarOffset, pVarCompIndex,
1077                            pVarLowIndex, pVarHighIndex);
1078        pLexSgn = 1;
1079        *p = pComp_otCOMPEXP;
1080#ifdef PDEBUG
1081        break;
1082      default:
1083        Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1084#endif
1085  }
1086  if (o_r == ringorder_lp || o_r == ringorder_ls)
1087  {
1088    pLexOrder=TRUE;
1089    pFDeg = pTotaldegree;
1090    pLDeg = ldeg1c;
1091    if (o_r == ringorder_ls)
1092        pGetVarIndicies_Lex(pVariables, pVarOffset, pVarCompIndex,
1093                            pVarLowIndex, pVarHighIndex);
1094  }
1095}
1096
1097/*2
1098* sets pSetm
1099* (according o_r = order of first block)
1100*/
1101static void SetpSetm(int o_r, int ip)
1102{
1103  switch(o_r)
1104  {
1105    case ringorder_lp:
1106    case ringorder_ls:
1107      if (pVariables>1)
1108        pSetm= setlex2;
1109      else
1110        pSetm= setlex1;
1111      break;
1112    case ringorder_dp:
1113    case ringorder_Dp:
1114    case ringorder_ds:
1115    case ringorder_Ds:
1116    case ringorder_unspec:
1117      pSetm= setdeg1;
1118      break;
1119    case ringorder_a:
1120    case ringorder_wp:
1121    case ringorder_Wp:
1122    case ringorder_ws:
1123    case ringorder_Ws:
1124    case ringorder_M:
1125      pSetm= setdeg1w;
1126      firstwv=polys_wv[ip];
1127      break;
1128    case ringorder_c:
1129    case ringorder_C:
1130      return;
1131      /*do not set firstBlockEnds for this orderings*/
1132#ifdef TEST
1133    default:
1134      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1135#endif
1136  }
1137  firstBlockEnds=block1[ip];
1138}
1139
1140
1141/*2
1142* sets the comparision routine for monomials: for all but the first
1143* block of variables (ip is the block number, o_r the number of the ordering)
1144*/
1145static void HighSet(int ip, int o_r)
1146{
1147  switch(o_r)
1148  {
1149    case ringorder_lp:
1150      bcomph[ip]=comp_lp;
1151      if (pOrdSgn==-1) pMixedOrder=TRUE;
1152      break;
1153    case ringorder_dp:
1154      bcomph[ip]=comp_dp;
1155      if (pOrdSgn==-1) pMixedOrder=TRUE;
1156      break;
1157    case ringorder_Dp:
1158      bcomph[ip]=comp_Dp;
1159      if (pOrdSgn==-1) pMixedOrder=TRUE;
1160      break;
1161    case ringorder_wp:
1162      bcomph[ip]=comp_wp;
1163      if (pOrdSgn==-1) pMixedOrder=TRUE;
1164      break;
1165    case ringorder_Wp:
1166      bcomph[ip]=comp_Wp;
1167      if (pOrdSgn==-1) pMixedOrder=TRUE;
1168      break;
1169    case ringorder_ls:
1170      bcomph[ip]=comp_ls;
1171      break;
1172    case ringorder_ds:
1173      bcomph[ip]=comp_ds;
1174      break;
1175    case ringorder_Ds:
1176      bcomph[ip]=comp_Ds;
1177      break;
1178    case ringorder_ws:
1179      bcomph[ip]=comp_ws;
1180      break;
1181    case ringorder_Ws:
1182      bcomph[ip]=comp_Ws;
1183      break;
1184    case ringorder_c:
1185      pComponentOrder=1;
1186      bcomph[ip]=comp_c;
1187      break;
1188    case ringorder_C:
1189      pComponentOrder=-1;
1190      bcomph[ip]=comp_c;
1191      break;
1192    case ringorder_M:
1193      bcomph[ip]=comp_M;
1194      pMixedOrder=TRUE;
1195      break;
1196    case ringorder_a:
1197      if (pOrdSgn==-1) pMixedOrder=TRUE;
1198      if (ip==0)
1199        bcomph[0]=comp1a;
1200      else
1201        bcomph[ip]=comp_a;
1202      break;
1203#ifdef TEST
1204    default:
1205      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1206#endif
1207  }
1208}
1209
1210/* -------------------------------------------------------- */
1211/*2
1212* change all variables to fit the description of the new ring
1213*/
1214
1215void pChangeRing(int n, int Sgn, int * orders, int * b0, int * b1,
1216         short ** wv)
1217{
1218  sip_sring tmpR;
1219  memset(&tmpR, 0, sizeof(sip_sring));
1220  tmpR.N = n;
1221  tmpR.OrdSgn = Sgn;
1222  tmpR.order = orders;
1223  tmpR.block0 = b0;
1224  tmpR.block1 = b1;
1225  tmpR.wvhdl = wv;
1226  rComplete(&tmpR);
1227  pSetGlobals(&tmpR);
1228}
1229
1230void pSetGlobals(ring r, BOOLEAN complete)
1231{
1232  int i;
1233  pComponentOrder=1;
1234  if (ppNoether!=NULL) pDelete(&ppNoether);
1235#ifdef SRING
1236  pSRING=FALSE;
1237  pAltVars=r->N+1;
1238#endif
1239  pVariables = r->N;
1240
1241  // set the various size parameters and initialize memory
1242  if ((((pVariables+1)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1243    pVariables1W = (pVariables+1)*sizeof(Exponent_t) / sizeof(void*);
1244  else
1245    pVariables1W = ((pVariables+1)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1246
1247  if ((((pVariables)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1248    pVariablesW = (pVariables)*sizeof(Exponent_t) / sizeof(void*);
1249  else
1250    pVariablesW = ((pVariables)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1251
1252  pMonomSize = POLYSIZE + (pVariables + 1) * sizeof(Exponent_t);
1253  if ((pMonomSize % sizeof(void*)) == 0)
1254  {
1255    pMonomSizeW = pMonomSize/sizeof(void*);
1256  }
1257  else
1258  {
1259    pMonomSizeW = pMonomSize/sizeof(void*) + 1;
1260    pMonomSize = pMonomSizeW*sizeof(void*);
1261  }
1262
1263  // Initialize memory management
1264  mmSpecializeBlock(pMonomSize);
1265
1266  pVarOffset = r->VarOffset;
1267 
1268  pOrdSgn = r->OrdSgn;
1269  pVectorOut=(r->order[0]==ringorder_c);
1270  order=r->order;
1271  block0=r->block0;
1272  block1=r->block1;
1273  firstwv=NULL;
1274  polys_wv=r->wvhdl;
1275  /*------- only one real block ----------------------*/
1276  pLexOrder=FALSE;
1277  pMixedOrder=FALSE;
1278  pFDeg=pDeg;
1279  if (pOrdSgn == 1) pLDeg = ldegb;
1280  else              pLDeg = ldeg0;
1281  /*======== ordering type is (_,c) =========================*/
1282  if ((order[0]==ringorder_unspec)
1283  ||(
1284    ((order[1]==ringorder_c)||(order[1]==ringorder_C))
1285    && (order[0]!=ringorder_M)
1286    && (order[2]==0))
1287  )
1288  {
1289    if ((order[0]!=ringorder_unspec)
1290    && (order[1]==ringorder_C))
1291      pComponentOrder=-1;
1292    if (pOrdSgn == -1) pLDeg = ldeg0c;
1293    SimpleChoose(order[0],order[1], &pComp0);
1294    SetpSetm(order[0],0);
1295  }
1296  /*======== ordering type is (c,_) =========================*/
1297  else if (((order[0]==ringorder_c)||(order[0]==ringorder_C))
1298  && (order[1]!=ringorder_M)
1299  &&  (order[2]==0))
1300  {
1301    /* pLDeg = ldeg0; is standard*/
1302    if (order[0]==ringorder_C)
1303      pComponentOrder=-1;
1304    SimpleChooseC(order[1], &pComp0);
1305    SetpSetm(order[1],1);
1306  }
1307  /*------- more than one block ----------------------*/
1308  else
1309  {
1310    pGetVarIndicies(pVariables, pVarOffset, pVarCompIndex, pVarLowIndex,
1311                    pVarHighIndex);
1312    //pLexOrder=TRUE;
1313    pVectorOut=order[0]==ringorder_c;
1314    if ((pVectorOut)||(order[0]==ringorder_C))
1315    {
1316      if(block1[1]!=pVariables) pLexOrder=TRUE;
1317    }
1318    else
1319    {
1320      if(block1[0]!=pVariables) pLexOrder=TRUE;
1321    }
1322    /*the number of orderings:*/
1323    i = 0;
1324    while (order[++i] != 0);
1325    do
1326    {
1327      i--;
1328      HighSet(i, order[i]);/*sets also pMixedOrder to TRUE, if...*/
1329      SetpSetm(order[i],i);
1330    }
1331    while (i != 0);
1332
1333    pComp0 = BlockComp;
1334    if ((order[0]!=ringorder_c)&&(order[0]!=ringorder_C))
1335    {
1336      pLDeg = ldeg1c;
1337    }
1338    else
1339    {
1340      pLDeg = ldeg1;
1341    }
1342    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
1343  }
1344  if (complete)
1345  {
1346    if ((pLexOrder) || (pOrdSgn==-1))
1347    {
1348      test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
1349    }
1350  }
1351}
1352
1353/* -------------------------------------------------------- */
1354
1355static BOOLEAN pMultT_nok;
1356/*2
1357* update the polynomial a by multipying it by
1358* the (number) coefficient
1359* and the exponent vector (of) exp (a well initialized polynomial)
1360*/
1361poly pMultT(poly a, poly exp )
1362{
1363  int i;
1364  number t,x,y=pGetCoeff(exp);
1365  poly aa=a;
1366  poly prev=NULL;
1367#ifdef SDRING
1368  poly pDRINGres=NULL;
1369#endif
1370
1371  pMultT_nok = pGetComp(exp);
1372#ifdef PDEBUG
1373  pTest(a);
1374  pTest(exp);
1375#endif
1376  while (a !=NULL)
1377  {
1378    x=pGetCoeff(a);
1379    t=nMult(x/*pGetCoeff(a)*/,y/*pGetCoeff(exp)*/);
1380    nDelete(&x/*pGetCoeff(a)*/);
1381    pSetCoeff0(a,t);
1382    if (nIsZero(t))
1383    {
1384      if (prev==NULL) { pDelete1(&a); aa=a; }
1385      else            { pDelete1(&prev->next); a=prev->next;}
1386    }
1387    else
1388    {
1389#ifdef DRING
1390      if (pDRING)
1391      {
1392         if (pdDFlag(a)==1)
1393         {
1394           if (pdDFlag(exp)==1)
1395           {
1396             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
1397           }
1398           else
1399           {
1400             pDRINGres=pAdd(pDRINGres,pMultDT(a,exp));
1401           }
1402         }
1403         else
1404         {
1405           if (pdDFlag(exp)==1)
1406           {
1407             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
1408           }
1409           else
1410           {
1411             pDRINGres=pAdd(pDRINGres,pMultTT(a,exp));
1412           }
1413         }
1414      }
1415      else
1416#endif
1417#ifdef SRING
1418      if (pSRING)
1419      {
1420        pDRINGres=pAdd(pDRINGres,psMultM(a,exp));
1421      }
1422      else
1423#endif
1424      {
1425        for (i=pVariables; i != 0; i--)
1426        {
1427           pAddExp(a,i, pGetExp(exp,i));
1428        }
1429        #ifdef TEST_MAC_ORDER
1430        if (bNoAdd)
1431          pSetm(a);
1432        else
1433        #endif
1434          a->Order += exp->Order;
1435        if (pMultT_nok)
1436        {
1437          if (pGetComp(a) == 0)
1438          {
1439             pSetComp(a, pGetComp(exp));
1440          }
1441          else
1442          {
1443            return NULL /*FALSE*/;
1444          }
1445        }
1446      }
1447      prev=a;
1448      pIter(a);
1449    }
1450  }
1451  pMultT_nok=0;
1452#ifdef SDRING
1453  if (
1454  #ifdef DRING
1455  pDRING ||
1456  #endif
1457  #ifdef SRING
1458  pSRING ||
1459  #endif
1460  0 )
1461  {
1462    pDelete(&aa);
1463    pTest(pDRINGres);
1464    return pDRINGres;
1465  }
1466#endif
1467  pTest(aa);
1468  return aa; /*TRUE*/
1469}
1470
1471/*2
1472* multiply p1 with p2, p1 and p2 are destroyed
1473* do not put attention on speed: the procedure is only used in the interpreter
1474*/
1475poly pMult(poly p1, poly p2)
1476{
1477  poly res, r, rn, a;
1478  BOOLEAN cont;
1479
1480  if ((p1!=NULL) && (p2!=NULL))
1481  {
1482#ifdef PDEBUG
1483    pTest(p1);
1484    pTest(p2);
1485#endif
1486    cont = TRUE;
1487    a = p1;
1488    if (pNext(p2)!=NULL)
1489      a = pCopy(a);
1490    else
1491      cont = FALSE;
1492    res = pMultT(a, p2);
1493    if (pMultT_nok)
1494    {
1495      if (cont) pDelete(&p1);
1496      pDelete(&res);
1497      pDelete(&p2);
1498      return NULL;
1499    }
1500    pTest(res);
1501    pDelete1(&p2);
1502    r = res;
1503    if (r!=NULL) rn = pNext(r);
1504    else         rn=NULL;
1505    while (cont)
1506    {
1507      if (pNext(p2)==NULL)
1508      {
1509        a = p1;
1510        cont = FALSE;
1511      }
1512      else
1513      {
1514        a = pCopy(p1);
1515      }
1516      a=pMultT(a, p2); //sets pMultT_nok
1517      pTest(a);
1518      if (pMultT_nok)
1519      {
1520        if (cont) pDelete(&p1);
1521        pDelete(&a);
1522        pDelete(&res);
1523        pDelete(&p2);
1524        return NULL;
1525      }
1526      while ((rn!=NULL) && (pComp0(rn,a)>0))
1527      {
1528        r = rn;
1529        pIter(rn);
1530      }
1531      if (r!=NULL) pNext(r) = rn = pAdd(a, rn);
1532      else         res=r=a;
1533      pDelete1(&p2);
1534    }
1535    pTest(res);
1536    return res;
1537  }
1538  pDelete(&p1);
1539  pDelete(&p2);
1540  return NULL;
1541}
1542
1543/*2
1544* update a by multiplying it with c (c will not be destroyed)
1545*/
1546void pMultN(poly a, number c)
1547{
1548  number t;
1549
1550  while (a!=NULL)
1551  {
1552    t=nMult(pGetCoeff(a), c);
1553    //nNormalize(t);
1554    pSetCoeff(a,t);
1555    pIter(a);
1556  }
1557}
1558
1559/*2
1560* return a copy of the poly a times the number c (a,c will not be destroyed)
1561*/
1562poly pMultCopyN(poly a, number c)
1563{
1564  poly result=NULL,hp;
1565
1566  if (a != NULL)
1567  {
1568    result=pNew();
1569    pCopy2(result,a);
1570    pNext(result)=NULL;
1571    pGetCoeff(result)=nMult(pGetCoeff(a),c);
1572    pIter(a);
1573    hp=result;
1574    while (a!=NULL)
1575    {
1576      hp=pNext(hp)=pNew();
1577      pCopy2(hp,a);
1578      pSetCoeff0(hp,nMult(pGetCoeff(a), c));
1579      pIter(a);
1580    }
1581    pNext(hp)=NULL;
1582  }
1583  return result;
1584}
1585
1586/*2
1587* assumes that the head term of b is a multiple of the head term of a
1588* and return the multiplicant *m
1589*/
1590poly pDivide(poly a, poly b)
1591{
1592  int i;
1593  poly result=pInit();
1594
1595  for(i=(int)pVariables; i; i--)
1596    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
1597  pSetComp(result, pGetComp(a) - pGetComp(b));
1598  pSetm(result);
1599  return result;
1600}
1601
1602/*2
1603* divides a by the monomial b, ignores monomials wihich are not divisible
1604* assumes that b is not NULL
1605*/
1606poly pDivideM(poly a, poly b)
1607{
1608  if (a==NULL) return NULL;
1609  poly result=a;
1610  poly prev=NULL;
1611  int i;
1612  number inv=nInvers(pGetCoeff(b));
1613
1614  while (a!=NULL)
1615  {
1616    if (pDivisibleBy(b,a))
1617    {
1618      for(i=(int)pVariables; i; i--)
1619         pSubExp(a,i, pGetExp(b,i));
1620      pSubComp(a, pGetComp(b));
1621      pSetm(a);
1622      prev=a;
1623      pIter(a);
1624    }
1625    else
1626    {
1627      if (prev==NULL)
1628      {
1629        pDelete1(&result);
1630        a=result;
1631      }
1632      else
1633      {
1634        pDelete1(&pNext(prev));
1635        a=pNext(prev);
1636      }
1637    }
1638  }
1639  pMultN(result,inv);
1640  nDelete(&inv);
1641  pDelete(&b);
1642  return result;
1643}
1644
1645/*2
1646* returns the LCM of the head terms of a and b in *m
1647*/
1648void pLcm(poly a, poly b, poly m)
1649{
1650  int i;
1651  for (i=pVariables; i; i--)
1652  {
1653    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
1654  }
1655  pSetComp(m, max(pGetComp(a), pGetComp(b)));
1656}
1657
1658/*2
1659* convert monomial given as string to poly, e.g. 1x3y5z
1660*/
1661poly pmInit(char *st, BOOLEAN &ok)
1662{
1663  int i,j;
1664  ok=FALSE;
1665  BOOLEAN b=FALSE;
1666  poly rc = pInit();
1667  char *s = nRead(st,&(rc->coef));
1668  if (s==st)
1669  /* i.e. it does not start with a coeff: test if it is a ringvar*/
1670  {
1671    j = rIsRingVar(s);
1672    if (j >= 0)
1673    {
1674      pIncrExp(rc,1+j);
1675      goto done;
1676    }
1677  }
1678  else
1679    b=TRUE;
1680  while (*s!='\0')
1681  {
1682    char ss[2];
1683    ss[0] = *s++;
1684    ss[1] = '\0';
1685    j = rIsRingVar(ss);
1686    if (j >= 0)
1687    {
1688      s = eati(s,&i);
1689      pAddExp(rc,1+j, (Exponent_t)i);
1690    }
1691    else
1692    {
1693      if ((s!=st)&&isdigit(st[0]))
1694      {
1695        errorreported=TRUE;
1696      }
1697      pDelete(&rc);
1698      return NULL;
1699    }
1700  }
1701done:
1702  ok=!errorreported;
1703  if (nIsZero(pGetCoeff(rc))) pDelete1(&rc);
1704  else
1705  {
1706#ifdef DRING
1707    if (pDRING)
1708    {
1709      for(i=1;i<=pdN;i++)
1710      {
1711        if(pGetExp(rc,pdDX(i))>0)
1712        {
1713          pdSetDFlag(rc,1);
1714          break;
1715        }
1716      }
1717    }
1718#endif
1719    pSetm(rc);
1720  }
1721  return rc;
1722}
1723
1724/*2
1725*make p homgeneous by multiplying the monomials by powers of x_varnum
1726*/
1727poly pHomogen (poly p, int varnum)
1728{
1729  poly q=NULL;
1730  poly res;
1731  int  o,ii;
1732
1733  if (p!=NULL)
1734  {
1735    if ((varnum < 1) || (varnum > pVariables))
1736    {
1737      return NULL;
1738    }
1739    o=pWTotaldegree(p);
1740    q=pNext(p);
1741    while (q != NULL)
1742    {
1743      ii=pWTotaldegree(q);
1744      if (ii>o) o=ii;
1745      pIter(q);
1746    }
1747    q = pCopy(p);
1748    res = q;
1749    while (q != NULL)
1750    {
1751      ii = o-pWTotaldegree(q);
1752      if (ii!=0)
1753      {
1754        pAddExp(q,varnum, (Exponent_t)ii);
1755        pSetm(q);
1756      }
1757      pIter(q);
1758    }
1759    q = pOrdPolyInsertSetm(res);
1760  }
1761  return q;
1762}
1763
1764
1765/*2
1766*replaces the maximal powers of the leading monomial of p2 in p1 by
1767*the same powers of n, utility for dehomogenization
1768*/
1769poly pDehomogen (poly p1,poly p2,number n)
1770{
1771  polyset P;
1772  int     SizeOfSet=5;
1773  int     i;
1774  poly    p;
1775  number  nn;
1776
1777  P = (polyset)Alloc0(5*sizeof(poly));
1778  //for (i=0; i<5; i++)
1779  //{
1780  //  P[i] = NULL;
1781  //}
1782  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
1783  p = P[0];
1784  //P[0] = NULL ;// for safety, may be remoeved later
1785  for (i=1; i<SizeOfSet; i++)
1786  {
1787    if (P[i] != NULL)
1788    {
1789      nPower(n,i,&nn);
1790      pMultN(P[i],nn);
1791      p = pAdd(p,P[i]);
1792      //P[i] =NULL; // for safety, may be removed later
1793      nDelete(&nn);
1794    }
1795  }
1796  Free((ADDRESS)P,SizeOfSet*sizeof(poly));
1797  return p;
1798}
1799
1800/*4
1801*Returns the exponent of the maximal power of the leading monomial of
1802*p2 in that of p1
1803*/
1804static int pGetMaxPower (poly p1,poly p2)
1805{
1806  int     i,k,res = 32000; /*a very large integer*/
1807
1808  if (p1 == NULL) return 0;
1809  for (i=1; i<=pVariables; i++)
1810  {
1811    if ( pGetExp(p2,i) != 0)
1812    {
1813      k =  pGetExp(p1,i) /  pGetExp(p2,i);
1814      if (k < res) res = k;
1815    }
1816  }
1817  return res;
1818}
1819
1820/*2
1821*Returns as i-th entry of P the coefficient of the (i-1) power of
1822*the leading monomial of p2 in p1
1823*/
1824void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
1825{
1826  int   maxPow;
1827  poly  p,qp,Coeff;
1828
1829  if (*P == NULL)
1830  {
1831    *P = (polyset) Alloc(5*sizeof(poly));
1832    *SizeOfSet = 5;
1833  }
1834  p = pCopy(p1);
1835  while (p != NULL)
1836  {
1837    qp = p->next;
1838    p->next = NULL;
1839    maxPow = pGetMaxPower(p,p2);
1840    Coeff = pDivByMonom(p,p2);
1841    if (maxPow > *SizeOfSet)
1842    {
1843      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
1844      *SizeOfSet = maxPow+1;
1845    }
1846    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
1847    pDelete(&p);
1848    p = qp;
1849  }
1850}
1851
1852/*2
1853*returns the leading monomial of p1 divided by the maximal power of that
1854*of p2
1855*/
1856poly pDivByMonom (poly p1,poly p2)
1857{
1858  int     k, i;
1859
1860  if (p1 == NULL) return NULL;
1861  k = pGetMaxPower(p1,p2);
1862  if (k == 0)
1863    return pHead(p1);
1864  else
1865  {
1866    number n;
1867    poly p = pInit();
1868
1869    p->next = NULL;
1870    for (i=1; i<=pVariables; i++)
1871    {
1872       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
1873    }
1874    nPower(p2->coef,k,&n);
1875    pSetCoeff0(p,nDiv(p1->coef,n));
1876    nDelete(&n);
1877    pSetm(p);
1878    return p;
1879  }
1880}
1881/*----------utilities for syzygies--------------*/
1882poly pTakeOutComp(poly * p, int k)
1883{
1884  poly q = *p,qq=NULL,result = NULL;
1885
1886  if (q==NULL) return NULL;
1887  if (pGetComp(q)==k)
1888  {
1889    result = q;
1890    while ((q!=NULL) && (pGetComp(q)==k))
1891    {
1892      pSetComp(q,0);
1893      qq = q;
1894      pIter(q);
1895    }
1896    *p = q;
1897    pNext(qq) = NULL;
1898  }
1899  if (q==NULL) return result;
1900  if (pGetComp(q) > k) pDecrComp(q);
1901  poly pNext_q;
1902  while ((pNext_q=pNext(q))!=NULL)
1903  {
1904    if (pGetComp(pNext_q)==k)
1905    {
1906      if (result==NULL)
1907      {
1908        result = pNext_q;
1909        qq = result;
1910      }
1911      else
1912      {
1913        pNext(qq) = pNext_q;
1914        pIter(qq);
1915      }
1916      pNext(q) = pNext(pNext_q);
1917      pNext(qq) =NULL;
1918      pSetComp(qq,0);
1919    }
1920    else
1921    {
1922      /*pIter(q);*/ q=pNext_q;
1923      if (pGetComp(q) > k) pDecrComp(q);
1924    }
1925  }
1926  return result;
1927}
1928
1929
1930// Splits *p into two polys: *q which consists of all monoms with
1931// component == comp and *p of all other monoms *lq == pLength(*q)
1932void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
1933{
1934  spolyrec pp, qq;
1935  poly p, q, p_prev;
1936  int l = 0;
1937
1938#ifdef HAVE_ASSUME
1939  int lp = pLength(*r_p);
1940#endif
1941
1942  pNext(&pp) = *r_p;
1943  p = *r_p;
1944  p_prev = &pp;
1945  q = &qq;
1946
1947  while(p != NULL)
1948  {
1949    while (pGetComp(p) == comp)
1950    {
1951      pNext(q) = p;
1952      pIter(q);
1953      pSetComp(p, 0);
1954      pIter(p);
1955      l++;
1956      if (p == NULL)
1957      {
1958        pNext(p_prev) = NULL;
1959        goto Finish;
1960      }
1961    }
1962    pNext(p_prev) = p;
1963    p_prev = p;
1964    pIter(p);
1965  }
1966
1967  Finish:
1968  pNext(q) = NULL;
1969  *r_p = pNext(&pp);
1970  *r_q = pNext(&qq);
1971  *lq = l;
1972#ifdef HAVE_ASSUME
1973  assume(pLength(*r_p) + pLength(*r_q) == lp);
1974#endif
1975  pTest(*r_p);
1976  pTest(*r_q);
1977}
1978
1979void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
1980                         poly *r_q, int *lq)
1981{
1982  spolyrec pp, qq;
1983  poly p, q, p_prev;
1984  int l = 0;
1985
1986  pNext(&pp) = *r_p;
1987  p = *r_p;
1988  p_prev = &pp;
1989  q = &qq;
1990
1991#ifdef HAVE_ASSUME
1992  if (p != NULL)
1993  {
1994    while (pNext(p) != NULL)
1995    {
1996      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
1997      pIter(p);
1998    }
1999  }
2000  p = *r_p;
2001#endif
2002
2003  while (p != NULL && pGetOrder(p) > order) pIter(p);
2004
2005  while(p != NULL && pGetOrder(p) == order)
2006  {
2007    while (pGetComp(p) == comp)
2008    {
2009      pNext(q) = p;
2010      pIter(q);
2011      pIter(p);
2012      pSetComp(p, 0);
2013      l++;
2014      if (p == NULL || pGetOrder(p) != order)
2015      {
2016        pNext(p_prev) = p;
2017        goto Finish;
2018      }
2019    }
2020    pNext(p_prev) = p;
2021    p_prev = p;
2022    pIter(p);
2023  }
2024
2025  Finish:
2026  pNext(q) = NULL;
2027  *r_p = pNext(&pp);
2028  *r_q = pNext(&qq);
2029  *lq = l;
2030}
2031
2032poly pTakeOutComp1(poly * p, int k)
2033{
2034  poly q = *p;
2035
2036  if (q==NULL) return NULL;
2037
2038  poly qq=NULL,result = NULL;
2039
2040  if (pGetComp(q)==k)
2041  {
2042    result = q; /* *p */
2043    while ((q!=NULL) && (pGetComp(q)==k))
2044    {
2045      pSetComp(q,0);
2046      qq = q;
2047      pIter(q);
2048    }
2049    *p = q;
2050    pNext(qq) = NULL;
2051  }
2052  if (q==NULL) return result;
2053//  if (pGetComp(q) > k) pGetComp(q)--;
2054  while (pNext(q)!=NULL)
2055  {
2056    if (pGetComp(pNext(q))==k)
2057    {
2058      if (result==NULL)
2059      {
2060        result = pNext(q);
2061        qq = result;
2062      }
2063      else
2064      {
2065        pNext(qq) = pNext(q);
2066        pIter(qq);
2067      }
2068      pNext(q) = pNext(pNext(q));
2069      pNext(qq) =NULL;
2070      pSetComp(qq,0);
2071    }
2072    else
2073    {
2074      pIter(q);
2075//      if (pGetComp(q) > k) pGetComp(q)--;
2076    }
2077  }
2078  return result;
2079}
2080
2081void pDeleteComp(poly * p,int k)
2082{
2083  poly q;
2084
2085  while ((*p!=NULL) && (pGetComp(*p)==k)) pDelete1(p);
2086  if (*p==NULL) return;
2087  q = *p;
2088  if (pGetComp(q)>k) pDecrComp(q);
2089  while (pNext(q)!=NULL)
2090  {
2091    if (pGetComp(pNext(q))==k)
2092      pDelete1(&(pNext(q)));
2093    else
2094    {
2095      pIter(q);
2096      if (pGetComp(q)>k) pDecrComp(q);
2097    }
2098  }
2099}
2100/*----------end of utilities for syzygies--------------*/
2101
2102/*2
2103* pair has no common factor ? or is no polynomial
2104*/
2105BOOLEAN pHasNotCF(poly p1, poly p2)
2106{
2107#ifdef SRING
2108  if (pSRING)
2109    return FALSE;
2110#endif
2111
2112  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
2113    return FALSE;
2114  int i = 1;
2115  loop
2116  {
2117    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
2118    if (i == pVariables)                                return TRUE;
2119    i++;
2120  }
2121}
2122
2123
2124/*2
2125*should return 1 if p divides q and p<q,
2126*             -1 if q divides p and q<p
2127*              0 otherwise
2128*/
2129int     pDivComp(poly p, poly q)
2130{
2131  if (pGetComp(p) == pGetComp(q))
2132  {
2133    int i=pVariables;
2134    long d;
2135    BOOLEAN a=FALSE, b=FALSE;
2136    for (; i>0; i--)
2137    {
2138      d = pGetExpDiff(p, q, i);
2139      if (d)
2140      {
2141        if (d < 0)
2142        {
2143          if (b) return 0;
2144          a =TRUE;
2145        }
2146        else
2147        {
2148          if (a) return 0;
2149          b = TRUE;
2150        }
2151      }
2152    }
2153    if (a) return 1;
2154    else if (b)  return -1;
2155  }
2156  return 0;
2157}
2158/*2
2159*divides p1 by its leading monomial
2160*/
2161void pNorm(poly p1)
2162{
2163  poly h;
2164  number k, c;
2165
2166  if (p1!=NULL)
2167  {
2168    if (!nIsOne(pGetCoeff(p1)))
2169    {
2170      nNormalize(pGetCoeff(p1));
2171      k=pGetCoeff(p1);
2172      c = nInit(1);
2173      pSetCoeff0(p1,c);
2174      h = pNext(p1);
2175      while (h!=NULL)
2176      {
2177        c=nDiv(pGetCoeff(h),k);
2178        if (!nIsOne(c)) nNormalize(c);
2179        pSetCoeff(h,c);
2180        pIter(h);
2181      }
2182      nDelete(&k);
2183    }
2184    else
2185    {
2186      h = pNext(p1);
2187      while (h!=NULL)
2188      {
2189        nNormalize(pGetCoeff(h));
2190        pIter(h);
2191      }
2192    }
2193  }
2194}
2195
2196/*2
2197*normalize all coeffizients
2198*/
2199void pNormalize(poly p)
2200{
2201  while (p!=NULL)
2202  {
2203    nTest(pGetCoeff(p));
2204    nNormalize(pGetCoeff(p));
2205    pIter(p);
2206  }
2207}
2208
2209/*3
2210* substitute the n-th variable by 1 in p
2211* destroy p
2212*/
2213static poly pSubst1 (poly p,int n)
2214{
2215  if (p == NULL) return NULL;
2216  if (pNext(p) == NULL)
2217  {
2218    if (pGetExp(p, n) != 0)
2219    {
2220      pSetExp(p, n, 0);
2221      pSetm(p);
2222    }
2223    return p;
2224  }
2225
2226  int l = pLength(p) - 1;
2227  poly* monoms = (poly*) Alloc(l*sizeof(poly));
2228  int i;
2229 
2230  for (i=0; i<l; i++)
2231  {
2232    if (pGetExp(p, n) != 0)
2233    {
2234      pSetExp(p, n, 0);
2235      pSetm(p);
2236    }
2237    monoms[i] = p;
2238    pIter(p);
2239  }
2240  if (pGetExp(p, n) != 0)
2241  {
2242    pSetExp(p, n, 0);
2243    pSetm(p);
2244  }
2245  for (i = l-1; i >= 0; i--)
2246  {
2247    pNext(monoms[i]) = NULL;
2248    p = pAdd(p, monoms[i]);
2249  }
2250  pTest(p);
2251  Free(monoms, l*sizeof(poly));
2252  return p;
2253}
2254
2255/*3
2256* substitute the n-th variable by number e in p
2257* destroy p
2258*/
2259static poly pSubst2 (poly p,int n, number e)
2260{
2261  number nn, nm;
2262  int exp;
2263  assume( ! nIsZero(e) );
2264 
2265  if (p == NULL) return NULL;
2266  if (pNext(p) == NULL)
2267  {
2268    exp = pGetExp(p, n);
2269    if (exp != 0)
2270    {
2271      nPower(e, exp, &nn);
2272      nm = nMult(nn, pGetCoeff(p));
2273      pSetCoeff(p, nm);
2274      nDelete(&nn);
2275      pSetExp(p, n, 0);
2276      pSetm(p);
2277    }
2278    return p;
2279  }
2280
2281  int l = pLength(p) - 1;
2282  poly* monoms = (poly*) Alloc(l*sizeof(poly));
2283  int i;
2284 
2285  for (i=0; i<l; i++)
2286  {
2287    exp = pGetExp(p, n);
2288    if (exp != 0)
2289    {
2290      nPower(e, exp, &nn);
2291      nm = nMult(nn, pGetCoeff(p));
2292      pSetCoeff(p, nm);
2293      nDelete(&nn);
2294      pSetExp(p, n, 0);
2295      pSetm(p);
2296    }
2297    monoms[i] = p;
2298    pIter(p);
2299  }
2300  exp = pGetExp(p, n);
2301  if (exp != 0)
2302  {
2303    nPower(e, exp, &nn);
2304    nm = nMult(nn, pGetCoeff(p));
2305    pSetCoeff(p, nm);
2306    nDelete(&nn);
2307    pSetExp(p, n, 0);
2308    pSetm(p);
2309  }
2310  for (i = l-1; i >= 0; i--)
2311  {
2312    pNext(monoms[i]) = NULL;
2313    p = pAdd(p, monoms[i]);
2314  }
2315  Free(monoms, l*sizeof(poly));
2316  pTest(p);
2317  return p;
2318}
2319
2320poly pSubst0(poly p, int n)
2321{
2322  spolyrec res;
2323  poly h = &res;
2324  pNext(h) = p;
2325 
2326  while (pNext(h)!=NULL)
2327  {
2328    if (pGetExp(pNext(h),n)!=0)
2329    {
2330      pDelete1(&pNext(h));
2331    }
2332    else
2333    {
2334      pIter(h);
2335    }
2336  }
2337  pTest(pNext(&res));
2338  return pNext(&res);
2339}
2340
2341/*2
2342* substitute the n-th variable by e in p
2343* destroy p
2344*/
2345poly pSubst(poly p, int n, poly e)
2346{
2347  if (e == NULL) return pSubst0(p, n);
2348
2349  if (pIsConstant(e))
2350  {
2351    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
2352    else return pSubst2(p, n, pGetCoeff(e));
2353  }
2354
2355  int exponent,i;
2356  poly h, res, m;
2357  Exponent_t *me,*ee;
2358  number nu,nu1;
2359
2360  me=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
2361  ee=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
2362  if (e!=NULL) pGetExpV(e,ee);
2363  res=NULL;
2364  h=p;
2365  while (h!=NULL)
2366  {
2367    if ((e!=NULL) || (pGetExp(h,n)==0))
2368    {
2369      m=pHead(h);
2370      pGetExpV(m,me);
2371      exponent=me[n];
2372      me[n]=0;
2373      for(i=pVariables;i>0;i--)
2374        me[i]+=exponent*ee[i];
2375      pSetExpV(m,me);
2376      if (e!=NULL)
2377      {
2378        nPower(pGetCoeff(e),exponent,&nu);
2379        nu1=nMult(pGetCoeff(m),nu);
2380        nDelete(&nu);
2381        pSetCoeff(m,nu1);
2382      }
2383      res=pAdd(res,m);
2384    }
2385    pDelete1(&h);
2386  }
2387  Free((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
2388  Free((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
2389  return res;
2390}
2391
2392BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
2393{
2394  int k, j;
2395
2396  if (lcm==NULL) return FALSE;
2397
2398  for (j=pVariables; j; j--)
2399    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
2400  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
2401  for (j=pVariables; j; j--)
2402  {
2403    if (pGetExp(p1,j)!=pGetExp(lcm,j))
2404    {
2405      if (pGetExp(p,j)!=pGetExp(lcm,j))
2406      {
2407        for (k=pVariables; k>j; k--)
2408        {
2409          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2410          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
2411            return TRUE;
2412        }
2413        for (k=j-1; k; k--)
2414        {
2415          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2416          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
2417            return TRUE;
2418        }
2419        return FALSE;
2420      }
2421    }
2422    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
2423    {
2424      if (pGetExp(p,j)!=pGetExp(lcm,j))
2425      {
2426        for (k=pVariables; k>j; k--)
2427        {
2428          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2429          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
2430            return TRUE;
2431        }
2432        for (k=j-1; k!=0 ; k--)
2433        {
2434          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2435          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
2436            return TRUE;
2437        }
2438        return FALSE;
2439      }
2440    }
2441  }
2442  return FALSE;
2443}
2444
2445int pWeight(int i)
2446{
2447  if ((firstwv==NULL) || (i>firstBlockEnds))
2448  {
2449    return 1;
2450  }
2451  return firstwv[i-1];
2452}
Note: See TracBrowser for help on using the repository browser.