source: git/Singular/walk.cc @ 9cf0188

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