source: git/Singular/walk.cc @ 186f01

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