source: git/Singular/walk.cc @ ec59a66

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