source: git/Singular/walk.cc @ f9b0bd

spielwiese
Last change on this file since f9b0bd was f9b0bd, checked in by Hans Schoenemann <hannes@…>, 7 years ago
chg: Print -> PrintS, PrintLn if possible
  • Property mode set to 100644
File size: 235.5 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/*
5* ABSTRACT: Implementation of the Groebner walk
6*/
7
8// define if the Buchberger alg should be used
9//   to compute a reduced GB of a omega-homogenoues ideal
10// default: we use the hilbert driven algorithm.
11#define BUCHBERGER_ALG  //we use the improved Buchberger alg.
12
13//#define UPPER_BOUND //for the original "Tran" algorithm
14//#define REPRESENTATION_OF_SIGMA //if one perturbs sigma in Tran
15
16//#define TEST_OVERFLOW
17
18#define CHECK_IDEAL_MWALK //to print intermediate results
19
20//#define NEXT_VECTORS_CC
21//#define PRINT_VECTORS //to print weight vectors
22
23#define INVEPS_SMALL_IN_FRACTAL  //to choose the small invers of epsilon
24#define INVEPS_SMALL_IN_MPERTVECTOR  //to choose the small invers of epsilon
25#define INVEPS_SMALL_IN_TRAN  //to choose the small invers of epsilon
26
27#define FIRST_STEP_FRACTAL // to define the first step of the fractal
28#define MSTDCC_FRACTAL // apply Buchberger alg to compute a red GB, if tau doesn't stay in the correct cone
29
30//#define TIME_TEST // print the used time of each subroutine
31//#define ENDWALKS //print the size of the last omega-homogenoues Groebner basis
32
33/* includes */
34
35#include <kernel/mod2.h>
36#include <misc/intvec.h>
37#include <Singular/cntrlc.h>
38#include <misc/options.h>
39#include <omalloc/omalloc.h>
40#include <Singular/ipshell.h>
41#include <Singular/ipconv.h>
42#include <coeffs/ffields.h>
43#include <coeffs/coeffs.h>
44#include <Singular/subexpr.h>
45#include <polys/templates/p_Procs.h>
46
47#include <polys/monomials/maps.h>
48
49/* include Hilbert-function */
50#include <kernel/combinatorics/stairc.h>
51
52/** kstd2.cc */
53#include <kernel/GBEngine/kutil.h>
54#include <kernel/GBEngine/khstd.h>
55
56#include <Singular/walk.h>
57#include <kernel/polys.h>
58#include <kernel/ideals.h>
59#include <Singular/ipid.h>
60#include <Singular/tok.h>
61#include <coeffs/numbers.h>
62#include <Singular/ipid.h>
63#include <polys/monomials/ring.h>
64#include <kernel/GBEngine/kstd1.h>
65#include <polys/matpol.h>
66#include <polys/weight.h>
67#include <misc/intvec.h>
68#include <kernel/GBEngine/syz.h>
69#include <Singular/lists.h>
70#include <polys/prCopy.h>
71#include <polys/monomials/ring.h>
72//#include <polys/ext_fields/longalg.h>
73#include <polys/clapsing.h>
74
75#include <coeffs/mpr_complex.h>
76
77#include <stdio.h>
78// === Zeit & System (Holger Croeni ===
79#include <time.h>
80#include <sys/time.h>
81#include <math.h>
82#include <sys/stat.h>
83#include <unistd.h>
84#include <float.h>
85#include <misc/mylimits.h>
86#include <sys/types.h>
87
88int nstep;
89
90extern BOOLEAN ErrorCheck();
91
92extern BOOLEAN pSetm_error;
93
94void Set_Error( BOOLEAN f) { pSetm_error=f; }
95
96BOOLEAN Overflow_Error =  FALSE;
97
98clock_t xtif, xtstd, xtlift, xtred, xtnw;
99clock_t xftostd, xtextra, xftinput, to;
100
101/****************************
102 * utilities for TSet, LSet *
103 ****************************/
104inline static intset initec (int maxnr)
105{
106  return (intset)omAlloc(maxnr*sizeof(int));
107}
108
109inline static unsigned long* initsevS (int maxnr)
110{
111  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
112}
113inline static int* initS_2_R (int maxnr)
114{
115  return (int*)omAlloc0(maxnr*sizeof(int));
116}
117
118/************************************
119 * construct the set s from F u {P} *
120 ************************************/
121// unused
122/*
123static void initSSpecialCC (ideal F, ideal Q, ideal P,kStrategy strat)
124{
125  int   i,pos;
126
127  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
128  else i=setmaxT;
129
130  strat->ecartS=initec(i);
131  strat->sevS=initsevS(i);
132  strat->S_2_R=initS_2_R(i);
133  strat->fromQ=NULL;
134  strat->Shdl=idInit(i,F->rank);
135  strat->S=strat->Shdl->m;
136
137  // - put polys into S -
138  if (Q!=NULL)
139  {
140    strat->fromQ=initec(i);
141    memset(strat->fromQ,0,i*sizeof(int));
142    for (i=0; i<IDELEMS(Q); i++)
143    {
144      if (Q->m[i]!=NULL)
145      {
146        LObject h;
147        h.p = pCopy(Q->m[i]);
148        //if (TEST_OPT_INTSTRATEGY)
149        //{
150        //  //pContent(h.p);
151        //  h.pCleardenom(); // also does a pContent
152        //}
153        //else
154        //{
155        //  h.pNorm();
156        //}
157        strat->initEcart(&h);
158        if (rHasLocalOrMixedOrdering_currRing())
159        {
160          deleteHC(&h,strat);
161        }
162        if (h.p!=NULL)
163        {
164          if (strat->sl==-1)
165            pos =0;
166          else
167          {
168            pos = posInS(strat,strat->sl,h.p,h.ecart);
169          }
170          h.sev = pGetShortExpVector(h.p);
171          h.SetpFDeg();
172          strat->enterS(h,pos,strat, strat->tl+1);
173          enterT(h, strat);
174          strat->fromQ[pos]=1;
175        }
176      }
177    }
178  }
179  //- put polys into S -
180  for (i=0; i<IDELEMS(F); i++)
181  {
182    if (F->m[i]!=NULL)
183    {
184      LObject h;
185      h.p = pCopy(F->m[i]);
186      if (rHasGlobalOrdering(currRing))
187      {
188        //h.p=redtailBba(h.p,strat->sl,strat);
189        h.p=redtailBba(h.p,strat->sl,strat);
190      }
191      else
192      {
193        deleteHC(&h,strat);
194      }
195      strat->initEcart(&h);
196      if (h.p!=NULL)
197      {
198        if (strat->sl==-1)
199          pos =0;
200        else
201          pos = posInS(strat,strat->sl,h.p,h.ecart);
202        h.sev = pGetShortExpVector(h.p);
203        strat->enterS(h,pos,strat, strat->tl+1);
204        h.length = pLength(h.p);
205        h.SetpFDeg();
206        enterT(h,strat);
207      }
208    }
209  }
210#ifdef INITSSPECIAL
211  for (i=0; i<IDELEMS(P); i++)
212  {
213    if (P->m[i]!=NULL)
214    {
215      LObject h;
216      h.p=pCopy(P->m[i]);
217      strat->initEcart(&h);
218      h.length = pLength(h.p);
219      if (TEST_OPT_INTSTRATEGY)
220      {
221        h.pCleardenom();
222      }
223      else
224      {
225        h.pNorm();
226      }
227      if(strat->sl>=0)
228      {
229        if (rHasGlobalOrdering(currRing))
230        {
231          h.p=redBba(h.p,strat->sl,strat);
232          if (h.p!=NULL)
233            h.p=redtailBba(h.p,strat->sl,strat);
234        }
235        else
236        {
237          h.p=redMora(h.p,strat->sl,strat);
238          strat->initEcart(&h);
239        }
240        if(h.p!=NULL)
241        {
242          if (TEST_OPT_INTSTRATEGY)
243          {
244            h.pCleardenom();
245          }
246          else
247          {
248            h.is_normalized = 0;
249            h.pNorm();
250          }
251          h.sev = pGetShortExpVector(h.p);
252          h.SetpFDeg();
253          pos = posInS(strat->S,strat->sl,h.p,h.ecart);
254          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
255          strat->enterS(h,pos,strat, strat->tl+1);
256          enterT(h,strat);
257        }
258      }
259      else
260      {
261        h.sev = pGetShortExpVector(h.p);
262        h.SetpFDeg();
263        strat->enterS(h,0,strat, strat->tl+1);
264        enterT(h,strat);
265      }
266    }
267  }
268#endif
269}
270*/
271
272/*****************
273 *interreduce F  *
274 *****************/
275static ideal kInterRedCC(ideal F, ideal Q)
276{
277  int j;
278  kStrategy strat = new skStrategy;
279/*
280  if (TEST_OPT_PROT)
281  {
282    writeTime("start InterRed:");
283    mflush();
284  }
285  strat->syzComp     = 0;
286*/
287  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
288  strat->kNoether=pCopy((currRing->ppNoether));
289  strat->ak = id_RankFreeModule(F, currRing);
290  initBuchMoraCrit(strat);
291  strat->NotUsedAxis = (BOOLEAN *)omAlloc((currRing->N+1)*sizeof(BOOLEAN));
292  for(j=currRing->N; j>0; j--)
293  {
294    strat->NotUsedAxis[j] = TRUE;
295  }
296  strat->enterS      = enterSBba;
297  strat->posInT      = posInT0;
298  strat->initEcart   = initEcartNormal;
299  strat->sl   = -1;
300  strat->tl          = -1;
301  strat->tmax        = setmaxT;
302  strat->T           = initT();
303  strat->R           = initR();
304  strat->sevT        = initsevT();
305  if(rHasLocalOrMixedOrdering_currRing())
306  {
307    strat->honey = TRUE;
308  }
309
310  //initSCC(F,Q,strat);
311  initS(F,Q,strat);
312
313  /*
314  timetmp=clock();//22.01.02
315  initSSpecialCC(F,Q,NULL,strat);
316  tininitS=tininitS+clock()-timetmp;//22.01.02
317  */
318  if(TEST_OPT_REDSB)
319  {
320    strat->noTailReduction=FALSE;
321  }
322  updateS(TRUE,strat);
323
324  if(TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
325  {
326    completeReduce(strat);
327  }
328  pDelete(&strat->kHEdge);
329  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
330  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
331  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
332  omFreeSize((ADDRESS)strat->NotUsedAxis,(currRing->N+1)*sizeof(BOOLEAN));
333  omfree(strat->sevT);
334  omfree(strat->S_2_R);
335  omfree(strat->R);
336
337  if(strat->fromQ)
338  {
339    for(j=0; j<IDELEMS(strat->Shdl); j++)
340    {
341      if(strat->fromQ[j])
342      {
343        pDelete(&strat->Shdl->m[j]);
344      }
345    }
346    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
347    strat->fromQ = NULL;
348  }
349/*
350  if (TEST_OPT_PROT)
351  {
352    writeTime("end Interred:");
353    mflush();
354  }
355*/
356  ideal shdl=strat->Shdl;
357  idSkipZeroes(shdl);
358  delete(strat);
359
360  return shdl;
361}
362
363#ifdef TIME_TEST
364static void TimeString(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
365                       clock_t tlf,clock_t tred, clock_t tnw, int step)
366{
367  double totm = ((double) (clock() - tinput))/1000000;
368  double ostd,mostd, mif, mstd, mlf, mred, mnw, mxif,mxstd,mxlf,mxred,mxnw,tot;
369  // double mextra
370  Print("\n// total time = %.2f sec", totm);
371  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
372        mostd=((((double) tostd)/1000000)/totm)*100);
373  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
374        mif=((((double) tif)/1000000)/totm)*100);
375  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
376        mstd=((((double) tstd)/1000000)/totm)*100);
377  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
378        mlf=((((double) tlf)/1000000)/totm)*100);
379  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
380        mred=((((double) tred)/1000000)/totm)*100);
381  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
382        mnw=((((double) tnw)/1000000)/totm)*100);
383  PrintS("\n Time for the last step:");
384  Print("\n// xinfo = %.2f sec = %.2f", ((double) xtif)/1000000,
385        mxif=((((double) xtif)/1000000)/totm)*100);
386  Print("\n// xstd  = %.2f sec = %.2f", ((double) xtstd)/1000000,
387        mxstd=((((double) xtstd)/1000000)/totm)*100);
388  Print("\n// xlift = %.2f sec = %.2f", ((double) xtlift)/1000000,
389        mxlf=((((double) xtlift)/1000000)/totm)*100);
390  Print("\n// xired = %.2f sec = %.2f", ((double) xtred)/1000000,
391        mxred=((((double) xtred)/1000000)/totm)*100);
392  Print("\n// xnextw= %.2f sec = %.2f", ((double) xtnw)/1000000,
393        mxnw=((((double) xtnw)/1000000)/totm)*100);
394
395  tot=mostd+mif+mstd+mlf+mred+mnw+mxif+mxstd+mxlf+mxred+mxnw;
396  double res = (double) 100 - tot;
397  Print("\n// &%d&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f(%.2f)\\ \\",
398        step, ostd, totm, mostd,mif,mstd,mlf,mred,mnw,mxif,mxstd,mxlf,mxred,mxnw,tot,res,
399        ((((double) xtextra)/1000000)/totm)*100);
400}
401
402static void TimeStringFractal(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
403                       clock_t textra, clock_t tlf,clock_t tred, clock_t tnw)
404{
405
406  double totm = ((double) (clock() - tinput))/1000000;
407  double ostd, mostd, mif, mstd, mextra, mlf, mred, mnw, tot, res;
408  Print("\n// total time = %.2f sec", totm);
409  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
410        mostd=((((double) tostd)/1000000)/totm)*100);
411  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
412        mif=((((double) tif)/1000000)/totm)*100);
413  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
414        mstd=((((double) tstd)/1000000)/totm)*100);
415  Print("\n// xstd  = %.2f sec = %.2f", ((double) textra)/1000000,
416        mextra=((((double) textra)/1000000)/totm)*100);
417  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
418        mlf=((((double) tlf)/1000000)/totm)*100);
419  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
420        mred=((((double) tred)/1000000)/totm)*100);
421  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
422        mnw=((((double) tnw)/1000000)/totm)*100);
423  tot = mostd+mif+mstd+mextra+mlf+mred+mnw;
424  res = (double) 100.00-tot;
425  Print("\n// &%.2f &%.2f&%.2f &%.2f &%.2f &%.2f &%.2f &%.2f &%.2f&%.2f&%.2f\\ \\ ",
426        ostd,totm,mostd,mif,mstd,mextra,mlf,mred,mnw,tot,res);
427}
428#endif
429
430#ifdef CHECK_IDEAL_MWALK
431static void idString(ideal L, const char* st)
432{
433  int i, nL = IDELEMS(L);
434
435  Print("\n//  ideal %s =  ", st);
436  for(i=0; i<nL-1; i++)
437  {
438    Print(" %s, ", pString(L->m[i]));
439  }
440  Print(" %s;", pString(L->m[nL-1]));
441}
442#endif
443/*
444#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
445static void headidString(ideal L, char* st)
446{
447  int i, nL = IDELEMS(L);
448
449  Print("\n//  ideal %s =  ", st);
450  for(i=0; i<nL-1; i++)
451  {
452    Print(" %s, ", pString(pHead(L->m[i])));
453  }
454  Print(" %s;", pString(pHead(L->m[nL-1])));
455}
456#endif
457
458#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
459static void idElements(ideal L, char* st)
460{
461  int i, nL = IDELEMS(L);
462  int *K=(int *)omAlloc(nL*sizeof(int));
463
464  Print("\n//  #monoms of %s =  ", st);
465  for(i=0; i<nL; i++)
466  {
467    K[i] = pLength(L->m[i]);
468  }
469  int j, nsame;
470  // int  nk=0;
471  for(i=0; i<nL; i++)
472  {
473    if(K[i]!=0)
474    {
475      nsame = 1;
476      for(j=i+1; j<nL; j++)
477      {
478        if(K[j]==K[i])
479        {
480          nsame ++;
481          K[j]=0;
482        }
483      }
484      if(nsame == 1)
485      {
486        Print("%d, ",K[i]);
487      }
488      else
489      {
490        Print("%d[%d], ", K[i], nsame);
491      }
492    }
493  }
494  omFree(K);
495}
496#endif
497*/
498
499static void ivString(intvec* iv, const char* ch)
500{
501  int nV = iv->length()-1;
502  Print("\n// intvec %s =  ", ch);
503
504  for(int i=0; i<nV; i++)
505  {
506    Print("%d, ", (*iv)[i]);
507  }
508  Print("%d;", (*iv)[nV]);
509}
510
511#ifdef PRINT_VECTORS
512static void MivString(intvec* iva, intvec* ivb, intvec* ivc)
513{
514  int nV = iva->length()-1;
515  int i;
516  PrintS("\n//  (");
517  for(i=0; i<nV; i++)
518  {
519    Print("%d, ", (*iva)[i]);
520  }
521  Print("%d) ==> (", (*iva)[nV]);
522  for(i=0; i<nV; i++)
523  {
524    Print("%d, ", (*ivb)[i]);
525  }
526  Print("%d) := (", (*ivb)[nV]);
527
528  for(i=0; i<nV; i++)
529  {
530    Print("%d, ", (*ivc)[i]);
531  }
532  Print("%d)", (*ivc)[nV]);
533}
534#endif
535
536/********************************************************************
537 * returns gcd of integers a and b                                  *
538 ********************************************************************/
539static inline long gcd(const long a, const long b)
540{
541  long r, p0 = a, p1 = b;
542  //assume(p0 >= 0 && p1 >= 0);
543  if(p0 < 0)
544  {
545    p0 = -p0;
546  }
547  if(p1 < 0)
548  {
549    p1 = -p1;
550  }
551  while(p1 != 0)
552  {
553    r = p0 % p1;
554    p0 = p1;
555    p1 = r;
556  }
557  return p0;
558}
559
560/*****************************************************************************
561 * compute the gcd of the entries of the vectors curr_weight and diff_weight *
562 *****************************************************************************/
563/* unused:
564static int simplify_gcd(intvec* curr_weight, intvec* diff_weight)
565{
566  int j;
567  int nRing = currRing->N;
568  int gcd_tmp = (*curr_weight)[0];
569  for (j=1; j<nRing; j++)
570  {
571    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
572    if(gcd_tmp == 1)
573    {
574      break;
575    }
576  }
577  if(gcd_tmp != 1)
578  {
579    for (j=0; j<nRing; j++)
580    {
581    gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
582    if(gcd_tmp == 1)
583      {
584        break;
585      }
586    }
587  }
588  return gcd_tmp;
589}
590*/
591
592/*********************************************
593 * cancel gcd of integers zaehler and nenner *
594 *********************************************/
595static void cancel(mpz_t zaehler, mpz_t nenner)
596{
597//  assume(zaehler >= 0 && nenner > 0);
598  mpz_t g;
599  mpz_init(g);
600  mpz_gcd(g, zaehler, nenner);
601
602  mpz_div(zaehler , zaehler, g);
603  mpz_div(nenner ,  nenner, g);
604
605  mpz_clear(g);
606}
607
608//unused
609#if 0
610static int isVectorNeg(intvec* omega)
611{
612  int i;
613
614  for(i=omega->length(); i>=0; i--)
615  {
616    if((*omega)[i]<0)
617    {
618      return 1;
619    }
620  }
621  return 0;
622}
623#endif
624
625/********************************************************************
626 * compute a weight degree of a monomial p w.r.t. a weight_vector   *
627 ********************************************************************/
628static inline int MLmWeightedDegree(const poly p, intvec* weight)
629{
630  /* 2147483647 is max. integer representation in SINGULAR */
631  mpz_t sing_int;
632  mpz_init_set_ui(sing_int,  2147483647);
633
634  int i, wgrad;
635
636  mpz_t zmul;
637  mpz_init(zmul);
638  mpz_t zvec;
639  mpz_init(zvec);
640  mpz_t zsum;
641  mpz_init(zsum);
642
643  for (i=currRing->N; i>0; i--)
644  {
645    mpz_set_si(zvec, (*weight)[i-1]);
646    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
647    mpz_add(zsum, zsum, zmul);
648  }
649
650  wgrad = mpz_get_ui(zsum);
651
652  if(mpz_cmp(zsum, sing_int)>0)
653  {
654    if(Overflow_Error ==  FALSE)
655    {
656      PrintLn();
657      PrintS("\n// ** OVERFLOW in \"MwalkInitialForm\": ");
658      mpz_out_str( stdout, 10, zsum);
659      PrintS(" is greater than 2147483647 (max. integer representation)");
660      Overflow_Error = TRUE;
661    }
662  }
663
664  mpz_clear(zmul);
665  mpz_clear(zvec);
666  mpz_clear(zsum);
667  mpz_clear(sing_int);
668
669  return wgrad;
670}
671
672/********************************************************************
673 * compute a weight degree of a polynomial p w.r.t. a weight_vector *
674 ********************************************************************/
675static inline int MwalkWeightDegree(poly p, intvec* weight_vector)
676{
677  assume(weight_vector->length() >= currRing->N);
678  int max = 0, maxtemp;
679
680  while(p != NULL)
681  {
682    maxtemp = MLmWeightedDegree(p, weight_vector);
683    pIter(p);
684
685    if (maxtemp > max)
686    {
687      max = maxtemp;
688    }
689  }
690  return max;
691}
692
693
694/********************************************************************
695 * compute a weight degree of a monomial p w.r.t. a weight_vector   *
696 ********************************************************************/
697static  void  MLmWeightedDegree_gmp(mpz_t result, const poly p, intvec* weight)
698{
699  /* 2147483647 is max. integer representation in SINGULAR */
700  mpz_t sing_int;
701  mpz_init_set_ui(sing_int,  2147483647);
702
703  int i;
704
705  mpz_t zmul;
706  mpz_init(zmul);
707  mpz_t zvec;
708  mpz_init(zvec);
709  mpz_t ztmp;
710  mpz_init(ztmp);
711
712  for (i=currRing->N; i>0; i--)
713  {
714    mpz_set_si(zvec, (*weight)[i-1]);
715    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
716    mpz_add(ztmp, ztmp, zmul);
717  }
718  mpz_init_set(result, ztmp);
719  mpz_clear(ztmp);
720  mpz_clear(sing_int);
721  mpz_clear(zvec);
722  mpz_clear(zmul);
723}
724
725
726/*****************************************************************************
727 * return an initial form of the polynom g w.r.t. a weight vector curr_weight *
728 *****************************************************************************/
729static poly MpolyInitialForm(poly g, intvec* curr_weight)
730{
731  if(g == NULL)
732  {
733    return NULL;
734  }
735  mpz_t max; mpz_init(max);
736  mpz_t maxtmp; mpz_init(maxtmp);
737
738  poly hg, in_w_g = NULL;
739
740  while(g != NULL)
741  {
742    hg = g;
743    pIter(g);
744    MLmWeightedDegree_gmp(maxtmp, hg, curr_weight);
745
746    if(mpz_cmp(maxtmp, max)>0)
747    {
748      mpz_set(max, maxtmp);
749      if (in_w_g!=NULL) pDelete(&in_w_g);
750      in_w_g = pHead(hg);
751    }
752    else
753    {
754      if(mpz_cmp(maxtmp, max)==0)
755      {
756        in_w_g = pAdd(in_w_g, pHead(hg));
757      }
758    }
759  }
760  mpz_clear(maxtmp);
761  mpz_clear(max);
762  return in_w_g;
763}
764
765/************************************************************************
766 * compute the initial form of an ideal <G> w.r.t. a weight vector iva  *
767 ************************************************************************/
768ideal MwalkInitialForm(ideal G, intvec* ivw)
769{
770  BOOLEAN nError =  Overflow_Error;
771  Overflow_Error = FALSE;
772
773  int i, nG = IDELEMS(G);
774  ideal Gomega = idInit(nG, 1);
775
776  for(i=nG-1; i>=0; i--)
777  {
778    Gomega->m[i] = MpolyInitialForm(G->m[i], ivw);
779  }
780  if(Overflow_Error == FALSE)
781  {
782    Overflow_Error = nError;
783  }
784  return Gomega;
785}
786
787/************************************************************************
788 * test whether the weight vector iv is in the cone of the ideal G      *
789 *     i.e. test whether in(in_w(g)) = in(g) for all g in G             *
790 ************************************************************************/
791
792static int test_w_in_ConeCC(ideal G, intvec* iv)
793{
794  if(G->m[0] == NULL)
795  {
796    PrintS("//** the result may be WRONG, i.e. 0!!\n");
797    return 0;
798  }
799
800  BOOLEAN nError =  Overflow_Error;
801  Overflow_Error = FALSE;
802
803  int i, nG = IDELEMS(G);
804  poly mi, gi;
805
806  for(i=nG-1; i>=0; i--)
807  {
808    mi = MpolyInitialForm(G->m[i], iv);
809    //Print("\n **// test_w_in_ConeCC: lm(initial)= %s \n",pString(mi));
810    gi = G->m[i];
811    //Print("\n **// test_w_in_ConeCC: lm(ideal)= %s \n",pString(gi));
812    if(mi == NULL)
813    {
814      if(Overflow_Error == FALSE)
815      {
816        Overflow_Error = nError;
817      }
818      return 0;
819    }
820    if(!pLmEqual(mi, gi))
821    {
822      pDelete(&mi);
823      if(Overflow_Error == FALSE)
824      {
825        Overflow_Error = nError;
826      }
827      return 0;
828    }
829    pDelete(&mi);
830  }
831
832  if(Overflow_Error == FALSE)
833  {
834    Overflow_Error = nError;
835  }
836  return 1;
837}
838
839/***************************************************
840 * compute a least common multiple of two integers *
841 ***************************************************/
842static inline long Mlcm(long &i1, long &i2)
843{
844  long temp = gcd(i1, i2);
845  return ((i1 / temp)* i2);
846}
847
848
849/***************************************************
850 * return  the dot product of two intvecs a and b  *
851 ***************************************************/
852static inline long  MivDotProduct(intvec* a, intvec* b)
853{
854  assume( a->length() ==  b->length());
855  int i, n = a->length();
856  long result = 0;
857
858  for(i=n-1; i>=0; i--)
859    {
860    result += (*a)[i] * (*b)[i];
861    }
862  return result;
863}
864
865/*****************************************************
866 * Substract two given intvecs componentwise         *
867 *****************************************************/
868static intvec* MivSub(intvec* a, intvec* b)
869{
870  assume( a->length() ==  b->length());
871  int i, n = a->length();
872  intvec* result = new intvec(n);
873
874  for(i=n-1; i>=0; i--)
875  {
876    (*result)[i] = (*a)[i] - (*b)[i];
877  }
878  return result;
879}
880
881/*****************************************************
882 * return the "intvec" lead exponent of a polynomial *
883 *****************************************************/
884static intvec* MExpPol(poly f)
885{
886  int i, nR = currRing->N;
887  intvec* result = new intvec(nR);
888
889  for(i=nR-1; i>=0; i--)
890  {
891    (*result)[i] = pGetExp(f,i+1);
892  }
893  return result;
894}
895
896/*****************************************************
897 * Compare two given intvecs and return 1, if they   *
898 * are the same, otherwise 0                         *
899 *****************************************************/
900int MivSame(intvec* u , intvec* v)
901{
902  assume(u->length() == v->length());
903
904  int i, niv = u->length();
905
906  for (i=0; i<niv; i++)
907  {
908    if ((*u)[i] != (*v)[i])
909    {
910      return 0;
911    }
912  }
913  return 1;
914}
915
916/******************************************************
917 * Compare 3 given intvecs and return 0, if the first *
918 * and the second are the same. Return 1, if the      *
919 * the second and the third are the same, otherwise 2 *
920 ******************************************************/
921int M3ivSame(intvec* temp, intvec* u , intvec* v)
922{
923  assume(temp->length() == u->length() && u->length() == v->length());
924
925  if((MivSame(temp, u)) == 1)
926  {
927    return 0;
928  }
929  if((MivSame(temp, v)) == 1)
930  {
931    return 1;
932  }
933  return 2;
934}
935
936/*****************************************************
937 * compute a Groebner basis of an ideal              *
938 *****************************************************/
939static ideal MstdCC(ideal G)
940{
941  BITSET save1,save2;
942  SI_SAVE_OPT(save1,save2);
943  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
944  ideal G1 = kStd(G, NULL, testHomog, NULL);
945  SI_RESTORE_OPT(save1,save2);
946
947  idSkipZeroes(G1);
948  return G1;
949}
950
951/*****************************************************
952 * compute a Groebner basis of an homogeneous ideal  *
953 *****************************************************/
954static ideal MstdhomCC(ideal G)
955{
956  BITSET save1,save2;
957  SI_SAVE_OPT(save1,save2);
958  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
959  ideal G1 = kStd(G, NULL, isHomog, NULL);
960  SI_RESTORE_OPT(save1,save2);
961
962  idSkipZeroes(G1);
963  return G1;
964}
965
966
967/*****************************************************************************
968* create a weight matrix order as intvec of an extra weight vector (a(iv),lp)*
969******************************************************************************/
970intvec* MivMatrixOrder(intvec* iv)
971{
972  int i, nR = iv->length();
973
974  intvec* ivm = new intvec(nR*nR);
975
976  for(i=0; i<nR; i++)
977  {
978    (*ivm)[i] = (*iv)[i];
979  }
980  for(i=1; i<nR; i++)
981  {
982    (*ivm)[i*nR+i-1] = 1;
983  }
984  return ivm;
985}
986
987/*********************************************************************************
988* create a weight matrix order as intvec of an extra weight vector (a(iv),M(iw)) *
989**********************************************************************************/
990intvec* MivMatrixOrderRefine(intvec* iv, intvec* iw)
991{
992  assume((iv->length())*(iv->length()) == iw->length());
993  int i,j, nR = iv->length();
994
995  intvec* ivm = new intvec(nR*nR);
996
997  for(i=0; i<nR; i++)
998  {
999    (*ivm)[i] = (*iv)[i];
1000  }
1001  for(i=1; i<nR; i++)
1002  {
1003    for(j=0; j<nR; j++)
1004    {
1005      (*ivm)[j+i*nR] = (*iw)[j+i*nR];
1006    }
1007  }
1008  return ivm;
1009}
1010
1011/*******************************
1012 * return intvec = (1, ..., 1) *
1013 *******************************/
1014intvec* Mivdp(int nR)
1015{
1016  int i;
1017  intvec* ivm = new intvec(nR);
1018
1019  for(i=nR-1; i>=0; i--)
1020  {
1021    (*ivm)[i] = 1;
1022  }
1023  return ivm;
1024}
1025
1026/**********************************
1027 * return intvvec = (1,0, ..., 0) *
1028 **********************************/
1029intvec* Mivlp(int nR)
1030{
1031  intvec* ivm = new intvec(nR);
1032  (*ivm)[0] = 1;
1033
1034  return ivm;
1035}
1036
1037//unused
1038/*****************************************************************************
1039 * print the max total degree and the max coefficient of G                   *
1040 *****************************************************************************/
1041/*
1042static void checkComplexity(ideal G, char* cG)
1043{
1044  int nV = currRing->N;
1045  int nG = IDELEMS(G);
1046  intvec* ivUnit = Mivdp(nV);
1047  int i, tmpdeg, maxdeg=0;
1048  number tmpcoeff , maxcoeff=currRing->cf->nNULL;
1049  poly p;
1050  for(i=nG-1; i>=0; i--)
1051  {
1052    tmpdeg = MwalkWeightDegree(G->m[i], ivUnit);
1053    if(tmpdeg > maxdeg )
1054    {
1055      maxdeg = tmpdeg;
1056    }
1057  }
1058
1059  for(i=nG-1; i>=0; i--)
1060  {
1061    p = pCopy(G->m[i]);
1062    while(p != NULL)
1063    {
1064      //tmpcoeff = pGetCoeff(pHead(p));
1065      tmpcoeff = pGetCoeff(p);
1066      if(nGreater(tmpcoeff,maxcoeff))
1067      {
1068         maxcoeff = nCopy(tmpcoeff);
1069      }
1070      pIter(p);
1071    }
1072    pDelete(&p);
1073  }
1074  p = pNSet(maxcoeff);
1075  char* pStr = pString(p);
1076  delete ivUnit;
1077  Print("// max total degree of %s = %d\n",cG, maxdeg);
1078  Print("// max coefficient of %s  = %s", cG, pStr);//ing(p));
1079  Print(" which consists of %d digits", (int)strlen(pStr));
1080  PrintLn();
1081}
1082*/
1083
1084/*****************************************************************************
1085* If target_ord = intmat(A1, ..., An) then calculate the perturbation        *
1086* vectors                                                                    *
1087*   tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg     *
1088* where                                                                      *
1089*      inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                    *
1090* intmat target_ord is an integer order matrix of the monomial ordering of   *
1091* basering.                                                                  *
1092* This programm computes a perturbated vector with a p_deg perturbation      *
1093* degree which smaller than the numbers of variables                         *
1094******************************************************************************/
1095intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg)
1096{
1097  // ivtarget is a matrix order of a degree reverse lex. order
1098  int nV = currRing->N;
1099  //assume(pdeg <= nV && pdeg >= 0);
1100
1101  int i, j, nG = IDELEMS(G);
1102  intvec* v_null =  new intvec(nV);
1103
1104  // Check that the perturbed degree is valid
1105  if(pdeg > nV || pdeg <= 0)
1106  {
1107    WerrorS("//** The perturbed degree is wrong!!");
1108    return v_null;
1109  }
1110  delete v_null;
1111
1112  if(pdeg == 1)
1113  {
1114    return ivtarget;
1115  }
1116  mpz_t *pert_vector = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
1117  mpz_t *pert_vector1 = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
1118
1119  for(i=0; i<nV; i++)
1120  {
1121    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
1122    mpz_init_set_si(pert_vector1[i], (*ivtarget)[i]);
1123  }
1124  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
1125  // where the Ai are the i-te rows of the matrix target_ord.
1126  int ntemp, maxAi, maxA=0;
1127  for(i=1; i<pdeg; i++)
1128  {
1129    maxAi = (*ivtarget)[i*nV];
1130    if(maxAi<0)
1131    {
1132      maxAi = -maxAi;
1133    }
1134    for(j=i*nV+1; j<(i+1)*nV; j++)
1135    {
1136      ntemp = (*ivtarget)[j];
1137      if(ntemp < 0)
1138      {
1139        ntemp = -ntemp;
1140      }
1141      if(ntemp > maxAi)
1142      {
1143        maxAi = ntemp;
1144      }
1145    }
1146    maxA += maxAi;
1147  }
1148
1149  // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G.
1150
1151  intvec* ivUnit = Mivdp(nV);
1152
1153  mpz_t tot_deg; mpz_init(tot_deg);
1154  mpz_t maxdeg; mpz_init(maxdeg);
1155  mpz_t inveps; mpz_init(inveps);
1156
1157
1158  for(i=nG-1; i>=0; i--)
1159  {
1160     mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
1161     if (mpz_cmp(maxdeg,  tot_deg) > 0 )
1162     {
1163       mpz_set(tot_deg, maxdeg);
1164     }
1165  }
1166
1167  delete ivUnit;
1168  mpz_mul_ui(inveps, tot_deg, maxA);
1169  mpz_add_ui(inveps, inveps, 1);
1170
1171
1172  // takes  "small" inveps
1173#ifdef INVEPS_SMALL_IN_MPERTVECTOR
1174  if(mpz_cmp_ui(inveps, pdeg)>0 && pdeg > 3)
1175  {
1176    //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", mpz_get_si(inveps), pdeg);
1177    mpz_fdiv_q_ui(inveps, inveps, pdeg);
1178    // mpz_out_str(stdout, 10, inveps);
1179  }
1180#else
1181  // PrintS("\n// the \"big\" inverse epsilon: ");
1182  mpz_out_str(stdout, 10, inveps);
1183#endif
1184
1185  // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
1186  // pert_vector := A1
1187  for( i=1; i < pdeg; i++ )
1188  {
1189    for(j=0; j<nV; j++)
1190    {
1191      mpz_mul(pert_vector[j], pert_vector[j], inveps);
1192      if((*ivtarget)[i*nV+j]<0)
1193      {
1194        mpz_sub_ui(pert_vector[j], pert_vector[j],-(*ivtarget)[i*nV+j]);
1195      }
1196      else
1197      {
1198        mpz_add_ui(pert_vector[j], pert_vector[j],(*ivtarget)[i*nV+j]);
1199      }
1200    }
1201  }
1202
1203  // 2147483647 is max. integer representation in SINGULAR
1204  mpz_t sing_int;
1205  mpz_init_set_ui(sing_int,  2147483647);
1206
1207  mpz_t check_int;
1208  mpz_init_set_ui(check_int,  100000);
1209
1210  mpz_t ztemp;
1211  mpz_init(ztemp);
1212  mpz_set(ztemp, pert_vector[0]);
1213  for(i=1; i<nV; i++)
1214  {
1215    mpz_gcd(ztemp, ztemp, pert_vector[i]);
1216    if(mpz_cmp_si(ztemp, 1)  == 0)
1217    {
1218      break;
1219    }
1220  }
1221  if(mpz_cmp_si(ztemp, 1) != 0)
1222  {
1223    for(i=0; i<nV; i++)
1224    {
1225      mpz_divexact(pert_vector[i], pert_vector[i], ztemp);
1226    }
1227  }
1228
1229  for(i=0; i<nV; i++)
1230  {
1231    if(mpz_cmp(pert_vector[i], check_int)>=0)
1232    {
1233      for(j=0; j<nV; j++)
1234      {
1235        mpz_fdiv_q_ui(pert_vector1[j], pert_vector[j], 100);
1236      }
1237    }
1238  }
1239
1240  intvec* result = new intvec(nV);
1241
1242  int ntrue=0;
1243
1244  for(i=0; i<nV; i++)
1245  {
1246    (*result)[i] = mpz_get_si(pert_vector1[i]);
1247    if(mpz_cmp(pert_vector1[i], sing_int)>=0)
1248    {
1249      ntrue++;
1250    }
1251  }
1252  if(ntrue > 0 || test_w_in_ConeCC(G,result)==0)
1253  {
1254    ntrue=0;
1255    for(i=0; i<nV; i++)
1256    {
1257      (*result)[i] = mpz_get_si(pert_vector[i]);
1258      if(mpz_cmp(pert_vector[i], sing_int)>=0)
1259      {
1260        ntrue++;
1261        if(Overflow_Error == FALSE)
1262        {
1263          Overflow_Error = TRUE;
1264          PrintS("\n// ** OVERFLOW in \"MPertvectors\": ");
1265          mpz_out_str( stdout, 10, pert_vector[i]);
1266          PrintS(" is greater than 2147483647 (max. integer representation)");
1267          Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
1268        }
1269      }
1270    }
1271
1272    if(Overflow_Error == TRUE)
1273    {
1274      ivString(result, "pert_vector");
1275      Print("\n// %d element(s) of it is overflow!!", ntrue);
1276    }
1277  }
1278
1279  mpz_clear(ztemp);
1280  mpz_clear(sing_int);
1281  mpz_clear(check_int);
1282  omFree(pert_vector);
1283  omFree(pert_vector1);
1284  mpz_clear(tot_deg);
1285  mpz_clear(maxdeg);
1286  mpz_clear(inveps);
1287
1288  rComplete(currRing);
1289  for(j=0; j<IDELEMS(G); j++)
1290  {
1291    poly p=G->m[j];
1292    while(p!=NULL)
1293    {
1294      p_Setm(p,currRing); pIter(p);
1295    }
1296  }
1297  return result;
1298}
1299
1300/*****************************************************************************
1301 * The following procedure returns                                           *
1302 *     Pert(A1) = 1/eps^(pdeg-1)*A_1 + 1/eps^(pdeg-2)*A_2+...+A_pdeg,        *
1303 * where the A_i are the i-th rows of the matrix target_ord and              *
1304 *     1/eps > deg(p)*(max(A_2) + max(A_3)+...+max(A_pdeg))                  *
1305 *****************************************************************************/
1306intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg)
1307{
1308  // ivtarget is a matrix order of the lex. order
1309  int nV = currRing->N;
1310  //assume(pdeg <= nV && pdeg >= 0);
1311
1312  int i, j, nG = IDELEMS(G);
1313  intvec* pert_vector =  new intvec(nV);
1314
1315  //Checking that the perturbated degree is valid
1316  if(pdeg > nV || pdeg <= 0)
1317  {
1318    WerrorS("//** The perturbed degree is wrong!!");
1319    return pert_vector;
1320  }
1321  for(i=0; i<nV; i++)
1322  {
1323    (*pert_vector)[i]=(*ivtarget)[i];
1324  }
1325  if(pdeg == 1)
1326  {
1327    return pert_vector;
1328  }
1329  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
1330  // where the Ai are the i-te rows of the matrix target_ord.
1331  int ntemp, maxAi, maxA=0;
1332  for(i=1; i<pdeg; i++)
1333  {
1334    maxAi = (*ivtarget)[i*nV];
1335    for(j=i*nV+1; j<(i+1)*nV; j++)
1336    {
1337      ntemp = (*ivtarget)[j];
1338      if(ntemp > maxAi)
1339      {
1340        maxAi = ntemp;
1341      }
1342    }
1343    maxA += maxAi;
1344  }
1345
1346  // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G.
1347  int inveps, tot_deg = 0, maxdeg;
1348
1349  intvec* ivUnit = Mivdp(nV);//19.02
1350  for(i=nG-1; i>=0; i--)
1351  {
1352    // maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
1353    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
1354    if (maxdeg > tot_deg )
1355    {
1356      tot_deg = maxdeg;
1357    }
1358  }
1359  delete ivUnit;
1360
1361  inveps = (tot_deg * maxA) + 1;
1362
1363#ifdef INVEPS_SMALL_IN_FRACTAL
1364  //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", inveps, pdeg);
1365  if(inveps > pdeg && pdeg > 3)
1366  {
1367    inveps = inveps / pdeg;
1368  }
1369  // Print(" %d", inveps);
1370#else
1371  PrintS("\n// the \"big\" inverse epsilon %d", inveps);
1372#endif
1373
1374  // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg
1375  for ( i=1; i < pdeg; i++ )
1376  {
1377    for(j=0; j<nV; j++)
1378    {
1379      (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j];
1380    }
1381  }
1382
1383  int temp = (*pert_vector)[0];
1384  for(i=1; i<nV; i++)
1385  {
1386    temp = gcd(temp, (*pert_vector)[i]);
1387    if(temp == 1)
1388    {
1389      break;
1390    }
1391  }
1392  if(temp != 1)
1393  {
1394    for(i=0; i<nV; i++)
1395    {
1396      (*pert_vector)[i] = (*pert_vector)[i] / temp;
1397    }
1398  }
1399
1400  intvec* result = pert_vector;
1401  delete pert_vector;
1402  return result;
1403}
1404
1405/*****************************************************************************
1406 * define a lexicographic order matrix as intvec                             *
1407 *****************************************************************************/
1408intvec* MivMatrixOrderlp(int nV)
1409{
1410  int i;
1411  intvec* ivM = new intvec(nV*nV);
1412
1413  for(i=0; i<nV; i++)
1414  {
1415    (*ivM)[i*nV + i] = 1;
1416  }
1417  return(ivM);
1418}
1419
1420
1421/*****************************************************************************
1422 * define a reverse lexicographic order (dp) matrix as intvec                *
1423 *****************************************************************************/
1424intvec* MivMatrixOrderdp(int nV)
1425{
1426  int i;
1427  intvec* ivM = new intvec(nV*nV);
1428
1429  for(i=0; i<nV; i++)
1430  {
1431    (*ivM)[i] = 1;
1432  }
1433  for(i=1; i<nV; i++)
1434  {
1435    (*ivM)[(i+1)*nV - i] = -1;
1436  }
1437  return(ivM);
1438}
1439
1440/*****************************************************************************
1441 * creates an intvec of the monomial order Wp(ivstart)                       *
1442 *****************************************************************************/
1443intvec* MivWeightOrderlp(intvec* ivstart)
1444{
1445  int i;
1446  int nV = ivstart->length();
1447  intvec* ivM = new intvec(nV*nV);
1448
1449  for(i=0; i<nV; i++)
1450  {
1451    (*ivM)[i] = (*ivstart)[i];
1452  }
1453  for(i=1; i<nV; i++)
1454  {
1455    (*ivM)[i*nV + i-1] = 1;
1456  }
1457  return(ivM);
1458}
1459
1460/*****************************************************************************
1461 * creates an intvec of the monomial order dp(ivstart)                       *
1462 *****************************************************************************/
1463intvec* MivWeightOrderdp(intvec* ivstart)
1464{
1465  int i;
1466  int nV = ivstart->length();
1467  intvec* ivM = new intvec(nV*nV);
1468
1469  for(i=0; i<nV; i++)
1470  {
1471    (*ivM)[i] = (*ivstart)[i];
1472  }
1473  for(i=0; i<nV; i++)
1474  {
1475    (*ivM)[nV+i] = 1;
1476  }
1477  for(i=2; i<nV; i++)
1478  {
1479    (*ivM)[(i+1)*nV - i] = -1;
1480  }
1481  return(ivM);
1482}
1483
1484//unused
1485/*
1486static intvec* MatrixOrderdp(int nV)
1487{
1488  int i;
1489  intvec* ivM = new intvec(nV*nV);
1490
1491  for(i=0; i<nV; i++)
1492  {
1493    (*ivM)[i] = 1;
1494  }
1495  for(i=1; i<nV; i++)
1496  {
1497    (*ivM)[(i+1)*nV - i] = -1;
1498  }
1499  return(ivM);
1500}
1501*/
1502
1503intvec* MivUnit(int nV)
1504{
1505  int i;
1506  intvec* ivM = new intvec(nV);
1507  for(i=nV-1; i>=0; i--)
1508  {
1509    (*ivM)[i] = 1;
1510  }
1511  return(ivM);
1512}
1513
1514
1515/************************************************************************
1516*  compute a perturbed weight vector of a matrix order w.r.t. an ideal  *
1517*************************************************************************/
1518int Xnlev;
1519intvec* Mfpertvector(ideal G, intvec* ivtarget)
1520{
1521  int i, j, nG = IDELEMS(G);
1522  int nV = currRing->N;
1523  int niv = nV*nV;
1524
1525
1526  // Calculate maxA = Max(A2) + Max(A3) + ... + Max(AnV),
1527  // where the Ai are the i-te rows of the matrix 'targer_ord'.
1528  int ntemp, maxAi, maxA=0;
1529  for(i=1; i<nV; i++)
1530  {
1531    maxAi = (*ivtarget)[i*nV];
1532    if(maxAi<0)
1533    {
1534      maxAi = -maxAi;
1535    }
1536    for(j=i*nV+1; j<(i+1)*nV; j++)
1537    {
1538      ntemp = (*ivtarget)[j];
1539      if(ntemp < 0)
1540      {
1541        ntemp = -ntemp;
1542      }
1543      if(ntemp > maxAi)
1544      {
1545        maxAi = ntemp;
1546      }
1547    }
1548    maxA = maxA + maxAi;
1549  }
1550  intvec* ivUnit = Mivdp(nV);
1551
1552  // Calculate inveps = 1/eps, where 1/eps > deg(p)*maxA for all p in G.
1553  mpz_t tot_deg; mpz_init(tot_deg);
1554  mpz_t maxdeg; mpz_init(maxdeg);
1555  mpz_t inveps; mpz_init(inveps);
1556
1557
1558  for(i=nG-1; i>=0; i--)
1559  {
1560    mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
1561    if (mpz_cmp(maxdeg,  tot_deg) > 0 )
1562    {
1563      mpz_set(tot_deg, maxdeg);
1564    }
1565  }
1566
1567  delete ivUnit;
1568  //inveps = (tot_deg * maxA) + 1;
1569  mpz_mul_ui(inveps, tot_deg, maxA);
1570  mpz_add_ui(inveps, inveps, 1);
1571
1572  // takes  "small" inveps
1573#ifdef INVEPS_SMALL_IN_FRACTAL
1574  if(mpz_cmp_ui(inveps, nV)>0 && nV > 3)
1575  {
1576    mpz_cdiv_q_ui(inveps, inveps, nV);
1577  }
1578  // choose the small inverse epsilon
1579#endif
1580
1581  // PrintLn();  mpz_out_str(stdout, 10, inveps);
1582
1583  // Calculate the perturbed target orders:
1584  mpz_t *ivtemp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
1585  mpz_t *pert_vector=(mpz_t *)omAlloc(niv*sizeof(mpz_t));
1586
1587  for(i=0; i < nV; i++)
1588  {
1589    mpz_init_set_si(ivtemp[i], (*ivtarget)[i]);
1590    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
1591  }
1592
1593  mpz_t ztmp; mpz_init(ztmp);
1594  // BOOLEAN isneg = FALSE;
1595
1596  for(i=1; i<nV; i++)
1597  {
1598    for(j=0; j<nV; j++)
1599    {
1600      mpz_mul(ztmp, inveps, ivtemp[j]);
1601      if((*ivtarget)[i*nV+j]<0)
1602      {
1603        mpz_sub_ui(ivtemp[j], ztmp, -(*ivtarget)[i*nV+j]);
1604      }
1605      else
1606      {
1607        mpz_add_ui(ivtemp[j], ztmp,(*ivtarget)[i*nV+j]);
1608      }
1609    }
1610
1611    for(j=0; j<nV; j++)
1612    {
1613      mpz_init_set(pert_vector[i*nV+j],ivtemp[j]);
1614    }
1615  }
1616
1617  // 2147483647 is max. integer representation in SINGULAR
1618  mpz_t sing_int;
1619  mpz_init_set_ui(sing_int,  2147483647);
1620
1621  intvec* result = new intvec(niv);
1622  intvec* result1 = new intvec(niv);
1623  BOOLEAN nflow = FALSE;
1624
1625  // computes gcd
1626  mpz_set(ztmp, pert_vector[0]);
1627  for(i=0; i<niv; i++)
1628  {
1629    mpz_gcd(ztmp, ztmp, pert_vector[i]);
1630    if(mpz_cmp_si(ztmp, 1)==0)
1631    {
1632      break;
1633    }
1634  }
1635
1636  for(i=0; i<niv; i++)
1637  {
1638    mpz_divexact(pert_vector[i], pert_vector[i], ztmp);
1639    (* result)[i] = mpz_get_si(pert_vector[i]);
1640  }
1641
1642  CHECK_OVERFLOW:
1643
1644  for(i=0; i<niv; i++)
1645  {
1646    if(mpz_cmp(pert_vector[i], sing_int)>0)
1647    {
1648      if(nflow == FALSE)
1649      {
1650        Xnlev = i / nV;
1651        nflow = TRUE;
1652        Overflow_Error = TRUE;
1653        Print("\n// Xlev = %d and the %d-th element is", Xnlev,  i+1);
1654        PrintS("\n// ** OVERFLOW in \"Mfpertvector\": ");
1655        mpz_out_str( stdout, 10, pert_vector[i]);
1656        PrintS(" is greater than 2147483647 (max. integer representation)");
1657        Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
1658      }
1659    }
1660  }
1661  if(Overflow_Error == TRUE)
1662  {
1663    ivString(result, "new_vector");
1664  }
1665  omFree(pert_vector);
1666  omFree(ivtemp);
1667  mpz_clear(ztmp);
1668  mpz_clear(tot_deg);
1669  mpz_clear(maxdeg);
1670  mpz_clear(inveps);
1671  mpz_clear(sing_int);
1672
1673  rComplete(currRing);
1674  for(j=0; j<IDELEMS(G); j++)
1675  {
1676    poly p=G->m[j];
1677    while(p!=NULL)
1678    {
1679      p_Setm(p,currRing);
1680      pIter(p);
1681    }
1682  }
1683  return result;
1684}
1685
1686/****************************************************************
1687 * Multiplication of two ideals element by element              *
1688 * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) *
1689 *  destroy A, keeps B                                          *
1690 ****************************************************************/
1691static ideal MidMult(ideal A, ideal B)
1692{
1693  int mA = IDELEMS(A), mB = IDELEMS(B);
1694
1695  if(A==NULL || B==NULL)
1696  {
1697    return NULL;
1698  }
1699  if(mB < mA)
1700  {
1701    mA = mB;
1702  }
1703  ideal result = idInit(mA, 1);
1704
1705  int i, k=0;
1706  for(i=0; i<mA; i++)
1707    {
1708      result->m[k] = pMult(A->m[i], pCopy(B->m[i]));
1709      A->m[i]=NULL;
1710      if (result->m[k]!=NULL)
1711      {
1712        k++;
1713      }
1714    }
1715
1716  idDelete(&A);
1717  idSkipZeroes(result);
1718  return result;
1719}
1720
1721/*********************************************************************
1722 * G is a red. Groebner basis w.r.t. <_1                             *
1723 * Gomega is an initial form ideal of <G> w.r.t. a weight vector w   *
1724 * M is a subideal of <Gomega> and M selft is a red. Groebner basis  *
1725 *    of the ideal <Gomega> w.r.t. <_w                               *
1726 * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega  *
1727 * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i*
1728 ********************************************************************/
1729static ideal MLifttwoIdeal(ideal Gw, ideal M, ideal G)
1730{
1731  ideal Mtmp = idLift(Gw, M, NULL, FALSE, TRUE, TRUE, NULL);
1732
1733  // If Gw is a GB, then isSB = TRUE, otherwise FALSE
1734  // So, it is better, if one tests whether Gw is a GB
1735  // in ideals.cc:
1736  // idLift (ideal mod, ideal submod,ideal * rest, BOOLEAN goodShape,
1737  //           BOOLEAN isSB,BOOLEAN divide,matrix * unit)
1738
1739  // Let be Mtmp = {m1,...,ms}, where mi=sum hij.in_gj, for all i=1,...,s
1740  // We compute F = {f1,...,fs}, where fi=sum hij.gj
1741  int i, j, nM = IDELEMS(Mtmp);
1742  ideal idpol, idLG;
1743  ideal F = idInit(nM, 1);
1744
1745  for(i=0; i<nM; i++)
1746  {
1747     idpol = idVec2Ideal(Mtmp->m[i]);
1748     idLG = MidMult(idpol, G);
1749     idpol = NULL;
1750     F->m[i] = NULL;
1751     for(j=IDELEMS(idLG)-1; j>=0; j--)
1752     {
1753       F->m[i] = pAdd(F->m[i], idLG->m[j]);
1754       idLG->m[j]=NULL;
1755     }
1756     idDelete(&idLG);
1757  }
1758  idDelete(&Mtmp);
1759  return F;
1760}
1761
1762//unused
1763/*
1764static void checkidealCC(ideal G, char* Ch)
1765{
1766  int i,nmon=0,ntmp;
1767  int nG = IDELEMS(G);
1768  int n = nG-1;
1769  Print("\n//** Ideal %s besteht aus %d Polynomen mit ", Ch, nG);
1770
1771  for(i=0; i<nG; i++)
1772  {
1773    ntmp =  pLength(G->m[i]);
1774    nmon += ntmp;
1775
1776    if(i != n)
1777    {
1778      Print("%d, ", ntmp);
1779    }
1780    else
1781    {
1782      Print(" bzw. %d ", ntmp);
1783    }
1784  }
1785  PrintS(" Monomen.\n");
1786  Print("//** %s besitzt %d Monome.", Ch, nmon);
1787  PrintLn();
1788}
1789*/
1790
1791//unused
1792/*
1793static void HeadidString(ideal L, char* st)
1794{
1795  int i, nL = IDELEMS(L)-1;
1796
1797  Print("//  The head terms of the ideal %s = ", st);
1798  for(i=0; i<nL; i++)
1799  {
1800    Print(" %s, ", pString(pHead(L->m[i])));
1801  }
1802  Print(" %s;\n", pString(pHead(L->m[nL])));
1803}
1804
1805*/
1806static inline int MivComp(intvec* iva, intvec* ivb)
1807{
1808  assume(iva->length() == ivb->length());
1809  int i;
1810  for(i=iva->length()-1; i>=0; i--)
1811  {
1812    if((*iva)[i] - (*ivb)[i] != 0)
1813    {
1814      return 0;
1815    }
1816  }
1817  return 1;
1818}
1819
1820/**********************************************
1821 * Look for the smallest absolut value in vec *
1822 **********************************************/
1823static int MivAbsMax(intvec* vec)
1824{
1825  int i,k;
1826  if((*vec)[0] < 0)
1827  {
1828    k = -(*vec)[0];
1829  }
1830  else
1831  {
1832    k = (*vec)[0];
1833  }
1834  for(i=1; i < (vec->length()); i++)
1835  {
1836    if((*vec)[i] < 0)
1837    {
1838      if(-(*vec)[i] > k)
1839      {
1840        k = -(*vec)[i];
1841      }
1842    }
1843    else
1844    {
1845      if((*vec)[i] > k)
1846      {
1847        k = (*vec)[i];
1848      }
1849    }
1850  }
1851  return k;
1852}
1853
1854
1855/**************************************************************
1856 * Look for the position of the smallest absolut value in vec *
1857 **************************************************************/
1858static int MivAbsMaxArg(intvec* vec)
1859{
1860  int k = MivAbsMax(vec);
1861  int i=0;
1862  while(1)
1863  {
1864    if((*vec)[i] == k || (*vec)[i] == -k)
1865    {
1866      break;
1867    }
1868    i++;
1869  }
1870  return i;
1871}
1872
1873
1874/**********************************************************************
1875 * Compute a next weight vector between curr_weight and target_weight *
1876 * with respect to an ideal <G>.                                      *
1877**********************************************************************/
1878/*
1879static intvec* MwalkNextWeightCC(intvec* curr_weight, intvec* target_weight,
1880                                 ideal G)
1881{
1882  BOOLEAN nError = Overflow_Error;
1883  Overflow_Error = FALSE;
1884
1885  assume(currRing != NULL && curr_weight != NULL &&
1886         target_weight != NULL && G != NULL);
1887
1888  int nRing = currRing->N;
1889  int checkRed, j, nG = IDELEMS(G);
1890  intvec* ivtemp;
1891
1892  mpz_t t_zaehler, t_nenner;
1893  mpz_init(t_zaehler);
1894  mpz_init(t_nenner);
1895
1896  mpz_t s_zaehler, s_nenner, temp, MwWd;
1897  mpz_init(s_zaehler);
1898  mpz_init(s_nenner);
1899  mpz_init(temp);
1900  mpz_init(MwWd);
1901
1902  mpz_t sing_int;
1903  mpz_init(sing_int);
1904  mpz_set_si(sing_int,  2147483647);
1905
1906  mpz_t sing_int_half;
1907  mpz_init(sing_int_half);
1908  mpz_set_si(sing_int_half,  3*(1073741824/2));
1909
1910  mpz_t deg_w0_p1, deg_d0_p1;
1911  mpz_init(deg_w0_p1);
1912  mpz_init(deg_d0_p1);
1913
1914  mpz_t sztn, sntz;
1915  mpz_init(sztn);
1916  mpz_init(sntz);
1917
1918  mpz_t t_null;
1919  mpz_init(t_null);
1920
1921  mpz_t ggt;
1922  mpz_init(ggt);
1923
1924  mpz_t dcw;
1925  mpz_init(dcw);
1926
1927  int gcd_tmp;
1928  intvec* diff_weight = MivSub(target_weight, curr_weight);
1929
1930  intvec* diff_weight1 = MivSub(target_weight, curr_weight);
1931  poly g;
1932
1933  for (j=0; j<nG; j++)
1934  {
1935    g = G->m[j];
1936    if (g != NULL)
1937    {
1938      ivtemp = MExpPol(g);
1939      mpz_set_si(deg_w0_p1, MivDotProduct(ivtemp, curr_weight));
1940      mpz_set_si(deg_d0_p1, MivDotProduct(ivtemp, diff_weight));
1941      delete ivtemp;
1942
1943      pIter(g);
1944      while (g != NULL)
1945      {
1946        ivtemp = MExpPol(g);
1947        mpz_set_si(MwWd, MivDotProduct(ivtemp, curr_weight));
1948        mpz_sub(s_zaehler, deg_w0_p1, MwWd);
1949        if(mpz_cmp(s_zaehler, t_null) != 0)
1950        {
1951          mpz_set_si(MwWd, MivDotProduct(ivtemp, diff_weight));
1952          mpz_sub(s_nenner, MwWd, deg_d0_p1);
1953          // check for 0 < s <= 1
1954          if( (mpz_cmp(s_zaehler,t_null) > 0 &&
1955               mpz_cmp(s_nenner, s_zaehler)>=0) ||
1956              (mpz_cmp(s_zaehler, t_null) < 0 &&
1957               mpz_cmp(s_nenner, s_zaehler)<=0))
1958          {
1959            // make both positive
1960            if (mpz_cmp(s_zaehler, t_null) < 0)
1961            {
1962              mpz_neg(s_zaehler, s_zaehler);
1963              mpz_neg(s_nenner, s_nenner);
1964            }
1965
1966            //compute a simple fraction of s
1967            cancel(s_zaehler, s_nenner);
1968
1969            if(mpz_cmp(t_nenner, t_null) != 0)
1970            {
1971              mpz_mul(sztn, s_zaehler, t_nenner);
1972              mpz_mul(sntz, s_nenner, t_zaehler);
1973
1974              if(mpz_cmp(sztn,sntz) < 0)
1975              {
1976                mpz_add(t_nenner, t_null, s_nenner);
1977                mpz_add(t_zaehler,t_null, s_zaehler);
1978              }
1979            }
1980            else
1981            {
1982              mpz_add(t_nenner, t_null, s_nenner);
1983              mpz_add(t_zaehler,t_null, s_zaehler);
1984            }
1985          }
1986        }
1987        pIter(g);
1988        delete ivtemp;
1989      }
1990    }
1991  }
1992  //Print("\n// Alloc Size = %d \n", nRing*sizeof(mpz_t));
1993  mpz_t *vec=(mpz_t*)omAlloc(nRing*sizeof(mpz_t));
1994
1995
1996  // there is no 0<t<1 and define the next weight vector that is equal
1997  // to the current weight vector
1998  if(mpz_cmp(t_nenner, t_null) == 0)
1999  {
2000#ifndef SING_NDEBUG
2001    PrintS("\n//MwalkNextWeightCC: t_nenner=0\n");
2002#endif
2003    delete diff_weight;
2004    diff_weight = ivCopy(curr_weight);//take memory
2005    goto FINISH;
2006  }
2007
2008  // define the target vector as the next weight vector, if t = 1
2009  if(mpz_cmp_si(t_nenner, 1)==0 && mpz_cmp_si(t_zaehler,1)==0)
2010  {
2011    delete diff_weight;
2012    diff_weight = ivCopy(target_weight); //this takes memory
2013    goto FINISH;
2014  }
2015
2016   checkRed = 0;
2017
2018  SIMPLIFY_GCD:
2019
2020  // simplify the vectors curr_weight and diff_weight (C-int)
2021  gcd_tmp = (*curr_weight)[0];
2022
2023  for (j=1; j<nRing; j++)
2024  {
2025    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
2026    if(gcd_tmp == 1)
2027    {
2028      break;
2029    }
2030  }
2031  if(gcd_tmp != 1)
2032  {
2033    for (j=0; j<nRing; j++)
2034    {
2035      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
2036      if(gcd_tmp == 1)
2037      {
2038        break;
2039      }
2040    }
2041  }
2042  if(gcd_tmp != 1)
2043  {
2044    for (j=0; j<nRing; j++)
2045    {
2046      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
2047      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
2048    }
2049  }
2050  if(checkRed > 0)
2051  {
2052    for (j=0; j<nRing; j++)
2053    {
2054      mpz_set_si(vec[j], (*diff_weight)[j]);
2055    }
2056    goto TEST_OVERFLOW;
2057  }
2058
2059#ifdef  NEXT_VECTORS_CC
2060  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
2061  ivString(curr_weight, "new cw");
2062  ivString(diff_weight, "new dw");
2063
2064  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
2065  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
2066#endif
2067
2068// construct a new weight vector and check whether vec[j] is overflow,
2069// i.e. vec[j] > 2^31.
2070// If vec[j] doesn't overflow, define a weight vector. Otherwise,
2071// report that overflow appears. In the second case, test whether the
2072// the correctness of the new vector plays an important role
2073
2074  for (j=0; j<nRing; j++)
2075  {
2076    mpz_set_si(dcw, (*curr_weight)[j]);
2077    mpz_mul(s_nenner, t_nenner, dcw);
2078
2079    if( (*diff_weight)[j]>0)
2080    {
2081      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
2082    }
2083    else
2084    {
2085      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
2086      mpz_neg(s_zaehler, s_zaehler);
2087    }
2088    mpz_add(sntz, s_nenner, s_zaehler);
2089    mpz_init_set(vec[j], sntz);
2090
2091#ifdef NEXT_VECTORS_CC
2092    Print("\n//   j = %d ==> ", j);
2093    PrintS("(");
2094    mpz_out_str( stdout, 10, t_nenner);
2095    Print(" * %d)", (*curr_weight)[j]);
2096    PrintS(" + ("); mpz_out_str( stdout, 10, t_zaehler);
2097    Print(" * %d) =  ",  (*diff_weight)[j]);
2098    mpz_out_str( stdout, 10, s_nenner);
2099    PrintS(" + ");
2100    mpz_out_str( stdout, 10, s_zaehler);
2101    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
2102    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
2103#endif
2104
2105    if(j==0)
2106    {
2107      mpz_set(ggt, sntz);
2108    }
2109    else
2110    {
2111      if(mpz_cmp_si(ggt,1) != 0)
2112      {
2113        mpz_gcd(ggt, ggt, sntz);
2114      }
2115    }
2116  }
2117  // reduce the vector with the gcd
2118  if(mpz_cmp_si(ggt,1) != 0)
2119  {
2120    for (j=0; j<nRing; j++)
2121    {
2122      mpz_divexact(vec[j], vec[j], ggt);
2123    }
2124  }
2125#ifdef  NEXT_VECTORS_CC
2126  PrintS("\n// gcd of elements of the vector: ");
2127  mpz_out_str( stdout, 10, ggt);
2128#endif
2129
2130  for(j=0; j<nRing; j++)
2131  {
2132    if(mpz_cmp(vec[j], sing_int_half) >= 0)
2133    {
2134      goto REDUCTION;
2135    }
2136  }
2137  checkRed = 1;
2138  for (j=0; j<nRing; j++)
2139    {
2140      (*diff_weight)[j] = mpz_get_si(vec[j]);
2141    }
2142  goto SIMPLIFY_GCD;
2143
2144  REDUCTION:
2145  checkRed = 1;
2146  for (j=0; j<nRing; j++)
2147  {
2148    (*diff_weight1)[j] = mpz_get_si(vec[j]);
2149  }
2150  while(test_w_in_ConeCC(G,diff_weight1))
2151  {
2152    for(j=0; j<nRing; j++)
2153    {
2154      (*diff_weight)[j] = (*diff_weight1)[j];
2155      mpz_set_si(vec[j], (*diff_weight)[j]);
2156    }
2157    for(j=0; j<nRing; j++)
2158    {
2159      (*diff_weight1)[j] = floor(0.1*(*diff_weight)[j] + 0.5);
2160    }
2161  }
2162  if(MivAbsMax(diff_weight)>10000)
2163  {
2164    for(j=0; j<nRing; j++)
2165    {
2166      (*diff_weight1)[j] = (*diff_weight)[j];
2167    }
2168    j = 0;
2169    while(test_w_in_ConeCC(G,diff_weight1))
2170    {
2171      (*diff_weight)[j] = (*diff_weight1)[j];
2172      mpz_set_si(vec[j], (*diff_weight)[j]);
2173      j = MivAbsMaxArg(diff_weight1);
2174      (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2175    }
2176    goto SIMPLIFY_GCD;
2177  }
2178
2179 TEST_OVERFLOW:
2180
2181  for (j=0; j<nRing; j++)
2182  {
2183    if(mpz_cmp(vec[j], sing_int)>=0)
2184    {
2185      if(Overflow_Error == FALSE)
2186      {
2187        Overflow_Error = TRUE;
2188        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
2189        mpz_out_str( stdout, 10, vec[j]);
2190        PrintS(" is greater than 2147483647 (max. integer representation)\n");
2191        //Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
2192      }
2193    }
2194  }
2195
2196 FINISH:
2197   delete diff_weight1;
2198   mpz_clear(t_zaehler);
2199   mpz_clear(t_nenner);
2200   mpz_clear(s_zaehler);
2201   mpz_clear(s_nenner);
2202   mpz_clear(sntz);
2203   mpz_clear(sztn);
2204   mpz_clear(temp);
2205   mpz_clear(MwWd);
2206   mpz_clear(deg_w0_p1);
2207   mpz_clear(deg_d0_p1);
2208   mpz_clear(ggt);
2209   omFree(vec);
2210   mpz_clear(sing_int_half);
2211   mpz_clear(sing_int);
2212   mpz_clear(dcw);
2213   mpz_clear(t_null);
2214
2215  if(Overflow_Error == FALSE)
2216  {
2217    Overflow_Error = nError;
2218  }
2219  rComplete(currRing);
2220  for(j=0; j<IDELEMS(G); j++)
2221  {
2222    poly p=G->m[j];
2223    while(p!=NULL)
2224    {
2225      p_Setm(p,currRing);
2226      pIter(p);
2227    }
2228  }
2229return diff_weight;
2230}
2231*/
2232/**********************************************************************
2233 * Compute a next weight vector between curr_weight and target_weight *
2234 * with respect to an ideal <G>.                                      *
2235**********************************************************************/
2236static intvec* MwalkNextWeightCC(intvec* curr_weight, intvec* target_weight,
2237                                 ideal G)
2238{
2239  BOOLEAN nError = Overflow_Error;
2240  Overflow_Error = FALSE;
2241
2242  assume(currRing != NULL && curr_weight != NULL &&
2243         target_weight != NULL && G != NULL);
2244
2245  int nRing = currRing->N;
2246  int j, nG = IDELEMS(G);
2247  intvec* ivtemp;
2248
2249  mpz_t t_zaehler, t_nenner;
2250  mpz_init(t_zaehler);
2251  mpz_init(t_nenner);
2252
2253  mpz_t s_zaehler, s_nenner, temp, MwWd;
2254  mpz_init(s_zaehler);
2255  mpz_init(s_nenner);
2256  mpz_init(temp);
2257  mpz_init(MwWd);
2258
2259  mpz_t sing_int;
2260  mpz_init(sing_int);
2261  mpz_set_si(sing_int,  2147483647);
2262
2263  mpz_t sing_int_half;
2264  mpz_init(sing_int_half);
2265  mpz_set_si(sing_int_half,  3*(1073741824/2));
2266
2267  mpz_t deg_w0_p1, deg_d0_p1;
2268  mpz_init(deg_w0_p1);
2269  mpz_init(deg_d0_p1);
2270
2271  mpz_t sztn, sntz;
2272  mpz_init(sztn);
2273  mpz_init(sntz);
2274
2275  mpz_t t_null;
2276  mpz_init(t_null);
2277
2278  mpz_t ggt;
2279  mpz_init(ggt);
2280
2281  mpz_t dcw;
2282  mpz_init(dcw);
2283
2284  int gcd_tmp;
2285  //intvec* diff_weight = MivSub(target_weight, curr_weight);
2286
2287  intvec* diff_weight1 = new intvec(nRing); //MivSub(target_weight, curr_weight);
2288  poly g;
2289
2290  // reduce the size of the entries of the current weight vector
2291  if(TEST_OPT_REDSB)
2292  {
2293    for (j=0; j<nRing; j++)
2294    {
2295      (*diff_weight1)[j] = (*curr_weight)[j];
2296    }
2297    while(MivAbsMax(diff_weight1)>10000 && test_w_in_ConeCC(G,diff_weight1)==1)
2298    {
2299      for(j=0; j<nRing; j++)
2300      {
2301        (*curr_weight)[j] = (*diff_weight1)[j];
2302      }
2303      for(j=0; j<nRing; j++)
2304      {
2305        (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2306      }
2307    }
2308
2309    if(MivAbsMax(curr_weight)>100000)
2310    {
2311      for(j=0; j<nRing; j++)
2312      {
2313        (*diff_weight1)[j] = (*curr_weight)[j];
2314      }
2315      j = 0;
2316      while(test_w_in_ConeCC(G,diff_weight1)==1 && MivAbsMax(diff_weight1)>1000)
2317      {
2318        (*curr_weight)[j] = (*diff_weight1)[j];
2319        j = MivAbsMaxArg(diff_weight1);
2320        (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2321      }
2322    }
2323
2324  }
2325  intvec* diff_weight = MivSub(target_weight, curr_weight);
2326
2327  // compute a suitable next weight vector
2328  for (j=0; j<nG; j++)
2329  {
2330    g = G->m[j];
2331    if (g != NULL)
2332    {
2333      ivtemp = MExpPol(g);
2334      mpz_set_si(deg_w0_p1, MivDotProduct(ivtemp, curr_weight));
2335      mpz_set_si(deg_d0_p1, MivDotProduct(ivtemp, diff_weight));
2336      delete ivtemp;
2337
2338      pIter(g);
2339      while (g != NULL)
2340      {
2341        ivtemp = MExpPol(g);
2342        mpz_set_si(MwWd, MivDotProduct(ivtemp, curr_weight));
2343        mpz_sub(s_zaehler, deg_w0_p1, MwWd);
2344        if(mpz_cmp(s_zaehler, t_null) != 0)
2345        {
2346          mpz_set_si(MwWd, MivDotProduct(ivtemp, diff_weight));
2347          mpz_sub(s_nenner, MwWd, deg_d0_p1);
2348          // check for 0 < s <= 1
2349          if( (mpz_cmp(s_zaehler,t_null) > 0 &&
2350               mpz_cmp(s_nenner, s_zaehler)>=0) ||
2351              (mpz_cmp(s_zaehler, t_null) < 0 &&
2352               mpz_cmp(s_nenner, s_zaehler)<=0))
2353          {
2354            // make both positive
2355            if (mpz_cmp(s_zaehler, t_null) < 0)
2356            {
2357              mpz_neg(s_zaehler, s_zaehler);
2358              mpz_neg(s_nenner, s_nenner);
2359            }
2360
2361            //compute a simple fraction of s
2362            cancel(s_zaehler, s_nenner);
2363
2364            if(mpz_cmp(t_nenner, t_null) != 0)
2365            {
2366              mpz_mul(sztn, s_zaehler, t_nenner);
2367              mpz_mul(sntz, s_nenner, t_zaehler);
2368
2369              if(mpz_cmp(sztn,sntz) < 0)
2370              {
2371                mpz_add(t_nenner, t_null, s_nenner);
2372                mpz_add(t_zaehler,t_null, s_zaehler);
2373              }
2374            }
2375            else
2376            {
2377              mpz_add(t_nenner, t_null, s_nenner);
2378              mpz_add(t_zaehler,t_null, s_zaehler);
2379            }
2380          }
2381        }
2382        pIter(g);
2383        delete ivtemp;
2384      }
2385    }
2386  }
2387  //Print("\n// Alloc Size = %d \n", nRing*sizeof(mpz_t));
2388  mpz_t *vec=(mpz_t*)omAlloc(nRing*sizeof(mpz_t));
2389
2390
2391  // there is no 0<t<1 and define the next weight vector that is equal
2392  // to the current weight vector
2393  if(mpz_cmp(t_nenner, t_null) == 0)
2394  {
2395#ifndef SING_NDEBUG
2396    PrintS("\n//MwalkNextWeightCC: t_nenner=0\n");
2397#endif
2398    delete diff_weight;
2399    diff_weight = ivCopy(curr_weight);//take memory
2400    goto FINISH;
2401  }
2402
2403  // define the target vector as the next weight vector, if t = 1
2404  if(mpz_cmp_si(t_nenner, 1)==0 && mpz_cmp_si(t_zaehler,1)==0)
2405  {
2406    delete diff_weight;
2407    diff_weight = ivCopy(target_weight); //this takes memory
2408    goto FINISH;
2409  }
2410
2411  SIMPLIFY_GCD:
2412
2413  // simplify the vectors curr_weight and diff_weight (C-int)
2414  gcd_tmp = (*curr_weight)[0];
2415
2416  for (j=1; j<nRing; j++)
2417  {
2418    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
2419    if(gcd_tmp == 1)
2420    {
2421      break;
2422    }
2423  }
2424  if(gcd_tmp != 1)
2425  {
2426    for (j=0; j<nRing; j++)
2427    {
2428      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
2429      if(gcd_tmp == 1)
2430      {
2431        break;
2432      }
2433    }
2434  }
2435  if(gcd_tmp != 1)
2436  {
2437    for (j=0; j<nRing; j++)
2438    {
2439      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
2440      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
2441    }
2442  }
2443
2444#ifdef  NEXT_VECTORS_CC
2445  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
2446  ivString(curr_weight, "new cw");
2447  ivString(diff_weight, "new dw");
2448
2449  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
2450  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
2451#endif
2452
2453// construct a new weight vector and check whether vec[j] is overflow, i.e. vec[j] > 2^31.
2454// If vec[j] doesn't overflow, define a weight vector. Otherwise, report that overflow
2455// appears. In the second case, test whether the the correctness of the new vector plays
2456// an important role
2457
2458  for (j=0; j<nRing; j++)
2459  {
2460    mpz_set_si(dcw, (*curr_weight)[j]);
2461    mpz_mul(s_nenner, t_nenner, dcw);
2462
2463    if( (*diff_weight)[j]>0)
2464    {
2465      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
2466    }
2467    else
2468    {
2469      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
2470      mpz_neg(s_zaehler, s_zaehler);
2471    }
2472    mpz_add(sntz, s_nenner, s_zaehler);
2473    mpz_init_set(vec[j], sntz);
2474
2475#ifdef NEXT_VECTORS_CC
2476    Print("\n//   j = %d ==> ", j);
2477    PrintS("(");
2478    mpz_out_str( stdout, 10, t_nenner);
2479    Print(" * %d)", (*curr_weight)[j]);
2480    PrintS(" + ("); mpz_out_str( stdout, 10, t_zaehler);
2481    Print(" * %d) =  ",  (*diff_weight)[j]);
2482    mpz_out_str( stdout, 10, s_nenner);
2483    PrintS(" + ");
2484    mpz_out_str( stdout, 10, s_zaehler);
2485    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
2486    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
2487#endif
2488
2489    if(j==0)
2490    {
2491      mpz_set(ggt, sntz);
2492    }
2493    else
2494    {
2495      if(mpz_cmp_si(ggt,1) != 0)
2496      {
2497        mpz_gcd(ggt, ggt, sntz);
2498      }
2499    }
2500  }
2501  // reduce the vector with the gcd
2502  if(mpz_cmp_si(ggt,1) != 0)
2503  {
2504    for (j=0; j<nRing; j++)
2505    {
2506      mpz_divexact(vec[j], vec[j], ggt);
2507    }
2508  }
2509#ifdef  NEXT_VECTORS_CC
2510  PrintS("\n// gcd of elements of the vector: ");
2511  mpz_out_str( stdout, 10, ggt);
2512#endif
2513
2514  for (j=0; j<nRing; j++)
2515  {
2516    (*diff_weight)[j] = mpz_get_si(vec[j]);
2517  }
2518
2519 TEST_OVERFLOW:
2520
2521  for (j=0; j<nRing; j++)
2522  {
2523    if(mpz_cmp(vec[j], sing_int)>=0)
2524    {
2525      if(Overflow_Error == FALSE)
2526      {
2527        Overflow_Error = TRUE;
2528        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
2529        mpz_out_str( stdout, 10, vec[j]);
2530        PrintS(" is greater than 2147483647 (max. integer representation)\n");
2531        //Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
2532      }
2533    }
2534  }
2535
2536 FINISH:
2537   delete diff_weight1;
2538   mpz_clear(t_zaehler);
2539   mpz_clear(t_nenner);
2540   mpz_clear(s_zaehler);
2541   mpz_clear(s_nenner);
2542   mpz_clear(sntz);
2543   mpz_clear(sztn);
2544   mpz_clear(temp);
2545   mpz_clear(MwWd);
2546   mpz_clear(deg_w0_p1);
2547   mpz_clear(deg_d0_p1);
2548   mpz_clear(ggt);
2549   omFree(vec);
2550   mpz_clear(sing_int_half);
2551   mpz_clear(sing_int);
2552   mpz_clear(dcw);
2553   mpz_clear(t_null);
2554
2555  if(Overflow_Error == FALSE)
2556  {
2557    Overflow_Error = nError;
2558  }
2559  rComplete(currRing);
2560  for(j=0; j<IDELEMS(G); j++)
2561  {
2562    poly p=G->m[j];
2563    while(p!=NULL)
2564    {
2565      p_Setm(p,currRing);
2566      pIter(p);
2567    }
2568  }
2569return diff_weight;
2570}
2571
2572
2573/**********************************************************************
2574* Compute an intermediate weight vector from iva to ivb w.r.t.        *
2575* the reduced Groebner basis G.                                       *
2576* Return NULL, if it is equal to iva or iva = avb.                    *
2577**********************************************************************/
2578intvec* MkInterRedNextWeight(intvec* iva, intvec* ivb, ideal G)
2579{
2580  intvec* tmp = new intvec(iva->length());
2581  intvec* result;
2582
2583  if(G == NULL)
2584  {
2585    return tmp;
2586  }
2587  if(MivComp(iva, ivb) == 1)
2588  {
2589    return tmp;
2590  }
2591  result = MwalkNextWeightCC(iva, ivb, G);
2592
2593  if(MivComp(result, iva) == 1)
2594  {
2595    delete result;
2596    return tmp;
2597  }
2598
2599  delete tmp;
2600  return result;
2601}
2602
2603/********************************************************************
2604 * define and execute a new ring which order is (a(vb),a(va),lp,C)  *
2605 * ******************************************************************/
2606/*static ring VMrHomogeneous(intvec* va, intvec* vb)
2607{
2608
2609  if ((currRing->ppNoether)!=NULL)
2610  {
2611    pDelete(&(currRing->ppNoether));
2612  }
2613  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2614      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2615  {
2616    sLastPrinted.CleanUp();
2617  }
2618
2619  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2620  int i, nv = currRing->N;
2621
2622  r->cf  = currRing->cf;
2623  r->N   = currRing->N;
2624  int nb = 4;
2625
2626
2627  //names
2628  char* Q; // In order to avoid the corrupted memory, do not change.
2629  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2630  for(i=0; i<nv; i++)
2631  {
2632    Q = currRing->names[i];
2633    r->names[i]  = omStrDup(Q);
2634  }
2635
2636  //weights: entries for 3 blocks: NULL Made:???
2637  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2638  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2639  r->wvhdl[1] = (int*) omAlloc((nv)*sizeof(int));
2640
2641  for(i=0; i<nv; i++)
2642  {
2643    r->wvhdl[1][i] = (*vb)[i];
2644    r->wvhdl[0][i] = (*va)[i];
2645  }
2646  r->wvhdl[0][nv] = (*va)[nv];
2647
2648  // order: (1..1),a,lp,C
2649  r->order = (int *) omAlloc(nb * sizeof(int *));
2650  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2651  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2652
2653  // ringorder a for the first block: var 1..nv
2654  r->order[0]  = ringorder_a;
2655  r->block0[0] = 1;
2656  r->block1[0] = nv;
2657
2658 // ringorder a for the second block: var 2..nv
2659  r->order[1]  = ringorder_a;
2660  r->block0[1] = 1;
2661  r->block1[1] = nv;
2662
2663  // ringorder lp for the third block: var 2..nv
2664  r->order[2]  = ringorder_lp;
2665  r->block0[2] = 1;
2666  r->block1[2] = nv;
2667
2668  // ringorder C for the 4th block
2669  // it is very important within "idLift",
2670  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2671  // therefore, nb  must be (nBlocks(currRing)  + 1)
2672  r->order[3]  = ringorder_C;
2673
2674  // polynomial ring
2675  r->OrdSgn    = 1;
2676
2677  // complete ring intializations
2678
2679  rComplete(r);
2680  return r;
2681  //rChangeCurrRing(r);
2682}
2683*/
2684
2685/**************************************************************
2686 * define and execute a new ring which order is (a(va),lp,C)  *
2687 * ************************************************************/
2688static ring VMrDefault(intvec* va)
2689{
2690
2691  ring r = rCopy0(currRing,FALSE,FALSE);
2692  int i, nv = currRing->N;
2693
2694  int nb = 4;
2695
2696  /*weights: entries for 3 blocks: NULL Made:???*/
2697  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2698  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2699  for(i=0; i<nv; i++)
2700    r->wvhdl[0][i] = (*va)[i];
2701
2702  /* order: a,lp,C,0 */
2703  r->order = (int *) omAlloc(nb * sizeof(int *));
2704  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2705  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2706
2707  // ringorder a for the first block: var 1..nv
2708  r->order[0]  = ringorder_a;
2709  r->block0[0] = 1;
2710  r->block1[0] = nv;
2711
2712  // ringorder lp for the second block: var 1..nv
2713  r->order[1]  = ringorder_lp;
2714  r->block0[1] = 1;
2715  r->block1[1] = nv;
2716
2717  // ringorder C for the third block
2718  // it is very important within "idLift",
2719  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2720  // therefore, nb  must be (nBlocks(currRing)  + 1)
2721  r->order[2]  = ringorder_C;
2722
2723  // the last block: everything is 0
2724  r->order[3]  = 0;
2725
2726  // polynomial ring
2727  r->OrdSgn    = 1;
2728
2729  // complete ring intializations
2730
2731  rComplete(r);
2732  return r;
2733  //rChangeCurrRing(r);
2734}
2735
2736/****************************************************************
2737 * define and execute a new ring with ordering (a(va),Wp(vb),C) *
2738 * **************************************************************/
2739static ring VMrRefine(intvec* va, intvec* vb)
2740{
2741
2742  ring r = rCopy0(currRing,FALSE,FALSE);
2743  int i, nv = currRing->N;
2744
2745  int nb = 5;
2746
2747  //weights: entries for 3 blocks: NULL Made:???
2748  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2749  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2750  r->wvhdl[1] = (int*) omAlloc(nv*sizeof(int));
2751
2752  for(i=0; i<nv; i++)
2753  {
2754    r->wvhdl[0][i] = (*vb)[i];
2755    r->wvhdl[1][i] = (*va)[i];
2756  }
2757
2758  // order: (1..1),a,lp,C
2759  r->order = (int *) omAlloc(nb * sizeof(int *));
2760  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2761  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2762
2763  // ringorder a for the first block: var 1..nv
2764  r->order[0]  = ringorder_a;
2765  r->block0[0] = 1;
2766  r->block1[0] = nv;
2767
2768 // ringorder Wp for the second block: var 1..nv
2769  r->order[1]  = ringorder_a;
2770  r->block0[1] = 1;
2771  r->block1[1] = nv;
2772
2773  // ringorder lp for the third block: var 1..nv
2774  r->order[2]  = ringorder_lp;
2775  r->block0[2] = 1;
2776  r->block1[2] = nv;
2777
2778  // ringorder C for the 4th block
2779  // it is very important within "idLift",
2780  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2781  // therefore, nb  must be (nBlocks(currRing)  + 1)
2782  r->order[3]  = ringorder_C;
2783
2784  // the last block: everything is 0
2785  r->order[4]  = 0;
2786
2787  // complete ring intializations
2788
2789  rComplete(r);
2790
2791  //rChangeCurrRing(r);
2792  return r;
2793}
2794
2795/*****************************************************
2796 * define and execute a new ring with ordering (M,C) *
2797 *****************************************************/
2798static ring VMatrDefault(intvec* va)
2799{
2800
2801  ring r = rCopy0(currRing,FALSE,FALSE);
2802  int i, nv = currRing->N;
2803
2804  int nb = 4;
2805
2806  /*weights: entries for 3 blocks: NULL Made:???*/
2807  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2808  r->wvhdl[0] = (int*) omAlloc(nv*nv*sizeof(int));
2809  r->wvhdl[1] =NULL; // (int*) omAlloc(nv*sizeof(int));
2810  r->wvhdl[2]=NULL;
2811  r->wvhdl[3]=NULL;
2812  for(i=0; i<nv*nv; i++)
2813    r->wvhdl[0][i] = (*va)[i];
2814
2815  /* order: a,lp,C,0 */
2816  r->order = (int *) omAlloc(nb * sizeof(int *));
2817  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2818  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2819
2820  // ringorder a for the first block: var 1..nv
2821  r->order[0]  = ringorder_M;
2822  r->block0[0] = 1;
2823  r->block1[0] = nv;
2824
2825  // ringorder C for the second block
2826  r->order[1]  = ringorder_C;
2827  r->block0[1] = 1;
2828  r->block1[1] = nv;
2829
2830// ringorder C for the third block: var 1..nv
2831  r->order[2]  = ringorder_C;
2832  r->block0[2] = 1;
2833  r->block1[2] = nv;
2834
2835  // the last block: everything is 0
2836  r->order[3]  = 0;
2837
2838  // complete ring intializations
2839
2840  rComplete(r);
2841
2842  //rChangeCurrRing(r);
2843  return r;
2844}
2845
2846/***********************************************************
2847 * define and execute a new ring with ordering (a(vb),M,C) *
2848 ***********************************************************/
2849static ring VMatrRefine(intvec* va, intvec* vb)
2850{
2851
2852  ring r = rCopy0(currRing,FALSE,FALSE);
2853  int i, nv = currRing->N;
2854  int nvs = nv*nv;
2855
2856  int nb = 4;
2857
2858  /*weights: entries for 3 blocks: NULL Made:???*/
2859  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2860  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2861  r->wvhdl[1] = (int*) omAlloc(nvs*sizeof(int));
2862  r->wvhdl[2]=NULL;
2863  r->wvhdl[3]=NULL;
2864  for(i=0; i<nvs; i++)
2865  {
2866    r->wvhdl[1][i] = (*va)[i];
2867  }
2868  for(i=0; i<nv; i++)
2869  {
2870    r->wvhdl[0][i] = (*vb)[i];
2871  }
2872  /* order: a,lp,C,0 */
2873  r->order = (int *) omAlloc(nb * sizeof(int *));
2874  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2875  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2876
2877  // ringorder a for the first block: var 1..nv
2878  r->order[0]  = ringorder_a;
2879  r->block0[0] = 1;
2880  r->block1[0] = nv;
2881
2882  // ringorder M for the second block: var 1..nv
2883  r->order[1]  = ringorder_M;
2884  r->block0[1] = 1;
2885  r->block1[1] = nv;
2886
2887  // ringorder C for the third block: var 1..nv
2888  r->order[2]  = ringorder_C;
2889  r->block0[2] = 1;
2890  r->block1[2] = nv;
2891
2892  // the last block: everything is 0
2893  r->order[3]  = 0;
2894
2895  // complete ring intializations
2896
2897  rComplete(r);
2898
2899  //rChangeCurrRing(r);
2900  return r;
2901}
2902
2903/**********************************************************************
2904* define and execute a new ring which order is  a lexicographic order *
2905***********************************************************************/
2906static void VMrDefaultlp(void)
2907{
2908  ring r = rCopy0(currRing,FALSE,FALSE);
2909  int i, nv = currRing->N;
2910
2911  int nb = rBlocks(currRing) + 1;
2912
2913  /*weights: entries for 3 blocks: NULL Made:???*/
2914
2915  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2916
2917  /* order: lp,C,0 */
2918  r->order = (int *) omAlloc(nb * sizeof(int *));
2919  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2920  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2921
2922  /* ringorder lp for the first block: var 1..nv */
2923  r->order[0]  = ringorder_lp;
2924  r->block0[0] = 1;
2925  r->block1[0] = nv;
2926
2927  /* ringorder C for the second block */
2928  r->order[1]  = ringorder_C;
2929
2930  /* the last block: everything is 0 */
2931  r->order[2]  = 0;
2932
2933  /*polynomial ring*/
2934  r->OrdSgn    = 1;
2935
2936  /* complete ring intializations */
2937
2938  rComplete(r);
2939
2940  rChangeCurrRing(r);
2941}
2942
2943/***************************************************
2944* define a ring with parameters und change to it   *
2945* DefRingPar and DefRingParlp corrupt still memory *
2946****************************************************/
2947static void DefRingPar(intvec* va)
2948{
2949  int i, nv = currRing->N;
2950  int nb = rBlocks(currRing) + 1;
2951
2952  ring res=rCopy0(currRing,FALSE,FALSE);
2953
2954  /*weights: entries for 3 blocks: NULL Made:???*/
2955  res->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2956  res->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2957  for(i=0; i<nv; i++)
2958    res->wvhdl[0][i] = (*va)[i];
2959
2960  /* order: a,lp,C,0 */
2961
2962  res->order = (int *) omAlloc(nb * sizeof(int *));
2963  res->block0 = (int *)omAlloc0(nb * sizeof(int *));
2964  res->block1 = (int *)omAlloc0(nb * sizeof(int *));
2965
2966  // ringorder a for the first block: var 1..nv
2967  res->order[0]  = ringorder_a;
2968  res->block0[0] = 1;
2969  res->block1[0] = nv;
2970
2971  // ringorder lp for the second block: var 1..nv
2972  res->order[1]  = ringorder_lp;
2973  res->block0[1] = 1;
2974  res->block1[1] = nv;
2975
2976  // ringorder C for the third block
2977  // it is very important within "idLift",
2978  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2979  // therefore, nb  must be (nBlocks(currRing)  + 1)
2980  res->order[2]  = ringorder_C;
2981
2982  // the last block: everything is 0
2983  res->order[3]  = 0;
2984
2985  // polynomial ring
2986  res->OrdSgn    = 1;
2987
2988
2989  // complete ring intializations
2990  rComplete(res);
2991
2992  // execute the created ring
2993  rChangeCurrRing(res);
2994}
2995
2996static void DefRingParlp(void)
2997{
2998  int i, nv = currRing->N;
2999
3000  ring r=rCopy0(currRing,FALSE,FALSE);
3001
3002  int nb = rBlocks(currRing) + 1;
3003
3004  /*weights: entries for 3 blocks: NULL Made:???*/
3005
3006  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
3007
3008  /* order: lp,C,0 */
3009  r->order = (int *) omAlloc(nb * sizeof(int *));
3010  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
3011  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
3012
3013  /* ringorder lp for the first block: var 1..nv */
3014  r->order[0]  = ringorder_lp;
3015  r->block0[0] = 1;
3016  r->block1[0] = nv;
3017
3018  /* ringorder C for the second block */
3019  r->order[1]  = ringorder_C;
3020
3021  /* the last block: everything is 0 */
3022  r->order[2]  = 0;
3023
3024  /*polynomial ring*/
3025  r->OrdSgn    = 1;
3026
3027
3028//   if (rParameter(currRing)!=NULL)
3029//   {
3030//     r->cf->extRing->qideal->m[0]=p_Copy(currRing->cf->extRing->qideal->m[0], currRing->cf->extRing);
3031//     int l=rPar(currRing);
3032//     r->cf->extRing->names=(char **)omAlloc(l*sizeof(char_ptr));
3033//
3034//     for(i=l-1;i>=0;i--)
3035//     {
3036//       rParameter(r)[i]=omStrDup(rParameter(currRing)[i]);
3037//     }
3038//   }
3039
3040  // complete ring intializations
3041
3042  rComplete(r);
3043
3044  // execute the created ring
3045  rChangeCurrRing(r);
3046}
3047
3048/*************************************************************
3049 * check whether one or more components of a vector are zero *
3050 *************************************************************/
3051/* unused:
3052static int isNolVector(intvec* hilb)
3053{
3054  int i;
3055  for(i=hilb->length()-1; i>=0; i--)
3056  {
3057    if((* hilb)[i]==0)
3058    {
3059      return 1;
3060    }
3061  }
3062  return 0;
3063}
3064*/
3065
3066/*************************************************************
3067 * check whether one or more components of a vector are <= 0 *
3068 *************************************************************/
3069static int isNegNolVector(intvec* hilb)
3070{
3071  int i;
3072  for(i=hilb->length()-1; i>=0; i--)
3073  {
3074    if((* hilb)[i]<=0)
3075    {
3076      return 1;
3077    }
3078  }
3079  return 0;
3080}
3081
3082/**************************************************************************
3083* Gomega is the initial ideal of G w. r. t. the current weight vector     *
3084* curr_weight. Check whether curr_weight lies on a border of the Groebner *
3085* cone, i. e. check whether a monomial is divisible by a leading monomial *
3086***************************************************************************/
3087static ideal middleOfCone(ideal G, ideal Gomega)
3088{
3089  BOOLEAN middle = FALSE;
3090  int i,j,N = IDELEMS(Gomega);
3091  poly p,lm,factor1,factor2;
3092
3093  ideal Go = idCopy(G);
3094
3095  // check whether leading monomials of G and Gomega coincide
3096  // and return NULL if not
3097  for(i=0; i<N; i++)
3098  {
3099    if(!pIsConstant(pSub(pCopy(Gomega->m[i]),pCopy(pHead(G->m[i])))))
3100    {
3101      idDelete(&Go);
3102      return NULL;
3103    }
3104  }
3105  for(i=0; i<N; i++)
3106  {
3107    for(j=0; j<N; j++)
3108    {
3109      if(i!=j)
3110      {
3111        p = pCopy(Gomega->m[i]);
3112        lm = pCopy(Gomega->m[j]);
3113        pIter(p);
3114        while(p!=NULL)
3115        {
3116          if(pDivisibleBy(lm,p))
3117          {
3118            if(middle == FALSE)
3119            {
3120              middle = TRUE;
3121            }
3122            factor1 = singclap_pdivide(pHead(p),lm,currRing);
3123            factor2 = pMult(pCopy(factor1),pCopy(Go->m[j]));
3124            pDelete(&factor1);
3125            Go->m[i] = pAdd((Go->m[i]),pNeg(pCopy(factor2)));
3126            pDelete(&factor2);
3127          }
3128          pIter(p);
3129        }
3130        pDelete(&lm);
3131        pDelete(&p);
3132      }
3133    }
3134  }
3135
3136  if(middle == TRUE)
3137  {
3138    return Go;
3139  }
3140  idDelete(&Go);
3141  return NULL;
3142}
3143
3144/******************************  Februar 2002  ****************************
3145 * G is a Groebner basis w.r.t. (a(curr_weight),lp) and                   *
3146 * we compute a GB of <G> w.r.t. the lex. order by the perturbation walk  *
3147 * its perturbation degree is tp_deg                                      *
3148 * We call the following subfunction LastGB, if                           *
3149 * the computed intermediate weight vector or                             *
3150 * if the perturbed target weight vector does NOT lie n the correct cone  *
3151 **************************************************************************/
3152
3153static ideal LastGB(ideal G, intvec* curr_weight,int tp_deg)
3154{
3155  BOOLEAN nError = Overflow_Error;
3156  Overflow_Error = FALSE;
3157
3158  int i, nV = currRing->N;
3159  int nwalk=0, endwalks=0, nnwinC=1;
3160  int nlast = 0;
3161  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
3162  ring newRing, oldRing, TargetRing;
3163  intvec* iv_M_lp;
3164  intvec* target_weight;
3165  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
3166  intvec* pert_target_vector;
3167  intvec* ivNull = new intvec(nV);
3168  intvec* extra_curr_weight = new intvec(nV);
3169  intvec* next_weight;
3170
3171#ifndef  BUCHBERGER_ALG
3172  intvec* hilb_func;
3173#endif
3174
3175  // to avoid (1,0,...,0) as the target vector
3176  intvec* last_omega = new intvec(nV);
3177  for(i=nV-1; i>0; i--)
3178  {
3179    (*last_omega)[i] = 1;
3180  }
3181  (*last_omega)[0] = 10000;
3182
3183  ring EXXRing = currRing;
3184
3185  // compute a pertubed weight vector of the target weight vector
3186  if(tp_deg > 1 && tp_deg <= nV)
3187  {
3188    //..25.03.03 VMrDefaultlp();//    VMrDefault(target_weight);
3189    if (rParameter (currRing) != NULL)
3190    {
3191      DefRingParlp();
3192    }
3193    else
3194    {
3195      VMrDefaultlp();
3196    }
3197    TargetRing = currRing;
3198    ssG = idrMoveR(G,EXXRing,currRing);
3199    iv_M_lp = MivMatrixOrderlp(nV);
3200    //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
3201    target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
3202    delete iv_M_lp;
3203    pert_target_vector = target_weight;
3204
3205    rChangeCurrRing(EXXRing);
3206    G = idrMoveR(ssG, TargetRing,currRing);
3207  }
3208  else
3209  {
3210    target_weight = Mivlp(nV);
3211  }
3212  //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3213
3214  while(1)
3215  {
3216    nwalk++;
3217    nstep++;
3218    to=clock();
3219   // compute a next weight vector
3220    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
3221    xtnw=xtnw+clock()-to;
3222
3223#ifdef PRINT_VECTORS
3224    MivString(curr_weight, target_weight, next_weight);
3225#endif
3226
3227    if(Overflow_Error == TRUE)
3228    {
3229      newRing = currRing;
3230      nnwinC = 0;
3231      if(tp_deg == 1)
3232      {
3233        nlast = 1;
3234      }
3235      delete next_weight;
3236
3237      //idElements(G, "G");
3238      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3239
3240      break;
3241    }
3242
3243    if(MivComp(next_weight, ivNull) == 1)
3244    {
3245      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3246      newRing = currRing;
3247      delete next_weight;
3248      break;
3249    }
3250
3251    if(MivComp(next_weight, target_weight) == 1)
3252      endwalks = 1;
3253
3254    for(i=nV-1; i>=0; i--)
3255    {
3256      (*extra_curr_weight)[i] = (*curr_weight)[i];
3257    }
3258    /* 06.11.01 NOT Changed */
3259    for(i=nV-1; i>=0; i--)
3260    {
3261      (*curr_weight)[i] = (*next_weight)[i];
3262    }
3263    oldRing = currRing;
3264    to=clock();
3265    // compute an initial form ideal of <G> w.r.t. "curr_vector"
3266    Gomega = MwalkInitialForm(G, curr_weight);
3267    xtif=xtif+clock()-to;
3268
3269#ifdef ENDWALKS
3270    if(endwalks == 1)
3271    {
3272      Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3273/*
3274      idElements(Gomega, "Gw");
3275      headidString(Gomega, "Gw");
3276*/
3277    }
3278#endif
3279
3280#ifndef  BUCHBERGER_ALG
3281    if(isNolVector(curr_weight) == 0)
3282    {
3283      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
3284    }
3285    else
3286    {
3287      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
3288    }
3289#endif // BUCHBERGER_ALG
3290
3291    /* define a new ring that its ordering is "(a(curr_weight),lp) */
3292    //..25.03.03 VMrDefault(curr_weight);
3293    if (rParameter (currRing) != NULL)
3294    {
3295      DefRingPar(curr_weight);
3296    }
3297    else
3298    {
3299      rChangeCurrRing(VMrDefault(curr_weight));
3300    }
3301    newRing = currRing;
3302    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
3303
3304    to=clock();
3305    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
3306#ifdef  BUCHBERGER_ALG
3307    M = MstdhomCC(Gomega1);
3308#else
3309    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
3310    delete hilb_func;
3311#endif // BUCHBERGER_ALG
3312    xtstd=xtstd+clock()-to;
3313    /* change the ring to oldRing */
3314    rChangeCurrRing(oldRing);
3315    M1 =  idrMoveR(M, newRing,currRing);
3316    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
3317
3318    to=clock();
3319    /* compute a reduced Groebner basis of <G> w.r.t. "newRing" */
3320    F = MLifttwoIdeal(Gomega2, M1, G);
3321    xtlift=xtlift+clock()-to;
3322
3323    idDelete(&M1);
3324    idDelete(&G);
3325
3326    /* change the ring to newRing */
3327    rChangeCurrRing(newRing);
3328    F1 = idrMoveR(F, oldRing,currRing);
3329
3330    to=clock();
3331    /* reduce the Groebner basis <G> w.r.t. new ring */
3332    G = kInterRedCC(F1, NULL);
3333    xtred=xtred+clock()-to;
3334    idDelete(&F1);
3335
3336    if(endwalks == 1)
3337    {
3338      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3339      break;
3340    }
3341
3342    delete next_weight;
3343  }//while
3344
3345  delete ivNull;
3346
3347  if(tp_deg != 1)
3348  {
3349    //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3350    if (rParameter (currRing) != NULL)
3351    {
3352      DefRingParlp();
3353    }
3354    else
3355    {
3356      VMrDefaultlp();
3357    }
3358    F1 = idrMoveR(G, newRing,currRing);
3359
3360    if(nnwinC == 0 || test_w_in_ConeCC(F1, pert_target_vector) != 1)
3361    {
3362      oldRing = currRing;
3363      rChangeCurrRing(newRing);
3364      G = idrMoveR(F1, oldRing,currRing);
3365      Print("\n// takes %d steps and calls the recursion of level %d:",
3366             nwalk, tp_deg-1);
3367
3368      F1 = LastGB(G,curr_weight, tp_deg-1);
3369    }
3370
3371    TargetRing = currRing;
3372    rChangeCurrRing(EXXRing);
3373    result = idrMoveR(F1, TargetRing,currRing);
3374  }
3375  else
3376  {
3377    if(nlast == 1)
3378    {
3379      //OMEGA_OVERFLOW_LASTGB:
3380      /*
3381      if(MivSame(curr_weight, iv_lp) == 1)
3382        if (rParameter(currRing) != NULL)
3383          DefRingParlp();
3384        else
3385          VMrDefaultlp();
3386      else
3387        if (rParameter(currRing) != NULL)
3388          DefRingPar(curr_weight);
3389        else
3390          VMrDefault(curr_weight);
3391      */
3392
3393        //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3394        if (rParameter (currRing) != NULL)
3395        {
3396          DefRingParlp();
3397        }
3398        else
3399        {
3400          VMrDefaultlp();
3401        }
3402
3403      F1 = idrMoveR(G, newRing,currRing);
3404      //Print("\n// Apply \"std\" in ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3405
3406      G = MstdCC(F1);
3407      idDelete(&F1);
3408      newRing = currRing;
3409    }
3410
3411    rChangeCurrRing(EXXRing);
3412    result = idrMoveR(G, newRing,currRing);
3413  }
3414  delete target_weight;
3415  delete last_omega;
3416  delete iv_lp;
3417
3418  if(Overflow_Error == FALSE)
3419  {
3420    Overflow_Error = nError;
3421  }
3422  return(result);
3423}
3424
3425/**********************************************************
3426 * check whether a polynomial of G has least 4 monomials  *
3427 **********************************************************/
3428static int lengthpoly(ideal G)
3429{
3430  int i;
3431  for(i=IDELEMS(G)-1; i>=0; i--)
3432  {
3433    if((G->m[i]!=NULL) /* len >=0 */
3434       && (G->m[i]->next!=NULL) /* len >=1 */
3435       && (G->m[i]->next->next!=NULL) /* len >=2 */
3436       && (G->m[i]->next->next->next!=NULL) /* len >=3 */
3437       && (G->m[i]->next->next->next->next!=NULL) /* len >=4*/ )
3438    {
3439      return 1;
3440    }
3441  }
3442  return 0;
3443}
3444
3445/*****************************************
3446 * return maximal polynomial length of G *
3447 *****************************************/
3448static int maxlengthpoly(ideal G)
3449{
3450  int i,k,length=0;
3451  for(i=IDELEMS(G)-1; i>=0; i--)
3452  {
3453    k = pLength(G->m[i]);
3454    if(k>length)
3455    {
3456      length = k;
3457    }
3458  }
3459  return length;
3460}
3461
3462/*********************************************************
3463 * check whether a polynomial of G has least 2 monomials *
3464**********************************************************/
3465static int islengthpoly2(ideal G)
3466{
3467  int i;
3468  for(i=IDELEMS(G)-1; i>=0; i--)
3469  {
3470    if((G->m[i]!=NULL) /* len >=0 */
3471       && (G->m[i]->next!=NULL) /* len >=1 */
3472       && (G->m[i]->next->next!=NULL)) /* len >=2 */
3473    {
3474      return 1;
3475    }
3476  }
3477  return 0;
3478}
3479
3480
3481
3482/* Implementation of the improved Groebner walk algorithm which is written
3483   by Quoc-Nam Tran (2000).
3484   One perturbs the original target weight vector, only if
3485   the next intermediate weight vector is equal to the current target weight
3486   vector. This must be repeated until the wanted reduced Groebner basis
3487   to reach.
3488   If the numbers of variables is big enough, the representation of the origin
3489   weight vector may be very big. Therefore, it is possible the intermediate
3490   weight vector doesn't stay in the correct Groebner cone.
3491   In this case we have just a reduced Groebner basis of the given ideal
3492   with respect to another monomial order. Then we have to compute
3493   a wanted reduced Groebner basis of it with respect to the given order.
3494   At the following subroutine we use the improved Buchberger algorithm or
3495   the changed perturbation walk algorithm with a decrased degree.
3496 */
3497
3498/***************************************
3499 * return the initial term of an ideal *
3500 ***************************************/
3501static ideal idHeadCC(ideal h)
3502{
3503  int i, nH =IDELEMS(h);
3504
3505  ideal m = idInit(nH,h->rank);
3506
3507  for (i=nH-1;i>=0; i--)
3508  {
3509    if (h->m[i]!=NULL)
3510    {
3511      m->m[i]=pHead(h->m[i]);
3512    }
3513  }
3514  return m;
3515}
3516
3517/**********************************************
3518 * check whether two head-ideals are the same *
3519 **********************************************/
3520static inline int test_G_GB_walk(ideal H0, ideal H1)
3521{
3522  int i, nG = IDELEMS(H0);
3523
3524  if(nG != IDELEMS(H1))
3525  {
3526    return 0;
3527  }
3528  for(i=nG-1; i>=0; i--)
3529  {
3530/*
3531    poly t;
3532    if((t=pSub(pCopy(H0->m[i]), pCopy(H1->m[i]))) != NULL)
3533    {
3534      pDelete(&t);
3535      return 0;
3536    }
3537    pDelete(&t);
3538*/
3539    if(!pEqualPolys(H0->m[i],H1->m[i]))
3540    {
3541      return 0;
3542    }
3543  }
3544  return 1;
3545}
3546
3547//unused
3548/*****************************************************
3549 * find the maximal total degree of polynomials in G *
3550 *****************************************************/
3551/*
3552static int Trandegreebound(ideal G)
3553{
3554  int i, nG = IDELEMS(G);
3555  // int np=1;
3556  int nV = currRing->N;
3557  int degtmp, result = 0;
3558  intvec* ivUnit = Mivdp(nV);
3559
3560  for(i=nG-1; i>=0; i--)
3561  {
3562    // find the maximal total degree of the polynomial G[i]
3563    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3564    if(degtmp > result)
3565    {
3566      result = degtmp;
3567    }
3568  }
3569  delete ivUnit;
3570  return result;
3571}
3572*/
3573
3574//unused
3575/************************************************************************
3576 * perturb the weight vector iva w.r.t. the ideal G.                    *
3577 *  the monomial order of the current ring is the w_1 weight lex. order *
3578 *  define w := d^(n-1)w_1+ d^(n-2)w_2, ...+ dw_(n-1)+ w_n              *
3579 *  where d := 1 + max{totdeg(g):g in G}*m, or                          *
3580 *  d := (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;                           *
3581 ************************************************************************/
3582#if 0
3583static intvec* TranPertVector(ideal G, intvec* iva)
3584{
3585  BOOLEAN nError = Overflow_Error;
3586  Overflow_Error = FALSE;
3587
3588  int i, j;
3589  // int nG = IDELEMS(G);
3590  int nV = currRing->N;
3591
3592  // define the sequence which expresses the current monomial ordering
3593  // w_1 = iva; w_2 = (1,0,..,0); w_n = (0,...,0,1,0)
3594  intvec* ivMat = MivMatrixOrder(iva);
3595
3596  int  mtmp, m=(*iva)[0];
3597
3598  for(i=ivMat->length(); i>=0; i--)
3599  {
3600    mtmp = (*ivMat)[i];
3601    if(mtmp <0)
3602    {
3603      mtmp = -mtmp;
3604    }
3605    if(mtmp > m)
3606    {
3607      m = mtmp;
3608    }
3609  }
3610
3611  // define the maximal total degree of polynomials of G
3612  mpz_t ndeg;
3613  mpz_init(ndeg);
3614
3615 // 12 Juli 03
3616#ifndef UPPER_BOUND
3617  mpz_set_si(ndeg, Trandegreebound(G)+1);
3618#else
3619  mpz_t ztmp;
3620  mpz_init(ztmp);
3621
3622  mpz_t maxdeg;
3623  mpz_init_set_si(maxdeg, Trandegreebound(G));
3624
3625  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;//Kalkbrenner (1999)
3626  mpz_pow_ui(ztmp, maxdeg, 2);
3627  mpz_mul_ui(ztmp, ztmp, 2);
3628  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3629  mpz_add(ndeg, ztmp, maxdeg);
3630  mpz_mul_ui(ndeg, ndeg, m);
3631
3632  mpz_clear(ztmp);
3633
3634  //PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3635  //Print("\n//         where d = %d, n = %d and bound = %d", maxdeg, nV, ndeg);
3636#endif //UPPER_BOUND
3637
3638#ifdef INVEPS_SMALL_IN_TRAN
3639  if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3640  {
3641    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3642  }
3643 //PrintS("\n// choose the \"small\" inverse epsilon:");
3644 //mpz_out_str(stdout, 10, ndeg);
3645#endif
3646  mpz_t deg_tmp;
3647  mpz_init_set(deg_tmp, ndeg);
3648
3649  mpz_t *ivres=( mpz_t *) omAlloc(nV*sizeof(mpz_t));
3650  mpz_init_set_si(ivres[nV-1],1);
3651
3652  for(i=nV-2; i>=0; i--)
3653  {
3654    mpz_init_set(ivres[i], deg_tmp);
3655    mpz_mul(deg_tmp, deg_tmp, ndeg);
3656  }
3657
3658  mpz_t *ivtmp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3659  for(i=0; i<nV; i++)
3660  {
3661    mpz_init(ivtmp[i]);
3662  }
3663  mpz_t sing_int;
3664  mpz_init_set_ui(sing_int,  2147483647);
3665
3666  intvec* repr_vector = new intvec(nV);
3667
3668  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3669  for(i=0; i<nV; i++)
3670  {
3671    for(j=0; j<nV; j++)
3672    {
3673      if( (*ivMat)[i*nV+j] >= 0 )
3674      {
3675        mpz_mul_ui(ivres[i], ivres[i], (*ivMat)[i*nV+j]);
3676      }
3677      else
3678      {
3679        mpz_mul_ui(ivres[i], ivres[i], -(*ivMat)[i*nV+j]);
3680        mpz_neg(ivres[i], ivres[i]);
3681      }
3682      mpz_add(ivtmp[j], ivtmp[j], ivres[i]);
3683    }
3684  }
3685  delete ivMat;
3686
3687  int ntrue=0;
3688  for(i=0; i<nV; i++)
3689  {
3690    (*repr_vector)[i] = mpz_get_si(ivtmp[i]);
3691    if(mpz_cmp(ivtmp[i], sing_int)>=0)
3692    {
3693      ntrue++;
3694      if(Overflow_Error == FALSE)
3695      {
3696        Overflow_Error = TRUE;
3697
3698        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3699        mpz_out_str( stdout, 10, ivtmp[i]);
3700        PrintS(" is greater than 2147483647 (max. integer representation)");
3701        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3702      }
3703    }
3704  }
3705  if(Overflow_Error == TRUE)
3706  {
3707    ivString(repr_vector, "repvector");
3708    Print("\n// %d element(s) of it are overflow!!", ntrue);
3709  }
3710
3711  if(Overflow_Error == FALSE)
3712    Overflow_Error=nError;
3713
3714  omFree(ivres);
3715  omFree(ivtmp);
3716
3717  mpz_clear(sing_int);
3718  mpz_clear(deg_tmp);
3719  mpz_clear(ndeg);
3720
3721  return repr_vector;
3722}
3723#endif
3724
3725//unused
3726#if 0
3727static intvec* TranPertVector_lp(ideal G)
3728{
3729  BOOLEAN nError = Overflow_Error;
3730  Overflow_Error = FALSE;
3731  // int j, nG = IDELEMS(G);
3732  int i;
3733  int nV = currRing->N;
3734
3735  // define the maximal total degree of polynomials of G
3736  mpz_t ndeg;
3737  mpz_init(ndeg);
3738
3739 // 12 Juli 03
3740#ifndef UPPER_BOUND
3741  mpz_set_si(ndeg, Trandegreebound(G)+1);
3742#else
3743  mpz_t ztmp;
3744  mpz_init(ztmp);
3745
3746  mpz_t maxdeg;
3747  mpz_init_set_si(maxdeg, Trandegreebound(G));
3748
3749  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg);//Kalkbrenner (1999)
3750  mpz_pow_ui(ztmp, maxdeg, 2);
3751  mpz_mul_ui(ztmp, ztmp, 2);
3752  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3753  mpz_add(ndeg, ztmp, maxdeg);
3754  // PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3755  // Print("\n//         where d = %d, n = %d and bound = %d",
3756  // mpz_get_si(maxdeg), nV, mpz_get_si(ndeg));
3757
3758 mpz_clear(ztmp);
3759
3760#endif
3761
3762#ifdef INVEPS_SMALL_IN_TRAN
3763 if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3764    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3765
3766 //PrintS("\n// choose the \"small\" inverse epsilon:");
3767 // mpz_out_str(stdout, 10, ndeg);
3768#endif
3769
3770  mpz_t deg_tmp;
3771  mpz_init_set(deg_tmp, ndeg);
3772
3773  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3774  mpz_init_set_si(ivres[nV-1], 1);
3775
3776  for(i=nV-2; i>=0; i--)
3777  {
3778    mpz_init_set(ivres[i], deg_tmp);
3779    mpz_mul(deg_tmp, deg_tmp, ndeg);
3780  }
3781
3782  mpz_t sing_int;
3783  mpz_init_set_ui(sing_int,  2147483647);
3784
3785  intvec* repr_vector = new intvec(nV);
3786  int ntrue=0;
3787  for(i=0; i<nV; i++)
3788  {
3789    (*repr_vector)[i] = mpz_get_si(ivres[i]);
3790
3791    if(mpz_cmp(ivres[i], sing_int)>=0)
3792    {
3793      ntrue++;
3794      if(Overflow_Error == FALSE)
3795      {
3796        Overflow_Error = TRUE;
3797        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3798        mpz_out_str( stdout, 10, ivres[i]);
3799        PrintS(" is greater than 2147483647 (max. integer representation)");
3800        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3801      }
3802    }
3803  }
3804  if(Overflow_Error == TRUE)
3805  {
3806    ivString(repr_vector, "repvector");
3807    Print("\n// %d element(s) of it are overflow!!", ntrue);
3808  }
3809  if(Overflow_Error == FALSE)
3810    Overflow_Error = nError;
3811
3812  omFree(ivres);
3813
3814  mpz_clear(ndeg);
3815  mpz_clear(sing_int);
3816
3817  return repr_vector;
3818}
3819#endif
3820
3821//unused
3822#if 0
3823static intvec* RepresentationMatrix_Dp(ideal G, intvec* M)
3824{
3825  BOOLEAN nError = Overflow_Error;
3826  Overflow_Error = FALSE;
3827
3828  int i, j;
3829  int nV = currRing->N;
3830
3831  intvec* ivUnit = Mivdp(nV);
3832  int degtmp, maxdeg = 0;
3833
3834  for(i=IDELEMS(G)-1; i>=0; i--)
3835  {
3836    // find the maximal total degree of the polynomial G[i]
3837    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3838    if(degtmp > maxdeg)
3839      maxdeg = degtmp;
3840  }
3841
3842  mpz_t ztmp;
3843  mpz_init_set_si(ztmp, maxdeg);
3844  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3845  mpz_init_set_si(ivres[nV-1], 1); // (*ivres)[nV-1] = 1;
3846
3847  for(i=nV-2; i>=0; i--)
3848  {
3849    mpz_init_set(ivres[i], ztmp); //(*ivres)[i] = ztmp;
3850    mpz_mul_ui(ztmp, ztmp, maxdeg); //ztmp *=maxdeg;
3851  }
3852
3853  mpz_t *ivtmp=(mpz_t*)omAlloc(nV*sizeof(mpz_t));
3854  for(i=0; i<nV; i++)
3855    mpz_init(ivtmp[i]);
3856
3857  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3858  for(i=0; i<nV; i++)
3859    for(j=0; j<nV; j++)
3860    {
3861      if((*M)[i*nV+j] < 0)
3862      {
3863        mpz_mul_ui(ztmp, ivres[i], -(*M)[i*nV+j]);
3864        mpz_neg(ztmp, ztmp);
3865      }
3866      else
3867        mpz_mul_ui(ztmp, ivres[i], (*M)[i*nV+j]);
3868
3869      mpz_add(ivtmp[j], ivtmp[j], ztmp);
3870    }
3871  delete ivres;
3872  mpz_t sing_int;
3873  mpz_init_set_ui(sing_int,  2147483647);
3874
3875  int ntrue=0;
3876  intvec* repvector = new intvec(nV);
3877  for(i=0; i<nV; i++)
3878  {
3879    (*repvector)[i] = mpz_get_si(ivtmp[i]);
3880    if(mpz_cmp(ivtmp[i], sing_int)>0)
3881    {
3882      ntrue++;
3883      if(Overflow_Error == FALSE)
3884      {
3885        Overflow_Error = TRUE;
3886        PrintS("\n// ** OVERFLOW in \"Repr.Matrix\": ");
3887        mpz_out_str( stdout, 10, ivtmp[i]);
3888        PrintS(" is greater than 2147483647 (max. integer representation)");
3889        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repvector)[i]);
3890      }
3891    }
3892  }
3893  if(Overflow_Error == TRUE)
3894  {
3895    ivString(repvector, "repvector");
3896    Print("\n// %d element(s) of it are overflow!!", ntrue);
3897  }
3898
3899  if(Overflow_Error == FALSE)
3900    Overflow_Error = nError;
3901
3902  mpz_clear(sing_int);
3903  mpz_clear(ztmp);
3904  omFree(ivtmp);
3905  omFree(ivres);
3906  return repvector;
3907}
3908#endif
3909
3910/*****************************************************************************
3911 * The following subroutine is the implementation of our first improved      *
3912 * Groebner walk algorithm, i.e. the first altervative algorithm.            *
3913 * First we use the Grobner walk algorithm and then we call the changed      *
3914 * perturbation walk algorithm with decreased degree, if an intermediate     *
3915 * weight vector is equal to the current target weight vector.               *
3916 * This call will be only repeated until we get the wanted reduced Groebner  *
3917 * basis or n times, where n is the numbers of variables.                    *
3918 *****************************************************************************/
3919
3920// npwinc = 0, if curr_weight doesn't stay in the correct Groebner cone
3921static ideal Rec_LastGB(ideal G, intvec* curr_weight,
3922                        intvec* orig_target_weight, int tp_deg, int npwinc)
3923{
3924  BOOLEAN nError = Overflow_Error;
3925  Overflow_Error = FALSE;
3926  // BOOLEAN nOverflow_Error = FALSE;
3927
3928  clock_t tproc=0;
3929  clock_t tinput = clock();
3930
3931  int i,  nV = currRing->N;
3932  int nwalk=0, endwalks=0, nnwinC=1;
3933  int nlast = 0;
3934  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
3935  ring newRing, oldRing, TargetRing;
3936  intvec* iv_M_lp;
3937  intvec* target_weight;
3938  intvec* ivNull = new intvec(nV); //define (0,...,0)
3939  ring EXXRing = currRing;
3940  //int NEG=0; //19 juni 03
3941  intvec* next_weight;
3942#ifndef  BUCHBERGER_ALG
3943  //08 Juli 03
3944  intvec* hilb_func;
3945#endif
3946  // to avoid (1,0,...,0) as the target vector
3947  intvec* last_omega = new intvec(nV);
3948  for(i=nV-1; i>0; i--)
3949    (*last_omega)[i] = 1;
3950  (*last_omega)[0] = 10000;
3951
3952  BOOLEAN isGB = FALSE;
3953
3954  // compute a pertubed weight vector of the target weight vector
3955  if(tp_deg > 1 && tp_deg <= nV)
3956  {
3957    ideal H0 = idHeadCC(G);
3958
3959    if (rParameter (currRing) != NULL)
3960    {
3961      DefRingParlp();
3962    }
3963    else
3964    {
3965      VMrDefaultlp();
3966    }
3967    TargetRing = currRing;
3968    ssG = idrMoveR(G,EXXRing,currRing);
3969
3970    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
3971    ideal H1 = idHeadCC(ssG);
3972
3973    // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
3974    if(test_G_GB_walk(H0_tmp,H1)==1)
3975    {
3976      idDelete(&H0_tmp);
3977      idDelete(&H1);
3978      G = ssG;
3979      ssG = NULL;
3980      newRing = currRing;
3981      delete ivNull;
3982
3983      if(npwinc != 0)
3984      {
3985        goto LastGB_Finish;
3986      }
3987      else
3988      {
3989        isGB = TRUE;
3990        goto KSTD_Finish;
3991      }
3992    }
3993    idDelete(&H0_tmp);
3994    idDelete(&H1);
3995
3996    iv_M_lp = MivMatrixOrderlp(nV);
3997    target_weight  = MPertVectors(ssG, iv_M_lp, tp_deg);
3998    delete iv_M_lp;
3999    //PrintS("\n// Input is not GB!!");
4000    rChangeCurrRing(EXXRing);
4001    G = idrMoveR(ssG, TargetRing,currRing);
4002
4003    if(Overflow_Error == TRUE)
4004    {
4005      //nOverflow_Error = Overflow_Error;
4006      //NEG = 1;
4007      newRing = currRing;
4008      goto JUNI_STD;
4009    }
4010  }
4011
4012  while(1)
4013  {
4014    nwalk ++;
4015    nstep++;
4016
4017    if(nwalk==1)
4018    {
4019      goto FIRST_STEP;
4020    }
4021    to=clock();
4022    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4023    Gomega = MwalkInitialForm(G, curr_weight);
4024    xtif=xtif+clock()-to;
4025
4026#ifndef  BUCHBERGER_ALG
4027    if(isNolVector(curr_weight) == 0)
4028    {
4029      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4030    }
4031    else
4032    {
4033      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4034    }
4035#endif // BUCHBERGER_ALG
4036
4037    oldRing = currRing;
4038
4039    // defiNe a new ring that its ordering is "(a(curr_weight),lp)
4040    if (rParameter(currRing) != NULL)
4041    {
4042      DefRingPar(curr_weight);
4043    }
4044    else
4045    {
4046      rChangeCurrRing(VMrDefault(curr_weight));
4047    }
4048    newRing = currRing;
4049    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4050    to=clock();
4051    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4052#ifdef  BUCHBERGER_ALG
4053    M = MstdhomCC(Gomega1);
4054#else
4055    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4056    delete hilb_func;
4057#endif // BUCHBERGER_ALG
4058    xtstd=xtstd+clock()-to;
4059    // change the ring to oldRing
4060    rChangeCurrRing(oldRing);
4061    M1 =  idrMoveR(M, newRing,currRing);
4062    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4063
4064     to=clock();
4065    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
4066    F = MLifttwoIdeal(Gomega2, M1, G);
4067    xtlift=xtlift+clock()-to;
4068    idDelete(&M1);
4069    idDelete(&Gomega2);
4070    idDelete(&G);
4071
4072    // change the ring to newRing
4073    rChangeCurrRing(newRing);
4074    F1 = idrMoveR(F, oldRing,currRing);
4075
4076    to=clock();
4077    // reduce the Groebner basis <G> w.r.t. new ring
4078    G = kInterRedCC(F1, NULL);
4079    xtred=xtred+clock()-to;
4080    idDelete(&F1);
4081
4082    if(endwalks == 1)
4083    {
4084      break;
4085    }
4086  FIRST_STEP:
4087    to=clock();
4088    Overflow_Error = FALSE;
4089    // compute a next weight vector
4090    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4091    xtnw=xtnw+clock()-to;
4092#ifdef PRINT_VECTORS
4093    MivString(curr_weight, target_weight, next_weight);
4094#endif
4095    if(Overflow_Error == TRUE)
4096    {
4097      //PrintS("\n// ** The next vector does NOT stay in Cone!!\n");
4098#ifdef TEST_OVERFLOW
4099      goto  LastGB_Finish;
4100#endif
4101
4102      nnwinC = 0;
4103      if(tp_deg == nV)
4104      {
4105        nlast = 1;
4106      }
4107      delete next_weight;
4108      break;
4109    }
4110
4111    if(MivComp(next_weight, ivNull) == 1)
4112    {
4113      //newRing = currRing;
4114      delete next_weight;
4115      break;
4116    }
4117
4118    if(MivComp(next_weight, target_weight) == 1)
4119    {
4120      if(tp_deg == nV)
4121      {
4122        endwalks = 1;
4123      }
4124      else
4125      {
4126        // REC_LAST_GB_ALT2:
4127        //nOverflow_Error = Overflow_Error;
4128        tproc=tproc+clock()-tinput;
4129
4130        /*Print("\n// takes %d steps and calls \"Rec_LastGB\" (%d):",
4131        nwalk, tp_deg+1);
4132        */
4133        G = Rec_LastGB(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4134        newRing = currRing;
4135        delete next_weight;
4136        break;
4137      }
4138    }
4139
4140    for(i=nV-1; i>=0; i--)
4141    {
4142      (*curr_weight)[i] = (*next_weight)[i];
4143    }
4144    delete next_weight;
4145  }//while
4146
4147  delete ivNull;
4148
4149  if(tp_deg != nV)
4150  {
4151    newRing = currRing;
4152
4153    if (rParameter(currRing) != NULL)
4154    {
4155      DefRingParlp();
4156    }
4157    else
4158    {
4159      VMrDefaultlp();
4160    }
4161    F1 = idrMoveR(G, newRing,currRing);
4162
4163    if(nnwinC == 0 || test_w_in_ConeCC(F1, target_weight) != 1 )
4164    {
4165      // nOverflow_Error = Overflow_Error;
4166      //Print("\n//  takes %d steps and calls \"Rec_LastGB (%d):", tp_deg+1);
4167      tproc=tproc+clock()-tinput;
4168      F1 = Rec_LastGB(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4169    }
4170    delete target_weight;
4171
4172    TargetRing = currRing;
4173    rChangeCurrRing(EXXRing);
4174    result = idrMoveR(F1, TargetRing,currRing);
4175  }
4176  else
4177  {
4178    if(nlast == 1)
4179    {
4180      JUNI_STD:
4181
4182      newRing = currRing;
4183      if (rParameter(currRing) != NULL)
4184      {
4185        DefRingParlp();
4186      }
4187      else
4188      {
4189        VMrDefaultlp();
4190      }
4191      KSTD_Finish:
4192      if(isGB == FALSE)
4193      {
4194        F1 = idrMoveR(G, newRing,currRing);
4195      }
4196      else
4197      {
4198        F1 = G;
4199      }
4200      to=clock();
4201      // Print("\n// apply the Buchberger's alg in ring = %s",rString(currRing));
4202      // idElements(F1, "F1");
4203      G = MstdCC(F1);
4204      xtextra=xtextra+clock()-to;
4205
4206
4207      idDelete(&F1);
4208      newRing = currRing;
4209    }
4210
4211    LastGB_Finish:
4212    rChangeCurrRing(EXXRing);
4213    result = idrMoveR(G, newRing,currRing);
4214  }
4215
4216  if(Overflow_Error == FALSE)
4217    {
4218    Overflow_Error=nError;
4219    }
4220#ifdef TIME_TEST
4221   //Print("\n// \"Rec_LastGB\" (%d) took %d steps and %.2f sec.Overflow_Error (%d)", tp_deg, nwalk, ((double) tproc)/1000000, nOverflow_Error);
4222#endif
4223  return(result);
4224}
4225
4226/* The following subroutine is the implementation of our second improved
4227   Groebner walk algorithm, i.e. the second altervative algorithm.
4228   First we use the Grobner walk algorithm and then we call the changed
4229   perturbation walk algorithm with increased degree, if an intermediate
4230   weight vector is equal to the current target weight vector.
4231   This call will be only repeated until we get the wanted reduced Groebner
4232   basis or n times, where n is the numbers of variables.
4233*/
4234
4235/******************************
4236 * walk + recursive LastGB    *
4237 ******************************/
4238ideal MAltwalk2(ideal Go, intvec* curr_weight, intvec* target_weight)
4239{
4240  Set_Error(FALSE);
4241  Overflow_Error = FALSE;
4242  //BOOLEAN nOverflow_Error = FALSE;
4243  //Print("// pSetm_Error = (%d)", ErrorCheck());
4244#ifdef TIME_TEST
4245  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
4246  xftinput = clock();
4247  clock_t tostd, tproc;
4248#endif
4249  nstep = 0;
4250  int i, nV = currRing->N;
4251  int nwalk=0, endwalks=0;
4252  // int nhilb = 1;
4253  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
4254  //ideal  G1;
4255  //ring endRing;
4256  ring newRing, oldRing;
4257  intvec* ivNull = new intvec(nV);
4258  intvec* next_weight;
4259  //intvec* extra_curr_weight = new intvec(nV);
4260  //intvec* hilb_func;
4261  intvec* exivlp = Mivlp(nV);
4262  ring XXRing = currRing;
4263
4264  //Print("\n// ring r_input = %s;", rString(currRing));
4265#ifdef TIME_TEST
4266  to = clock();
4267#endif
4268  /* compute the reduced Groebner basis of the given ideal w.r.t.
4269     a "fast" monomial order, e.g. degree reverse lex. order (dp) */
4270  G = MstdCC(Go);
4271#ifdef TIME_TEST
4272  tostd=clock()-to;
4273
4274  Print("\n// Computation of the first std took = %.2f sec",
4275        ((double) tostd)/1000000);
4276#endif
4277  if(currRing->order[0] == ringorder_a)
4278  {
4279    goto NEXT_VECTOR;
4280  }
4281  while(1)
4282  {
4283    nwalk ++;
4284    nstep ++;
4285#ifdef TIME_TEST
4286    to = clock();
4287#endif
4288    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
4289    Gomega = MwalkInitialForm(G, curr_weight);
4290#ifdef TIME_TEST
4291    xtif=xtif+clock()-to;
4292#endif
4293/*
4294    if(Overflow_Error == TRUE)
4295    {
4296      for(i=nV-1; i>=0; i--)
4297        (*curr_weight)[i] = (*extra_curr_weight)[i];
4298      delete extra_curr_weight;
4299      goto LAST_GB_ALT2;
4300    }
4301*/
4302    oldRing = currRing;
4303
4304    /* define a new ring that its ordering is "(a(curr_weight),lp) */
4305    if (rParameter(currRing) != NULL)
4306    {
4307      DefRingPar(curr_weight);
4308    }
4309    else
4310    {
4311      rChangeCurrRing(VMrDefault(curr_weight));
4312    }
4313    newRing = currRing;
4314    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4315#ifdef TIME_TEST
4316    to = clock();
4317#endif
4318    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
4319    M = MstdhomCC(Gomega1);
4320#ifdef TIME_TEST
4321    xtstd=xtstd+clock()-to;
4322#endif
4323    /* change the ring to oldRing */
4324    rChangeCurrRing(oldRing);
4325    M1 =  idrMoveR(M, newRing,currRing);
4326    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4327#ifdef TIME_TEST
4328    to = clock();
4329#endif
4330    /* compute the reduced Groebner basis of <G> w.r.t. "newRing"
4331       by the liftig process */
4332    F = MLifttwoIdeal(Gomega2, M1, G);
4333#ifdef TIME_TEST
4334    xtlift=xtlift+clock()-to;
4335#endif
4336    idDelete(&M1);
4337    idDelete(&Gomega2);
4338    idDelete(&G);
4339
4340    /* change the ring to newRing */
4341    rChangeCurrRing(newRing);
4342    F1 = idrMoveR(F, oldRing,currRing);
4343#ifdef TIME_TEST
4344    to = clock();
4345#endif
4346    /* reduce the Groebner basis <G> w.r.t. newRing */
4347    G = kInterRedCC(F1, NULL);
4348#ifdef TIME_TEST
4349    xtred=xtred+clock()-to;
4350#endif
4351    idDelete(&F1);
4352
4353    if(endwalks == 1)
4354      break;
4355
4356  NEXT_VECTOR:
4357#ifdef TIME_TEST
4358    to = clock();
4359#endif
4360    /* compute a next weight vector */
4361    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4362#ifdef TIME_TEST
4363    xtnw=xtnw+clock()-to;
4364#endif
4365#ifdef PRINT_VECTORS
4366    MivString(curr_weight, target_weight, next_weight);
4367#endif
4368
4369    if(Overflow_Error == TRUE)
4370    {
4371      /*
4372        ivString(next_weight, "omega");
4373        PrintS("\n// ** The weight vector does NOT stay in Cone!!\n");
4374      */
4375#ifdef TEST_OVERFLOW
4376      goto  TEST_OVERFLOW_OI;
4377#endif
4378
4379      newRing = currRing;
4380      if (rParameter(currRing) != NULL)
4381      {
4382        DefRingPar(target_weight);
4383      }
4384      else
4385      {
4386        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
4387      }
4388      F1 = idrMoveR(G, newRing,currRing);
4389      G = MstdCC(F1);
4390      idDelete(&F1);
4391      newRing = currRing;
4392      break;
4393    }
4394
4395    if(MivComp(next_weight, ivNull) == 1)
4396    {
4397      newRing = currRing;
4398      delete next_weight;
4399      break;
4400    }
4401
4402    if(MivComp(next_weight, target_weight) == 1)
4403    {
4404      if(MivSame(target_weight, exivlp)==1)
4405      {
4406     // LAST_GB_ALT2:
4407        //nOverflow_Error = Overflow_Error;
4408#ifdef TIME_TEST
4409        tproc = clock()-xftinput;
4410#endif
4411        //Print("\n// takes %d steps and calls the recursion of level 2:",  nwalk);
4412        /* call the changed perturbation walk algorithm with degree 2 */
4413        G = Rec_LastGB(G, curr_weight, target_weight, 2,1);
4414        newRing = currRing;
4415        delete next_weight;
4416        break;
4417      }
4418      endwalks = 1;
4419    }
4420
4421    for(i=nV-1; i>=0; i--)
4422    {
4423      //(*extra_curr_weight)[i] = (*curr_weight)[i];
4424      (*curr_weight)[i] = (*next_weight)[i];
4425    }
4426    delete next_weight;
4427  }
4428#ifdef TEST_OVERFLOW
4429 TEST_OVERFLOW_OI:
4430#endif
4431  rChangeCurrRing(XXRing);
4432  G = idrMoveR(G, newRing,currRing);
4433  delete ivNull;
4434  delete exivlp;
4435
4436#ifdef TIME_TEST
4437  /*Print("\n// \"Main procedure\"  took %d steps dnd %.2f sec. Overflow_Error (%d)",
4438        nwalk, ((double) tproc)/1000000, nOverflow_Error);
4439*/
4440  TimeStringFractal(xftinput, tostd, xtif, xtstd, xtextra,xtlift, xtred,xtnw);
4441
4442  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
4443  //Print("\n// Overflow_Error? (%d)", nOverflow_Error);
4444  //Print("\n// Awalk2 took %d steps!!", nstep);
4445#endif
4446
4447  return(G);
4448}
4449
4450
4451/**************************************
4452 * perturb the matrix order of  "lex" *
4453 **************************************/
4454static intvec* NewVectorlp(ideal I)
4455{
4456  int nV = currRing->N;
4457  intvec* iv_wlp =  MivMatrixOrderlp(nV);
4458  intvec* result = Mfpertvector(I, iv_wlp);
4459  delete iv_wlp;
4460  return result;
4461}
4462
4463int ngleich;
4464intvec* Xsigma;
4465intvec* Xtau;
4466int xn;
4467intvec* Xivinput;
4468intvec* Xivlp;
4469
4470
4471/********************************
4472 * compute a next weight vector *
4473 ********************************/
4474static intvec* MWalkRandomNextWeight(ideal G, intvec* orig_M, intvec* target_weight,
4475       int weight_rad, int pert_deg)
4476{
4477  assume(currRing != NULL && orig_M != NULL &&
4478         target_weight != NULL && G->m[0] != NULL);
4479
4480  //BOOLEAN nError = Overflow_Error;
4481  Overflow_Error = FALSE;
4482
4483  BOOLEAN found_random_weight = FALSE;
4484  int i,nV = currRing->N;
4485  intvec* curr_weight = new intvec(nV);
4486
4487  for(i=0; i<nV; i++)
4488  {
4489    (*curr_weight)[i] = (*orig_M)[i];
4490  }
4491
4492  int k=0,weight_norm;
4493  intvec* next_weight;
4494  intvec* next_weight1 = MkInterRedNextWeight(curr_weight,target_weight,G);
4495  intvec* next_weight2 = new intvec(nV);
4496  intvec* next_weight22 = new intvec(nV);
4497  intvec* result = new intvec(nV);
4498  intvec* curr_weight1;
4499  ideal G_test, G_test1, G_test2;
4500
4501  //try to find a random next weight vector "next_weight2"
4502  if(weight_rad > 0)
4503  {
4504    while(k<10)
4505    {
4506      weight_norm = 0;
4507      while(weight_norm == 0)
4508      {
4509        for(i=0; i<nV; i++)
4510        {
4511          (*next_weight2)[i] = rand() % 60000 - 30000;
4512          weight_norm = weight_norm + (*next_weight2)[i]*(*next_weight2)[i];
4513        }
4514        weight_norm = 1 + floor(sqrt(weight_norm));
4515      }
4516      for(i=0; i<nV; i++)
4517      {
4518        if((*next_weight2)[i] < 0)
4519        {
4520          (*next_weight2)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4521        }
4522        else
4523        {
4524          (*next_weight2)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4525        }
4526      }
4527      if(test_w_in_ConeCC(G,next_weight2) == 1)
4528      {
4529        if(maxlengthpoly(MwalkInitialForm(G,next_weight2))<2)
4530        {
4531          next_weight2 = MkInterRedNextWeight(next_weight2,target_weight,G);
4532        }
4533        G_test2 = MwalkInitialForm(G, next_weight2);
4534        found_random_weight = TRUE;
4535        break;
4536      }
4537      k++;
4538    }
4539  }
4540
4541  // compute "perturbed" next weight vector
4542  if(pert_deg > 1)
4543  {
4544    curr_weight1 = MPertVectors(G,orig_M,pert_deg);
4545    next_weight = MkInterRedNextWeight(curr_weight1,target_weight,G);
4546    delete curr_weight1;
4547  }
4548  else
4549  {
4550    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4551  }
4552  if(MivSame(curr_weight,next_weight)==1 || Overflow_Error == TRUE)
4553  {
4554    Overflow_Error = FALSE;
4555    delete next_weight;
4556    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4557  }
4558  G_test=MwalkInitialForm(G,next_weight);
4559  G_test1=MwalkInitialForm(G,next_weight1);
4560
4561  // compare next weights
4562  if(Overflow_Error == FALSE)
4563  {
4564    if(found_random_weight == TRUE)
4565    {
4566    // random next weight vector found
4567      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4568      {
4569        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test1))
4570        {
4571          for(i=0; i<nV; i++)
4572          {
4573            (*result)[i] = (*next_weight2)[i];
4574          }
4575        }
4576        else
4577        {
4578          for(i=0; i<nV; i++)
4579          {
4580            (*result)[i] = (*next_weight1)[i];
4581          }
4582        }
4583      }
4584      else
4585      {
4586        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4587        {
4588          for(i=0; i<nV; i++)
4589          {
4590            (*result)[i] = (*next_weight2)[i];
4591          }
4592        }
4593        else
4594        {
4595          for(i=0; i<nV; i++)
4596          {
4597            (*result)[i] = (*next_weight)[i];
4598          }
4599        }
4600      }
4601    }
4602    else
4603    {
4604      // no random next weight vector found
4605      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4606      {
4607       for(i=0; i<nV; i++)
4608        {
4609          (*result)[i] = (*next_weight1)[i];
4610        }
4611      }
4612      else
4613      {
4614        for(i=0; i<nV; i++)
4615        {
4616          (*result)[i] = (*next_weight)[i];
4617        }
4618      }
4619    }
4620  }
4621  else
4622  {
4623    Overflow_Error = FALSE;
4624    if(found_random_weight == TRUE)
4625    {
4626      if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4627      {
4628        for(i=1; i<nV; i++)
4629        {
4630          (*result)[i] = (*next_weight2)[i];
4631        }
4632      }
4633      else
4634      {
4635        for(i=0; i<nV; i++)
4636        {
4637          (*result)[i] = (*next_weight)[i];
4638        }
4639      }
4640    }
4641    else
4642    {
4643      for(i=0; i<nV; i++)
4644      {
4645        (*result)[i] = (*next_weight)[i];
4646      }
4647    }
4648  }
4649
4650  delete next_weight;
4651  delete next_weight2;
4652  idDelete(&G_test);
4653  idDelete(&G_test1);
4654  if(found_random_weight == TRUE)
4655  {
4656    idDelete(&G_test2);
4657  }
4658  if(test_w_in_ConeCC(G, result) == 1 && MivSame(curr_weight,result)==0)
4659  {
4660    delete curr_weight;
4661    delete next_weight1;
4662    return result;
4663  }
4664  else
4665  {
4666    delete curr_weight;
4667    delete result;
4668    return next_weight1;
4669  }
4670}
4671
4672
4673/***************************************************************************
4674 * The procedur REC_GB_Mwalk computes a GB for <G> w.r.t. the weight order *
4675 * otw, where G is a reduced GB w.r.t. the weight order cw.                *
4676 * The new procedure Mwalk calls REC_GB.                                   *
4677 ***************************************************************************/
4678static ideal REC_GB_Mwalk(ideal G, intvec* curr_weight, intvec* orig_target_weight,
4679                          int tp_deg, int npwinc)
4680{
4681  BOOLEAN nError = Overflow_Error;
4682  Overflow_Error = FALSE;
4683
4684  int i,  nV = currRing->N;
4685  int nwalk=0, endwalks=0, nnwinC=1, nlast = 0;
4686  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4687  ring newRing, oldRing, TargetRing;
4688  intvec* target_weight;
4689  intvec* ivNull = new intvec(nV);
4690#ifndef BUCHBERGER_ALG
4691  intvec* hilb_func;
4692  // to avoid (1,0,...,0) as the target vector
4693  intvec* last_omega = new intvec(nV);
4694  for(i=nV-1; i>0; i--)
4695  {
4696    (*last_omega)[i] = 1;
4697  }
4698  (*last_omega)[0] = 10000;
4699#endif
4700  BOOLEAN isGB = FALSE;
4701
4702  ring EXXRing = currRing;
4703
4704  // compute a pertubed weight vector of the target weight vector
4705  if(tp_deg > 1 && tp_deg <= nV)
4706  {
4707    ideal H0 = idHeadCC(G);
4708    if (rParameter(currRing) != NULL)
4709    {
4710      DefRingPar(orig_target_weight);
4711    }
4712    else
4713    {
4714      rChangeCurrRing(VMrDefault(orig_target_weight));
4715    }
4716    TargetRing = currRing;
4717    ssG = idrMoveR(G,EXXRing,currRing);
4718
4719    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4720    ideal H1 = idHeadCC(ssG);
4721    id_Delete(&H0,EXXRing);
4722
4723    if(test_G_GB_walk(H0_tmp,H1)==1)
4724    {
4725      //Print("\n//REC_GB_Mwalk: input in %d-th recursive is a GB!\n",tp_deg);
4726      idDelete(&H0_tmp);
4727      idDelete(&H1);
4728      G = ssG;
4729      ssG = NULL;
4730      newRing = currRing;
4731      delete ivNull;
4732      if(npwinc == 0)
4733      {
4734        isGB = TRUE;
4735        goto KSTD_Finish;
4736      }
4737      else
4738      {
4739        goto LastGB_Finish;
4740      }
4741    }
4742    idDelete(&H0_tmp);
4743    idDelete(&H1);
4744
4745    target_weight  = MPertVectors(ssG, MivMatrixOrder(orig_target_weight), tp_deg);
4746
4747    rChangeCurrRing(EXXRing);
4748    G = idrMoveR(ssG, TargetRing,currRing);
4749  }
4750
4751  while(1)
4752  {
4753    nwalk ++;
4754    nstep++;
4755    if(nwalk == 1)
4756    {
4757      goto NEXT_STEP;
4758    }
4759    //Print("\n//REC_GB_Mwalk: Entering the %d-th step in the %d-th recursive:\n",nwalk,tp_deg);
4760    to = clock();
4761    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4762    Gomega = MwalkInitialForm(G, curr_weight);
4763    xtif = xtif + clock()-to;
4764
4765#ifndef  BUCHBERGER_ALG
4766    if(isNolVector(curr_weight) == 0)
4767    {
4768      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4769    }
4770    else
4771    {
4772      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4773    }
4774#endif
4775
4776    oldRing = currRing;
4777
4778    // define a new ring with ordering "(a(curr_weight),lp)
4779    if (rParameter(currRing) != NULL)
4780    {
4781      DefRingPar(curr_weight);
4782    }
4783    else
4784    {
4785      rChangeCurrRing(VMrDefault(curr_weight));
4786    }
4787    newRing = currRing;
4788    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4789
4790    to = clock();
4791    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4792#ifdef  BUCHBERGER_ALG
4793    M = MstdhomCC(Gomega1);
4794#else
4795    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4796    delete hilb_func;
4797#endif
4798    xtstd = xtstd + clock() - to;
4799
4800    // change the ring to oldRing
4801    rChangeCurrRing(oldRing);
4802
4803    M1 =  idrMoveR(M, newRing,currRing);
4804    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4805
4806    to = clock();
4807    F = MLifttwoIdeal(Gomega2, M1, G);
4808    xtlift = xtlift + clock() -to;
4809
4810    idDelete(&M1);
4811    idDelete(&Gomega2);
4812    idDelete(&G);
4813
4814
4815    // change the ring to newRing
4816    rChangeCurrRing(newRing);
4817    F1 = idrMoveR(F, oldRing,currRing);
4818
4819    to = clock();
4820    // reduce the Groebner basis <G> w.r.t. new ring
4821    G = kInterRedCC(F1, NULL);
4822    xtred = xtred + clock() -to;
4823
4824    idDelete(&F1);
4825
4826    if(endwalks == 1)
4827    {
4828      break;
4829    }
4830  NEXT_STEP:
4831    to = clock();
4832    // compute a next weight vector
4833    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4834
4835
4836    xtnw = xtnw + clock() - to;
4837
4838#ifdef PRINT_VECTORS
4839    MivString(curr_weight, target_weight, next_weight);
4840#endif
4841
4842    if(Overflow_Error == TRUE)
4843    {
4844      //PrintS("\n//REC_GB_Mwalk: The computed vector does NOT stay in the correct cone!!\n");
4845      nnwinC = 0;
4846      if(tp_deg == nV)
4847      {
4848        nlast = 1;
4849      }
4850      delete next_weight;
4851      break;
4852    }
4853    if(MivComp(next_weight, ivNull) == 1)
4854    {
4855      newRing = currRing;
4856      delete next_weight;
4857      break;
4858    }
4859
4860    if(MivComp(next_weight, target_weight) == 1)
4861    {
4862      if(tp_deg == nV)
4863      {
4864        endwalks = 1;
4865      }
4866      else
4867      {
4868        G = REC_GB_Mwalk(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4869        newRing = currRing;
4870        delete next_weight;
4871        break;
4872      }
4873    }
4874
4875    for(i=nV-1; i>=0; i--)
4876    {
4877      (*curr_weight)[i] = (*next_weight)[i];
4878    }
4879    delete next_weight;
4880  }
4881
4882  delete ivNull;
4883
4884  if(tp_deg != nV)
4885  {
4886    newRing = currRing;
4887
4888    if (rParameter(currRing) != NULL)
4889    {
4890      DefRingPar(orig_target_weight);
4891    }
4892    else
4893    {
4894      rChangeCurrRing(VMrDefault(orig_target_weight));
4895    }
4896    F1 = idrMoveR(G, newRing,currRing);
4897
4898    if(nnwinC == 0)
4899    {
4900      F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4901    }
4902    else
4903    {
4904      if(test_w_in_ConeCC(F1, target_weight) != 1)
4905      {
4906        F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight,tp_deg+1,nnwinC);
4907      }
4908    }
4909    delete target_weight;
4910
4911    TargetRing = currRing;
4912    rChangeCurrRing(EXXRing);
4913    result = idrMoveR(F1, TargetRing,currRing);
4914  }
4915  else
4916  {
4917    if(nlast == 1)
4918    {
4919      if (rParameter(currRing) != NULL)
4920      {
4921        DefRingPar(orig_target_weight);
4922      }
4923      else
4924      {
4925        rChangeCurrRing(VMrDefault(orig_target_weight));
4926      }
4927    KSTD_Finish:
4928      if(isGB == FALSE)
4929      {
4930        F1 = idrMoveR(G, newRing,currRing);
4931      }
4932      else
4933      {
4934        F1 = G;
4935      }
4936      to=clock();
4937      // apply Buchberger alg to compute a red. GB of F1
4938      G = MstdCC(F1);
4939      xtextra=clock()-to;
4940      idDelete(&F1);
4941      newRing = currRing;
4942    }
4943
4944  LastGB_Finish:
4945    rChangeCurrRing(EXXRing);
4946    result = idrMoveR(G, newRing,currRing);
4947  }
4948
4949  if(Overflow_Error == FALSE)
4950    {
4951    Overflow_Error = nError;
4952    }
4953#ifndef BUCHBERGER_ALG
4954  delete last_omega;
4955#endif
4956  return(result);
4957}
4958
4959
4960// THE NEW GROEBNER WALK ALGORITHM
4961// Groebnerwalk with a recursive "second" alternative GW, called REC_GB_Mwalk that only computes the last reduced GB
4962ideal MwalkAlt(ideal Go, intvec* curr_weight, intvec* target_weight)
4963{
4964  Set_Error(FALSE);
4965  Overflow_Error = FALSE;
4966  //Print("// pSetm_Error = (%d)", ErrorCheck());
4967
4968  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
4969  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
4970  tinput = clock();
4971  clock_t tim;
4972  nstep=0;
4973  int i;
4974  int nV = currRing->N;
4975  int nwalk=0;
4976  int endwalks=0;
4977
4978  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
4979
4980  ring newRing, oldRing;
4981  intvec* ivNull = new intvec(nV);
4982  intvec* exivlp = Mivlp(nV);
4983#ifndef BUCHBERGER_ALG
4984  intvec* hilb_func;
4985#endif
4986  intvec* tmp_weight = new intvec(nV);
4987  for(i=nV-1; i>=0; i--)
4988    (*tmp_weight)[i] = (*curr_weight)[i];
4989
4990   // to avoid (1,0,...,0) as the target vector
4991  intvec* last_omega = new intvec(nV);
4992  for(i=nV-1; i>0; i--)
4993    (*last_omega)[i] = 1;
4994  (*last_omega)[0] = 10000;
4995
4996  ring XXRing = currRing;
4997
4998  to = clock();
4999  // the monomial ordering of this current ring would be "dp"
5000  G = MstdCC(Go);
5001  tostd = clock()-to;
5002
5003  if(currRing->order[0] == ringorder_a)
5004    goto NEXT_VECTOR;
5005
5006  while(1)
5007  {
5008    nwalk ++;
5009    nstep ++;
5010    to = clock();
5011    // compute an initial form ideal of <G> w.r.t. "curr_vector"
5012    Gomega = MwalkInitialForm(G, curr_weight);
5013    tif = tif + clock()-to;
5014    oldRing = currRing;
5015
5016    if(endwalks == 1)
5017    {
5018      /* compute a reduced Groebner basis of Gomega w.r.t. >>_cw by
5019         the recursive changed perturbation walk alg. */
5020      tim = clock();
5021#ifdef CHECK_IDEAL_MWALK
5022        Print("\n// **** Groebnerwalk took %d steps and ", nwalk);
5023        PrintS("\n// **** call the rec. Pert. Walk to compute a red GB of:");
5024        idString(Gomega, "Gomega");
5025#endif
5026
5027      if(MivSame(exivlp, target_weight)==1)
5028        M = REC_GB_Mwalk(idCopy(Gomega), tmp_weight, curr_weight, 2,1);
5029      else
5030        goto NORMAL_GW;
5031#ifdef TIME_TEST
5032        Print("\n//  time for the last std(Gw)  = %.2f sec",
5033        ((double) (clock()-tim)/1000000));
5034#endif
5035/*
5036#ifdef CHECK_IDEAL_MWALK
5037      idElements(Gomega, "G_omega");
5038      headidString(Gomega, "Gw");
5039      idElements(M, "M");
5040      //headidString(M, "M");
5041#endif
5042*/
5043      to = clock();
5044      F = MLifttwoIdeal(Gomega, M, G);
5045      xtlift = xtlift + clock() - to;
5046
5047      idDelete(&Gomega);
5048      idDelete(&M);
5049      idDelete(&G);
5050
5051      oldRing = currRing;
5052
5053      // create a new ring newRing
5054       if (rParameter(currRing) != NULL)
5055       {
5056         DefRingPar(curr_weight);
5057       }
5058       else
5059       {
5060         rChangeCurrRing(VMrDefault(curr_weight));
5061       }
5062      newRing = currRing;
5063      F1 = idrMoveR(F, oldRing,currRing);
5064    }
5065    else
5066    {
5067    NORMAL_GW:
5068#ifndef  BUCHBERGER_ALG
5069      if(isNolVector(curr_weight) == 0)
5070      {
5071        hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5072      }
5073      else
5074      {
5075        hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5076      }
5077#endif // BUCHBERGER_ALG
5078
5079      // define a new ring that its ordering is "(a(curr_weight),lp)
5080      if (rParameter(currRing) != NULL)
5081      {
5082        DefRingPar(curr_weight);
5083      }
5084      else
5085      {
5086        rChangeCurrRing(VMrDefault(curr_weight));
5087      }
5088      newRing = currRing;
5089      Gomega1 = idrMoveR(Gomega, oldRing,currRing);
5090
5091      to = clock();
5092      // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5093#ifdef  BUCHBERGER_ALG
5094      M = MstdhomCC(Gomega1);
5095#else
5096      M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5097      delete hilb_func;
5098#endif
5099      tstd = tstd + clock() - to;
5100
5101      // change the ring to oldRing
5102      rChangeCurrRing(oldRing);
5103      M1 =  idrMoveR(M, newRing,currRing);
5104      Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
5105
5106      to = clock();
5107      // compute a representation of the generators of submod (M) with respect
5108      // to those of mod (Gomega).
5109      // Gomega is a reduced Groebner basis w.r.t. the current ring.
5110      F = MLifttwoIdeal(Gomega2, M1, G);
5111      tlift = tlift + clock() - to;
5112
5113      idDelete(&M1);
5114      idDelete(&Gomega2);
5115      idDelete(&G);
5116
5117      // change the ring to newRing
5118      rChangeCurrRing(newRing);
5119      F1 = idrMoveR(F, oldRing,currRing);
5120    }
5121
5122    to = clock();
5123    // reduce the Groebner basis <G> w.r.t. new ring
5124    G = kInterRedCC(F1, NULL);
5125    if(endwalks != 1)
5126    {
5127      tred = tred + clock() - to;
5128    }
5129    else
5130    {
5131      xtred = xtred + clock() - to;
5132    }
5133    idDelete(&F1);
5134    if(endwalks == 1)
5135    {
5136      break;
5137    }
5138  NEXT_VECTOR:
5139    to = clock();
5140    // compute a next weight vector
5141    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
5142    tnw = tnw + clock() - to;
5143#ifdef PRINT_VECTORS
5144    MivString(curr_weight, target_weight, next_weight);
5145#endif
5146
5147    //if(test_w_in_ConeCC(G, next_weight) != 1)
5148    if(Overflow_Error == TRUE)
5149    {
5150      newRing = currRing;
5151      PrintS("\n// ** The computed vector does NOT stay in Cone!!\n");
5152
5153      if (rParameter(currRing) != NULL)
5154      {
5155        DefRingPar(target_weight);
5156      }
5157      else
5158      {
5159        rChangeCurrRing(VMrDefault(target_weight));
5160      }
5161      F1 = idrMoveR(G, newRing,currRing);
5162      G = MstdCC(F1);
5163      idDelete(&F1);
5164
5165      newRing = currRing;
5166      break;
5167    }
5168
5169    if(MivComp(next_weight, ivNull) == 1)
5170    {
5171      newRing = currRing;
5172      delete next_weight;
5173      break;
5174    }
5175    if(MivComp(next_weight, target_weight) == 1)
5176    {
5177      endwalks = 1;
5178    }
5179    for(i=nV-1; i>=0; i--)
5180    {
5181      (*tmp_weight)[i] = (*curr_weight)[i];
5182      (*curr_weight)[i] = (*next_weight)[i];
5183    }
5184    delete next_weight;
5185  }
5186  rChangeCurrRing(XXRing);
5187  G = idrMoveR(G, newRing,currRing);
5188
5189  delete tmp_weight;
5190  delete ivNull;
5191  delete exivlp;
5192
5193#ifdef TIME_TEST
5194  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5195
5196  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5197  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5198#endif
5199  return(G);
5200}
5201
5202/*******************************
5203 * THE GROEBNER WALK ALGORITHM *
5204 *******************************/
5205ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M,
5206            ring baseRing, int reduction, int printout)
5207{
5208  // save current options
5209  BITSET save1 = si_opt_1;
5210  if(reduction == 0)
5211  {
5212    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5213    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5214  }
5215  Set_Error(FALSE);
5216  Overflow_Error = FALSE;
5217  //BOOLEAN endwalks = FALSE;
5218#ifdef TIME_TEST
5219  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5220  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5221  tinput = clock();
5222  clock_t tim;
5223#endif
5224  nstep=0;
5225  int i,nwalk;
5226  int nV = baseRing->N;
5227
5228  ideal Gomega, M, F, FF, Gomega1, Gomega2, M1;
5229  ring newRing;
5230  ring XXRing = baseRing;
5231  ring targetRing;
5232  intvec* ivNull = new intvec(nV);
5233  intvec* curr_weight = new intvec(nV);
5234  intvec* target_weight = new intvec(nV);
5235  intvec* exivlp = Mivlp(nV);
5236/*
5237  intvec* tmp_weight = new intvec(nV);
5238  for(i=0; i<nV; i++)
5239  {
5240    (*tmp_weight)[i] = (*orig_M)[i];
5241  }
5242*/
5243  for(i=0; i<nV; i++)
5244  {
5245    (*curr_weight)[i] = (*orig_M)[i];
5246    (*target_weight)[i] = (*target_M)[i];
5247  }
5248#ifndef BUCHBERGER_ALG
5249  intvec* hilb_func;
5250   // to avoid (1,0,...,0) as the target vector
5251  intvec* last_omega = new intvec(nV);
5252  for(i=nV-1; i>0; i--)
5253  {
5254    (*last_omega)[i] = 1;
5255  }
5256  (*last_omega)[0] = 10000;
5257#endif
5258  rComplete(currRing);
5259#ifdef CHECK_IDEAL_MWALK
5260  if(printout > 2)
5261  {
5262    idString(Go,"//** Mwalk: Go");
5263  }
5264#endif
5265
5266  if(target_M->length() == nV)
5267  {
5268   // define the target ring
5269    targetRing = VMrDefault(target_weight);
5270  }
5271  else
5272  {
5273    targetRing = VMatrDefault(target_M);
5274  }
5275  if(orig_M->length() == nV)
5276  {
5277    // define a new ring with ordering "(a(curr_weight),lp)
5278    //newRing = VMrDefault(curr_weight);
5279    newRing=VMrRefine(target_weight, curr_weight);
5280  }
5281  else
5282  {
5283    newRing = VMatrRefine(target_M,curr_weight); //newRing = VMatrDefault(orig_M);
5284  }
5285  rChangeCurrRing(newRing);
5286  if(printout > 2)
5287  {
5288    Print("\n//** Mrwalk: Current ring r = %s;\n", rString(currRing));
5289  }
5290#ifdef TIME_TEST
5291  to = clock();
5292#endif
5293  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5294#ifdef TIME_TEST
5295  tostd = clock()-to;
5296#endif
5297
5298  baseRing = currRing;
5299  nwalk = 0;
5300
5301  while(1)
5302  {
5303    nwalk ++;
5304    nstep ++;
5305    //compute an initial form ideal of <G> w.r.t. "curr_vector"
5306#ifdef TIME_TEST
5307    to = clock();
5308#endif
5309    Gomega = MwalkInitialForm(G, curr_weight);
5310#ifdef TIME_TEST
5311    tif = tif + clock()-to;
5312#endif
5313
5314#ifdef CHECK_IDEAL_MWALK
5315    if(printout > 1)
5316    {
5317      idString(Gomega,"//** Mwalk: Gomega");
5318    }
5319#endif
5320
5321    if(reduction == 0)
5322    {
5323      FF = middleOfCone(G,Gomega);
5324      if(FF != NULL)
5325      {
5326      PrintS("middle of Cone");
5327        idDelete(&G);
5328        G = idCopy(FF);
5329        idDelete(&FF);
5330        goto NEXT_VECTOR;
5331      }
5332    }
5333
5334#ifndef  BUCHBERGER_ALG
5335    if(isNolVector(curr_weight) == 0)
5336    {
5337      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5338    }
5339    else
5340    {
5341      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5342    }
5343#endif
5344
5345    if(nwalk == 1)
5346    {
5347      if(orig_M->length() == nV)
5348      {
5349        // define a new ring with ordering "(a(curr_weight),lp)
5350        //newRing = VMrDefault(curr_weight);
5351        newRing=VMrRefine(target_weight, curr_weight);
5352      }
5353      else
5354      {
5355        newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5356      }
5357    }
5358    else
5359    {
5360     if(target_M->length() == nV)
5361     {
5362       //define a new ring with ordering "(a(curr_weight),lp)"
5363       //newRing = VMrDefault(curr_weight);
5364       newRing=VMrRefine(target_weight, curr_weight);
5365     }
5366     else
5367     {
5368       //define a new ring with matrix ordering
5369       newRing = VMatrRefine(target_M,curr_weight);
5370     }
5371    }
5372    rChangeCurrRing(newRing);
5373    if(printout > 2)
5374    {
5375      Print("\n// Current ring r = %s;\n", rString(currRing));
5376    }
5377    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5378    idDelete(&Gomega);
5379    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5380#ifdef TIME_TEST
5381    to = clock();
5382#endif
5383#ifndef  BUCHBERGER_ALG
5384    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5385    delete hilb_func;
5386#else
5387    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5388#endif
5389#ifdef TIME_TEST
5390    tstd = tstd + clock() - to;
5391#endif
5392    idSkipZeroes(M);
5393#ifdef CHECK_IDEAL_MWALK
5394    if(printout > 2)
5395    {
5396      idString(M, "//** Mwalk: M");
5397    }
5398#endif
5399    //change the ring to baseRing
5400    rChangeCurrRing(baseRing);
5401    M1 =  idrMoveR(M, newRing,currRing);
5402    idDelete(&M);
5403    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5404    idDelete(&Gomega1);
5405#ifdef TIME_TEST
5406    to = clock();
5407#endif
5408    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5409    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5410    F = MLifttwoIdeal(Gomega2, M1, G);
5411#ifdef TIME_TEST
5412    tlift = tlift + clock() - to;
5413#endif
5414#ifdef CHECK_IDEAL_MWALK
5415    if(printout > 2)
5416    {
5417      idString(F, "//** Mwalk: F");
5418    }
5419#endif
5420    idDelete(&Gomega2);
5421    idDelete(&M1);
5422
5423    rChangeCurrRing(newRing); // change the ring to newRing
5424    G = idrMoveR(F,baseRing,currRing);
5425    idDelete(&F);
5426    idSkipZeroes(G);
5427
5428#ifdef CHECK_IDEAL_MWALK
5429    if(printout > 2)
5430    {
5431      idString(G, "//** Mwalk: G");
5432    }
5433#endif
5434
5435    rChangeCurrRing(targetRing);
5436    G = idrMoveR(G,newRing,currRing);
5437    // test whether target cone is reached
5438    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5439    {
5440      baseRing = currRing;
5441      break;
5442      //endwalks = TRUE;
5443    }
5444
5445    rChangeCurrRing(newRing);
5446    G = idrMoveR(G,targetRing,currRing);
5447    baseRing = currRing;
5448
5449    NEXT_VECTOR:
5450#ifdef TIME_TEST
5451    to = clock();
5452#endif
5453    intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5454#ifdef TIME_TEST
5455    tnw = tnw + clock() - to;
5456#endif
5457#ifdef PRINT_VECTORS
5458    if(printout > 0)
5459    {
5460      MivString(curr_weight, target_weight, next_weight);
5461    }
5462#endif
5463    if(reduction ==0)
5464    {
5465      if(MivComp(curr_weight,next_weight)==1)
5466      {
5467        break;
5468      }
5469    }
5470    if(MivComp(target_weight,curr_weight) == 1)
5471    {
5472      break;
5473    }
5474
5475    for(i=nV-1; i>=0; i--)
5476    {
5477      //(*tmp_weight)[i] = (*curr_weight)[i];
5478      (*curr_weight)[i] = (*next_weight)[i];
5479    }
5480    delete next_weight;
5481  }
5482  rChangeCurrRing(XXRing);
5483  ideal result = idrMoveR(G,baseRing,currRing);
5484  idDelete(&Go);
5485  idDelete(&G);
5486  //delete tmp_weight;
5487  delete ivNull;
5488  delete exivlp;
5489#ifndef BUCHBERGER_ALG
5490  delete last_omega;
5491#endif
5492#ifdef TIME_TEST
5493  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5494  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5495  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5496#endif
5497  if(printout > 0)
5498  {
5499    Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
5500  }
5501  si_opt_1 = save1; //set original options
5502  return(result);
5503}
5504
5505// THE RANDOM WALK ALGORITHM
5506ideal Mrwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad, int pert_deg,
5507             int reduction, int printout)
5508{
5509  BITSET save1 = si_opt_1; // save current options
5510  if(reduction == 0)
5511  {
5512    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5513    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5514  }
5515
5516  Set_Error(FALSE);
5517  Overflow_Error = FALSE;
5518  BOOLEAN endwalks = FALSE;
5519#ifdef TIME_TEST
5520  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5521  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5522  tinput = clock();
5523  clock_t tim;
5524#endif
5525  nstep=0;
5526  int i,nwalk;//polylength;
5527  int nV = currRing->N;
5528
5529  //check that weight radius is valid
5530  if(weight_rad < 0)
5531  {
5532    WerrorS("Invalid radius.\n");
5533    return NULL;
5534  }
5535
5536  //check that perturbation degree is valid
5537  if(pert_deg > nV || pert_deg < 1)
5538  {
5539    WerrorS("Invalid perturbation degree.\n");
5540    return NULL;
5541  }
5542
5543  ideal Gomega, M, F,FF, Gomega1, Gomega2, M1;
5544  ring newRing;
5545  ring targetRing;
5546  ring baseRing = currRing;
5547  ring XXRing = currRing;
5548  intvec* iv_M;
5549  intvec* ivNull = new intvec(nV);
5550  intvec* curr_weight = new intvec(nV);
5551  intvec* target_weight = new intvec(nV);
5552  intvec* next_weight= new intvec(nV);
5553
5554  for(i=0; i<nV; i++)
5555  {
5556    (*curr_weight)[i] = (*orig_M)[i];
5557    (*target_weight)[i] = (*target_M)[i];
5558  }
5559
5560#ifndef BUCHBERGER_ALG
5561  intvec* hilb_func;
5562   // to avoid (1,0,...,0) as the target vector
5563  intvec* last_omega = new intvec(nV);
5564  for(i=nV-1; i>0; i--)
5565  {
5566    (*last_omega)[i] = 1;
5567  }
5568  (*last_omega)[0] = 10000;
5569#endif
5570  rComplete(currRing);
5571
5572  if(target_M->length() == nV)
5573  {
5574    targetRing = VMrDefault(target_weight); // define the target ring
5575  }
5576  else
5577  {
5578    targetRing = VMatrDefault(target_M);
5579  }
5580  if(orig_M->length() == nV)
5581  {
5582    //newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5583    newRing=VMrRefine(target_weight, curr_weight);
5584  }
5585  else
5586  {
5587    newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5588  }
5589  rChangeCurrRing(newRing);
5590#ifdef TIME_TEST
5591  to = clock();
5592#endif
5593  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5594#ifdef TIME_TEST
5595  tostd = clock()-to;
5596#endif
5597  baseRing = currRing;
5598  nwalk = 0;
5599
5600#ifdef TIME_TEST
5601  to = clock();
5602#endif
5603  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5604#ifdef TIME_TEST
5605  tif = tif + clock()-to; //time for computing initial form ideal
5606#endif
5607
5608  while(1)
5609  {
5610    nwalk ++;
5611    nstep ++;
5612#ifdef CHECK_IDEAL_MWALK
5613    if(printout > 1)
5614    {
5615      idString(Gomega,"//** Mrwalk: Gomega");
5616    }
5617#endif
5618    if(reduction == 0)
5619    {
5620      FF = middleOfCone(G,Gomega);
5621      if(FF != NULL)
5622      {
5623        idDelete(&G);
5624        G = idCopy(FF);
5625        idDelete(&FF);
5626        goto NEXT_VECTOR;
5627      }
5628    }
5629#ifndef  BUCHBERGER_ALG
5630    if(isNolVector(curr_weight) == 0)
5631    {
5632      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5633    }
5634    else
5635    {
5636      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5637    }
5638#endif
5639    if(nwalk == 1)
5640    {
5641      if(orig_M->length() == nV)
5642      {
5643        /*newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)*/
5644        newRing=VMrRefine(target_weight, curr_weight);
5645      }
5646      else
5647      {
5648        newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5649      }
5650    }
5651    else
5652    {
5653     if(target_M->length() == nV)
5654     {
5655       /*newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)*/
5656       newRing=VMrRefine(target_weight, curr_weight);
5657     }
5658     else
5659     {
5660       newRing = VMatrRefine(target_M,curr_weight);
5661     }
5662    }
5663    rChangeCurrRing(newRing);
5664    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5665    idDelete(&Gomega);
5666    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5667#ifdef TIME_TEST
5668    to = clock();
5669#endif
5670#ifndef BUCHBERGER_ALG
5671    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5672    delete hilb_func;
5673#else
5674    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5675#endif
5676#ifdef TIME_TEST
5677    tstd = tstd + clock() - to;
5678#endif
5679    idSkipZeroes(M);
5680#ifdef CHECK_IDEAL_MWALK
5681    if(printout > 2)
5682    {
5683      idString(M, "//** Mrwalk: M");
5684    }
5685#endif
5686    //change the ring to baseRing
5687    rChangeCurrRing(baseRing);
5688    M1 =  idrMoveR(M, newRing,currRing);
5689    idDelete(&M);
5690    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5691    idDelete(&Gomega1);
5692#ifdef TIME_TEST
5693    to = clock();
5694#endif
5695    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5696    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5697    F = MLifttwoIdeal(Gomega2, M1, G);
5698#ifdef TIME_TEST
5699    tlift = tlift + clock() - to;
5700#endif
5701#ifdef CHECK_IDEAL_MWALK
5702    if(printout > 2)
5703    {
5704      idString(F,"//** Mrwalk: F");
5705    }
5706#endif
5707    idDelete(&Gomega2);
5708    idDelete(&M1);
5709    rChangeCurrRing(newRing); // change the ring to newRing
5710    G = idrMoveR(F,baseRing,currRing);
5711    idDelete(&F);
5712    baseRing = currRing;
5713#ifdef TIME_TEST
5714    to = clock();
5715    tstd = tstd + clock() - to;
5716#endif
5717    idSkipZeroes(G);
5718#ifdef CHECK_IDEAL_MWALK
5719    if(printout > 2)
5720    {
5721      idString(G,"//** Mrwalk: G");
5722    }
5723#endif
5724
5725    rChangeCurrRing(targetRing);
5726    G = idrMoveR(G,newRing,currRing);
5727
5728    // test whether target cone is reached
5729    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5730    {
5731      baseRing = currRing;
5732      break;
5733    }
5734
5735    rChangeCurrRing(newRing);
5736    G = idrMoveR(G,targetRing,currRing);
5737    baseRing = currRing;
5738
5739    NEXT_VECTOR:
5740#ifdef TIME_TEST
5741    to = clock();
5742#endif
5743    next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5744#ifdef TIME_TEST
5745    tnw = tnw + clock() - to;
5746#endif
5747
5748#ifdef TIME_TEST
5749    to = clock();
5750#endif
5751    Gomega = MwalkInitialForm(G, next_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5752#ifdef TIME_TEST
5753    tif = tif + clock()-to; //time for computing initial form ideal
5754#endif
5755
5756    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
5757    //polylength = lengthpoly(Gomega);
5758    if(lengthpoly(Gomega) > 0)
5759    {
5760      //there is a polynomial in Gomega with at least 3 monomials,
5761      //low-dimensional facet of the cone
5762      delete next_weight;
5763      if(target_M->length() == nV)
5764      {
5765        //iv_M = MivMatrixOrder(curr_weight);
5766        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
5767      }
5768      else
5769      {
5770        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
5771      }
5772#ifdef TIME_TEST
5773      to = clock();
5774#endif
5775      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, pert_deg);
5776#ifdef TIME_TEST
5777      tnw = tnw + clock() - to;
5778#endif
5779      idDelete(&Gomega);
5780#ifdef TIME_TEST
5781      to = clock();
5782#endif
5783      Gomega = MwalkInitialForm(G, next_weight);
5784#ifdef TIME_TEST
5785      tif = tif + clock()-to; //time for computing initial form ideal
5786#endif
5787      delete iv_M;
5788    }
5789
5790    // test whether target weight vector is reached
5791    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)
5792    {
5793      baseRing = currRing;
5794      delete next_weight;
5795      break;
5796    }
5797    if(reduction ==0)
5798    {
5799      if(MivComp(curr_weight,next_weight)==1)
5800      {
5801        break;
5802      }
5803    }
5804#ifdef PRINT_VECTORS
5805    if(printout > 0)
5806    {
5807      MivString(curr_weight, target_weight, next_weight);
5808    }
5809#endif
5810
5811    for(i=nV-1; i>=0; i--)
5812    {
5813      (*curr_weight)[i] = (*next_weight)[i];
5814    }
5815    delete next_weight;
5816  }
5817  baseRing = currRing;
5818  rChangeCurrRing(XXRing);
5819  ideal result = idrMoveR(G,baseRing,currRing);
5820  idDelete(&G);
5821  delete ivNull;
5822#ifndef BUCHBERGER_ALG
5823  delete last_omega;
5824#endif
5825  if(printout > 0)
5826  {
5827    Print("\n//** Mrwalk: Groebner Walk took %d steps.\n", nstep);
5828  }
5829#ifdef TIME_TEST
5830  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5831  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5832  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5833#endif
5834  si_opt_1 = save1; //set original options
5835  return(result);
5836}
5837
5838/**************************************************************/
5839/*     Implementation of the perturbation walk algorithm      */
5840/**************************************************************/
5841/* If the perturbed target weight vector or an intermediate weight vector
5842   doesn't stay in the correct Groebner cone, we have only
5843   a reduced Groebner basis for the given ideal with respect to
5844   a monomial order which differs to the given order.
5845   Then we have to compute the wanted  reduced Groebner basis for it.
5846   For this, we can use
5847   1) the improved Buchberger algorithm or
5848   2) the changed perturbation walk algorithm with a decreased degree.
5849*/
5850// if nP = 0 use kStd, else call LastGB
5851ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,
5852             intvec* target_weight, int nP, int reduction, int printout)
5853{
5854  BITSET save1 = si_opt_1; // save current options
5855  if(reduction == 0)
5856  {
5857    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5858    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5859  }
5860  Set_Error(FALSE  );
5861  Overflow_Error = FALSE;
5862  //Print("// pSetm_Error = (%d)", ErrorCheck());
5863#ifdef TIME_TEST
5864  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5865  xtextra=0;
5866  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5867  tinput = clock();
5868
5869  clock_t tim;
5870#endif
5871  nstep = 0;
5872  int i, ntwC=1, ntestw=1,  nV = currRing->N;
5873
5874  //check that perturbation degree is valid
5875  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
5876  {
5877    WerrorS("Invalid perturbation degree.\n");
5878    return NULL;
5879  }
5880
5881  BOOLEAN endwalks = FALSE;
5882  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
5883  ring newRing, oldRing, TargetRing;
5884  intvec* iv_M_dp;
5885  intvec* iv_M_lp;
5886  intvec* exivlp = Mivlp(nV);
5887  intvec* orig_target = target_weight;
5888  intvec* pert_target_vector = target_weight;
5889  intvec* ivNull = new intvec(nV);
5890  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
5891#ifndef BUCHBERGER_ALG
5892  intvec* hilb_func;
5893#endif
5894  intvec* next_weight;
5895
5896  // to avoid (1,0,...,0) as the target vector
5897  intvec* last_omega = new intvec(nV);
5898  for(i=nV-1; i>0; i--)
5899    (*last_omega)[i] = 1;
5900  (*last_omega)[0] = 10000;
5901
5902  ring XXRing = currRing;
5903#ifdef TIME_TEST
5904  to = clock();
5905#endif
5906  // perturbs the original vector
5907  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
5908  {
5909    G = MstdCC(Go);
5910#ifdef TIME_TEST
5911    tostd = clock()-to;
5912#endif
5913    if(op_deg != 1){
5914      iv_M_dp = MivMatrixOrderdp(nV);
5915      //ivString(iv_M_dp, "iv_M_dp");
5916      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
5917    }
5918  }
5919  else
5920  {
5921    //define ring order := (a(curr_weight),lp);
5922/*
5923    if (rParameter(currRing) != NULL)
5924      DefRingPar(curr_weight);
5925    else
5926      rChangeCurrRing(VMrDefault(curr_weight));
5927*/
5928    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
5929
5930    G = idrMoveR(Go, XXRing,currRing);
5931    G = MstdCC(G);
5932#ifdef TIME_TEST
5933    tostd = clock()-to;
5934#endif
5935    if(op_deg != 1){
5936      iv_M_dp = MivMatrixOrder(curr_weight);
5937      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
5938    }
5939  }
5940  delete iv_dp;
5941  if(op_deg != 1) delete iv_M_dp;
5942
5943  ring HelpRing = currRing;
5944
5945  // perturbs the target weight vector
5946  if(tp_deg > 1 && tp_deg <= nV)
5947  {
5948/*
5949    if (rParameter(currRing) != NULL)
5950      DefRingPar(target_weight);
5951    else
5952      rChangeCurrRing(VMrDefault(target_weight));
5953*/
5954    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
5955
5956    TargetRing = currRing;
5957    ssG = idrMoveR(G,HelpRing,currRing);
5958    if(MivSame(target_weight, exivlp) == 1)
5959    {
5960      iv_M_lp = MivMatrixOrderlp(nV);
5961      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
5962    }
5963    else
5964    {
5965      iv_M_lp = MivMatrixOrder(target_weight);
5966      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
5967    }
5968    delete iv_M_lp;
5969    pert_target_vector = target_weight;
5970    rChangeCurrRing(HelpRing);
5971    G = idrMoveR(ssG, TargetRing,currRing);
5972  }
5973  if(printout > 0)
5974  {
5975    Print("\n//** Mpwalk: Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
5976#ifdef PRINT_VECTORS
5977    ivString(curr_weight, "//** Mpwalk: new current weight");
5978    ivString(target_weight, "//** Mpwalk: new target weight");
5979#endif
5980  }
5981  while(1)
5982  {
5983    nstep ++;
5984#ifdef TIME_TEST
5985    to = clock();
5986#endif
5987    // compute an initial form ideal of <G> w.r.t. the weight vector
5988    // "curr_weight"
5989    Gomega = MwalkInitialForm(G, curr_weight);
5990#ifdef TIME_TEST
5991    tif = tif + clock()-to;
5992#endif
5993#ifdef CHECK_IDEAL_MWALK
5994    if(printout > 1)
5995    {
5996      idString(Gomega,"//** Mpwalk: Gomega");
5997    }
5998#endif
5999    if(reduction == 0 && nstep > 1)
6000    {
6001      FF = middleOfCone(G,Gomega);
6002      if(FF != NULL)
6003      {
6004        idDelete(&G);
6005        G = idCopy(FF);
6006        idDelete(&FF);
6007        goto NEXT_VECTOR;
6008      }
6009    }
6010
6011#ifdef ENDWALKS
6012    if(endwalks == TRUE)
6013    {
6014      if(printout > 0)
6015      {
6016        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6017      }
6018      //idElements(G, "G");
6019      //headidString(G, "G");
6020    }
6021#endif
6022
6023#ifndef  BUCHBERGER_ALG
6024    if(isNolVector(curr_weight) == 0)
6025      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6026    else
6027      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6028#endif // BUCHBERGER_ALG
6029
6030    oldRing = currRing;
6031
6032    // define a new ring with ordering "(a(curr_weight),lp)
6033/*
6034    if (rParameter(currRing) != NULL)
6035      DefRingPar(curr_weight);
6036    else
6037      rChangeCurrRing(VMrDefault(curr_weight));
6038*/
6039    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
6040
6041    newRing = currRing;
6042    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6043
6044#ifdef ENDWALKS
6045    if(endwalks==TRUE)
6046    {
6047      if(printout > 0)
6048      {
6049        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6050        //idElements(Gomega1, "Gw");
6051        //headidString(Gomega1, "headGw");
6052        PrintS("\n// compute a rGB of Gw:\n");
6053      }
6054#ifndef  BUCHBERGER_ALG
6055      ivString(hilb_func, "w");
6056#endif
6057    }
6058#endif
6059#ifdef TIME_TEST
6060    tim = clock();
6061    to = clock();
6062#endif
6063    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6064#ifdef  BUCHBERGER_ALG
6065    M = MstdhomCC(Gomega1);
6066#else
6067    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6068    delete hilb_func;
6069#endif
6070
6071    if(endwalks == TRUE)
6072    {
6073#ifdef TIME_TEST
6074      xtstd = xtstd+clock()-to;
6075#endif
6076#ifdef ENDWALKS
6077      if(printout > 1)
6078      {
6079        Print("\n// time for the last std(Gw)  = %.2f sec\n",
6080            ((double) clock())/1000000 -((double)tim) /1000000);
6081      }
6082#endif
6083    }
6084    else
6085    {
6086#ifdef TIME_TEST
6087      tstd=tstd+clock()-to;
6088#endif
6089    }
6090#ifdef CHECK_IDEAL_MWALK
6091    if(printout > 2)
6092    {
6093      idString(M,"//** Mpwalk: M");
6094    }
6095#endif
6096    // change the ring to oldRing
6097    rChangeCurrRing(oldRing);
6098    M1 =  idrMoveR(M, newRing,currRing);
6099    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6100#ifdef TIME_TEST
6101    to=clock();
6102#endif
6103    /* compute a representation of the generators of submod (M)
6104       with respect to those of mod (Gomega).
6105       Gomega is a reduced Groebner basis w.r.t. the current ring */
6106    F = MLifttwoIdeal(Gomega2, M1, G);
6107#ifdef TIME_TEST
6108    if(endwalks == FALSE)
6109      tlift = tlift+clock()-to;
6110    else
6111      xtlift=clock()-to;
6112#endif
6113#ifdef CHECK_IDEAL_MWALK
6114    if(printout > 2)
6115    {
6116      idString(F,"//** Mpwalk: F");
6117    }
6118#endif
6119
6120    idDelete(&M1);
6121    idDelete(&Gomega2);
6122    idDelete(&G);
6123
6124    // change the ring to newRing
6125    rChangeCurrRing(newRing);
6126    if(reduction == 0)
6127    {
6128      G = idrMoveR(F,oldRing,currRing);
6129    }
6130    else
6131    {
6132      F1 = idrMoveR(F, oldRing,currRing);
6133      if(printout > 2)
6134      {
6135        PrintS("\n //** Mpwalk: reduce the Groebner basis.\n");
6136      }
6137#ifdef TIME_TEST
6138      to=clock();
6139#endif
6140      G = kInterRedCC(F1, NULL);
6141#ifdef TIME_TEST
6142      if(endwalks == FALSE)
6143        tred = tred+clock()-to;
6144      else
6145        xtred=clock()-to;
6146#endif
6147      idDelete(&F1);
6148    }
6149    if(endwalks == TRUE)
6150      break;
6151
6152    NEXT_VECTOR:
6153#ifdef TIME_TEST
6154    to=clock();
6155#endif
6156    // compute a next weight vector
6157    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6158#ifdef TIME_TEST
6159    tnw=tnw+clock()-to;
6160#endif
6161#ifdef PRINT_VECTORS
6162    if(printout > 0)
6163    {
6164      MivString(curr_weight, target_weight, next_weight);
6165    }
6166#endif
6167
6168    if(Overflow_Error == TRUE)
6169    {
6170      ntwC = 0;
6171      //ntestomega = 1;
6172      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6173      //idElements(G, "G");
6174      delete next_weight;
6175      goto FINISH_160302;
6176    }
6177    if(MivComp(next_weight, ivNull) == 1){
6178      newRing = currRing;
6179      delete next_weight;
6180      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6181      break;
6182    }
6183    if(MivComp(next_weight, target_weight) == 1)
6184      endwalks = TRUE;
6185
6186    for(i=nV-1; i>=0; i--)
6187      (*curr_weight)[i] = (*next_weight)[i];
6188
6189    delete next_weight;
6190  }//end of while-loop
6191
6192  if(tp_deg != 1)
6193  {
6194  FINISH_160302:
6195    if(MivSame(orig_target, exivlp) == 1) {
6196    /*  if (rParameter(currRing) != NULL)
6197        DefRingParlp();
6198      else
6199        VMrDefaultlp();
6200    else
6201      if (rParameter(currRing) != NULL)
6202        DefRingPar(orig_target);
6203      else*/
6204        rChangeCurrRing(VMrDefault(orig_target));
6205    }
6206    TargetRing=currRing;
6207    F1 = idrMoveR(G, newRing,currRing);
6208/*
6209#ifdef CHECK_IDEAL_MWALK
6210      headidString(G, "G");
6211#endif
6212*/
6213
6214    // check whether the pertubed target vector stays in the correct cone
6215    if(ntwC != 0){
6216      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6217    }
6218
6219    if( ntestw != 1 || ntwC == 0)
6220    {
6221      if(ntestw != 1 && printout >2)
6222      {
6223        ivString(pert_target_vector, "tau");
6224        PrintS("\n// ** perturbed target vector doesn't stay in cone!!");
6225        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6226        //idElements(F1, "G");
6227      }
6228      // LastGB is "better" than the kStd subroutine
6229      to=clock();
6230      ideal eF1;
6231      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1){
6232        // PrintS("\n// ** calls \"std\" to compute a GB");
6233        eF1 = MstdCC(F1);
6234        idDelete(&F1);
6235      }
6236      else {
6237        // PrintS("\n// ** calls \"LastGB\" to compute a GB");
6238        rChangeCurrRing(newRing);
6239        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6240        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6241        F2=NULL;
6242      }
6243      xtextra=clock()-to;
6244      ring exTargetRing = currRing;
6245
6246      rChangeCurrRing(XXRing);
6247      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6248    }
6249    else{
6250      rChangeCurrRing(XXRing);
6251      Eresult = idrMoveR(F1, TargetRing,currRing);
6252    }
6253  }
6254  else {
6255    rChangeCurrRing(XXRing);
6256    Eresult = idrMoveR(G, newRing,currRing);
6257  }
6258  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6259  delete ivNull;
6260  if(tp_deg != 1)
6261    delete target_weight;
6262
6263  if(op_deg != 1 )
6264    delete curr_weight;
6265
6266  delete exivlp;
6267  delete last_omega;
6268
6269#ifdef TIME_TEST
6270  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6271             tnw+xtnw);
6272
6273  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6274  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6275#endif
6276  if(printout > 0)
6277  {
6278    Print("\n//** Mpwalk: Perturbation Walk took %d steps.\n", nstep);
6279  }
6280  return(Eresult);
6281}
6282
6283/*******************************************************
6284 * THE PERTURBATION WALK ALGORITHM WITH RANDOM ELEMENT *
6285 *******************************************************/
6286ideal Mprwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad,
6287              int op_deg, int tp_deg, int nP, int reduction, int printout)
6288{
6289  BITSET save1 = si_opt_1; // save current options
6290  if(reduction == 0)
6291  {
6292    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6293    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6294  }
6295  Set_Error(FALSE);
6296  Overflow_Error = FALSE;
6297  //Print("// pSetm_Error = (%d)", ErrorCheck());
6298#ifdef TIME_TEST
6299  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6300  xtextra=0;
6301  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6302  tinput = clock();
6303
6304  clock_t tim;
6305#endif
6306  nstep = 0;
6307  int i, ntwC=1, ntestw=1, nV = currRing->N; //polylength
6308
6309  //check that weight radius is valid
6310  if(weight_rad < 0)
6311  {
6312    WerrorS("Invalid radius.\n");
6313    return NULL;
6314  }
6315
6316  //check that perturbation degree is valid
6317  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6318  {
6319    WerrorS("Invalid perturbation degree.\n");
6320    return NULL;
6321  }
6322
6323  BOOLEAN endwalks = FALSE;
6324
6325  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6326  ring newRing, oldRing, TargetRing;
6327  intvec* iv_M;
6328  intvec* iv_M_dp;
6329  intvec* iv_M_lp;
6330  intvec* exivlp = Mivlp(nV);
6331  intvec* curr_weight = new intvec(nV);
6332  intvec* target_weight = new intvec(nV);
6333  for(i=0; i<nV; i++)
6334  {
6335    (*curr_weight)[i] = (*orig_M)[i];
6336    (*target_weight)[i] = (*target_M)[i];
6337  }
6338  intvec* orig_target = target_weight;
6339  intvec* pert_target_vector = target_weight;
6340  intvec* ivNull = new intvec(nV);
6341  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6342#ifndef BUCHBERGER_ALG
6343  intvec* hilb_func;
6344#endif
6345  intvec* next_weight;
6346
6347  // to avoid (1,0,...,0) as the target vector
6348  intvec* last_omega = new intvec(nV);
6349  for(i=nV-1; i>0; i--)
6350    (*last_omega)[i] = 1;
6351  (*last_omega)[0] = 10000;
6352
6353  ring XXRing = currRing;
6354
6355  // perturbs the original vector
6356  if(orig_M->length() == nV)
6357  {
6358    if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6359    {
6360#ifdef TIME_TEST
6361  to = clock();
6362#endif
6363      G = MstdCC(Go);
6364#ifdef TIME_TEST
6365      tostd = clock()-to;
6366#endif
6367      if(op_deg != 1)
6368      {
6369        iv_M_dp = MivMatrixOrderdp(nV);
6370        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6371      }
6372    }
6373    else
6374    {
6375      //define ring order := (a(curr_weight),lp);
6376      if (rParameter(currRing) != NULL)
6377        DefRingPar(curr_weight);
6378      else
6379        rChangeCurrRing(VMrDefault(curr_weight));
6380
6381      G = idrMoveR(Go, XXRing,currRing);
6382#ifdef TIME_TEST
6383  to = clock();
6384#endif
6385      G = MstdCC(G);
6386#ifdef TIME_TEST
6387      tostd = clock()-to;
6388#endif
6389      if(op_deg != 1)
6390      {
6391        iv_M_dp = MivMatrixOrder(curr_weight);
6392        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6393      }
6394    }
6395  }
6396  else
6397  {
6398    rChangeCurrRing(VMatrDefault(orig_M));
6399    G = idrMoveR(Go, XXRing,currRing);
6400#ifdef TIME_TEST
6401    to = clock();
6402#endif
6403    G = MstdCC(G);
6404#ifdef TIME_TEST
6405    tostd = clock()-to;
6406#endif
6407    if(op_deg != 1)
6408    {
6409      curr_weight = MPertVectors(G, orig_M, op_deg);
6410    }
6411  }
6412
6413  delete iv_dp;
6414  if(op_deg != 1) delete iv_M_dp;
6415
6416  ring HelpRing = currRing;
6417
6418  // perturbs the target weight vector
6419  if(target_M->length() == nV)
6420  {
6421    if(tp_deg > 1 && tp_deg <= nV)
6422    {
6423      if (rParameter(currRing) != NULL)
6424        DefRingPar(target_weight);
6425      else
6426        rChangeCurrRing(VMrDefault(target_weight));
6427
6428      TargetRing = currRing;
6429      ssG = idrMoveR(G,HelpRing,currRing);
6430      if(MivSame(target_weight, exivlp) == 1)
6431      {
6432        iv_M_lp = MivMatrixOrderlp(nV);
6433        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6434      }
6435      else
6436      {
6437        iv_M_lp = MivMatrixOrder(target_weight);
6438        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6439      }
6440      delete iv_M_lp;
6441      pert_target_vector = target_weight;
6442      rChangeCurrRing(HelpRing);
6443      G = idrMoveR(ssG, TargetRing,currRing);
6444    }
6445  }
6446  else
6447  {
6448    if(tp_deg > 1 && tp_deg <= nV)
6449    {
6450      rChangeCurrRing(VMatrDefault(target_M));
6451      TargetRing = currRing;
6452      ssG = idrMoveR(G,HelpRing,currRing);
6453      target_weight = MPertVectors(ssG, target_M, tp_deg);
6454    }
6455  }
6456  if(printout > 0)
6457  {
6458    Print("\n//** Mprwalk: Random Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6459    ivString(curr_weight, "//** Mprwalk: new current weight");
6460    ivString(target_weight, "//** Mprwalk: new target weight");
6461  }
6462
6463#ifdef TIME_TEST
6464  to = clock();
6465#endif
6466  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
6467#ifdef TIME_TEST
6468  tif = tif + clock()-to; //time for computing initial form ideal
6469#endif
6470
6471  while(1)
6472  {
6473    nstep ++;
6474#ifdef CHECK_IDEAL_MWALK
6475    if(printout > 1)
6476    {
6477      idString(Gomega,"//** Mprwalk: Gomega");
6478    }
6479#endif
6480
6481    if(reduction == 0 && nstep > 1)
6482    {
6483      FF = middleOfCone(G,Gomega);
6484      if(FF != NULL)
6485      {
6486        idDelete(&G);
6487        G = idCopy(FF);
6488        idDelete(&FF);
6489        goto NEXT_VECTOR;
6490      }
6491    }
6492
6493#ifdef ENDWALKS
6494    if(endwalks == TRUE)
6495    {
6496      if(printout > 0)
6497      {
6498        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6499        //idElements(G, "G");
6500        //headidString(G, "G");
6501      }
6502    }
6503#endif
6504
6505#ifndef  BUCHBERGER_ALG
6506    if(isNolVector(curr_weight) == 0)
6507      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6508    else
6509      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6510#endif // BUCHBERGER_ALG
6511
6512    oldRing = currRing;
6513
6514    if(target_M->length() == nV)
6515    {/*
6516      // define a new ring with ordering "(a(curr_weight),lp)
6517      if (rParameter(currRing) != NULL)
6518        DefRingPar(curr_weight);
6519      else
6520        rChangeCurrRing(VMrDefault(curr_weight));
6521*/
6522      rChangeCurrRing(VMrRefine(target_M,curr_weight));
6523    }
6524    else
6525    {
6526      rChangeCurrRing(VMatrRefine(target_M,curr_weight));
6527    }
6528    newRing = currRing;
6529    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6530#ifdef ENDWALKS
6531    if(endwalks == TRUE)
6532    {
6533      if(printout > 0)
6534      {
6535        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6536
6537        //idElements(Gomega1, "Gw");
6538        //headidString(Gomega1, "headGw");
6539
6540        PrintS("\n// compute a rGB of Gw:\n");
6541      }
6542#ifndef  BUCHBERGER_ALG
6543      ivString(hilb_func, "w");
6544#endif
6545    }
6546#endif
6547#ifdef TIME_TEST
6548    tim = clock();
6549    to = clock();
6550#endif
6551    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6552#ifdef  BUCHBERGER_ALG
6553    M = MstdhomCC(Gomega1);
6554#else
6555    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6556    delete hilb_func;
6557#endif
6558#ifdef CHECK_IDEAL_MWALK
6559    if(printout > 2)
6560    {
6561      idString(M,"//** Mprwalk: M");
6562    }
6563#endif
6564#ifdef TIME_TEST
6565    if(endwalks == TRUE)
6566    {
6567      xtstd = xtstd+clock()-to;
6568#ifdef ENDWALKS
6569      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6570            ((double) clock())/1000000 -((double)tim) /1000000);
6571#endif
6572    }
6573    else
6574      tstd=tstd+clock()-to;
6575#endif
6576    /* change the ring to oldRing */
6577    rChangeCurrRing(oldRing);
6578    M1 =  idrMoveR(M, newRing,currRing);
6579    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6580#ifdef TIME_TEST
6581    to=clock();
6582#endif
6583    /* compute a representation of the generators of submod (M)
6584       with respect to those of mod (Gomega).
6585       Gomega is a reduced Groebner basis w.r.t. the current ring */
6586    F = MLifttwoIdeal(Gomega2, M1, G);
6587#ifdef TIME_TEST
6588    if(endwalks == FALSE)
6589      tlift = tlift+clock()-to;
6590    else
6591      xtlift=clock()-to;
6592#endif
6593#ifdef CHECK_IDEAL_MWALK
6594    if(printout > 2)
6595    {
6596      idString(F,"//** Mprwalk: F");
6597    }
6598#endif
6599
6600    idDelete(&M1);
6601    idDelete(&Gomega2);
6602    idDelete(&G);
6603
6604    // change the ring to newRing
6605    rChangeCurrRing(newRing);
6606    if(reduction == 0)
6607    {
6608      G = idrMoveR(F,oldRing,currRing);
6609    }
6610    else
6611    {
6612      F1 = idrMoveR(F, oldRing,currRing);
6613      if(printout > 2)
6614      {
6615        PrintS("\n //** Mprwalk: reduce the Groebner basis.\n");
6616      }
6617#ifdef TIME_TEST
6618      to=clock();
6619#endif
6620      G = kInterRedCC(F1, NULL);
6621#ifdef TIME_TEST
6622      if(endwalks == FALSE)
6623        tred = tred+clock()-to;
6624      else
6625        xtred=clock()-to;
6626#endif
6627      idDelete(&F1);
6628    }
6629
6630    if(endwalks == TRUE)
6631      break;
6632
6633    NEXT_VECTOR:
6634#ifdef TIME_TEST
6635    to = clock();
6636#endif
6637    next_weight = next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6638#ifdef TIME_TEST
6639    tnw = tnw + clock() - to;
6640#endif
6641
6642#ifdef TIME_TEST
6643    to = clock();
6644#endif
6645    // compute an initial form ideal of <G> w.r.t. "next_vector"
6646    Gomega = MwalkInitialForm(G, next_weight);
6647#ifdef TIME_TEST
6648    tif = tif + clock()-to; //time for computing initial form ideal
6649#endif
6650
6651    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
6652    if(lengthpoly(Gomega) > 0)
6653    {
6654      if(printout > 1)
6655      {
6656        PrintS("\n Mpwalk: there is a polynomial in Gomega with at least 3 monomials.\n");
6657      }
6658      // low-dimensional facet of the cone
6659      delete next_weight;
6660      if(target_M->length() == nV)
6661      {
6662        iv_M = MivMatrixOrder(curr_weight);
6663      }
6664      else
6665      {
6666        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
6667      }
6668#ifdef TIME_TEST
6669      to = clock();
6670#endif
6671      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, op_deg);
6672#ifdef TIME_TEST
6673      tnw = tnw + clock() - to;
6674#endif
6675      idDelete(&Gomega);
6676#ifdef TIME_TEST
6677      to = clock();
6678#endif
6679      Gomega = MwalkInitialForm(G, next_weight);
6680#ifdef TIME_TEST
6681      tif = tif + clock()-to; //time for computing initial form ideal
6682#endif
6683      delete iv_M;
6684    }
6685
6686#ifdef PRINT_VECTORS
6687    if(printout > 0)
6688    {
6689      MivString(curr_weight, target_weight, next_weight);
6690    }
6691#endif
6692
6693    if(Overflow_Error == TRUE)
6694    {
6695      ntwC = 0;
6696      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6697      //idElements(G, "G");
6698      delete next_weight;
6699      goto FINISH_160302;
6700    }
6701    if(MivComp(next_weight, ivNull) == 1){
6702      newRing = currRing;
6703      delete next_weight;
6704      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6705      break;
6706    }
6707    if(MivComp(next_weight, target_weight) == 1)
6708      endwalks = TRUE;
6709
6710    for(i=nV-1; i>=0; i--)
6711      (*curr_weight)[i] = (*next_weight)[i];
6712
6713    delete next_weight;
6714  }// end of while-loop
6715
6716  if(tp_deg != 1)
6717  {
6718    FINISH_160302:
6719    if(target_M->length() == nV)
6720    {
6721      if(MivSame(orig_target, exivlp) == 1)
6722        if (rParameter(currRing) != NULL)
6723          DefRingParlp();
6724        else
6725          VMrDefaultlp();
6726      else
6727        if (rParameter(currRing) != NULL)
6728          DefRingPar(orig_target);
6729        else
6730          rChangeCurrRing(VMrDefault(orig_target));
6731    }
6732    else
6733    {
6734      rChangeCurrRing(VMatrDefault(target_M));
6735    }
6736    TargetRing=currRing;
6737    F1 = idrMoveR(G, newRing,currRing);
6738
6739    // check whether the pertubed target vector stays in the correct cone
6740    if(ntwC != 0)
6741    {
6742      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6743    }
6744    if(ntestw != 1 || ntwC == 0)
6745    {
6746      if(ntestw != 1 && printout > 2)
6747      {
6748#ifdef PRINT_VECTORS
6749        ivString(pert_target_vector, "tau");
6750#endif
6751        PrintS("\n// **Mprwalk: perturbed target vector doesn't stay in cone.");
6752        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6753        //idElements(F1, "G");
6754      }
6755      // LastGB is "better" than the kStd subroutine
6756#ifdef TIME_TEST
6757      to=clock();
6758#endif
6759      ideal eF1;
6760      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1 || target_M->length() != nV)
6761      {
6762        if(printout > 2)
6763        {
6764          PrintS("\n// ** Mprwalk: Call \"std\" to compute a Groebner basis.\n");
6765        }
6766        eF1 = MstdCC(F1);
6767        idDelete(&F1);
6768      }
6769      else
6770      {
6771        if(printout > 2)
6772        {
6773          PrintS("\n// **Mprwalk: Call \"LastGB\" to compute a Groebner basis.\n");
6774        }
6775        rChangeCurrRing(newRing);
6776        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6777        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6778        F2=NULL;
6779      }
6780#ifdef TIME_TEST
6781      xtextra=clock()-to;
6782#endif
6783      ring exTargetRing = currRing;
6784
6785      rChangeCurrRing(XXRing);
6786      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6787    }
6788    else
6789    {
6790      rChangeCurrRing(XXRing);
6791      Eresult = idrMoveR(F1, TargetRing,currRing);
6792    }
6793  }
6794  else
6795  {
6796    rChangeCurrRing(XXRing);
6797    Eresult = idrMoveR(G, newRing,currRing);
6798  }
6799  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6800  delete ivNull;
6801  if(tp_deg != 1)
6802    delete target_weight;
6803
6804  if(op_deg != 1 )
6805    delete curr_weight;
6806
6807  delete exivlp;
6808  delete last_omega;
6809
6810#ifdef TIME_TEST
6811  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6812             tnw+xtnw);
6813
6814  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6815  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6816#endif
6817
6818  if(printout > 0)
6819  {
6820    Print("\n//** Mprwalk: Perturbation Walk took %d steps.\n", nstep);
6821  }
6822  return(Eresult);
6823}
6824
6825intvec* XivNull;
6826
6827/*****************************
6828 * define a matrix (1 ... 1) *
6829 *****************************/
6830intvec* MMatrixone(int nV)
6831{
6832  int i,j;
6833  intvec* ivM = new intvec(nV*nV);
6834
6835  for(i=0; i<nV; i++)
6836    for(j=0; j<nV; j++)
6837    (*ivM)[i*nV + j] = 1;
6838
6839  return(ivM);
6840}
6841
6842int nnflow;
6843int Xcall;
6844int Xngleich;
6845
6846/***********************************************************************
6847 * Perturb the start weight vector at the top level, i.e. nlev = 1     *
6848 ***********************************************************************/
6849static ideal rec_fractal_call(ideal G, int nlev, intvec* ivtarget,
6850             int reduction, int printout)
6851{
6852  Overflow_Error =  FALSE;
6853  if(printout >0)
6854  {
6855    Print("\n\n// Entering the %d-th recursion:", nlev);
6856  }
6857  int i, nV = currRing->N;
6858  ring new_ring, testring;
6859  //ring extoRing;
6860  ideal Gomega, Gomega1, Gomega2, FF, F, F1, Gresult, Gresult1, G1, Gt;
6861  int nwalks = 0;
6862  intvec* Mwlp;
6863#ifndef BUCHBERGER_ALG
6864  intvec* hilb_func;
6865#endif
6866  //intvec* extXtau;
6867  intvec* next_vect;
6868  intvec* omega2 = new intvec(nV);
6869  intvec* omtmp = new intvec(nV);
6870  //intvec* altomega = new intvec(nV);
6871
6872  for(i = nV -1; i>=0; i--)//Aenderung!!
6873  {
6874    (*omtmp)[i] = (*ivtarget)[i];
6875  }
6876  //BOOLEAN isnewtarget = FALSE;
6877
6878  // to avoid (1,0,...,0) as the target vector (Hans)
6879  intvec* last_omega = new intvec(nV);
6880  for(i=nV-1; i>0; i--)
6881    (*last_omega)[i] = 1;
6882  (*last_omega)[0] = 10000;
6883
6884  intvec* omega = new intvec(nV);
6885  for(i=0; i<nV; i++) {
6886    if(Xsigma->length