source: git/Singular/polys.cc @ 4e46cde

spielwiese
Last change on this file since 4e46cde was 4e46cde, checked in by Olaf Bachmann <obachman@…>, 26 years ago
Tue Dec 16 16:59:41 1997 Olaf Bachmann <obachman@mathematik.uni-kl.de> * polys-impl.h: Introduced COMP_NO_EXP_VECTOR_OPS -- which turns off "vector techniques" of monomial operations, i.e. does everything exponent-wise git-svn-id: file:///usr/local/Singular/svn/trunk@981 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 68.8 KB
Line 
1
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/* $Id: polys.cc,v 1.11 1997-12-16 18:24:00 obachman Exp $ */
6
7/*
8* ABSTRACT - all basic methods to manipulate polynomials
9*/
10
11/* includes */
12#include <stdio.h>
13#include <string.h>
14#include <ctype.h>
15#include "mod2.h"
16#include "tok.h"
17#include "mmemory.h"
18#include "febase.h"
19#include "numbers.h"
20#include "polys.h"
21#include "ring.h"
22#include "binom.h"
23
24#ifdef COMP_FAST
25#include "polys-comp.h"
26#endif
27
28/* ----------- global variables, set by pChangeRing --------------------- */
29/* initializes the internal data from the exp vector */
30pSetmProc pSetm;
31/* computes length and maximal degree of a POLYnomial */
32pLDegProc pLDeg;
33/* computes the degree of the initial term, used for std */
34pFDegProc pFDeg;
35/* the monomial ordering of the head monomials a and b */
36pCompProc pComp0;
37/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
38
39/* the number of variables             */
40/* 1 for polynomial ring, -1 otherwise */
41int     pOrdSgn;
42/* TRUE for momomial output as x2y, FALSE for x^2*y */
43int pShortOut = (int)TRUE;
44// it is of type int, not BOOLEAN because it is also in ip
45/* TRUE if the monomial ordering is not compatible with pFDeg */
46BOOLEAN pLexOrder;
47/* TRUE if the monomial ordering has polynomial and power series blocks */
48BOOLEAN pMixedOrder;
49
50#if defined(TEST_MAC_ORDER) || defined(COMP_FAST)
51int  pComponentOrder;
52#else
53static int  pComponentOrder;
54#endif
55
56#ifdef DRING
57int      p2;
58BOOLEAN  pDRING=FALSE;
59#endif
60
61#ifdef SRING
62int      pAltVars;
63BOOLEAN  pSRING=FALSE;
64#endif
65
66#ifdef SDRING
67BOOLEAN  pSDRING=FALSE;
68#include "polys.inc"
69#endif
70
71/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
72/* the highest monomial below pHEdge */
73poly      ppNoether = NULL;
74
75/* -------------- static variables --------------------------------------- */
76/*is the basic comparing procedure during a computation of syzygies*/
77static pCompProc pCompOld;
78/*for grouping module indecees during computations*/
79#ifndef COMP_FAST
80static int maxBound = 0;
81#else
82int maxBound = 0;
83#endif
84
85/*contains the headterms for the Schreyer orderings*/
86static int* SchreyerOrd;
87static int maxSchreyer=0;
88static int indexShift=0;
89static pLDegProc pLDegOld;
90
91typedef int (*bcompProc)(poly p1, poly p2, int i1, int i2, short * w);
92static bcompProc bcomph[20];
93static short**   polys_wv;
94static short *   firstwv;
95static int * block0;
96static int * block1;
97static int firstBlockEnds;
98static int * order;
99
100/*0 implementation*/
101/*-------- the several possibilities for pSetm:-----------------------*/
102
103/* Remark: These could be made more efficient by avoiding using pGetExp */
104
105/*2
106* define the order of p with respect to lex. ordering, N=1
107*/
108static void setlex1(poly p)
109{
110  p->Order = (Order_t)pGetExp(p,1);
111}
112
113/*2
114* define the order of p with respect to lex. ordering, N>1
115*/
116static void setlex2(poly p)
117{
118  p->Order = (((Order_t)pGetExp(p,1))<<(sizeof(short)*8))
119    + (Order_t)pGetExp(p,2); 
120}
121
122/*2
123* define the order of p with respect to a degree ordering
124*/
125static void setdeg1(poly p)
126{
127  p->Order = pExpQuerSum1(p, firstBlockEnds);
128#ifdef COMP_DEBUG 
129    int i, j = pGetExp(p,1);
130
131  for (i = firstBlockEnds; i>1; i--) j += pGetExp(p,i);
132  if (j != p->Order)
133  {
134    Print("Error in setdeg1");
135    pExpQuerSum1(p, firstBlockEnds);
136  }
137#endif 
138}
139
140/*2
141* define the order of p with respect to a degree ordering
142* with weigthts
143*/
144static void setdeg1w(poly p)
145{
146  Order_t i, j = 0;
147
148  for (i = firstBlockEnds; i>0; i--)
149  {
150     j += ((Order_t) pGetExp(p,i))*firstwv[i-1];
151  }
152  p->Order = j;
153}
154
155
156/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
157
158
159/***************************************************************
160 *************************************************************** 
161 *
162 * MONOMIAL COMPARIONS:
163 * They are influenced by the following macros:
164 * COMP_TRADITIONAL -- (un)set in polys-impl.h
165     Keeps the traditional comparison routines
166     defined -- needed as long as their might be comparisons with
167     negativ components.
168     All the traditional routines are prefixed by t_
169     
170 * COMP_FAST -- (un)set in polys-impl.h
171     Implements monomial comparisons using the fast
172     techniques. Undefine in case there are problems. All the fast
173     routines are prefixed by f_
174     
175 * COMP_STATISTIC -- (un)set in polys-impl.h
176     Provides several routines for accumulating statistics on monomial
177     comparisons
178     
179 * COMP_DEBUG -- (un)set in polys-impl.h
180     Turns on debugging of COMP_FAST by comparing the resutsl of fast
181     comparison with traditional comparison
182
183 *   
184 *
185 *************************************************************** 
186 ***************************************************************/
187
188#ifdef COMP_DEBUG
189static int debug_comp(poly p1, poly p2);
190#endif // COMP_DEBUG
191
192#ifdef COMP_STATISTICS
193// Initializes, resets and outputs Comp statistics
194void InitCompStatistics(int nvars);
195void ResetCompStatistics();
196void OutputCompStatistics();
197unsigned long MonomCountTotal = 0;
198unsigned long MonomCountOrderS = 0;
199unsigned long MonomCountOrderG = 0;
200unsigned long* MonomCountExp = NULL;
201unsigned long MonomCountExpS = 0;
202unsigned long MonomCountExpG = 0;
203unsigned long MonomCountCompS = 0;
204unsigned long MonomCountCompG = 0;
205unsigned long MonomCountEqual = 0;
206#endif // COMP_STATISTICS
207
208
209#define NonZeroR(l, actionG, actionS)           \
210do                                              \
211{                                               \
212  long _l = l;                                  \
213  if (_l)                                       \
214  {                                             \
215    if (_l > 0) actionG;                        \
216    actionS;                                    \
217  }                                             \
218}                                               \
219while(0)
220 
221/***************************************************************
222 *
223 * FAST COMPARISONS
224 *
225 ***************************************************************/
226#ifdef COMP_FAST
227static pCompProc f_pComp0 = NULL;
228static int f_comp_1(poly p1, poly p2);
229static int f_comp_c_1(poly p1, poly p2);
230static int f_comp_1_c(poly p1, poly p2);
231static int f_comp_2(poly p1, poly p2);
232static int f_comp_c_2(poly p1, poly p2);
233static int f_comp_2_c(poly p1, poly p2);
234static int f_comp_2i(poly p1, poly p2);
235static int f_comp_c_2i(poly p1, poly p2);
236static int f_comp_2i_c(poly p1, poly p2);
237static int f_comp_2i_1(poly p1, poly p2);
238static int f_comp_c_2i_1(poly p1, poly p2);
239static int f_comp_2i_1_c(poly p1, poly p2);
240
241#define Mreturn(d, multiplier)                      \
242{                                                   \
243  if (d > 0) return multiplier;                     \
244  return -multiplier;                               \
245}                                               
246 
247// comp_1 is used if pVariables1W == 1 and component is compatible with ordering
248static int f_comp_1(poly p1, poly p2) 
249{
250  register long d = pGetOrder(p1) - pGetOrder(p2);
251
252  if (d) Mreturn(d, pOrdSgn);
253  _pMonCmp_1(p1, p2, d, goto NotEqual, return 0);
254
255  NotEqual:
256  Mreturn(d, pLexSgn);
257}
258
259// comp_1_c is used if pVariables1W == 1, priority is given to exponents,
260// component is incompatible with ordering
261static int f_comp_1_c(poly p1, poly p2) 
262{
263  register long d = pGetOrder(p1) - pGetOrder(p2);
264
265  if (d) Mreturn(d, pOrdSgn);
266  _pMonCmp_1_c(p1, p2, d, goto NotEqual , return 0);
267
268  NotEqual:
269  Mreturn(d, pLexSgn)
270}
271
272// comp_1_c is used if pVariables1W == 1, priority is given to component,
273// component is incompatible with ordering
274static int f_comp_c_1(poly p1, poly p2) 
275{
276  register long d = pGetComp(p2) - pGetComp(p1);
277  if (d) Mreturn(d, pComponentOrder);
278  d = pGetOrder(p1) - pGetOrder(p2);
279  if (d) Mreturn(d, pOrdSgn);
280  _pMonCmp_1(p1, p2, d, goto NotEqual , return 0);
281 
282  NotEqual:
283  Mreturn(d, pLexSgn);
284}
285
286// comp_2 is used if pVariables1W == 2 and component is compatible with ordering
287static int f_comp_2(poly p1, poly p2) 
288{
289  register long d = pGetOrder(p1) - pGetOrder(p2);
290
291  if (d) Mreturn(d, pOrdSgn);
292  _pMonCmp_2(p1, p2, d, goto NotEqual , return 0);
293
294  NotEqual:
295  Mreturn(d, pLexSgn);
296}
297
298// comp_2_c is used if pVariables1W == 2, priority is given to exponents,
299// component is incompatible with ordering
300static int f_comp_2_c(poly p1, poly p2) 
301{
302  register long d = pGetOrder(p1) - pGetOrder(p2);
303
304  if (d) Mreturn(d, pOrdSgn);
305  _pMonCmp_2_c(p1, p2, d, goto NotEqual, return 0);
306
307  NotEqual:
308  Mreturn(d, pLexSgn);
309}
310
311// comp_2_c is used if pVariables1W == 2, priority is given to component,
312// component is incompatible with ordering
313static int f_comp_c_2(poly p1, poly p2) 
314{
315  register long d = pGetComp(p2) - pGetComp(p1);
316  if (d) Mreturn(d, pComponentOrder);
317  d = pGetOrder(p1) - pGetOrder(p2);
318  if (d) Mreturn(d, pOrdSgn);
319  _pMonCmp_2(p1, p2, d, goto NotEqual , return 0);
320 
321  NotEqual:
322  Mreturn(d, pLexSgn);
323}
324
325// comp_2i is used if pVariables1W == 2*i and component is compatible
326// with ordering
327static int f_comp_2i(poly p1, poly p2) 
328{
329  register long d = pGetOrder(p1) - pGetOrder(p2);
330
331  if (d) Mreturn(d, pOrdSgn);
332  _pMonCmp_2i(p1, p2, pVariables1W, d, goto NotEqual , return 0);
333
334  NotEqual:
335  Mreturn(d, pLexSgn);
336}
337
338// comp_2i_c is used if pVariables1W == 2*i, priority is given to exponents,
339// component is incompatible with ordering
340static int f_comp_2i_c(poly p1, poly p2) 
341{
342  register long d = pGetOrder(p1) - pGetOrder(p2);
343
344  if (d) Mreturn(d, pOrdSgn);
345  _pMonCmp_2i_c(p1, p2, pVariables1W, d, goto NotEqual , return 0);
346
347  NotEqual:
348  Mreturn(d, pLexSgn);
349}
350
351// comp_2i_c is used if pVariables1W == 2*i, priority is given to component,
352// component is incompatible with ordering
353static int f_comp_c_2i(poly p1, poly p2) 
354{
355  register long d = pGetComp(p2) - pGetComp(p1);
356  if (d) Mreturn(d, pComponentOrder);
357  d = pGetOrder(p1) - pGetOrder(p2);
358  if (d) Mreturn(d, pOrdSgn);
359  _pMonCmp_2i(p1, p2, pVariablesW, d, goto NotEqual, return 0);
360 
361  NotEqual:
362  Mreturn(d, pLexSgn);
363}
364
365// comp_2i_1 is used if pVariables1W == 2*i and component is compatible
366// with ordering
367static int f_comp_2i_1(poly p1, poly p2) 
368{
369  register long d = pGetOrder(p1) - pGetOrder(p2);
370
371  if (d) Mreturn(d, pOrdSgn);
372  _pMonCmp_2i_1(p1, p2, pVariables1W, d, goto NotEqual, return 0);
373
374  NotEqual:
375  Mreturn(d, pLexSgn);
376}
377
378// comp_2i_1_c is used if pVariables1W == 2*i, priority is given to exponents,
379// component is incompatible with ordering
380static int f_comp_2i_1_c(poly p1, poly p2) 
381{
382  register long d = pGetOrder(p1) - pGetOrder(p2);
383  if (d) 
384  {
385    if (d > 0) return pOrdSgn;
386    return -pOrdSgn;
387  }
388 
389  _pMonCmp_2i_1_c(p1, p2, pVariables1W, d, goto NotEqual , return 0);
390 
391  NotEqual:
392  Mreturn(d, pLexSgn);
393}
394
395// comp_c_2i_1 is used if pVariables1W == 2*i, priority is given to component,
396// component is incompatible with ordering
397static int f_comp_c_2i_1(poly p1, poly p2) 
398{
399  register long d = pGetComp(p2) - pGetComp(p1);
400  if (d) Mreturn(d, pComponentOrder);
401  d = pGetOrder(p1) - pGetOrder(p2);
402  if (d) Mreturn(d, pOrdSgn);
403  _pMonCmp_2i_1(p1, p2, pVariablesW, d, goto NotEqual, return 0);
404 
405  NotEqual:
406  Mreturn(d, pLexSgn);
407}
408#endif // COMP_FAST
409
410/***************************************************************
411 *
412 * FAST COMPARISONS
413 *
414 ***************************************************************/
415#ifdef COMP_TRADITIONAL
416
417pCompProc t_pComp0;
418
419static int t_comp_c_1(poly p1, poly p2);
420static int t_comp_1_c(poly p1, poly p2);
421static int t_comp_lex_c_i(poly p1, poly p2);
422static int t_comp_c_lex_i(poly p1, poly p2);
423static int t_comp_revlex_c_i(poly p1, poly p2);
424static int t_comp_c_revlex_i(poly p1, poly p2);
425
426inline long LexComp(poly p1, poly p2)
427{
428  long d, i;
429  for (i=1; i<pVariables; i++)
430  {
431    d = pGetExpDiff(p1, p2, i);
432    if (d) return d;
433  }
434  return pGetExpDiff(p1, p2, pVariables);
435}
436
437inline long RevLexComp(poly p1, poly p2)
438{
439  long d, i;
440  for (i=pVariables; i>1; i--)
441  {
442    d = pGetExpDiff(p1, p2, i);
443    if (d) return d;
444  }
445  return pGetExpDiff(p1, p2, 1);
446}
447
448static int t_comp_c_1(poly p1, poly p2)
449{
450  NonZeroR(pGetComp(p1) - pGetComp(p2),
451           return -pComponentOrder, return pComponentOrder);
452  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
453  return 0;
454}
455
456static int t_comp_1_c(poly p1, poly p2)
457{
458  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
459  NonZeroR(pGetComp(p1) - pGetComp(p2),
460           return -pComponentOrder, return pComponentOrder);
461  return 0;
462}
463
464static int t_comp_lex_c_i(poly p1, poly p2)
465{
466  NonZeroR(pGetComp(p1) - pGetComp(p2),
467           return -pComponentOrder, return pComponentOrder);
468  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
469  NonZeroR(LexComp(p1, p2), return pLexSgn, return -pLexSgn);
470  return 0;
471}
472
473static int t_comp_lex_i_c(poly p1, poly p2)
474{
475  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
476  NonZeroR(LexComp(p1, p2), return pLexSgn, return -pLexSgn);
477  NonZeroR(pGetComp(p1) - pGetComp(p2),
478           return -pComponentOrder, return pComponentOrder);
479  return 0;
480}
481
482static int t_comp_revlex_c_i(poly p1, poly p2)
483{
484  NonZeroR(pGetComp(p1) - pGetComp(p2),
485           return -pComponentOrder, return pComponentOrder);
486  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
487  NonZeroR(RevLexComp(p1, p2), return pLexSgn, return -pLexSgn);
488  return 0;
489}
490
491static int t_comp_revlex_i_c(poly p1, poly p2)
492{
493  NonZeroR(pGetOrder(p1) - pGetOrder(p2), return pOrdSgn, return -pOrdSgn);
494  NonZeroR(RevLexComp(p1, p2), return pLexSgn, return -pLexSgn);
495  NonZeroR(pGetComp(p1) - pGetComp(p2),
496           return -pComponentOrder, return pComponentOrder);
497  return 0;
498}
499
500#endif // COMP_TRADITIONAL
501
502/*2
503* compare the head monomial of p1 and p2 with weight vector
504*/
505static int comp1a  ( poly p1, poly p2, int f, int l, short * w )
506{
507  int d= p1->Order - p2->Order;
508  if ( d > 0 /*p1->Order > p2->Order*/ )
509    return 1;
510  else if ( d < 0 /*p1->Order < p2->Order*/ )
511    return -1;
512  return 0;
513}
514
515
516/*---------------------------------------------------*/
517
518/* These functions could be made faster if you use pointers to the
519* exponent vectors and pointer arithmetic instead of using the
520* macro pGetExp !!!
521*/
522
523/*2
524* compare the head monomial of p1 and p2 with lexicographic ordering
525*/
526static int comp_lp ( poly p1, poly p2, int f, int l, short * w )
527{
528  int i = f;
529  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
530    i++;
531  if ( i > l )
532    return 0;
533  if ( pGetExp(p1,i) > pGetExp(p2,i) )
534    return 1;
535  return -1;
536}
537
538/*2
539* compare the head monomial of p1 and p2 with degree reverse lexicographic
540* ordering
541*/
542static int comp_dp ( poly p1, poly p2, int f, int l, short * w )
543{
544  int i, s1 = 0, s2 = 0;
545
546  for ( i = f; i <= l; i++ )
547  {
548    s1 += pGetExp(p1,i);
549    s2 += pGetExp(p2,i);
550  }
551  if ( s1 == s2 )
552  {
553    i = l;
554    while ( (i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
555      i--;
556    if ( i < f )
557      return 0;
558    if ( pGetExp(p1,i) > pGetExp(p2,i) )
559      return -1;
560    return 1;
561  }
562  if ( s1 > s2 )
563    return 1;
564  return -1;
565}
566
567/*2
568* compare the head monomial of p1 and p2 with degree lexicographic ordering
569*/
570static int comp_Dp ( poly p1, poly p2, int f, int l, short * w )
571{
572  int i, s1 = 0, s2 = 0;
573
574  for ( i = f; i <= l; i++ )
575  {
576    s1 += pGetExp(p1,i);
577    s2 += pGetExp(p2,i);
578  }
579  if ( s1 == s2 )
580  {
581    i = f;
582    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
583      i++;
584    if ( i > l )
585      return 0;
586    if ( pGetExp(p1,i) > pGetExp(p2,i) )
587      return 1;
588    return -1;
589  }
590  if ( s1 > s2 )
591    return 1;
592  return -1;
593}
594
595/*2
596* compare the head monomial of p1 and p2 with weighted degree reverse
597* lexicographic ordering
598*/
599static int comp_wp ( poly p1, poly p2, int f, int l, short * w )
600{
601  int i, s1 = 0, s2 = 0;
602
603  for ( i = f; i <= l; i++, w++ )
604  {
605    s1 += (int)pGetExp(p1,i)*(*w);
606    s2 += (int)pGetExp(p2,i)*(*w);
607  }
608  if ( s1 == s2 )
609  {
610    i = l;
611    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
612      i--;
613    if ( i < f )
614      return 0;
615    if ( pGetExp(p1,i) > pGetExp(p2,i) )
616      return -1;
617    return 1;
618  }
619  if ( s1 > s2 )
620    return 1;
621  return -1;
622}
623
624/*2
625* compare the head monomial of p1 and p2 with weighted degree lexicographic
626* ordering
627*/
628static int comp_Wp ( poly p1, poly p2, int f, int l, short * w )
629{
630  int i, s1 = 0, s2 = 0;
631
632  for ( i = f; i <= l; i++, w++ )
633  {
634    s1 += (int)pGetExp(p1,i)*(*w);
635    s2 += (int)pGetExp(p2,i)*(*w);
636  }
637  if ( s1 == s2 )
638  {
639    i = f;
640    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
641      i++;
642    if ( i > l )
643      return 0;
644    if ( pGetExp(p1,i) > pGetExp(p2,i) )
645      return 1;
646    return -1;
647  }
648  if ( s1 > s2 )
649    return 1;
650  return -1;
651}
652
653/*2
654* compare the head monomial of p1 and p2 with lexicographic ordering
655* (power series case)
656*/
657static int comp_ls ( poly p1, poly p2, int f, int l, short * w )
658{
659  int i;
660
661  i = f;
662  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
663    i++;
664  if ( i > l )
665    return 0;
666  if ( pGetExp(p1,i) < pGetExp(p2,i) )
667    return 1;
668  return -1;
669}
670
671/*2
672* compare the head monomial of p1 and p2 with degree reverse lexicographic
673* ordering (power series case)
674*/
675static int comp_ds ( poly p1, poly p2, int f, int l, short * w )
676{
677  int i, s1 = 0, s2 = 0;
678
679  for ( i = f; i <= l; i++ )
680  {
681    s1 += pGetExp(p1,i);
682    s2 += pGetExp(p2,i);
683  }
684  if ( s1 == s2 )
685  {
686    i = l;
687    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
688      i--;
689    if ( i < f )
690      return 0;
691    if ( pGetExp(p1,i) < pGetExp(p2,i) )
692      return 1;
693    return -1;
694  }
695  if ( s1 < s2 )
696    return 1;
697  return -1;
698}
699
700/*2
701* compare the head monomial of p1 and p2 with degree lexicographic ordering
702* (power series case)
703*/
704static int comp_Ds ( poly p1, poly p2, int f, int l, short * w )
705{
706  int i, s1 = 0, s2 = 0;
707
708  for ( i = f; i <= l; i++ )
709  {
710    s1 += pGetExp(p1,i);
711    s2 += pGetExp(p2,i);
712  }
713  if ( s1 == s2 )
714  {
715    i = f;
716    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
717      i++;
718    if ( i > l )
719      return 0;
720    if ( pGetExp(p1,i) < pGetExp(p2,i) )
721      return -1;
722    return 1;
723  }
724  if ( s1 < s2 )
725    return 1;
726  return -1;
727}
728
729/*2
730* compare the head monomial of p1 and p2 with weighted degree reverse
731* lexicographic ordering (power series case)
732*/
733static int comp_ws ( poly p1, poly p2, int f, int l, short * w )
734{
735  int i, s1 = 0, s2 = 0;
736
737  for ( i = f; i <= l; i++, w++ )
738  {
739    s1 += (int)pGetExp(p1,i)*(*w);
740    s2 += (int)pGetExp(p2,i)*(*w);
741  }
742  if ( s1 == s2 )
743  {
744    i = l;
745    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
746      i--;
747    if ( i < f )
748      return 0;
749    if ( pGetExp(p1,i) < pGetExp(p2,i) )
750      return 1;
751    return -1;
752  }
753  if ( s1 < s2 )
754    return 1;
755  return -1;
756}
757
758/*2
759* compare the head monomial of p1 and p2 with weighted degree lexicographic
760* ordering (power series case)
761*/
762static int comp_Ws ( poly p1, poly p2, int f, int l, short * w )
763{
764  int i, s1 = 0, s2 = 0;
765
766  for ( i = f; i <= l; i++, w++ )
767  {
768    s1 += (int)pGetExp(p1,i)*(*w);
769    s2 += (int)pGetExp(p2,i)*(*w);
770  }
771  if ( s1 == s2 )
772  {
773    i = f;
774    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
775      i++;
776    if ( i > l )
777      return 0;
778    if ( pGetExp(p1,i) < pGetExp(p2,i) )
779      return -1;
780    return 1;
781  }
782  if ( s1 < s2 )
783    return 1;
784  return -1;
785}
786
787/*2
788* compare the head monomial of p1 and p2 with matrix order
789* w contains a series of l-f+1 lines
790*/
791static int comp_M ( poly p1, poly p2, int f, int l, short * w )
792{
793  int i, j, s1, s2;
794
795  for ( i = f; i <= l; i++ )
796  {
797    s1 = s2 = 0;
798    for ( j = f; j <= l; j++, w++ )
799    {
800      s1 += (int)pGetExp(p1,j)*(int)(*w);
801      s2 += (int)pGetExp(p2,j)*(int)(*w);
802    }
803    if ( s1 < s2 )
804      return -1;
805    if ( s1 > s2 )
806      return 1;
807    /* now w points to the last element of the current row, the next w++ */
808    /* moves on to the first element of the next row ! */
809  }
810  return 0;
811}
812
813/*2
814* compare the head monomial of p1 and p2 with weight vector
815*/
816static int comp_a  ( poly p1, poly p2, int f, int l, short * w )
817{
818  int i, s1 = 0, s2 = 0;
819
820  for ( i = f; i <= l; i++, w++ )
821  {
822    s1 += (int)pGetExp(p1,i)*(*w);
823    s2 += (int)pGetExp(p2,i)*(*w);
824  }
825  if ( s1 > s2 )
826    return 1;
827  if ( s1 < s2 )
828    return -1;
829  return 0;
830}
831
832/*2
833* compare the head monomial of p1 and p2 with module component
834*/
835static int comp_c  ( poly p1, poly p2, int f, int l, short * w )
836{
837  if ( pGetComp(p1) > pGetComp(p2) )
838    return -pComponentOrder;
839  if ( pGetComp(p1) < pGetComp(p2) )
840    return pComponentOrder;
841  return 0;
842}
843
844/*---------------------------------------------------------------*/
845
846/*2
847* compare p1 and p2 by a block ordering
848* uses (*bcomph[])() to do the real work
849*/
850static int BlockComp(poly p1, poly p2)
851{
852  int res, i, e, a;
853
854  /*4 compare in all blocks,*
855  * each block has var numbers a(=block0[i]) to e (=block1[i])*
856  * the block number starts with 0*/
857  e = 0;
858  i = 0;
859  loop
860  {
861    a = block0[i];
862    e = block1[i];
863    res = (*bcomph[i])(p1, p2, a, e , polys_wv[i]);
864    if (res)
865      return res;
866    i++;
867    if (order[i]==0)
868      break;
869  }
870  return 0;
871}
872
873int pComp(poly p1, poly p2)
874{
875  if (p2==NULL)
876    return 1;
877  if (p1==NULL)
878    return -1;
879  return pComp0(p1,p2);
880}
881
882/*----------pComp handling for syzygies---------------------*/
883static void newHeadsB(polyset actHeads,int length)
884{
885  int i;
886  int* newOrder=(int*)Alloc(length*sizeof(int));
887
888  for (i=0;i<length;i++)
889  {
890    if (actHeads[i])
891    {
892      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
893    }
894    else
895    {
896      newOrder[i]=0;
897    }
898  }
899  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
900  SchreyerOrd = newOrder;
901  maxSchreyer = length;
902/*
903*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
904*PrintLn();
905*/
906}
907
908int mcompSchrB(poly p1,poly p2)
909{
910  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
911      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
912
913  if (CompP1==CompP2) return pCompOld(p1,p2);
914  pSetComp(p1,cP1);
915  pSetComp(p2,cP2);
916  result = pCompOld(p1,p2);
917  pSetComp(p1,CompP1);
918  pSetComp(p2,CompP2);
919  if (!result)
920  {
921    if (CompP1>CompP2)
922      return -1;
923    else if (CompP1<CompP2)
924      return 1;
925  }
926  return result;
927}
928
929
930static void newHeadsM(polyset actHeads,int length)
931{
932  int i;
933  int* newOrder=
934    (int*)Alloc((length+maxSchreyer-indexShift)*sizeof(int));
935
936  for (i=0;i<length+maxSchreyer-indexShift;i++)
937    newOrder[i]=0;
938  for (i=indexShift;i<maxSchreyer;i++)
939  {
940    newOrder[i-indexShift] = SchreyerOrd[i];
941    SchreyerOrd[i] = 0;
942  }
943  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
944    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
945  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
946  SchreyerOrd = newOrder;
947  indexShift = maxSchreyer-indexShift;
948  maxSchreyer = length+indexShift;
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 and the module component
955* has to be <= indexShift
956*/
957static int ldegSchrM(poly p,int *l)
958{
959  int  t,max;
960
961  (*l)=1;
962  max=pFDeg(p);
963  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
964  {
965    pIter(p);
966    t=pFDeg(p);
967    if (t>max) max=t;
968    (*l)++;
969  }
970  return max;
971}
972
973int mcompSchrM(poly p1,poly p2)
974{
975  if ( pGetComp(p1)<=indexShift)
976  {
977    if ( pGetComp(p2)>indexShift) return 1;
978  }
979  else if ( pGetComp(p2)<=indexShift)  return -1;
980  return mcompSchrB(p1,p2);
981}
982
983void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
984{
985  int i;
986
987  if (length!=0)
988  {
989    if (maxSchreyer!=0)
990      newHeadsM(nextOrder, length);
991    else
992    {
993      indexShift = comps;
994      if (!indexShift) indexShift = 1;
995      SchreyerOrd = (int*)Alloc((indexShift+length)*sizeof(int));
996      maxSchreyer = length+indexShift;
997      for (i=0;i<indexShift;i++)
998        SchreyerOrd[i] = i;
999      for (i=indexShift;i<maxSchreyer;i++)
1000        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
1001#ifdef COMP_DEBUG     
1002      pCompOld = t_pComp0;
1003#else
1004      pCompOld = pComp0;
1005#endif     
1006      pComp0 = mcompSchrM;
1007      t_pComp0 = mcompSchrM;
1008      pLDegOld = pLDeg;
1009      pLDeg = ldegSchrM;
1010    }
1011  }
1012  else
1013  {
1014    if (maxSchreyer!=0)
1015    {
1016      Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
1017      maxSchreyer = 0;
1018      indexShift = 0;
1019#ifdef COMP_DEBUG
1020      pComp0 = debug_comp;
1021#else
1022      pComp0 = pCompOld;
1023#endif     
1024      t_pComp0 = pCompOld;
1025      pLDeg = pLDegOld;
1026    }
1027  }
1028}
1029
1030/*2
1031*the pComp0 for normal syzygies
1032*compares monomials in the usual ring order (pCompOld)
1033*but groups module indecees according indexBounds befor
1034*/
1035static int mcompSyz(poly p1,poly p2)
1036{
1037  if (pGetComp(p1)<=maxBound)
1038  {
1039    if (pGetComp(p2)>maxBound) return 1;
1040  }
1041  else if (pGetComp(p2)<=maxBound)
1042  {
1043    return -1;
1044  }
1045  return pCompOld(p1,p2);
1046}
1047
1048void pSetSyzComp(int k)
1049{
1050  if (k!=0)
1051  {
1052    if (maxBound==0)
1053    {
1054#ifdef COMP_DEBUG
1055      pCompOld = t_pComp0;
1056      pComp0 = mcompSyz;
1057      t_pComp0 = mcompSyz;
1058#else
1059      pCompOld = pComp0;
1060      pComp0 = mcompSyz;
1061      t_pComp0 = mcompSyz;
1062#endif
1063    }
1064    maxBound = k;
1065  }
1066  else
1067  {
1068    if (maxBound!=0)
1069    {
1070#ifdef COMP_DEBUG
1071      pComp0 = debug_comp;
1072#else
1073      pComp0 = pCompOld;
1074#endif     
1075      t_pComp0 = pCompOld;
1076      maxBound = 0;
1077    }
1078  }
1079}
1080
1081/*2
1082* the type of the module ordering: C: -1, c: 1
1083*/
1084int pModuleOrder()
1085{
1086  return pComponentOrder;
1087}
1088
1089/* -------------------------------------------------------------------*/
1090/* several possibilities for pFDeg: the degree of the head term       */
1091/*2
1092* compute the degree of the leading monomial of p
1093* the ordering is compatible with degree, use a->order
1094*/
1095int pDeg(poly a)
1096{
1097  return ((a!=NULL) ? (a->Order) : (-1));
1098}
1099
1100/*2
1101* compute the degree of the leading monomial of p
1102* with respect to weigths 1
1103* (all are 1 so save multiplications or they are of different signs)
1104* the ordering is not compatible with degree so do not use p->Order
1105*/
1106int pTotaldegree(poly p)
1107{
1108  return pExpQuerSum(p); 
1109}
1110
1111/*2
1112* compute the degree of the leading monomial of p
1113* with respect to weigths from the ordering
1114* the ordering is not compatible with degree so do not use p->Order
1115*/
1116int pWTotaldegree(poly p)
1117{
1118  int i, k;
1119  int j =0;
1120
1121  // iterate through each block:
1122  for (i=0;order[i]!=0;i++)
1123  {
1124    switch(order[i])
1125    {
1126      case ringorder_wp:
1127      case ringorder_ws:
1128      case ringorder_Wp:
1129      case ringorder_Ws:
1130        for (k=block0[i];k<=block1[i];k++)
1131        { // in jedem block:
1132          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
1133        }
1134        break;
1135      case ringorder_M:
1136      case ringorder_lp:
1137      case ringorder_dp:
1138      case ringorder_ds:
1139      case ringorder_Dp:
1140      case ringorder_Ds:
1141        for (k=block0[i];k<=block1[i];k++)
1142        {
1143          j+= pGetExp(p,k);
1144        }
1145        break;
1146      case ringorder_c:
1147      case ringorder_C:
1148        break;
1149      case ringorder_a:
1150        for (k=block0[i];k<=block1[i];k++)
1151        { // only one line
1152          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
1153        }
1154        return j;
1155    }
1156  }
1157  return  j;
1158}
1159/* ---------------------------------------------------------------------*/
1160/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
1161/*  compute in l also the pLength of p                                   */
1162
1163/*2
1164* compute the length of a polynomial (in l)
1165* and the degree of the monomial with maximal degree: the last one
1166*/
1167static int ldeg0(poly p,int *l)
1168{
1169  Exponent_t k= pGetComp(p);
1170  int ll=1;
1171
1172  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
1173  {
1174    pIter(p);
1175    ll++;
1176  }
1177  *l=ll;
1178  return (p->Order);
1179}
1180
1181/*2
1182* compute the length of a polynomial (in l)
1183* and the degree of the monomial with maximal degree: the last one
1184* but search in all components before syzcomp
1185*/
1186static int ldeg0c(poly p,int *l)
1187{
1188  int o=pFDeg(p);
1189  int ll=1;
1190
1191  if (maxBound/*syzComp*/==0)
1192  {
1193    while ((p=pNext(p))!=NULL)
1194    {
1195      o=pFDeg(p);
1196      ll++;
1197    }
1198  }
1199  else
1200  {
1201    while ((p=pNext(p))!=NULL)
1202    {
1203      if (pGetComp(p)<=maxBound/*syzComp*/)
1204      {
1205        o=pFDeg(p);
1206        ll++;
1207      }
1208      else break;
1209    }
1210  }
1211  *l=ll;
1212  return o;
1213}
1214
1215/*2
1216* compute the length of a polynomial (in l)
1217* and the degree of the monomial with maximal degree: the first one
1218* this works for the polynomial case with degree orderings
1219* (both c,dp and dp,c)
1220*/
1221static int ldegb(poly p,int *l)
1222{
1223  Exponent_t k= pGetComp(p);
1224  int o = p->Order;
1225  int ll=1;
1226
1227  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
1228  {
1229    ll++;
1230  }
1231  *l=ll;
1232  return o;
1233}
1234
1235/*2
1236* compute the length of a polynomial (in l)
1237* and the degree of the monomial with maximal degree:
1238* this is NOT the last one, we have to look for it
1239*/
1240static int ldeg1(poly p,int *l)
1241{
1242  Exponent_t k= pGetComp(p);
1243  int ll=1;
1244  int  t,max;
1245
1246  max=pFDeg(p);
1247  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
1248  {
1249    t=pFDeg(p);
1250    if (t>max) max=t;
1251    ll++;
1252  }
1253  *l=ll;
1254  return max;
1255}
1256
1257/*2
1258* compute the length of a polynomial (in l)
1259* and the degree of the monomial with maximal degree:
1260* this is NOT the last one, we have to look for it
1261* in all components
1262*/
1263static int ldeg1c(poly p,int *l)
1264{
1265  int ll=1;
1266  int  t,max;
1267
1268  max=pFDeg(p);
1269  while ((p=pNext(p))!=NULL)
1270  {
1271    if ((maxBound/*syzComp*/==0) || (pGetComp(p)<=maxBound/*syzComp*/))
1272    {
1273       if ((t=pFDeg(p))>max) max=t;
1274       ll++;
1275    }
1276    else break;
1277  }
1278  *l=ll;
1279  return max;
1280}
1281
1282/* -------------------------------------------------------- */
1283/* set the variables for a choosen ordering                 */
1284
1285
1286/*2
1287* sets the comparision routine for monomials: for the first block
1288* of variables (or is the number of the ordering)
1289*/
1290#ifdef COMP_FAST
1291static void SimpleChoose(int or, int comp_order, pCompProc *p)
1292#else 
1293static void SimpleChoose(int or, pCompProc *p)
1294#endif 
1295{
1296#ifdef COMP_TRADITIONAL
1297  if (pVariables <= 1)
1298  {
1299    t_pComp0 = t_comp_1_c;
1300  }
1301  else
1302  {
1303    switch(or)
1304    {
1305        case ringorder_lp:
1306        case ringorder_Dp:
1307        case ringorder_Wp:
1308        case ringorder_Ds:
1309        case ringorder_Ws:
1310        case ringorder_ls:
1311          t_pComp0 = t_comp_lex_i_c;
1312          pLexSgn = 1;
1313          break;
1314
1315#ifdef PDEBUG
1316        case ringorder_unspec:
1317        case ringorder_dp:
1318        case ringorder_wp:
1319        case ringorder_ds:
1320        case ringorder_ws:
1321#else
1322        default:
1323#endif     
1324          t_pComp0 = t_comp_revlex_i_c;
1325          pLexSgn = -1;
1326          break;
1327#ifdef PDEBUG
1328        default:
1329          Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1330#endif
1331    }
1332  }
1333  if (or == ringorder_lp || or == ringorder_ls)
1334  {
1335      pLexOrder=TRUE;
1336      pFDeg = pTotaldegree;
1337      pLDeg = ldeg1c;
1338      if (or == ringorder_ls) pLexSgn = -1;
1339  }
1340 
1341  *p = t_pComp0;
1342#endif
1343#ifdef COMP_FAST
1344  switch(or)
1345  {
1346      case ringorder_dp:
1347      case ringorder_wp:
1348      case ringorder_ds:
1349      case ringorder_ws:
1350      case ringorder_ls:
1351      case ringorder_unspec:
1352        pSetVarIndicies_RevLex(pVariables);
1353        pLexSgn = -1;
1354        if (comp_order == ringorder_C || or == ringorder_unspec)
1355        {
1356          if (pVariables1W == 1)
1357            f_pComp0 = f_comp_1_c;
1358          else if (pVariables1W == 2)
1359            f_pComp0 = f_comp_2_c;
1360          else if (pVariables1W & 1)
1361            f_pComp0 = f_comp_2i_1_c;
1362          else
1363            f_pComp0 = f_comp_2i_c;
1364        }
1365        else
1366        {
1367          if (pVariables1W == 1)
1368            f_pComp0 = f_comp_1;
1369          else if (pVariables1W == 2)
1370            f_pComp0 = f_comp_2;
1371          else if (pVariables1W & 1)
1372            f_pComp0 = f_comp_2i_1;
1373          else
1374            f_pComp0 = f_comp_2i;
1375        }
1376        break;
1377       
1378#ifdef PDEBUG
1379      case ringorder_lp:
1380      case ringorder_Dp:
1381      case ringorder_Wp:
1382      case ringorder_Ds:
1383      case ringorder_Ws:
1384#else
1385      default:
1386#endif
1387        pSetVarIndicies_Lex(pVariables);
1388        pLexSgn = 1;
1389        if (comp_order == ringorder_c)
1390        {
1391          if (pVariables1W == 1)
1392            f_pComp0 = f_comp_1_c;
1393          else if (pVariables1W == 2)
1394            f_pComp0 = f_comp_2_c;
1395          else if (pVariables1W & 1)
1396            f_pComp0 = f_comp_2i_1_c;
1397          else
1398            f_pComp0 = f_comp_2i_c;
1399        }
1400        else
1401        {
1402          if (pVariables1W == 1)
1403            f_pComp0 = f_comp_1;
1404          else if (pVariables1W == 2)
1405            f_pComp0 = f_comp_2;
1406          else if (pVariables1W & 1)
1407            f_pComp0 = f_comp_2i_1;
1408          else
1409            f_pComp0 = f_comp_2i;
1410        }
1411#ifdef PDEBUG
1412        break;
1413      default:
1414        Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1415#endif
1416  }
1417 
1418  if (or == ringorder_lp || or == ringorder_ls)
1419  {
1420    pLexOrder=TRUE;
1421    pFDeg = pTotaldegree;
1422    pLDeg = ldeg1c;
1423    if (or == ringorder_ls)
1424      pSetVarIndicies_Lex(pVariables);
1425  }
1426  *p = f_pComp0;
1427#endif // COMP_FAST 
1428
1429#ifdef COMP_DEBUG
1430    *p = debug_comp;
1431#endif 
1432}
1433
1434/*2
1435* sets pSetm
1436* (according or = order of first block)
1437*/
1438static void SetpSetm(int or, int ip)
1439{
1440  switch(or)
1441  {
1442    case ringorder_lp:
1443    case ringorder_ls:
1444      if (pVariables>1)
1445        pSetm= setlex2;
1446      else
1447        pSetm= setlex1;
1448      break;
1449    case ringorder_dp:
1450    case ringorder_Dp:
1451    case ringorder_ds:
1452    case ringorder_Ds:
1453    case ringorder_unspec:
1454      pSetm= setdeg1;
1455      break;
1456    case ringorder_a:
1457    case ringorder_wp:
1458    case ringorder_Wp:
1459    case ringorder_ws:
1460    case ringorder_Ws:
1461    case ringorder_M:
1462      pSetm= setdeg1w;
1463      firstwv=polys_wv[ip];
1464      break;
1465    case ringorder_c:
1466    case ringorder_C:
1467      return;
1468      /*do not set firstBlockEnds for this orderings*/
1469#ifdef TEST
1470    default:
1471      Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1472#endif
1473  }
1474  firstBlockEnds=block1[ip];
1475}
1476
1477/*2
1478* sets the comparision routine for monomials: for the first block
1479* of variables (or is the number of the ordering)
1480*/
1481#ifdef COMP_FAST
1482static void SimpleChooseC(int or, int comp_order, pCompProc *p)
1483#else 
1484static void SimpleChooseC(int or, pCompProc *p)
1485#endif 
1486{
1487#ifdef COMP_TRADITIONAL
1488  if (pVariables <= 1)
1489  {
1490    t_pComp0 = t_comp_c_1;
1491  }
1492  else
1493  {
1494    switch(or)
1495    {
1496        case ringorder_lp:
1497        case ringorder_Dp:
1498        case ringorder_Wp:
1499        case ringorder_Ds:
1500        case ringorder_Ws:
1501        case ringorder_ls:
1502          t_pComp0 = t_comp_lex_c_i;
1503          pLexSgn = 1;
1504          break;
1505
1506#ifdef PDEBUG
1507        case ringorder_unspec:
1508        case ringorder_dp:
1509        case ringorder_wp:
1510        case ringorder_ds:
1511        case ringorder_ws:
1512#else
1513        default:
1514#endif     
1515          t_pComp0 = t_comp_revlex_c_i;
1516          pLexSgn = -1;
1517          break;
1518#ifdef PDEBUG
1519        default:
1520          Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1521#endif
1522    }
1523  }
1524  if (or == ringorder_lp || or == ringorder_ls)
1525  {
1526      pLexOrder=TRUE;
1527      pFDeg = pTotaldegree;
1528      pLDeg = ldeg1c;
1529      if (or == ringorder_ls) pLexSgn = -1;
1530  }
1531 
1532  *p = t_pComp0;
1533#endif
1534#ifdef COMP_FAST
1535  switch(or)
1536  {
1537      case ringorder_dp:
1538      case ringorder_wp:
1539      case ringorder_ds:
1540      case ringorder_ls:
1541      case ringorder_ws:
1542        pSetVarIndicies_RevLex(pVariables);
1543        pLexSgn = -1;
1544        if (pVariablesW == 1)
1545          f_pComp0 = f_comp_c_1;
1546        else if (pVariablesW == 2)
1547          f_pComp0 = f_comp_c_2;
1548        else if (pVariablesW & 1)
1549          f_pComp0 = f_comp_c_2i_1;
1550        else
1551          f_pComp0 = f_comp_c_2i;
1552        break;
1553       
1554#ifdef PDEBUG
1555      case ringorder_lp:
1556      case ringorder_Dp:
1557      case ringorder_Wp:
1558      case ringorder_Ds:
1559      case ringorder_Ws:
1560#else
1561      default:
1562#endif
1563        pSetVarIndicies_Lex(pVariables);
1564        pLexSgn = 1;
1565        if (pVariablesW == 1)
1566          f_pComp0 = f_comp_c_1;
1567        else if (pVariablesW == 2)
1568          f_pComp0 = f_comp_c_2;
1569        else if (pVariablesW & 1)
1570          f_pComp0 = f_comp_c_2i_1;
1571        else
1572          f_pComp0 = f_comp_c_2i;
1573#ifdef PDEBUG
1574        break;
1575      default:
1576        Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1577#endif
1578  }
1579  if (or == ringorder_lp || or == ringorder_ls)
1580  {
1581    pLexOrder=TRUE;
1582    pFDeg = pTotaldegree;
1583    pLDeg = ldeg1c;
1584    if (or == ringorder_ls)
1585     pSetVarIndicies_Lex(pVariables);
1586  }
1587  *p = f_pComp0;
1588#endif // COMP_FAST 
1589
1590#ifdef COMP_DEBUG
1591    *p = debug_comp;
1592#endif 
1593}
1594
1595/*2
1596* sets the comparision routine for monomials: for all but the first
1597* block of variables (ip is the block number, or the number of the ordering)
1598*/
1599static void HighSet(int ip, int or)
1600{
1601  switch(or)
1602  {
1603    case ringorder_lp:
1604      bcomph[ip]=comp_lp;
1605      if (pOrdSgn==-1) pMixedOrder=TRUE;
1606      break;
1607    case ringorder_dp:
1608      bcomph[ip]=comp_dp;
1609      if (pOrdSgn==-1) pMixedOrder=TRUE;
1610      break;
1611    case ringorder_Dp:
1612      bcomph[ip]=comp_Dp;
1613      if (pOrdSgn==-1) pMixedOrder=TRUE;
1614      break;
1615    case ringorder_wp:
1616      bcomph[ip]=comp_wp;
1617      if (pOrdSgn==-1) pMixedOrder=TRUE;
1618      break;
1619    case ringorder_Wp:
1620      bcomph[ip]=comp_Wp;
1621      if (pOrdSgn==-1) pMixedOrder=TRUE;
1622      break;
1623    case ringorder_ls:
1624      bcomph[ip]=comp_ls;
1625      break;
1626    case ringorder_ds:
1627      bcomph[ip]=comp_ds;
1628      break;
1629    case ringorder_Ds:
1630      bcomph[ip]=comp_Ds;
1631      break;
1632    case ringorder_ws:
1633      bcomph[ip]=comp_ws;
1634      break;
1635    case ringorder_Ws:
1636      bcomph[ip]=comp_Ws;
1637      break;
1638    case ringorder_c:
1639      pComponentOrder=1;
1640      bcomph[ip]=comp_c;
1641      break;
1642    case ringorder_C:
1643      pComponentOrder=-1;
1644      bcomph[ip]=comp_c;
1645      break;
1646    case ringorder_M:
1647      bcomph[ip]=comp_M;
1648      pMixedOrder=TRUE;
1649      break;
1650    case ringorder_a:
1651      if (pOrdSgn==-1) pMixedOrder=TRUE;
1652      if (ip==0)
1653        bcomph[0]=comp1a;
1654      else
1655        bcomph[ip]=comp_a;
1656      break;
1657#ifdef TEST
1658    default:
1659      Werror("wrong internal ordering:%d at %s, l:%d\n",or,__FILE__,__LINE__);
1660#endif
1661  }
1662}
1663
1664#ifdef DIV_COUNT
1665struct div_triple
1666{
1667  unsigned long greater;
1668  unsigned long equal;
1669  unsigned long smaller;
1670};
1671
1672static div_triple* DivTriples = NULL;
1673static int NumberOfDivTriples = 0;
1674static unsigned long DivCountTotal = 0;
1675static unsigned long DivCountDiv = 0;
1676static unsigned long LexDivCount = 0;
1677static unsigned long RevLexDivCount = 0;
1678static unsigned long LexDivCount2 = 0;
1679static unsigned long RevLexDivCount2 = 0;
1680static int pVariables2;
1681static int pVariablesEven;
1682
1683void InitDivCount(int nvars)
1684{
1685  if (nvars & 1) pVariablesEven = 0;
1686  else pVariablesEven = 1;
1687
1688  pVariables2 = (pVariables -1) / 2;
1689
1690  if (DivTriples == NULL)
1691    {
1692      DivTriples = (div_triple*) Alloc0(nvars*sizeof(div_triple));
1693      NumberOfDivTriples = nvars;
1694    }
1695  else if (nvars > NumberOfDivTriples)
1696    {
1697      DivTriples = (div_triple*) ReAlloc(DivTriples, 
1698                                         NumberOfDivTriples*sizeof(div_triple),
1699                                         nvars*sizeof(div_triple));
1700      for (int i=NumberOfDivTriples; i<nvars; i++)
1701        {
1702          DivTriples[i].greater = 0;
1703          DivTriples[i].smaller = 0;
1704          DivTriples[i].equal = 0;
1705        }
1706
1707      NumberOfDivTriples = nvars;
1708    }
1709}
1710
1711void ResetDivCount()
1712{
1713  int i;
1714  for (i=0; i<NumberOfDivTriples;i++)
1715    {
1716      DivTriples[i].greater = 0;
1717      DivTriples[i].equal = 0;
1718      DivTriples[i].smaller = 0;
1719    }
1720
1721  DivCountTotal = 0;
1722  DivCountDiv = 0;
1723  LexDivCount = 0;
1724  RevLexDivCount = 0;
1725  LexDivCount2 = 0;
1726  RevLexDivCount2 = 0;
1727}
1728
1729void OutputDivCount()
1730{
1731  printf("Total      : %10u\n", DivCountTotal);
1732  if (DivCountTotal == 0) DivCountTotal++;
1733  printf("Div        : %10u \t %.4f\n", DivCountDiv,
1734         (float) DivCountDiv / (float) DivCountTotal);
1735  printf("LexCount   :  %10u \t %.4f\n", LexDivCount,
1736         (float) LexDivCount / (float) DivCountTotal);
1737  printf("RevLexCount:  %10u \t %.4f\n", RevLexDivCount,
1738         (float) RevLexDivCount / (float) DivCountTotal);
1739  printf("LexCount2   :  %10u \t %.4f\n", LexDivCount2,
1740         (float) LexDivCount2 / (float) DivCountTotal);
1741  printf("RevLexCount2:  %10u \t %.4f\n", RevLexDivCount2,
1742         (float) RevLexDivCount2 / (float) DivCountTotal);
1743
1744  for (int i=0; i<NumberOfDivTriples; i++)
1745    {
1746      unsigned long total = DivTriples[i].greater + 
1747        DivTriples[i].equal + DivTriples[i].smaller;
1748      // avoid total==0
1749      if (total == 0) total=1;
1750      printf("  [%d]: %10u (%.4f)  %10u (%.4f)  %10u (%.4f)\n", i,
1751             DivTriples[i].greater, 
1752             (float) DivTriples[i].greater / (float) total ,
1753             DivTriples[i].equal, 
1754             (float) DivTriples[i].equal / (float) total  ,
1755             DivTriples[i].smaller, 
1756             (float) DivTriples[i].smaller / (float) total  );
1757    }
1758}
1759
1760BOOLEAN pDivisibleBy(poly a, poly b)
1761{
1762  if ((a!=NULL)&&(( pGetComp(a)==0) || ( pGetComp(a) ==  pGetComp(b))))
1763  {
1764    int i;
1765    Exponent_t *e1=&( pGetExp(a,1));
1766    Exponent_t *e2=&( pGetExp(b,1));
1767    BOOLEAN res = TRUE, res2 = TRUE;
1768    DivCountTotal++;
1769
1770    for (i=0; i<pVariables; i++)
1771    {
1772      if (res == TRUE) LexDivCount++;
1773      if (*e1 > *e2) 
1774      {
1775        DivTriples[i].greater++;
1776        res = FALSE;
1777      }
1778      else if (*e1 == *e2)  DivTriples[i].equal++;
1779      else DivTriples[i].smaller++;
1780      e1++;
1781      e2++;
1782    } 
1783    if (res == TRUE) DivCountDiv++;
1784    e1 = &(pGetExp(a,pVariables));
1785    e2 = &(pGetExp(b,pVariables));
1786
1787    for (i=0; i<pVariables; i++)
1788    {
1789      RevLexDivCount++;
1790      if (*e1 > *e2)
1791      {
1792        res2 = FALSE;
1793        break;
1794      }
1795      e1--;
1796      e2--;
1797    }
1798    if (res != res2)
1799      fprintf(stderr, "Error in RevLexCount\n");
1800   
1801    if (pVariables < 4) return res;
1802    LexTop:
1803    res2 = TRUE;
1804    int* s1 = (int*) &( pGetExp(a,2));
1805    int* s2 = (int*) &( pGetExp(b,2));
1806    for (i=0; i<pVariables2; i++, s1++, s2++)
1807    {
1808      LexDivCount2++;
1809      if (*s1 > *s2)
1810          {
1811            res2 = FALSE;
1812            break;
1813          }
1814    }
1815    if (res2 == TRUE)
1816    {
1817      LexDivCount2++;
1818      if ( pGetExp(a,1) >  pGetExp(b,1)) res2 = FALSE;
1819      if (res2 == TRUE && pVariablesEven)
1820          {
1821            LexDivCount2++;
1822            if (pGetExp(a,pVariables) > pGetExp(b,pVariables))
1823              res2 = FALSE;
1824          }
1825    }
1826    if (res2 == TRUE)
1827    {
1828      e1 = &( pGetExp(a,2));
1829      e2 = &( pGetExp(b,2));
1830      for (i=0; i<pVariables2; i++, e1 += 2, e2 += 2)
1831      {
1832        LexDivCount++;
1833#ifdef WORDS_BIG_ENDIAN
1834        if (e1[1] > e2[1])
1835#else
1836        if (*e1 > *e2)
1837#endif
1838        {
1839          res2 = FALSE;
1840          break;
1841        }
1842      }
1843    }
1844    if (res != res2)
1845    {
1846      fprintf(stderr, "Error in LexDivCount2\n");
1847      // goto LexTop;
1848    }
1849   
1850    RevLexTop:
1851    res2 = TRUE;
1852    if (pVariablesEven)
1853    {
1854      s1 = (int*) &(pGetExp(a,pVariables-2));
1855      s2 = (int*) &(pGetExp(b,pVariables-2));
1856    }
1857    else
1858    {
1859      s1 = (int*) &(pGetExp(a,pVariables-1));
1860      s2 = (int*) &(pGetExp(b,pVariables-1));
1861    }
1862    for (i=0; i< pVariables2; i++, s1--, s2--)
1863    {
1864      RevLexDivCount2++;
1865      if (*s1 > *s2)
1866          {
1867            res2 = FALSE;
1868            break;
1869          }
1870    }
1871    if (res2 == TRUE)
1872    {
1873      if (pVariablesEven)
1874          {
1875            RevLexDivCount2++;
1876            if (pGetExp(a,pVariables) > pGetExp(b,pVariables))
1877              res2 = FALSE;
1878          }
1879      if (res2 == TRUE)
1880          {
1881            RevLexDivCount2++;
1882            if ( pGetExp(a,1) >  pGetExp(b,1)) res2 = FALSE;
1883          }
1884    }
1885    if (res2 == TRUE)
1886    {
1887      if (pVariablesEven)
1888      {
1889        e1 = &(pGetExp(a,pVariables-2));
1890        e2 = &(pGetExp(b,pVariables-2));
1891      }
1892      else
1893      {
1894        e1 = &(pGetExp(a,pVariables-1));
1895        e2 = &(pGetExp(b,pVariables-1));
1896      }
1897      for (i=0; i<pVariables2; i++, e1 -= 2, e2 -= 2)
1898      {
1899#ifdef WORDS_BIG_ENDIAN     
1900      if (e1[1] > e2[1])
1901#else
1902      if (*e1 > *e2) 
1903#endif       
1904        {
1905          res2 = FALSE;
1906          break;
1907        }
1908      }
1909    }
1910    if (res != res2)
1911    {
1912      fprintf(stderr, "Error in RevLexDivCount2\n");
1913      // goto RevLexTop;
1914    }
1915    return res;
1916  }
1917  return FALSE;
1918}
1919#endif
1920
1921/* -------------------------------------------------------- */
1922/*2
1923* change all variables to fit the description of the new ring
1924*/
1925void pChangeRing(int n, int Sgn, int * orders, int * b0, int * b1,
1926         short ** wv)
1927{
1928  int i;
1929  pComponentOrder=1;
1930  if (ppNoether!=NULL) pDelete(&ppNoether);
1931#ifdef SRING
1932  pSRING=FALSE;
1933  pAltVars=n+1;
1934#endif
1935  t_pComp0 = NULL;
1936#ifdef COMP_FAST
1937  f_pComp0 = NULL;
1938#endif 
1939  pVariables = n;
1940
1941  // set the various size parameters and initialize memory
1942  pMonomSize = POLYSIZE + (pVariables + 1) * sizeof(Exponent_t);
1943  if ((pMonomSize % sizeof(void*)) == 0)
1944  {
1945    pMonomSizeW = pMonomSize/sizeof(void*);
1946  }
1947  else
1948  {
1949    pMonomSizeW = pMonomSize/sizeof(void*) + 1;
1950    pMonomSize = pMonomSizeW*sizeof(void*);
1951  }
1952
1953#ifdef COMP_FAST 
1954  if ((((pVariables+1)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1955    pVariables1W = (pVariables+1)*sizeof(Exponent_t) / sizeof(void*);
1956  else
1957    pVariables1W = ((pVariables+1)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1958  if ((((pVariables)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1959    pVariablesW = (pVariables)*sizeof(Exponent_t) / sizeof(void*);
1960  else
1961    pVariablesW = ((pVariables)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1962 
1963  // Set default Var Indicies
1964  pSetVarIndicies(pVariables);
1965#endif
1966  mmSpecializeBlock(pMonomSize);
1967 
1968  pOrdSgn = Sgn;
1969  pVectorOut=(orders[0]==ringorder_c);
1970  order=orders;
1971  block0=b0;
1972  block1=b1;
1973  firstwv=NULL;
1974  polys_wv=wv;
1975  /*------- only one real block ----------------------*/
1976  pLexOrder=FALSE;
1977  pMixedOrder=FALSE;
1978  pFDeg=pDeg;
1979  if (pOrdSgn == 1) pLDeg = ldegb;
1980  else              pLDeg = ldeg0;
1981  /*======== ordering type is (_,c) =========================*/
1982  if ((orders[0]==ringorder_unspec)
1983  ||(
1984    ((orders[1]==ringorder_c)||(orders[1]==ringorder_C))
1985    && (orders[0]!=ringorder_M)
1986    && (orders[2]==0))
1987  )
1988  {
1989    if ((orders[0]!=ringorder_unspec)
1990    && (orders[1]==ringorder_C))
1991      pComponentOrder=-1;
1992    if (pOrdSgn == -1) pLDeg = ldeg0c;
1993#ifdef COMP_FAST   
1994    SimpleChoose(orders[0],orders[1], &pComp0);
1995#else   
1996    SimpleChoose(orders[0],&pComp0);
1997#endif   
1998    SetpSetm(orders[0],0);
1999#ifdef TEST_MAC_ORDER
2000    if (orders[0]==ringorder_dp)
2001       bBinomSet();
2002#endif
2003  }
2004  /*======== ordering type is (c,_) =========================*/
2005  else if (((orders[0]==ringorder_c)||(orders[0]==ringorder_C))
2006  && (orders[1]!=ringorder_M)
2007  &&  (orders[2]==0))
2008  {
2009    /* pLDeg = ldeg0; is standard*/
2010    if (orders[0]==ringorder_C)
2011      pComponentOrder=-1;
2012#ifdef COMP_FAST
2013    SimpleChooseC(orders[1],pComponentOrder, &pComp0);
2014#else   
2015    SimpleChooseC(orders[1],&pComp0);
2016#endif   
2017    SetpSetm(orders[1],1);
2018  }
2019  /*------- more than one block ----------------------*/
2020  else
2021  {
2022    //pLexOrder=TRUE;
2023    pVectorOut=orders[0]==ringorder_c;
2024    if ((pVectorOut)||(orders[0]==ringorder_C))
2025    {
2026      if(block1[1]!=pVariables) pLexOrder=TRUE;
2027    } 
2028    else
2029    {
2030      if(block1[0]!=pVariables) pLexOrder=TRUE;
2031    }
2032    /*the number of orderings:*/
2033    i = 0;
2034    while (orders[++i] != 0);
2035    do
2036    {
2037      i--;
2038      HighSet(i, orders[i]);/*sets also pMixedOrder to TRUE, if...*/
2039      SetpSetm(orders[i],i);
2040    }
2041    while (i != 0);
2042
2043    pComp0 = BlockComp;
2044    if ((orders[0]!=ringorder_c)&&(orders[0]!=ringorder_C))
2045    {
2046      pLDeg = ldeg1c;
2047    }
2048    else
2049    {
2050      pLDeg = ldeg1; 
2051    }
2052    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
2053  }
2054  if ((pLexOrder) || (pOrdSgn==-1))
2055  {
2056    test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
2057  }
2058#ifdef COMP_TRADITIONAL 
2059  if (t_pComp0 == NULL)
2060    t_pComp0 = pComp0;
2061#endif
2062
2063#ifdef COMP_FAST
2064  if (f_pComp0 == NULL)
2065    f_pComp0 = pComp0;
2066#endif
2067 
2068#ifdef DIV_COUNT
2069  InitDivCount(pVariables);
2070#endif
2071}
2072
2073/* -------------------------------------------------------- */
2074
2075static BOOLEAN pMultT_nok;
2076/*2
2077* update the polynomial a by multipying it by
2078* the (number) coefficient
2079* and the exponent vector (of) exp (a well initialized polynomial)
2080*/
2081poly pMultT(poly a, poly exp )
2082{
2083  int i;
2084  number t,x,y=pGetCoeff(exp);
2085  poly aa=a;
2086  poly prev=NULL;
2087#ifdef SDRING
2088  poly pDRINGres=NULL;
2089#endif
2090
2091  pMultT_nok = pGetComp(exp);
2092#ifdef PDEBUG
2093  pTest(a);
2094  pTest(exp);
2095#endif
2096  while (a !=NULL)
2097  {
2098    x=pGetCoeff(a);
2099    t=nMult(x/*pGetCoeff(a)*/,y/*pGetCoeff(exp)*/);
2100    nDelete(&x/*pGetCoeff(a)*/);
2101    pSetCoeff0(a,t);
2102    if (nIsZero(t))
2103    {
2104      if (prev==NULL) { pDelete1(&a); aa=a; }
2105      else            { pDelete1(&prev->next); a=prev->next;}
2106    }
2107    else
2108    {
2109#ifdef DRING
2110      if (pDRING)
2111      {
2112         if (pdDFlag(a)==1)
2113         {
2114           if (pdDFlag(exp)==1)
2115           {
2116             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
2117           }
2118           else
2119           {
2120             pDRINGres=pAdd(pDRINGres,pMultDT(a,exp));
2121           }
2122         }
2123         else
2124         {
2125           if (pdDFlag(exp)==1)
2126           {
2127             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
2128           }
2129           else
2130           {
2131             pDRINGres=pAdd(pDRINGres,pMultTT(a,exp));
2132           }
2133         }
2134      }
2135      else
2136#endif
2137#ifdef SRING
2138      if (pSRING)
2139      {
2140        pDRINGres=pAdd(pDRINGres,psMultM(a,exp));
2141      }
2142      else
2143#endif
2144      {
2145        for (i=pVariables; i != 0; i--)
2146        {
2147           pAddExp(a,i, pGetExp(exp,i));
2148        }
2149        #ifndef TEST_MAC_ORDER
2150        a->Order += exp->Order;
2151        #else
2152        pSetm(a);
2153        #endif
2154        if (pMultT_nok)
2155        {
2156          if (pGetComp(a) == 0)
2157          {
2158             pSetComp(a, pGetComp(exp));
2159          }
2160          else
2161          {
2162            return NULL /*FALSE*/;
2163          }
2164        }
2165      }
2166      prev=a;
2167      pIter(a);
2168    }
2169  }
2170  pMultT_nok=0;
2171#ifdef DRING
2172   if (pDRING)
2173   {
2174     pDelete(&aa);
2175     return pDRINGres;
2176   }
2177#endif
2178#ifdef SRING
2179   if (pSRING)
2180   {
2181     pDelete(&aa);
2182     return pDRINGres;
2183   }
2184#endif
2185   return aa; /*TRUE*/
2186}
2187
2188/*2
2189* multiply p1 with p2, p1 and p2 are destroyed
2190* do not put attention on speed: the procedure is only used in the interpreter
2191*/
2192poly pMult(poly p1, poly p2)
2193{
2194  poly res, r, rn, a;
2195  BOOLEAN cont;
2196
2197  if ((p1!=NULL) && (p2!=NULL))
2198  {
2199#ifdef PDEBUG
2200    pTest(p1);
2201    pTest(p2);
2202#endif
2203    cont = TRUE;
2204    a = p1;
2205    if (pNext(p2)!=NULL)
2206      a = pCopy(a);
2207    else
2208      cont = FALSE;
2209    res = pMultT(a, p2);
2210    if (pMultT_nok)
2211    {
2212      if (cont) pDelete(&p1);
2213      pDelete(&res);
2214      pDelete(&p2);
2215      return NULL;
2216    }
2217    pDelete1(&p2);
2218    r = res;
2219    if (r!=NULL) rn = pNext(r);
2220    else         rn=NULL;
2221    while (cont)
2222    {
2223      if (pNext(p2)==NULL)
2224      {
2225        a = p1;
2226        cont = FALSE;
2227      }
2228      else
2229      {
2230        a = pCopy(p1);
2231      }
2232      a=pMultT(a, p2); //sets pMultT_nok
2233      if (pMultT_nok)
2234      {
2235        if (cont) pDelete(&p1);
2236        pDelete(&a);
2237        pDelete(&res);
2238        pDelete(&p2);
2239        return NULL;
2240      }
2241      while ((rn!=NULL) && (pComp0(rn,a)>0))
2242      {
2243        r = rn;
2244        pIter(rn);
2245      }
2246      if (r!=NULL) pNext(r) = rn = pAdd(a, rn);
2247      else         res=r=a;
2248      pDelete1(&p2);
2249    }
2250    return res;
2251  }
2252  pDelete(&p1);
2253  pDelete(&p2);
2254  return NULL;
2255}
2256
2257/*2
2258* update a by multiplying it with c (c will not be destroyed)
2259*/
2260void pMultN(poly a, number c)
2261{
2262  number t;
2263
2264  while (a!=NULL)
2265  {
2266    t=nMult(pGetCoeff(a), c);
2267    //nNormalize(t);
2268    pSetCoeff(a,t);
2269    pIter(a);
2270  }
2271}
2272
2273/*2
2274* return a copy of the poly a times the number c (a,c will not be destroyed)
2275*/
2276poly pMultCopyN(poly a, number c)
2277{
2278  poly result=NULL,hp;
2279
2280  if (a != NULL)
2281  {
2282    result=pNew();
2283    pCopy2(result,a);
2284    pNext(result)=NULL;
2285    pGetCoeff(result)=nMult(pGetCoeff(a),c);
2286    pIter(a);
2287    hp=result;
2288    while (a)
2289    {
2290      hp=pNext(hp)=pNew();
2291      pCopy2(hp,a);
2292      pSetCoeff0(hp,nMult(pGetCoeff(a), c));
2293      pIter(a);
2294    }
2295    pNext(hp)=NULL;
2296  }
2297  return result;
2298}
2299
2300/*2
2301* returns TRUE if the head term of b is a multiple of the head term of a
2302*/
2303#if defined(macintosh)
2304BOOLEAN pDivisibleBy(poly a, poly b)
2305{
2306  if ((a!=NULL)&&(( pGetComp(a)==0) || ( pGetComp(a) ==  pGetComp(b))))
2307  {
2308    int i=pVariables;
2309    Exponent_t *e1=&( pGetExp(a,1));
2310    Exponent_t *e2=&( pGetExp(b,1));
2311    if ((*e1) > (*e2)) return FALSE;
2312    do
2313    {
2314      i--;
2315      if (i == 0) return TRUE;
2316      e1++;
2317      e2++;
2318     } while ((*e1) <= (*e2));
2319   }
2320   return FALSE;
2321}
2322#endif
2323
2324
2325/*2
2326* assumes that the head term of b is a multiple of the head term of a
2327* and return the multiplicant *m
2328*/
2329poly pDivide(poly a, poly b)
2330{
2331  int i;
2332  poly result=pInit();
2333
2334  for(i=(int)pVariables; i; i--)
2335    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
2336  pSetComp(result, pGetComp(a) - pGetComp(b));
2337  pSetm(result);
2338  return result;
2339}
2340
2341/*2
2342* divides a by the monomial b, ignores monomials wihich are not divisible
2343* assumes that b is not NULL
2344*/
2345poly pDivideM(poly a, poly b)
2346{
2347  if (a==NULL) return NULL;
2348  poly result=a;
2349  poly prev=NULL;
2350  int i;
2351  number inv=nInvers(pGetCoeff(b));
2352
2353  while (a!=NULL)
2354  {
2355    if (pDivisibleBy(b,a))
2356    {
2357      for(i=(int)pVariables; i; i--)
2358         pSubExp(a,i, pGetExp(b,i));
2359      pSubComp(a, pGetComp(b));
2360      pSetm(a);
2361      prev=a;
2362      pIter(a);
2363    }
2364    else
2365    {
2366      if (prev==NULL)
2367      {
2368        pDelete1(&result);
2369        a=result;
2370      }
2371      else
2372      {
2373        pDelete1(&pNext(prev));
2374        a=pNext(prev);
2375      }
2376    }
2377  }
2378  pMultN(result,inv);
2379  nDelete(&inv);
2380  pDelete(&b);
2381  return result;
2382}
2383
2384/*2
2385* returns the LCM of the head terms of a and b in *m
2386*/
2387void pLcm(poly a, poly b, poly m)
2388{
2389  int i;
2390  for (i=pVariables; i; i--)
2391  {
2392    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
2393  }
2394  pSetComp(m, max(pGetComp(a), pGetComp(b)));
2395}
2396
2397/*2
2398* convert monomial given as string to poly, e.g. 1x3y5z
2399*/
2400poly pmInit(char *st, BOOLEAN &ok)
2401{
2402  int i,j;
2403  ok=FALSE;
2404  BOOLEAN b=FALSE;
2405  poly rc = pInit();
2406  char *s = nRead(st,&(rc->coef));
2407  if (s==st)
2408  /* i.e. it does not start with a coeff: test if it is a ringvar*/
2409  {
2410    j = rIsRingVar(s);
2411    if (j >= 0)
2412    {
2413      pIncrExp(rc,1+j);
2414      goto done;
2415    }
2416  }
2417  else
2418    b=TRUE;
2419  while (*s!='\0')
2420  {
2421    char ss[2];
2422    ss[0] = *s++;
2423    ss[1] = '\0';
2424    j = rIsRingVar(ss);
2425    if (j >= 0)
2426    {
2427      s = eati(s,&i);
2428      pAddExp(rc,1+j, (Exponent_t)i);
2429    }
2430    else
2431    {
2432      if ((s!=st)&&isdigit(st[0]))
2433      {
2434        errorreported=TRUE;
2435      }
2436      pDelete(&rc);
2437      return NULL;
2438    }
2439  }
2440done:
2441  ok=!errorreported;
2442  if (nIsZero(pGetCoeff(rc))) pDelete1(&rc);
2443  else
2444  {
2445#ifdef DRING
2446    if (pDRING)
2447    {
2448      for(i=1;i<=pdN;i++)
2449      {
2450        if(pGetExp(rc,pdDX(i))>0)
2451        {
2452          pdDFlag(rc)=1;
2453          break;
2454        }
2455      }
2456    }
2457#endif
2458    pSetm(rc);
2459  }
2460  return rc;
2461}
2462
2463/*2
2464*make p homgeneous by multiplying the monomials by powers of x_varnum
2465*/
2466poly pHomogen (poly p, int varnum)
2467{
2468  poly q=NULL;
2469  poly res;
2470  int  o,ii;
2471
2472  if (p!=NULL)
2473  {
2474    if ((varnum < 1) || (varnum > pVariables))
2475    {
2476      return NULL;
2477    }
2478    o=pWTotaldegree(p);
2479    q=pNext(p);
2480    while (q != NULL)
2481    {
2482      ii=pWTotaldegree(q);
2483      if (ii>o) o=ii;
2484      pIter(q);
2485    }
2486    q = pCopy(p);
2487    res = q;
2488    while (q != NULL)
2489    {
2490      ii = o-pWTotaldegree(q);
2491      if (ii!=0)
2492      {
2493        pAddExp(q,varnum, (Exponent_t)ii);
2494        pSetm(q);
2495      }
2496      pIter(q);
2497    }
2498    q = pOrdPolyInsertSetm(res);
2499  }
2500  return q;
2501}
2502
2503
2504/*2
2505*replaces the maximal powers of the leading monomial of p2 in p1 by
2506*the same powers of n, utility for dehomogenization
2507*/
2508poly pDehomogen (poly p1,poly p2,number n)
2509{
2510  polyset P;
2511  int     SizeOfSet=5;
2512  int     i;
2513  poly    p;
2514  number  nn;
2515
2516  P = (polyset)Alloc(5*sizeof(poly));
2517  for (i=0; i<5; i++)
2518  {
2519    P[i] = NULL;
2520  }
2521  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
2522  p = P[0];
2523  //P[0] = NULL ;// for safety, may be remoeved later
2524  for (i=1; i<SizeOfSet; i++)
2525  {
2526    if (P[i] != NULL)
2527    {
2528      nPower(n,i,&nn);
2529      pMultN(P[i],nn);
2530      p = pAdd(p,P[i]);
2531      //P[i] =NULL; // for safety, may be removed later
2532      nDelete(&nn);
2533    }
2534  }
2535  Free((ADDRESS)P,SizeOfSet*sizeof(poly));
2536  return p;
2537}
2538
2539/*4
2540*Returns the exponent of the maximal power of the leading monomial of
2541*p2 in that of p1
2542*/
2543static int pGetMaxPower (poly p1,poly p2)
2544{
2545  int     i,k,res = 32000; /*a very large integer*/
2546
2547  if (p1 == NULL) return 0;
2548  for (i=1; i<=pVariables; i++)
2549  {
2550    if ( pGetExp(p2,i) != 0)
2551    {
2552      k =  pGetExp(p1,i) /  pGetExp(p2,i);
2553      if (k < res) res = k;
2554    }
2555  }
2556  return res;
2557}
2558
2559/*2
2560*Returns as i-th entry of P the coefficient of the (i-1) power of
2561*the leading monomial of p2 in p1
2562*/
2563void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
2564{
2565  int   maxPow;
2566  poly  p,qp,Coeff;
2567
2568  if (*P == NULL)
2569  {
2570    *P = (polyset) Alloc(5*sizeof(poly));
2571    *SizeOfSet = 5;
2572  }
2573  p = pCopy(p1);
2574  while (p != NULL)
2575  {
2576    qp = p->next;
2577    p->next = NULL;
2578    maxPow = pGetMaxPower(p,p2);
2579    Coeff = pDivByMonom(p,p2);
2580    if (maxPow > *SizeOfSet)
2581    {
2582      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
2583      *SizeOfSet = maxPow+1;
2584    }
2585    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
2586    pDelete(&p);
2587    p = qp;
2588  }
2589}
2590
2591/*2
2592*returns the leading monomial of p1 divided by the maximal power of that
2593*of p2
2594*/
2595poly pDivByMonom (poly p1,poly p2)
2596{
2597  int     k, i;
2598
2599  if (p1 == NULL) return NULL;
2600  k = pGetMaxPower(p1,p2);
2601  if (k == 0)
2602    return pHead(p1);
2603  else
2604  {
2605    number n;
2606    poly p = pInit();
2607
2608    p->next = NULL;
2609    for (i=1; i<=pVariables; i++)
2610    {
2611       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
2612    }
2613    nPower(p2->coef,k,&n);
2614    pSetCoeff0(p,nDiv(p1->coef,n));
2615    nDelete(&n);
2616    pSetm(p);
2617    return p;
2618  }
2619}
2620/*----------utilities for syzygies--------------*/
2621poly pTakeOutComp(poly * p, int k)
2622{
2623  poly q = *p,qq=NULL,result = NULL;
2624
2625  if (q==NULL) return NULL;
2626  if (pGetComp(q)==k)
2627  {
2628    result = q;
2629    while ((q!=NULL) && (pGetComp(q)==k))
2630    {
2631      pSetComp(q,0);
2632      qq = q;
2633      pIter(q);
2634    }
2635    *p = q;
2636    pNext(qq) = NULL;
2637  }
2638  if (q==NULL) return result;
2639  if (pGetComp(q) > k) pDecrComp(q);
2640  poly pNext_q;
2641  while ((pNext_q=pNext(q))!=NULL)
2642  {
2643    if (pGetComp(pNext_q)==k)
2644    {
2645      if (result==NULL)
2646      {
2647        result = pNext_q;
2648        qq = result;
2649      }
2650      else
2651      {
2652        pNext(qq) = pNext_q;
2653        pIter(qq);
2654      }
2655      pNext(q) = pNext(pNext_q);
2656      pNext(qq) =NULL;
2657      pSetComp(qq,0);
2658    }
2659    else
2660    {
2661      /*pIter(q);*/ q=pNext_q;
2662      if (pGetComp(q) > k) pDecrComp(q);
2663    }
2664  }
2665  return result;
2666}
2667
2668poly pTakeOutComp1(poly * p, int k)
2669{
2670  poly q = *p;
2671
2672  if (q==NULL) return NULL;
2673
2674  poly qq=NULL,result = NULL;
2675
2676  if (pGetComp(q)==k)
2677  {
2678    result = q; /* *p */
2679    while ((q!=NULL) && (pGetComp(q)==k))
2680    {
2681      pSetComp(q,0);
2682      qq = q;
2683      pIter(q);
2684    }
2685    *p = q;
2686    pNext(qq) = NULL;
2687  }
2688  if (q==NULL) return result;
2689//  if (pGetComp(q) > k) pGetComp(q)--;
2690  while (pNext(q)!=NULL)
2691  {
2692    if (pGetComp(pNext(q))==k)
2693    {
2694      if (result==NULL)
2695      {
2696        result = pNext(q);
2697        qq = result;
2698      }
2699      else
2700      {
2701        pNext(qq) = pNext(q);
2702        pIter(qq);
2703      }
2704      pNext(q) = pNext(pNext(q));
2705      pNext(qq) =NULL;
2706      pSetComp(qq,0);
2707    }
2708    else
2709    {
2710      pIter(q);
2711//      if (pGetComp(q) > k) pGetComp(q)--;
2712    }
2713  }
2714  return result;
2715}
2716
2717void pDeleteComp(poly * p,int k)
2718{
2719  poly q;
2720
2721  while ((*p!=NULL) && (pGetComp(*p)==k)) pDelete1(p);
2722  if (*p==NULL) return;
2723  q = *p;
2724  if (pGetComp(q)>k) pDecrComp(q);
2725  while (pNext(q)!=NULL)
2726  {
2727    if (pGetComp(pNext(q))==k)
2728      pDelete1(&(pNext(q)));
2729    else
2730    {
2731      pIter(q);
2732      if (pGetComp(q)>k) pDecrComp(q);
2733    }
2734  }
2735}
2736/*----------end of utilities for syzygies--------------*/
2737
2738/*2
2739* pair has no common factor ? or is no polynomial
2740*/
2741#ifdef COMP_FAST
2742BOOLEAN pHasNotCF(poly p1, poly p2)
2743{
2744#ifdef SRING
2745  if (pSRING)
2746    return FALSE;
2747#endif
2748
2749  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
2750    return FALSE;
2751  Exponent_t * m1 = &(p1->exp[pVarLowIndex]);
2752  Exponent_t * m2 = &(p2->exp[pVarLowIndex]);
2753  int i = 1;
2754  loop
2755  {
2756    if (((*m1) > 0) && ((*m2) > 0))
2757      return FALSE;
2758    if (i == pVariables)
2759      return TRUE;
2760    m1++;m2++;
2761    i++;
2762  }
2763}
2764#else
2765BOOLEAN pHasNotCF(poly p1, poly p2)
2766{
2767#ifdef SRING
2768  if (pSRING)
2769    return FALSE;
2770#endif
2771  short * m1 = p1->exp;
2772  short * m2 = p2->exp;
2773
2774  if (((*m1) > 0)||((*m2) > 0))
2775    return FALSE;
2776  int i = 1;
2777  loop
2778  {
2779    m1++;m2++;
2780    if (((*m1) > 0) && ((*m2) > 0))
2781      return FALSE;
2782    if (i == pVariables)
2783      return TRUE;
2784    i++;
2785  }
2786}
2787#endif
2788/*
2789*void    pSFactors(poly f, poly g, poly a, poly b)
2790*{
2791*  int i,d;
2792*
2793*  for (i=pVariables;i>0;i--)
2794*  {
2795*    d =  pGetExp(f,i)- pGetExp(g,i);
2796*    if (d >= 0)
2797*    {
2798*       pGetExp(a,i) = 0;
2799*       pGetExp(b,i) = d;
2800*    }
2801*    else
2802*    {
2803*       pGetExp(a,i) = -d;
2804*       pGetExp(b,i) = 0;
2805*    }
2806*  }
2807*   pGetComp(a) = 0;
2808*   pGetComp(b) = 0;
2809*  pSetm(a);
2810*  pSetm(b);
2811*}
2812*/
2813
2814/*
2815*void    pSDiv(poly f, poly g, poly b)
2816*{
2817*  int i,d;
2818*
2819*  for (i=pVariables;i>0;i--)
2820*  {
2821*    d =  pGetExp(f,i)- pGetExp(g,i);
2822*     pGetExp(b,i) = d;
2823*  }
2824*   pGetComp(b) = 0;
2825*  pSetm(b);
2826*}
2827*/
2828
2829/*2
2830* update the initial term of a polynomial a by multipying it by
2831* the (number) coefficient
2832* and the exponent vector (of) exp (a well initialized polynomial)
2833*/
2834/*
2835*void    pSMultBy(poly f, poly m)
2836*{
2837*  number t;
2838*  int i;
2839* //  short notok;
2840*
2841*  t=nMult(f->coef, m->coef);
2842*  nDelete(&(f->coef));
2843*  f->coef = t;
2844*  f->Order  += m->Order;
2845*  for (i=pVariables; i; i--)
2846*     pGetExp(f,i) +=  pGetExp(m,i);
2847* //  if (notok)
2848* //  {
2849*    if (!( pGetComp(f)))
2850*    {
2851*       pGetComp(f) =  pGetComp(m);
2852*    }
2853* //    else
2854* //    {
2855* //      HALT;
2856* //    }
2857* //  }
2858*}
2859*/
2860
2861
2862/*2
2863*should return 1 if p divides q and p<q,
2864*             -1 if q divides p and q<p
2865*              0 otherwise
2866*/
2867#ifdef COMP_FAST
2868int     pDivComp(poly p, poly q)
2869{
2870  if (pGetComp(p) == pGetComp(q))
2871  {
2872    Exponent_t * mp = &(p->exp[pVarLowIndex]);
2873    Exponent_t * mq = &(q->exp[pVarLowIndex]);
2874    int i=pVariables;
2875    BOOLEAN a=FALSE, b=FALSE;
2876    for (; i>0; i--)
2877    {
2878      if (*mp<*mq)
2879      {
2880        if (b) return 0;
2881        a =TRUE;
2882      }
2883      else if (*mp>*mq)
2884      {
2885        if (a) return 0;
2886        b = TRUE;
2887      }
2888      mp++;mq++;
2889    }
2890    if (a) return 1;
2891    else if (b)  return -1;
2892  }
2893  return 0;
2894}
2895#else
2896int     pDivComp(poly p, poly q)
2897{
2898  short * mp = p->exp;
2899  short * mq = q->exp;
2900
2901  if (*mp==*mq)
2902  {
2903    int i=pVariables;
2904    BOOLEAN a=FALSE, b=FALSE;
2905    for (; i>0; i--)
2906    {
2907      mp++;mq++;
2908      if (*mp<*mq)
2909      {
2910        if (b) return 0;
2911        a =TRUE;
2912      }
2913      else if (*mp>*mq)
2914      {
2915        if (a) return 0;
2916        b = TRUE;
2917      }
2918    }
2919    if (a) return 1;
2920    else if (b)  return -1;
2921  }
2922  return 0;
2923}
2924#endif
2925/*2
2926*divides p1 by its leading monomial
2927*/
2928void pNorm(poly p1)
2929{
2930  poly h;
2931  number k, c;
2932
2933  if (p1!=NULL)
2934  {
2935    if (!nIsOne(pGetCoeff(p1)))
2936    {
2937      nNormalize(pGetCoeff(p1));
2938      k=pGetCoeff(p1);
2939      c = nInit(1);
2940      pSetCoeff0(p1,c);
2941      h = pNext(p1);
2942      while (h!=NULL)
2943      {
2944        c=nDiv(pGetCoeff(h),k);
2945        if (!nIsOne(c)) nNormalize(c);
2946        pSetCoeff(h,c);
2947        pIter(h);
2948      }
2949      nDelete(&k);
2950    }
2951    else
2952    {
2953      h = pNext(p1);
2954      while (h!=NULL)
2955      {
2956        nNormalize(pGetCoeff(h));
2957        pIter(h);
2958      }
2959    }
2960  }
2961}
2962
2963/*2
2964*normalize all coeffizients
2965*/
2966void pNormalize(poly p)
2967{
2968  while (p!=NULL)
2969  {
2970    nTest(pGetCoeff(p));
2971    nNormalize(pGetCoeff(p));
2972    pIter(p);
2973  }
2974}
2975
2976/*3
2977* substitute the n-th variable by 1 in p
2978* destroy p
2979*/
2980static poly pSubst1 (poly p,int n)
2981{
2982  poly qq,result = NULL;
2983
2984  while (p != NULL)
2985  {
2986    qq = p;
2987    pIter(p);
2988    qq->next = NULL;
2989    pSetExp(qq,n,0);
2990    pSetm(qq);
2991    result = pAdd(result,qq);
2992  }
2993  return result;
2994}
2995
2996/*2
2997* substitute the n-th variable by e in p
2998* destroy p
2999*/
3000poly pSubst(poly p, int n, poly e)
3001{
3002  if ((e!=NULL)&&(pIsConstant(e))&&(nIsOne(pGetCoeff(e))))
3003    return pSubst1(p,n);
3004
3005  int exponent,i;
3006  poly h, res, m;
3007  Exponent_t *me,*ee;
3008  number nu,nu1;
3009
3010  me=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
3011  ee=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
3012  if (e!=NULL) pGetExpV(e,ee);
3013  res=NULL;
3014  h=p;
3015  while (h!=NULL)
3016  {
3017    if ((e!=NULL) || (pGetExp(h,n)==0))
3018    {
3019      m=pHead(h);
3020      pGetExpV(m,me);
3021      exponent=me[n];
3022      me[n]=0;
3023      for(i=1;i<=pVariables;i++)
3024        me[i]+=exponent*ee[i];
3025      pSetExpV(m,me);
3026      if (e!=NULL)
3027      {
3028        nPower(pGetCoeff(e),exponent,&nu);
3029        nu1=nMult(pGetCoeff(m),nu);
3030        nDelete(&nu);
3031        pSetCoeff(m,nu1);
3032      }
3033      res=pAdd(res,m);
3034    }
3035    pDelete1(&h);
3036  }
3037  Free((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
3038  Free((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
3039  return res;
3040}
3041
3042BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
3043{
3044  int k, j;
3045
3046  if (lcm==NULL) return FALSE;
3047
3048  for (j=pVariables; j; j--)
3049    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
3050  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
3051  for (j=pVariables; j; j--)
3052  {
3053    if (pGetExp(p1,j)!=pGetExp(lcm,j))
3054    {
3055      if (pGetExp(p,j)!=pGetExp(lcm,j))
3056      {
3057        for (k=pVariables; k>j; k--)
3058        {
3059          if ((pGetExp(p,k)!=pGetExp(lcm,k))
3060          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
3061            return TRUE;
3062        }
3063        for (k=j-1; k; k--)
3064        {
3065          if ((pGetExp(p,k)!=pGetExp(lcm,k))
3066          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
3067            return TRUE;
3068        }
3069        return FALSE;
3070      }
3071    }
3072    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
3073    {
3074      if (pGetExp(p,j)!=pGetExp(lcm,j))
3075      {
3076        for (k=pVariables; k>j; k--)
3077        {
3078          if ((pGetExp(p,k)!=pGetExp(lcm,k))
3079          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
3080            return TRUE;
3081        }
3082        for (k=j-1; k; k--)
3083        {
3084          if ((pGetExp(p,k)!=pGetExp(lcm,k))
3085          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
3086            return TRUE;
3087        }
3088        return FALSE;
3089      }
3090    }
3091  }
3092  return FALSE;
3093}
3094
3095int pWeight(int i)
3096{
3097  if ((firstwv==NULL) || (i>firstBlockEnds))
3098  {
3099    return 1;
3100  }
3101  return firstwv[i-1];
3102}
3103
3104#ifdef COMP_DEBUG
3105static int debug_comp(poly p1, poly p2)
3106{
3107  int t_d = t_pComp0(p1, p2);
3108  int f_d = f_pComp0(p1, p2);
3109
3110  if (t_d != f_d)
3111  {
3112    fprintf(stderr, "Error in comp1lpc\n");
3113    t_pComp0(p1, p2);
3114    f_pComp0(p1, p2);
3115  }
3116  return t_d;
3117}
3118#endif
3119
3120#ifdef COMP_STATISTICS
3121static int s_comp_lp_c_1(poly p1, poly p2) 
3122{
3123  MonomCountTotal++;
3124
3125  OrderCmp(p2, p1,
3126           {MonomCountOrderS++; return -1;},
3127           {MonomCountOrderG++; return 1;});
3128 
3129  CompCmp(p2, p1,
3130          {MonomCountCompS++; return -pComponentOrder},
3131          {MonomCountCompG++; return pComponentOrder});
3132
3133  MonomCountEqual++;
3134  return 0;
3135}
3136#endif
3137
3138#ifdef COMP_STATISTICS
3139static int s_comp_lp_c_i(poly p1, poly p2) 
3140{
3141  MonomCountTotal++;
3142
3143  OrderCmp(p2, p1,
3144           {MonomCountOrderS++; return -1;},
3145           {MonomCountOrderG++; return 1;});
3146
3147  int i = SIZEOF_ORDER / SIZEOF_EXPONENT + 1;
3148  Exponent_t d;
3149 
3150
3151  for (;;)
3152  {
3153    d = pGetExp(p1, i)  - pGetExp(p2, i);
3154    if (d)
3155    {
3156      MonomCountExp[i]++;
3157      if (d < 0)
3158      {
3159        return -1;
3160        MonomCountExpS++;
3161      }
3162      MonomCountExpG++;
3163      return 1;
3164    }
3165    i++;
3166    if (i == pVariables) break;
3167  }
3168 
3169  CompCmp(p2, p1,
3170          {MonomCountCompS++; return -pComponentOrder},
3171          {MonomCountCompG++; return pComponentOrder});
3172
3173  MonomCountEqual++;
3174  return 0;
3175}
3176#endif
3177
3178#ifdef MONOM_COUNT
3179static void InitMonomCount(unsigned int nvars)
3180{
3181  if (gMonomCount == NULL)
3182  {
3183    gMonomCount = (unsigned long *) Alloc0(nvars*sizeof(int));
3184    gMonomCountLength = nvars;
3185  }
3186  else if (gMonomCountLength < nvars)
3187  {
3188    int i;
3189    gMonomCount = (unsigned long *) ReAlloc(gMonomCount,
3190                                          gMonomCountLength*sizeof(int),
3191                                          nvars*sizeof(int));
3192    for (i = gMonomCountLength; i< nvars; i++)
3193      gMonomCount[i] = 0; 
3194    gMonomCountLength = nvars;
3195  }
3196}
3197
3198void OutputMonomCount()
3199{
3200  unsigned int i;
3201  unsigned long max = gMonomCount0;
3202  float fmax;
3203  unsigned long sum = 0;
3204 
3205
3206  // check that everything went ok
3207  if (gMonomCountS !=
3208      gMonomCount0 + gMonomCountOrder + gMonomCountL + gMonomCountG)
3209  {
3210    printf("MonomCountTotalError: %10lu %10lu\n", gMonomCountS,
3211           gMonomCount0 + gMonomCountOrder + gMonomCountL + gMonomCountG);
3212  }
3213  for (i=0; i<gMonomCountLength; i++)
3214    sum += gMonomCount[i];
3215  if (sum != gMonomCountL + gMonomCountG)
3216  {
3217    printf("MonomCountNotEqualError: %10lu %10lu\n",
3218           gMonomCountL + gMonomCountG, sum);
3219  }
3220
3221  printf("Total   : %10lu\n", gMonomCountS);
3222  if (gMonomCountS == 0) gMonomCountS = 1;
3223 
3224  printf("Order   : %10lu \t %.4f\n",gMonomCountOrder,
3225         (float) gMonomCountOrder / (float) gMonomCountS);
3226  printf("Equal   : %10lu \t %.4f\n",gMonomCount0,
3227         (float) gMonomCount0 / (float) gMonomCountS);
3228  printf("NotEqual: %10lu \t %.4f\n",gMonomCountL + gMonomCountG,
3229         ((float) gMonomCountL + gMonomCountG) / (float) gMonomCountS);
3230  printf("\tGreater: %10lu \t %.4f\n",gMonomCountG,
3231         (float) gMonomCountG / (float) gMonomCountS);
3232  printf("\tLess   : %10lu \t %.4f\n",gMonomCountL,
3233         (float) gMonomCountL / (float) gMonomCountS);
3234
3235  for (i=0; i<gMonomCountLength; i++)
3236  {
3237    printf("\t\t[%d]    : %10lu \t %.4f\n", i, gMonomCount[i],
3238           (float) gMonomCount[i] / (float) gMonomCountS);
3239  }
3240  printf("E1Neg   : %10lu \t %.4f\n",gMonomCountN1,
3241         (float) gMonomCountN1 / (float) gMonomCountS);
3242  printf("E2Neg   : %10lu \t %.4f\n",gMonomCountN2,
3243         (float) gMonomCountN2 / (float) gMonomCountS);
3244  printf("BothNeg : %10lu \t %.4f\n",gMonomCountNN,
3245         (float) gMonomCountNN / (float) gMonomCountS);
3246  printf("Mcount2 : %u\n", gMcount2);
3247}
3248
3249void ResetMonomCount()
3250{
3251  int i;
3252
3253  for (i=0; i<gMonomCountLength; i++)
3254    gMonomCount[i] = 0;
3255  gMonomCountOrder = 0;
3256  gMonomCount0 = 0;
3257  gMonomCountS = 0;
3258  gMonomCountG = 0;
3259  gMonomCountL = 0;
3260  gMonomCountN1 = 0;
3261  gMonomCountN2 = 0;
3262  gMonomCountNN = 0;
3263  gMcount2 = 0;
3264}
3265
3266#endif
3267#ifdef MONOM_COUNT
3268unsigned long  gMonomCount0 = 0;
3269unsigned long  gMonomCountLength = 0;
3270unsigned long  gMonomCountOrder = 0;
3271unsigned long  gMonomCountG = 0;
3272unsigned long  gMonomCountL = 0;
3273unsigned long  gMonomCountS = 0;
3274unsigned long  gMonomCountN1 = 0;
3275unsigned long  gMonomCountN2 = 0;
3276unsigned long  gMonomCountNN = 0;
3277unsigned long  gMcount2 = 0;
3278unsigned long* gMonomCount = NULL;
3279#endif
Note: See TracBrowser for help on using the repository browser.