source: git/Singular/walk.cc @ 16f511

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