source: git/Singular/walk.cc @ bc55ff

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