source: git/Singular/walk.cc @ 42a7cb4

spielwiese
Last change on this file since 42a7cb4 was 266ddd, checked in by Hans Schönemann <hannes@…>, 8 years ago
chg: some compiler warnings
  • Property mode set to 100644
File size: 238.1 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
98#ifdef TIME_TEST
99clock_t xtif, xtstd, xtlift, xtred, xtnw;
100clock_t xftostd, xtextra, xftinput, to;
101#endif
102
103/****************************
104 * utilities for TSet, LSet *
105 ****************************/
106inline static intset initec (int maxnr)
107{
108  return (intset)omAlloc(maxnr*sizeof(int));
109}
110
111inline static unsigned long* initsevS (int maxnr)
112{
113  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
114}
115inline static int* initS_2_R (int maxnr)
116{
117  return (int*)omAlloc0(maxnr*sizeof(int));
118}
119
120/************************************
121 * construct the set s from F u {P} *
122 ************************************/
123// unused
124/*
125static void initSSpecialCC (ideal F, ideal Q, ideal P,kStrategy strat)
126{
127  int   i,pos;
128
129  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
130  else i=setmaxT;
131
132  strat->ecartS=initec(i);
133  strat->sevS=initsevS(i);
134  strat->S_2_R=initS_2_R(i);
135  strat->fromQ=NULL;
136  strat->Shdl=idInit(i,F->rank);
137  strat->S=strat->Shdl->m;
138
139  // - put polys into S -
140  if (Q!=NULL)
141  {
142    strat->fromQ=initec(i);
143    memset(strat->fromQ,0,i*sizeof(int));
144    for (i=0; i<IDELEMS(Q); i++)
145    {
146      if (Q->m[i]!=NULL)
147      {
148        LObject h;
149        h.p = pCopy(Q->m[i]);
150        //if (TEST_OPT_INTSTRATEGY)
151        //{
152        //  //pContent(h.p);
153        //  h.pCleardenom(); // also does a pContent
154        //}
155        //else
156        //{
157        //  h.pNorm();
158        //}
159        strat->initEcart(&h);
160        if (rHasLocalOrMixedOrdering_currRing())
161        {
162          deleteHC(&h,strat);
163        }
164        if (h.p!=NULL)
165        {
166          if (strat->sl==-1)
167            pos =0;
168          else
169          {
170            pos = posInS(strat,strat->sl,h.p,h.ecart);
171          }
172          h.sev = pGetShortExpVector(h.p);
173          h.SetpFDeg();
174          strat->enterS(h,pos,strat, strat->tl+1);
175          enterT(h, strat);
176          strat->fromQ[pos]=1;
177        }
178      }
179    }
180  }
181  //- put polys into S -
182  for (i=0; i<IDELEMS(F); i++)
183  {
184    if (F->m[i]!=NULL)
185    {
186      LObject h;
187      h.p = pCopy(F->m[i]);
188      if (rHasGlobalOrdering(currRing))
189      {
190        //h.p=redtailBba(h.p,strat->sl,strat);
191        h.p=redtailBba(h.p,strat->sl,strat);
192      }
193      else
194      {
195        deleteHC(&h,strat);
196      }
197      strat->initEcart(&h);
198      if (h.p!=NULL)
199      {
200        if (strat->sl==-1)
201          pos =0;
202        else
203          pos = posInS(strat,strat->sl,h.p,h.ecart);
204        h.sev = pGetShortExpVector(h.p);
205        strat->enterS(h,pos,strat, strat->tl+1);
206        h.length = pLength(h.p);
207        h.SetpFDeg();
208        enterT(h,strat);
209      }
210    }
211  }
212#ifdef INITSSPECIAL
213  for (i=0; i<IDELEMS(P); i++)
214  {
215    if (P->m[i]!=NULL)
216    {
217      LObject h;
218      h.p=pCopy(P->m[i]);
219      strat->initEcart(&h);
220      h.length = pLength(h.p);
221      if (TEST_OPT_INTSTRATEGY)
222      {
223        h.pCleardenom();
224      }
225      else
226      {
227        h.pNorm();
228      }
229      if(strat->sl>=0)
230      {
231        if (rHasGlobalOrdering(currRing))
232        {
233          h.p=redBba(h.p,strat->sl,strat);
234          if (h.p!=NULL)
235            h.p=redtailBba(h.p,strat->sl,strat);
236        }
237        else
238        {
239          h.p=redMora(h.p,strat->sl,strat);
240          strat->initEcart(&h);
241        }
242        if(h.p!=NULL)
243        {
244          if (TEST_OPT_INTSTRATEGY)
245          {
246            h.pCleardenom();
247          }
248          else
249          {
250            h.is_normalized = 0;
251            h.pNorm();
252          }
253          h.sev = pGetShortExpVector(h.p);
254          h.SetpFDeg();
255          pos = posInS(strat->S,strat->sl,h.p,h.ecart);
256          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
257          strat->enterS(h,pos,strat, strat->tl+1);
258          enterT(h,strat);
259        }
260      }
261      else
262      {
263        h.sev = pGetShortExpVector(h.p);
264        h.SetpFDeg();
265        strat->enterS(h,0,strat, strat->tl+1);
266        enterT(h,strat);
267      }
268    }
269  }
270#endif
271}
272*/
273
274/*****************
275 *interreduce F  *
276 *****************/
277static ideal kInterRedCC(ideal F, ideal Q)
278{
279  int j;
280  kStrategy strat = new skStrategy;
281/*
282  if (TEST_OPT_PROT)
283  {
284    writeTime("start InterRed:");
285    mflush();
286  }
287  strat->syzComp     = 0;
288*/
289  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
290  strat->kNoether=pCopy((currRing->ppNoether));
291  strat->ak = id_RankFreeModule(F, currRing);
292  initBuchMoraCrit(strat);
293  strat->NotUsedAxis = (BOOLEAN *)omAlloc((currRing->N+1)*sizeof(BOOLEAN));
294  for(j=currRing->N; j>0; j--)
295  {
296    strat->NotUsedAxis[j] = TRUE;
297  }
298  strat->enterS      = enterSBba;
299  strat->posInT      = posInT0;
300  strat->initEcart   = initEcartNormal;
301  strat->sl   = -1;
302  strat->tl          = -1;
303  strat->tmax        = setmaxT;
304  strat->T           = initT();
305  strat->R           = initR();
306  strat->sevT        = initsevT();
307  if(rHasLocalOrMixedOrdering_currRing())
308  {
309    strat->honey = TRUE;
310  }
311
312  //initSCC(F,Q,strat);
313  initS(F,Q,strat);
314
315  /*
316  timetmp=clock();//22.01.02
317  initSSpecialCC(F,Q,NULL,strat);
318  tininitS=tininitS+clock()-timetmp;//22.01.02
319  */
320  if(TEST_OPT_REDSB)
321  {
322    strat->noTailReduction=FALSE;
323  }
324  updateS(TRUE,strat);
325
326  if(TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
327  {
328    completeReduce(strat);
329  }
330  pDelete(&strat->kHEdge);
331  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
332  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
333  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
334  omFreeSize((ADDRESS)strat->NotUsedAxis,(currRing->N+1)*sizeof(BOOLEAN));
335  omfree(strat->sevT);
336  omfree(strat->S_2_R);
337  omfree(strat->R);
338
339  if(strat->fromQ)
340  {
341    for(j=0; j<IDELEMS(strat->Shdl); j++)
342    {
343      if(strat->fromQ[j])
344      {
345        pDelete(&strat->Shdl->m[j]);
346      }
347    }
348    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
349    strat->fromQ = NULL;
350  }
351/*
352  if (TEST_OPT_PROT)
353  {
354    writeTime("end Interred:");
355    mflush();
356  }
357*/
358  ideal shdl=strat->Shdl;
359  idSkipZeroes(shdl);
360  delete(strat);
361
362  return shdl;
363}
364
365#ifdef TIME_TEST
366static void TimeString(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
367                       clock_t tlf,clock_t tred, clock_t tnw, int step)
368{
369  double totm = ((double) (clock() - tinput))/1000000;
370  double ostd,mostd, mif, mstd, mlf, mred, mnw, mxif,mxstd,mxlf,mxred,mxnw,tot;
371  // double mextra
372  Print("\n// total time = %.2f sec", totm);
373  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
374        mostd=((((double) tostd)/1000000)/totm)*100);
375  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
376        mif=((((double) tif)/1000000)/totm)*100);
377  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
378        mstd=((((double) tstd)/1000000)/totm)*100);
379  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
380        mlf=((((double) tlf)/1000000)/totm)*100);
381  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
382        mred=((((double) tred)/1000000)/totm)*100);
383  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
384        mnw=((((double) tnw)/1000000)/totm)*100);
385  PrintS("\n Time for the last step:");
386  Print("\n// xinfo = %.2f sec = %.2f", ((double) xtif)/1000000,
387        mxif=((((double) xtif)/1000000)/totm)*100);
388  Print("\n// xstd  = %.2f sec = %.2f", ((double) xtstd)/1000000,
389        mxstd=((((double) xtstd)/1000000)/totm)*100);
390  Print("\n// xlift = %.2f sec = %.2f", ((double) xtlift)/1000000,
391        mxlf=((((double) xtlift)/1000000)/totm)*100);
392  Print("\n// xired = %.2f sec = %.2f", ((double) xtred)/1000000,
393        mxred=((((double) xtred)/1000000)/totm)*100);
394  Print("\n// xnextw= %.2f sec = %.2f", ((double) xtnw)/1000000,
395        mxnw=((((double) xtnw)/1000000)/totm)*100);
396
397  tot=mostd+mif+mstd+mlf+mred+mnw+mxif+mxstd+mxlf+mxred+mxnw;
398  double res = (double) 100 - tot;
399  Print("\n// &%d&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f(%.2f)\\ \\",
400        step, ostd, totm, mostd,mif,mstd,mlf,mred,mnw,mxif,mxstd,mxlf,mxred,mxnw,tot,res,
401        ((((double) xtextra)/1000000)/totm)*100);
402}
403
404static void TimeStringFractal(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
405                       clock_t textra, clock_t tlf,clock_t tred, clock_t tnw)
406{
407
408  double totm = ((double) (clock() - tinput))/1000000;
409  double ostd, mostd, mif, mstd, mextra, mlf, mred, mnw, tot, res;
410  Print("\n// total time = %.2f sec", totm);
411  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
412        mostd=((((double) tostd)/1000000)/totm)*100);
413  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
414        mif=((((double) tif)/1000000)/totm)*100);
415  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
416        mstd=((((double) tstd)/1000000)/totm)*100);
417  Print("\n// xstd  = %.2f sec = %.2f", ((double) textra)/1000000,
418        mextra=((((double) textra)/1000000)/totm)*100);
419  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
420        mlf=((((double) tlf)/1000000)/totm)*100);
421  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
422        mred=((((double) tred)/1000000)/totm)*100);
423  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
424        mnw=((((double) tnw)/1000000)/totm)*100);
425  tot = mostd+mif+mstd+mextra+mlf+mred+mnw;
426  res = (double) 100.00-tot;
427  Print("\n// &%.2f &%.2f&%.2f &%.2f &%.2f &%.2f &%.2f &%.2f &%.2f&%.2f&%.2f\\ \\ ",
428        ostd,totm,mostd,mif,mstd,mextra,mlf,mred,mnw,tot,res);
429}
430#endif
431
432#ifdef CHECK_IDEAL_MWALK
433static void idString(ideal L, const char* st)
434{
435  int i, nL = IDELEMS(L);
436
437  Print("\n//  ideal %s =  ", st);
438  for(i=0; i<nL-1; i++)
439  {
440    Print(" %s, ", pString(L->m[i]));
441  }
442  Print(" %s;", pString(L->m[nL-1]));
443}
444#endif
445/*
446#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
447static void headidString(ideal L, char* st)
448{
449  int i, nL = IDELEMS(L);
450
451  Print("\n//  ideal %s =  ", st);
452  for(i=0; i<nL-1; i++)
453  {
454    Print(" %s, ", pString(pHead(L->m[i])));
455  }
456  Print(" %s;", pString(pHead(L->m[nL-1])));
457}
458#endif
459
460#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
461static void idElements(ideal L, char* st)
462{
463  int i, nL = IDELEMS(L);
464  int *K=(int *)omAlloc(nL*sizeof(int));
465
466  Print("\n//  #monoms of %s =  ", st);
467  for(i=0; i<nL; i++)
468  {
469    K[i] = pLength(L->m[i]);
470  }
471  int j, nsame;
472  // int  nk=0;
473  for(i=0; i<nL; i++)
474  {
475    if(K[i]!=0)
476    {
477      nsame = 1;
478      for(j=i+1; j<nL; j++)
479      {
480        if(K[j]==K[i])
481        {
482          nsame ++;
483          K[j]=0;
484        }
485      }
486      if(nsame == 1)
487      {
488        Print("%d, ",K[i]);
489      }
490      else
491      {
492        Print("%d[%d], ", K[i], nsame);
493      }
494    }
495  }
496  omFree(K);
497}
498#endif
499*/
500
501static void ivString(intvec* iv, const char* ch)
502{
503  int nV = iv->length()-1;
504  Print("\n// intvec %s =  ", ch);
505
506  for(int i=0; i<nV; i++)
507  {
508    Print("%d, ", (*iv)[i]);
509  }
510  Print("%d;", (*iv)[nV]);
511}
512
513#ifdef PRINT_VECTORS
514static void MivString(intvec* iva, intvec* ivb, intvec* ivc)
515{
516  int nV = iva->length()-1;
517  int i;
518  PrintS("\n//  (");
519  for(i=0; i<nV; i++)
520  {
521    Print("%d, ", (*iva)[i]);
522  }
523  Print("%d) ==> (", (*iva)[nV]);
524  for(i=0; i<nV; i++)
525  {
526    Print("%d, ", (*ivb)[i]);
527  }
528  Print("%d) := (", (*ivb)[nV]);
529
530  for(i=0; i<nV; i++)
531  {
532    Print("%d, ", (*ivc)[i]);
533  }
534  Print("%d)", (*ivc)[nV]);
535}
536#endif
537
538/********************************************************************
539 * returns gcd of integers a and b                                  *
540 ********************************************************************/
541static inline long gcd(const long a, const long b)
542{
543  long r, p0 = a, p1 = b;
544  //assume(p0 >= 0 && p1 >= 0);
545  if(p0 < 0)
546  {
547    p0 = -p0;
548  }
549  if(p1 < 0)
550  {
551    p1 = -p1;
552  }
553  while(p1 != 0)
554  {
555    r = p0 % p1;
556    p0 = p1;
557    p1 = r;
558  }
559  return p0;
560}
561
562/*****************************************************************************
563 * compute the gcd of the entries of the vectors curr_weight and diff_weight *
564 *****************************************************************************/
565/* unused:
566static int simplify_gcd(intvec* curr_weight, intvec* diff_weight)
567{
568  int j;
569  int nRing = currRing->N;
570  int gcd_tmp = (*curr_weight)[0];
571  for (j=1; j<nRing; j++)
572  {
573    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
574    if(gcd_tmp == 1)
575    {
576      break;
577    }
578  }
579  if(gcd_tmp != 1)
580  {
581    for (j=0; j<nRing; j++)
582    {
583    gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
584    if(gcd_tmp == 1)
585      {
586        break;
587      }
588    }
589  }
590  return gcd_tmp;
591}
592*/
593
594/*********************************************
595 * cancel gcd of integers zaehler and nenner *
596 *********************************************/
597static void cancel(mpz_t zaehler, mpz_t nenner)
598{
599//  assume(zaehler >= 0 && nenner > 0);
600  mpz_t g;
601  mpz_init(g);
602  mpz_gcd(g, zaehler, nenner);
603
604  mpz_div(zaehler , zaehler, g);
605  mpz_div(nenner ,  nenner, g);
606
607  mpz_clear(g);
608}
609
610//unused
611#if 0
612static int isVectorNeg(intvec* omega)
613{
614  int i;
615
616  for(i=omega->length(); i>=0; i--)
617  {
618    if((*omega)[i]<0)
619    {
620      return 1;
621    }
622  }
623  return 0;
624}
625#endif
626
627/********************************************************************
628 * compute a weight degree of a monomial p w.r.t. a weight_vector   *
629 ********************************************************************/
630static inline int MLmWeightedDegree(const poly p, intvec* weight)
631{
632  /* 2147483647 is max. integer representation in SINGULAR */
633  mpz_t sing_int;
634  mpz_init_set_ui(sing_int,  2147483647);
635
636  int i, wgrad;
637
638  mpz_t zmul;
639  mpz_init(zmul);
640  mpz_t zvec;
641  mpz_init(zvec);
642  mpz_t zsum;
643  mpz_init(zsum);
644
645  for (i=currRing->N; i>0; i--)
646  {
647    mpz_set_si(zvec, (*weight)[i-1]);
648    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
649    mpz_add(zsum, zsum, zmul);
650  }
651
652  wgrad = mpz_get_ui(zsum);
653
654  if(mpz_cmp(zsum, sing_int)>0)
655  {
656    if(Overflow_Error ==  FALSE)
657    {
658      PrintLn();
659      PrintS("\n// ** OVERFLOW in \"MwalkInitialForm\": ");
660      mpz_out_str( stdout, 10, zsum);
661      PrintS(" is greater than 2147483647 (max. integer representation)");
662      Overflow_Error = TRUE;
663    }
664  }
665
666  mpz_clear(zmul);
667  mpz_clear(zvec);
668  mpz_clear(zsum);
669  mpz_clear(sing_int);
670
671  return wgrad;
672}
673
674/********************************************************************
675 * compute a weight degree of a polynomial p w.r.t. a weight_vector *
676 ********************************************************************/
677static inline int MwalkWeightDegree(poly p, intvec* weight_vector)
678{
679  assume(weight_vector->length() >= currRing->N);
680  int max = 0, maxtemp;
681
682  while(p != NULL)
683  {
684    maxtemp = MLmWeightedDegree(p, weight_vector);
685    pIter(p);
686
687    if (maxtemp > max)
688    {
689      max = maxtemp;
690    }
691  }
692  return max;
693}
694
695
696/********************************************************************
697 * compute a weight degree of a monomial p w.r.t. a weight_vector   *
698 ********************************************************************/
699static  void  MLmWeightedDegree_gmp(mpz_t result, const poly p, intvec* weight)
700{
701  /* 2147483647 is max. integer representation in SINGULAR */
702  mpz_t sing_int;
703  mpz_init_set_ui(sing_int,  2147483647);
704
705  int i;
706
707  mpz_t zmul;
708  mpz_init(zmul);
709  mpz_t zvec;
710  mpz_init(zvec);
711  mpz_t ztmp;
712  mpz_init(ztmp);
713
714  for (i=currRing->N; i>0; i--)
715  {
716    mpz_set_si(zvec, (*weight)[i-1]);
717    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
718    mpz_add(ztmp, ztmp, zmul);
719  }
720  mpz_init_set(result, ztmp);
721  mpz_clear(ztmp);
722  mpz_clear(sing_int);
723  mpz_clear(zvec);
724  mpz_clear(zmul);
725}
726
727
728/*****************************************************************************
729 * return an initial form of the polynom g w.r.t. a weight vector curr_weight *
730 *****************************************************************************/
731static poly MpolyInitialForm(poly g, intvec* curr_weight)
732{
733  if(g == NULL)
734  {
735    return NULL;
736  }
737  mpz_t max; mpz_init(max);
738  mpz_t maxtmp; mpz_init(maxtmp);
739
740  poly hg, in_w_g = NULL;
741
742  while(g != NULL)
743  {
744    hg = g;
745    pIter(g);
746    MLmWeightedDegree_gmp(maxtmp, hg, curr_weight);
747
748    if(mpz_cmp(maxtmp, max)>0)
749    {
750      mpz_set(max, maxtmp);
751      if (in_w_g!=NULL) pDelete(&in_w_g);
752      in_w_g = pHead(hg);
753    }
754    else
755    {
756      if(mpz_cmp(maxtmp, max)==0)
757      {
758        in_w_g = pAdd(in_w_g, pHead(hg));
759      }
760    }
761  }
762  mpz_clear(maxtmp);
763  mpz_clear(max);
764  return in_w_g;
765}
766
767/************************************************************************
768 * compute the initial form of an ideal <G> w.r.t. a weight vector iva  *
769 ************************************************************************/
770ideal MwalkInitialForm(ideal G, intvec* ivw)
771{
772  BOOLEAN nError =  Overflow_Error;
773  Overflow_Error = FALSE;
774
775  int i, nG = IDELEMS(G);
776  ideal Gomega = idInit(nG, 1);
777
778  for(i=nG-1; i>=0; i--)
779  {
780    Gomega->m[i] = MpolyInitialForm(G->m[i], ivw);
781  }
782  if(Overflow_Error == FALSE)
783  {
784    Overflow_Error = nError;
785  }
786  return Gomega;
787}
788
789/************************************************************************
790 * test whether the weight vector iv is in the cone of the ideal G      *
791 *     i.e. test whether in(in_w(g)) = in(g) for all g in G             *
792 ************************************************************************/
793
794static int test_w_in_ConeCC(ideal G, intvec* iv)
795{
796  if(G->m[0] == NULL)
797  {
798    PrintS("//** the result may be WRONG, i.e. 0!!\n");
799    return 0;
800  }
801
802  BOOLEAN nError =  Overflow_Error;
803  Overflow_Error = FALSE;
804
805  int i, nG = IDELEMS(G);
806  poly mi, gi;
807
808  for(i=nG-1; i>=0; i--)
809  {
810    mi = MpolyInitialForm(G->m[i], iv);
811    //Print("\n **// test_w_in_ConeCC: lm(initial)= %s \n",pString(mi));
812    gi = G->m[i];
813    //Print("\n **// test_w_in_ConeCC: lm(ideal)= %s \n",pString(gi));
814    if(mi == NULL)
815    {
816      if(Overflow_Error == FALSE)
817      {
818        Overflow_Error = nError;
819      }
820      return 0;
821    }
822    if(!pLmEqual(mi, gi))
823    {
824      pDelete(&mi);
825      if(Overflow_Error == FALSE)
826      {
827        Overflow_Error = nError;
828      }
829      return 0;
830    }
831    pDelete(&mi);
832  }
833
834  if(Overflow_Error == FALSE)
835  {
836    Overflow_Error = nError;
837  }
838  return 1;
839}
840
841/***************************************************
842 * compute a least common multiple of two integers *
843 ***************************************************/
844static inline long Mlcm(long &i1, long &i2)
845{
846  long temp = gcd(i1, i2);
847  return ((i1 / temp)* i2);
848}
849
850
851/***************************************************
852 * return  the dot product of two intvecs a and b  *
853 ***************************************************/
854static inline long  MivDotProduct(intvec* a, intvec* b)
855{
856  assume( a->length() ==  b->length());
857  int i, n = a->length();
858  long result = 0;
859
860  for(i=n-1; i>=0; i--)
861    {
862    result += (*a)[i] * (*b)[i];
863    }
864  return result;
865}
866
867/*****************************************************
868 * Substract two given intvecs componentwise         *
869 *****************************************************/
870static intvec* MivSub(intvec* a, intvec* b)
871{
872  assume( a->length() ==  b->length());
873  int i, n = a->length();
874  intvec* result = new intvec(n);
875
876  for(i=n-1; i>=0; i--)
877  {
878    (*result)[i] = (*a)[i] - (*b)[i];
879  }
880  return result;
881}
882
883/*****************************************************
884 * return the "intvec" lead exponent of a polynomial *
885 *****************************************************/
886static intvec* MExpPol(poly f)
887{
888  int i, nR = currRing->N;
889  intvec* result = new intvec(nR);
890
891  for(i=nR-1; i>=0; i--)
892  {
893    (*result)[i] = pGetExp(f,i+1);
894  }
895  return result;
896}
897
898/*****************************************************
899 * Compare two given intvecs and return 1, if they   *
900 * are the same, otherwise 0                         *
901 *****************************************************/
902int MivSame(intvec* u , intvec* v)
903{
904  assume(u->length() == v->length());
905
906  int i, niv = u->length();
907
908  for (i=0; i<niv; i++)
909  {
910    if ((*u)[i] != (*v)[i])
911    {
912      return 0;
913    }
914  }
915  return 1;
916}
917
918/******************************************************
919 * Compare 3 given intvecs and return 0, if the first *
920 * and the second are the same. Return 1, if the      *
921 * the second and the third are the same, otherwise 2 *
922 ******************************************************/
923int M3ivSame(intvec* temp, intvec* u , intvec* v)
924{
925  assume(temp->length() == u->length() && u->length() == v->length());
926
927  if((MivSame(temp, u)) == 1)
928  {
929    return 0;
930  }
931  if((MivSame(temp, v)) == 1)
932  {
933    return 1;
934  }
935  return 2;
936}
937
938/*****************************************************
939 * compute a Groebner basis of an ideal              *
940 *****************************************************/
941static ideal MstdCC(ideal G)
942{
943  BITSET save1,save2;
944  SI_SAVE_OPT(save1,save2);
945  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
946  ideal G1 = kStd(G, NULL, testHomog, NULL);
947  SI_RESTORE_OPT(save1,save2);
948
949  idSkipZeroes(G1);
950  return G1;
951}
952
953/*****************************************************
954 * compute a Groebner basis of an homogeneous ideal  *
955 *****************************************************/
956static ideal MstdhomCC(ideal G)
957{
958  BITSET save1,save2;
959  SI_SAVE_OPT(save1,save2);
960  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
961  ideal G1 = kStd(G, NULL, isHomog, NULL);
962  SI_RESTORE_OPT(save1,save2);
963
964  idSkipZeroes(G1);
965  return G1;
966}
967
968
969/*****************************************************************************
970* create a weight matrix order as intvec of an extra weight vector (a(iv),lp)*
971******************************************************************************/
972intvec* MivMatrixOrder(intvec* iv)
973{
974  int i, nR = iv->length();
975
976  intvec* ivm = new intvec(nR*nR);
977
978  for(i=0; i<nR; i++)
979  {
980    (*ivm)[i] = (*iv)[i];
981  }
982  for(i=1; i<nR; i++)
983  {
984    (*ivm)[i*nR+i-1] = 1;
985  }
986  return ivm;
987}
988
989/*********************************************************************************
990* create a weight matrix order as intvec of an extra weight vector (a(iv),M(iw)) *
991**********************************************************************************/
992intvec* MivMatrixOrderRefine(intvec* iv, intvec* iw)
993{
994  assume((iv->length())*(iv->length()) == iw->length());
995  int i,j, nR = iv->length();
996
997  intvec* ivm = new intvec(nR*nR);
998
999  for(i=0; i<nR; i++)
1000  {
1001    (*ivm)[i] = (*iv)[i];
1002  }
1003  for(i=1; i<nR; i++)
1004  {
1005    for(j=0; j<nR; j++)
1006    {
1007      (*ivm)[j+i*nR] = (*iw)[j+i*nR];
1008    }
1009  }
1010  return ivm;
1011}
1012
1013/*******************************
1014 * return intvec = (1, ..., 1) *
1015 *******************************/
1016intvec* Mivdp(int nR)
1017{
1018  int i;
1019  intvec* ivm = new intvec(nR);
1020
1021  for(i=nR-1; i>=0; i--)
1022  {
1023    (*ivm)[i] = 1;
1024  }
1025  return ivm;
1026}
1027
1028/**********************************
1029 * return intvvec = (1,0, ..., 0) *
1030 **********************************/
1031intvec* Mivlp(int nR)
1032{
1033  intvec* ivm = new intvec(nR);
1034  (*ivm)[0] = 1;
1035
1036  return ivm;
1037}
1038
1039//unused
1040/*****************************************************************************
1041 * print the max total degree and the max coefficient of G                   *
1042 *****************************************************************************/
1043/*
1044static void checkComplexity(ideal G, char* cG)
1045{
1046  int nV = currRing->N;
1047  int nG = IDELEMS(G);
1048  intvec* ivUnit = Mivdp(nV);
1049  int i, tmpdeg, maxdeg=0;
1050  number tmpcoeff , maxcoeff=currRing->cf->nNULL;
1051  poly p;
1052  for(i=nG-1; i>=0; i--)
1053  {
1054    tmpdeg = MwalkWeightDegree(G->m[i], ivUnit);
1055    if(tmpdeg > maxdeg )
1056    {
1057      maxdeg = tmpdeg;
1058    }
1059  }
1060
1061  for(i=nG-1; i>=0; i--)
1062  {
1063    p = pCopy(G->m[i]);
1064    while(p != NULL)
1065    {
1066      //tmpcoeff = pGetCoeff(pHead(p));
1067      tmpcoeff = pGetCoeff(p);
1068      if(nGreater(tmpcoeff,maxcoeff))
1069      {
1070         maxcoeff = nCopy(tmpcoeff);
1071      }
1072      pIter(p);
1073    }
1074    pDelete(&p);
1075  }
1076  p = pNSet(maxcoeff);
1077  char* pStr = pString(p);
1078  delete ivUnit;
1079  Print("// max total degree of %s = %d\n",cG, maxdeg);
1080  Print("// max coefficient of %s  = %s", cG, pStr);//ing(p));
1081  Print(" which consists of %d digits", (int)strlen(pStr));
1082  PrintLn();
1083}
1084*/
1085
1086/*****************************************************************************
1087* If target_ord = intmat(A1, ..., An) then calculate the perturbation        *
1088* vectors                                                                    *
1089*   tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg     *
1090* where                                                                      *
1091*      inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                    *
1092* intmat target_ord is an integer order matrix of the monomial ordering of   *
1093* basering.                                                                  *
1094* This programm computes a perturbated vector with a p_deg perturbation      *
1095* degree which smaller than the numbers of variables                         *
1096******************************************************************************/
1097intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg)
1098{
1099  // ivtarget is a matrix order of a degree reverse lex. order
1100  int nV = currRing->N;
1101  //assume(pdeg <= nV && pdeg >= 0);
1102
1103  int i, j, nG = IDELEMS(G);
1104  intvec* v_null =  new intvec(nV);
1105
1106  // Check that the perturbed degree is valid
1107  if(pdeg > nV || pdeg <= 0)
1108  {
1109    WerrorS("//** The perturbed degree is wrong!!");
1110    return v_null;
1111  }
1112  delete v_null;
1113
1114  if(pdeg == 1)
1115  {
1116    return ivtarget;
1117  }
1118  mpz_t *pert_vector = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
1119  mpz_t *pert_vector1 = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
1120
1121  for(i=0; i<nV; i++)
1122  {
1123    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
1124    mpz_init_set_si(pert_vector1[i], (*ivtarget)[i]);
1125  }
1126  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
1127  // where the Ai are the i-te rows of the matrix target_ord.
1128  int ntemp, maxAi, maxA=0;
1129  for(i=1; i<pdeg; i++)
1130  {
1131    maxAi = (*ivtarget)[i*nV];
1132    if(maxAi<0)
1133    {
1134      maxAi = -maxAi;
1135    }
1136    for(j=i*nV+1; j<(i+1)*nV; j++)
1137    {
1138      ntemp = (*ivtarget)[j];
1139      if(ntemp < 0)
1140      {
1141        ntemp = -ntemp;
1142      }
1143      if(ntemp > maxAi)
1144      {
1145        maxAi = ntemp;
1146      }
1147    }
1148    maxA += maxAi;
1149  }
1150
1151  // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G.
1152
1153  intvec* ivUnit = Mivdp(nV);
1154
1155  mpz_t tot_deg; mpz_init(tot_deg);
1156  mpz_t maxdeg; mpz_init(maxdeg);
1157  mpz_t inveps; mpz_init(inveps);
1158
1159
1160  for(i=nG-1; i>=0; i--)
1161  {
1162     mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
1163     if (mpz_cmp(maxdeg,  tot_deg) > 0 )
1164     {
1165       mpz_set(tot_deg, maxdeg);
1166     }
1167  }
1168
1169  delete ivUnit;
1170  mpz_mul_ui(inveps, tot_deg, maxA);
1171  mpz_add_ui(inveps, inveps, 1);
1172
1173
1174  // takes  "small" inveps
1175#ifdef INVEPS_SMALL_IN_MPERTVECTOR
1176  if(mpz_cmp_ui(inveps, pdeg)>0 && pdeg > 3)
1177  {
1178    //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", mpz_get_si(inveps), pdeg);
1179    mpz_fdiv_q_ui(inveps, inveps, pdeg);
1180    // mpz_out_str(stdout, 10, inveps);
1181  }
1182#else
1183  // PrintS("\n// the \"big\" inverse epsilon: ");
1184  mpz_out_str(stdout, 10, inveps);
1185#endif
1186
1187  // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
1188  // pert_vector := A1
1189  for( i=1; i < pdeg; i++ )
1190  {
1191    for(j=0; j<nV; j++)
1192    {
1193      mpz_mul(pert_vector[j], pert_vector[j], inveps);
1194      if((*ivtarget)[i*nV+j]<0)
1195      {
1196        mpz_sub_ui(pert_vector[j], pert_vector[j],-(*ivtarget)[i*nV+j]);
1197      }
1198      else
1199      {
1200        mpz_add_ui(pert_vector[j], pert_vector[j],(*ivtarget)[i*nV+j]);
1201      }
1202    }
1203  }
1204
1205  // 2147483647 is max. integer representation in SINGULAR
1206  mpz_t sing_int;
1207  mpz_init_set_ui(sing_int,  2147483647);
1208
1209  mpz_t check_int;
1210  mpz_init_set_ui(check_int,  100000);
1211
1212  mpz_t ztemp;
1213  mpz_init(ztemp);
1214  mpz_set(ztemp, pert_vector[0]);
1215  for(i=1; i<nV; i++)
1216  {
1217    mpz_gcd(ztemp, ztemp, pert_vector[i]);
1218    if(mpz_cmp_si(ztemp, 1)  == 0)
1219    {
1220      break;
1221    }
1222  }
1223  if(mpz_cmp_si(ztemp, 1) != 0)
1224  {
1225    for(i=0; i<nV; i++)
1226    {
1227      mpz_divexact(pert_vector[i], pert_vector[i], ztemp);
1228    }
1229  }
1230
1231  for(i=0; i<nV; i++)
1232  {
1233    if(mpz_cmp(pert_vector[i], check_int)>=0)
1234    {
1235      for(j=0; j<nV; j++)
1236      {
1237        mpz_fdiv_q_ui(pert_vector1[j], pert_vector[j], 100);
1238      }
1239    }
1240  }
1241
1242  intvec* result = new intvec(nV);
1243
1244  int ntrue=0;
1245
1246  for(i=0; i<nV; i++)
1247  {
1248    (*result)[i] = mpz_get_si(pert_vector1[i]);
1249    if(mpz_cmp(pert_vector1[i], sing_int)>=0)
1250    {
1251      ntrue++;
1252    }
1253  }
1254  if(ntrue > 0 || test_w_in_ConeCC(G,result)==0)
1255  {
1256    ntrue=0;
1257    for(i=0; i<nV; i++)
1258    {
1259      (*result)[i] = mpz_get_si(pert_vector[i]);
1260      if(mpz_cmp(pert_vector[i], sing_int)>=0)
1261      {
1262        ntrue++;
1263        if(Overflow_Error == FALSE)
1264        {
1265          Overflow_Error = TRUE;
1266          PrintS("\n// ** OVERFLOW in \"MPertvectors\": ");
1267          mpz_out_str( stdout, 10, pert_vector[i]);
1268          PrintS(" is greater than 2147483647 (max. integer representation)");
1269          Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
1270        }
1271      }
1272    }
1273
1274    if(Overflow_Error == TRUE)
1275    {
1276      ivString(result, "pert_vector");
1277      Print("\n// %d element(s) of it is overflow!!", ntrue);
1278    }
1279  }
1280
1281  mpz_clear(ztemp);
1282  mpz_clear(sing_int);
1283  mpz_clear(check_int);
1284  omFree(pert_vector);
1285  omFree(pert_vector1);
1286  mpz_clear(tot_deg);
1287  mpz_clear(maxdeg);
1288  mpz_clear(inveps);
1289
1290  rComplete(currRing);
1291  for(j=0; j<IDELEMS(G); j++)
1292  {
1293    poly p=G->m[j];
1294    while(p!=NULL)
1295    {
1296      p_Setm(p,currRing); pIter(p);
1297    }
1298  }
1299  return result;
1300}
1301
1302/*****************************************************************************
1303 * The following procedure returns                                           *
1304 *     Pert(A1) = 1/eps^(pdeg-1)*A_1 + 1/eps^(pdeg-2)*A_2+...+A_pdeg,        *
1305 * where the A_i are the i-th rows of the matrix target_ord and              *
1306 *     1/eps > deg(p)*(max(A_2) + max(A_3)+...+max(A_pdeg))                  *
1307 *****************************************************************************/
1308intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg)
1309{
1310  // ivtarget is a matrix order of the lex. order
1311  int nV = currRing->N;
1312  //assume(pdeg <= nV && pdeg >= 0);
1313
1314  int i, j, nG = IDELEMS(G);
1315  intvec* pert_vector =  new intvec(nV);
1316
1317  //Checking that the perturbated degree is valid
1318  if(pdeg > nV || pdeg <= 0)
1319  {
1320    WerrorS("//** The perturbed degree is wrong!!");
1321    return pert_vector;
1322  }
1323  for(i=0; i<nV; i++)
1324  {
1325    (*pert_vector)[i]=(*ivtarget)[i];
1326  }
1327  if(pdeg == 1)
1328  {
1329    return pert_vector;
1330  }
1331  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
1332  // where the Ai are the i-te rows of the matrix target_ord.
1333  int ntemp, maxAi, maxA=0;
1334  for(i=1; i<pdeg; i++)
1335  {
1336    maxAi = (*ivtarget)[i*nV];
1337    for(j=i*nV+1; j<(i+1)*nV; j++)
1338    {
1339      ntemp = (*ivtarget)[j];
1340      if(ntemp > maxAi)
1341      {
1342        maxAi = ntemp;
1343      }
1344    }
1345    maxA += maxAi;
1346  }
1347
1348  // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G.
1349  int inveps, tot_deg = 0, maxdeg;
1350
1351  intvec* ivUnit = Mivdp(nV);//19.02
1352  for(i=nG-1; i>=0; i--)
1353  {
1354    // maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
1355    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
1356    if (maxdeg > tot_deg )
1357    {
1358      tot_deg = maxdeg;
1359    }
1360  }
1361  delete ivUnit;
1362
1363  inveps = (tot_deg * maxA) + 1;
1364
1365#ifdef INVEPS_SMALL_IN_FRACTAL
1366  //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", inveps, pdeg);
1367  if(inveps > pdeg && pdeg > 3)
1368  {
1369    inveps = inveps / pdeg;
1370  }
1371  // Print(" %d", inveps);
1372#else
1373  PrintS("\n// the \"big\" inverse epsilon %d", inveps);
1374#endif
1375
1376  // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg
1377  for ( i=1; i < pdeg; i++ )
1378  {
1379    for(j=0; j<nV; j++)
1380    {
1381      (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j];
1382    }
1383  }
1384
1385  int temp = (*pert_vector)[0];
1386  for(i=1; i<nV; i++)
1387  {
1388    temp = gcd(temp, (*pert_vector)[i]);
1389    if(temp == 1)
1390    {
1391      break;
1392    }
1393  }
1394  if(temp != 1)
1395  {
1396    for(i=0; i<nV; i++)
1397    {
1398      (*pert_vector)[i] = (*pert_vector)[i] / temp;
1399    }
1400  }
1401
1402  intvec* result = pert_vector;
1403  delete pert_vector;
1404  return result;
1405}
1406
1407/*****************************************************************************
1408 * define a lexicographic order matrix as intvec                             *
1409 *****************************************************************************/
1410intvec* MivMatrixOrderlp(int nV)
1411{
1412  int i;
1413  intvec* ivM = new intvec(nV*nV);
1414
1415  for(i=0; i<nV; i++)
1416  {
1417    (*ivM)[i*nV + i] = 1;
1418  }
1419  return(ivM);
1420}
1421
1422
1423/*****************************************************************************
1424 * define a reverse lexicographic order (dp) matrix as intvec                *
1425 *****************************************************************************/
1426intvec* MivMatrixOrderdp(int nV)
1427{
1428  int i;
1429  intvec* ivM = new intvec(nV*nV);
1430
1431  for(i=0; i<nV; i++)
1432  {
1433    (*ivM)[i] = 1;
1434  }
1435  for(i=1; i<nV; i++)
1436  {
1437    (*ivM)[(i+1)*nV - i] = -1;
1438  }
1439  return(ivM);
1440}
1441
1442/*****************************************************************************
1443 * creates an intvec of the monomial order Wp(ivstart)                       *
1444 *****************************************************************************/
1445intvec* MivWeightOrderlp(intvec* ivstart)
1446{
1447  int i;
1448  int nV = ivstart->length();
1449  intvec* ivM = new intvec(nV*nV);
1450
1451  for(i=0; i<nV; i++)
1452  {
1453    (*ivM)[i] = (*ivstart)[i];
1454  }
1455  for(i=1; i<nV; i++)
1456  {
1457    (*ivM)[i*nV + i-1] = 1;
1458  }
1459  return(ivM);
1460}
1461
1462/*****************************************************************************
1463 * creates an intvec of the monomial order dp(ivstart)                       *
1464 *****************************************************************************/
1465intvec* MivWeightOrderdp(intvec* ivstart)
1466{
1467  int i;
1468  int nV = ivstart->length();
1469  intvec* ivM = new intvec(nV*nV);
1470
1471  for(i=0; i<nV; i++)
1472  {
1473    (*ivM)[i] = (*ivstart)[i];
1474  }
1475  for(i=0; i<nV; i++)
1476  {
1477    (*ivM)[nV+i] = 1;
1478  }
1479  for(i=2; i<nV; i++)
1480  {
1481    (*ivM)[(i+1)*nV - i] = -1;
1482  }
1483  return(ivM);
1484}
1485
1486//unused
1487/*
1488static intvec* MatrixOrderdp(int nV)
1489{
1490  int i;
1491  intvec* ivM = new intvec(nV*nV);
1492
1493  for(i=0; i<nV; i++)
1494  {
1495    (*ivM)[i] = 1;
1496  }
1497  for(i=1; i<nV; i++)
1498  {
1499    (*ivM)[(i+1)*nV - i] = -1;
1500  }
1501  return(ivM);
1502}
1503*/
1504
1505intvec* MivUnit(int nV)
1506{
1507  int i;
1508  intvec* ivM = new intvec(nV);
1509  for(i=nV-1; i>=0; i--)
1510  {
1511    (*ivM)[i] = 1;
1512  }
1513  return(ivM);
1514}
1515
1516
1517/************************************************************************
1518*  compute a perturbed weight vector of a matrix order w.r.t. an ideal  *
1519*************************************************************************/
1520int Xnlev;
1521intvec* Mfpertvector(ideal G, intvec* ivtarget)
1522{
1523  int i, j, nG = IDELEMS(G);
1524  int nV = currRing->N;
1525  int niv = nV*nV;
1526
1527
1528  // Calculate maxA = Max(A2) + Max(A3) + ... + Max(AnV),
1529  // where the Ai are the i-te rows of the matrix 'targer_ord'.
1530  int ntemp, maxAi, maxA=0;
1531  for(i=1; i<nV; i++)
1532  {
1533    maxAi = (*ivtarget)[i*nV];
1534    if(maxAi<0)
1535    {
1536      maxAi = -maxAi;
1537    }
1538    for(j=i*nV+1; j<(i+1)*nV; j++)
1539    {
1540      ntemp = (*ivtarget)[j];
1541      if(ntemp < 0)
1542      {
1543        ntemp = -ntemp;
1544      }
1545      if(ntemp > maxAi)
1546      {
1547        maxAi = ntemp;
1548      }
1549    }
1550    maxA = maxA + maxAi;
1551  }
1552  intvec* ivUnit = Mivdp(nV);
1553
1554  // Calculate inveps = 1/eps, where 1/eps > deg(p)*maxA for all p in G.
1555  mpz_t tot_deg; mpz_init(tot_deg);
1556  mpz_t maxdeg; mpz_init(maxdeg);
1557  mpz_t inveps; mpz_init(inveps);
1558
1559
1560  for(i=nG-1; i>=0; i--)
1561  {
1562    mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
1563    if (mpz_cmp(maxdeg,  tot_deg) > 0 )
1564    {
1565      mpz_set(tot_deg, maxdeg);
1566    }
1567  }
1568
1569  delete ivUnit;
1570  //inveps = (tot_deg * maxA) + 1;
1571  mpz_mul_ui(inveps, tot_deg, maxA);
1572  mpz_add_ui(inveps, inveps, 1);
1573
1574  // takes  "small" inveps
1575#ifdef INVEPS_SMALL_IN_FRACTAL
1576  if(mpz_cmp_ui(inveps, nV)>0 && nV > 3)
1577  {
1578    mpz_cdiv_q_ui(inveps, inveps, nV);
1579  }
1580  // choose the small inverse epsilon
1581#endif
1582
1583  // PrintLn();  mpz_out_str(stdout, 10, inveps);
1584
1585  // Calculate the perturbed target orders:
1586  mpz_t *ivtemp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
1587  mpz_t *pert_vector=(mpz_t *)omAlloc(niv*sizeof(mpz_t));
1588
1589  for(i=0; i < nV; i++)
1590  {
1591    mpz_init_set_si(ivtemp[i], (*ivtarget)[i]);
1592    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
1593  }
1594
1595  mpz_t ztmp; mpz_init(ztmp);
1596  // BOOLEAN isneg = FALSE;
1597
1598  for(i=1; i<nV; i++)
1599  {
1600    for(j=0; j<nV; j++)
1601    {
1602      mpz_mul(ztmp, inveps, ivtemp[j]);
1603      if((*ivtarget)[i*nV+j]<0)
1604      {
1605        mpz_sub_ui(ivtemp[j], ztmp, -(*ivtarget)[i*nV+j]);
1606      }
1607      else
1608      {
1609        mpz_add_ui(ivtemp[j], ztmp,(*ivtarget)[i*nV+j]);
1610      }
1611    }
1612
1613    for(j=0; j<nV; j++)
1614    {
1615      mpz_init_set(pert_vector[i*nV+j],ivtemp[j]);
1616    }
1617  }
1618
1619  // 2147483647 is max. integer representation in SINGULAR
1620  mpz_t sing_int;
1621  mpz_init_set_ui(sing_int,  2147483647);
1622
1623  intvec* result = new intvec(niv);
1624  BOOLEAN nflow = FALSE;
1625
1626  // computes gcd
1627  mpz_set(ztmp, pert_vector[0]);
1628  for(i=0; i<niv; i++)
1629  {
1630    mpz_gcd(ztmp, ztmp, pert_vector[i]);
1631    if(mpz_cmp_si(ztmp, 1)==0)
1632    {
1633      break;
1634    }
1635  }
1636
1637  for(i=0; i<niv; i++)
1638  {
1639    mpz_divexact(pert_vector[i], pert_vector[i], ztmp);
1640    (* result)[i] = mpz_get_si(pert_vector[i]);
1641  }
1642
1643  CHECK_OVERFLOW:
1644
1645  for(i=0; i<niv; i++)
1646  {
1647    if(mpz_cmp(pert_vector[i], sing_int)>0)
1648    {
1649      if(nflow == FALSE)
1650      {
1651        Xnlev = i / nV;
1652        nflow = TRUE;
1653        Overflow_Error = TRUE;
1654        Print("\n// Xlev = %d and the %d-th element is", Xnlev,  i+1);
1655        PrintS("\n// ** OVERFLOW in \"Mfpertvector\": ");
1656        mpz_out_str( stdout, 10, pert_vector[i]);
1657        PrintS(" is greater than 2147483647 (max. integer representation)");
1658        Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
1659      }
1660    }
1661  }
1662  if(Overflow_Error == TRUE)
1663  {
1664    ivString(result, "new_vector");
1665  }
1666  omFree(pert_vector);
1667  omFree(ivtemp);
1668  mpz_clear(ztmp);
1669  mpz_clear(tot_deg);
1670  mpz_clear(maxdeg);
1671  mpz_clear(inveps);
1672  mpz_clear(sing_int);
1673
1674  rComplete(currRing);
1675  for(j=0; j<IDELEMS(G); j++)
1676  {
1677    poly p=G->m[j];
1678    while(p!=NULL)
1679    {
1680      p_Setm(p,currRing);
1681      pIter(p);
1682    }
1683  }
1684  return result;
1685}
1686
1687/****************************************************************
1688 * Multiplication of two ideals element by element              *
1689 * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) *
1690 *  destroy A, keeps B                                          *
1691 ****************************************************************/
1692static ideal MidMult(ideal A, ideal B)
1693{
1694  int mA = IDELEMS(A), mB = IDELEMS(B);
1695
1696  if(A==NULL || B==NULL)
1697  {
1698    return NULL;
1699  }
1700  if(mB < mA)
1701  {
1702    mA = mB;
1703  }
1704  ideal result = idInit(mA, 1);
1705
1706  int i, k=0;
1707  for(i=0; i<mA; i++)
1708    {
1709      result->m[k] = pMult(A->m[i], pCopy(B->m[i]));
1710      A->m[i]=NULL;
1711      if (result->m[k]!=NULL)
1712      {
1713        k++;
1714      }
1715    }
1716
1717  idDelete(&A);
1718  idSkipZeroes(result);
1719  return result;
1720}
1721
1722/*********************************************************************
1723 * G is a red. Groebner basis w.r.t. <_1                             *
1724 * Gomega is an initial form ideal of <G> w.r.t. a weight vector w   *
1725 * M is a subideal of <Gomega> and M selft is a red. Groebner basis  *
1726 *    of the ideal <Gomega> w.r.t. <_w                               *
1727 * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega  *
1728 * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i*
1729 ********************************************************************/
1730static ideal MLifttwoIdeal(ideal Gw, ideal M, ideal G)
1731{
1732  ideal Mtmp = idLift(Gw, M, NULL, FALSE, TRUE, TRUE, NULL);
1733
1734  // If Gw is a GB, then isSB = TRUE, otherwise FALSE
1735  // So, it is better, if one tests whether Gw is a GB
1736  // in ideals.cc:
1737  // idLift (ideal mod, ideal submod,ideal * rest, BOOLEAN goodShape,
1738  //           BOOLEAN isSB,BOOLEAN divide,matrix * unit)
1739
1740  // Let be Mtmp = {m1,...,ms}, where mi=sum hij.in_gj, for all i=1,...,s
1741  // We compute F = {f1,...,fs}, where fi=sum hij.gj
1742  int i, j, nM = IDELEMS(Mtmp);
1743  ideal idpol, idLG;
1744  ideal F = idInit(nM, 1);
1745
1746  for(i=0; i<nM; i++)
1747  {
1748     idpol = idVec2Ideal(Mtmp->m[i]);
1749     idLG = MidMult(idpol, G);
1750     idpol = NULL;
1751     F->m[i] = NULL;
1752     for(j=IDELEMS(idLG)-1; j>=0; j--)
1753     {
1754       F->m[i] = pAdd(F->m[i], idLG->m[j]);
1755       idLG->m[j]=NULL;
1756     }
1757     idDelete(&idLG);
1758  }
1759  idDelete(&Mtmp);
1760  return F;
1761}
1762
1763//unused
1764/*
1765static void checkidealCC(ideal G, char* Ch)
1766{
1767  int i,nmon=0,ntmp;
1768  int nG = IDELEMS(G);
1769  int n = nG-1;
1770  Print("\n// ** Ideal %s besteht aus %d Polynomen mit ", Ch, nG);
1771
1772  for(i=0; i<nG; i++)
1773  {
1774    ntmp =  pLength(G->m[i]);
1775    nmon += ntmp;
1776
1777    if(i != n)
1778    {
1779      Print("%d, ", ntmp);
1780    }
1781    else
1782    {
1783      Print(" bzw. %d ", ntmp);
1784    }
1785  }
1786  PrintS(" Monomen.\n");
1787  Print("// ** %s besitzt %d Monome.", Ch, nmon);
1788  PrintLn();
1789}
1790*/
1791
1792//unused
1793/*
1794static void HeadidString(ideal L, char* st)
1795{
1796  int i, nL = IDELEMS(L)-1;
1797
1798  Print("//  The head terms of the ideal %s = ", st);
1799  for(i=0; i<nL; i++)
1800  {
1801    Print(" %s, ", pString(pHead(L->m[i])));
1802  }
1803  Print(" %s;\n", pString(pHead(L->m[nL])));
1804}
1805
1806*/
1807static inline int MivComp(intvec* iva, intvec* ivb)
1808{
1809  assume(iva->length() == ivb->length());
1810  int i;
1811  for(i=iva->length()-1; i>=0; i--)
1812  {
1813    if((*iva)[i] - (*ivb)[i] != 0)
1814    {
1815      return 0;
1816    }
1817  }
1818  return 1;
1819}
1820
1821/**********************************************
1822 * Look for the smallest absolut value in vec *
1823 **********************************************/
1824static int MivAbsMax(intvec* vec)
1825{
1826  int i,k;
1827  if((*vec)[0] < 0)
1828  {
1829    k = -(*vec)[0];
1830  }
1831  else
1832  {
1833    k = (*vec)[0];
1834  }
1835  for(i=1; i < (vec->length()); i++)
1836  {
1837    if((*vec)[i] < 0)
1838    {
1839      if(-(*vec)[i] > k)
1840      {
1841        k = -(*vec)[i];
1842      }
1843    }
1844    else
1845    {
1846      if((*vec)[i] > k)
1847      {
1848        k = (*vec)[i];
1849      }
1850    }
1851  }
1852  return k;
1853}
1854
1855
1856/**************************************************************
1857 * Look for the position of the smallest absolut value in vec *
1858 **************************************************************/
1859static int MivAbsMaxArg(intvec* vec)
1860{
1861  int k = MivAbsMax(vec);
1862  int i=0;
1863  while(1)
1864  {
1865    if((*vec)[i] == k || (*vec)[i] == -k)
1866    {
1867      break;
1868    }
1869    i++;
1870  }
1871  return i;
1872}
1873
1874
1875/**********************************************************************
1876 * Compute a next weight vector between curr_weight and target_weight *
1877 * with respect to an ideal <G>.                                      *
1878**********************************************************************/
1879/*
1880static intvec* MwalkNextWeightCC(intvec* curr_weight, intvec* target_weight,
1881                                 ideal G)
1882{
1883  BOOLEAN nError = Overflow_Error;
1884  Overflow_Error = FALSE;
1885
1886  assume(currRing != NULL && curr_weight != NULL &&
1887         target_weight != NULL && G != NULL);
1888
1889  int nRing = currRing->N;
1890  int checkRed, j, nG = IDELEMS(G);
1891  intvec* ivtemp;
1892
1893  mpz_t t_zaehler, t_nenner;
1894  mpz_init(t_zaehler);
1895  mpz_init(t_nenner);
1896
1897  mpz_t s_zaehler, s_nenner, temp, MwWd;
1898  mpz_init(s_zaehler);
1899  mpz_init(s_nenner);
1900  mpz_init(temp);
1901  mpz_init(MwWd);
1902
1903  mpz_t sing_int;
1904  mpz_init(sing_int);
1905  mpz_set_si(sing_int,  2147483647);
1906
1907  mpz_t sing_int_half;
1908  mpz_init(sing_int_half);
1909  mpz_set_si(sing_int_half,  3*(1073741824/2));
1910
1911  mpz_t deg_w0_p1, deg_d0_p1;
1912  mpz_init(deg_w0_p1);
1913  mpz_init(deg_d0_p1);
1914
1915  mpz_t sztn, sntz;
1916  mpz_init(sztn);
1917  mpz_init(sntz);
1918
1919  mpz_t t_null;
1920  mpz_init(t_null);
1921
1922  mpz_t ggt;
1923  mpz_init(ggt);
1924
1925  mpz_t dcw;
1926  mpz_init(dcw);
1927
1928  int gcd_tmp;
1929  intvec* diff_weight = MivSub(target_weight, curr_weight);
1930
1931  intvec* diff_weight1 = MivSub(target_weight, curr_weight);
1932  poly g;
1933
1934  for (j=0; j<nG; j++)
1935  {
1936    g = G->m[j];
1937    if (g != NULL)
1938    {
1939      ivtemp = MExpPol(g);
1940      mpz_set_si(deg_w0_p1, MivDotProduct(ivtemp, curr_weight));
1941      mpz_set_si(deg_d0_p1, MivDotProduct(ivtemp, diff_weight));
1942      delete ivtemp;
1943
1944      pIter(g);
1945      while (g != NULL)
1946      {
1947        ivtemp = MExpPol(g);
1948        mpz_set_si(MwWd, MivDotProduct(ivtemp, curr_weight));
1949        mpz_sub(s_zaehler, deg_w0_p1, MwWd);
1950        if(mpz_cmp(s_zaehler, t_null) != 0)
1951        {
1952          mpz_set_si(MwWd, MivDotProduct(ivtemp, diff_weight));
1953          mpz_sub(s_nenner, MwWd, deg_d0_p1);
1954          // check for 0 < s <= 1
1955          if( (mpz_cmp(s_zaehler,t_null) > 0 &&
1956               mpz_cmp(s_nenner, s_zaehler)>=0) ||
1957              (mpz_cmp(s_zaehler, t_null) < 0 &&
1958               mpz_cmp(s_nenner, s_zaehler)<=0))
1959          {
1960            // make both positive
1961            if (mpz_cmp(s_zaehler, t_null) < 0)
1962            {
1963              mpz_neg(s_zaehler, s_zaehler);
1964              mpz_neg(s_nenner, s_nenner);
1965            }
1966
1967            //compute a simple fraction of s
1968            cancel(s_zaehler, s_nenner);
1969
1970            if(mpz_cmp(t_nenner, t_null) != 0)
1971            {
1972              mpz_mul(sztn, s_zaehler, t_nenner);
1973              mpz_mul(sntz, s_nenner, t_zaehler);
1974
1975              if(mpz_cmp(sztn,sntz) < 0)
1976              {
1977                mpz_add(t_nenner, t_null, s_nenner);
1978                mpz_add(t_zaehler,t_null, s_zaehler);
1979              }
1980            }
1981            else
1982            {
1983              mpz_add(t_nenner, t_null, s_nenner);
1984              mpz_add(t_zaehler,t_null, s_zaehler);
1985            }
1986          }
1987        }
1988        pIter(g);
1989        delete ivtemp;
1990      }
1991    }
1992  }
1993  //Print("\n// Alloc Size = %d \n", nRing*sizeof(mpz_t));
1994  mpz_t *vec=(mpz_t*)omAlloc(nRing*sizeof(mpz_t));
1995
1996
1997  // there is no 0<t<1 and define the next weight vector that is equal
1998  // to the current weight vector
1999  if(mpz_cmp(t_nenner, t_null) == 0)
2000  {
2001#ifndef SING_NDEBUG
2002    PrintS("\n//MwalkNextWeightCC: t_nenner=0\n");
2003#endif
2004    delete diff_weight;
2005    diff_weight = ivCopy(curr_weight);//take memory
2006    goto FINISH;
2007  }
2008
2009  // define the target vector as the next weight vector, if t = 1
2010  if(mpz_cmp_si(t_nenner, 1)==0 && mpz_cmp_si(t_zaehler,1)==0)
2011  {
2012    delete diff_weight;
2013    diff_weight = ivCopy(target_weight); //this takes memory
2014    goto FINISH;
2015  }
2016
2017   checkRed = 0;
2018
2019  SIMPLIFY_GCD:
2020
2021  // simplify the vectors curr_weight and diff_weight (C-int)
2022  gcd_tmp = (*curr_weight)[0];
2023
2024  for (j=1; j<nRing; j++)
2025  {
2026    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
2027    if(gcd_tmp == 1)
2028    {
2029      break;
2030    }
2031  }
2032  if(gcd_tmp != 1)
2033  {
2034    for (j=0; j<nRing; j++)
2035    {
2036      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
2037      if(gcd_tmp == 1)
2038      {
2039        break;
2040      }
2041    }
2042  }
2043  if(gcd_tmp != 1)
2044  {
2045    for (j=0; j<nRing; j++)
2046    {
2047      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
2048      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
2049    }
2050  }
2051  if(checkRed > 0)
2052  {
2053    for (j=0; j<nRing; j++)
2054    {
2055      mpz_set_si(vec[j], (*diff_weight)[j]);
2056    }
2057    goto TEST_OVERFLOW;
2058  }
2059
2060#ifdef  NEXT_VECTORS_CC
2061  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
2062  ivString(curr_weight, "new cw");
2063  ivString(diff_weight, "new dw");
2064
2065  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
2066  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
2067#endif
2068
2069// construct a new weight vector and check whether vec[j] is overflow,
2070// i.e. vec[j] > 2^31.
2071// If vec[j] doesn't overflow, define a weight vector. Otherwise,
2072// report that overflow appears. In the second case, test whether the
2073// the correctness of the new vector plays an important role
2074
2075  for (j=0; j<nRing; j++)
2076  {
2077    mpz_set_si(dcw, (*curr_weight)[j]);
2078    mpz_mul(s_nenner, t_nenner, dcw);
2079
2080    if( (*diff_weight)[j]>0)
2081    {
2082      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
2083    }
2084    else
2085    {
2086      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
2087      mpz_neg(s_zaehler, s_zaehler);
2088    }
2089    mpz_add(sntz, s_nenner, s_zaehler);
2090    mpz_init_set(vec[j], sntz);
2091
2092#ifdef NEXT_VECTORS_CC
2093    Print("\n//   j = %d ==> ", j);
2094    PrintS("(");
2095    mpz_out_str( stdout, 10, t_nenner);
2096    Print(" * %d)", (*curr_weight)[j]);
2097    PrintS(" + ("); mpz_out_str( stdout, 10, t_zaehler);
2098    Print(" * %d) =  ",  (*diff_weight)[j]);
2099    mpz_out_str( stdout, 10, s_nenner);
2100    PrintS(" + ");
2101    mpz_out_str( stdout, 10, s_zaehler);
2102    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
2103    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
2104#endif
2105
2106    if(j==0)
2107    {
2108      mpz_set(ggt, sntz);
2109    }
2110    else
2111    {
2112      if(mpz_cmp_si(ggt,1) != 0)
2113      {
2114        mpz_gcd(ggt, ggt, sntz);
2115      }
2116    }
2117  }
2118  // reduce the vector with the gcd
2119  if(mpz_cmp_si(ggt,1) != 0)
2120  {
2121    for (j=0; j<nRing; j++)
2122    {
2123      mpz_divexact(vec[j], vec[j], ggt);
2124    }
2125  }
2126#ifdef  NEXT_VECTORS_CC
2127  PrintS("\n// gcd of elements of the vector: ");
2128  mpz_out_str( stdout, 10, ggt);
2129#endif
2130
2131  for(j=0; j<nRing; j++)
2132  {
2133    if(mpz_cmp(vec[j], sing_int_half) >= 0)
2134    {
2135      goto REDUCTION;
2136    }
2137  }
2138  checkRed = 1;
2139  for (j=0; j<nRing; j++)
2140    {
2141      (*diff_weight)[j] = mpz_get_si(vec[j]);
2142    }
2143  goto SIMPLIFY_GCD;
2144
2145  REDUCTION:
2146  checkRed = 1;
2147  for (j=0; j<nRing; j++)
2148  {
2149    (*diff_weight1)[j] = mpz_get_si(vec[j]);
2150  }
2151  while(test_w_in_ConeCC(G,diff_weight1))
2152  {
2153    for(j=0; j<nRing; j++)
2154    {
2155      (*diff_weight)[j] = (*diff_weight1)[j];
2156      mpz_set_si(vec[j], (*diff_weight)[j]);
2157    }
2158    for(j=0; j<nRing; j++)
2159    {
2160      (*diff_weight1)[j] = floor(0.1*(*diff_weight)[j] + 0.5);
2161    }
2162  }
2163  if(MivAbsMax(diff_weight)>10000)
2164  {
2165    for(j=0; j<nRing; j++)
2166    {
2167      (*diff_weight1)[j] = (*diff_weight)[j];
2168    }
2169    j = 0;
2170    while(test_w_in_ConeCC(G,diff_weight1))
2171    {
2172      (*diff_weight)[j] = (*diff_weight1)[j];
2173      mpz_set_si(vec[j], (*diff_weight)[j]);
2174      j = MivAbsMaxArg(diff_weight1);
2175      (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2176    }
2177    goto SIMPLIFY_GCD;
2178  }
2179
2180 TEST_OVERFLOW:
2181
2182  for (j=0; j<nRing; j++)
2183  {
2184    if(mpz_cmp(vec[j], sing_int)>=0)
2185    {
2186      if(Overflow_Error == FALSE)
2187      {
2188        Overflow_Error = TRUE;
2189        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
2190        mpz_out_str( stdout, 10, vec[j]);
2191        PrintS(" is greater than 2147483647 (max. integer representation)\n");
2192        //Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
2193      }
2194    }
2195  }
2196
2197 FINISH:
2198   delete diff_weight1;
2199   mpz_clear(t_zaehler);
2200   mpz_clear(t_nenner);
2201   mpz_clear(s_zaehler);
2202   mpz_clear(s_nenner);
2203   mpz_clear(sntz);
2204   mpz_clear(sztn);
2205   mpz_clear(temp);
2206   mpz_clear(MwWd);
2207   mpz_clear(deg_w0_p1);
2208   mpz_clear(deg_d0_p1);
2209   mpz_clear(ggt);
2210   omFree(vec);
2211   mpz_clear(sing_int_half);
2212   mpz_clear(sing_int);
2213   mpz_clear(dcw);
2214   mpz_clear(t_null);
2215
2216  if(Overflow_Error == FALSE)
2217  {
2218    Overflow_Error = nError;
2219  }
2220  rComplete(currRing);
2221  for(j=0; j<IDELEMS(G); j++)
2222  {
2223    poly p=G->m[j];
2224    while(p!=NULL)
2225    {
2226      p_Setm(p,currRing);
2227      pIter(p);
2228    }
2229  }
2230return diff_weight;
2231}
2232*/
2233/**********************************************************************
2234 * Compute a next weight vector between curr_weight and target_weight *
2235 * with respect to an ideal <G>.                                      *
2236**********************************************************************/
2237static intvec* MwalkNextWeightCC(intvec* curr_weight, intvec* target_weight,
2238                                 ideal G)
2239{
2240  BOOLEAN nError = Overflow_Error;
2241  Overflow_Error = FALSE;
2242
2243  assume(currRing != NULL && curr_weight != NULL &&
2244         target_weight != NULL && G != NULL);
2245
2246  int nRing = currRing->N;
2247  int j, nG = IDELEMS(G);
2248  intvec* ivtemp;
2249
2250  mpz_t t_zaehler, t_nenner;
2251  mpz_init(t_zaehler);
2252  mpz_init(t_nenner);
2253
2254  mpz_t s_zaehler, s_nenner, temp, MwWd;
2255  mpz_init(s_zaehler);
2256  mpz_init(s_nenner);
2257  mpz_init(temp);
2258  mpz_init(MwWd);
2259
2260  mpz_t sing_int;
2261  mpz_init(sing_int);
2262  mpz_set_si(sing_int,  2147483647);
2263
2264  mpz_t sing_int_half;
2265  mpz_init(sing_int_half);
2266  mpz_set_si(sing_int_half,  3*(1073741824/2));
2267
2268  mpz_t deg_w0_p1, deg_d0_p1;
2269  mpz_init(deg_w0_p1);
2270  mpz_init(deg_d0_p1);
2271
2272  mpz_t sztn, sntz;
2273  mpz_init(sztn);
2274  mpz_init(sntz);
2275
2276  mpz_t t_null;
2277  mpz_init(t_null);
2278
2279  mpz_t ggt;
2280  mpz_init(ggt);
2281
2282  mpz_t dcw;
2283  mpz_init(dcw);
2284
2285  int gcd_tmp;
2286  //intvec* diff_weight = MivSub(target_weight, curr_weight);
2287
2288  intvec* diff_weight1 = new intvec(nRing); //MivSub(target_weight, curr_weight);
2289  poly g;
2290
2291  // reduce the size of the entries of the current weight vector
2292  if(TEST_OPT_REDSB)
2293  {
2294    for (j=0; j<nRing; j++)
2295    {
2296      (*diff_weight1)[j] = (*curr_weight)[j];
2297    }
2298    while(MivAbsMax(diff_weight1)>10000 && test_w_in_ConeCC(G,diff_weight1)==1)
2299    {
2300      for(j=0; j<nRing; j++)
2301      {
2302        (*curr_weight)[j] = (*diff_weight1)[j];
2303      }
2304      for(j=0; j<nRing; j++)
2305      {
2306        (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2307      }
2308    }
2309
2310    if(MivAbsMax(curr_weight)>100000)
2311    {
2312      for(j=0; j<nRing; j++)
2313      {
2314        (*diff_weight1)[j] = (*curr_weight)[j];
2315      }
2316      j = 0;
2317      while(test_w_in_ConeCC(G,diff_weight1)==1 && MivAbsMax(diff_weight1)>1000)
2318      {
2319        (*curr_weight)[j] = (*diff_weight1)[j];
2320        j = MivAbsMaxArg(diff_weight1);
2321        (*diff_weight1)[j] = floor(0.1*(*diff_weight1)[j] + 0.5);
2322      }
2323    }
2324
2325  }
2326  intvec* diff_weight = MivSub(target_weight, curr_weight);
2327
2328  // compute a suitable next weight vector
2329  for (j=0; j<nG; j++)
2330  {
2331    g = G->m[j];
2332    if (g != NULL)
2333    {
2334      ivtemp = MExpPol(g);
2335      mpz_set_si(deg_w0_p1, MivDotProduct(ivtemp, curr_weight));
2336      mpz_set_si(deg_d0_p1, MivDotProduct(ivtemp, diff_weight));
2337      delete ivtemp;
2338
2339      pIter(g);
2340      while (g != NULL)
2341      {
2342        ivtemp = MExpPol(g);
2343        mpz_set_si(MwWd, MivDotProduct(ivtemp, curr_weight));
2344        mpz_sub(s_zaehler, deg_w0_p1, MwWd);
2345        if(mpz_cmp(s_zaehler, t_null) != 0)
2346        {
2347          mpz_set_si(MwWd, MivDotProduct(ivtemp, diff_weight));
2348          mpz_sub(s_nenner, MwWd, deg_d0_p1);
2349          // check for 0 < s <= 1
2350          if( (mpz_cmp(s_zaehler,t_null) > 0 &&
2351               mpz_cmp(s_nenner, s_zaehler)>=0) ||
2352              (mpz_cmp(s_zaehler, t_null) < 0 &&
2353               mpz_cmp(s_nenner, s_zaehler)<=0))
2354          {
2355            // make both positive
2356            if (mpz_cmp(s_zaehler, t_null) < 0)
2357            {
2358              mpz_neg(s_zaehler, s_zaehler);
2359              mpz_neg(s_nenner, s_nenner);
2360            }
2361
2362            //compute a simple fraction of s
2363            cancel(s_zaehler, s_nenner);
2364
2365            if(mpz_cmp(t_nenner, t_null) != 0)
2366            {
2367              mpz_mul(sztn, s_zaehler, t_nenner);
2368              mpz_mul(sntz, s_nenner, t_zaehler);
2369
2370              if(mpz_cmp(sztn,sntz) < 0)
2371              {
2372                mpz_add(t_nenner, t_null, s_nenner);
2373                mpz_add(t_zaehler,t_null, s_zaehler);
2374              }
2375            }
2376            else
2377            {
2378              mpz_add(t_nenner, t_null, s_nenner);
2379              mpz_add(t_zaehler,t_null, s_zaehler);
2380            }
2381          }
2382        }
2383        pIter(g);
2384        delete ivtemp;
2385      }
2386    }
2387  }
2388  //Print("\n// Alloc Size = %d \n", nRing*sizeof(mpz_t));
2389  mpz_t *vec=(mpz_t*)omAlloc(nRing*sizeof(mpz_t));
2390
2391
2392  // there is no 0<t<1 and define the next weight vector that is equal
2393  // to the current weight vector
2394  if(mpz_cmp(t_nenner, t_null) == 0)
2395  {
2396#ifndef SING_NDEBUG
2397    PrintS("\n//MwalkNextWeightCC: t_nenner=0\n");
2398#endif
2399    delete diff_weight;
2400    diff_weight = ivCopy(curr_weight);//take memory
2401    goto FINISH;
2402  }
2403
2404  // define the target vector as the next weight vector, if t = 1
2405  if(mpz_cmp_si(t_nenner, 1)==0 && mpz_cmp_si(t_zaehler,1)==0)
2406  {
2407    delete diff_weight;
2408    diff_weight = ivCopy(target_weight); //this takes memory
2409    goto FINISH;
2410  }
2411
2412  SIMPLIFY_GCD:
2413
2414  // simplify the vectors curr_weight and diff_weight (C-int)
2415  gcd_tmp = (*curr_weight)[0];
2416
2417  for (j=1; j<nRing; j++)
2418  {
2419    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
2420    if(gcd_tmp == 1)
2421    {
2422      break;
2423    }
2424  }
2425  if(gcd_tmp != 1)
2426  {
2427    for (j=0; j<nRing; j++)
2428    {
2429      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
2430      if(gcd_tmp == 1)
2431      {
2432        break;
2433      }
2434    }
2435  }
2436  if(gcd_tmp != 1)
2437  {
2438    for (j=0; j<nRing; j++)
2439    {
2440      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
2441      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
2442    }
2443  }
2444
2445#ifdef  NEXT_VECTORS_CC
2446  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
2447  ivString(curr_weight, "new cw");
2448  ivString(diff_weight, "new dw");
2449
2450  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
2451  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
2452#endif
2453
2454// construct a new weight vector and check whether vec[j] is overflow, i.e. vec[j] > 2^31.
2455// If vec[j] doesn't overflow, define a weight vector. Otherwise, report that overflow
2456// appears. In the second case, test whether the the correctness of the new vector plays
2457// an important role
2458
2459  for (j=0; j<nRing; j++)
2460  {
2461    mpz_set_si(dcw, (*curr_weight)[j]);
2462    mpz_mul(s_nenner, t_nenner, dcw);
2463
2464    if( (*diff_weight)[j]>0)
2465    {
2466      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
2467    }
2468    else
2469    {
2470      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
2471      mpz_neg(s_zaehler, s_zaehler);
2472    }
2473    mpz_add(sntz, s_nenner, s_zaehler);
2474    mpz_init_set(vec[j], sntz);
2475
2476#ifdef NEXT_VECTORS_CC
2477    Print("\n//   j = %d ==> ", j);
2478    PrintS("(");
2479    mpz_out_str( stdout, 10, t_nenner);
2480    Print(" * %d)", (*curr_weight)[j]);
2481    PrintS(" + ("); mpz_out_str( stdout, 10, t_zaehler);
2482    Print(" * %d) =  ",  (*diff_weight)[j]);
2483    mpz_out_str( stdout, 10, s_nenner);
2484    PrintS(" + ");
2485    mpz_out_str( stdout, 10, s_zaehler);
2486    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
2487    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
2488#endif
2489
2490    if(j==0)
2491    {
2492      mpz_set(ggt, sntz);
2493    }
2494    else
2495    {
2496      if(mpz_cmp_si(ggt,1) != 0)
2497      {
2498        mpz_gcd(ggt, ggt, sntz);
2499      }
2500    }
2501  }
2502  // reduce the vector with the gcd
2503  if(mpz_cmp_si(ggt,1) != 0)
2504  {
2505    for (j=0; j<nRing; j++)
2506    {
2507      mpz_divexact(vec[j], vec[j], ggt);
2508    }
2509  }
2510#ifdef  NEXT_VECTORS_CC
2511  PrintS("\n// gcd of elements of the vector: ");
2512  mpz_out_str( stdout, 10, ggt);
2513#endif
2514
2515  for (j=0; j<nRing; j++)
2516  {
2517    (*diff_weight)[j] = mpz_get_si(vec[j]);
2518  }
2519
2520 TEST_OVERFLOW:
2521
2522  for (j=0; j<nRing; j++)
2523  {
2524    if(mpz_cmp(vec[j], sing_int)>=0)
2525    {
2526      if(Overflow_Error == FALSE)
2527      {
2528        Overflow_Error = TRUE;
2529        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
2530        mpz_out_str( stdout, 10, vec[j]);
2531        PrintS(" is greater than 2147483647 (max. integer representation)\n");
2532        //Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
2533      }
2534    }
2535  }
2536
2537 FINISH:
2538   delete diff_weight1;
2539   mpz_clear(t_zaehler);
2540   mpz_clear(t_nenner);
2541   mpz_clear(s_zaehler);
2542   mpz_clear(s_nenner);
2543   mpz_clear(sntz);
2544   mpz_clear(sztn);
2545   mpz_clear(temp);
2546   mpz_clear(MwWd);
2547   mpz_clear(deg_w0_p1);
2548   mpz_clear(deg_d0_p1);
2549   mpz_clear(ggt);
2550   omFree(vec);
2551   mpz_clear(sing_int_half);
2552   mpz_clear(sing_int);
2553   mpz_clear(dcw);
2554   mpz_clear(t_null);
2555
2556  if(Overflow_Error == FALSE)
2557  {
2558    Overflow_Error = nError;
2559  }
2560  rComplete(currRing);
2561  for(j=0; j<IDELEMS(G); j++)
2562  {
2563    poly p=G->m[j];
2564    while(p!=NULL)
2565    {
2566      p_Setm(p,currRing);
2567      pIter(p);
2568    }
2569  }
2570return diff_weight;
2571}
2572
2573
2574/**********************************************************************
2575* Compute an intermediate weight vector from iva to ivb w.r.t.        *
2576* the reduced Groebner basis G.                                       *
2577* Return NULL, if it is equal to iva or iva = avb.                    *
2578**********************************************************************/
2579intvec* MkInterRedNextWeight(intvec* iva, intvec* ivb, ideal G)
2580{
2581  intvec* tmp = new intvec(iva->length());
2582  intvec* result;
2583
2584  if(G == NULL)
2585  {
2586    return tmp;
2587  }
2588  if(MivComp(iva, ivb) == 1)
2589  {
2590    return tmp;
2591  }
2592  result = MwalkNextWeightCC(iva, ivb, G);
2593
2594  if(MivComp(result, iva) == 1)
2595  {
2596    delete result;
2597    return tmp;
2598  }
2599
2600  delete tmp;
2601  return result;
2602}
2603
2604/********************************************************************
2605 * define and execute a new ring which order is (a(vb),a(va),lp,C)  *
2606 * ******************************************************************/
2607/*static ring VMrHomogeneous(intvec* va, intvec* vb)
2608{
2609
2610  if ((currRing->ppNoether)!=NULL)
2611  {
2612    pDelete(&(currRing->ppNoether));
2613  }
2614  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2615      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2616  {
2617    sLastPrinted.CleanUp();
2618  }
2619
2620  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2621  int i, nv = currRing->N;
2622
2623  r->cf  = currRing->cf;
2624  r->N   = currRing->N;
2625  int nb = 4;
2626
2627
2628  //names
2629  char* Q; // In order to avoid the corrupted memory, do not change.
2630  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2631  for(i=0; i<nv; i++)
2632  {
2633    Q = currRing->names[i];
2634    r->names[i]  = omStrDup(Q);
2635  }
2636
2637  //weights: entries for 3 blocks: NULL Made:???
2638  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2639  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2640  r->wvhdl[1] = (int*) omAlloc((nv)*sizeof(int));
2641
2642  for(i=0; i<nv; i++)
2643  {
2644    r->wvhdl[1][i] = (*vb)[i];
2645    r->wvhdl[0][i] = (*va)[i];
2646  }
2647  r->wvhdl[0][nv] = (*va)[nv];
2648
2649  // order: (1..1),a,lp,C
2650  r->order = (int *) omAlloc(nb * sizeof(int *));
2651  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2652  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2653
2654  // ringorder a for the first block: var 1..nv
2655  r->order[0]  = ringorder_a;
2656  r->block0[0] = 1;
2657  r->block1[0] = nv;
2658
2659 // ringorder a for the second block: var 2..nv
2660  r->order[1]  = ringorder_a;
2661  r->block0[1] = 1;
2662  r->block1[1] = nv;
2663
2664  // ringorder lp for the third block: var 2..nv
2665  r->order[2]  = ringorder_lp;
2666  r->block0[2] = 1;
2667  r->block1[2] = nv;
2668
2669  // ringorder C for the 4th block
2670  // it is very important within "idLift",
2671  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2672  // therefore, nb  must be (nBlocks(currRing)  + 1)
2673  r->order[3]  = ringorder_C;
2674
2675  // polynomial ring
2676  r->OrdSgn    = 1;
2677
2678  // complete ring intializations
2679
2680  rComplete(r);
2681  return r;
2682  //rChangeCurrRing(r);
2683}
2684*/
2685
2686/**************************************************************
2687 * define and execute a new ring which order is (a(va),lp,C)  *
2688 * ************************************************************/
2689static ring VMrDefault(intvec* va)
2690{
2691
2692  ring r = rCopy0(currRing,FALSE,FALSE);
2693  int i, nv = currRing->N;
2694
2695  int nb = 4;
2696
2697  /*weights: entries for 3 blocks: NULL Made:???*/
2698  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2699  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2700  for(i=0; i<nv; i++)
2701    r->wvhdl[0][i] = (*va)[i];
2702
2703  /* order: a,lp,C,0 */
2704  r->order = (int *) omAlloc(nb * sizeof(int *));
2705  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2706  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2707
2708  // ringorder a for the first block: var 1..nv
2709  r->order[0]  = ringorder_a;
2710  r->block0[0] = 1;
2711  r->block1[0] = nv;
2712
2713  // ringorder lp for the second block: var 1..nv
2714  r->order[1]  = ringorder_lp;
2715  r->block0[1] = 1;
2716  r->block1[1] = nv;
2717
2718  // ringorder C for the third block
2719  // it is very important within "idLift",
2720  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2721  // therefore, nb  must be (nBlocks(currRing)  + 1)
2722  r->order[2]  = ringorder_C;
2723
2724  // the last block: everything is 0
2725  r->order[3]  = 0;
2726
2727  // polynomial ring
2728  r->OrdSgn    = 1;
2729
2730  // complete ring intializations
2731
2732  rComplete(r);
2733  return r;
2734  //rChangeCurrRing(r);
2735}
2736
2737/****************************************************************
2738 * define and execute a new ring with ordering (a(va),Wp(vb),C) *
2739 * **************************************************************/
2740static ring VMrRefine(intvec* va, intvec* vb)
2741{
2742
2743  ring r = rCopy0(currRing,FALSE,FALSE);
2744  int i, nv = currRing->N;
2745
2746  int nb = 5;
2747
2748  //weights: entries for 3 blocks: NULL Made:???
2749  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2750  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2751  r->wvhdl[1] = (int*) omAlloc(nv*sizeof(int));
2752
2753  for(i=0; i<nv; i++)
2754  {
2755    r->wvhdl[0][i] = (*vb)[i];
2756    r->wvhdl[1][i] = (*va)[i];
2757  }
2758
2759  // order: (1..1),a,lp,C
2760  r->order = (int *) omAlloc(nb * sizeof(int *));
2761  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2762  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2763
2764  // ringorder a for the first block: var 1..nv
2765  r->order[0]  = ringorder_a;
2766  r->block0[0] = 1;
2767  r->block1[0] = nv;
2768
2769 // ringorder Wp for the second block: var 1..nv
2770  r->order[1]  = ringorder_a;
2771  r->block0[1] = 1;
2772  r->block1[1] = nv;
2773
2774  // ringorder lp for the third block: var 1..nv
2775  r->order[2]  = ringorder_lp;
2776  r->block0[2] = 1;
2777  r->block1[2] = nv;
2778
2779  // ringorder C for the 4th block
2780  // it is very important within "idLift",
2781  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2782  // therefore, nb  must be (nBlocks(currRing)  + 1)
2783  r->order[3]  = ringorder_C;
2784
2785  // the last block: everything is 0
2786  r->order[4]  = 0;
2787
2788  // complete ring intializations
2789
2790  rComplete(r);
2791
2792  //rChangeCurrRing(r);
2793  return r;
2794}
2795
2796/*****************************************************
2797 * define and execute a new ring with ordering (M,C) *
2798 *****************************************************/
2799static ring VMatrDefault(intvec* va)
2800{
2801
2802  ring r = rCopy0(currRing,FALSE,FALSE);
2803  int i, nv = currRing->N;
2804
2805  int nb = 4;
2806
2807  /*weights: entries for 3 blocks: NULL Made:???*/
2808  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2809  r->wvhdl[0] = (int*) omAlloc(nv*nv*sizeof(int));
2810  r->wvhdl[1] =NULL; // (int*) omAlloc(nv*sizeof(int));
2811  r->wvhdl[2]=NULL;
2812  r->wvhdl[3]=NULL;
2813  for(i=0; i<nv*nv; i++)
2814    r->wvhdl[0][i] = (*va)[i];
2815
2816  /* order: a,lp,C,0 */
2817  r->order = (int *) omAlloc(nb * sizeof(int *));
2818  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2819  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2820
2821  // ringorder a for the first block: var 1..nv
2822  r->order[0]  = ringorder_M;
2823  r->block0[0] = 1;
2824  r->block1[0] = nv;
2825
2826  // ringorder C for the second block
2827  r->order[1]  = ringorder_C;
2828  r->block0[1] = 1;
2829  r->block1[1] = nv;
2830
2831// ringorder C for the third block: var 1..nv
2832  r->order[2]  = ringorder_C;
2833  r->block0[2] = 1;
2834  r->block1[2] = nv;
2835
2836  // the last block: everything is 0
2837  r->order[3]  = 0;
2838
2839  // complete ring intializations
2840
2841  rComplete(r);
2842
2843  //rChangeCurrRing(r);
2844  return r;
2845}
2846
2847/***********************************************************
2848 * define and execute a new ring with ordering (a(vb),M,C) *
2849 ***********************************************************/
2850static ring VMatrRefine(intvec* va, intvec* vb)
2851{
2852
2853  ring r = rCopy0(currRing,FALSE,FALSE);
2854  int i, nv = currRing->N;
2855  int nvs = nv*nv;
2856
2857  int nb = 4;
2858
2859  /*weights: entries for 3 blocks: NULL Made:???*/
2860  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2861  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2862  r->wvhdl[1] = (int*) omAlloc(nvs*sizeof(int));
2863  r->wvhdl[2]=NULL;
2864  r->wvhdl[3]=NULL;
2865  for(i=0; i<nvs; i++)
2866  {
2867    r->wvhdl[1][i] = (*va)[i];
2868  }
2869  for(i=0; i<nv; i++)
2870  {
2871    r->wvhdl[0][i] = (*vb)[i];
2872  }
2873  /* order: a,lp,C,0 */
2874  r->order = (int *) omAlloc(nb * sizeof(int *));
2875  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2876  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2877
2878  // ringorder a for the first block: var 1..nv
2879  r->order[0]  = ringorder_a;
2880  r->block0[0] = 1;
2881  r->block1[0] = nv;
2882
2883  // ringorder M for the second block: var 1..nv
2884  r->order[1]  = ringorder_M;
2885  r->block0[1] = 1;
2886  r->block1[1] = nv;
2887
2888  // ringorder C for the third block: var 1..nv
2889  r->order[2]  = ringorder_C;
2890  r->block0[2] = 1;
2891  r->block1[2] = nv;
2892
2893  // the last block: everything is 0
2894  r->order[3]  = 0;
2895
2896  // complete ring intializations
2897
2898  rComplete(r);
2899
2900  //rChangeCurrRing(r);
2901  return r;
2902}
2903
2904/**********************************************************************
2905* define and execute a new ring which order is  a lexicographic order *
2906***********************************************************************/
2907static void VMrDefaultlp(void)
2908{
2909  ring r = rCopy0(currRing,FALSE,FALSE);
2910  int nv = currRing->N;
2911
2912  int nb = rBlocks(currRing) + 1;
2913
2914  /*weights: entries for 3 blocks: NULL Made:???*/
2915
2916  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2917
2918  /* order: lp,C,0 */
2919  r->order = (int *) omAlloc(nb * sizeof(int *));
2920  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2921  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2922
2923  /* ringorder lp for the first block: var 1..nv */
2924  r->order[0]  = ringorder_lp;
2925  r->block0[0] = 1;
2926  r->block1[0] = nv;
2927
2928  /* ringorder C for the second block */
2929  r->order[1]  = ringorder_C;
2930
2931  /* the last block: everything is 0 */
2932  r->order[2]  = 0;
2933
2934  /*polynomial ring*/
2935  r->OrdSgn    = 1;
2936
2937  /* complete ring intializations */
2938
2939  rComplete(r);
2940
2941  rChangeCurrRing(r);
2942}
2943
2944/***************************************************
2945* define a ring with parameters und change to it   *
2946* DefRingPar and DefRingParlp corrupt still memory *
2947****************************************************/
2948static void DefRingPar(intvec* va)
2949{
2950  int nv = currRing->N;
2951  int nb = rBlocks(currRing) + 1;
2952
2953  ring res=rCopy0(currRing,FALSE,FALSE);
2954
2955  /*weights: entries for 3 blocks: NULL Made:???*/
2956  res->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2957  res->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2958  for(int i=0; i<nv; i++)
2959    res->wvhdl[0][i] = (*va)[i];
2960
2961  /* order: a,lp,C,0 */
2962
2963  res->order = (int *) omAlloc(nb * sizeof(int *));
2964  res->block0 = (int *)omAlloc0(nb * sizeof(int *));
2965  res->block1 = (int *)omAlloc0(nb * sizeof(int *));
2966
2967  // ringorder a for the first block: var 1..nv
2968  res->order[0]  = ringorder_a;
2969  res->block0[0] = 1;
2970  res->block1[0] = nv;
2971
2972  // ringorder lp for the second block: var 1..nv
2973  res->order[1]  = ringorder_lp;
2974  res->block0[1] = 1;
2975  res->block1[1] = nv;
2976
2977  // ringorder C for the third block
2978  // it is very important within "idLift",
2979  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2980  // therefore, nb  must be (nBlocks(currRing)  + 1)
2981  res->order[2]  = ringorder_C;
2982
2983  // the last block: everything is 0
2984  res->order[3]  = 0;
2985
2986  // polynomial ring
2987  res->OrdSgn    = 1;
2988
2989
2990  // complete ring intializations
2991  rComplete(res);
2992
2993  // execute the created ring
2994  rChangeCurrRing(res);
2995}
2996
2997static void DefRingParlp(void)
2998{
2999  int nv = currRing->N;
3000
3001  ring r=rCopy0(currRing,FALSE,FALSE);
3002
3003  int nb = rBlocks(currRing) + 1;
3004
3005  /*weights: entries for 3 blocks: NULL Made:???*/
3006
3007  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
3008
3009  /* order: lp,C,0 */
3010  r->order = (int *) omAlloc(nb * sizeof(int *));
3011  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
3012  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
3013
3014  /* ringorder lp for the first block: var 1..nv */
3015  r->order[0]  = ringorder_lp;
3016  r->block0[0] = 1;
3017  r->block1[0] = nv;
3018
3019  /* ringorder C for the second block */
3020  r->order[1]  = ringorder_C;
3021
3022  /* the last block: everything is 0 */
3023  r->order[2]  = 0;
3024
3025  /*polynomial ring*/
3026  r->OrdSgn    = 1;
3027
3028
3029//   if (rParameter(currRing)!=NULL)
3030//   {
3031//     r->cf->extRing->qideal->m[0]=p_Copy(currRing->cf->extRing->qideal->m[0], currRing->cf->extRing);
3032//     int l=rPar(currRing);
3033//     r->cf->extRing->names=(char **)omAlloc(l*sizeof(char_ptr));
3034//
3035//     for(int i=l-1;i>=0;i--)
3036//     {
3037//       rParameter(r)[i]=omStrDup(rParameter(currRing)[i]);
3038//     }
3039//   }
3040
3041  // complete ring intializations
3042
3043  rComplete(r);
3044
3045  // execute the created ring
3046  rChangeCurrRing(r);
3047}
3048
3049/*************************************************************
3050 * check whether one or more components of a vector are zero *
3051 *************************************************************/
3052/* unused:
3053static int isNolVector(intvec* hilb)
3054{
3055  int i;
3056  for(i=hilb->length()-1; i>=0; i--)
3057  {
3058    if((* hilb)[i]==0)
3059    {
3060      return 1;
3061    }
3062  }
3063  return 0;
3064}
3065*/
3066
3067/*************************************************************
3068 * check whether one or more components of a vector are <= 0 *
3069 *************************************************************/
3070static int isNegNolVector(intvec* hilb)
3071{
3072  int i;
3073  for(i=hilb->length()-1; i>=0; i--)
3074  {
3075    if((* hilb)[i]<=0)
3076    {
3077      return 1;
3078    }
3079  }
3080  return 0;
3081}
3082
3083/**************************************************************************
3084* Gomega is the initial ideal of G w. r. t. the current weight vector     *
3085* curr_weight. Check whether curr_weight lies on a border of the Groebner *
3086* cone, i. e. check whether a monomial is divisible by a leading monomial *
3087***************************************************************************/
3088static ideal middleOfCone(ideal G, ideal Gomega)
3089{
3090  BOOLEAN middle = FALSE;
3091  int i,j,N = IDELEMS(Gomega);
3092  poly p,lm,factor1,factor2;
3093
3094  ideal Go = idCopy(G);
3095
3096  // check whether leading monomials of G and Gomega coincide
3097  // and return NULL if not
3098  for(i=0; i<N; i++)
3099  {
3100    if(!pIsConstant(pSub(pCopy(Gomega->m[i]),pCopy(pHead(G->m[i])))))
3101    {
3102      idDelete(&Go);
3103      return NULL;
3104    }
3105  }
3106  for(i=0; i<N; i++)
3107  {
3108    for(j=0; j<N; j++)
3109    {
3110      if(i!=j)
3111      {
3112        p = pCopy(Gomega->m[i]);
3113        lm = pCopy(Gomega->m[j]);
3114        pIter(p);
3115        while(p!=NULL)
3116        {
3117          if(pDivisibleBy(lm,p))
3118          {
3119            if(middle == FALSE)
3120            {
3121              middle = TRUE;
3122            }
3123            factor1 = singclap_pdivide(pHead(p),lm,currRing);
3124            factor2 = pMult(pCopy(factor1),pCopy(Go->m[j]));
3125            pDelete(&factor1);
3126            Go->m[i] = pAdd((Go->m[i]),pNeg(pCopy(factor2)));
3127            pDelete(&factor2);
3128          }
3129          pIter(p);
3130        }
3131        pDelete(&lm);
3132        pDelete(&p);
3133      }
3134    }
3135  }
3136
3137  if(middle == TRUE)
3138  {
3139    return Go;
3140  }
3141  idDelete(&Go);
3142  return NULL;
3143}
3144
3145/******************************  Februar 2002  ****************************
3146 * G is a Groebner basis w.r.t. (a(curr_weight),lp) and                   *
3147 * we compute a GB of <G> w.r.t. the lex. order by the perturbation walk  *
3148 * its perturbation degree is tp_deg                                      *
3149 * We call the following subfunction LastGB, if                           *
3150 * the computed intermediate weight vector or                             *
3151 * if the perturbed target weight vector does NOT lie n the correct cone  *
3152 **************************************************************************/
3153
3154static ideal LastGB(ideal G, intvec* curr_weight,int tp_deg)
3155{
3156  BOOLEAN nError = Overflow_Error;
3157  Overflow_Error = FALSE;
3158
3159  int i, nV = currRing->N;
3160  int nwalk=0, endwalks=0, nnwinC=1;
3161  int nlast = 0;
3162  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
3163  ring newRing, oldRing, TargetRing;
3164  intvec* iv_M_lp;
3165  intvec* target_weight;
3166  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
3167  intvec* pert_target_vector;
3168  intvec* ivNull = new intvec(nV);
3169  intvec* extra_curr_weight = new intvec(nV);
3170  intvec* next_weight;
3171
3172#ifndef  BUCHBERGER_ALG
3173  intvec* hilb_func;
3174#endif
3175
3176  // to avoid (1,0,...,0) as the target vector
3177  intvec* last_omega = new intvec(nV);
3178  for(i=nV-1; i>0; i--)
3179  {
3180    (*last_omega)[i] = 1;
3181  }
3182  (*last_omega)[0] = 10000;
3183
3184  ring EXXRing = currRing;
3185
3186  // compute a pertubed weight vector of the target weight vector
3187  if(tp_deg > 1 && tp_deg <= nV)
3188  {
3189    //..25.03.03 VMrDefaultlp();//    VMrDefault(target_weight);
3190    if (rParameter (currRing) != NULL)
3191    {
3192      DefRingParlp();
3193    }
3194    else
3195    {
3196      VMrDefaultlp();
3197    }
3198    TargetRing = currRing;
3199    ssG = idrMoveR(G,EXXRing,currRing);
3200    iv_M_lp = MivMatrixOrderlp(nV);
3201    //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
3202    target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
3203    delete iv_M_lp;
3204    pert_target_vector = target_weight;
3205
3206    rChangeCurrRing(EXXRing);
3207    G = idrMoveR(ssG, TargetRing,currRing);
3208  }
3209  else
3210  {
3211    target_weight = Mivlp(nV);
3212  }
3213  //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3214
3215  while(1)
3216  {
3217    nwalk++;
3218    nstep++;
3219#ifdef TIME_TEST
3220    to=clock();
3221#endif
3222   // compute a next weight vector
3223    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
3224#ifdef TIME_TEST
3225    xtnw=xtnw+clock()-to;
3226#endif
3227
3228#ifdef PRINT_VECTORS
3229    MivString(curr_weight, target_weight, next_weight);
3230#endif
3231
3232    if(Overflow_Error == TRUE)
3233    {
3234      newRing = currRing;
3235      nnwinC = 0;
3236      if(tp_deg == 1)
3237      {
3238        nlast = 1;
3239      }
3240      delete next_weight;
3241
3242      //idElements(G, "G");
3243      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3244
3245      break;
3246    }
3247
3248    if(MivComp(next_weight, ivNull) == 1)
3249    {
3250      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3251      newRing = currRing;
3252      delete next_weight;
3253      break;
3254    }
3255
3256    if(MivComp(next_weight, target_weight) == 1)
3257      endwalks = 1;
3258
3259    for(i=nV-1; i>=0; i--)
3260    {
3261      (*extra_curr_weight)[i] = (*curr_weight)[i];
3262    }
3263    /* 06.11.01 NOT Changed */
3264    for(i=nV-1; i>=0; i--)
3265    {
3266      (*curr_weight)[i] = (*next_weight)[i];
3267    }
3268    oldRing = currRing;
3269#ifdef TIME_TEST
3270    to=clock();
3271#endif
3272    // compute an initial form ideal of <G> w.r.t. "curr_vector"
3273    Gomega = MwalkInitialForm(G, curr_weight);
3274#ifdef TIME_TEST
3275    xtif=xtif+clock()-to;
3276#endif
3277
3278#ifdef ENDWALKS
3279    if(endwalks == 1)
3280    {
3281      Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3282/*
3283      idElements(Gomega, "Gw");
3284      headidString(Gomega, "Gw");
3285*/
3286    }
3287#endif
3288
3289#ifndef  BUCHBERGER_ALG
3290    if(isNolVector(curr_weight) == 0)
3291    {
3292      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
3293    }
3294    else
3295    {
3296      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
3297    }
3298#endif // BUCHBERGER_ALG
3299
3300    /* define a new ring that its ordering is "(a(curr_weight),lp) */
3301    //..25.03.03 VMrDefault(curr_weight);
3302    if (rParameter (currRing) != NULL)
3303    {
3304      DefRingPar(curr_weight);
3305    }
3306    else
3307    {
3308      rChangeCurrRing(VMrDefault(curr_weight));
3309    }
3310    newRing = currRing;
3311    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
3312
3313#ifdef TIME_TEST
3314    to=clock();
3315#endif
3316    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
3317#ifdef  BUCHBERGER_ALG
3318    M = MstdhomCC(Gomega1);
3319#else
3320    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
3321    delete hilb_func;
3322#endif // BUCHBERGER_ALG
3323#ifdef TIME_TEST
3324    xtstd=xtstd+clock()-to;
3325#endif
3326    /* change the ring to oldRing */
3327    rChangeCurrRing(oldRing);
3328    M1 =  idrMoveR(M, newRing,currRing);
3329    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
3330
3331#ifdef TIME_TEST
3332    to=clock();
3333#endif
3334    /* compute a reduced Groebner basis of <G> w.r.t. "newRing" */
3335    F = MLifttwoIdeal(Gomega2, M1, G);
3336#ifdef TIME_TEST
3337    xtlift=xtlift+clock()-to;
3338#endif
3339
3340    idDelete(&M1);
3341    idDelete(&G);
3342
3343    /* change the ring to newRing */
3344    rChangeCurrRing(newRing);
3345    F1 = idrMoveR(F, oldRing,currRing);
3346
3347#ifdef TIME_TEST
3348    to=clock();
3349#endif
3350    /* reduce the Groebner basis <G> w.r.t. new ring */
3351    G = kInterRedCC(F1, NULL);
3352#ifdef TIME_TEST
3353    xtred=xtred+clock()-to;
3354#endif
3355    idDelete(&F1);
3356
3357    if(endwalks == 1)
3358    {
3359      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3360      break;
3361    }
3362
3363    delete next_weight;
3364  }//while
3365
3366  delete ivNull;
3367
3368  if(tp_deg != 1)
3369  {
3370    //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3371    if (rParameter (currRing) != NULL)
3372    {
3373      DefRingParlp();
3374    }
3375    else
3376    {
3377      VMrDefaultlp();
3378    }
3379    F1 = idrMoveR(G, newRing,currRing);
3380
3381    if(nnwinC == 0 || test_w_in_ConeCC(F1, pert_target_vector) != 1)
3382    {
3383      oldRing = currRing;
3384      rChangeCurrRing(newRing);
3385      G = idrMoveR(F1, oldRing,currRing);
3386      Print("\n// takes %d steps and calls the recursion of level %d:",
3387             nwalk, tp_deg-1);
3388
3389      F1 = LastGB(G,curr_weight, tp_deg-1);
3390    }
3391
3392    TargetRing = currRing;
3393    rChangeCurrRing(EXXRing);
3394    result = idrMoveR(F1, TargetRing,currRing);
3395  }
3396  else
3397  {
3398    if(nlast == 1)
3399    {
3400      //OMEGA_OVERFLOW_LASTGB:
3401      /*
3402      if(MivSame(curr_weight, iv_lp) == 1)
3403        if (rParameter(currRing) != NULL)
3404          DefRingParlp();
3405        else
3406          VMrDefaultlp();
3407      else
3408        if (rParameter(currRing) != NULL)
3409          DefRingPar(curr_weight);
3410        else
3411          VMrDefault(curr_weight);
3412      */
3413
3414        //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3415        if (rParameter (currRing) != NULL)
3416        {
3417          DefRingParlp();
3418        }
3419        else
3420        {
3421          VMrDefaultlp();
3422        }
3423
3424      F1 = idrMoveR(G, newRing,currRing);
3425      //Print("\n// Apply \"std\" in ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3426
3427      G = MstdCC(F1);
3428      idDelete(&F1);
3429      newRing = currRing;
3430    }
3431
3432    rChangeCurrRing(EXXRing);
3433    result = idrMoveR(G, newRing,currRing);
3434  }
3435  delete target_weight;
3436  delete last_omega;
3437  delete iv_lp;
3438
3439  if(Overflow_Error == FALSE)
3440  {
3441    Overflow_Error = nError;
3442  }
3443  return(result);
3444}
3445
3446/**********************************************************
3447 * check whether a polynomial of G has least 4 monomials  *
3448 **********************************************************/
3449static int lengthpoly(ideal G)
3450{
3451  int i;
3452  for(i=IDELEMS(G)-1; i>=0; i--)
3453  {
3454    if((G->m[i]!=NULL) /* len >=0 */
3455       && (G->m[i]->next!=NULL) /* len >=1 */
3456       && (G->m[i]->next->next!=NULL) /* len >=2 */
3457       && (G->m[i]->next->next->next!=NULL) /* len >=3 */
3458       && (G->m[i]->next->next->next->next!=NULL) /* len >=4*/ )
3459    {
3460      return 1;
3461    }
3462  }
3463  return 0;
3464}
3465
3466/*****************************************
3467 * return maximal polynomial length of G *
3468 *****************************************/
3469static int maxlengthpoly(ideal G)
3470{
3471  int i,k,length=0;
3472  for(i=IDELEMS(G)-1; i>=0; i--)
3473  {
3474    k = pLength(G->m[i]);
3475    if(k>length)
3476    {
3477      length = k;
3478    }
3479  }
3480  return length;
3481}
3482
3483/*********************************************************
3484 * check whether a polynomial of G has least 2 monomials *
3485**********************************************************/
3486static int islengthpoly2(ideal G)
3487{
3488  int i;
3489  for(i=IDELEMS(G)-1; i>=0; i--)
3490  {
3491    if((G->m[i]!=NULL) /* len >=0 */
3492       && (G->m[i]->next!=NULL) /* len >=1 */
3493       && (G->m[i]->next->next!=NULL)) /* len >=2 */
3494    {
3495      return 1;
3496    }
3497  }
3498  return 0;
3499}
3500
3501
3502
3503/* Implementation of the improved Groebner walk algorithm which is written
3504   by Quoc-Nam Tran (2000).
3505   One perturbs the original target weight vector, only if
3506   the next intermediate weight vector is equal to the current target weight
3507   vector. This must be repeated until the wanted reduced Groebner basis
3508   to reach.
3509   If the numbers of variables is big enough, the representation of the origin
3510   weight vector may be very big. Therefore, it is possible the intermediate
3511   weight vector doesn't stay in the correct Groebner cone.
3512   In this case we have just a reduced Groebner basis of the given ideal
3513   with respect to another monomial order. Then we have to compute
3514   a wanted reduced Groebner basis of it with respect to the given order.
3515   At the following subroutine we use the improved Buchberger algorithm or
3516   the changed perturbation walk algorithm with a decrased degree.
3517 */
3518
3519/***************************************
3520 * return the initial term of an ideal *
3521 ***************************************/
3522static ideal idHeadCC(ideal h)
3523{
3524  int i, nH =IDELEMS(h);
3525
3526  ideal m = idInit(nH,h->rank);
3527
3528  for (i=nH-1;i>=0; i--)
3529  {
3530    if (h->m[i]!=NULL)
3531    {
3532      m->m[i]=pHead(h->m[i]);
3533    }
3534  }
3535  return m;
3536}
3537
3538/**********************************************
3539 * check whether two head-ideals are the same *
3540 **********************************************/
3541static inline int test_G_GB_walk(ideal H0, ideal H1)
3542{
3543  int i, nG = IDELEMS(H0);
3544
3545  if(nG != IDELEMS(H1))
3546  {
3547    return 0;
3548  }
3549  for(i=nG-1; i>=0; i--)
3550  {
3551/*
3552    poly t;
3553    if((t=pSub(pCopy(H0->m[i]), pCopy(H1->m[i]))) != NULL)
3554    {
3555      pDelete(&t);
3556      return 0;
3557    }
3558    pDelete(&t);
3559*/
3560    if(!pEqualPolys(H0->m[i],H1->m[i]))
3561    {
3562      return 0;
3563    }
3564  }
3565  return 1;
3566}
3567
3568//unused
3569/*****************************************************
3570 * find the maximal total degree of polynomials in G *
3571 *****************************************************/
3572/*
3573static int Trandegreebound(ideal G)
3574{
3575  int i, nG = IDELEMS(G);
3576  // int np=1;
3577  int nV = currRing->N;
3578  int degtmp, result = 0;
3579  intvec* ivUnit = Mivdp(nV);
3580
3581  for(i=nG-1; i>=0; i--)
3582  {
3583    // find the maximal total degree of the polynomial G[i]
3584    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3585    if(degtmp > result)
3586    {
3587      result = degtmp;
3588    }
3589  }
3590  delete ivUnit;
3591  return result;
3592}
3593*/
3594
3595//unused
3596/************************************************************************
3597 * perturb the weight vector iva w.r.t. the ideal G.                    *
3598 *  the monomial order of the current ring is the w_1 weight lex. order *
3599 *  define w := d^(n-1)w_1+ d^(n-2)w_2, ...+ dw_(n-1)+ w_n              *
3600 *  where d := 1 + max{totdeg(g):g in G}*m, or                          *
3601 *  d := (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;                           *
3602 ************************************************************************/
3603#if 0
3604static intvec* TranPertVector(ideal G, intvec* iva)
3605{
3606  BOOLEAN nError = Overflow_Error;
3607  Overflow_Error = FALSE;
3608
3609  int i, j;
3610  // int nG = IDELEMS(G);
3611  int nV = currRing->N;
3612
3613  // define the sequence which expresses the current monomial ordering
3614  // w_1 = iva; w_2 = (1,0,..,0); w_n = (0,...,0,1,0)
3615  intvec* ivMat = MivMatrixOrder(iva);
3616
3617  int  mtmp, m=(*iva)[0];
3618
3619  for(i=ivMat->length(); i>=0; i--)
3620  {
3621    mtmp = (*ivMat)[i];
3622    if(mtmp <0)
3623    {
3624      mtmp = -mtmp;
3625    }
3626    if(mtmp > m)
3627    {
3628      m = mtmp;
3629    }
3630  }
3631
3632  // define the maximal total degree of polynomials of G
3633  mpz_t ndeg;
3634  mpz_init(ndeg);
3635
3636 // 12 Juli 03
3637#ifndef UPPER_BOUND
3638  mpz_set_si(ndeg, Trandegreebound(G)+1);
3639#else
3640  mpz_t ztmp;
3641  mpz_init(ztmp);
3642
3643  mpz_t maxdeg;
3644  mpz_init_set_si(maxdeg, Trandegreebound(G));
3645
3646  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;//Kalkbrenner (1999)
3647  mpz_pow_ui(ztmp, maxdeg, 2);
3648  mpz_mul_ui(ztmp, ztmp, 2);
3649  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3650  mpz_add(ndeg, ztmp, maxdeg);
3651  mpz_mul_ui(ndeg, ndeg, m);
3652
3653  mpz_clear(ztmp);
3654
3655  //PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3656  //Print("\n//         where d = %d, n = %d and bound = %d", maxdeg, nV, ndeg);
3657#endif //UPPER_BOUND
3658
3659#ifdef INVEPS_SMALL_IN_TRAN
3660  if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3661  {
3662    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3663  }
3664 //PrintS("\n// choose the \"small\" inverse epsilon:");
3665 //mpz_out_str(stdout, 10, ndeg);
3666#endif
3667  mpz_t deg_tmp;
3668  mpz_init_set(deg_tmp, ndeg);
3669
3670  mpz_t *ivres=( mpz_t *) omAlloc(nV*sizeof(mpz_t));
3671  mpz_init_set_si(ivres[nV-1],1);
3672
3673  for(i=nV-2; i>=0; i--)
3674  {
3675    mpz_init_set(ivres[i], deg_tmp);
3676    mpz_mul(deg_tmp, deg_tmp, ndeg);
3677  }
3678
3679  mpz_t *ivtmp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3680  for(i=0; i<nV; i++)
3681  {
3682    mpz_init(ivtmp[i]);
3683  }
3684  mpz_t sing_int;
3685  mpz_init_set_ui(sing_int,  2147483647);
3686
3687  intvec* repr_vector = new intvec(nV);
3688
3689  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3690  for(i=0; i<nV; i++)
3691  {
3692    for(j=0; j<nV; j++)
3693    {
3694      if( (*ivMat)[i*nV+j] >= 0 )
3695      {
3696        mpz_mul_ui(ivres[i], ivres[i], (*ivMat)[i*nV+j]);
3697      }
3698      else
3699      {
3700        mpz_mul_ui(ivres[i], ivres[i], -(*ivMat)[i*nV+j]);
3701        mpz_neg(ivres[i], ivres[i]);
3702      }
3703      mpz_add(ivtmp[j], ivtmp[j], ivres[i]);
3704    }
3705  }
3706  delete ivMat;
3707
3708  int ntrue=0;
3709  for(i=0; i<nV; i++)
3710  {
3711    (*repr_vector)[i] = mpz_get_si(ivtmp[i]);
3712    if(mpz_cmp(ivtmp[i], sing_int)>=0)
3713    {
3714      ntrue++;
3715      if(Overflow_Error == FALSE)
3716      {
3717        Overflow_Error = TRUE;
3718
3719        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3720        mpz_out_str( stdout, 10, ivtmp[i]);
3721        PrintS(" is greater than 2147483647 (max. integer representation)");
3722        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3723      }
3724    }
3725  }
3726  if(Overflow_Error == TRUE)
3727  {
3728    ivString(repr_vector, "repvector");
3729    Print("\n// %d element(s) of it are overflow!!", ntrue);
3730  }
3731
3732  if(Overflow_Error == FALSE)
3733    Overflow_Error=nError;
3734
3735  omFree(ivres);
3736  omFree(ivtmp);
3737
3738  mpz_clear(sing_int);
3739  mpz_clear(deg_tmp);
3740  mpz_clear(ndeg);
3741
3742  return repr_vector;
3743}
3744#endif
3745
3746//unused
3747#if 0
3748static intvec* TranPertVector_lp(ideal G)
3749{
3750  BOOLEAN nError = Overflow_Error;
3751  Overflow_Error = FALSE;
3752  // int j, nG = IDELEMS(G);
3753  int i;
3754  int nV = currRing->N;
3755
3756  // define the maximal total degree of polynomials of G
3757  mpz_t ndeg;
3758  mpz_init(ndeg);
3759
3760 // 12 Juli 03
3761#ifndef UPPER_BOUND
3762  mpz_set_si(ndeg, Trandegreebound(G)+1);
3763#else
3764  mpz_t ztmp;
3765  mpz_init(ztmp);
3766
3767  mpz_t maxdeg;
3768  mpz_init_set_si(maxdeg, Trandegreebound(G));
3769
3770  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg);//Kalkbrenner (1999)
3771  mpz_pow_ui(ztmp, maxdeg, 2);
3772  mpz_mul_ui(ztmp, ztmp, 2);
3773  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3774  mpz_add(ndeg, ztmp, maxdeg);
3775  // PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3776  // Print("\n//         where d = %d, n = %d and bound = %d",
3777  // mpz_get_si(maxdeg), nV, mpz_get_si(ndeg));
3778
3779 mpz_clear(ztmp);
3780
3781#endif
3782
3783#ifdef INVEPS_SMALL_IN_TRAN
3784 if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3785    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3786
3787 //PrintS("\n// choose the \"small\" inverse epsilon:");
3788 // mpz_out_str(stdout, 10, ndeg);
3789#endif
3790
3791  mpz_t deg_tmp;
3792  mpz_init_set(deg_tmp, ndeg);
3793
3794  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3795  mpz_init_set_si(ivres[nV-1], 1);
3796
3797  for(i=nV-2; i>=0; i--)
3798  {
3799    mpz_init_set(ivres[i], deg_tmp);
3800    mpz_mul(deg_tmp, deg_tmp, ndeg);
3801  }
3802
3803  mpz_t sing_int;
3804  mpz_init_set_ui(sing_int,  2147483647);
3805
3806  intvec* repr_vector = new intvec(nV);
3807  int ntrue=0;
3808  for(i=0; i<nV; i++)
3809  {
3810    (*repr_vector)[i] = mpz_get_si(ivres[i]);
3811
3812    if(mpz_cmp(ivres[i], sing_int)>=0)
3813    {
3814      ntrue++;
3815      if(Overflow_Error == FALSE)
3816      {
3817        Overflow_Error = TRUE;
3818        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3819        mpz_out_str( stdout, 10, ivres[i]);
3820        PrintS(" is greater than 2147483647 (max. integer representation)");
3821        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3822      }
3823    }
3824  }
3825  if(Overflow_Error == TRUE)
3826  {
3827    ivString(repr_vector, "repvector");
3828    Print("\n// %d element(s) of it are overflow!!", ntrue);
3829  }
3830  if(Overflow_Error == FALSE)
3831    Overflow_Error = nError;
3832
3833  omFree(ivres);
3834
3835  mpz_clear(ndeg);
3836  mpz_clear(sing_int);
3837
3838  return repr_vector;
3839}
3840#endif
3841
3842//unused
3843#if 0
3844static intvec* RepresentationMatrix_Dp(ideal G, intvec* M)
3845{
3846  BOOLEAN nError = Overflow_Error;
3847  Overflow_Error = FALSE;
3848
3849  int i, j;
3850  int nV = currRing->N;
3851
3852  intvec* ivUnit = Mivdp(nV);
3853  int degtmp, maxdeg = 0;
3854
3855  for(i=IDELEMS(G)-1; i>=0; i--)
3856  {
3857    // find the maximal total degree of the polynomial G[i]
3858    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3859    if(degtmp > maxdeg)
3860      maxdeg = degtmp;
3861  }
3862
3863  mpz_t ztmp;
3864  mpz_init_set_si(ztmp, maxdeg);
3865  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3866  mpz_init_set_si(ivres[nV-1], 1); // (*ivres)[nV-1] = 1;
3867
3868  for(i=nV-2; i>=0; i--)
3869  {
3870    mpz_init_set(ivres[i], ztmp); //(*ivres)[i] = ztmp;
3871    mpz_mul_ui(ztmp, ztmp, maxdeg); //ztmp *=maxdeg;
3872  }
3873
3874  mpz_t *ivtmp=(mpz_t*)omAlloc(nV*sizeof(mpz_t));
3875  for(i=0; i<nV; i++)
3876    mpz_init(ivtmp[i]);
3877
3878  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3879  for(i=0; i<nV; i++)
3880    for(j=0; j<nV; j++)
3881    {
3882      if((*M)[i*nV+j] < 0)
3883      {
3884        mpz_mul_ui(ztmp, ivres[i], -(*M)[i*nV+j]);
3885        mpz_neg(ztmp, ztmp);
3886      }
3887      else
3888        mpz_mul_ui(ztmp, ivres[i], (*M)[i*nV+j]);
3889
3890      mpz_add(ivtmp[j], ivtmp[j], ztmp);
3891    }
3892  delete ivres;
3893  mpz_t sing_int;
3894  mpz_init_set_ui(sing_int,  2147483647);
3895
3896  int ntrue=0;
3897  intvec* repvector = new intvec(nV);
3898  for(i=0; i<nV; i++)
3899  {
3900    (*repvector)[i] = mpz_get_si(ivtmp[i]);
3901    if(mpz_cmp(ivtmp[i], sing_int)>0)
3902    {
3903      ntrue++;
3904      if(Overflow_Error == FALSE)
3905      {
3906        Overflow_Error = TRUE;
3907        PrintS("\n// ** OVERFLOW in \"Repr.Matrix\": ");
3908        mpz_out_str( stdout, 10, ivtmp[i]);
3909        PrintS(" is greater than 2147483647 (max. integer representation)");
3910        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repvector)[i]);
3911      }
3912    }
3913  }
3914  if(Overflow_Error == TRUE)
3915  {
3916    ivString(repvector, "repvector");
3917    Print("\n// %d element(s) of it are overflow!!", ntrue);
3918  }
3919
3920  if(Overflow_Error == FALSE)
3921    Overflow_Error = nError;
3922
3923  mpz_clear(sing_int);
3924  mpz_clear(ztmp);
3925  omFree(ivtmp);
3926  omFree(ivres);
3927  return repvector;
3928}
3929#endif
3930
3931/*****************************************************************************
3932 * The following subroutine is the implementation of our first improved      *
3933 * Groebner walk algorithm, i.e. the first altervative algorithm.            *
3934 * First we use the Grobner walk algorithm and then we call the changed      *
3935 * perturbation walk algorithm with decreased degree, if an intermediate     *
3936 * weight vector is equal to the current target weight vector.               *
3937 * This call will be only repeated until we get the wanted reduced Groebner  *
3938 * basis or n times, where n is the numbers of variables.                    *
3939 *****************************************************************************/
3940
3941// npwinc = 0, if curr_weight doesn't stay in the correct Groebner cone
3942static ideal Rec_LastGB(ideal G, intvec* curr_weight,
3943                        intvec* orig_target_weight, int tp_deg, int npwinc)
3944{
3945  BOOLEAN nError = Overflow_Error;
3946  Overflow_Error = FALSE;
3947  // BOOLEAN nOverflow_Error = FALSE;
3948
3949#ifdef TIME_TEST
3950  clock_t tproc=0;
3951  clock_t tinput = clock();
3952#endif
3953
3954  int i,  nV = currRing->N;
3955  int nwalk=0, endwalks=0, nnwinC=1;
3956  int nlast = 0;
3957  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
3958  ring newRing, oldRing, TargetRing;
3959  intvec* iv_M_lp;
3960  intvec* target_weight;
3961  intvec* ivNull = new intvec(nV); //define (0,...,0)
3962  ring EXXRing = currRing;
3963  //int NEG=0; //19 juni 03
3964  intvec* next_weight;
3965#ifndef  BUCHBERGER_ALG
3966  //08 Juli 03
3967  intvec* hilb_func;
3968#endif
3969  // to avoid (1,0,...,0) as the target vector
3970  intvec* last_omega = new intvec(nV);
3971  for(i=nV-1; i>0; i--)
3972    (*last_omega)[i] = 1;
3973  (*last_omega)[0] = 10000;
3974
3975  BOOLEAN isGB = FALSE;
3976
3977  // compute a pertubed weight vector of the target weight vector
3978  if(tp_deg > 1 && tp_deg <= nV)
3979  {
3980    ideal H0 = idHeadCC(G);
3981
3982    if (rParameter (currRing) != NULL)
3983    {
3984      DefRingParlp();
3985    }
3986    else
3987    {
3988      VMrDefaultlp();
3989    }
3990    TargetRing = currRing;
3991    ssG = idrMoveR(G,EXXRing,currRing);
3992
3993    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
3994    ideal H1 = idHeadCC(ssG);
3995
3996    // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
3997    if(test_G_GB_walk(H0_tmp,H1)==1)
3998    {
3999      idDelete(&H0_tmp);
4000      idDelete(&H1);
4001      G = ssG;
4002      ssG = NULL;
4003      newRing = currRing;
4004      delete ivNull;
4005
4006      if(npwinc != 0)
4007      {
4008        goto LastGB_Finish;
4009      }
4010      else
4011      {
4012        isGB = TRUE;
4013        goto KSTD_Finish;
4014      }
4015    }
4016    idDelete(&H0_tmp);
4017    idDelete(&H1);
4018
4019    iv_M_lp = MivMatrixOrderlp(nV);
4020    target_weight  = MPertVectors(ssG, iv_M_lp, tp_deg);
4021    delete iv_M_lp;
4022    //PrintS("\n// Input is not GB!!");
4023    rChangeCurrRing(EXXRing);
4024    G = idrMoveR(ssG, TargetRing,currRing);
4025
4026    if(Overflow_Error == TRUE)
4027    {
4028      //nOverflow_Error = Overflow_Error;
4029      //NEG = 1;
4030      newRing = currRing;
4031      goto JUNI_STD;
4032    }
4033  }
4034
4035  while(1)
4036  {
4037    nwalk ++;
4038    nstep++;
4039
4040    if(nwalk==1)
4041    {
4042      goto FIRST_STEP;
4043    }
4044#ifdef TIME_TEST
4045    to=clock();
4046#endif
4047    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4048    Gomega = MwalkInitialForm(G, curr_weight);
4049#ifdef TIME_TEST
4050    xtif=xtif+clock()-to;
4051#endif
4052
4053#ifndef  BUCHBERGER_ALG
4054    if(isNolVector(curr_weight) == 0)
4055    {
4056      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4057    }
4058    else
4059    {
4060      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4061    }
4062#endif // BUCHBERGER_ALG
4063
4064    oldRing = currRing;
4065
4066    // defiNe a new ring that its ordering is "(a(curr_weight),lp)
4067    if (rParameter(currRing) != NULL)
4068    {
4069      DefRingPar(curr_weight);
4070    }
4071    else
4072    {
4073      rChangeCurrRing(VMrDefault(curr_weight));
4074    }
4075    newRing = currRing;
4076    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4077#ifdef TIME_TEST
4078    to=clock();
4079#endif
4080    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4081#ifdef  BUCHBERGER_ALG
4082    M = MstdhomCC(Gomega1);
4083#else
4084    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4085    delete hilb_func;
4086#endif // BUCHBERGER_ALG
4087#ifdef TIME_TEST
4088    xtstd=xtstd+clock()-to;
4089#endif
4090    // change the ring to oldRing
4091    rChangeCurrRing(oldRing);
4092    M1 =  idrMoveR(M, newRing,currRing);
4093    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4094
4095#ifdef TIME_TEST
4096     to=clock();
4097#endif
4098    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
4099    F = MLifttwoIdeal(Gomega2, M1, G);
4100#ifdef TIME_TEST
4101    xtlift=xtlift+clock()-to;
4102#endif
4103    idDelete(&M1);
4104    idDelete(&Gomega2);
4105    idDelete(&G);
4106
4107    // change the ring to newRing
4108    rChangeCurrRing(newRing);
4109    F1 = idrMoveR(F, oldRing,currRing);
4110
4111#ifdef TIME_TEST
4112    to=clock();
4113#endif
4114    // reduce the Groebner basis <G> w.r.t. new ring
4115    G = kInterRedCC(F1, NULL);
4116#ifdef TIME_TEST
4117    xtred=xtred+clock()-to;
4118#endif
4119    idDelete(&F1);
4120
4121    if(endwalks == 1)
4122    {
4123      break;
4124    }
4125  FIRST_STEP:
4126#ifdef TIME_TEST
4127    to=clock();
4128#endif
4129    Overflow_Error = FALSE;
4130    // compute a next weight vector
4131    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4132#ifdef TIME_TEST
4133    xtnw=xtnw+clock()-to;
4134#endif
4135#ifdef PRINT_VECTORS
4136    MivString(curr_weight, target_weight, next_weight);
4137#endif
4138    if(Overflow_Error == TRUE)
4139    {
4140      //PrintS("\n// ** The next vector does NOT stay in Cone!!\n");
4141#ifdef TEST_OVERFLOW
4142      goto  LastGB_Finish;
4143#endif
4144
4145      nnwinC = 0;
4146      if(tp_deg == nV)
4147      {
4148        nlast = 1;
4149      }
4150      delete next_weight;
4151      break;
4152    }
4153
4154    if(MivComp(next_weight, ivNull) == 1)
4155    {
4156      //newRing = currRing;
4157      delete next_weight;
4158      break;
4159    }
4160
4161    if(MivComp(next_weight, target_weight) == 1)
4162    {
4163      if(tp_deg == nV)
4164      {
4165        endwalks = 1;
4166      }
4167      else
4168      {
4169        // REC_LAST_GB_ALT2:
4170        //nOverflow_Error = Overflow_Error;
4171#ifdef TIME_TEST
4172        tproc=tproc+clock()-tinput;
4173#endif
4174
4175        /*Print("\n// takes %d steps and calls \"Rec_LastGB\" (%d):",
4176        nwalk, tp_deg+1);
4177        */
4178        G = Rec_LastGB(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4179        newRing = currRing;
4180        delete next_weight;
4181        break;
4182      }
4183    }
4184
4185    for(i=nV-1; i>=0; i--)
4186    {
4187      (*curr_weight)[i] = (*next_weight)[i];
4188    }
4189    delete next_weight;
4190  }//while
4191
4192  delete ivNull;
4193
4194  if(tp_deg != nV)
4195  {
4196    newRing = currRing;
4197
4198    if (rParameter(currRing) != NULL)
4199    {
4200      DefRingParlp();
4201    }
4202    else
4203    {
4204      VMrDefaultlp();
4205    }
4206    F1 = idrMoveR(G, newRing,currRing);
4207
4208    if(nnwinC == 0 || test_w_in_ConeCC(F1, target_weight) != 1 )
4209    {
4210      // nOverflow_Error = Overflow_Error;
4211      //Print("\n//  takes %d steps and calls \"Rec_LastGB (%d):", tp_deg+1);
4212#ifdef TIME_TEST
4213      tproc=tproc+clock()-tinput;
4214#endif
4215      F1 = Rec_LastGB(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4216    }
4217    delete target_weight;
4218
4219    TargetRing = currRing;
4220    rChangeCurrRing(EXXRing);
4221    result = idrMoveR(F1, TargetRing,currRing);
4222  }
4223  else
4224  {
4225    if(nlast == 1)
4226    {
4227      JUNI_STD:
4228
4229      newRing = currRing;
4230      if (rParameter(currRing) != NULL)
4231      {
4232        DefRingParlp();
4233      }
4234      else
4235      {
4236        VMrDefaultlp();
4237      }
4238      KSTD_Finish:
4239      if(isGB == FALSE)
4240      {
4241        F1 = idrMoveR(G, newRing,currRing);
4242      }
4243      else
4244      {
4245        F1 = G;
4246      }
4247#ifdef TIME_TEST
4248      to=clock();
4249#endif
4250      // Print("\n// apply the Buchberger's alg in ring = %s",rString(currRing));
4251      // idElements(F1, "F1");
4252      G = MstdCC(F1);
4253#ifdef TIME_TEST
4254      xtextra=xtextra+clock()-to;
4255#endif
4256
4257
4258      idDelete(&F1);
4259      newRing = currRing;
4260    }
4261
4262    LastGB_Finish:
4263    rChangeCurrRing(EXXRing);
4264    result = idrMoveR(G, newRing,currRing);
4265  }
4266
4267  if(Overflow_Error == FALSE)
4268    {
4269    Overflow_Error=nError;
4270    }
4271#ifdef TIME_TEST
4272   //Print("\n// \"Rec_LastGB\" (%d) took %d steps and %.2f sec.Overflow_Error (%d)", tp_deg, nwalk, ((double) tproc)/1000000, nOverflow_Error);
4273#endif
4274  return(result);
4275}
4276
4277/* The following subroutine is the implementation of our second improved
4278   Groebner walk algorithm, i.e. the second altervative algorithm.
4279   First we use the Grobner walk algorithm and then we call the changed
4280   perturbation walk algorithm with increased degree, if an intermediate
4281   weight vector is equal to the current target weight vector.
4282   This call will be only repeated until we get the wanted reduced Groebner
4283   basis or n times, where n is the numbers of variables.
4284*/
4285
4286/******************************
4287 * walk + recursive LastGB    *
4288 ******************************/
4289ideal MAltwalk2(ideal Go, intvec* curr_weight, intvec* target_weight)
4290{
4291  Set_Error(FALSE);
4292  Overflow_Error = FALSE;
4293  //BOOLEAN nOverflow_Error = FALSE;
4294  //Print("// pSetm_Error = (%d)", ErrorCheck());
4295#ifdef TIME_TEST
4296  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
4297  xftinput = clock();
4298  clock_t tostd, tproc;
4299#endif
4300  nstep = 0;
4301  int i, nV = currRing->N;
4302  int nwalk=0, endwalks=0;
4303  // int nhilb = 1;
4304  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
4305  //ideal  G1;
4306  //ring endRing;
4307  ring newRing, oldRing;
4308  intvec* ivNull = new intvec(nV);
4309  intvec* next_weight;
4310  //intvec* extra_curr_weight = new intvec(nV);
4311  //intvec* hilb_func;
4312  intvec* exivlp = Mivlp(nV);
4313  ring XXRing = currRing;
4314
4315  //Print("\n// ring r_input = %s;", rString(currRing));
4316#ifdef TIME_TEST
4317  to = clock();
4318#endif
4319  /* compute the reduced Groebner basis of the given ideal w.r.t.
4320     a "fast" monomial order, e.g. degree reverse lex. order (dp) */
4321  G = MstdCC(Go);
4322#ifdef TIME_TEST
4323  tostd=clock()-to;
4324
4325  Print("\n// Computation of the first std took = %.2f sec",
4326        ((double) tostd)/1000000);
4327#endif
4328  if(currRing->order[0] == ringorder_a)
4329  {
4330    goto NEXT_VECTOR;
4331  }
4332  while(1)
4333  {
4334    nwalk ++;
4335    nstep ++;
4336#ifdef TIME_TEST
4337    to = clock();
4338#endif
4339    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
4340    Gomega = MwalkInitialForm(G, curr_weight);
4341#ifdef TIME_TEST
4342    xtif=xtif+clock()-to;
4343#endif
4344/*
4345    if(Overflow_Error == TRUE)
4346    {
4347      for(i=nV-1; i>=0; i--)
4348        (*curr_weight)[i] = (*extra_curr_weight)[i];
4349      delete extra_curr_weight;
4350      goto LAST_GB_ALT2;
4351    }
4352*/
4353    oldRing = currRing;
4354
4355    /* define a new ring that its ordering is "(a(curr_weight),lp) */
4356    if (rParameter(currRing) != NULL)
4357    {
4358      DefRingPar(curr_weight);
4359    }
4360    else
4361    {
4362      rChangeCurrRing(VMrDefault(curr_weight));
4363    }
4364    newRing = currRing;
4365    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4366#ifdef TIME_TEST
4367    to = clock();
4368#endif
4369    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
4370    M = MstdhomCC(Gomega1);
4371#ifdef TIME_TEST
4372    xtstd=xtstd+clock()-to;
4373#endif
4374    /* change the ring to oldRing */
4375    rChangeCurrRing(oldRing);
4376    M1 =  idrMoveR(M, newRing,currRing);
4377    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4378#ifdef TIME_TEST
4379    to = clock();
4380#endif
4381    /* compute the reduced Groebner basis of <G> w.r.t. "newRing"
4382       by the liftig process */
4383    F = MLifttwoIdeal(Gomega2, M1, G);
4384#ifdef TIME_TEST
4385    xtlift=xtlift+clock()-to;
4386#endif
4387    idDelete(&M1);
4388    idDelete(&Gomega2);
4389    idDelete(&G);
4390
4391    /* change the ring to newRing */
4392    rChangeCurrRing(newRing);
4393    F1 = idrMoveR(F, oldRing,currRing);
4394#ifdef TIME_TEST
4395    to = clock();
4396#endif
4397    /* reduce the Groebner basis <G> w.r.t. newRing */
4398    G = kInterRedCC(F1, NULL);
4399#ifdef TIME_TEST
4400    xtred=xtred+clock()-to;
4401#endif
4402    idDelete(&F1);
4403
4404    if(endwalks == 1)
4405      break;
4406
4407  NEXT_VECTOR:
4408#ifdef TIME_TEST
4409    to = clock();
4410#endif
4411    /* compute a next weight vector */
4412    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4413#ifdef TIME_TEST
4414    xtnw=xtnw+clock()-to;
4415#endif
4416#ifdef PRINT_VECTORS
4417    MivString(curr_weight, target_weight, next_weight);
4418#endif
4419
4420    if(Overflow_Error == TRUE)
4421    {
4422      /*
4423        ivString(next_weight, "omega");
4424        PrintS("\n// ** The weight vector does NOT stay in Cone!!\n");
4425      */
4426#ifdef TEST_OVERFLOW
4427      goto  TEST_OVERFLOW_OI;
4428#endif
4429
4430      newRing = currRing;
4431      if (rParameter(currRing) != NULL)
4432      {
4433        DefRingPar(target_weight);
4434      }
4435      else
4436      {
4437        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
4438      }
4439      F1 = idrMoveR(G, newRing,currRing);
4440      G = MstdCC(F1);
4441      idDelete(&F1);
4442      newRing = currRing;
4443      break;
4444    }
4445
4446    if(MivComp(next_weight, ivNull) == 1)
4447    {
4448      newRing = currRing;
4449      delete next_weight;
4450      break;
4451    }
4452
4453    if(MivComp(next_weight, target_weight) == 1)
4454    {
4455      if(MivSame(target_weight, exivlp)==1)
4456      {
4457     // LAST_GB_ALT2:
4458        //nOverflow_Error = Overflow_Error;
4459#ifdef TIME_TEST
4460        tproc = clock()-xftinput;
4461#endif
4462        //Print("\n// takes %d steps and calls the recursion of level 2:",  nwalk);
4463        /* call the changed perturbation walk algorithm with degree 2 */
4464        G = Rec_LastGB(G, curr_weight, target_weight, 2,1);
4465        newRing = currRing;
4466        delete next_weight;
4467        break;
4468      }
4469      endwalks = 1;
4470    }
4471
4472    for(i=nV-1; i>=0; i--)
4473    {
4474      //(*extra_curr_weight)[i] = (*curr_weight)[i];
4475      (*curr_weight)[i] = (*next_weight)[i];
4476    }
4477    delete next_weight;
4478  }
4479#ifdef TEST_OVERFLOW
4480 TEST_OVERFLOW_OI:
4481#endif
4482  rChangeCurrRing(XXRing);
4483  G = idrMoveR(G, newRing,currRing);
4484  delete ivNull;
4485  delete exivlp;
4486
4487#ifdef TIME_TEST
4488  /*Print("\n// \"Main procedure\"  took %d steps dnd %.2f sec. Overflow_Error (%d)",
4489        nwalk, ((double) tproc)/1000000, nOverflow_Error);
4490*/
4491  TimeStringFractal(xftinput, tostd, xtif, xtstd, xtextra,xtlift, xtred,xtnw);
4492
4493  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
4494  //Print("\n// Overflow_Error? (%d)", nOverflow_Error);
4495  //Print("\n// Awalk2 took %d steps!!", nstep);
4496#endif
4497
4498  return(G);
4499}
4500
4501
4502/**************************************
4503 * perturb the matrix order of  "lex" *
4504 **************************************/
4505static intvec* NewVectorlp(ideal I)
4506{
4507  int nV = currRing->N;
4508  intvec* iv_wlp =  MivMatrixOrderlp(nV);
4509  intvec* result = Mfpertvector(I, iv_wlp);
4510  delete iv_wlp;
4511  return result;
4512}
4513
4514int ngleich;
4515intvec* Xsigma;
4516intvec* Xtau;
4517int xn;
4518intvec* Xivinput;
4519intvec* Xivlp;
4520
4521
4522/********************************
4523 * compute a next weight vector *
4524 ********************************/
4525static intvec* MWalkRandomNextWeight(ideal G, intvec* orig_M, intvec* target_weight,
4526       int weight_rad, int pert_deg)
4527{
4528  assume(currRing != NULL && orig_M != NULL &&
4529         target_weight != NULL && G->m[0] != NULL);
4530
4531  //BOOLEAN nError = Overflow_Error;
4532  Overflow_Error = FALSE;
4533
4534  BOOLEAN found_random_weight = FALSE;
4535  int i,nV = currRing->N;
4536  intvec* curr_weight = new intvec(nV);
4537
4538  for(i=0; i<nV; i++)
4539  {
4540    (*curr_weight)[i] = (*orig_M)[i];
4541  }
4542
4543  int k=0,weight_norm;
4544  intvec* next_weight;
4545  intvec* next_weight1 = MkInterRedNextWeight(curr_weight,target_weight,G);
4546  intvec* next_weight2 = new intvec(nV);
4547  intvec* result = new intvec(nV);
4548  intvec* curr_weight1;
4549  ideal G_test, G_test1, G_test2;
4550
4551  //try to find a random next weight vector "next_weight2"
4552  if(weight_rad > 0)
4553  {
4554    while(k<10)
4555    {
4556      weight_norm = 0;
4557      while(weight_norm == 0)
4558      {
4559        for(i=0; i<nV; i++)
4560        {
4561          (*next_weight2)[i] = rand() % 60000 - 30000;
4562          weight_norm = weight_norm + (*next_weight2)[i]*(*next_weight2)[i];
4563        }
4564        weight_norm = 1 + floor(sqrt(weight_norm));
4565      }
4566      for(i=0; i<nV; i++)
4567      {
4568        if((*next_weight2)[i] < 0)
4569        {
4570          (*next_weight2)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4571        }
4572        else
4573        {
4574          (*next_weight2)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4575        }
4576      }
4577      if(test_w_in_ConeCC(G,next_weight2) == 1)
4578      {
4579        if(maxlengthpoly(MwalkInitialForm(G,next_weight2))<2)
4580        {
4581          next_weight2 = MkInterRedNextWeight(next_weight2,target_weight,G);
4582        }
4583        G_test2 = MwalkInitialForm(G, next_weight2);
4584        found_random_weight = TRUE;
4585        break;
4586      }
4587      k++;
4588    }
4589  }
4590
4591  // compute "perturbed" next weight vector
4592  if(pert_deg > 1)
4593  {
4594    curr_weight1 = MPertVectors(G,orig_M,pert_deg);
4595    next_weight = MkInterRedNextWeight(curr_weight1,target_weight,G);
4596    delete curr_weight1;
4597  }
4598  else
4599  {
4600    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4601  }
4602  if(MivSame(curr_weight,next_weight)==1 || Overflow_Error == TRUE)
4603  {
4604    Overflow_Error = FALSE;
4605    delete next_weight;
4606    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4607  }
4608  G_test=MwalkInitialForm(G,next_weight);
4609  G_test1=MwalkInitialForm(G,next_weight1);
4610
4611  // compare next weights
4612  if(Overflow_Error == FALSE)
4613  {
4614    if(found_random_weight == TRUE)
4615    {
4616    // random next weight vector found
4617      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4618      {
4619        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test1))
4620        {
4621          for(i=0; i<nV; i++)
4622          {
4623            (*result)[i] = (*next_weight2)[i];
4624          }
4625        }
4626        else
4627        {
4628          for(i=0; i<nV; i++)
4629          {
4630            (*result)[i] = (*next_weight1)[i];
4631          }
4632        }
4633      }
4634      else
4635      {
4636        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4637        {
4638          for(i=0; i<nV; i++)
4639          {
4640            (*result)[i] = (*next_weight2)[i];
4641          }
4642        }
4643        else
4644        {
4645          for(i=0; i<nV; i++)
4646          {
4647            (*result)[i] = (*next_weight)[i];
4648          }
4649        }
4650      }
4651    }
4652    else
4653    {
4654      // no random next weight vector found
4655      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4656      {
4657       for(i=0; i<nV; i++)
4658        {
4659          (*result)[i] = (*next_weight1)[i];
4660        }
4661      }
4662      else
4663      {
4664        for(i=0; i<nV; i++)
4665        {
4666          (*result)[i] = (*next_weight)[i];
4667        }
4668      }
4669    }
4670  }
4671  else
4672  {
4673    Overflow_Error = FALSE;
4674    if(found_random_weight == TRUE)
4675    {
4676      if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4677      {
4678        for(i=1; i<nV; i++)
4679        {
4680          (*result)[i] = (*next_weight2)[i];
4681        }
4682      }
4683      else
4684      {
4685        for(i=0; i<nV; i++)
4686        {
4687          (*result)[i] = (*next_weight)[i];
4688        }
4689      }
4690    }
4691    else
4692    {
4693      for(i=0; i<nV; i++)
4694      {
4695        (*result)[i] = (*next_weight)[i];
4696      }
4697    }
4698  }
4699
4700  delete next_weight;
4701  delete next_weight2;
4702  idDelete(&G_test);
4703  idDelete(&G_test1);
4704  if(found_random_weight == TRUE)
4705  {
4706    idDelete(&G_test2);
4707  }
4708  if(test_w_in_ConeCC(G, result) == 1 && MivSame(curr_weight,result)==0)
4709  {
4710    delete curr_weight;
4711    delete next_weight1;
4712    return result;
4713  }
4714  else
4715  {
4716    delete curr_weight;
4717    delete result;
4718    return next_weight1;
4719  }
4720}
4721
4722
4723/***************************************************************************
4724 * The procedur REC_GB_Mwalk computes a GB for <G> w.r.t. the weight order *
4725 * otw, where G is a reduced GB w.r.t. the weight order cw.                *
4726 * The new procedure Mwalk calls REC_GB.                                   *
4727 ***************************************************************************/
4728static ideal REC_GB_Mwalk(ideal G, intvec* curr_weight, intvec* orig_target_weight,
4729                          int tp_deg, int npwinc)
4730{
4731  BOOLEAN nError = Overflow_Error;
4732  Overflow_Error = FALSE;
4733
4734  int i,  nV = currRing->N;
4735  int nwalk=0, endwalks=0, nnwinC=1, nlast = 0;
4736  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4737  ring newRing, oldRing, TargetRing;
4738  intvec* target_weight;
4739  intvec* ivNull = new intvec(nV);
4740#ifndef BUCHBERGER_ALG
4741  intvec* hilb_func;
4742  // to avoid (1,0,...,0) as the target vector
4743  intvec* last_omega = new intvec(nV);
4744  for(i=nV-1; i>0; i--)
4745  {
4746    (*last_omega)[i] = 1;
4747  }
4748  (*last_omega)[0] = 10000;
4749#endif
4750  BOOLEAN isGB = FALSE;
4751
4752  ring EXXRing = currRing;
4753
4754  // compute a pertubed weight vector of the target weight vector
4755  if(tp_deg > 1 && tp_deg <= nV)
4756  {
4757    ideal H0 = idHeadCC(G);
4758    if (rParameter(currRing) != NULL)
4759    {
4760      DefRingPar(orig_target_weight);
4761    }
4762    else
4763    {
4764      rChangeCurrRing(VMrDefault(orig_target_weight));
4765    }
4766    TargetRing = currRing;
4767    ssG = idrMoveR(G,EXXRing,currRing);
4768
4769    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4770    ideal H1 = idHeadCC(ssG);
4771    id_Delete(&H0,EXXRing);
4772
4773    if(test_G_GB_walk(H0_tmp,H1)==1)
4774    {
4775      //Print("\n//REC_GB_Mwalk: input in %d-th recursive is a GB!\n",tp_deg);
4776      idDelete(&H0_tmp);
4777      idDelete(&H1);
4778      G = ssG;
4779      ssG = NULL;
4780      newRing = currRing;
4781      delete ivNull;
4782      if(npwinc == 0)
4783      {
4784        isGB = TRUE;
4785        goto KSTD_Finish;
4786      }
4787      else
4788      {
4789        goto LastGB_Finish;
4790      }
4791    }
4792    idDelete(&H0_tmp);
4793    idDelete(&H1);
4794
4795    target_weight  = MPertVectors(ssG, MivMatrixOrder(orig_target_weight), tp_deg);
4796
4797    rChangeCurrRing(EXXRing);
4798    G = idrMoveR(ssG, TargetRing,currRing);
4799  }
4800
4801  while(1)
4802  {
4803    nwalk ++;
4804    nstep++;
4805    if(nwalk == 1)
4806    {
4807      goto NEXT_STEP;
4808    }
4809    //Print("\n//REC_GB_Mwalk: Entering the %d-th step in the %d-th recursive:\n",nwalk,tp_deg);
4810#ifdef TIME_TEST
4811    to = clock();
4812#endif
4813    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4814    Gomega = MwalkInitialForm(G, curr_weight);
4815#ifdef TIME_TEST
4816    xtif = xtif + clock()-to;
4817#endif
4818
4819#ifndef  BUCHBERGER_ALG
4820    if(isNolVector(curr_weight) == 0)
4821    {
4822      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4823    }
4824    else
4825    {
4826      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4827    }
4828#endif
4829
4830    oldRing = currRing;
4831
4832    // define a new ring with ordering "(a(curr_weight),lp)
4833    if (rParameter(currRing) != NULL)
4834    {
4835      DefRingPar(curr_weight);
4836    }
4837    else
4838    {
4839      rChangeCurrRing(VMrDefault(curr_weight));
4840    }
4841    newRing = currRing;
4842    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4843
4844#ifdef TIME_TEST
4845    to = clock();
4846#endif
4847    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4848#ifdef  BUCHBERGER_ALG
4849    M = MstdhomCC(Gomega1);
4850#else
4851    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4852    delete hilb_func;
4853#endif
4854#ifdef TIME_TEST
4855    xtstd = xtstd + clock() - to;
4856#endif
4857
4858    // change the ring to oldRing
4859    rChangeCurrRing(oldRing);
4860
4861    M1 =  idrMoveR(M, newRing,currRing);
4862    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4863
4864#ifdef TIME_TEST
4865    to = clock();
4866#endif
4867    F = MLifttwoIdeal(Gomega2, M1, G);
4868#ifdef TIME_TEST
4869    xtlift = xtlift + clock() -to;
4870#endif
4871
4872    idDelete(&M1);
4873    idDelete(&Gomega2);
4874    idDelete(&G);
4875
4876
4877    // change the ring to newRing
4878    rChangeCurrRing(newRing);
4879    F1 = idrMoveR(F, oldRing,currRing);
4880
4881#ifdef TIME_TEST
4882    to = clock();
4883#endif
4884    // reduce the Groebner basis <G> w.r.t. new ring
4885    G = kInterRedCC(F1, NULL);
4886#ifdef TIME_TEST
4887    xtred = xtred + clock() -to;
4888#endif
4889
4890    idDelete(&F1);
4891
4892    if(endwalks == 1)
4893    {
4894      break;
4895    }
4896  NEXT_STEP:
4897#ifdef TIME_TEST
4898    to = clock();
4899#endif
4900    // compute a next weight vector
4901    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4902
4903
4904#ifdef TIME_TEST
4905    xtnw = xtnw + clock() - to;
4906#endif
4907
4908#ifdef PRINT_VECTORS
4909    MivString(curr_weight, target_weight, next_weight);
4910#endif
4911
4912    if(Overflow_Error == TRUE)
4913    {
4914      //PrintS("\n//REC_GB_Mwalk: The computed vector does NOT stay in the correct cone!!\n");
4915      nnwinC = 0;
4916      if(tp_deg == nV)
4917      {
4918        nlast = 1;
4919      }
4920      delete next_weight;
4921      break;
4922    }
4923    if(MivComp(next_weight, ivNull) == 1)
4924    {
4925      newRing = currRing;
4926      delete next_weight;
4927      break;
4928    }
4929
4930    if(MivComp(next_weight, target_weight) == 1)
4931    {
4932      if(tp_deg == nV)
4933      {
4934        endwalks = 1;
4935      }
4936      else
4937      {
4938        G = REC_GB_Mwalk(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4939        newRing = currRing;
4940        delete next_weight;
4941        break;
4942      }
4943    }
4944
4945    for(i=nV-1; i>=0; i--)
4946    {
4947      (*curr_weight)[i] = (*next_weight)[i];
4948    }
4949    delete next_weight;
4950  }
4951
4952  delete ivNull;
4953
4954  if(tp_deg != nV)
4955  {
4956    newRing = currRing;
4957
4958    if (rParameter(currRing) != NULL)
4959    {
4960      DefRingPar(orig_target_weight);
4961    }
4962    else
4963    {
4964      rChangeCurrRing(VMrDefault(orig_target_weight));
4965    }
4966    F1 = idrMoveR(G, newRing,currRing);
4967
4968    if(nnwinC == 0)
4969    {
4970      F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4971    }
4972    else
4973    {
4974      if(test_w_in_ConeCC(F1, target_weight) != 1)
4975      {
4976        F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight,tp_deg+1,nnwinC);
4977      }
4978    }
4979    delete target_weight;
4980
4981    TargetRing = currRing;
4982    rChangeCurrRing(EXXRing);
4983    result = idrMoveR(F1, TargetRing,currRing);
4984  }
4985  else
4986  {
4987    if(nlast == 1)
4988    {
4989      if (rParameter(currRing) != NULL)
4990      {
4991        DefRingPar(orig_target_weight);
4992      }
4993      else
4994      {
4995        rChangeCurrRing(VMrDefault(orig_target_weight));
4996      }
4997    KSTD_Finish:
4998      if(isGB == FALSE)
4999      {
5000        F1 = idrMoveR(G, newRing,currRing);
5001      }
5002      else
5003      {
5004        F1 = G;
5005      }
5006#ifdef TIME_TEST
5007      to=clock();
5008#endif
5009      // apply Buchberger alg to compute a red. GB of F1
5010      G = MstdCC(F1);
5011#ifdef TIME_TEST
5012      xtextra=clock()-to;
5013#endif
5014      idDelete(&F1);
5015      newRing = currRing;
5016    }
5017
5018  LastGB_Finish:
5019    rChangeCurrRing(EXXRing);
5020    result = idrMoveR(G, newRing,currRing);
5021  }
5022
5023  if(Overflow_Error == FALSE)
5024    {
5025    Overflow_Error = nError;
5026    }
5027#ifndef BUCHBERGER_ALG
5028  delete last_omega;
5029#endif
5030  return(result);
5031}
5032
5033
5034// THE NEW GROEBNER WALK ALGORITHM
5035// Groebnerwalk with a recursive "second" alternative GW, called REC_GB_Mwalk that only computes the last reduced GB
5036ideal MwalkAlt(ideal Go, intvec* curr_weight, intvec* target_weight)
5037{
5038  Set_Error(FALSE);
5039  Overflow_Error = FALSE;
5040  //Print("// pSetm_Error = (%d)", ErrorCheck());
5041
5042#ifdef TIME_TEST
5043  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5044  tinput = clock();
5045  clock_t tim;
5046  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5047#endif
5048  nstep=0;
5049  int i;
5050  int nV = currRing->N;
5051  int nwalk=0;
5052  int endwalks=0;
5053
5054  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
5055
5056  ring newRing, oldRing;
5057  intvec* ivNull = new intvec(nV);
5058  intvec* exivlp = Mivlp(nV);
5059#ifndef BUCHBERGER_ALG
5060  intvec* hilb_func;
5061#endif
5062  intvec* tmp_weight = new intvec(nV);
5063  for(i=nV-1; i>=0; i--)
5064    (*tmp_weight)[i] = (*curr_weight)[i];
5065
5066   // to avoid (1,0,...,0) as the target vector
5067  intvec* last_omega = new intvec(nV);
5068  for(i=nV-1; i>0; i--)
5069    (*last_omega)[i] = 1;
5070  (*last_omega)[0] = 10000;
5071
5072  ring XXRing = currRing;
5073
5074#ifdef TIME_TEST
5075  to = clock();
5076#endif
5077  // the monomial ordering of this current ring would be "dp"
5078  G = MstdCC(Go);
5079#ifdef TIME_TEST
5080  tostd = clock()-to;
5081#endif
5082
5083  if(currRing->order[0] == ringorder_a)
5084    goto NEXT_VECTOR;
5085
5086  while(1)
5087  {
5088    nwalk ++;
5089    nstep ++;
5090#ifdef TIME_TEST
5091    to = clock();
5092#endif
5093    // compute an initial form ideal of <G> w.r.t. "curr_vector"
5094    Gomega = MwalkInitialForm(G, curr_weight);
5095#ifdef TIME_TEST
5096    tif = tif + clock()-to;
5097#endif
5098    oldRing = currRing;
5099
5100    if(endwalks == 1)
5101    {
5102      /* compute a reduced Groebner basis of Gomega w.r.t. >>_cw by
5103         the recursive changed perturbation walk alg. */
5104#ifdef TIME_TEST
5105      tim = clock();
5106#endif
5107#ifdef CHECK_IDEAL_MWALK
5108        Print("\n// **** Groebnerwalk took %d steps and ", nwalk);
5109        PrintS("\n// **** call the rec. Pert. Walk to compute a red GB of:");
5110        idString(Gomega, "Gomega");
5111#endif
5112
5113      if(MivSame(exivlp, target_weight)==1)
5114        M = REC_GB_Mwalk(idCopy(Gomega), tmp_weight, curr_weight, 2,1);
5115      else
5116        goto NORMAL_GW;
5117#ifdef TIME_TEST
5118        Print("\n//  time for the last std(Gw)  = %.2f sec",
5119        ((double) (clock()-tim)/1000000));
5120#endif
5121/*
5122#ifdef CHECK_IDEAL_MWALK
5123      idElements(Gomega, "G_omega");
5124      headidString(Gomega, "Gw");
5125      idElements(M, "M");
5126      //headidString(M, "M");
5127#endif
5128*/
5129#ifdef TIME_TEST
5130      to = clock();
5131#endif
5132      F = MLifttwoIdeal(Gomega, M, G);
5133#ifdef TIME_TEST
5134      xtlift = xtlift + clock() - to;
5135#endif
5136
5137      idDelete(&Gomega);
5138      idDelete(&M);
5139      idDelete(&G);
5140
5141      oldRing = currRing;
5142
5143      // create a new ring newRing
5144       if (rParameter(currRing) != NULL)
5145       {
5146         DefRingPar(curr_weight);
5147       }
5148       else
5149       {
5150         rChangeCurrRing(VMrDefault(curr_weight));
5151       }
5152      newRing = currRing;
5153      F1 = idrMoveR(F, oldRing,currRing);
5154    }
5155    else
5156    {
5157    NORMAL_GW:
5158#ifndef  BUCHBERGER_ALG
5159      if(isNolVector(curr_weight) == 0)
5160      {
5161        hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5162      }
5163      else
5164      {
5165        hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5166      }
5167#endif // BUCHBERGER_ALG
5168
5169      // define a new ring that its ordering is "(a(curr_weight),lp)
5170      if (rParameter(currRing) != NULL)
5171      {
5172        DefRingPar(curr_weight);
5173      }
5174      else
5175      {
5176        rChangeCurrRing(VMrDefault(curr_weight));
5177      }
5178      newRing = currRing;
5179      Gomega1 = idrMoveR(Gomega, oldRing,currRing);
5180
5181#ifdef TIME_TEST
5182      to = clock();
5183#endif
5184      // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5185#ifdef  BUCHBERGER_ALG
5186      M = MstdhomCC(Gomega1);
5187#else
5188      M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5189      delete hilb_func;
5190#endif
5191#ifdef TIME_TEST
5192      tstd = tstd + clock() - to;
5193#endif
5194
5195      // change the ring to oldRing
5196      rChangeCurrRing(oldRing);
5197      M1 =  idrMoveR(M, newRing,currRing);
5198      Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
5199
5200#ifdef TIME_TEST
5201      to = clock();
5202#endif
5203      // compute a representation of the generators of submod (M) with respect
5204      // to those of mod (Gomega).
5205      // Gomega is a reduced Groebner basis w.r.t. the current ring.
5206      F = MLifttwoIdeal(Gomega2, M1, G);
5207#ifdef TIME_TEST
5208      tlift = tlift + clock() - to;
5209#endif
5210
5211      idDelete(&M1);
5212      idDelete(&Gomega2);
5213      idDelete(&G);
5214
5215      // change the ring to newRing
5216      rChangeCurrRing(newRing);
5217      F1 = idrMoveR(F, oldRing,currRing);
5218    }
5219
5220#ifdef TIME_TEST
5221    to = clock();
5222#endif
5223    // reduce the Groebner basis <G> w.r.t. new ring
5224    G = kInterRedCC(F1, NULL);
5225#ifdef TIME_TEST
5226    if(endwalks != 1)
5227    {
5228      tred = tred + clock() - to;
5229    }
5230    else
5231    {
5232      xtred = xtred + clock() - to;
5233    }
5234#endif
5235    idDelete(&F1);
5236    if(endwalks == 1)
5237    {
5238      break;
5239    }
5240  NEXT_VECTOR:
5241#ifdef TIME_TEST
5242    to = clock();
5243#endif
5244    // compute a next weight vector
5245    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
5246#ifdef TIME_TEST
5247    tnw = tnw + clock() - to;
5248#endif
5249#ifdef PRINT_VECTORS
5250    MivString(curr_weight, target_weight, next_weight);
5251#endif
5252
5253    //if(test_w_in_ConeCC(G, next_weight) != 1)
5254    if(Overflow_Error == TRUE)
5255    {
5256      newRing = currRing;
5257      PrintS("\n// ** The computed vector does NOT stay in Cone!!\n");
5258
5259      if (rParameter(currRing) != NULL)
5260      {
5261        DefRingPar(target_weight);
5262      }
5263      else
5264      {
5265        rChangeCurrRing(VMrDefault(target_weight));
5266      }
5267      F1 = idrMoveR(G, newRing,currRing);
5268      G = MstdCC(F1);
5269      idDelete(&F1);
5270
5271      newRing = currRing;
5272      break;
5273    }
5274
5275    if(MivComp(next_weight, ivNull) == 1)
5276    {
5277      newRing = currRing;
5278      delete next_weight;
5279      break;
5280    }
5281    if(MivComp(next_weight, target_weight) == 1)
5282    {
5283      endwalks = 1;
5284    }
5285    for(i=nV-1; i>=0; i--)
5286    {
5287      (*tmp_weight)[i] = (*curr_weight)[i];
5288      (*curr_weight)[i] = (*next_weight)[i];
5289    }
5290    delete next_weight;
5291  }
5292  rChangeCurrRing(XXRing);
5293  G = idrMoveR(G, newRing,currRing);
5294
5295  delete tmp_weight;
5296  delete ivNull;
5297  delete exivlp;
5298
5299#ifdef TIME_TEST
5300  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5301
5302  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5303  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5304#endif
5305  return(G);
5306}
5307
5308/*******************************
5309 * THE GROEBNER WALK ALGORITHM *
5310 *******************************/
5311ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M,
5312            ring baseRing, int reduction, int printout)
5313{
5314  // save current options
5315  BITSET save1 = si_opt_1;
5316  if(reduction == 0)
5317  {
5318    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5319    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5320  }
5321  Set_Error(FALSE);
5322  Overflow_Error = FALSE;
5323  //BOOLEAN endwalks = FALSE;
5324#ifdef TIME_TEST
5325  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5326  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5327  tinput = clock();
5328  clock_t tim;
5329#endif
5330  nstep=0;
5331  int i,nwalk;
5332  int nV = baseRing->N;
5333
5334  ideal Gomega, M, F, FF, Gomega1, Gomega2, M1;
5335  ring newRing;
5336  ring XXRing = baseRing;
5337  ring targetRing;
5338  intvec* ivNull = new intvec(nV);
5339  intvec* curr_weight = new intvec(nV);
5340  intvec* target_weight = new intvec(nV);
5341  intvec* exivlp = Mivlp(nV);
5342/*
5343  intvec* tmp_weight = new intvec(nV);
5344  for(i=0; i<nV; i++)
5345  {
5346    (*tmp_weight)[i] = (*orig_M)[i];
5347  }
5348*/
5349  for(i=0; i<nV; i++)
5350  {
5351    (*curr_weight)[i] = (*orig_M)[i];
5352    (*target_weight)[i] = (*target_M)[i];
5353  }
5354#ifndef BUCHBERGER_ALG
5355  intvec* hilb_func;
5356   // to avoid (1,0,...,0) as the target vector
5357  intvec* last_omega = new intvec(nV);
5358  for(i=nV-1; i>0; i--)
5359  {
5360    (*last_omega)[i] = 1;
5361  }
5362  (*last_omega)[0] = 10000;
5363#endif
5364  rComplete(currRing);
5365#ifdef CHECK_IDEAL_MWALK
5366  if(printout > 2)
5367  {
5368    idString(Go,"//** Mwalk: Go");
5369  }
5370#endif
5371
5372  if(target_M->length() == nV)
5373  {
5374   // define the target ring
5375    targetRing = VMrDefault(target_weight);
5376  }
5377  else
5378  {
5379    targetRing = VMatrDefault(target_M);
5380  }
5381  if(orig_M->length() == nV)
5382  {
5383    // define a new ring with ordering "(a(curr_weight),lp)
5384    //newRing = VMrDefault(curr_weight);
5385    newRing=VMrRefine(target_weight, curr_weight);
5386  }
5387  else
5388  {
5389    newRing = VMatrRefine(target_M,curr_weight); //newRing = VMatrDefault(orig_M);
5390  }
5391  rChangeCurrRing(newRing);
5392  if(printout > 2)
5393  {
5394    Print("\n//** Mrwalk: Current ring r = %s;\n", rString(currRing));
5395  }
5396#ifdef TIME_TEST
5397  to = clock();
5398#endif
5399  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5400#ifdef TIME_TEST
5401  tostd = clock()-to;
5402#endif
5403
5404  baseRing = currRing;
5405  nwalk = 0;
5406
5407  while(1)
5408  {
5409    nwalk ++;
5410    nstep ++;
5411    //compute an initial form ideal of <G> w.r.t. "curr_vector"
5412#ifdef TIME_TEST
5413    to = clock();
5414#endif
5415    Gomega = MwalkInitialForm(G, curr_weight);
5416#ifdef TIME_TEST
5417    tif = tif + clock()-to;
5418#endif
5419
5420#ifdef CHECK_IDEAL_MWALK
5421    if(printout > 1)
5422    {
5423      idString(Gomega,"//** Mwalk: Gomega");
5424    }
5425#endif
5426
5427    if(reduction == 0)
5428    {
5429      FF = middleOfCone(G,Gomega);
5430      if(FF != NULL)
5431      {
5432      PrintS("middle of Cone");
5433        idDelete(&G);
5434        G = idCopy(FF);
5435        idDelete(&FF);
5436        goto NEXT_VECTOR;
5437      }
5438    }
5439
5440#ifndef  BUCHBERGER_ALG
5441    if(isNolVector(curr_weight) == 0)
5442    {
5443      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5444    }
5445    else
5446    {
5447      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5448    }
5449#endif
5450
5451    if(nwalk == 1)
5452    {
5453      if(orig_M->length() == nV)
5454      {
5455        // define a new ring with ordering "(a(curr_weight),lp)
5456        //newRing = VMrDefault(curr_weight);
5457        newRing=VMrRefine(target_weight, curr_weight);
5458      }
5459      else
5460      {
5461        newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5462      }
5463    }
5464    else
5465    {
5466     if(target_M->length() == nV)
5467     {
5468       //define a new ring with ordering "(a(curr_weight),lp)"
5469       //newRing = VMrDefault(curr_weight);
5470       newRing=VMrRefine(target_weight, curr_weight);
5471     }
5472     else
5473     {
5474       //define a new ring with matrix ordering
5475       newRing = VMatrRefine(target_M,curr_weight);
5476     }
5477    }
5478    rChangeCurrRing(newRing);
5479    if(printout > 2)
5480    {
5481      Print("\n// Current ring r = %s;\n", rString(currRing));
5482    }
5483    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5484    idDelete(&Gomega);
5485    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5486#ifdef TIME_TEST
5487    to = clock();
5488#endif
5489#ifndef  BUCHBERGER_ALG
5490    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5491    delete hilb_func;
5492#else
5493    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5494#endif
5495#ifdef TIME_TEST
5496    tstd = tstd + clock() - to;
5497#endif
5498    idSkipZeroes(M);
5499#ifdef CHECK_IDEAL_MWALK
5500    if(printout > 2)
5501    {
5502      idString(M, "//** Mwalk: M");
5503    }
5504#endif
5505    //change the ring to baseRing
5506    rChangeCurrRing(baseRing);
5507    M1 =  idrMoveR(M, newRing,currRing);
5508    idDelete(&M);
5509    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5510    idDelete(&Gomega1);
5511#ifdef TIME_TEST
5512    to = clock();
5513#endif
5514    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5515    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5516    F = MLifttwoIdeal(Gomega2, M1, G);
5517#ifdef TIME_TEST
5518    tlift = tlift + clock() - to;
5519#endif
5520#ifdef CHECK_IDEAL_MWALK
5521    if(printout > 2)
5522    {
5523      idString(F, "//** Mwalk: F");
5524    }
5525#endif
5526    idDelete(&Gomega2);
5527    idDelete(&M1);
5528
5529    rChangeCurrRing(newRing); // change the ring to newRing
5530    G = idrMoveR(F,baseRing,currRing);
5531    idDelete(&F);
5532    idSkipZeroes(G);
5533
5534#ifdef CHECK_IDEAL_MWALK
5535    if(printout > 2)
5536    {
5537      idString(G, "//** Mwalk: G");
5538    }
5539#endif
5540
5541    rChangeCurrRing(targetRing);
5542    G = idrMoveR(G,newRing,currRing);
5543    // test whether target cone is reached
5544    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5545    {
5546      baseRing = currRing;
5547      break;
5548      //endwalks = TRUE;
5549    }
5550
5551    rChangeCurrRing(newRing);
5552    G = idrMoveR(G,targetRing,currRing);
5553    baseRing = currRing;
5554
5555    NEXT_VECTOR:
5556#ifdef TIME_TEST
5557    to = clock();
5558#endif
5559    intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5560#ifdef TIME_TEST
5561    tnw = tnw + clock() - to;
5562#endif
5563#ifdef PRINT_VECTORS
5564    if(printout > 0)
5565    {
5566      MivString(curr_weight, target_weight, next_weight);
5567    }
5568#endif
5569    if(reduction ==0)
5570    {
5571      if(MivComp(curr_weight,next_weight)==1)
5572      {
5573        break;
5574      }
5575    }
5576    if(MivComp(target_weight,curr_weight) == 1)
5577    {
5578      break;
5579    }
5580
5581    for(i=nV-1; i>=0; i--)
5582    {
5583      //(*tmp_weight)[i] = (*curr_weight)[i];
5584      (*curr_weight)[i] = (*next_weight)[i];
5585    }
5586    delete next_weight;
5587  }
5588  rChangeCurrRing(XXRing);
5589  ideal result = idrMoveR(G,baseRing,currRing);
5590  idDelete(&Go);
5591  idDelete(&G);
5592  //delete tmp_weight;
5593  delete ivNull;
5594  delete exivlp;
5595#ifndef BUCHBERGER_ALG
5596  delete last_omega;
5597#endif
5598#ifdef TIME_TEST
5599  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5600  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5601  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5602#endif
5603  if(printout > 0)
5604  {
5605    Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
5606  }
5607  si_opt_1 = save1; //set original options
5608  return(result);
5609}
5610
5611// THE RANDOM WALK ALGORITHM
5612ideal Mrwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad, int pert_deg,
5613             int reduction, int printout)
5614{
5615  BITSET save1 = si_opt_1; // save current options
5616  if(reduction == 0)
5617  {
5618    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5619    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5620  }
5621
5622  Set_Error(FALSE);
5623  Overflow_Error = FALSE;
5624#ifdef TIME_TEST
5625  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5626  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5627  tinput = clock();
5628  clock_t tim;
5629#endif
5630  nstep=0;
5631  int i,nwalk;//polylength;
5632  int nV = currRing->N;
5633
5634  //check that weight radius is valid
5635  if(weight_rad < 0)
5636  {
5637    WerrorS("Invalid radius.\n");
5638    return NULL;
5639  }
5640
5641  //check that perturbation degree is valid
5642  if(pert_deg > nV || pert_deg < 1)
5643  {
5644    WerrorS("Invalid perturbation degree.\n");
5645    return NULL;
5646  }
5647
5648  ideal Gomega, M, F,FF, Gomega1, Gomega2, M1;
5649  ring newRing;
5650  ring targetRing;
5651  ring baseRing = currRing;
5652  ring XXRing = currRing;
5653  intvec* iv_M;
5654  intvec* ivNull = new intvec(nV);
5655  intvec* curr_weight = new intvec(nV);
5656  intvec* target_weight = new intvec(nV);
5657  intvec* next_weight= new intvec(nV);
5658
5659  for(i=0; i<nV; i++)
5660  {
5661    (*curr_weight)[i] = (*orig_M)[i];
5662    (*target_weight)[i] = (*target_M)[i];
5663  }
5664
5665#ifndef BUCHBERGER_ALG
5666  intvec* hilb_func;
5667   // to avoid (1,0,...,0) as the target vector
5668  intvec* last_omega = new intvec(nV);
5669  for(i=nV-1; i>0; i--)
5670  {
5671    (*last_omega)[i] = 1;
5672  }
5673  (*last_omega)[0] = 10000;
5674#endif
5675  rComplete(currRing);
5676
5677  if(target_M->length() == nV)
5678  {
5679    targetRing = VMrDefault(target_weight); // define the target ring
5680  }
5681  else
5682  {
5683    targetRing = VMatrDefault(target_M);
5684  }
5685  if(orig_M->length() == nV)
5686  {
5687    //newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5688    newRing=VMrRefine(target_weight, curr_weight);
5689  }
5690  else
5691  {
5692    newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5693  }
5694  rChangeCurrRing(newRing);
5695#ifdef TIME_TEST
5696  to = clock();
5697#endif
5698  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5699#ifdef TIME_TEST
5700  tostd = clock()-to;
5701#endif
5702  baseRing = currRing;
5703  nwalk = 0;
5704
5705#ifdef TIME_TEST
5706  to = clock();
5707#endif
5708  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5709#ifdef TIME_TEST
5710  tif = tif + clock()-to; //time for computing initial form ideal
5711#endif
5712
5713  while(1)
5714  {
5715    nwalk ++;
5716    nstep ++;
5717#ifdef CHECK_IDEAL_MWALK
5718    if(printout > 1)
5719    {
5720      idString(Gomega,"//** Mrwalk: Gomega");
5721    }
5722#endif
5723    if(reduction == 0)
5724    {
5725      FF = middleOfCone(G,Gomega);
5726      if(FF != NULL)
5727      {
5728        idDelete(&G);
5729        G = idCopy(FF);
5730        idDelete(&FF);
5731        goto NEXT_VECTOR;
5732      }
5733    }
5734#ifndef  BUCHBERGER_ALG
5735    if(isNolVector(curr_weight) == 0)
5736    {
5737      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5738    }
5739    else
5740    {
5741      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5742    }
5743#endif
5744    if(nwalk == 1)
5745    {
5746      if(orig_M->length() == nV)
5747      {
5748        /*newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)*/
5749        newRing=VMrRefine(target_weight, curr_weight);
5750      }
5751      else
5752      {
5753        newRing = VMatrRefine(target_M,curr_weight);//newRing = VMatrDefault(orig_M);
5754      }
5755    }
5756    else
5757    {
5758     if(target_M->length() == nV)
5759     {
5760       /*newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)*/
5761       newRing=VMrRefine(target_weight, curr_weight);
5762     }
5763     else
5764     {
5765       newRing = VMatrRefine(target_M,curr_weight);
5766     }
5767    }
5768    rChangeCurrRing(newRing);
5769    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5770    idDelete(&Gomega);
5771    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5772#ifdef TIME_TEST
5773    to = clock();
5774#endif
5775#ifndef BUCHBERGER_ALG
5776    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5777    delete hilb_func;
5778#else
5779    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5780#endif
5781#ifdef TIME_TEST
5782    tstd = tstd + clock() - to;
5783#endif
5784    idSkipZeroes(M);
5785#ifdef CHECK_IDEAL_MWALK
5786    if(printout > 2)
5787    {
5788      idString(M, "//** Mrwalk: M");
5789    }
5790#endif
5791    //change the ring to baseRing
5792    rChangeCurrRing(baseRing);
5793    M1 =  idrMoveR(M, newRing,currRing);
5794    idDelete(&M);
5795    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5796    idDelete(&Gomega1);
5797#ifdef TIME_TEST
5798    to = clock();
5799#endif
5800    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5801    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5802    F = MLifttwoIdeal(Gomega2, M1, G);
5803#ifdef TIME_TEST
5804    tlift = tlift + clock() - to;
5805#endif
5806#ifdef CHECK_IDEAL_MWALK
5807    if(printout > 2)
5808    {
5809      idString(F,"//** Mrwalk: F");
5810    }
5811#endif
5812    idDelete(&Gomega2);
5813    idDelete(&M1);
5814    rChangeCurrRing(newRing); // change the ring to newRing
5815    G = idrMoveR(F,baseRing,currRing);
5816    idDelete(&F);
5817    baseRing = currRing;
5818#ifdef TIME_TEST
5819    to = clock();
5820    tstd = tstd + clock() - to;
5821#endif
5822    idSkipZeroes(G);
5823#ifdef CHECK_IDEAL_MWALK
5824    if(printout > 2)
5825    {
5826      idString(G,"//** Mrwalk: G");
5827    }
5828#endif
5829
5830    rChangeCurrRing(targetRing);
5831    G = idrMoveR(G,newRing,currRing);
5832
5833    // test whether target cone is reached
5834    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5835    {
5836      baseRing = currRing;
5837      break;
5838    }
5839
5840    rChangeCurrRing(newRing);
5841    G = idrMoveR(G,targetRing,currRing);
5842    baseRing = currRing;
5843
5844    NEXT_VECTOR:
5845#ifdef TIME_TEST
5846    to = clock();
5847#endif
5848    next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5849#ifdef TIME_TEST
5850    tnw = tnw + clock() - to;
5851#endif
5852
5853#ifdef TIME_TEST
5854    to = clock();
5855#endif
5856    Gomega = MwalkInitialForm(G, next_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5857#ifdef TIME_TEST
5858    tif = tif + clock()-to; //time for computing initial form ideal
5859#endif
5860
5861    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
5862    //polylength = lengthpoly(Gomega);
5863    if(lengthpoly(Gomega) > 0)
5864    {
5865      //there is a polynomial in Gomega with at least 3 monomials,
5866      //low-dimensional facet of the cone
5867      delete next_weight;
5868      if(target_M->length() == nV)
5869      {
5870        //iv_M = MivMatrixOrder(curr_weight);
5871        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
5872      }
5873      else
5874      {
5875        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
5876      }
5877#ifdef TIME_TEST
5878      to = clock();
5879#endif
5880      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, pert_deg);
5881#ifdef TIME_TEST
5882      tnw = tnw + clock() - to;
5883#endif
5884      idDelete(&Gomega);
5885#ifdef TIME_TEST
5886      to = clock();
5887#endif
5888      Gomega = MwalkInitialForm(G, next_weight);
5889#ifdef TIME_TEST
5890      tif = tif + clock()-to; //time for computing initial form ideal
5891#endif
5892      delete iv_M;
5893    }
5894
5895    // test whether target weight vector is reached
5896    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)
5897    {
5898      baseRing = currRing;
5899      delete next_weight;
5900      break;
5901    }
5902    if(reduction ==0)
5903    {
5904      if(MivComp(curr_weight,next_weight)==1)
5905      {
5906        break;
5907      }
5908    }
5909#ifdef PRINT_VECTORS
5910    if(printout > 0)
5911    {
5912      MivString(curr_weight, target_weight, next_weight);
5913    }
5914#endif
5915
5916    for(i=nV-1; i>=0; i--)
5917    {
5918      (*curr_weight)[i] = (*next_weight)[i];
5919    }
5920    delete next_weight;
5921  }
5922  baseRing = currRing;
5923  rChangeCurrRing(XXRing);
5924  ideal result = idrMoveR(G,baseRing,currRing);
5925  idDelete(&G);
5926  delete ivNull;
5927#ifndef BUCHBERGER_ALG
5928  delete last_omega;
5929#endif
5930  if(printout > 0)
5931  {
5932    Print("\n//** Mrwalk: Groebner Walk took %d steps.\n", nstep);
5933  }
5934#ifdef TIME_TEST
5935  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5936  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5937  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5938#endif
5939  si_opt_1 = save1; //set original options
5940  return(result);
5941}
5942
5943/**************************************************************/
5944/*     Implementation of the perturbation walk algorithm      */
5945/**************************************************************/
5946/* If the perturbed target weight vector or an intermediate weight vector
5947   doesn't stay in the correct Groebner cone, we have only
5948   a reduced Groebner basis for the given ideal with respect to
5949   a monomial order which differs to the given order.
5950   Then we have to compute the wanted  reduced Groebner basis for it.
5951   For this, we can use
5952   1) the improved Buchberger algorithm or
5953   2) the changed perturbation walk algorithm with a decreased degree.
5954*/
5955// if nP = 0 use kStd, else call LastGB
5956ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,
5957             intvec* target_weight, int nP, int reduction, int printout)
5958{
5959  BITSET save1 = si_opt_1; // save current options
5960  if(reduction == 0)
5961  {
5962    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5963    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5964  }
5965  Set_Error(FALSE  );
5966  Overflow_Error = FALSE;
5967  //Print("// pSetm_Error = (%d)", ErrorCheck());
5968#ifdef TIME_TEST
5969  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5970  xtextra=0;
5971  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5972  tinput = clock();
5973
5974  clock_t tim;
5975#endif
5976  nstep = 0;
5977  int i, ntwC=1, ntestw=1,  nV = currRing->N;
5978
5979  //check that perturbation degree is valid
5980  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
5981  {
5982    WerrorS("Invalid perturbation degree.\n");
5983    return NULL;
5984  }
5985
5986  BOOLEAN endwalks = FALSE;
5987  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
5988  ring newRing, oldRing, TargetRing;
5989  intvec* iv_M_dp;
5990  intvec* iv_M_lp;
5991  intvec* exivlp = Mivlp(nV);
5992  intvec* orig_target = target_weight;
5993  intvec* pert_target_vector = target_weight;
5994  intvec* ivNull = new intvec(nV);
5995  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
5996#ifndef BUCHBERGER_ALG
5997  intvec* hilb_func;
5998#endif
5999  intvec* next_weight;
6000
6001  // to avoid (1,0,...,0) as the target vector
6002  intvec* last_omega = new intvec(nV);
6003  for(i=nV-1; i>0; i--)
6004    (*last_omega)[i] = 1;
6005  (*last_omega)[0] = 10000;
6006
6007  ring XXRing = currRing;
6008#ifdef TIME_TEST
6009  to = clock();
6010#endif
6011  // perturbs the original vector
6012  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6013  {
6014    G = MstdCC(Go);
6015#ifdef TIME_TEST
6016    tostd = clock()-to;
6017#endif
6018    if(op_deg != 1){
6019      iv_M_dp = MivMatrixOrderdp(nV);
6020      //ivString(iv_M_dp, "iv_M_dp");
6021      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6022    }
6023  }
6024  else
6025  {
6026    //define ring order := (a(curr_weight),lp);
6027/*
6028    if (rParameter(currRing) != NULL)
6029      DefRingPar(curr_weight);
6030    else
6031      rChangeCurrRing(VMrDefault(curr_weight));
6032*/
6033    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
6034
6035    G = idrMoveR(Go, XXRing,currRing);
6036    G = MstdCC(G);
6037#ifdef TIME_TEST
6038    tostd = clock()-to;
6039#endif
6040    if(op_deg != 1){
6041      iv_M_dp = MivMatrixOrder(curr_weight);
6042      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6043    }
6044  }
6045  delete iv_dp;
6046  if(op_deg != 1) delete iv_M_dp;
6047
6048  ring HelpRing = currRing;
6049
6050  // perturbs the target weight vector
6051  if(tp_deg > 1 && tp_deg <= nV)
6052  {
6053/*
6054    if (rParameter(currRing) != NULL)
6055      DefRingPar(target_weight);
6056    else
6057      rChangeCurrRing(VMrDefault(target_weight));
6058*/
6059    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
6060
6061    TargetRing = currRing;
6062    ssG = idrMoveR(G,HelpRing,currRing);
6063    if(MivSame(target_weight, exivlp) == 1)
6064    {
6065      iv_M_lp = MivMatrixOrderlp(nV);
6066      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6067    }
6068    else
6069    {
6070      iv_M_lp = MivMatrixOrder(target_weight);
6071      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6072    }
6073    delete iv_M_lp;
6074    pert_target_vector = target_weight;
6075    rChangeCurrRing(HelpRing);
6076    G = idrMoveR(ssG, TargetRing,currRing);
6077  }
6078  if(printout > 0)
6079  {
6080    Print("\n//** Mpwalk: Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6081#ifdef PRINT_VECTORS
6082    ivString(curr_weight, "//** Mpwalk: new current weight");
6083    ivString(target_weight, "//** Mpwalk: new target weight");
6084#endif
6085  }
6086  while(1)
6087  {
6088    nstep ++;
6089#ifdef TIME_TEST
6090    to = clock();
6091#endif
6092    // compute an initial form ideal of <G> w.r.t. the weight vector
6093    // "curr_weight"
6094    Gomega = MwalkInitialForm(G, curr_weight);
6095#ifdef TIME_TEST
6096    tif = tif + clock()-to;
6097#endif
6098#ifdef CHECK_IDEAL_MWALK
6099    if(printout > 1)
6100    {
6101      idString(Gomega,"//** Mpwalk: Gomega");
6102    }
6103#endif
6104    if(reduction == 0 && nstep > 1)
6105    {
6106      FF = middleOfCone(G,Gomega);
6107      if(FF != NULL)
6108      {
6109        idDelete(&G);
6110        G = idCopy(FF);
6111        idDelete(&FF);
6112        goto NEXT_VECTOR;
6113      }
6114    }
6115
6116#ifdef ENDWALKS
6117    if(endwalks == TRUE)
6118    {
6119      if(printout > 0)
6120      {
6121        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6122      }
6123      //idElements(G, "G");
6124      //headidString(G, "G");
6125    }
6126#endif
6127
6128#ifndef  BUCHBERGER_ALG
6129    if(isNolVector(curr_weight) == 0)
6130      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6131    else
6132      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6133#endif // BUCHBERGER_ALG
6134
6135    oldRing = currRing;
6136
6137    // define a new ring with ordering "(a(curr_weight),lp)
6138/*
6139    if (rParameter(currRing) != NULL)
6140      DefRingPar(curr_weight);
6141    else
6142      rChangeCurrRing(VMrDefault(curr_weight));
6143*/
6144    rChangeCurrRing(VMrRefine(target_weight,curr_weight));
6145
6146    newRing = currRing;
6147    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6148
6149#ifdef ENDWALKS
6150    if(endwalks==TRUE)
6151    {
6152      if(printout > 0)
6153      {
6154        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6155        //idElements(Gomega1, "Gw");
6156        //headidString(Gomega1, "headGw");
6157        PrintS("\n// compute a rGB of Gw:\n");
6158      }
6159#ifndef  BUCHBERGER_ALG
6160      ivString(hilb_func, "w");
6161#endif
6162    }
6163#endif
6164#ifdef TIME_TEST
6165    tim = clock();
6166    to = clock();
6167#endif
6168    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6169#ifdef  BUCHBERGER_ALG
6170    M = MstdhomCC(Gomega1);
6171#else
6172    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6173    delete hilb_func;
6174#endif
6175
6176    if(endwalks == TRUE)
6177    {
6178#ifdef TIME_TEST
6179      xtstd = xtstd+clock()-to;
6180#endif
6181#ifdef ENDWALKS
6182#ifdef TIME_TEST
6183      if(printout > 1)
6184      {
6185        Print("\n// time for the last std(Gw)  = %.2f sec\n",
6186            ((double) clock())/1000000 -((double)tim) /1000000);
6187      }
6188#endif
6189#endif
6190    }
6191    else
6192    {
6193#ifdef TIME_TEST
6194      tstd=tstd+clock()-to;
6195#endif
6196    }
6197#ifdef CHECK_IDEAL_MWALK
6198    if(printout > 2)
6199    {
6200      idString(M,"//** Mpwalk: M");
6201    }
6202#endif
6203    // change the ring to oldRing
6204    rChangeCurrRing(oldRing);
6205    M1 =  idrMoveR(M, newRing,currRing);
6206    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6207#ifdef TIME_TEST
6208    to=clock();
6209#endif
6210    /* compute a representation of the generators of submod (M)
6211       with respect to those of mod (Gomega).
6212       Gomega is a reduced Groebner basis w.r.t. the current ring */
6213    F = MLifttwoIdeal(Gomega2, M1, G);
6214#ifdef TIME_TEST
6215    if(endwalks == FALSE)
6216      tlift = tlift+clock()-to;
6217    else
6218      xtlift=clock()-to;
6219#endif
6220#ifdef CHECK_IDEAL_MWALK
6221    if(printout > 2)
6222    {
6223      idString(F,"//** Mpwalk: F");
6224    }
6225#endif
6226
6227    idDelete(&M1);
6228    idDelete(&Gomega2);
6229    idDelete(&G);
6230
6231    // change the ring to newRing
6232    rChangeCurrRing(newRing);
6233    if(reduction == 0)
6234    {
6235      G = idrMoveR(F,oldRing,currRing);
6236    }
6237    else
6238    {
6239      F1 = idrMoveR(F, oldRing,currRing);
6240      if(printout > 2)
6241      {
6242        PrintS("\n //** Mpwalk: reduce the Groebner basis.\n");
6243      }
6244#ifdef TIME_TEST
6245      to=clock();
6246#endif
6247      G = kInterRedCC(F1, NULL);
6248#ifdef TIME_TEST
6249      if(endwalks == FALSE)
6250        tred = tred+clock()-to;
6251      else
6252        xtred=clock()-to;
6253#endif
6254      idDelete(&F1);
6255    }
6256    if(endwalks == TRUE)
6257      break;
6258
6259    NEXT_VECTOR:
6260#ifdef TIME_TEST
6261    to=clock();
6262#endif
6263    // compute a next weight vector
6264    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6265#ifdef TIME_TEST
6266    tnw=tnw+clock()-to;
6267#endif
6268#ifdef PRINT_VECTORS
6269    if(printout > 0)
6270    {
6271      MivString(curr_weight, target_weight, next_weight);
6272    }
6273#endif
6274
6275    if(Overflow_Error == TRUE)
6276    {
6277      ntwC = 0;
6278      //ntestomega = 1;
6279      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6280      //idElements(G, "G");
6281      delete next_weight;
6282      goto FINISH_160302;
6283    }
6284    if(MivComp(next_weight, ivNull) == 1){
6285      newRing = currRing;
6286      delete next_weight;
6287      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6288      break;
6289    }
6290    if(MivComp(next_weight, target_weight) == 1)
6291      endwalks = TRUE;
6292
6293    for(i=nV-1; i>=0; i--)
6294      (*curr_weight)[i] = (*next_weight)[i];
6295
6296    delete next_weight;
6297  }//end of while-loop
6298
6299  if(tp_deg != 1)
6300  {
6301  FINISH_160302:
6302    if(MivSame(orig_target, exivlp) == 1) {
6303    /*  if (rParameter(currRing) != NULL)
6304        DefRingParlp();
6305      else
6306        VMrDefaultlp();
6307    else
6308      if (rParameter(currRing) != NULL)
6309        DefRingPar(orig_target);
6310      else*/
6311        rChangeCurrRing(VMrDefault(orig_target));
6312    }
6313    TargetRing=currRing;
6314    F1 = idrMoveR(G, newRing,currRing);
6315/*
6316#ifdef CHECK_IDEAL_MWALK
6317      headidString(G, "G");
6318#endif
6319*/
6320
6321    // check whether the pertubed target vector stays in the correct cone
6322    if(ntwC != 0){
6323      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6324    }
6325
6326    if( ntestw != 1 || ntwC == 0)
6327    {
6328      if(ntestw != 1 && printout >2)
6329      {
6330        ivString(pert_target_vector, "tau");
6331        PrintS("\n// ** perturbed target vector doesn't stay in cone!!");
6332        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6333        //idElements(F1, "G");
6334      }
6335      // LastGB is "better" than the kStd subroutine
6336#ifdef TIME_TEST
6337      to=clock();
6338#endif
6339      ideal eF1;
6340      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1){
6341        // PrintS("\n// ** calls \"std\" to compute a GB");
6342        eF1 = MstdCC(F1);
6343        idDelete(&F1);
6344      }
6345      else {
6346        // PrintS("\n// ** calls \"LastGB\" to compute a GB");
6347        rChangeCurrRing(newRing);
6348        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6349        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6350        F2=NULL;
6351      }
6352#ifdef TIME_TEST
6353      xtextra=clock()-to;
6354#endif
6355      ring exTargetRing = currRing;
6356
6357      rChangeCurrRing(XXRing);
6358      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6359    }
6360    else{
6361      rChangeCurrRing(XXRing);
6362      Eresult = idrMoveR(F1, TargetRing,currRing);
6363    }
6364  }
6365  else {
6366    rChangeCurrRing(XXRing);
6367    Eresult = idrMoveR(G, newRing,currRing);
6368  }
6369  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6370  delete ivNull;
6371  if(tp_deg != 1)
6372    delete target_weight;
6373
6374  if(op_deg != 1 )
6375    delete curr_weight;
6376
6377  delete exivlp;
6378  delete last_omega;
6379
6380#ifdef TIME_TEST
6381  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6382             tnw+xtnw);
6383
6384  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6385  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6386#endif
6387  if(printout > 0)
6388  {
6389    Print("\n//** Mpwalk: Perturbation Walk took %d steps.\n", nstep);
6390  }
6391  return(Eresult);
6392}
6393
6394/*******************************************************
6395 * THE PERTURBATION WALK ALGORITHM WITH RANDOM ELEMENT *
6396 *******************************************************/
6397ideal Mprwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad,
6398              int op_deg, int tp_deg, int nP, int reduction, int printout)
6399{
6400  BITSET save1 = si_opt_1; // save current options
6401  if(reduction == 0)
6402  {
6403    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6404    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6405  }
6406  Set_Error(FALSE);
6407  Overflow_Error = FALSE;
6408  //Print("// pSetm_Error = (%d)", ErrorCheck());
6409#ifdef TIME_TEST
6410  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6411  xtextra=0;
6412  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6413  tinput = clock();
6414
6415  clock_t tim;
6416#endif
6417  nstep = 0;
6418  int i, ntwC=1, ntestw=1, nV = currRing->N; //polylength
6419
6420  //check that weight radius is valid
6421  if(weight_rad < 0)
6422  {
6423    WerrorS("Invalid radius.\n");
6424    return NULL;
6425  }
6426
6427  //check that perturbation degree is valid
6428  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6429  {
6430    WerrorS("Invalid perturbation degree.\n");
6431    return NULL;
6432  }
6433
6434  BOOLEAN endwalks = FALSE;
6435
6436  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6437  ring newRing, oldRing, TargetRing;
6438  intvec* iv_M;
6439  intvec* iv_M_dp;
6440  intvec* iv_M_lp;
6441  intvec* exivlp = Mivlp(nV);
6442  intvec* curr_weight = new intvec(nV);
6443  intvec* target_weight = new intvec(nV);
6444  for(i=0; i<nV; i++)
6445  {
6446    (*curr_weight)[i] = (*orig_M)[i];
6447    (*target_weight)[i] = (*target_M)[i];
6448  }
6449  intvec* orig_target = target_weight;
6450  intvec* pert_target_vector = target_weight;
6451  intvec* ivNull = new intvec(nV);
6452  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6453#ifndef BUCHBERGER_ALG
6454  intvec* hilb_func;
6455#endif
6456  intvec* next_weight;
6457
6458  // to avoid (1,0,...,0) as the target vector
6459  intvec* last_omega = new intvec(nV);
6460  for(i=nV-1; i>0; i--)
6461    (*last_omega)[i] = 1;
6462  (*last_omega)[0] = 10000;
6463
6464  ring XXRing = currRing;
6465
6466  // perturbs the original vector
6467  if(orig_M->length() == nV)
6468  {
6469    if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6470    {
6471#ifdef TIME_TEST
6472  to = clock();
6473#endif
6474      G = MstdCC(Go);
6475#ifdef TIME_TEST
6476      tostd = clock()-to;
6477#endif
6478      if(op_deg != 1)
6479      {
6480        iv_M_dp = MivMatrixOrderdp(nV);
6481        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6482      }
6483    }
6484    else
6485    {
6486      //define ring order := (a(curr_weight),lp);
6487      if (rParameter(currRing) != NULL)
6488        DefRingPar(curr_weight);
6489      else
6490        rChangeCurrRing(VMrDefault(curr_weight));
6491
6492      G = idrMoveR(Go, XXRing,currRing);
6493#ifdef TIME_TEST
6494  to = clock();
6495#endif
6496      G = MstdCC(G);
6497#ifdef TIME_TEST
6498      tostd = clock()-to;
6499#endif
6500      if(op_deg != 1)
6501      {
6502        iv_M_dp = MivMatrixOrder(curr_weight);
6503        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6504      }
6505    }
6506  }
6507  else
6508  {
6509    rChangeCurrRing(VMatrDefault(orig_M));
6510    G = idrMoveR(Go, XXRing,currRing);
6511#ifdef TIME_TEST
6512    to = clock();
6513#endif
6514    G = MstdCC(G);
6515#ifdef TIME_TEST
6516    tostd = clock()-to;
6517#endif
6518    if(op_deg != 1)
6519    {
6520      curr_weight = MPertVectors(G, orig_M, op_deg);
6521    }
6522  }
6523
6524  delete iv_dp;
6525  if(op_deg != 1) delete iv_M_dp;
6526
6527  ring HelpRing = currRing;
6528
6529  // perturbs the target weight vector
6530  if(target_M->length() == nV)
6531  {
6532    if(tp_deg > 1 && tp_deg <= nV)
6533    {
6534      if (rParameter(currRing) != NULL)
6535        DefRingPar(target_weight);
6536      else
6537        rChangeCurrRing(VMrDefault(target_weight));
6538
6539      TargetRing = currRing;
6540      ssG = idrMoveR(G,HelpRing,currRing);
6541      if(MivSame(target_weight, exivlp) == 1)
6542      {
6543        iv_M_lp = MivMatrixOrderlp(nV);
6544        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6545      }
6546      else
6547      {
6548        iv_M_lp = MivMatrixOrder(target_weight);
6549        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6550      }
6551      delete iv_M_lp;
6552      pert_target_vector = target_weight;
6553      rChangeCurrRing(HelpRing);
6554      G = idrMoveR(ssG, TargetRing,currRing);
6555    }
6556  }
6557  else
6558  {
6559    if(tp_deg > 1 && tp_deg <= nV)
6560    {
6561      rChangeCurrRing(VMatrDefault(target_M));
6562      TargetRing = currRing;
6563      ssG = idrMoveR(G,HelpRing,currRing);
6564      target_weight = MPertVectors(ssG, target_M, tp_deg);
6565    }
6566  }
6567  if(printout > 0)
6568  {
6569    Print("\n//** Mprwalk: Random Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6570    ivString(curr_weight, "//** Mprwalk: new current weight");
6571    ivString(target_weight, "//** Mprwalk: new target weight");
6572  }
6573
6574#ifdef TIME_TEST
6575  to = clock();
6576#endif
6577  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
6578#ifdef TIME_TEST
6579  tif = tif + clock()-to; //time for computing initial form ideal
6580#endif
6581
6582  while(1)
6583  {
6584    nstep ++;
6585#ifdef CHECK_IDEAL_MWALK
6586    if(printout > 1)
6587    {
6588      idString(Gomega,"//** Mprwalk: Gomega");
6589    }
6590#endif
6591
6592    if(reduction == 0 && nstep > 1)
6593    {
6594      FF = middleOfCone(G,Gomega);
6595      if(FF != NULL)
6596      {
6597        idDelete(&G);
6598        G = idCopy(FF);
6599        idDelete(&FF);
6600        goto NEXT_VECTOR;
6601      }
6602    }
6603
6604#ifdef ENDWALKS
6605    if(endwalks == TRUE)
6606    {
6607      if(printout > 0)
6608      {
6609        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6610        //idElements(G, "G");
6611        //headidString(G, "G");
6612      }
6613    }
6614#endif
6615
6616#ifndef  BUCHBERGER_ALG
6617    if(isNolVector(curr_weight) == 0)
6618      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6619    else
6620      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6621#endif // BUCHBERGER_ALG
6622
6623    oldRing = currRing;
6624
6625    if(target_M->length() == nV)
6626    {/*
6627      // define a new ring with ordering "(a(curr_weight),lp)
6628      if (rParameter(currRing) != NULL)
6629        DefRingPar(curr_weight);
6630      else
6631        rChangeCurrRing(VMrDefault(curr_weight));
6632*/
6633      rChangeCurrRing(VMrRefine(target_M,curr_weight));
6634    }
6635    else
6636    {
6637      rChangeCurrRing(VMatrRefine(target_M,curr_weight));
6638    }
6639    newRing = currRing;
6640    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6641#ifdef ENDWALKS
6642    if(endwalks == TRUE)
6643    {
6644      if(printout > 0)
6645      {
6646        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6647
6648        //idElements(Gomega1, "Gw");
6649        //headidString(Gomega1, "headGw");
6650
6651        PrintS("\n// compute a rGB of Gw:\n");
6652      }
6653#ifndef  BUCHBERGER_ALG
6654      ivString(hilb_func, "w");
6655#endif
6656    }
6657#endif
6658#ifdef TIME_TEST
6659    tim = clock();
6660    to = clock();
6661#endif
6662    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6663#ifdef  BUCHBERGER_ALG
6664    M = MstdhomCC(Gomega1);
6665#else
6666    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6667    delete hilb_func;
6668#endif
6669#ifdef CHECK_IDEAL_MWALK
6670    if(printout > 2)
6671    {
6672      idString(M,"//** Mprwalk: M");
6673    }
6674#endif
6675#ifdef TIME_TEST
6676    if(endwalks == TRUE)
6677    {
6678      xtstd = xtstd+clock()-to;
6679#ifdef ENDWALKS
6680      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6681            ((double) clock())/1000000 -((double)tim) /1000000);
6682#endif
6683    }
6684    else
6685      tstd=tstd+clock()-to;
6686#endif
6687    /* change the ring to oldRing */
6688    rChangeCurrRing(oldRing);
6689    M1 =  idrMoveR(M, newRing,currRing);
6690    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6691#ifdef TIME_TEST
6692    to=clock();
6693#endif
6694    /* compute a representation of the generators of submod (M)
6695       with respect to those of mod (Gomega).
6696       Gomega is a reduced Groebner basis w.r.t. the current ring */
6697    F = MLifttwoIdeal(Gomega2, M1, G);
6698#ifdef TIME_TEST
6699    if(endwalks == FALSE)
6700      tlift = tlift+clock()-to;
6701    else
6702      xtlift=clock()-to;
6703#endif
6704#ifdef CHECK_IDEAL_MWALK
6705    if(printout > 2)
6706    {
6707      idString(F,"//** Mprwalk: F");
6708    }
6709#endif
6710
6711    idDelete(&M1);
6712    idDelete(&Gomega2);
6713    idDelete(&G);
6714
6715    // change the ring to newRing
6716    rChangeCurrRing(newRing);
6717    if(reduction == 0)
6718    {
6719      G = idrMoveR(F,oldRing,currRing);
6720    }
6721    else
6722    {
6723      F1 = idrMoveR(F, oldRing,currRing);
6724      if(printout > 2)
6725      {
6726        PrintS("\n //** Mprwalk: reduce the Groebner basis.\n");
6727      }
6728#ifdef TIME_TEST
6729      to=clock();
6730#endif
6731      G = kInterRedCC(F1, NULL);
6732#ifdef TIME_TEST
6733      if(endwalks == FALSE)
6734        tred = tred+clock()-to;
6735      else
6736        xtred=clock()-to;
6737#endif
6738      idDelete(&F1);
6739    }
6740
6741    if(endwalks == TRUE)
6742      break;
6743
6744    NEXT_VECTOR:
6745#ifdef TIME_TEST
6746    to = clock();
6747#endif
6748    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6749#ifdef TIME_TEST
6750    tnw = tnw + clock() - to;
6751#endif
6752
6753#ifdef TIME_TEST
6754    to = clock();
6755#endif
6756    // compute an initial form ideal of <G> w.r.t. "next_vector"
6757    Gomega = MwalkInitialForm(G, next_weight);
6758#ifdef TIME_TEST
6759    tif = tif + clock()-to; //time for computing initial form ideal
6760#endif
6761
6762    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
6763    if(lengthpoly(Gomega) > 0)
6764    {
6765      if(printout > 1)
6766      {
6767        PrintS("\n Mpwalk: there is a polynomial in Gomega with at least 3 monomials.\n");
6768      }
6769      // low-dimensional facet of the cone
6770      delete next_weight;
6771      if(target_M->length() == nV)
6772      {
6773        iv_M = MivMatrixOrder(curr_weight);
6774      }
6775      else
6776      {
6777        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
6778      }
6779#ifdef TIME_TEST
6780      to = clock();
6781#endif
6782      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, op_deg);
6783#ifdef TIME_TEST
6784      tnw = tnw + clock() - to;
6785#endif
6786      idDelete(&Gomega);
6787#ifdef TIME_TEST
6788      to = clock();
6789#endif
6790      Gomega = MwalkInitialForm(G, next_weight);
6791#ifdef TIME_TEST
6792      tif = tif + clock()-to; //time for computing initial form ideal
6793#endif
6794      delete iv_M;
6795    }
6796
6797#ifdef PRINT_VECTORS
6798    if(printout > 0)
6799    {
6800      MivString(curr_weight, target_weight, next_weight);
6801    }
6802#endif
6803
6804    if(Overflow_Error == TRUE)
6805    {
6806      ntwC = 0;
6807      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6808      //idElements(G, "G");
6809      delete next_weight;
6810      goto FINISH_160302;
6811    }
6812    if(MivComp(next_weight, ivNull) == 1){
6813      newRing = currRing;
6814      delete next_weight;
6815      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6816      break;
6817    }
6818    if(MivComp(next_weight, target_weight) == 1)
6819      endwalks = TRUE;
6820
6821    for(i=nV-1; i>=0; i--)
6822      (*curr_weight)[i] = (*next_weight)[i];
6823
6824    delete next_weight;
6825  }// end of while-loop
6826
6827  if(tp_deg != 1)
6828  {
6829    FINISH_160302:
6830    if(target_M->length() == nV)
6831    {
6832      if(MivSame(orig_target, exivlp) == 1)
6833        if (rParameter(currRing) != NULL)
6834          DefRingParlp();
6835        else
6836          VMrDefaultlp();
6837      else
6838        if (rParameter(currRing) != NULL)
6839          DefRingPar(orig_target);
6840        else
6841          rChangeCurrRing(VMrDefault(orig_target));
6842    }
6843    else
6844    {
6845      rChangeCurrRing(VMatrDefault(target_M));
6846    }
6847    TargetRing=currRing;
6848    F1 = idrMoveR(G, newRing,currRing);
6849
6850    // check whether the pertubed target vector stays in the correct cone
6851    if(ntwC != 0)
6852    {
6853      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6854    }
6855    if(ntestw != 1 || ntwC == 0)
6856    {
6857      if(ntestw != 1 && printout > 2)
6858      {
6859#ifdef PRINT_VECTORS
6860        ivString(pert_target_vector, "tau");
6861#endif
6862        PrintS("\n// **Mprwalk: perturbed target vector doesn't stay in cone.");
6863        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6864        //idElements(F1, "G");
6865      }
6866      // LastGB is "better" than the kStd subroutine
6867#ifdef TIME_TEST
6868      to=clock();
6869#endif
6870      ideal eF1;
6871      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1 || target_M->length() != nV)
6872      {
6873        if(printout > 2)
6874        {
6875          PrintS("\n// ** Mprwalk: Call \"std\" to compute a Groebner basis.\n");
6876        }
6877        eF1 = MstdCC(F1);
6878        idDelete(&F1);
6879      }
6880      else
6881      {
6882        if(printout > 2)
6883        {
6884          PrintS("\n// **Mprwalk: Call \"LastGB\" to compute a Groebner basis.\n");
6885        }
6886        rChangeCurrRing(newRing);
6887        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6888        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6889        F2=NULL;
6890      }
6891#ifdef TIME_TEST
6892      xtextra=clock()-to;
6893#endif
6894      ring exTargetRing = currRing;
6895
6896      rChangeCurrRing(XXRing);
6897      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6898    }
6899    else
6900    {
6901      rChangeCurrRing(XXRing);
6902      Eresult = idrMoveR(F1, TargetRing,currRing);
6903    }
6904  }
6905  else
6906  {
6907    rChangeCurrRing(XXRing);
6908    Eresult = idrMoveR(G, newRing,currRing);
6909  }
6910  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6911  delete ivNull;
6912  if(tp_deg != 1)
6913    delete target_weight;
6914
6915  if(op_deg != 1 )
6916    delete curr_weight;
6917
6918  delete exivlp;
6919  delete last_omega;
6920
6921#ifdef TIME_TEST
6922  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6923             tnw+xtnw);
6924
6925  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6926  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6927#endif
6928
6929  if(printout > 0)
6930  {
6931    Print("\n//** Mprwalk: Perturbation Walk took %d steps.\n", nstep);
6932  }
6933  return(Eresult);
6934}
6935
6936intvec* XivNull;
6937
6938/*****************************
6939 * define a matrix (1 ... 1) *
6940 *****************************/
6941intvec* MMatrixone(int nV)
6942{
6943  int i,j;
6944  intvec* ivM = new intvec(nV*nV);
6945
6946  for(i=0; i<nV; i++)
6947    for(j=0; j<nV; j++)
6948    (*ivM)[i*nV + j] = 1;
6949
6950  return(ivM);
6951}
6952
6953int nnflow;
6954int Xcall;
6955int Xngleich;
6956
6957/***********************************************************************
6958 * Perturb the start weight vector at the top level, i.e. nlev = 1     *
6959 ***********************************************************************/
6960static ideal rec_fractal_call(ideal G, int nlev, intvec* ivtarget,
6961             int reduction, int printout)
6962{
6963  Overflow_Error =  FALSE;
6964  if(printout >0)
6965  {
6966    Print("\n\n// Entering the %d-th recursion:", nlev);
6967  }
6968  int i, nV = currRing->N;
6969  ring new_ring, testring;
6970  //ring extoRing;
6971  ideal Gomega, Gomega1, Gomega2, FF, F, Gresult, Gresult1, G1, Gt;
6972  int nwalks = 0;
6973  intvec* Mwlp;
6974#ifndef BUCHBERGER_ALG
6975  intvec* hilb_func;
6976#endif
6977  //intvec* extXtau;
6978  intvec* next_vect;
6979  intvec* omega2 = new intvec(nV);
6980  intvec* omtmp = new intvec(nV);
6981  //intvec* altomega = new intvec(nV);
6982
6983  for(i = nV -1; i>=0; i--)//Aenderung!!
6984  {
6985    (*omtmp)[i] = (*ivtarget)[i];
6986  }
6987  //BOOLEAN isnewtarget = FALSE;
6988
6989  // to avoid (1,0,...,0) as the target vector (Hans)
6990  intvec* last_omega = new intvec(nV);
6991  for(i=nV-1; i>0; i--)
6992    (*last_omega)[i] = 1;
6993  (*last_omega)[0] = 10000;
6994
6995  intvec* omega = new intvec(nV);
6996  for(i=0; i<nV; i++) {
6997    if(Xsigma->length() == nV)
6998      (*omega)[i] =  (*Xsigma)[i];
6999    else
7000      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
7001
7002    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7003  }
7004
7005   if(nlev == 1)  Xcall = 1;
7006   else Xcall = 0;
7007
7008  ring oRing = currRing;
7009
7010  while(1)
7011  {
7012#ifdef FIRST_STEP_FRACTAL
7013    // perturb the current weight vector only on the top level or
7014    // after perturbation of the both vectors, nlev = 2 as the top level
7015    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
7016      if(islengthpoly2(G) == 1)
7017      {
7018        Mwlp = MivWeightOrderlp(omega);
7019        Xsigma = Mfpertvector(G, Mwlp);
7020        delete Mwlp;
7021        Overflow_Error = FALSE;
7022      }
7023#endif
7024    nwalks ++;
7025    NEXT_VECTOR_FRACTAL:
7026#ifdef TIME_TEST
7027    to=clock();
7028#endif
7029    // determine the next border
7030    next_vect = MkInterRedNextWeight(omega,omega2,G);
7031#ifdef TIME_TEST
7032    xtnw=xtnw+clock()-to;
7033#endif
7034    oRing = currRing;
7035
7036    // We only perturb the current target vector at the recursion level 1
7037    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
7038      if (MivComp(next_vect, omega2) == 1)
7039      {
7040        // to dispense with taking initial (and lifting/interreducing
7041        // after the call of recursion
7042        if(printout > 0)
7043        {
7044          Print("\n//** rec_fractal_call: Perturb the both vectors with degree %d.",nlev);
7045          //idElements(G, "G");
7046        }
7047
7048        Xngleich = 1;
7049        nlev +=1;
7050
7051        if(ivtarget->length() == nV)
7052        {
7053/*
7054          if (rParameter(currRing) != NULL)
7055            DefRingPar(omtmp);
7056          else
7057            rChangeCurrRing(VMrDefault(omtmp));
7058*/
7059          rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7060        }
7061        else
7062        {
7063          //rChangeCurrRing(VMatrDefault(ivtarget));
7064          rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7065        }
7066        testring = currRing;
7067        Gt = idrMoveR(G, oRing,currRing);
7068
7069        // perturb the original target vector w.r.t. the current GB
7070        if(ivtarget->length() == nV)
7071        {
7072          delete Xtau;
7073          Xtau = NewVectorlp(Gt);
7074        }
7075        else
7076        {
7077          delete Xtau;
7078          Xtau = Mfpertvector(Gt,ivtarget);
7079        }
7080
7081        rChangeCurrRing(oRing);
7082        G = idrMoveR(Gt, testring,currRing);
7083
7084        // perturb the current vector w.r.t. the current GB
7085        Mwlp = MivWeightOrderlp(omega);
7086        Xsigma = Mfpertvector(G, Mwlp);
7087        delete Mwlp;
7088
7089        for(i=nV-1; i>=0; i--) {
7090          (*omega2)[i] = (*Xtau)[nV+i];
7091          (*omega)[i] = (*Xsigma)[nV+i];
7092        }
7093
7094        delete next_vect;
7095#ifdef TIME_TEST
7096        to=clock();
7097#endif
7098        // to avoid the value of Overflow_Error that occur in Mfpertvector
7099        Overflow_Error = FALSE;
7100        next_vect = MkInterRedNextWeight(omega,omega2,G);
7101#ifdef TIME_TEST
7102        xtnw=xtnw+clock()-to;
7103#endif
7104      }// end of (if MivComp(next_vect, omega2) == 1)
7105
7106#ifdef PRINT_VECTORS
7107      if(printout > 0)
7108      {
7109        MivString(omega, omega2, next_vect);
7110      }
7111#endif
7112
7113    // check whether the the computed vector is in the correct cone.
7114    // If no, compute the reduced Groebner basis of an omega-homogeneous
7115    // ideal with Buchberger's algorithm and stop this recursion step
7116    if(Overflow_Error == TRUE || test_w_in_ConeCC(G, next_vect) != 1)  //e.g. Example s7, cyc6
7117    {
7118      delete next_vect;
7119      if(ivtarget->length() == nV)
7120      {
7121/*
7122        if (rParameter(currRing) != NULL)
7123          DefRingPar(omtmp);
7124        else
7125          rChangeCurrRing(VMrDefault(omtmp));
7126*/
7127        rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7128      }
7129      else
7130      {
7131        //rChangeCurrRing(VMatrDefault(ivtarget));
7132        rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7133      }
7134#ifdef TEST_OVERFLOW
7135      Gt = idrMoveR(G, oRing,currRing);
7136      Gt = NULL; return(Gt);
7137#endif
7138      if(printout > 0)
7139      {
7140        Print("\n//** rec_fractal_call: Applying Buchberger's algorithm in ring r = %s;",
7141              rString(currRing));
7142      }
7143#ifdef TIME_TEST
7144      to=clock();
7145#endif
7146      Gt = idrMoveR(G, oRing,currRing);
7147      G1 = MstdCC(Gt);
7148#ifdef TIME_TEST
7149      xtextra=xtextra+clock()-to;
7150#endif
7151      Gt = NULL;
7152
7153      delete omega2;
7154      //delete altomega;
7155      if(printout > 0)
7156      {
7157        Print("\n//** rec_fractal_call: Overflow. (4) Leaving the %d-th recursion with %d steps.\n",
7158              nlev, nwalks);
7159        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7160      }
7161
7162      nnflow ++;
7163      Overflow_Error = FALSE;
7164      return (G1);
7165    }
7166
7167    /* If the perturbed target vector stays in the correct cone,
7168       return the current GB,
7169       otherwise, return the computed  GB by the Buchberger-algorithm.
7170       Then we update the perturbed target vectors w.r.t. this GB. */
7171
7172    /* the computed vector is equal to the origin vector, since
7173       t is not defined */
7174
7175    if (MivComp(next_vect, XivNull) == 1)
7176    {
7177      if(ivtarget->length() == nV)
7178      {
7179/*
7180        if (rParameter(currRing) != NULL)
7181          DefRingPar(omtmp);
7182        else
7183          rChangeCurrRing(VMrDefault(omtmp));
7184*/
7185        rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7186      }
7187      else
7188      {
7189        //rChangeCurrRing(VMatrDefault(ivtarget));
7190        rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7191      }
7192
7193      testring = currRing;
7194      Gt = idrMoveR(G, oRing,currRing);
7195      if(test_w_in_ConeCC(Gt, omega2) == 1)
7196      {
7197        delete omega2;
7198        delete next_vect;
7199        //delete altomega;
7200        if(printout > 0)
7201        {
7202          Print("\n//** rec_fractal_call: Correct cone. (5) Leaving the %d-th recursion with %d steps.\n",
7203              nlev, nwalks);
7204        }
7205        if(printout>2)
7206        {
7207          idString(Gt,"//** rec_fractal_call: Gt");
7208        }
7209        return (Gt);
7210      }
7211      else
7212      {
7213        if(printout > 0)
7214        {
7215          PrintS("\n//** rec_fractal_call: Wrong cone. Tau doesn't stay in the correct cone.\n");
7216        }
7217
7218#ifndef  MSTDCC_FRACTAL
7219        intvec* Xtautmp;
7220        if(ivtarget->length() == nV)
7221        {
7222          Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
7223        }
7224        else
7225        {
7226          Xtautmp = Mfpertvector(Gt, ivtarget);
7227        }
7228#ifdef TEST_OVERFLOW
7229      if(Overflow_Error == TRUE)
7230      Gt = NULL; return(Gt);
7231#endif
7232
7233        if(MivSame(Xtau, Xtautmp) == 1)
7234        {
7235          if(printout > 0)
7236          {
7237            PrintS("\n//** rec_fractal_call: Updated vectors are equal to the old vectors.\n");
7238          }
7239          delete Xtautmp;
7240          goto FRACTAL_MSTDCC;
7241        }
7242
7243        Xtau = Xtautmp;
7244        Xtautmp = NULL;
7245
7246        for(i=nV-1; i>=0; i--)
7247          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7248
7249        rChangeCurrRing(oRing);
7250        G = idrMoveR(Gt, testring,currRing);
7251
7252        goto NEXT_VECTOR_FRACTAL;
7253#endif
7254
7255      FRACTAL_MSTDCC:
7256        if(printout > 0)
7257        {
7258          Print("\n//** rec_fractal_call: Wrong cone. Applying Buchberger's algorithm in ring = %s.\n",
7259                rString(currRing));
7260        }
7261#ifdef TIME_TEST
7262        to=clock();
7263#endif
7264        G = MstdCC(Gt);
7265#ifdef TIME_TEST
7266        xtextra=xtextra+clock()-to;
7267#endif
7268        oRing = currRing;
7269
7270        // update the original target vector w.r.t. the current GB
7271        if(ivtarget->length() == nV)
7272        {
7273/*
7274          if(MivSame(Xivinput, Xivlp) == 1)
7275            if (rParameter(currRing) != NULL)
7276              DefRingParlp();
7277            else
7278              VMrDefaultlp();
7279          else
7280            if (rParameter(currRing) != NULL)
7281              DefRingPar(Xivinput);
7282            else
7283              rChangeCurrRing(VMrDefault(Xivinput));
7284*/
7285          rChangeCurrRing(VMrRefine(ivtarget,Xivinput));
7286        }
7287        else
7288        {
7289          rChangeCurrRing(VMatrRefine(ivtarget,Xivinput));
7290        }
7291        testring = currRing;
7292        Gt = idrMoveR(G, oRing,currRing);
7293
7294        // perturb the original target vector w.r.t. the current GB
7295        if(ivtarget->length() == nV)
7296        {
7297          delete Xtau;
7298          Xtau = NewVectorlp(Gt);
7299        }
7300        else
7301        {
7302          delete Xtau;
7303          Xtau = Mfpertvector(Gt,ivtarget);
7304        }
7305
7306        rChangeCurrRing(oRing);
7307        G = idrMoveR(Gt, testring,currRing);
7308
7309        delete omega2;
7310        delete next_vect;
7311        //delete altomega;
7312        if(printout > 0)
7313        {
7314          Print("\n//** rec_fractal_call: Vectors updated. (6) Leaving the %d-th recursion with %d steps.\n",
7315              nlev, nwalks);
7316          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7317        }
7318        if(Overflow_Error == TRUE)
7319          nnflow ++;
7320
7321        Overflow_Error = FALSE;
7322        return(G);
7323      }
7324    }// end of (if next_vect==nullvector)
7325
7326    for(i=nV-1; i>=0; i--) {
7327      //(*altomega)[i] = (*omega)[i];
7328      (*omega)[i] = (*next_vect)[i];
7329    }
7330    delete next_vect;
7331#ifdef TIME_TEST
7332    to=clock();
7333#endif
7334    // Take the initial form of <G> w.r.t. omega
7335    Gomega = MwalkInitialForm(G, omega);
7336#ifdef TIME_TEST
7337    xtif=xtif+clock()-to;
7338#endif
7339#ifdef CHECK_IDEAL_MWALK
7340    if(printout > 1)
7341    {
7342      idString(Gomega,"//** rec_fractal_call: Gomega");
7343    }
7344#endif
7345    if(reduction == 0)
7346    {
7347      // Check whether the intermediate weight vector lies in the interior of the cone.
7348      // If so, only perform reductions. Otherwise apply Buchberger's algorithm.
7349      FF = middleOfCone(G,Gomega);
7350      if( FF != NULL)
7351      {
7352        idDelete(&G);
7353        G = idCopy(FF);
7354        idDelete(&FF);
7355        // Compue next vector.
7356        goto NEXT_VECTOR_FRACTAL;
7357      }
7358    }
7359
7360#ifndef  BUCHBERGER_ALG
7361    if(isNolVector(omega) == 0)
7362      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
7363    else
7364      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
7365#endif
7366
7367    if(ivtarget->length() == nV)
7368    {
7369/*
7370      if (rParameter(currRing) != NULL)
7371        DefRingPar(omega);
7372      else
7373        rChangeCurrRing(VMrDefault(omega));
7374*/
7375      rChangeCurrRing(VMrRefine(ivtarget,omega));
7376    }
7377    else
7378    {
7379      rChangeCurrRing(VMatrRefine(ivtarget,omega));
7380    }
7381    Gomega1 = idrMoveR(Gomega, oRing,currRing);
7382
7383    // Maximal recursion depth, to compute a red. GB
7384    // Fractal walk with the alternative recursion
7385    // alternative recursion
7386    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
7387    {
7388      if(printout > 1)
7389      {
7390        PrintS("\n//** rec_fractal_call: Maximal recursion depth.\n");
7391      }
7392#ifdef TIME_TEST
7393      to=clock();
7394#endif
7395#ifdef  BUCHBERGER_ALG
7396      Gresult = MstdhomCC(Gomega1);
7397#else
7398      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
7399      delete hilb_func;
7400#endif
7401#ifdef TIME_TEST
7402      xtstd=xtstd+clock()-to;
7403#endif
7404    }
7405    else
7406    {
7407      rChangeCurrRing(oRing);
7408      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
7409      Gresult = rec_fractal_call(idCopy(Gomega1),nlev+1,omega,reduction,printout);
7410    }
7411#ifdef CHECK_IDEAL_MWALK
7412    if(printout > 2)
7413    {
7414      idString(Gresult,"//** rec_fractal_call: M");
7415    }
7416#endif
7417    //convert a Groebner basis from a ring to another ring
7418    new_ring = currRing;
7419
7420    rChangeCurrRing(oRing);
7421    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
7422    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
7423#ifdef TIME_TEST
7424    to=clock();
7425#endif
7426    // Lifting process
7427    F = MLifttwoIdeal(Gomega2, Gresult1, G);
7428#ifdef TIME_TEST
7429    xtlift=xtlift+clock()-to;
7430#endif
7431#ifdef CHECK_IDEAL_MWALK
7432    if(printout > 2)
7433    {
7434      idString(F,"//** rec_fractal_call: F");
7435    }
7436#endif
7437    id_Normalize(F,currRing);
7438    idDelete(&Gresult1);
7439    idDelete(&Gomega2);
7440    idDelete(&G);
7441
7442    rChangeCurrRing(new_ring);
7443    G = idrMoveR(F,oRing,currRing);
7444/*
7445    ideal F1 = idrMoveR(F, oRing,currRing);
7446#ifdef TIME_TEST
7447    to=clock();
7448#endif
7449    // Interreduce G
7450    G = kInterRedCC(F1, NULL);
7451#ifdef TIME_TEST
7452    xtred=xtred+clock()-to;
7453#endif
7454    idDelete(&F1);
7455*/
7456  }
7457}
7458
7459/************************************************************************
7460 * Perturb the start weight vector at the top level with random element *
7461 ************************************************************************/
7462static ideal rec_r_fractal_call(ideal G, int nlev, intvec* ivtarget,
7463                int weight_rad, int reduction, int printout)
7464{
7465  Overflow_Error =  FALSE;
7466  //Print("\n\n// Entering the %d-th recursion:", nlev);
7467
7468  int nwalks = 0,i,nV=currRing->N;//polylength
7469  ring new_ring, testring;
7470  //ring extoRing;
7471  ideal Gomega, Gomega1, Gomega2, F, FF, Gresult, Gresult1, G1, Gt;
7472#ifdef TIME_TEST
7473  ideal F1;
7474#endif
7475  intvec* Mwlp;
7476#ifndef BUCHBERGER_ALG
7477  intvec* hilb_func;
7478#endif
7479//  intvec* extXtau;
7480  intvec* next_vect;
7481  intvec* iv_M;
7482  intvec* omega2 = new intvec(nV);
7483  intvec* omtmp = new intvec(nV);
7484  intvec* altomega = new intvec(nV);
7485
7486  //BOOLEAN isnewtarget = FALSE;
7487
7488  for(i = nV -1; i>=0; i--)
7489  {
7490    (*omtmp)[i] = (*ivtarget)[i];
7491  }
7492  // to avoid (1,0,...,0) as the target vector (Hans)
7493  intvec* last_omega = new intvec(nV);
7494  for(i=nV-1; i>0; i--)
7495    (*last_omega)[i] = 1;
7496  (*last_omega)[0] = 10000;
7497
7498  intvec* omega = new intvec(nV);
7499  for(i=0; i<nV; i++) {
7500    if(Xsigma->length() == nV)
7501      (*omega)[i] =  (*Xsigma)[i];
7502    else
7503      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
7504
7505    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7506  }
7507
7508   if(nlev == 1)  Xcall = 1;
7509   else Xcall = 0;
7510
7511  ring oRing = currRing;
7512
7513  while(1)
7514  {
7515#ifdef FIRST_STEP_FRACTAL
7516    /*
7517    perturb the current weight vector only on the top level or
7518    after perturbation of the both vectors, nlev = 2 as the top level
7519    */
7520    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
7521      if(islengthpoly2(G) == 1)
7522      {
7523        Mwlp = MivWeightOrderlp(omega);
7524        Xsigma = Mfpertvector(G, Mwlp);
7525        delete Mwlp;
7526        Overflow_Error = FALSE;
7527      }
7528#endif
7529    nwalks ++;
7530    NEXT_VECTOR_FRACTAL:
7531#ifdef TIME_TEST
7532    to=clock();
7533#endif
7534    /* determine the next border */
7535    next_vect = MkInterRedNextWeight(omega,omega2,G);
7536#ifdef TIME_TEST
7537    xtnw=xtnw+clock()-to;
7538#endif
7539    if(lengthpoly(MwalkInitialForm(G, next_vect)) > 0 && G->m[0] != NULL)
7540    {
7541      if(printout > 0)
7542      {
7543        PrintS("\n**// rec_r_fractal_call: there is a polynomial in Gomega with at least 3 monomials.\n");
7544      }
7545      delete next_vect;
7546      iv_M = MivMatrixOrder(omega);
7547#ifdef TIME_TEST
7548      to=clock();
7549#endif
7550      next_vect = MWalkRandomNextWeight(G,iv_M,omega2,weight_rad,nlev);
7551#ifdef TIME_TEST
7552      xtnw=xtnw+clock()-to;
7553#endif
7554      if(isNegNolVector(next_vect) == 1)
7555      {
7556        delete next_vect;
7557#ifdef TIME_TEST
7558        to=clock();
7559#endif
7560        next_vect = MkInterRedNextWeight(omega,omega2,G);
7561#ifdef TIME_TEST
7562        xtnw=xtnw+clock()-to;
7563#endif
7564      }
7565    }
7566    oRing = currRing;
7567
7568    // We only perturb the current target vector at the recursion  level 1
7569    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
7570      if (MivComp(next_vect, omega2) == 1)
7571      {
7572        // to dispense with taking initials and lifting/interreducing
7573        // after the call of recursion.
7574        if(printout > 0)
7575        {
7576          Print("\n//** rec_r_fractal_call: Perturb both vectors with degree %d.",nlev);
7577          //idElements(G, "G");
7578        }
7579        Xngleich = 1;
7580        nlev +=1;
7581        if(ivtarget->length() == nV)
7582        {
7583/*
7584          if (rParameter(currRing) != NULL)
7585            DefRingPar(omtmp);
7586          else
7587            rChangeCurrRing(VMrDefault(omtmp));
7588*/
7589          rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7590        }
7591        else
7592        {
7593          //rChangeCurrRing(VMatrDefault(ivtarget));
7594          rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7595        }
7596        testring = currRing;
7597        Gt = idrMoveR(G, oRing,currRing);
7598
7599        // perturb the original target vector w.r.t. the current GB
7600        if(ivtarget->length() == nV)
7601        {
7602          delete Xtau;
7603          Xtau = NewVectorlp(Gt);
7604        }
7605        else
7606        {
7607          delete Xtau;
7608          Xtau = Mfpertvector(Gt,ivtarget);
7609        }
7610
7611        rChangeCurrRing(oRing);
7612        G = idrMoveR(Gt,testring,currRing);
7613
7614        // perturb the current vector w.r.t. the current GB
7615        Mwlp = MivWeightOrderlp(omega);
7616        if(ivtarget->length() > nV)
7617        {
7618          delete Mwlp;
7619          Mwlp = MivMatrixOrderRefine(omega,ivtarget);
7620        }
7621        Xsigma = Mfpertvector(G, Mwlp);
7622        delete Mwlp;
7623
7624        for(i=nV-1; i>=0; i--)
7625        {
7626          (*omega2)[i] = (*Xtau)[nV+i];
7627          (*omega)[i] = (*Xsigma)[nV+i];
7628        }
7629
7630        delete next_vect;
7631
7632   //to avoid the value of Overflow_Error that occur in Mfpertvector
7633        Overflow_Error = FALSE;
7634#ifdef TIME_TEST
7635        to=clock();
7636#endif
7637        next_vect = MkInterRedNextWeight(omega,omega2,G);
7638#ifdef TIME_TEST
7639        xtnw=xtnw+clock()-to;
7640#endif
7641        if(lengthpoly(MwalkInitialForm(G, next_vect)) > 0 && G->m[0] != NULL)
7642        {
7643          // there is a polynomial in Gomega with at least 3 monomials
7644          iv_M = MivMatrixOrder(omega);
7645          delete next_vect;
7646#ifdef TIME_TEST
7647          to=clock();
7648#endif
7649          next_vect = MWalkRandomNextWeight(G,iv_M,omega2,weight_rad,nlev);
7650#ifdef TIME_TEST
7651          xtnw=xtnw+clock()-to;
7652#endif
7653          delete iv_M;
7654          if(isNegNolVector(next_vect) == 1)
7655          {
7656            delete next_vect;
7657#ifdef TIME_TEST
7658            to=clock();
7659#endif
7660            next_vect = MkInterRedNextWeight(omega,omega2,G);
7661#ifdef TIME_TEST
7662        xtnw=xtnw+clock()-to;
7663#endif
7664          }
7665        }
7666      }
7667#ifdef PRINT_VECTORS
7668      if(printout > 0)
7669      {
7670        MivString(omega, omega2, next_vect);
7671      }
7672#endif
7673
7674/*     check whether the the computed vector is in the correct cone
7675       If no, the reduced GB of an omega-homogeneous ideal will be
7676       computed by Buchberger algorithm and stop this recursion step
7677*/
7678    if(Overflow_Error == TRUE || test_w_in_ConeCC(G,next_vect) != 1)//e.g. Example s7, cyc6
7679    {
7680      delete next_vect;
7681      if(ivtarget->length() == nV)
7682      {
7683/*
7684        if (rParameter(currRing) != NULL)
7685        {
7686          DefRingPar(omtmp);
7687        }
7688        else
7689        {
7690          rChangeCurrRing(VMrDefault(omtmp));
7691        }
7692*/
7693        rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7694      }
7695      else
7696      {
7697        //rChangeCurrRing(VMatrDefault(ivtarget));
7698        rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7699      }
7700#ifdef TEST_OVERFLOW
7701      Gt = idrMoveR(G, oRing,currRing);
7702      Gt = NULL;
7703      return(Gt);
7704#endif
7705      if(printout > 0)
7706      {
7707        Print("\n//** rec_r_fractal_call: applying Buchberger's algorithm in ring r = %s;",
7708              rString(currRing));
7709      }
7710      Gt = idrMoveR(G, oRing,currRing);
7711#ifdef TIME_TEST
7712      to=clock();
7713#endif
7714      G1 = MstdCC(Gt);
7715#ifdef TIME_TEST
7716      xtextra=xtextra+clock()-to;
7717#endif
7718      Gt = NULL;
7719
7720      delete omega2;
7721      delete altomega;
7722      if(printout > 0)
7723      {
7724        Print("\n//** rec_r_fractal_call: (1) Leaving the %d-th recursion with %d steps.\n",
7725              nlev, nwalks);
7726        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7727      }
7728      nnflow ++;
7729      Overflow_Error = FALSE;
7730      return (G1);
7731    }
7732    /*
7733       If the perturbed target vector stays in the correct cone,
7734       return the current Groebner basis.
7735       Otherwise, return the Groebner basis computed with Buchberger's
7736       algorithm.
7737       Then we update the perturbed target vectors w.r.t. this GB.
7738    */
7739    if (MivComp(next_vect, XivNull) == 1)
7740    {
7741      // The computed vector is equal to the origin vector,
7742      // because t is not defined
7743      if(ivtarget->length() == nV)
7744      {
7745/*
7746        if (rParameter(currRing) != NULL)
7747          DefRingPar(omtmp);
7748        else
7749          rChangeCurrRing(VMrDefault(omtmp));
7750*/
7751        rChangeCurrRing(VMrRefine(ivtarget,omtmp));
7752      }
7753      else
7754      {
7755        //rChangeCurrRing(VMatrDefault(ivtarget));
7756        rChangeCurrRing(VMatrRefine(ivtarget,omtmp));
7757      }
7758      testring = currRing;
7759      Gt = idrMoveR(G, oRing,currRing);
7760
7761      if(test_w_in_ConeCC(Gt, omega2) == 1)
7762      {
7763        delete omega2;
7764        delete next_vect;
7765        delete altomega;
7766        if(printout > 0)
7767        {
7768          Print("\n//** rec_r_fractal_call: (2) Leaving the %d-th recursion with %d steps.\n",
7769                nlev, nwalks);
7770          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7771        }
7772        return (Gt);
7773      }
7774      else
7775      {
7776        if(printout > 0)
7777        {
7778          Print("\n//** rec_r_fractal_call: target weight doesn't stay in the correct cone.\n");
7779        }
7780
7781#ifndef  MSTDCC_FRACTAL
7782#ifdef PRINT_VECTORS
7783        if(printout > 0)
7784        {
7785          ivString(Xtau, "old Xtau");
7786        }
7787#endif
7788        intvec* Xtautmp;
7789        if(ivtarget->length() == nV)
7790        {
7791          Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
7792        }
7793        else
7794        {
7795          Xtautmp = Mfpertvector(Gt, ivtarget);
7796        }
7797#ifdef TEST_OVERFLOW
7798      if(Overflow_Error == TRUE)
7799      Gt = NULL; return(Gt);
7800#endif
7801
7802        if(MivSame(Xtau, Xtautmp) == 1)
7803        {
7804          //PrintS("\n// Update vectors are equal to the old vectors!!");
7805          delete Xtautmp;
7806          goto FRACTAL_MSTDCC;
7807        }
7808
7809        Xtau = Xtautmp;
7810        Xtautmp = NULL;
7811#ifdef PRINT_VECTORS
7812        if(printout > 0)
7813        {
7814          ivString(Xtau, "new  Xtau");
7815        }
7816#endif
7817
7818        for(i=nV-1; i>=0; i--)
7819          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7820
7821        //Print("\n//  ring tau = %s;", rString(currRing));
7822        rChangeCurrRing(oRing);
7823        G = idrMoveR(Gt, testring,currRing);
7824
7825        goto NEXT_VECTOR_FRACTAL;
7826#endif
7827
7828      FRACTAL_MSTDCC:
7829        if(printout > 0)
7830        {
7831          Print("\n//** rec_r_fractal_call: apply Buchberger's algorithm in ring = %s.\n",
7832                rString(currRing));
7833        }
7834#ifdef TIME_TEST
7835        to=clock();
7836#endif
7837        G = MstdCC(Gt);
7838#ifdef TIME_TEST
7839        xtextra=xtextra+clock()-to;
7840#endif
7841        oRing = currRing;
7842
7843        // update the original target vector w.r.t. the current GB
7844        if(ivtarget->length() == nV)
7845        {
7846/*
7847          if(MivSame(Xivinput, Xivlp) == 1)
7848            if (rParameter(currRing) != NULL)
7849              DefRingParlp();
7850            else
7851              VMrDefaultlp();
7852          else
7853            if (rParameter(currRing) != NULL)
7854              DefRingPar(Xivinput);
7855            else
7856              rChangeCurrRing(VMrDefault(Xivinput));
7857*/
7858          rChangeCurrRing(VMrRefine(ivtarget,Xivinput));
7859        }
7860        else
7861        {
7862          rChangeCurrRing(VMatrRefine(ivtarget,Xivinput));
7863        }
7864        testring = currRing;
7865        Gt = idrMoveR(G, oRing,currRing);
7866
7867        // perturb the original target vector w.r.t. the current GB
7868        if(ivtarget->length() == nV)
7869        {
7870          delete Xtau;
7871          Xtau = NewVectorlp(Gt);
7872        }
7873        else
7874        {
7875          delete Xtau;
7876          Xtau = Mfpertvector(Gt,ivtarget);
7877        }
7878
7879        rChangeCurrRing(oRing);
7880        G = idrMoveR(Gt, testring,currRing);
7881
7882        delete omega2;
7883        delete next_vect;
7884        delete altomega;
7885        if(printout > 0)
7886        {
7887          Print("\n//** rec_r_fractal_call: (3) Leaving the %d-th recursion with %d steps.\n",
7888                nlev,nwalks);
7889          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7890        }
7891        if(Overflow_Error == TRUE)
7892          nnflow ++;
7893
7894        Overflow_Error = FALSE;
7895        return(G);
7896      }
7897    } //end of if(MivComp(next_vect, XivNull) == 1)
7898
7899    for(i=nV-1; i>=0; i--)
7900    {
7901      (*altomega)[i] = (*omega)[i];
7902      (*omega)[i] = (*next_vect)[i];
7903    }
7904    delete next_vect;
7905#ifdef TIME_TEST
7906    to=clock();
7907#endif
7908    // Take the initial form of <G> w.r.t. omega
7909    Gomega = MwalkInitialForm(G, omega);
7910#ifdef TIME_TEST
7911    xtif=xtif+clock()-to;
7912#endif
7913    //polylength = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
7914    //polylength = lengthpoly(Gomega);
7915#ifdef CHECK_IDEAL_MWALK
7916    if(printout > 1)
7917    {
7918      idString(Gomega,"//** rec_r_fractal_call: Gomega");
7919    }
7920#endif
7921    if(reduction == 0)
7922    {
7923      /* Check whether the intermediate weight vector lies in the interior of the cone.
7924       * If so, only perform reductions. Otherwise apply Buchberger's algorithm. */
7925      FF = middleOfCone(G,Gomega);
7926      if( FF != NULL)
7927      {
7928        idDelete(&G);
7929        G = idCopy(FF);
7930        idDelete(&FF);
7931        /* Compue next vector. */
7932        goto NEXT_VECTOR_FRACTAL;
7933      }
7934    }
7935
7936#ifndef  BUCHBERGER_ALG
7937    if(isNolVector(omega) == 0)
7938      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
7939    else
7940      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
7941#endif
7942    if(ivtarget->length() == nV)
7943    {
7944/*
7945      if (rParameter(currRing) != NULL)
7946        DefRingPar(omega);
7947      else
7948        rChangeCurrRing(VMrDefault(omega));
7949*/
7950      rChangeCurrRing(VMrRefine(ivtarget,omega));
7951    }
7952    else
7953    {
7954      rChangeCurrRing(VMatrRefine(ivtarget,omega));
7955    }
7956    Gomega1 = idrMoveR(Gomega, oRing,currRing);
7957
7958    // Maximal recursion depth, to compute a red. GB
7959    // Fractal walk with the alternative recursion
7960    // alternative recursion
7961    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
7962    {
7963#ifdef TIME_TEST
7964      to=clock();
7965#endif
7966#ifdef  BUCHBERGER_ALG
7967      Gresult = MstdhomCC(Gomega1);
7968#else
7969      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
7970      delete hilb_func;
7971#endif
7972#ifdef TIME_TEST
7973      xtstd=xtstd+clock()-to;
7974#endif
7975    }
7976    else
7977    {
7978      rChangeCurrRing(oRing);
7979      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
7980      Gresult = rec_r_fractal_call(idCopy(Gomega1),nlev+1,omega,weight_rad,reduction,printout);
7981    }
7982#ifdef CHECK_IDEAL_MWALK
7983    if(printout > 2)
7984    {
7985      idString(Gresult,"//** rec_r_fractal_call: M");
7986    }
7987#endif
7988    //convert a Groebner basis from a ring to another ring
7989    new_ring = currRing;
7990
7991    rChangeCurrRing(oRing);
7992    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
7993    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
7994#ifdef TIME_TEST
7995    to=clock();
7996#endif
7997    // Lifting process
7998    F = MLifttwoIdeal(Gomega2, Gresult1, G);
7999#ifdef TIME_TEST
8000    xtlift=xtlift+clock()-to;
8001#endif
8002#ifdef CHECK_IDEAL_MWALK
8003    if(printout > 2)
8004    {
8005      idString(F,"//** rec_r_fractal_call: F");
8006    }
8007#endif
8008    id_Normalize(F,currRing);
8009    idDelete(&Gresult1);
8010    idDelete(&Gomega2);
8011    idDelete(&G);
8012
8013    rChangeCurrRing(new_ring);
8014    //F1 = idrMoveR(F, oRing,currRing);
8015    G = idrMoveR(F,oRing,currRing);
8016/*
8017#ifdef TIME_TEST
8018    to=clock();
8019#endif
8020    // Interreduce G
8021    G = kInterRedCC(F1, NULL);
8022#ifdef TIME_TEST
8023    xtred=xtred+clock()-to;
8024#endif
8025    idDelete(&F1);
8026*/
8027  }
8028}
8029
8030
8031/*******************************************************************************
8032 * The implementation of the fractal walk algorithm                            *
8033 *                                                                             *
8034 * The main procedure Mfwalk calls the recursive Subroutine                    *
8035 * rec_fractal_call to compute the wanted Groebner basis.                      *
8036 * At the main procedur we compute the reduced Groebner basis w.r.t. a "fast"  *
8037 * order, e.g. "dp" and a sequence of weight vectors which are row vectors     *
8038 * of a matrix. This matrix defines the given monomial order, e.g. "lp"        *
8039 *******************************************************************************/
8040ideal Mfwalk(ideal G, intvec* ivstart, intvec* ivtarget,
8041             int reduction, int printout)
8042{
8043  BITSET save1 = si_opt_1; // save current options
8044  if(reduction == 0)
8045  {
8046    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
8047    //si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
8048  }
8049  Set_Error(FALSE);
8050  Overflow_Error = FALSE;
8051  //Print("// pSetm_Error = (%d)", ErrorCheck());
8052  //Print("\n// ring ro = %s;", rString(currRing));
8053
8054  nnflow = 0;
8055  Xngleich = 0;
8056  Xcall = 0;
8057#ifdef TIME_TEST
8058  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
8059  xftinput = clock();
8060#endif
8061  ring  oldRing = currRing;
8062  int i, nV = currRing->N;
8063  XivNull = new intvec(nV);
8064  Xivinput = ivtarget;
8065  ngleich = 0;
8066#ifdef TIME_TEST
8067  to=clock();
8068#endif
8069  ideal I = MstdCC(G);
8070  G = NULL;
8071#ifdef TIME_TEST
8072  xftostd=clock()-to;
8073#endif
8074  Xsigma = ivstart;
8075
8076  Xnlev=nV;
8077
8078#ifdef FIRST_STEP_FRACTAL
8079  ideal Gw = MwalkInitialForm(I, ivstart);
8080  for(i=IDELEMS(Gw)-1; i>=0; i--)
8081  {
8082    if((Gw->m[i]!=NULL) // len >=0
8083    && (Gw->m[i]->next!=NULL) // len >=1
8084    && (Gw->m[i]->next->next!=NULL)) // len >=2
8085    {
8086      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
8087      intvec* Mdp;
8088      if(ivstart->length() == nV)
8089      {
8090        if(MivSame(ivstart, iv_dp) != 1)
8091          Mdp = MivWeightOrderdp(ivstart);
8092        else
8093          Mdp = MivMatrixOrderdp(nV);
8094      }
8095      else
8096      {
8097        Mdp = ivstart;
8098      }
8099
8100      Xsigma = Mfpertvector(I, Mdp);
8101      Overflow_Error = FALSE;
8102
8103      delete Mdp;
8104      delete iv_dp;
8105      break;
8106    }
8107  }
8108  idDelete(&Gw);
8109#endif
8110
8111  ideal I1;
8112  intvec* Mlp;
8113  Xivlp = Mivlp(nV);
8114
8115  if(ivtarget->length() == nV)
8116  {
8117    if(MivComp(ivtarget, Xivlp)  != 1)
8118    {
8119      if (rParameter(currRing) != NULL)
8120        DefRingPar(ivtarget);
8121      else
8122        rChangeCurrRing(VMrDefault(ivtarget));
8123
8124      I1 = idrMoveR(I, oldRing,currRing);
8125      Mlp = MivWeightOrderlp(ivtarget);
8126      Xtau = Mfpertvector(I1, Mlp);
8127    }
8128    else
8129    {
8130      if (rParameter(currRing) != NULL)
8131        DefRingParlp();
8132      else
8133        VMrDefaultlp();
8134
8135      I1 = idrMoveR(I, oldRing,currRing);
8136      Mlp =  MivMatrixOrderlp(nV);
8137      Xtau = Mfpertvector(I1, Mlp);
8138    }
8139  }
8140  else
8141  {
8142    rChangeCurrRing(VMatrDefault(ivtarget));
8143    I1 = idrMoveR(I,oldRing,currRing);
8144    Mlp =  ivtarget;
8145    Xtau = Mfpertvector(I1, Mlp);
8146  }
8147  delete Mlp;
8148  Overflow_Error = FALSE;
8149
8150  //ivString(Xsigma, "Xsigma");
8151  //ivString(Xtau, "Xtau");
8152
8153  id_Delete(&I, oldRing);
8154  ring tRing = currRing;
8155  if(ivtarget->length() == nV)
8156  {
8157/*
8158    if (rParameter(currRing) != NULL)
8159      DefRingPar(ivstart);
8160    else
8161      rChangeCurrRing(VMrDefault(ivstart));
8162*/
8163    rChangeCurrRing(VMrRefine(ivtarget,ivstart));
8164  }
8165  else
8166  {
8167    //rChangeCurrRing(VMatrDefault(ivstart));
8168    rChangeCurrRing(VMatrRefine(ivtarget,ivstart));
8169  }
8170
8171  I = idrMoveR(I1,tRing,currRing);
8172#ifdef TIME_TEST
8173  to=clock();
8174#endif
8175  ideal J = MstdCC(I);
8176  idDelete(&I);
8177#ifdef TIME_TEST
8178  xftostd=xftostd+clock()-to;
8179#endif
8180  ideal resF;
8181  ring helpRing = currRing;
8182
8183  J = rec_fractal_call(J,1,ivtarget,reduction,printout);
8184  //idString(J,"//** Mfwalk: J");
8185  rChangeCurrRing(oldRing);
8186  //Print("\n//Mfwalk: (2)\n");
8187  resF = idrMoveR(J, helpRing,currRing);
8188  //Print("\n//Mfwalk: (3)\n");
8189  idSkipZeroes(resF);
8190  //Print("\n//Mfwalk: (4)\n");
8191
8192  si_opt_1 = save1; //set original options, e. g. option(RedSB)
8193  delete Xivlp;
8194  //delete Xsigma;
8195  delete Xtau;
8196  delete XivNull;
8197  //Print("\n//Mfwalk: (5)\n");
8198#ifdef TIME_TEST
8199  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
8200                    xtlift, xtred, xtnw);
8201
8202
8203  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
8204  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8205  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
8206#endif
8207  //Print("\n//Mfwalk: (6)\n");
8208  //idString(resF,"//** Mfwalk: resF");
8209  return(idCopy(resF));
8210}
8211
8212/*******************************************************************************
8213 * The implementation of the fractal walk algorithm with random element        *
8214 *                                                                             *
8215 * The main procedur Mfwalk calls the recursive Subroutine                     *
8216 * rec_r_fractal_call to compute the wanted Groebner basis.                    *
8217 * At the main procedure we compute the reduced Groebner basis w.r.t. a "fast" *
8218 * order, e.g. "dp" and a sequence of weight vectors which are row vectors     *
8219 * of a matrix. This matrix defines the given monomial order, e.g. "lp"        *
8220 *******************************************************************************/
8221ideal Mfrwalk(ideal G, intvec* ivstart, intvec* ivtarget,
8222              int weight_rad, int reduction, int printout)
8223{
8224  BITSET save1 = si_opt_1; // save current options
8225  //check that weight radius is valid
8226  if(weight_rad < 0)
8227  {
8228    WerrorS("Invalid radius.\n");
8229    return NULL;
8230  }
8231  if(reduction == 0)
8232  {
8233    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
8234    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
8235  }
8236  Set_Error(FALSE);
8237  Overflow_Error = FALSE;
8238  //Print("// pSetm_Error = (%d)", ErrorCheck());
8239  //Print("\n// ring ro = %s;", rString(currRing));
8240
8241  nnflow = 0;
8242  Xngleich = 0;
8243  Xcall = 0;
8244#ifdef TIME_TEST
8245  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
8246  xftinput = clock();
8247#endif
8248  ring  oldRing = currRing;
8249  int i, nV = currRing->N;
8250  XivNull = new intvec(nV);
8251  Xivinput = ivtarget;
8252  ngleich = 0;
8253#ifdef TIME_TEST
8254  to=clock();
8255#endif
8256  ideal I = MstdCC(G);
8257  G = NULL;
8258#ifdef TIME_TEST
8259  xftostd=clock()-to;
8260#endif
8261  Xsigma = ivstart;
8262
8263  Xnlev=nV;
8264
8265#ifdef FIRST_STEP_FRACTAL
8266  ideal Gw = MwalkInitialForm(I, ivstart);
8267  for(i=IDELEMS(Gw)-1; i>=0; i--)
8268  {
8269    if((Gw->m[i]!=NULL) // len >=0
8270    && (Gw->m[i]->next!=NULL) // len >=1
8271    && (Gw->m[i]->next->next!=NULL)) // len >=2
8272    {
8273      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
8274      intvec* Mdp;
8275      if(ivstart->length() == nV)
8276      {
8277        if(MivSame(ivstart, iv_dp) != 1)
8278          Mdp = MivWeightOrderdp(ivstart);
8279        else
8280          Mdp = MivMatrixOrderdp(nV);
8281      }
8282      else
8283      {
8284        Mdp = ivstart;
8285      }
8286
8287      Xsigma = Mfpertvector(I, Mdp);
8288      Overflow_Error = FALSE;
8289
8290      delete Mdp;
8291      delete iv_dp;
8292      break;
8293    }
8294  }
8295  idDelete(&Gw);
8296#endif
8297
8298  ideal I1;
8299  intvec* Mlp;
8300  Xivlp = Mivlp(nV);
8301
8302  if(ivtarget->length() == nV)
8303  {
8304    if(MivComp(ivtarget, Xivlp)  != 1)
8305    {
8306      if (rParameter(currRing) != NULL)
8307        DefRingPar(ivtarget);
8308      else
8309        rChangeCurrRing(VMrDefault(ivtarget));
8310
8311      I1 = idrMoveR(I, oldRing,currRing);
8312      Mlp = MivWeightOrderlp(ivtarget);
8313      Xtau = Mfpertvector(I1, Mlp);
8314    }
8315    else
8316    {
8317      if (rParameter(currRing) != NULL)
8318        DefRingParlp();
8319      else
8320        VMrDefaultlp();
8321
8322      I1 = idrMoveR(I, oldRing,currRing);
8323      Mlp =  MivMatrixOrderlp(nV);
8324      Xtau = Mfpertvector(I1, Mlp);
8325    }
8326  }
8327  else
8328  {
8329    rChangeCurrRing(VMatrDefault(ivtarget));
8330    I1 = idrMoveR(I,oldRing,currRing);
8331    Mlp =  ivtarget;
8332    Xtau = Mfpertvector(I1, Mlp);
8333  }
8334  delete Mlp;
8335  Overflow_Error = FALSE;
8336
8337  //ivString(Xsigma, "Xsigma");
8338  //ivString(Xtau, "Xtau");
8339
8340  id_Delete(&I, oldRing);
8341  ring tRing = currRing;
8342  if(ivtarget->length() == nV)
8343  {
8344/*
8345    if (rParameter(currRing) != NULL)
8346      DefRingPar(ivstart);
8347    else
8348      rChangeCurrRing(VMrDefault(ivstart));
8349*/
8350    rChangeCurrRing(VMrRefine(ivtarget,ivstart));
8351  }
8352  else
8353  {
8354    //rChangeCurrRing(VMatrDefault(ivstart));
8355    rChangeCurrRing(VMatrRefine(ivtarget,ivstart));
8356  }
8357
8358  I = idrMoveR(I1,tRing,currRing);
8359#ifdef TIME_TEST
8360  to=clock();
8361#endif
8362  ideal J = MstdCC(I);
8363  idDelete(&I);
8364#ifdef TIME_TEST
8365  xftostd=xftostd+clock()-to;
8366#endif
8367  ideal resF;
8368  ring helpRing = currRing;
8369
8370  J = rec_r_fractal_call(J,1,ivtarget,weight_rad,reduction,printout);
8371  //idString(J,"//*** Mfrwalk: J");
8372  //Print("\n//** Mfrwalk hier (1)\n");
8373  rChangeCurrRing(oldRing);
8374  //Print("\n//** Mfrwalk hier (2)\n");
8375  resF = idrMoveR(J, helpRing,currRing);
8376  //Print("\n//** Mfrwalk hier (3)\n");
8377  //idSkipZeroes(resF);
8378  //Print("\n//** Mfrwalk hier (4)\n");
8379  si_opt_1 = save1; //set original options, e. g. option(RedSB)
8380  delete Xivlp;
8381  //delete Xsigma;
8382  delete Xtau;
8383  delete XivNull;
8384  //Print("\n//** Mfrwalk hier (5)\n");
8385#ifdef TIME_TEST
8386  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
8387                    xtlift, xtred, xtnw);
8388
8389
8390 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
8391  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8392  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
8393#endif
8394  //Print("\n//** Mfrwalk hier (6)\n");
8395  //idString(resF,"resF");
8396  //Print("\n//** Mfrwalk hier (7)\n");
8397  return(resF);
8398}
8399
8400/*******************************************************
8401 * Tran's algorithm                                    *
8402 *                                                     *
8403 * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
8404 *******************************************************/
8405ideal TranMImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP)
8406{
8407#ifdef TIME_TEST
8408  clock_t mtim = clock();
8409#endif
8410  Set_Error(FALSE  );
8411  Overflow_Error =  FALSE;
8412  //Print("// pSetm_Error = (%d)", ErrorCheck());
8413  //Print("\n// ring ro = %s;", rString(currRing));
8414
8415#ifdef TIME_TEST
8416  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
8417  clock_t tinput = clock();
8418#endif
8419  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
8420  int *npert=(int*)omAlloc(2*nV*sizeof(int));
8421  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
8422  //ring endRing;
8423  ring newRing, oldRing, lpRing;
8424  intvec* next_weight;
8425  intvec* ivNull = new intvec(nV); //define (0,...,0)
8426  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
8427  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
8428  ideal H0;
8429  //ideal  H1;
8430  ideal H2, Glp;
8431  int nGB, endwalks = 0,  nwalkpert=0;
8432  intvec* Mlp =  MivMatrixOrderlp(nV);
8433  intvec* vector_tmp = new intvec(nV);
8434#ifndef BUCHBERGER_ALG
8435  intvec* hilb_func;
8436#endif
8437  // to avoid (1,0,...,0) as the target vector
8438  intvec* last_omega = new intvec(nV);
8439  for(i=nV-1; i>0; i--)
8440    (*last_omega)[i] = 1;
8441  (*last_omega)[0] = 10000;
8442
8443  //  intvec* extra_curr_weight = new intvec(nV);
8444  intvec* target_weight = new intvec(nV);
8445  for(i=nV-1; i>=0; i--)
8446    (*target_weight)[i] = (*target_tmp)[i];
8447
8448  ring XXRing = currRing;
8449  newRing = currRing;
8450
8451#ifdef TIME_TEST
8452  to=clock();
8453#endif
8454  // compute a red. GB w.r.t. the help ring
8455  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) = "dp"
8456    G = MstdCC(G);
8457  else
8458  {
8459    //rOrdStr(currRing) = (a(.c_w..),lp,C)
8460    if (rParameter(currRing) != NULL)
8461      DefRingPar(curr_weight);
8462    else
8463      rChangeCurrRing(VMrDefault(curr_weight));
8464    G = idrMoveR(G, XXRing,currRing);
8465    G = MstdCC(G);
8466  }
8467#ifdef TIME_TEST
8468  tostd=clock()-to;
8469#endif
8470
8471#ifdef REPRESENTATION_OF_SIGMA
8472  ideal Gw = MwalkInitialForm(G, curr_weight);
8473
8474  if(islengthpoly2(Gw)==1)
8475  {
8476    intvec* MDp;
8477    if(MivComp(curr_weight, iv_dp) == 1)
8478      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
8479    else
8480      MDp = MivWeightOrderlp(curr_weight);
8481
8482    curr_weight = RepresentationMatrix_Dp(G, MDp);
8483
8484    delete MDp;
8485
8486    ring exring = currRing;
8487
8488    if (rParameter(currRing) != NULL)
8489      DefRingPar(curr_weight);
8490    else
8491      rChangeCurrRing(VMrDefault(curr_weight));
8492#ifdef TIME_TEST
8493    to=clock();
8494#endif
8495    Gw = idrMoveR(G, exring,currRing);
8496    G = MstdCC(Gw);
8497    Gw = NULL;
8498#ifdef TIME_TEST
8499    tostd=tostd+clock()-to;
8500#endif
8501    //ivString(curr_weight,"rep. sigma");
8502    goto COMPUTE_NEW_VECTOR;
8503  }
8504
8505  idDelete(&Gw);
8506  delete iv_dp;
8507#endif
8508
8509
8510  while(1)
8511  {
8512#ifdef TIME_TEST
8513    to=clock();
8514#endif
8515    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
8516    Gomega = MwalkInitialForm(G, curr_weight);
8517#ifdef TIME_TEST
8518    tif=tif+clock()-to;
8519#endif
8520
8521#ifndef  BUCHBERGER_ALG
8522    if(isNolVector(curr_weight) == 0)
8523      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
8524    else
8525      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
8526#endif // BUCHBERGER_ALG
8527
8528    oldRing = currRing;
8529
8530    /* define a new ring that its ordering is "(a(curr_weight),lp) */
8531    if (rParameter(currRing) != NULL)
8532      DefRingPar(curr_weight);
8533    else
8534      rChangeCurrRing(VMrDefault(curr_weight));
8535
8536    newRing = currRing;
8537    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
8538
8539#ifdef TIME_TEST
8540    to=clock();
8541#endif
8542    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
8543#ifdef  BUCHBERGER_ALG
8544    M = MstdhomCC(Gomega1);
8545#else
8546    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
8547    delete hilb_func;
8548#endif // BUCHBERGER_ALG
8549#ifdef TIME_TEST
8550    tstd=tstd+clock()-to;
8551#endif
8552
8553    /* change the ring to oldRing */
8554    rChangeCurrRing(oldRing);
8555    M1 =  idrMoveR(M, newRing,currRing);
8556    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
8557
8558#ifdef TIME_TEST
8559    to=clock();
8560#endif
8561    /* compute a representation of the generators of submod (M)
8562       with respect to those of mod (Gomega).
8563       Gomega is a reduced Groebner basis w.r.t. the current ring */
8564    F = MLifttwoIdeal(Gomega2, M1, G);
8565#ifdef TIME_TEST
8566    tlift=tlift+clock()-to;
8567#endif
8568
8569    idDelete(&M1);
8570    idDelete(&Gomega2);
8571    idDelete(&G);
8572
8573    /* change the ring to newRing */
8574    rChangeCurrRing(newRing);
8575    F1 = idrMoveR(F, oldRing,currRing);
8576
8577#ifdef TIME_TEST
8578    to=clock();
8579#endif
8580    /* reduce the Groebner basis <G> w.r.t. new ring */
8581    G = kInterRedCC(F1, NULL);
8582#ifdef TIME_TEST
8583    tred=tred+clock()-to;
8584#endif
8585    idDelete(&F1);
8586
8587
8588  COMPUTE_NEW_VECTOR:
8589    newRing = currRing;
8590    nwalk++;
8591    nwalkpert++;
8592#ifdef TIME_TEST
8593    to=clock();
8594#endif
8595    // compute a next weight vector
8596    next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
8597#ifdef TIME_TEST
8598    tnw=tnw+clock()-to;
8599#endif
8600#ifdef PRINT_VECTORS
8601    MivString(curr_weight, target_weight, next_weight);
8602#endif
8603
8604    /* check whether the computed intermediate weight vector is in
8605       the correct cone; sometimes it is very big e.g. s7, cyc7.
8606       If it is NOT in the correct cone, then compute directly
8607       a reduced Groebner basis with respect to the lexicographic ordering
8608       for the known Groebner basis that it is computed in the last step.
8609    */
8610    //if(test_w_in_ConeCC(G, next_weight) != 1)
8611    if(Overflow_Error == TRUE)
8612    {
8613    OMEGA_OVERFLOW_TRAN_NEW:
8614      //Print("\n//  takes %d steps!", nwalk-1);
8615      //Print("\n//ring lastRing = %s;", rString(currRing));
8616#ifdef TEST_OVERFLOW
8617      goto  BE_FINISH;
8618#endif
8619/*
8620#ifdef CHECK_IDEAL_MWALK
8621      idElements(G, "G");
8622      //headidString(G, "G");
8623#endif
8624*/
8625      if(MivSame(target_tmp, iv_lp) == 1)
8626        if (rParameter(currRing) != NULL)
8627          DefRingParlp();
8628        else
8629          VMrDefaultlp();
8630      else
8631        if (rParameter(currRing) != NULL)
8632          DefRingPar(target_tmp);
8633        else
8634          rChangeCurrRing(VMrDefault(target_tmp));
8635
8636      lpRing = currRing;
8637      G1 = idrMoveR(G, newRing,currRing);
8638
8639#ifdef TIME_TEST
8640      to=clock();
8641#endif
8642      /*apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>*/
8643      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0){
8644        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
8645        G = MstdCC(G1);//no result for qnt1
8646      }
8647      else {
8648        rChangeCurrRing(newRing);
8649        G1 = idrMoveR(G1, lpRing,currRing);
8650
8651        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
8652        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
8653
8654        rChangeCurrRing(lpRing);
8655        G = idrMoveR(G, newRing,currRing);
8656      }
8657#ifdef TIME_TEST
8658      textra=clock()-to;
8659#endif
8660      npert[endwalks]=nwalk-npert_tmp;
8661      npert_tmp = nwalk;
8662      endwalks ++;
8663      break;
8664    }
8665
8666    /* check whether the computed Groebner basis is really a Groebner basis.
8667       If not, we perturb the target vector with the maximal "perturbation"
8668       degree.*/
8669    if(MivComp(next_weight, target_weight) == 1 ||
8670       MivComp(next_weight, curr_weight) == 1 )
8671    {
8672      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
8673
8674
8675      //compute the number of perturbations and its step
8676      npert[endwalks]=nwalk-npert_tmp;
8677      npert_tmp = nwalk;
8678
8679      endwalks ++;
8680
8681      /*it is very important if the walk only uses one step, e.g. Fate, liu*/
8682      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1){
8683        rChangeCurrRing(XXRing);
8684        G = idrMoveR(G, newRing,currRing);
8685        goto FINISH;
8686      }
8687      H0 = id_Head(G,currRing);
8688
8689      if(MivSame(target_tmp, iv_lp) == 1)
8690        if (rParameter(currRing) != NULL)
8691          DefRingParlp();
8692        else
8693          VMrDefaultlp();
8694      else
8695        if (rParameter(currRing) != NULL)
8696          DefRingPar(target_tmp);
8697        else
8698          rChangeCurrRing(VMrDefault(target_tmp));
8699
8700      lpRing = currRing;
8701      Glp = idrMoveR(G, newRing,currRing);
8702      H2 = idrMoveR(H0, newRing,currRing);
8703
8704      /* Apply Lemma 2.2 in Collart et. al (1997) to check whether
8705         cone(k-1) is equal to cone(k) */
8706      nGB = 1;
8707      for(i=IDELEMS(Glp)-1; i>=0; i--)
8708      {
8709        poly t;
8710        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
8711        {
8712          pDelete(&t);
8713          idDelete(&H2);//5.5.02
8714          nGB = 0; //i.e. Glp is no reduced Groebner basis
8715          break;
8716        }
8717        pDelete(&t);
8718      }
8719
8720      idDelete(&H2);//5.5.02
8721
8722      if(nGB == 1)
8723      {
8724        G = Glp;
8725        Glp = NULL;
8726        break;
8727      }
8728
8729       /* perturb the target weight vector, if the vector target_tmp
8730          stays in many cones */
8731      poly p;
8732      BOOLEAN plength3 = FALSE;
8733      for(i=IDELEMS(Glp)-1; i>=0; i--)
8734      {
8735        p = MpolyInitialForm(Glp->m[i], target_tmp);
8736        if(p->next != NULL &&
8737           p->next->next != NULL &&
8738           p->next->next->next != NULL)
8739        {
8740          Overflow_Error = FALSE;
8741
8742          for(i=0; i<nV; i++)
8743            (*vector_tmp)[i] = (*target_weight)[i];
8744
8745          delete target_weight;
8746          target_weight = MPertVectors(Glp, Mlp, nV);
8747
8748          if(MivComp(vector_tmp, target_weight)==1)
8749          {
8750            //PrintS("\n// The old and new representaion vector are the same!!");
8751            G = Glp;
8752            newRing = currRing;
8753            goto OMEGA_OVERFLOW_TRAN_NEW;
8754           }
8755
8756          if(Overflow_Error == TRUE)
8757          {
8758            rChangeCurrRing(newRing);
8759            G = idrMoveR(Glp, lpRing,currRing);
8760            goto OMEGA_OVERFLOW_TRAN_NEW;
8761          }
8762
8763          plength3 = TRUE;
8764          pDelete(&p);
8765          break;
8766        }
8767        pDelete(&p);
8768      }
8769
8770      if(plength3 == FALSE)
8771      {
8772        rChangeCurrRing(newRing);
8773        G = idrMoveR(Glp, lpRing,currRing);
8774        goto TRAN_LIFTING;
8775      }
8776
8777
8778      nwalkpert = 1;
8779      nsteppert ++;
8780
8781      /*
8782      Print("\n// Subroutine needs (%d) steps.", nwalk);
8783      idElements(Glp, "last G in walk:");
8784      PrintS("\n// ****************************************");
8785      Print("\n// Perturb the original target vector (%d): ", nsteppert);
8786      ivString(target_weight, "new target");
8787      PrintS("\n// ****************************************\n");
8788      */
8789      rChangeCurrRing(newRing);
8790      G = idrMoveR(Glp, lpRing,currRing);
8791
8792      delete next_weight;
8793
8794      //Print("\n// ring rNEW = %s;", rString(currRing));
8795      goto COMPUTE_NEW_VECTOR;
8796    }
8797
8798  TRAN_LIFTING:
8799    for(i=nV-1; i>=0; i--)
8800      (*curr_weight)[i] = (*next_weight)[i];
8801
8802    delete next_weight;
8803  }//while
8804#ifdef TEST_OVERFLOW
8805 BE_FINISH:
8806#endif
8807  rChangeCurrRing(XXRing);
8808  G = idrMoveR(G, lpRing,currRing);
8809
8810 FINISH:
8811  delete ivNull;
8812  delete next_weight;
8813  delete iv_lp;
8814  omFree(npert);
8815/*
8816#ifdef TIME_TEST
8817  Print("\n// Computation took %d steps and %.2f sec",
8818        nwalk, ((double) (clock()-mtim)/1000000));
8819
8820  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
8821
8822 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
8823  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8824#endif
8825*/
8826  return(G);
8827}
8828
8829#if 0
8830/*******************************************************
8831 * Tran's algorithm with random element                *
8832 *                                                     *
8833 * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
8834 *******************************************************/
8835ideal TranMrImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP, int weight_rad, int pert_deg)
8836{
8837#ifdef TIME_TEST
8838  clock_t mtim = clock();
8839#endif
8840  Set_Error(FALSE  );
8841  Overflow_Error =  FALSE;
8842  //Print("// pSetm_Error = (%d)", ErrorCheck());
8843  //Print("\n// ring ro = %s;", rString(currRing));
8844
8845#ifdef TIME_TEST
8846  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
8847  clock_t tinput = clock();
8848#endif
8849  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
8850  int *npert=(int*)omAlloc(2*nV*sizeof(int));
8851  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
8852  //ring endRing;
8853  ring newRing, oldRing, lpRing;
8854  intvec* next_weight;
8855  intvec* ivNull = new intvec(nV); //define (0,...,0)
8856  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
8857  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
8858  ideal H0;
8859  //ideal H1;
8860  ideal H2, Glp;
8861  int weight_norm, nGB, endwalks = 0,  nwalkpert=0,  npertstep=0;
8862  intvec* Mlp =  MivMatrixOrderlp(nV);
8863  intvec* vector_tmp = new intvec(nV);
8864#ifndef BUCHBERGER_ALG
8865  intvec* hilb_func;
8866#endif
8867  // to avoid (1,0,...,0) as the target vector
8868  intvec* last_omega = new intvec(nV);
8869  for(i=nV-1; i>0; i--)
8870  {
8871    (*last_omega)[i] = 1;
8872  }
8873  (*last_omega)[0] = 10000;
8874
8875//intvec* extra_curr_weight = new intvec(nV);
8876  intvec* target_weight = new intvec(nV);
8877  for(i=nV-1; i>=0; i--)
8878  {
8879    (*target_weight)[i] = (*target_tmp)[i];
8880  }
8881  ring XXRing = currRing;
8882  newRing = currRing;
8883
8884#ifdef TIME_TEST
8885  to=clock();
8886#endif
8887  // compute a red. GB w.r.t. the help ring
8888  if(MivComp(curr_weight, iv_dp) == 1)
8889  {
8890    //rOrdStr(currRing) = "dp"
8891    G = MstdCC(G);
8892  }
8893  else
8894  {
8895    //rOrdStr(currRing) = (a(.c_w..),lp,C)
8896    if (rParameter(currRing) != NULL)
8897    {
8898      DefRingPar(curr_weight);
8899    }
8900    else
8901    {
8902      rChangeCurrRing(VMrDefault(curr_weight));
8903    }
8904    G = idrMoveR(G, XXRing,currRing);
8905    G = MstdCC(G);
8906  }
8907#ifdef TIME_TEST
8908  tostd=clock()-to;
8909#endif
8910
8911#ifdef REPRESENTATION_OF_SIGMA
8912  ideal Gw = MwalkInitialForm(G, curr_weight);
8913
8914  if(islengthpoly2(Gw)==1)
8915  {
8916    intvec* MDp;
8917    if(MivComp(curr_weight, iv_dp) == 1)
8918    {
8919      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
8920    }
8921    else
8922    {
8923      MDp = MivWeightOrderlp(curr_weight);
8924    }
8925    curr_weight = RepresentationMatrix_Dp(G, MDp);
8926
8927    delete MDp;
8928
8929    ring exring = currRing;
8930
8931    if (rParameter(currRing) != NULL)
8932    {
8933      DefRingPar(curr_weight);
8934    }
8935    else
8936    {
8937      rChangeCurrRing(VMrDefault(curr_weight));
8938    }
8939#ifdef TIME_TEST
8940    to=clock();
8941#endif
8942    Gw = idrMoveR(G, exring,currRing);
8943    G = MstdCC(Gw);
8944    Gw = NULL;
8945#ifdef TIME_TEST
8946    tostd=tostd+clock()-to;
8947#endif
8948    //ivString(curr_weight,"rep. sigma");
8949    goto COMPUTE_NEW_VECTOR;
8950  }
8951
8952  idDelete(&Gw);
8953  delete iv_dp;
8954#endif
8955
8956
8957  while(1)
8958  {
8959#ifdef TIME_TEST
8960    to=clock();
8961#endif
8962    // compute an initial form ideal of <G> w.r.t. "curr_vector"
8963    Gomega = MwalkInitialForm(G, curr_weight);
8964#ifdef TIME_TEST
8965    tif=tif+clock()-to;
8966#endif
8967
8968#ifndef  BUCHBERGER_ALG
8969    if(isNolVector(curr_weight) == 0)
8970    {
8971      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
8972    }
8973    else
8974    {
8975      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
8976    }
8977#endif // BUCHBERGER_ALG
8978
8979    oldRing = currRing;
8980
8981    // define a new ring with ordering "(a(curr_weight),lp)
8982    if (rParameter(currRing) != NULL)
8983    {
8984      DefRingPar(curr_weight);
8985    }
8986    else
8987    {
8988      rChangeCurrRing(VMrDefault(curr_weight));
8989    }
8990    newRing = currRing;
8991    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
8992
8993#ifdef TIME_TEST
8994    to=clock();
8995#endif
8996    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
8997#ifdef  BUCHBERGER_ALG
8998    M = MstdhomCC(Gomega1);
8999#else
9000    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9001    delete hilb_func;
9002#endif
9003#ifdef TIME_TEST
9004    tstd=tstd+clock()-to;
9005#endif
9006
9007    // change the ring to oldRing
9008    rChangeCurrRing(oldRing);
9009    M1 =  idrMoveR(M, newRing,currRing);
9010    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9011
9012#ifdef TIME_TEST
9013    to=clock();
9014#endif
9015    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega).
9016    // Gomega is a reduced Groebner basis w.r.t. the current ring
9017    F = MLifttwoIdeal(Gomega2, M1, G);
9018#ifdef TIME_TEST
9019    tlift=tlift+clock()-to;
9020#endif
9021
9022    idDelete(&M1);
9023    idDelete(&Gomega2);
9024    idDelete(&G);
9025
9026    // change the ring to newRing
9027    rChangeCurrRing(newRing);
9028    F1 = idrMoveR(F, oldRing,currRing);
9029
9030#ifdef TIME_TEST
9031    to=clock();
9032#endif
9033    // reduce the Groebner basis <G> w.r.t. new ring
9034    G = kInterRedCC(F1, NULL);
9035#ifdef TIME_TEST
9036    tred=tred+clock()-to;
9037#endif
9038    idDelete(&F1);
9039
9040  COMPUTE_NEW_VECTOR:
9041    newRing = currRing;
9042    nwalk++;
9043    nwalkpert++;
9044#ifdef TIME_TEST
9045    to=clock();
9046#endif
9047    // compute a next weight vector
9048    //next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
9049    next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, pert_deg);
9050/*
9051    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
9052
9053    if(MivComp(next_weight, target_weight) != 1)
9054    {
9055      // compute a perturbed next weight vector "next_weight1"
9056      intvec* next_weight1 = MkInterRedNextWeight(MPertVectors(G, MivMatrixOrder(curr_weight), pert_deg), target_weight, G);
9057
9058      // compare next_weight and next_weight1
9059      ideal G_test = MwalkInitialForm(G, next_weight);
9060      ideal G_test1 = MwalkInitialForm(G, next_weight1);
9061      if(IDELEMS(G_test1) <= IDELEMS(G_test))
9062      {
9063        next_weight = ivCopy(next_weight1);
9064      }
9065      delete next_weight1;
9066      // compute a random next weight vector "next_weight2"
9067      intvec* next_weight22 = ivCopy(target_weight);
9068      // Print("\n//  size of target_weight  = %d", sizeof((*target_weight)));
9069      k = 0;
9070
9071      while(test_w_in_ConeCC(G, next_weight22) == 0 && k < 11)
9072      {
9073        k++;
9074        if(k>10)
9075        {
9076          break;
9077        }
9078        weight_norm = 0;
9079        while(weight_norm == 0)
9080        {
9081          for(i=nV-1; i>=0; i--)
9082          {
9083            // Print("\n//  next_weight[%d]  = %d", i, (*next_weight)[i]);
9084            (*next_weight22)[i] = rand() % 60000 - 30000;
9085            weight_norm = weight_norm + (*next_weight22)[i]*(*next_weight22)[i];
9086          }
9087          weight_norm = 1 + floor(sqrt(weight_norm));
9088        }
9089        for(i=nV-1; i>=0; i--)
9090        {
9091          if((*next_weight22)[i] < 0)
9092          {
9093            (*next_weight22)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
9094          }
9095          else
9096          {
9097            (*next_weight22)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
9098          }
9099          // Print("\n//  next_weight22[%d]  = %d", i, (*next_weight22)[i]);
9100        }
9101      }
9102
9103      if(test_w_in_ConeCC(G, next_weight22) == 1)
9104      {
9105        // compare next_weight and next_weight2
9106        // Print("\n// ZUFALL IM KEGEL");
9107        intvec* next_weight2 = MkInterRedNextWeight(next_weight22, target_weight, G);
9108
9109        ideal G_test2 = MwalkInitialForm(G, next_weight2);
9110        if(IDELEMS(G_test2) <= IDELEMS(G_test))
9111        {
9112          if(IDELEMS(G_test2) <= IDELEMS(G_test1))
9113          {
9114             // Print("\n// ZUFALL BENUTZT!\n");
9115            next_weight = ivCopy(next_weight2);
9116          }
9117        }
9118        idDelete(&G_test2);
9119        delete next_weight2;
9120      }
9121      delete next_weight22;
9122      idDelete(&G_test);
9123      idDelete(&G_test1);
9124    }*/
9125
9126#ifdef TIME_TEST
9127    tnw=tnw+clock()-to;
9128#endif
9129#ifdef PRINT_VECTORS
9130    MivString(curr_weight, target_weight, next_weight);
9131#endif
9132
9133/*   check whether the computed intermediate weight vector is in
9134     the correct cone; sometimes it is very big e.g. s7, cyc7.
9135     If it is NOT in the correct cone, then compute directly
9136     a reduced Groebner basis with respect to the lexicographic ordering
9137     for the known Groebner basis that it is computed in the last step.
9138*/
9139    //if(test_w_in_ConeCC(G, next_weight) != 1)
9140    if(Overflow_Error == TRUE)
9141    {
9142    OMEGA_OVERFLOW_TRAN_NEW:
9143      //Print("\n//  takes %d steps!", nwalk-1);
9144      //Print("\n//ring lastRing = %s;", rString(currRing));
9145#ifdef TEST_OVERFLOW
9146      goto  BE_FINISH;
9147#endif
9148
9149#ifdef CHECK_IDEAL_MWALK
9150      idElements(G, "G");
9151      //headidString(G, "G");
9152#endif
9153
9154      if(MivSame(target_tmp, iv_lp) == 1)
9155      {
9156        if (rParameter(currRing) != NULL)
9157        {
9158          DefRingParlp();
9159        }
9160        else
9161        {
9162          VMrDefaultlp();
9163        }
9164      }
9165      else
9166      {
9167        if (rParameter(currRing) != NULL)
9168        {
9169          DefRingPar(target_tmp);
9170        }
9171        else
9172        {
9173          rChangeCurrRing(VMrDefault(target_tmp));
9174        }
9175      }
9176      lpRing = currRing;
9177      G1 = idrMoveR(G, newRing,currRing);
9178
9179#ifdef TIME_TEST
9180      to=clock();
9181#endif
9182      // apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>
9183      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0)
9184      {
9185        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
9186        G = MstdCC(G1);//no result for qnt1
9187      }
9188      else
9189      {
9190        rChangeCurrRing(newRing);
9191        G1 = idrMoveR(G1, lpRing,currRing);
9192
9193        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
9194        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
9195
9196        rChangeCurrRing(lpRing);
9197        G = idrMoveR(G, newRing,currRing);
9198      }
9199#ifdef TIME_TEST
9200      textra=clock()-to;
9201#endif
9202      npert[endwalks]=nwalk-npert_tmp;
9203      npert_tmp = nwalk;
9204      endwalks ++;
9205      break;
9206    }
9207
9208    // check whether the computed Groebner basis is really a Groebner basis.
9209    // If not, we perturb the target vector with the maximal "perturbation" degree.
9210
9211    if(MivComp(next_weight, target_weight) == 1 || MivComp(next_weight, curr_weight) == 1 )
9212    {
9213      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
9214
9215
9216      //compute the number of perturbations and its step
9217      npert[endwalks]=nwalk-npert_tmp;
9218      npert_tmp = nwalk;
9219
9220      endwalks ++;
9221
9222      // it is very important if the walk only uses one step, e.g. Fate, liu
9223      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1)
9224      {
9225        rChangeCurrRing(XXRing);
9226        G = idrMoveR(G, newRing,currRing);
9227        goto FINISH;
9228      }
9229      H0 = id_Head(G,currRing);
9230
9231      if(MivSame(target_tmp, iv_lp) == 1)
9232      {
9233        if (rParameter(currRing) != NULL)
9234        {
9235          DefRingParlp();
9236        }
9237        else
9238        {
9239          VMrDefaultlp();
9240        }
9241      }
9242      else
9243      {
9244        if (rParameter(currRing) != NULL)
9245        {
9246          DefRingPar(target_tmp);
9247        }
9248        else
9249        {
9250          rChangeCurrRing(VMrDefault(target_tmp));
9251        }
9252      }
9253      lpRing = currRing;
9254      Glp = idrMoveR(G, newRing,currRing);
9255      H2 = idrMoveR(H0, newRing,currRing);
9256
9257      // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
9258      nGB = 1;
9259      for(i=IDELEMS(Glp)-1; i>=0; i--)
9260      {
9261        poly t;
9262        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
9263        {
9264          pDelete(&t);
9265          idDelete(&H2);//5.5.02
9266          nGB = 0; //i.e. Glp is no reduced Groebner basis
9267          break;
9268        }
9269        pDelete(&t);
9270      }
9271
9272      idDelete(&H2);//5.5.02
9273
9274      if(nGB == 1)
9275      {
9276        G = Glp;
9277        Glp = NULL;
9278        break;
9279      }
9280
9281       // perturb the target weight vector, if the vector target_tmp stays in many cones
9282      poly p;
9283      BOOLEAN plength3 = FALSE;
9284      for(i=IDELEMS(Glp)-1; i>=0; i--)
9285      {
9286        p = MpolyInitialForm(Glp->m[i], target_tmp);
9287        if(p->next != NULL &&
9288           p->next->next != NULL &&
9289           p->next->next->next != NULL)
9290        {
9291          Overflow_Error = FALSE;
9292
9293          for(i=0; i<nV; i++)
9294          {
9295            (*vector_tmp)[i] = (*target_weight)[i];
9296          }
9297          delete target_weight;
9298          target_weight = MPertVectors(Glp, Mlp, nV);
9299
9300          if(MivComp(vector_tmp, target_weight)==1)
9301          {
9302            //PrintS("\n// The old and new representaion vector are the same!!");
9303            G = Glp;
9304            newRing = currRing;
9305            goto OMEGA_OVERFLOW_TRAN_NEW;
9306           }
9307
9308          if(Overflow_Error == TRUE)
9309          {
9310            rChangeCurrRing(newRing);
9311            G = idrMoveR(Glp, lpRing,currRing);
9312            goto OMEGA_OVERFLOW_TRAN_NEW;
9313          }
9314
9315          plength3 = TRUE;
9316          pDelete(&p);
9317          break;
9318        }
9319        pDelete(&p);
9320      }
9321
9322      if(plength3 == FALSE)
9323      {
9324        rChangeCurrRing(newRing);
9325        G = idrMoveR(Glp, lpRing,currRing);
9326        goto TRAN_LIFTING;
9327      }
9328
9329
9330      npertstep = nwalk;
9331      nwalkpert = 1;
9332      nsteppert ++;
9333
9334      /*
9335      Print("\n// Subroutine needs (%d) steps.", nwalk);
9336      idElements(Glp, "last G in walk:");
9337      PrintS("\n// ****************************************");
9338      Print("\n// Perturb the original target vector (%d): ", nsteppert);
9339      ivString(target_weight, "new target");
9340      PrintS("\n// ****************************************\n");
9341      */
9342      rChangeCurrRing(newRing);
9343      G = idrMoveR(Glp, lpRing,currRing);
9344
9345      delete next_weight;
9346
9347      //Print("\n// ring rNEW = %s;", rString(currRing));
9348      goto COMPUTE_NEW_VECTOR;
9349    }
9350
9351  TRAN_LIFTING:
9352    for(i=nV-1; i>=0; i--)
9353    {
9354      (*curr_weight)[i] = (*next_weight)[i];
9355    }
9356    delete next_weight;
9357  } // end of while
9358#ifdef TEST_OVERFLOW
9359 BE_FINISH:
9360#endif
9361  rChangeCurrRing(XXRing);
9362  G = idrMoveR(G, lpRing,currRing);
9363
9364 FINISH:
9365  delete ivNull;
9366  delete next_weight;
9367  delete iv_lp;
9368  omFree(npert);
9369
9370#ifdef TIME_TEST
9371  Print("\n// Computation took %d steps and %.2f sec", nwalk, ((double) (clock()-mtim)/1000000));
9372
9373  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
9374
9375  Print("\n// pSetm_Error = (%d)", ErrorCheck());
9376  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
9377#endif
9378
9379  return(G);
9380}
9381#endif
9382
9383/*****************************************************************
9384 * compute the reduced Groebner basis of an ideal <Go> w.r.t. lp *
9385 *****************************************************************/
9386static ideal Mpwalk_MAltwalk1(ideal Go, intvec* curr_weight, int tp_deg)
9387{
9388  Overflow_Error = FALSE;
9389 // BOOLEAN nOverflow_Error = FALSE;
9390#ifdef TIME_TEST
9391  clock_t tproc=0;
9392  clock_t tinput=clock();
9393#endif
9394  int i, nV = currRing->N;
9395
9396  //check that perturbation degree is valid
9397  if(tp_deg < 1 || tp_deg > nV)
9398  {
9399    WerrorS("Invalid perturbation degree.\n");
9400    return NULL;
9401  }
9402
9403  int nwalk=0, endwalks=0, ntestwinC=1;
9404  int tp_deg_tmp = tp_deg;
9405  ideal Gomega, M, F, G, M1, F1, Gomega1, Gomega2, G1;
9406  ring newRing, oldRing, TargetRing;
9407  intvec* next_weight;
9408  intvec* ivNull = new intvec(nV);
9409
9410  ring YXXRing = currRing;
9411
9412  intvec* iv_M_dpp = MivMatrixOrderlp(nV);
9413  intvec* target_weight;// = Mivlp(nV);
9414  ideal ssG;
9415
9416  // perturb the target vector
9417  while(1)
9418  {
9419    if(Overflow_Error == FALSE)
9420    {
9421      if (rParameter(currRing) != NULL)
9422      {
9423        DefRingParlp();
9424      }
9425      else
9426      {
9427        VMrDefaultlp();
9428      }
9429      TargetRing = currRing;
9430      ssG = idrMoveR(Go,YXXRing,currRing);
9431    }
9432    Overflow_Error = FALSE;
9433    if(tp_deg != 1)
9434    {
9435      target_weight = MPertVectors(ssG, iv_M_dpp, tp_deg);
9436    }
9437    else
9438    {
9439      target_weight = Mivlp(nV);
9440      break;
9441    }
9442    if(Overflow_Error == FALSE)
9443    {
9444      break;
9445    }
9446    Overflow_Error = TRUE;
9447    tp_deg --;
9448  }
9449  if(tp_deg != tp_deg_tmp)
9450  {
9451    Overflow_Error = TRUE;
9452    //nOverflow_Error = TRUE;
9453  }
9454
9455  //  Print("\n// tp_deg = %d", tp_deg);
9456  // ivString(target_weight, "pert target");
9457
9458  delete iv_M_dpp;
9459#ifndef  BUCHBERGER_ALG
9460  intvec* hilb_func;
9461#endif
9462  // to avoid (1,0,...,0) as the target vector
9463  intvec* last_omega = new intvec(nV);
9464  for(i=nV-1; i>0; i--)
9465  {
9466    (*last_omega)[i] = 1;
9467  }
9468  (*last_omega)[0] = 10000;
9469
9470  rChangeCurrRing(YXXRing);
9471  G = idrMoveR(ssG, TargetRing,currRing);
9472
9473  while(1)
9474  {
9475    nwalk ++;
9476    nstep ++;
9477
9478    if(nwalk==1)
9479    {
9480      goto FIRST_STEP;
9481    }
9482#ifdef TIME_TEST
9483    to=clock();
9484#endif
9485    // compute an initial form ideal of <G> w.r.t. "curr_vector"
9486    Gomega = MwalkInitialForm(G, curr_weight);
9487#ifdef TIME_TEST
9488    xtif=xtif+clock()-to;
9489#endif
9490
9491#ifndef  BUCHBERGER_ALG
9492    if(isNolVector(curr_weight) == 0)
9493      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
9494    else
9495      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
9496#endif
9497
9498    oldRing = currRing;
9499
9500    // define a new ring that its ordering is "(a(curr_weight),lp)
9501    if (rParameter(currRing) != NULL)
9502    {
9503      DefRingPar(curr_weight);
9504    }
9505    else
9506    {
9507      rChangeCurrRing(VMrDefault(curr_weight));
9508    }
9509    newRing = currRing;
9510    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
9511/*
9512#ifdef ENDWALKS
9513    if(endwalks == 1)
9514    {
9515      Print("\n//  it is  %d-th step!!", nwalk);
9516      idString(Gomega1, "Gw");
9517      PrintS("\n//  compute a rGB of Gw:");
9518    }
9519#endif
9520*/
9521#ifdef TIME_TEST
9522    to=clock();
9523#endif
9524    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
9525#ifdef  BUCHBERGER_ALG
9526    M = MstdhomCC(Gomega1);
9527#else
9528    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9529    delete hilb_func;
9530#endif // BUCHBERGER_ALG
9531#ifdef TIME_TEST
9532    xtstd=xtstd+clock()-to;
9533#endif
9534
9535    // change the ring to oldRing
9536    rChangeCurrRing(oldRing);
9537    M1 =  idrMoveR(M, newRing,currRing);
9538    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9539#ifdef TIME_TEST
9540    to=clock();
9541#endif
9542
9543    // if(endwalks == 1){PrintS("\n//  Lifting is still working:");}
9544
9545    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
9546    F = MLifttwoIdeal(Gomega2, M1, G);
9547#ifdef TIME_TEST
9548    xtlift=xtlift+clock()-to;
9549#endif
9550
9551    idDelete(&M1);
9552    idDelete(&Gomega2);
9553    idDelete(&G);
9554
9555    // change the ring to newRing
9556    rChangeCurrRing(newRing);
9557    F1 = idrMoveR(F, oldRing,currRing);
9558#ifdef TIME_TEST
9559    to=clock();
9560#endif
9561    //if(endwalks == 1){ PrintS("\n//  InterRed is still working:");}
9562    // reduce the Groebner basis <G> w.r.t. the new ring
9563    G = kInterRedCC(F1, NULL);
9564#ifdef TIME_TEST
9565    xtred=xtred+clock()-to;
9566#endif
9567    idDelete(&F1);
9568
9569    if(endwalks == 1)
9570      break;
9571
9572  FIRST_STEP:
9573    Overflow_Error=FALSE;
9574#ifdef TIME_TEST
9575    to=clock();
9576#endif
9577    // compute a next weight vector
9578    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
9579#ifdef TIME_TEST
9580    xtnw=xtnw+clock()-to;
9581#endif
9582#ifdef PRINT_VECTORS
9583    MivString(curr_weight, target_weight, next_weight);
9584#endif
9585
9586    if(Overflow_Error == TRUE)
9587    {
9588      delete next_weight;
9589      if(tp_deg > 1){
9590        //nOverflow_Error = Overflow_Error;
9591#ifdef TIME_TEST
9592        tproc = tproc+clock()-tinput;
9593#endif
9594        //Print("\n// A subroutine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk, tp_deg-1);
9595        G1 = Mpwalk_MAltwalk1(G, curr_weight, tp_deg-1);
9596        goto MPW_Finish;
9597      }
9598      else {
9599        newRing = currRing;
9600        ntestwinC = 0;
9601        break;
9602      }
9603    }
9604
9605    if(MivComp(next_weight, ivNull) == 1)
9606    {
9607      newRing = currRing;
9608      delete next_weight;
9609      break;
9610    }
9611    if(MivComp(next_weight, target_weight) == 1)
9612    {
9613      endwalks = 1;
9614    }
9615    for(i=nV-1; i>=0; i--)
9616    {
9617      //(*extra_curr_weight)[i] = (*curr_weight)[i];
9618      (*curr_weight)[i] = (*next_weight)[i];
9619    }
9620    delete next_weight;
9621  }//while
9622
9623  // check whether the pertubed target vector is correct
9624
9625  //define and execute ring with lex. order
9626  if (rParameter(currRing) != NULL)
9627  {
9628    DefRingParlp();
9629  }
9630  else
9631  {
9632    VMrDefaultlp();
9633  }
9634  G1 = idrMoveR(G, newRing,currRing);
9635
9636  if( test_w_in_ConeCC(G1, target_weight) != 1 || ntestwinC == 0)
9637  {
9638    //PrintS("\n// The perturbed target vector doesn't STAY in the correct cone!!");
9639    if(tp_deg == 1)
9640    {
9641      //Print("\n// subroutine takes %d steps and applys \"std\"", nwalk);
9642#ifdef TIME_TEST
9643      to=clock();
9644#endif
9645      ideal G2 = MstdCC(G1);
9646#ifdef TIME_TEST
9647      xtextra=xtextra+clock()-to;
9648#endif
9649      idDelete(&G1);
9650      G1 = G2;
9651      G2 = NULL;
9652    }
9653    else
9654    {
9655      //nOverflow_Error = Overflow_Error;
9656#ifdef TIME_TEST
9657      tproc = tproc+clock()-tinput;
9658#endif
9659      // Print("\n// B subroutine takes %d steps and calls \"Mpwalk\" (1,%d) :", nwalk,  tp_deg-1);
9660      G1 = Mpwalk_MAltwalk1(G1, curr_weight, tp_deg-1);
9661    }
9662  }
9663
9664 MPW_Finish:
9665  newRing = currRing;
9666  rChangeCurrRing(YXXRing);
9667  ideal result = idrMoveR(G1, newRing,currRing);
9668
9669  delete ivNull;
9670  delete target_weight;
9671
9672  //Print("\n// \"Mpwalk\" (1,%d) took %d steps and %.2f sec. Overflow_Error (%d)", tp_deg, nwalk, ((double) clock()-tinput)/1000000, nOverflow_Error);
9673  //Print("\n// Mprwalk took %d steps. Ring= %s;\n", nwalk, rString(currRing));
9674  return(result);
9675}
9676
9677/*******************************************************************
9678 * Implementation of the first alternative Groebner Walk Algorithm *
9679 *******************************************************************/
9680ideal MAltwalk1(ideal Go, int op_deg, int tp_deg, intvec* curr_weight,
9681                intvec* target_weight)
9682{
9683  Set_Error(FALSE  );
9684  Overflow_Error = FALSE;
9685#ifdef TIME_TEST
9686  BOOLEAN nOverflow_Error = FALSE;
9687#endif
9688  // Print("// pSetm_Error = (%d)", ErrorCheck());
9689
9690#ifdef TIME_TEST
9691  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
9692  xftinput = clock();
9693  clock_t tostd, tproc;
9694#endif
9695
9696  nstep = 0;
9697  int i, nV = currRing->N;
9698  int nwalk=0, endwalks=0;
9699  int op_tmp = op_deg;
9700  ideal Gomega, M, F, G, Gomega1, Gomega2, M1, F1;
9701  ring newRing, oldRing;
9702  intvec* next_weight;
9703  intvec* iv_M_dp;
9704  intvec* ivNull = new intvec(nV);
9705  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
9706  intvec* exivlp = Mivlp(nV);
9707  //intvec* extra_curr_weight = new intvec(nV);
9708#ifndef  BUCHBERGER_ALG
9709  intvec* hilb_func;
9710#endif
9711  intvec* cw_tmp = curr_weight;
9712
9713  // to avoid (1,0,...,0) as the target vector
9714  intvec* last_omega = new intvec(nV);
9715  for(i=nV-1; i>0; i--)
9716  {
9717    (*last_omega)[i] = 1;
9718  }
9719  (*last_omega)[0] = 10000;
9720
9721  ring XXRing = currRing;
9722
9723#ifdef TIME_TEST
9724  to=clock();
9725#endif
9726  /* compute a pertubed weight vector of the original weight vector.
9727     The perturbation degree is recursive decrease until that vector
9728     stays inn the correct cone. */
9729  while(1)
9730  {
9731    if(Overflow_Error == FALSE)
9732    {
9733      if(MivComp(curr_weight, iv_dp) == 1)
9734      {
9735      //rOrdStr(currRing) = "dp"
9736        if(op_tmp == op_deg)
9737        {
9738          G = MstdCC(Go);
9739          if(op_deg != 1)
9740          {
9741            iv_M_dp = MivMatrixOrderdp(nV);
9742          }
9743        }
9744      }
9745    }
9746    else
9747    {
9748      if(op_tmp == op_deg)
9749      {
9750        //rOrdStr(currRing) = (a(...),lp,C)
9751        if (rParameter(currRing) != NULL)
9752        {
9753          DefRingPar(cw_tmp);
9754        }
9755        else
9756        {
9757          rChangeCurrRing(VMrDefault(cw_tmp));
9758        }
9759        G = idrMoveR(Go, XXRing,currRing);
9760        G = MstdCC(G);
9761        if(op_deg != 1)
9762          iv_M_dp = MivMatrixOrder(cw_tmp);
9763      }
9764    }
9765    Overflow_Error = FALSE;
9766    if(op_deg != 1)
9767    {
9768      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
9769    }
9770    else
9771    {
9772      curr_weight =  cw_tmp;
9773      break;
9774    }
9775    if(Overflow_Error == FALSE)
9776    {
9777      break;
9778    }
9779    Overflow_Error = TRUE;
9780    op_deg --;
9781  }
9782#ifdef TIME_TEST
9783  tostd=clock()-to;
9784#endif
9785
9786  if(op_tmp != 1 )
9787    delete iv_M_dp;
9788  delete iv_dp;
9789
9790  if(currRing->order[0] == ringorder_a)
9791    goto NEXT_VECTOR;
9792
9793  while(1)
9794  {
9795    nwalk ++;
9796    nstep ++;
9797
9798#ifdef TIME_TEST
9799    to = clock();
9800#endif
9801    // compute an initial form ideal of <G> w.r.t. "curr_vector"
9802    Gomega = MwalkInitialForm(G, curr_weight);
9803#ifdef TIME_TEST
9804    xtif=xtif+clock()-to;
9805#endif
9806#if 0
9807    if(Overflow_Error == TRUE)
9808    {
9809      for(i=nV-1; i>=0; i--)
9810        (*curr_weight)[i] = (*extra_curr_weight)[i];
9811      delete extra_curr_weight;
9812
9813      newRing = currRing;
9814      goto MSTD_ALT1;
9815    }
9816#endif
9817#ifndef  BUCHBERGER_ALG
9818    if(isNolVector(curr_weight) == 0)
9819    {
9820      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
9821    }
9822    else
9823    {
9824      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
9825    }
9826#endif // BUCHBERGER_ALG
9827
9828    oldRing = currRing;
9829
9830    // define a new ring which ordering is "(a(curr_weight),lp)
9831    if (rParameter(currRing) != NULL)
9832    {
9833      DefRingPar(curr_weight);
9834    }
9835    else
9836    {
9837      rChangeCurrRing(VMrDefault(curr_weight));
9838    }
9839    newRing = currRing;
9840    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
9841
9842#ifdef TIME_TEST
9843    to=clock();
9844#endif
9845    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
9846#ifdef  BUCHBERGER_ALG
9847    M = MstdhomCC(Gomega1);
9848#else
9849    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9850    delete hilb_func;
9851#endif // BUCHBERGER_ALG
9852#ifdef TIME_TEST
9853    xtstd=xtstd+clock()-to;
9854#endif
9855
9856    // change the ring to oldRing
9857    rChangeCurrRing(oldRing);
9858    M1 =  idrMoveR(M, newRing,currRing);
9859    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9860
9861#ifdef TIME_TEST
9862    to=clock();
9863#endif
9864    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
9865    F = MLifttwoIdeal(Gomega2, M1, G);
9866#ifdef TIME_TEST
9867    xtlift=xtlift+clock()-to;
9868#endif
9869
9870    idDelete(&M1);
9871    idDelete(&Gomega2);
9872    idDelete(&G);
9873
9874    // change the ring to newRing
9875    rChangeCurrRing(newRing);
9876    F1 = idrMoveR(F, oldRing,currRing);
9877    if (oldRing!=IDRING(currRingHdl)) rDelete(oldRing); // do not delete the global currRing
9878    oldRing=NULL;
9879
9880#ifdef TIME_TEST
9881    to=clock();
9882#endif
9883    // reduce the Groebner basis <G> w.r.t. new ring
9884    G = kInterRedCC(F1, NULL);
9885#ifdef TIME_TEST
9886    xtred=xtred+clock()-to;
9887#endif
9888    idDelete(&F1);
9889
9890    if(endwalks == 1)
9891    {
9892      break;
9893    }
9894  NEXT_VECTOR:
9895#ifdef TIME_TEST
9896    to=clock();
9897#endif
9898    // compute a next weight vector
9899    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
9900#ifdef TIME_TEST
9901    xtnw=xtnw+clock()-to;
9902#endif
9903#ifdef PRINT_VECTORS
9904    MivString(curr_weight, target_weight, next_weight);
9905#endif
9906    if(Overflow_Error == TRUE)
9907    {
9908      newRing = currRing;
9909
9910      if (rParameter(currRing) != NULL)
9911      {
9912        DefRingPar(target_weight);
9913      }
9914      else
9915      {
9916        rChangeCurrRing(VMrDefault(target_weight));
9917      }
9918      F1 = idrMoveR(G, newRing,currRing);
9919      G = MstdCC(F1);
9920      idDelete(&F1);
9921      newRing = currRing;
9922      break; //for while
9923    }
9924
9925
9926    /* G is the wanted Groebner basis if next_weight == curr_weight */
9927    if(MivComp(next_weight, ivNull) == 1)
9928    {
9929      newRing = currRing;
9930      delete next_weight;
9931      break; //for while
9932    }
9933
9934    if(MivComp(next_weight, target_weight) == 1)
9935    {
9936      if(tp_deg == 1 || MivSame(target_weight, exivlp) == 0)
9937        endwalks = 1;
9938      else
9939      {
9940       // MSTD_ALT1:
9941#ifdef TIME_TEST
9942        nOverflow_Error = Overflow_Error;
9943        tproc = clock()-xftinput;
9944#endif
9945
9946        //Print("\n//  main routine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk,  tp_deg);
9947
9948        // compute the red. GB of <G> w.r.t. the lex order by the "recursive-modified" perturbation walk alg (1,tp_deg)
9949        G = Mpwalk_MAltwalk1(G, curr_weight, tp_deg);
9950        delete next_weight;
9951        break; // for while
9952      }
9953    }
9954
9955    //NOT Changed, to free memory
9956    for(i=nV-1; i>=0; i--)
9957    {
9958      //(*extra_curr_weight)[i] = (*curr_weight)[i];
9959      (*curr_weight)[i] = (*next_weight)[i];
9960    }
9961    delete next_weight;
9962  }//while
9963
9964  rChangeCurrRing(XXRing);
9965  ideal result = idrMoveR(G, newRing,currRing);
9966  id_Delete(&G, newRing);
9967
9968  delete ivNull;
9969  if(op_deg != 1 )
9970  {
9971    delete curr_weight;
9972  }
9973  delete exivlp;
9974#ifdef TIME_TEST
9975/*
9976  Print("\n// \"Main procedure\"  took %d steps, %.2f sec. and Overflow_Error(%d)",
9977        nwalk, ((double) tproc)/1000000, nOverflow_Error);
9978
9979  TimeStringFractal(xftinput, tostd, xtif, xtstd,xtextra, xtlift, xtred, xtnw);
9980*/
9981 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
9982 // Print("\n// Overflow_Error? (%d)", Overflow_Error);
9983 // Print("\n// Awalk1 took %d steps.\n", nstep);
9984#endif
9985  return(result);
9986}
Note: See TracBrowser for help on using the repository browser.