source: git/Singular/walk.cc @ 622b41

spielwiese
Last change on this file since 622b41 was 622b41, checked in by Stephan Oberfranz <oberfran@…>, 9 years ago
---
  • Property mode set to 100755
File size: 238.2 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 checkRed, 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   //checkRed = 0;
2410
2411  SIMPLIFY_GCD:
2412
2413  // simplify the vectors curr_weight and diff_weight (C-int)
2414  gcd_tmp = (*curr_weight)[0];
2415
2416  for (j=1; j<nRing; j++)
2417  {
2418    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
2419    if(gcd_tmp == 1)
2420    {
2421      break;
2422    }
2423  }
2424  if(gcd_tmp != 1)
2425  {
2426    for (j=0; j<nRing; j++)
2427    {
2428      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
2429      if(gcd_tmp == 1)
2430      {
2431        break;
2432      }
2433    }
2434  }
2435  if(gcd_tmp != 1)
2436  {
2437    for (j=0; j<nRing; j++)
2438    {
2439      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
2440      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
2441    }
2442  }
2443  if(checkRed > 0)
2444  {
2445    for (j=0; j<nRing; j++)
2446    {
2447      mpz_set_si(vec[j], (*diff_weight)[j]);
2448    }
2449    goto TEST_OVERFLOW;
2450  }
2451
2452#ifdef  NEXT_VECTORS_CC
2453  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
2454  ivString(curr_weight, "new cw");
2455  ivString(diff_weight, "new dw");
2456
2457  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
2458  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
2459#endif
2460
2461// construct a new weight vector and check whether vec[j] is overflow, i.e. vec[j] > 2^31.
2462// If vec[j] doesn't overflow, define a weight vector. Otherwise, report that overflow
2463// appears. In the second case, test whether the the correctness of the new vector plays
2464// an important role
2465
2466  for (j=0; j<nRing; j++)
2467  {
2468    mpz_set_si(dcw, (*curr_weight)[j]);
2469    mpz_mul(s_nenner, t_nenner, dcw);
2470
2471    if( (*diff_weight)[j]>0)
2472    {
2473      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
2474    }
2475    else
2476    {
2477      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
2478      mpz_neg(s_zaehler, s_zaehler);
2479    }
2480    mpz_add(sntz, s_nenner, s_zaehler);
2481    mpz_init_set(vec[j], sntz);
2482
2483#ifdef NEXT_VECTORS_CC
2484    Print("\n//   j = %d ==> ", j);
2485    PrintS("(");
2486    mpz_out_str( stdout, 10, t_nenner);
2487    Print(" * %d)", (*curr_weight)[j]);
2488    Print(" + ("); mpz_out_str( stdout, 10, t_zaehler);
2489    Print(" * %d) =  ",  (*diff_weight)[j]);
2490    mpz_out_str( stdout, 10, s_nenner);
2491    PrintS(" + ");
2492    mpz_out_str( stdout, 10, s_zaehler);
2493    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
2494    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
2495#endif
2496
2497    if(j==0)
2498    {
2499      mpz_set(ggt, sntz);
2500    }
2501    else
2502    {
2503      if(mpz_cmp_si(ggt,1) != 0)
2504      {
2505        mpz_gcd(ggt, ggt, sntz);
2506      }
2507    }
2508  }
2509  // reduce the vector with the gcd
2510  if(mpz_cmp_si(ggt,1) != 0)
2511  {
2512    for (j=0; j<nRing; j++)
2513    {
2514      mpz_divexact(vec[j], vec[j], ggt);
2515    }
2516  }
2517#ifdef  NEXT_VECTORS_CC
2518  PrintS("\n// gcd of elements of the vector: ");
2519  mpz_out_str( stdout, 10, ggt);
2520#endif
2521
2522  for (j=0; j<nRing; j++)
2523  {
2524    (*diff_weight)[j] = mpz_get_si(vec[j]);
2525  }
2526
2527 TEST_OVERFLOW:
2528
2529  for (j=0; j<nRing; j++)
2530  {
2531    if(mpz_cmp(vec[j], sing_int)>=0)
2532    {
2533      if(Overflow_Error == FALSE)
2534      {
2535        Overflow_Error = TRUE;
2536        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
2537        mpz_out_str( stdout, 10, vec[j]);
2538        PrintS(" is greater than 2147483647 (max. integer representation)\n");
2539        Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
2540      }
2541    }
2542  }
2543
2544 FINISH:
2545   delete diff_weight1;
2546   mpz_clear(t_zaehler);
2547   mpz_clear(t_nenner);
2548   mpz_clear(s_zaehler);
2549   mpz_clear(s_nenner);
2550   mpz_clear(sntz);
2551   mpz_clear(sztn);
2552   mpz_clear(temp);
2553   mpz_clear(MwWd);
2554   mpz_clear(deg_w0_p1);
2555   mpz_clear(deg_d0_p1);
2556   mpz_clear(ggt);
2557   omFree(vec);
2558   mpz_clear(sing_int_half);
2559   mpz_clear(sing_int);
2560   mpz_clear(dcw);
2561   mpz_clear(t_null);
2562
2563  if(Overflow_Error == FALSE)
2564  {
2565    Overflow_Error = nError;
2566  }
2567  rComplete(currRing);
2568  for(j=0; j<IDELEMS(G); j++)
2569  {
2570    poly p=G->m[j];
2571    while(p!=NULL)
2572    {
2573      p_Setm(p,currRing);
2574      pIter(p);
2575    }
2576  }
2577return diff_weight;
2578}
2579
2580
2581/**********************************************************************
2582* Compute an intermediate weight vector from iva to ivb w.r.t.        *
2583* the reduced Groebner basis G.                                       *
2584* Return NULL, if it is equal to iva or iva = avb.                    *
2585**********************************************************************/
2586intvec* MkInterRedNextWeight(intvec* iva, intvec* ivb, ideal G)
2587{
2588  intvec* tmp = new intvec(iva->length());
2589  intvec* result;
2590
2591  if(G == NULL)
2592  {
2593    return tmp;
2594  }
2595  if(MivComp(iva, ivb) == 1)
2596  {
2597    return tmp;
2598  }
2599  result = MwalkNextWeightCC(iva, ivb, G);
2600
2601  if(MivComp(result, iva) == 1)
2602  {
2603    delete result;
2604    return tmp;
2605  }
2606
2607  delete tmp;
2608  return result;
2609}
2610
2611/********************************************************************
2612 * define and execute a new ring which order is (a(vb),a(va),lp,C)  *
2613 * ******************************************************************/
2614static void VMrHomogeneous(intvec* va, intvec* vb)
2615{
2616
2617  if ((currRing->ppNoether)!=NULL)
2618  {
2619    pDelete(&(currRing->ppNoether));
2620  }
2621  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2622      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2623  {
2624    sLastPrinted.CleanUp();
2625  }
2626
2627  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2628  int i, nv = currRing->N;
2629
2630  r->cf  = currRing->cf;
2631  r->N   = currRing->N;
2632  int nb = 4;
2633
2634
2635  //names
2636  char* Q; // In order to avoid the corrupted memory, do not change.
2637  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2638  for(i=0; i<nv; i++)
2639  {
2640    Q = currRing->names[i];
2641    r->names[i]  = omStrDup(Q);
2642  }
2643
2644  //weights: entries for 3 blocks: NULL Made:???
2645  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2646  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2647  r->wvhdl[1] = (int*) omAlloc((nv-1)*sizeof(int));
2648
2649  for(i=0; i<nv-1; i++)
2650  {
2651    r->wvhdl[1][i] = (*vb)[i];
2652    r->wvhdl[0][i] = (*va)[i];
2653  }
2654  r->wvhdl[0][nv] = (*va)[nv];
2655
2656  // order: (1..1),a,lp,C
2657  r->order = (int *) omAlloc(nb * sizeof(int *));
2658  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2659  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2660
2661  // ringorder a for the first block: var 1..nv
2662  r->order[0]  = ringorder_a;
2663  r->block0[0] = 1;
2664  r->block1[0] = nv;
2665
2666 // ringorder a for the second block: var 2..nv
2667  r->order[1]  = ringorder_a;
2668  r->block0[1] = 2;
2669  r->block1[1] = nv;
2670
2671  // ringorder lp for the third block: var 2..nv
2672  r->order[2]  = ringorder_lp;
2673  r->block0[2] = 2;
2674  r->block1[2] = nv;
2675
2676  // ringorder C for the 4th block
2677  // it is very important within "idLift",
2678  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2679  // therefore, nb  must be (nBlocks(currRing)  + 1)
2680  r->order[3]  = ringorder_C;
2681
2682  // polynomial ring
2683  r->OrdSgn    = 1;
2684
2685  // complete ring intializations
2686
2687  rComplete(r);
2688
2689  rChangeCurrRing(r);
2690}
2691
2692
2693/**************************************************************
2694 * define and execute a new ring which order is (a(va),lp,C)  *
2695 * ************************************************************/
2696static ring VMrDefault(intvec* va)
2697{
2698
2699  if ((currRing->ppNoether)!=NULL)
2700  {
2701    pDelete(&(currRing->ppNoether));
2702  }
2703  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2704      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2705  {
2706    sLastPrinted.CleanUp();
2707  }
2708
2709  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2710  int i, nv = currRing->N;
2711
2712  r->cf  = currRing->cf;
2713  r->N   = currRing->N;
2714
2715  int nb = 4;
2716
2717  //names
2718  char* Q; // In order to avoid the corrupted memory, do not change.
2719  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2720  for(i=0; i<nv; i++)
2721  {
2722    Q = currRing->names[i];
2723    r->names[i]  = omStrDup(Q);
2724  }
2725
2726  /*weights: entries for 3 blocks: NULL Made:???*/
2727  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2728  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2729  for(i=0; i<nv; i++)
2730    r->wvhdl[0][i] = (*va)[i];
2731
2732  /* order: a,lp,C,0 */
2733  r->order = (int *) omAlloc(nb * sizeof(int *));
2734  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2735  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2736
2737  // ringorder a for the first block: var 1..nv
2738  r->order[0]  = ringorder_a;
2739  r->block0[0] = 1;
2740  r->block1[0] = nv;
2741
2742  // ringorder lp for the second block: var 1..nv
2743  r->order[1]  = ringorder_lp;
2744  r->block0[1] = 1;
2745  r->block1[1] = nv;
2746
2747  // ringorder C for the third block
2748  // it is very important within "idLift",
2749  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2750  // therefore, nb  must be (nBlocks(currRing)  + 1)
2751  r->order[2]  = ringorder_C;
2752
2753  // the last block: everything is 0
2754  r->order[3]  = 0;
2755
2756  // polynomial ring
2757  r->OrdSgn    = 1;
2758
2759  // complete ring intializations
2760
2761  rComplete(r);
2762  return r;
2763  //rChangeCurrRing(r);
2764}
2765
2766/****************************************************************
2767 * define and execute a new ring with ordering (a(va),Wp(vb),C) *
2768 * **************************************************************/
2769static ring VMrRefine(intvec* va, intvec* vb)
2770{
2771
2772  if ((currRing->ppNoether)!=NULL)
2773  {
2774    pDelete(&(currRing->ppNoether));
2775  }
2776  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2777      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2778  {
2779    sLastPrinted.CleanUp();
2780  }
2781
2782  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2783  int i, nv = currRing->N;
2784
2785  r->cf  = currRing->cf;
2786  r->N   = currRing->N;
2787  //int nb = nBlocks(currRing)  + 1;
2788  int nb = 4;
2789
2790  //names
2791  char* Q; // In order to avoid the corrupted memory, do not change.
2792  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2793  for(i=0; i<nv; i++)
2794  {
2795    Q = currRing->names[i];
2796    r->names[i]  = omStrDup(Q);
2797  }
2798
2799  //weights: entries for 3 blocks: NULL Made:???
2800  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2801  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2802  r->wvhdl[1] = (int*) omAlloc(nv*sizeof(int));
2803
2804  for(i=0; i<nv; i++)
2805  {
2806    r->wvhdl[0][i] = (*va)[i];
2807    r->wvhdl[1][i] = (*vb)[i];
2808  }
2809  r->wvhdl[2]=NULL;
2810  r->wvhdl[3]=NULL;
2811
2812  // order: (1..1),a,lp,C
2813  r->order = (int *) omAlloc(nb * sizeof(int *));
2814  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2815  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2816
2817  // ringorder a for the first block: var 1..nv
2818  r->order[0]  = ringorder_a;
2819  r->block0[0] = 1;
2820  r->block1[0] = nv;
2821
2822 // ringorder Wp for the second block: var 1..nv
2823  r->order[1]  = ringorder_Wp;
2824  r->block0[1] = 1;
2825  r->block1[1] = nv;
2826
2827  // ringorder lp for the third block: var 1..nv
2828  r->order[2]  = ringorder_C;
2829  r->block0[2] = 1;
2830  r->block1[2] = nv;
2831
2832  // ringorder C for the 4th block
2833  // it is very important within "idLift",
2834  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
2835  // therefore, nb  must be (nBlocks(currRing)  + 1)
2836  r->order[3]  = 0;
2837
2838  // polynomial ring
2839  r->OrdSgn    = 1;
2840
2841  // complete ring intializations
2842 
2843  rComplete(r);
2844
2845  //rChangeCurrRing(r);
2846  return r;
2847}
2848
2849/*****************************************************
2850 * define and execute a new ring with ordering (M,C) *
2851 *****************************************************/
2852static ring VMatrDefault(intvec* va)
2853{
2854
2855  if ((currRing->ppNoether)!=NULL)
2856  {
2857    pDelete(&(currRing->ppNoether));
2858  }
2859  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2860      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2861  {
2862    sLastPrinted.CleanUp();
2863  }
2864
2865  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2866  int i, nv = currRing->N;
2867
2868  r->cf  = currRing->cf;
2869  r->N   = currRing->N;
2870
2871  int nb = 4;
2872
2873  //names
2874  char* Q; // In order to avoid the corrupted memory, do not change.
2875  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2876  for(i=0; i<nv; i++)
2877  {
2878    Q = currRing->names[i];
2879    r->names[i]  = omStrDup(Q);
2880  }
2881
2882  /*weights: entries for 3 blocks: NULL Made:???*/
2883  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2884  r->wvhdl[0] = (int*) omAlloc(nv*nv*sizeof(int));
2885  r->wvhdl[1] =NULL; // (int*) omAlloc(nv*sizeof(int));
2886  r->wvhdl[2]=NULL;
2887  r->wvhdl[3]=NULL;
2888  for(i=0; i<nv*nv; i++)
2889    r->wvhdl[0][i] = (*va)[i];
2890
2891  /* order: a,lp,C,0 */
2892  r->order = (int *) omAlloc(nb * sizeof(int *));
2893  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2894  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2895
2896  // ringorder a for the first block: var 1..nv
2897  r->order[0]  = ringorder_M;
2898  r->block0[0] = 1;
2899  r->block1[0] = nv;
2900
2901  // ringorder C for the second block
2902  r->order[1]  = ringorder_C;
2903  r->block0[1] = 1;
2904  r->block1[1] = nv;
2905
2906
2907// ringorder C for the third block: var 1..nv
2908  r->order[2]  = ringorder_C;
2909  r->block0[2] = 1;
2910  r->block1[2] = nv;
2911
2912
2913  // the last block: everything is 0
2914  r->order[3]  = 0;
2915
2916  // polynomial ring
2917  r->OrdSgn    = 1;
2918
2919  // complete ring intializations
2920
2921  rComplete(r);
2922
2923  //rChangeCurrRing(r);
2924  return r;
2925}
2926
2927/***********************************************************
2928 * define and execute a new ring with ordering (a(vb),M,C) *
2929 ***********************************************************/
2930static ring VMatrRefine(intvec* va, intvec* vb)
2931{
2932
2933  if ((currRing->ppNoether)!=NULL)
2934  {
2935    pDelete(&(currRing->ppNoether));
2936  }
2937  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
2938      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
2939  {
2940    sLastPrinted.CleanUp();
2941  }
2942
2943  ring r = (ring) omAlloc0Bin(sip_sring_bin);
2944  int i, nv = currRing->N;
2945  int nvs = nv*nv;
2946  r->cf  = currRing->cf;
2947  r->N   = currRing->N;
2948
2949  int nb = 4;
2950
2951  //names
2952  char* Q; // In order to avoid the corrupted memory, do not change.
2953  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
2954  for(i=0; i<nv; i++)
2955  {
2956    Q = currRing->names[i];
2957    r->names[i]  = omStrDup(Q);
2958  }
2959
2960  /*weights: entries for 3 blocks: NULL Made:???*/
2961  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
2962  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
2963  r->wvhdl[1] = (int*) omAlloc(nvs*sizeof(int));
2964  r->wvhdl[2]=NULL;
2965  r->wvhdl[3]=NULL;
2966  for(i=0; i<nvs; i++)
2967  {
2968    r->wvhdl[1][i] = (*va)[i];
2969  }
2970  for(i=0; i<nv; i++)
2971  {
2972    r->wvhdl[0][i] = (*vb)[i];
2973  }
2974  /* order: a,lp,C,0 */
2975  r->order = (int *) omAlloc(nb * sizeof(int *));
2976  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
2977  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
2978
2979  // ringorder a for the first block: var 1..nv
2980  r->order[0]  = ringorder_a;
2981  r->block0[0] = 1;
2982  r->block1[0] = nv;
2983
2984  // ringorder M for the second block: var 1..nv
2985  r->order[1]  = ringorder_M;
2986  r->block0[1] = 1;
2987  r->block1[1] = nv;
2988
2989  // ringorder C for the third block: var 1..nv
2990  r->order[2]  = ringorder_C;
2991  r->block0[2] = 1;
2992  r->block1[2] = nv;
2993
2994
2995  // the last block: everything is 0
2996  r->order[3]  = 0;
2997
2998  // polynomial ring
2999  r->OrdSgn    = 1;
3000
3001  // complete ring intializations
3002
3003  rComplete(r);
3004
3005  //rChangeCurrRing(r);
3006  return r;
3007}
3008
3009/**********************************************************************
3010* define and execute a new ring which order is  a lexicographic order *
3011***********************************************************************/
3012static void VMrDefaultlp(void)
3013{
3014
3015  if ((currRing->ppNoether)!=NULL)
3016  {
3017    pDelete(&(currRing->ppNoether));
3018  }
3019  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
3020      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
3021
3022  {
3023    sLastPrinted.CleanUp();
3024  }
3025
3026  ring r = (ring) omAlloc0Bin(sip_sring_bin);
3027  int i, nv = currRing->N;
3028
3029  r->cf  = currRing->cf;
3030  r->N   = currRing->N;
3031  int nb = rBlocks(currRing) + 1;
3032
3033  // names
3034  char* Q; // to avoid the corrupted memory, do not change!!
3035  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
3036  for(i=0; i<nv; i++)
3037  {
3038    Q = currRing->names[i];
3039    r->names[i]  = omStrDup(Q);
3040  }
3041
3042  /*weights: entries for 3 blocks: NULL Made:???*/
3043
3044  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
3045
3046  /* order: lp,C,0 */
3047  r->order = (int *) omAlloc(nb * sizeof(int *));
3048  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
3049  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
3050
3051  /* ringorder lp for the first block: var 1..nv */
3052  r->order[0]  = ringorder_lp;
3053  r->block0[0] = 1;
3054  r->block1[0] = nv;
3055
3056  /* ringorder C for the second block */
3057  r->order[1]  = ringorder_C;
3058
3059  /* the last block: everything is 0 */
3060  r->order[2]  = 0;
3061
3062  /*polynomial ring*/
3063  r->OrdSgn    = 1;
3064
3065  /* complete ring intializations */
3066
3067  rComplete(r);
3068
3069  rChangeCurrRing(r);
3070}
3071
3072/***************************************************
3073* define a ring with parameters und change to it   *
3074* DefRingPar and DefRingParlp corrupt still memory *
3075****************************************************/
3076static void DefRingPar(intvec* va)
3077{
3078  int i, nv = currRing->N;
3079  int nb = rBlocks(currRing) + 1;
3080
3081  ring res=(ring)omAllocBin(sip_sring_bin);
3082
3083  memcpy(res,currRing,sizeof(ip_sring));
3084
3085  res->VarOffset = NULL;
3086  res->ref=0;
3087
3088  res->cf = currRing->cf; currRing->cf->ref++;
3089
3090
3091  /*weights: entries for 3 blocks: NULL Made:???*/
3092  res->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
3093  res->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
3094  for(i=0; i<nv; i++)
3095    res->wvhdl[0][i] = (*va)[i];
3096
3097  /* order: a,lp,C,0 */
3098
3099  res->order = (int *) omAlloc(nb * sizeof(int *));
3100  res->block0 = (int *)omAlloc0(nb * sizeof(int *));
3101  res->block1 = (int *)omAlloc0(nb * sizeof(int *));
3102
3103  // ringorder a for the first block: var 1..nv
3104  res->order[0]  = ringorder_a;
3105  res->block0[0] = 1;
3106  res->block1[0] = nv;
3107
3108  // ringorder lp for the second block: var 1..nv
3109  res->order[1]  = ringorder_lp;
3110  res->block0[1] = 1;
3111  res->block1[1] = nv;
3112
3113  // ringorder C for the third block
3114  // it is very important within "idLift",
3115  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
3116  // therefore, nb  must be (nBlocks(currRing)  + 1)
3117  res->order[2]  = ringorder_C;
3118
3119  // the last block: everything is 0
3120  res->order[3]  = 0;
3121
3122  // polynomial ring
3123  res->OrdSgn    = 1;
3124
3125
3126  res->names   = (char **)omAlloc0(nv * sizeof(char_ptr));
3127  for (i=nv-1; i>=0; i--)
3128  {
3129    res->names[i] = omStrDup(currRing->names[i]);
3130  }
3131  // complete ring intializations
3132  rComplete(res);
3133
3134  // clean up history
3135  if (sLastPrinted.RingDependend())
3136  {
3137    sLastPrinted.CleanUp();
3138  }
3139
3140
3141  // execute the created ring
3142  rChangeCurrRing(res);
3143}
3144
3145
3146static void DefRingParlp(void)
3147{
3148  int i, nv = currRing->N;
3149
3150  ring r=(ring)omAllocBin(sip_sring_bin);
3151
3152  memcpy(r,currRing,sizeof(ip_sring));
3153
3154  r->VarOffset = NULL;
3155  r->ref=0;
3156
3157  r->cf = currRing->cf; currRing->cf->ref++;
3158
3159
3160  r->cf  = currRing->cf;
3161  r->N   = currRing->N;
3162  int nb = rBlocks(currRing) + 1;
3163
3164  // names
3165  char* Q;
3166  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
3167  for(i=nv-1; i>=0; i--)
3168  {
3169    Q = currRing->names[i];
3170    r->names[i]  = omStrDup(Q);
3171  }
3172
3173  /*weights: entries for 3 blocks: NULL Made:???*/
3174
3175  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
3176
3177  /* order: lp,C,0 */
3178  r->order = (int *) omAlloc(nb * sizeof(int *));
3179  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
3180  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
3181
3182  /* ringorder lp for the first block: var 1..nv */
3183  r->order[0]  = ringorder_lp;
3184  r->block0[0] = 1;
3185  r->block1[0] = nv;
3186
3187  /* ringorder C for the second block */
3188  r->order[1]  = ringorder_C;
3189
3190  /* the last block: everything is 0 */
3191  r->order[2]  = 0;
3192
3193  /*polynomial ring*/
3194  r->OrdSgn    = 1;
3195
3196
3197//   if (rParameter(currRing)!=NULL)
3198//   {
3199//     r->cf->extRing->qideal->m[0]=p_Copy(currRing->cf->extRing->qideal->m[0], currRing->cf->extRing);
3200//     int l=rPar(currRing);
3201//     r->cf->extRing->names=(char **)omAlloc(l*sizeof(char_ptr));
3202//
3203//     for(i=l-1;i>=0;i--)
3204//     {
3205//       rParameter(r)[i]=omStrDup(rParameter(currRing)[i]);
3206//     }
3207//   }
3208
3209  // complete ring intializations
3210
3211  rComplete(r);
3212
3213  // clean up history
3214  if (sLastPrinted.RingDependend())
3215  {
3216    sLastPrinted.CleanUp();
3217  }
3218
3219  // execute the created ring
3220  rChangeCurrRing(r);
3221}
3222
3223/*************************************************************
3224 * check whether one or more components of a vector are zero *
3225 *************************************************************/
3226static int isNolVector(intvec* hilb)
3227{
3228  int i;
3229  for(i=hilb->length()-1; i>=0; i--)
3230  {
3231    if((* hilb)[i]==0)
3232    {
3233      return 1;
3234    }
3235  }
3236  return 0;
3237}
3238
3239/*************************************************************
3240 * check whether one or more components of a vector are <= 0 *
3241 *************************************************************/
3242static int isNegNolVector(intvec* hilb)
3243{
3244  int i;
3245  for(i=hilb->length()-1; i>=0; i--)
3246  {
3247    if((* hilb)[i]<=0)
3248    {
3249      return 1;
3250    }
3251  }
3252  return 0;
3253}
3254
3255/**************************************************************************
3256* Gomega is the initial ideal of G w. r. t. the current weight vector     *
3257* curr_weight. Check whether curr_weight lies on a border of the Groebner *
3258* cone, i. e. check whether a monomial is divisible by a leading monomial *
3259***************************************************************************/
3260static ideal middleOfCone(ideal G, ideal Gomega)
3261{
3262  BOOLEAN middle = FALSE;
3263  int i,j,N = IDELEMS(Gomega);
3264  poly p,lm,factor1,factor2;
3265
3266  ideal Go = idCopy(G);
3267 
3268  // check whether leading monomials of G and Gomega coincide
3269  // and return NULL if not
3270  for(i=0; i<N; i++)
3271  {
3272    if(!pIsConstant(pSub(pCopy(Gomega->m[i]),pCopy(pHead(G->m[i])))))
3273    {
3274      idDelete(&Go);
3275      return NULL; 
3276    }
3277  }
3278  for(i=0; i<N; i++)
3279  {
3280    for(j=0; j<N; j++)
3281    {
3282      if(i!=j)
3283      {
3284        p = pCopy(Gomega->m[i]);
3285        lm = pCopy(Gomega->m[j]);
3286        pIter(p);
3287        while(p!=NULL)
3288        {
3289          if(pDivisibleBy(lm,p))
3290          {
3291            if(middle == FALSE)
3292            {
3293              middle = TRUE;
3294            }
3295            factor1 = singclap_pdivide(pHead(p),lm,currRing);
3296            factor2 = pMult(pCopy(factor1),pCopy(Go->m[j]));
3297            pDelete(&factor1);
3298            Go->m[i] = pAdd((Go->m[i]),pNeg(pCopy(factor2)));
3299            pDelete(&factor2);
3300          }
3301          pIter(p);
3302        }
3303        pDelete(&lm);
3304        pDelete(&p);
3305      }
3306    }
3307  }
3308
3309  if(middle == TRUE)
3310  {
3311    return Go;
3312  }
3313  idDelete(&Go);
3314  return NULL; 
3315}
3316
3317/******************************  Februar 2002  ****************************
3318 * G is a Groebner basis w.r.t. (a(curr_weight),lp) and                   *
3319 * we compute a GB of <G> w.r.t. the lex. order by the perturbation walk  *
3320 * its perturbation degree is tp_deg                                      *
3321 * We call the following subfunction LastGB, if                           *
3322 * the computed intermediate weight vector or                             *
3323 * if the perturbed target weight vector does NOT lie n the correct cone  *
3324 **************************************************************************/
3325
3326static ideal LastGB(ideal G, intvec* curr_weight,int tp_deg)
3327{
3328  BOOLEAN nError = Overflow_Error;
3329  Overflow_Error = FALSE;
3330
3331  int i, nV = currRing->N;
3332  int nwalk=0, endwalks=0, nnwinC=1;
3333  int nlast = 0;
3334  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
3335  ring newRing, oldRing, TargetRing;
3336  intvec* iv_M_lp;
3337  intvec* target_weight;
3338  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
3339  intvec* pert_target_vector;
3340  intvec* ivNull = new intvec(nV);
3341  intvec* extra_curr_weight = new intvec(nV);
3342  intvec* next_weight;
3343
3344#ifndef  BUCHBERGER_ALG
3345  intvec* hilb_func;
3346#endif
3347
3348  // to avoid (1,0,...,0) as the target vector
3349  intvec* last_omega = new intvec(nV);
3350  for(i=nV-1; i>0; i--)
3351  {
3352    (*last_omega)[i] = 1;
3353  }
3354  (*last_omega)[0] = 10000;
3355
3356  ring EXXRing = currRing;
3357
3358  // compute a pertubed weight vector of the target weight vector
3359  if(tp_deg > 1 && tp_deg <= nV)
3360  {
3361    //..25.03.03 VMrDefaultlp();//    VMrDefault(target_weight);
3362    if (rParameter (currRing) != NULL)
3363    {
3364      DefRingParlp();
3365    }
3366    else
3367    {
3368      VMrDefaultlp();
3369    }
3370    TargetRing = currRing;
3371    ssG = idrMoveR(G,EXXRing,currRing);
3372    iv_M_lp = MivMatrixOrderlp(nV);
3373    //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
3374    target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
3375    delete iv_M_lp;
3376    pert_target_vector = target_weight;
3377
3378    rChangeCurrRing(EXXRing);
3379    G = idrMoveR(ssG, TargetRing,currRing);
3380  }
3381  else
3382  {
3383    target_weight = Mivlp(nV);
3384  }
3385  //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3386
3387  while(1)
3388  {
3389    nwalk++;
3390    nstep++;
3391    to=clock();
3392   // compute a next weight vector
3393    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
3394    xtnw=xtnw+clock()-to;
3395
3396#ifdef PRINT_VECTORS
3397    MivString(curr_weight, target_weight, next_weight);
3398#endif
3399
3400    if(Overflow_Error == TRUE)
3401    {
3402      newRing = currRing;
3403      nnwinC = 0;
3404      if(tp_deg == 1)
3405      {
3406        nlast = 1;
3407      }
3408      delete next_weight;
3409
3410      //idElements(G, "G");
3411      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3412
3413      break;
3414    }
3415
3416    if(MivComp(next_weight, ivNull) == 1)
3417    {
3418      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3419      newRing = currRing;
3420      delete next_weight;
3421      break;
3422    }
3423
3424    if(MivComp(next_weight, target_weight) == 1)
3425      endwalks = 1;
3426
3427    for(i=nV-1; i>=0; i--)
3428    {
3429      (*extra_curr_weight)[i] = (*curr_weight)[i];
3430    }
3431    /* 06.11.01 NOT Changed */
3432    for(i=nV-1; i>=0; i--)
3433    {
3434      (*curr_weight)[i] = (*next_weight)[i];
3435    }
3436    oldRing = currRing;
3437    to=clock();
3438    // compute an initial form ideal of <G> w.r.t. "curr_vector"
3439    Gomega = MwalkInitialForm(G, curr_weight);
3440    xtif=xtif+clock()-to;
3441
3442#ifdef ENDWALKS
3443    if(endwalks == 1)
3444    {
3445      Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3446/*
3447      idElements(Gomega, "Gw");
3448      headidString(Gomega, "Gw");
3449*/
3450    }
3451#endif
3452
3453#ifndef  BUCHBERGER_ALG
3454    if(isNolVector(curr_weight) == 0)
3455    {
3456      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
3457    }
3458    else
3459    {
3460      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
3461    }
3462#endif // BUCHBERGER_ALG
3463
3464    /* define a new ring that its ordering is "(a(curr_weight),lp) */
3465    //..25.03.03 VMrDefault(curr_weight);
3466    if (rParameter (currRing) != NULL)
3467    {
3468      DefRingPar(curr_weight);
3469    }
3470    else
3471    {
3472      rChangeCurrRing(VMrDefault(curr_weight));
3473    }
3474    newRing = currRing;
3475    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
3476
3477    to=clock();
3478    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
3479#ifdef  BUCHBERGER_ALG
3480    M = MstdhomCC(Gomega1);
3481#else
3482    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
3483    delete hilb_func;
3484#endif // BUCHBERGER_ALG
3485    xtstd=xtstd+clock()-to;
3486    /* change the ring to oldRing */
3487    rChangeCurrRing(oldRing);
3488    M1 =  idrMoveR(M, newRing,currRing);
3489    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
3490
3491    to=clock();
3492    /* compute a reduced Groebner basis of <G> w.r.t. "newRing" */
3493    F = MLifttwoIdeal(Gomega2, M1, G);
3494    xtlift=xtlift+clock()-to;
3495
3496    idDelete(&M1);
3497    idDelete(&G);
3498
3499    /* change the ring to newRing */
3500    rChangeCurrRing(newRing);
3501    F1 = idrMoveR(F, oldRing,currRing);
3502
3503    to=clock();
3504    /* reduce the Groebner basis <G> w.r.t. new ring */
3505    G = kInterRedCC(F1, NULL);
3506    xtred=xtred+clock()-to;
3507    idDelete(&F1);
3508
3509    if(endwalks == 1)
3510    {
3511      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3512      break;
3513    }
3514
3515    delete next_weight;
3516  }//while
3517
3518  delete ivNull;
3519
3520  if(tp_deg != 1)
3521  {
3522    //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3523    if (rParameter (currRing) != NULL)
3524    {
3525      DefRingParlp();
3526    }
3527    else
3528    {
3529      VMrDefaultlp();
3530    }
3531    F1 = idrMoveR(G, newRing,currRing);
3532
3533    if(nnwinC == 0 || test_w_in_ConeCC(F1, pert_target_vector) != 1)
3534    {
3535      oldRing = currRing;
3536      rChangeCurrRing(newRing);
3537      G = idrMoveR(F1, oldRing,currRing);
3538      Print("\n// takes %d steps and calls the recursion of level %d:",
3539             nwalk, tp_deg-1);
3540
3541      F1 = LastGB(G,curr_weight, tp_deg-1);
3542    }
3543
3544    TargetRing = currRing;
3545    rChangeCurrRing(EXXRing);
3546    result = idrMoveR(F1, TargetRing,currRing);
3547  }
3548  else
3549  {
3550    if(nlast == 1)
3551    {
3552      //OMEGA_OVERFLOW_LASTGB:
3553      /*
3554      if(MivSame(curr_weight, iv_lp) == 1)
3555        if (rParameter(currRing) != NULL)
3556          DefRingParlp();
3557        else
3558          VMrDefaultlp();
3559      else
3560        if (rParameter(currRing) != NULL)
3561          DefRingPar(curr_weight);
3562        else
3563          VMrDefault(curr_weight);
3564      */
3565
3566        //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
3567        if (rParameter (currRing) != NULL)
3568        {
3569          DefRingParlp();
3570        }
3571        else
3572        {
3573          VMrDefaultlp();
3574        }
3575
3576      F1 = idrMoveR(G, newRing,currRing);
3577      //Print("\n// Apply \"std\" in ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
3578
3579      G = MstdCC(F1);
3580      idDelete(&F1);
3581      newRing = currRing;
3582    }
3583
3584    rChangeCurrRing(EXXRing);
3585    result = idrMoveR(G, newRing,currRing);
3586  }
3587  delete target_weight;
3588  delete last_omega;
3589  delete iv_lp;
3590
3591  if(Overflow_Error == FALSE)
3592  {
3593    Overflow_Error = nError;
3594  }
3595  return(result);
3596}
3597
3598/**********************************************************
3599 * check whether a polynomial of G has least 4 monomials  *
3600 **********************************************************/
3601static int lengthpoly(ideal G)
3602{
3603  int i;
3604  for(i=IDELEMS(G)-1; i>=0; i--)
3605  {
3606    if((G->m[i]!=NULL) /* len >=0 */
3607       && (G->m[i]->next!=NULL) /* len >=1 */
3608       && (G->m[i]->next->next!=NULL) /* len >=2 */
3609       && (G->m[i]->next->next->next!=NULL) /* len >=3 */
3610       && (G->m[i]->next->next->next->next!=NULL) /* len >=4*/ )
3611    {
3612      return 1;
3613    }
3614  }
3615  return 0;
3616}
3617
3618/*****************************************
3619 * return maximal polynomial length of G *
3620 *****************************************/
3621static int maxlengthpoly(ideal G)
3622{
3623  int i,k,length=0;
3624  for(i=IDELEMS(G)-1; i>=0; i--)
3625  {
3626    k = pLength(G->m[i]);
3627    if(k>length)
3628    {
3629      length = k;
3630    }
3631  }
3632  return length;
3633}
3634
3635/*********************************************************
3636 * check whether a polynomial of G has least 2 monomials *
3637**********************************************************/
3638static int islengthpoly2(ideal G)
3639{
3640  int i;
3641  for(i=IDELEMS(G)-1; i>=0; i--)
3642  {
3643    if((G->m[i]!=NULL) /* len >=0 */
3644       && (G->m[i]->next!=NULL) /* len >=1 */
3645       && (G->m[i]->next->next!=NULL)) /* len >=2 */
3646    {
3647      return 1;
3648    }
3649  }
3650  return 0;
3651}
3652
3653
3654
3655/* Implementation of the improved Groebner walk algorithm which is written
3656   by Quoc-Nam Tran (2000).
3657   One perturbs the original target weight vector, only if
3658   the next intermediate weight vector is equal to the current target weight
3659   vector. This must be repeated until the wanted reduced Groebner basis
3660   to reach.
3661   If the numbers of variables is big enough, the representation of the origin
3662   weight vector may be very big. Therefore, it is possible the intermediate
3663   weight vector doesn't stay in the correct Groebner cone.
3664   In this case we have just a reduced Groebner basis of the given ideal
3665   with respect to another monomial order. Then we have to compute
3666   a wanted reduced Groebner basis of it with respect to the given order.
3667   At the following subroutine we use the improved Buchberger algorithm or
3668   the changed perturbation walk algorithm with a decrased degree.
3669 */
3670
3671/***************************************
3672 * return the initial term of an ideal *
3673 ***************************************/
3674static ideal idHeadCC(ideal h)
3675{
3676  int i, nH =IDELEMS(h);
3677
3678  ideal m = idInit(nH,h->rank);
3679
3680  for (i=nH-1;i>=0; i--)
3681  {
3682    if (h->m[i]!=NULL)
3683    {
3684      m->m[i]=pHead(h->m[i]);
3685    }
3686  }
3687  return m;
3688}
3689
3690/**********************************************
3691 * check whether two head-ideals are the same *
3692 **********************************************/
3693static inline int test_G_GB_walk(ideal H0, ideal H1)
3694{
3695  int i, nG = IDELEMS(H0);
3696
3697  if(nG != IDELEMS(H1))
3698  {
3699    return 0;
3700  }
3701  for(i=nG-1; i>=0; i--)
3702  {
3703/*
3704    poly t;
3705    if((t=pSub(pCopy(H0->m[i]), pCopy(H1->m[i]))) != NULL)
3706    {
3707      pDelete(&t);
3708      return 0;
3709    }
3710    pDelete(&t);
3711*/
3712    if(!pEqualPolys(H0->m[i],H1->m[i]))
3713    {
3714      return 0;
3715    }
3716  }
3717  return 1;
3718}
3719
3720//unused
3721/*****************************************************
3722 * find the maximal total degree of polynomials in G *
3723 *****************************************************/
3724/*
3725static int Trandegreebound(ideal G)
3726{
3727  int i, nG = IDELEMS(G);
3728  // int np=1;
3729  int nV = currRing->N;
3730  int degtmp, result = 0;
3731  intvec* ivUnit = Mivdp(nV);
3732
3733  for(i=nG-1; i>=0; i--)
3734  {
3735    // find the maximal total degree of the polynomial G[i]
3736    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3737    if(degtmp > result)
3738    {
3739      result = degtmp;
3740    }
3741  }
3742  delete ivUnit;
3743  return result;
3744}
3745*/
3746
3747//unused
3748/************************************************************************
3749 * perturb the weight vector iva w.r.t. the ideal G.                    *
3750 *  the monomial order of the current ring is the w_1 weight lex. order *
3751 *  define w := d^(n-1)w_1+ d^(n-2)w_2, ...+ dw_(n-1)+ w_n              *
3752 *  where d := 1 + max{totdeg(g):g in G}*m, or                          *
3753 *  d := (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;                           *
3754 ************************************************************************/
3755#if 0
3756static intvec* TranPertVector(ideal G, intvec* iva)
3757{
3758  BOOLEAN nError = Overflow_Error;
3759  Overflow_Error = FALSE;
3760
3761  int i, j;
3762  // int nG = IDELEMS(G);
3763  int nV = currRing->N;
3764
3765  // define the sequence which expresses the current monomial ordering
3766  // w_1 = iva; w_2 = (1,0,..,0); w_n = (0,...,0,1,0)
3767  intvec* ivMat = MivMatrixOrder(iva);
3768
3769  int  mtmp, m=(*iva)[0];
3770
3771  for(i=ivMat->length(); i>=0; i--)
3772  {
3773    mtmp = (*ivMat)[i];
3774    if(mtmp <0)
3775    {
3776      mtmp = -mtmp;
3777    }
3778    if(mtmp > m)
3779    {
3780      m = mtmp;
3781    }
3782  }
3783
3784  // define the maximal total degree of polynomials of G
3785  mpz_t ndeg;
3786  mpz_init(ndeg);
3787
3788 // 12 Juli 03
3789#ifndef UPPER_BOUND
3790  mpz_set_si(ndeg, Trandegreebound(G)+1);
3791#else
3792  mpz_t ztmp;
3793  mpz_init(ztmp);
3794
3795  mpz_t maxdeg;
3796  mpz_init_set_si(maxdeg, Trandegreebound(G));
3797
3798  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;//Kalkbrenner (1999)
3799  mpz_pow_ui(ztmp, maxdeg, 2);
3800  mpz_mul_ui(ztmp, ztmp, 2);
3801  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3802  mpz_add(ndeg, ztmp, maxdeg);
3803  mpz_mul_ui(ndeg, ndeg, m);
3804
3805  mpz_clear(ztmp);
3806
3807  //PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3808  //Print("\n//         where d = %d, n = %d and bound = %d", maxdeg, nV, ndeg);
3809#endif //UPPER_BOUND
3810
3811#ifdef INVEPS_SMALL_IN_TRAN
3812  if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3813  {
3814    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3815  }
3816 //PrintS("\n// choose the \"small\" inverse epsilon:");
3817 //mpz_out_str(stdout, 10, ndeg);
3818#endif
3819  mpz_t deg_tmp;
3820  mpz_init_set(deg_tmp, ndeg);
3821
3822  mpz_t *ivres=( mpz_t *) omAlloc(nV*sizeof(mpz_t));
3823  mpz_init_set_si(ivres[nV-1],1);
3824
3825  for(i=nV-2; i>=0; i--)
3826  {
3827    mpz_init_set(ivres[i], deg_tmp);
3828    mpz_mul(deg_tmp, deg_tmp, ndeg);
3829  }
3830
3831  mpz_t *ivtmp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3832  for(i=0; i<nV; i++)
3833  {
3834    mpz_init(ivtmp[i]);
3835  }
3836  mpz_t sing_int;
3837  mpz_init_set_ui(sing_int,  2147483647);
3838
3839  intvec* repr_vector = new intvec(nV);
3840
3841  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3842  for(i=0; i<nV; i++)
3843  {
3844    for(j=0; j<nV; j++)
3845    {
3846      if( (*ivMat)[i*nV+j] >= 0 )
3847      {
3848        mpz_mul_ui(ivres[i], ivres[i], (*ivMat)[i*nV+j]);
3849      }
3850      else
3851      {
3852        mpz_mul_ui(ivres[i], ivres[i], -(*ivMat)[i*nV+j]);
3853        mpz_neg(ivres[i], ivres[i]);
3854      }
3855      mpz_add(ivtmp[j], ivtmp[j], ivres[i]);
3856    }
3857  }
3858  delete ivMat;
3859
3860  int ntrue=0;
3861  for(i=0; i<nV; i++)
3862  {
3863    (*repr_vector)[i] = mpz_get_si(ivtmp[i]);
3864    if(mpz_cmp(ivtmp[i], sing_int)>=0)
3865    {
3866      ntrue++;
3867      if(Overflow_Error == FALSE)
3868      {
3869        Overflow_Error = TRUE;
3870
3871        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3872        mpz_out_str( stdout, 10, ivtmp[i]);
3873        PrintS(" is greater than 2147483647 (max. integer representation)");
3874        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3875      }
3876    }
3877  }
3878  if(Overflow_Error == TRUE)
3879  {
3880    ivString(repr_vector, "repvector");
3881    Print("\n// %d element(s) of it are overflow!!", ntrue);
3882  }
3883
3884  if(Overflow_Error == FALSE)
3885    Overflow_Error=nError;
3886
3887  omFree(ivres);
3888  omFree(ivtmp);
3889
3890  mpz_clear(sing_int);
3891  mpz_clear(deg_tmp);
3892  mpz_clear(ndeg);
3893
3894  return repr_vector;
3895}
3896#endif
3897
3898//unused
3899#if 0
3900static intvec* TranPertVector_lp(ideal G)
3901{
3902  BOOLEAN nError = Overflow_Error;
3903  Overflow_Error = FALSE;
3904  // int j, nG = IDELEMS(G);
3905  int i;
3906  int nV = currRing->N;
3907
3908  // define the maximal total degree of polynomials of G
3909  mpz_t ndeg;
3910  mpz_init(ndeg);
3911
3912 // 12 Juli 03
3913#ifndef UPPER_BOUND
3914  mpz_set_si(ndeg, Trandegreebound(G)+1);
3915#else
3916  mpz_t ztmp;
3917  mpz_init(ztmp);
3918
3919  mpz_t maxdeg;
3920  mpz_init_set_si(maxdeg, Trandegreebound(G));
3921
3922  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg);//Kalkbrenner (1999)
3923  mpz_pow_ui(ztmp, maxdeg, 2);
3924  mpz_mul_ui(ztmp, ztmp, 2);
3925  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3926  mpz_add(ndeg, ztmp, maxdeg);
3927  // PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3928  // Print("\n//         where d = %d, n = %d and bound = %d",
3929  // mpz_get_si(maxdeg), nV, mpz_get_si(ndeg));
3930
3931 mpz_clear(ztmp);
3932
3933#endif
3934
3935#ifdef INVEPS_SMALL_IN_TRAN
3936 if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3937    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3938
3939 //PrintS("\n// choose the \"small\" inverse epsilon:");
3940 // mpz_out_str(stdout, 10, ndeg);
3941#endif
3942
3943  mpz_t deg_tmp;
3944  mpz_init_set(deg_tmp, ndeg);
3945
3946  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3947  mpz_init_set_si(ivres[nV-1], 1);
3948
3949  for(i=nV-2; i>=0; i--)
3950  {
3951    mpz_init_set(ivres[i], deg_tmp);
3952    mpz_mul(deg_tmp, deg_tmp, ndeg);
3953  }
3954
3955  mpz_t sing_int;
3956  mpz_init_set_ui(sing_int,  2147483647);
3957
3958  intvec* repr_vector = new intvec(nV);
3959  int ntrue=0;
3960  for(i=0; i<nV; i++)
3961  {
3962    (*repr_vector)[i] = mpz_get_si(ivres[i]);
3963
3964    if(mpz_cmp(ivres[i], sing_int)>=0)
3965    {
3966      ntrue++;
3967      if(Overflow_Error == FALSE)
3968      {
3969        Overflow_Error = TRUE;
3970        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3971        mpz_out_str( stdout, 10, ivres[i]);
3972        PrintS(" is greater than 2147483647 (max. integer representation)");
3973        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3974      }
3975    }
3976  }
3977  if(Overflow_Error == TRUE)
3978  {
3979    ivString(repr_vector, "repvector");
3980    Print("\n// %d element(s) of it are overflow!!", ntrue);
3981  }
3982  if(Overflow_Error == FALSE)
3983    Overflow_Error = nError;
3984
3985  omFree(ivres);
3986
3987  mpz_clear(ndeg);
3988  mpz_clear(sing_int);
3989
3990  return repr_vector;
3991}
3992#endif
3993
3994//unused
3995#if 0
3996static intvec* RepresentationMatrix_Dp(ideal G, intvec* M)
3997{
3998  BOOLEAN nError = Overflow_Error;
3999  Overflow_Error = FALSE;
4000
4001  int i, j;
4002  int nV = currRing->N;
4003
4004  intvec* ivUnit = Mivdp(nV);
4005  int degtmp, maxdeg = 0;
4006
4007  for(i=IDELEMS(G)-1; i>=0; i--)
4008  {
4009    // find the maximal total degree of the polynomial G[i]
4010    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
4011    if(degtmp > maxdeg)
4012      maxdeg = degtmp;
4013  }
4014
4015  mpz_t ztmp;
4016  mpz_init_set_si(ztmp, maxdeg);
4017  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
4018  mpz_init_set_si(ivres[nV-1], 1); // (*ivres)[nV-1] = 1;
4019
4020  for(i=nV-2; i>=0; i--)
4021  {
4022    mpz_init_set(ivres[i], ztmp); //(*ivres)[i] = ztmp;
4023    mpz_mul_ui(ztmp, ztmp, maxdeg); //ztmp *=maxdeg;
4024  }
4025
4026  mpz_t *ivtmp=(mpz_t*)omAlloc(nV*sizeof(mpz_t));
4027  for(i=0; i<nV; i++)
4028    mpz_init(ivtmp[i]);
4029
4030  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
4031  for(i=0; i<nV; i++)
4032    for(j=0; j<nV; j++)
4033    {
4034      if((*M)[i*nV+j] < 0)
4035      {
4036        mpz_mul_ui(ztmp, ivres[i], -(*M)[i*nV+j]);
4037        mpz_neg(ztmp, ztmp);
4038      }
4039      else
4040        mpz_mul_ui(ztmp, ivres[i], (*M)[i*nV+j]);
4041
4042      mpz_add(ivtmp[j], ivtmp[j], ztmp);
4043    }
4044  delete ivres;
4045  mpz_t sing_int;
4046  mpz_init_set_ui(sing_int,  2147483647);
4047
4048  int ntrue=0;
4049  intvec* repvector = new intvec(nV);
4050  for(i=0; i<nV; i++)
4051  {
4052    (*repvector)[i] = mpz_get_si(ivtmp[i]);
4053    if(mpz_cmp(ivtmp[i], sing_int)>0)
4054    {
4055      ntrue++;
4056      if(Overflow_Error == FALSE)
4057      {
4058        Overflow_Error = TRUE;
4059        PrintS("\n// ** OVERFLOW in \"Repr.Matrix\": ");
4060        mpz_out_str( stdout, 10, ivtmp[i]);
4061        PrintS(" is greater than 2147483647 (max. integer representation)");
4062        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repvector)[i]);
4063      }
4064    }
4065  }
4066  if(Overflow_Error == TRUE)
4067  {
4068    ivString(repvector, "repvector");
4069    Print("\n// %d element(s) of it are overflow!!", ntrue);
4070  }
4071
4072  if(Overflow_Error == FALSE)
4073    Overflow_Error = nError;
4074
4075  mpz_clear(sing_int);
4076  mpz_clear(ztmp);
4077  omFree(ivtmp);
4078  omFree(ivres);
4079  return repvector;
4080}
4081#endif
4082
4083/*****************************************************************************
4084 * The following subroutine is the implementation of our first improved      *
4085 * Groebner walk algorithm, i.e. the first altervative algorithm.            *
4086 * First we use the Grobner walk algorithm and then we call the changed      *
4087 * perturbation walk algorithm with decreased degree, if an intermediate     *
4088 * weight vector is equal to the current target weight vector.               *
4089 * This call will be only repeated until we get the wanted reduced Groebner  *
4090 * basis or n times, where n is the numbers of variables.                    *
4091 *****************************************************************************/
4092
4093// npwinc = 0, if curr_weight doesn't stay in the correct Groebner cone
4094static ideal Rec_LastGB(ideal G, intvec* curr_weight,
4095                        intvec* orig_target_weight, int tp_deg, int npwinc)
4096{
4097  BOOLEAN nError = Overflow_Error;
4098  Overflow_Error = FALSE;
4099  // BOOLEAN nOverflow_Error = FALSE;
4100
4101  clock_t tproc=0;
4102  clock_t tinput = clock();
4103
4104  int i,  nV = currRing->N;
4105  int nwalk=0, endwalks=0, nnwinC=1;
4106  int nlast = 0;
4107  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4108  ring newRing, oldRing, TargetRing;
4109  intvec* iv_M_lp;
4110  intvec* target_weight;
4111  intvec* ivNull = new intvec(nV); //define (0,...,0)
4112  ring EXXRing = currRing;
4113  //int NEG=0; //19 juni 03
4114  intvec* next_weight;
4115#ifndef  BUCHBERGER_ALG
4116  //08 Juli 03
4117  intvec* hilb_func;
4118#endif
4119  // to avoid (1,0,...,0) as the target vector
4120  intvec* last_omega = new intvec(nV);
4121  for(i=nV-1; i>0; i--)
4122    (*last_omega)[i] = 1;
4123  (*last_omega)[0] = 10000;
4124
4125  BOOLEAN isGB = FALSE;
4126
4127  // compute a pertubed weight vector of the target weight vector
4128  if(tp_deg > 1 && tp_deg <= nV)
4129  {
4130    ideal H0 = idHeadCC(G);
4131
4132    if (rParameter (currRing) != NULL)
4133    {
4134      DefRingParlp();
4135    }
4136    else
4137    {
4138      VMrDefaultlp();
4139    }
4140    TargetRing = currRing;
4141    ssG = idrMoveR(G,EXXRing,currRing);
4142
4143    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4144    ideal H1 = idHeadCC(ssG);
4145
4146    // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
4147    if(test_G_GB_walk(H0_tmp,H1)==1)
4148    {
4149      idDelete(&H0_tmp);
4150      idDelete(&H1);
4151      G = ssG;
4152      ssG = NULL;
4153      newRing = currRing;
4154      delete ivNull;
4155
4156      if(npwinc != 0)
4157      {
4158        goto LastGB_Finish;
4159      }
4160      else
4161      {
4162        isGB = TRUE;
4163        goto KSTD_Finish;
4164      }
4165    }
4166    idDelete(&H0_tmp);
4167    idDelete(&H1);
4168
4169    iv_M_lp = MivMatrixOrderlp(nV);
4170    target_weight  = MPertVectors(ssG, iv_M_lp, tp_deg);
4171    delete iv_M_lp;
4172    //PrintS("\n// Input is not GB!!");
4173    rChangeCurrRing(EXXRing);
4174    G = idrMoveR(ssG, TargetRing,currRing);
4175
4176    if(Overflow_Error == TRUE)
4177    {
4178      //nOverflow_Error = Overflow_Error;
4179      //NEG = 1;
4180      newRing = currRing;
4181      goto JUNI_STD;
4182    }
4183  }
4184
4185  while(1)
4186  {
4187    nwalk ++;
4188    nstep++;
4189
4190    if(nwalk==1)
4191    {
4192      goto FIRST_STEP;
4193    }
4194    to=clock();
4195    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4196    Gomega = MwalkInitialForm(G, curr_weight);
4197    xtif=xtif+clock()-to;
4198
4199#ifndef  BUCHBERGER_ALG
4200    if(isNolVector(curr_weight) == 0)
4201    {
4202      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4203    }
4204    else
4205    {
4206      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4207    }
4208#endif // BUCHBERGER_ALG
4209
4210    oldRing = currRing;
4211
4212    // defiNe a new ring that its ordering is "(a(curr_weight),lp)
4213    if (rParameter(currRing) != NULL)
4214    {
4215      DefRingPar(curr_weight);
4216    }
4217    else
4218    {
4219      rChangeCurrRing(VMrDefault(curr_weight));
4220    }
4221    newRing = currRing;
4222    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4223    to=clock();
4224    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4225#ifdef  BUCHBERGER_ALG
4226    M = MstdhomCC(Gomega1);
4227#else
4228    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4229    delete hilb_func;
4230#endif // BUCHBERGER_ALG
4231    xtstd=xtstd+clock()-to;
4232    // change the ring to oldRing
4233    rChangeCurrRing(oldRing);
4234    M1 =  idrMoveR(M, newRing,currRing);
4235    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4236
4237     to=clock();
4238    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
4239    F = MLifttwoIdeal(Gomega2, M1, G);
4240    xtlift=xtlift+clock()-to;
4241    idDelete(&M1);
4242    idDelete(&Gomega2);
4243    idDelete(&G);
4244
4245    // change the ring to newRing
4246    rChangeCurrRing(newRing);
4247    F1 = idrMoveR(F, oldRing,currRing);
4248
4249    to=clock();
4250    // reduce the Groebner basis <G> w.r.t. new ring
4251    G = kInterRedCC(F1, NULL);
4252    xtred=xtred+clock()-to;
4253    idDelete(&F1);
4254
4255    if(endwalks == 1)
4256    {
4257      break;
4258    }
4259  FIRST_STEP:
4260    to=clock();
4261    Overflow_Error = FALSE;
4262    // compute a next weight vector
4263    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4264    xtnw=xtnw+clock()-to;
4265#ifdef PRINT_VECTORS
4266    MivString(curr_weight, target_weight, next_weight);
4267#endif
4268
4269    if(Overflow_Error == TRUE)
4270    {
4271      //PrintS("\n// ** The next vector does NOT stay in Cone!!\n");
4272#ifdef TEST_OVERFLOW
4273      goto  LastGB_Finish;
4274#endif
4275
4276      nnwinC = 0;
4277      if(tp_deg == nV)
4278      {
4279        nlast = 1;
4280      }
4281      delete next_weight;
4282      break;
4283    }
4284
4285    if(MivComp(next_weight, ivNull) == 1)
4286    {
4287      //newRing = currRing;
4288      delete next_weight;
4289      break;
4290    }
4291
4292    if(MivComp(next_weight, target_weight) == 1)
4293    {
4294      if(tp_deg == nV)
4295      {
4296        endwalks = 1;
4297      }
4298      else
4299      {
4300        // REC_LAST_GB_ALT2:
4301        //nOverflow_Error = Overflow_Error;
4302        tproc=tproc+clock()-tinput;
4303       
4304        Print("\n// takes %d steps and calls \"Rec_LastGB\" (%d):",
4305        nwalk, tp_deg+1);
4306       
4307        G = Rec_LastGB(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4308        newRing = currRing;
4309        delete next_weight;
4310        break;
4311      }
4312    }
4313
4314    for(i=nV-1; i>=0; i--)
4315    {
4316      (*curr_weight)[i] = (*next_weight)[i];
4317    }
4318    delete next_weight;
4319  }//while
4320
4321  delete ivNull;
4322
4323  if(tp_deg != nV)
4324  {
4325    newRing = currRing;
4326
4327    if (rParameter(currRing) != NULL)
4328    {
4329      DefRingParlp();
4330    }
4331    else
4332    {
4333      VMrDefaultlp();
4334    }
4335    F1 = idrMoveR(G, newRing,currRing);
4336
4337    if(nnwinC == 0 || test_w_in_ConeCC(F1, target_weight) != 1 )
4338    {
4339      // nOverflow_Error = Overflow_Error;
4340      Print("\n//  takes %d steps and calls \"Rec_LastGB (%d):", tp_deg+1);
4341      tproc=tproc+clock()-tinput;
4342      F1 = Rec_LastGB(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4343    }
4344    delete target_weight;
4345
4346    TargetRing = currRing;
4347    rChangeCurrRing(EXXRing);
4348    result = idrMoveR(F1, TargetRing,currRing);
4349  }
4350  else
4351  {
4352    if(nlast == 1)
4353    {
4354      JUNI_STD:
4355
4356      newRing = currRing;
4357      if (rParameter(currRing) != NULL)
4358      {
4359        DefRingParlp();
4360      }
4361      else
4362      {
4363        VMrDefaultlp();
4364      }
4365      KSTD_Finish:
4366      if(isGB == FALSE)
4367      {
4368        F1 = idrMoveR(G, newRing,currRing);
4369      }
4370      else
4371      {
4372        F1 = G;
4373      }
4374      to=clock();
4375      // Print("\n// apply the Buchberger's alg in ring = %s",rString(currRing));
4376      // idElements(F1, "F1");
4377      G = MstdCC(F1);
4378      xtextra=xtextra+clock()-to;
4379
4380
4381      idDelete(&F1);
4382      newRing = currRing;
4383    }
4384
4385    LastGB_Finish:
4386    rChangeCurrRing(EXXRing);
4387    result = idrMoveR(G, newRing,currRing);
4388  }
4389
4390  if(Overflow_Error == FALSE)
4391    {
4392    Overflow_Error=nError;
4393    }
4394#ifdef TIME_TEST
4395   //Print("\n// \"Rec_LastGB\" (%d) took %d steps and %.2f sec.Overflow_Error (%d)", tp_deg, nwalk, ((double) tproc)/1000000, nOverflow_Error);
4396#endif
4397  return(result);
4398}
4399
4400/* The following subroutine is the implementation of our second improved
4401   Groebner walk algorithm, i.e. the second altervative algorithm.
4402   First we use the Grobner walk algorithm and then we call the changed
4403   perturbation walk algorithm with increased degree, if an intermediate
4404   weight vector is equal to the current target weight vector.
4405   This call will be only repeated until we get the wanted reduced Groebner
4406   basis or n times, where n is the numbers of variables.
4407*/
4408
4409/******************************
4410 * walk + recursive LastGB    *
4411 ******************************/
4412ideal MAltwalk2(ideal Go, intvec* curr_weight, intvec* target_weight)
4413{
4414  Set_Error(FALSE);
4415  Overflow_Error = FALSE;
4416  //BOOLEAN nOverflow_Error = FALSE;
4417  //Print("// pSetm_Error = (%d)", ErrorCheck());
4418#ifdef TIME_TEST
4419  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
4420  xftinput = clock();
4421  clock_t tostd, tproc;
4422#endif
4423  nstep = 0;
4424  int i, nV = currRing->N;
4425  int nwalk=0, endwalks=0;
4426  // int nhilb = 1;
4427  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
4428  //ideal  G1;
4429  //ring endRing;
4430  ring newRing, oldRing;
4431  intvec* ivNull = new intvec(nV);
4432  intvec* next_weight;
4433  //intvec* extra_curr_weight = new intvec(nV);
4434  //intvec* hilb_func;
4435  intvec* exivlp = Mivlp(nV);
4436  ring XXRing = currRing;
4437
4438  //Print("\n// ring r_input = %s;", rString(currRing));
4439#ifdef TIME_TEST
4440  to = clock();
4441#endif
4442  /* compute the reduced Groebner basis of the given ideal w.r.t.
4443     a "fast" monomial order, e.g. degree reverse lex. order (dp) */
4444  G = MstdCC(Go);
4445#ifdef TIME_TEST
4446  tostd=clock()-to;
4447
4448  Print("\n// Computation of the first std took = %.2f sec",
4449        ((double) tostd)/1000000);
4450#endif
4451  if(currRing->order[0] == ringorder_a)
4452  {
4453    goto NEXT_VECTOR;
4454  }
4455  while(1)
4456  {
4457    nwalk ++;
4458    nstep ++;
4459#ifdef TIME_TEST
4460    to = clock();
4461#endif
4462    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
4463    Gomega = MwalkInitialForm(G, curr_weight);
4464#ifdef TIME_TEST
4465    xtif=xtif+clock()-to;
4466#endif
4467/*
4468    if(Overflow_Error == TRUE)
4469    {
4470      for(i=nV-1; i>=0; i--)
4471        (*curr_weight)[i] = (*extra_curr_weight)[i];
4472      delete extra_curr_weight;
4473      goto LAST_GB_ALT2;
4474    }
4475*/
4476    oldRing = currRing;
4477
4478    /* define a new ring that its ordering is "(a(curr_weight),lp) */
4479    if (rParameter(currRing) != NULL)
4480    {
4481      DefRingPar(curr_weight);
4482    }
4483    else
4484    {
4485      rChangeCurrRing(VMrDefault(curr_weight));
4486    }
4487    newRing = currRing;
4488    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4489#ifdef TIME_TEST
4490    to = clock();
4491#endif
4492    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
4493    M = MstdhomCC(Gomega1);
4494#ifdef TIME_TEST
4495    xtstd=xtstd+clock()-to;
4496#endif
4497    /* change the ring to oldRing */
4498    rChangeCurrRing(oldRing);
4499    M1 =  idrMoveR(M, newRing,currRing);
4500    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4501#ifdef TIME_TEST
4502    to = clock();
4503#endif
4504    /* compute the reduced Groebner basis of <G> w.r.t. "newRing"
4505       by the liftig process */
4506    F = MLifttwoIdeal(Gomega2, M1, G);
4507#ifdef TIME_TEST
4508    xtlift=xtlift+clock()-to;
4509#endif
4510    idDelete(&M1);
4511    idDelete(&Gomega2);
4512    idDelete(&G);
4513
4514    /* change the ring to newRing */
4515    rChangeCurrRing(newRing);
4516    F1 = idrMoveR(F, oldRing,currRing);
4517#ifdef TIME_TEST
4518    to = clock();
4519#endif
4520    /* reduce the Groebner basis <G> w.r.t. newRing */
4521    G = kInterRedCC(F1, NULL);
4522#ifdef TIME_TEST
4523    xtred=xtred+clock()-to;
4524#endif
4525    idDelete(&F1);
4526
4527    if(endwalks == 1)
4528      break;
4529
4530  NEXT_VECTOR:
4531#ifdef TIME_TEST
4532    to = clock();
4533#endif
4534    /* compute a next weight vector */
4535    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4536#ifdef TIME_TEST
4537    xtnw=xtnw+clock()-to;
4538#endif
4539#ifdef PRINT_VECTORS
4540    MivString(curr_weight, target_weight, next_weight);
4541#endif
4542
4543    if(Overflow_Error == TRUE)
4544    {
4545      /*
4546        ivString(next_weight, "omega");
4547        PrintS("\n// ** The weight vector does NOT stay in Cone!!\n");
4548      */
4549#ifdef TEST_OVERFLOW
4550      goto  TEST_OVERFLOW_OI;
4551#endif
4552
4553      newRing = currRing;
4554      if (rParameter(currRing) != NULL)
4555      {
4556        DefRingPar(target_weight);
4557      }
4558      else
4559      {
4560        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
4561      }
4562      F1 = idrMoveR(G, newRing,currRing);
4563      G = MstdCC(F1);
4564      idDelete(&F1);
4565      newRing = currRing;
4566      break;
4567    }
4568
4569    if(MivComp(next_weight, ivNull) == 1)
4570    {
4571      newRing = currRing;
4572      delete next_weight;
4573      break;
4574    }
4575
4576    if(MivComp(next_weight, target_weight) == 1)
4577    {
4578      if(MivSame(target_weight, exivlp)==1)
4579      {
4580     // LAST_GB_ALT2:
4581        //nOverflow_Error = Overflow_Error;
4582#ifdef TIME_TEST
4583        tproc = clock()-xftinput;
4584#endif
4585        //Print("\n// takes %d steps and calls the recursion of level 2:",  nwalk);
4586        /* call the changed perturbation walk algorithm with degree 2 */
4587        G = Rec_LastGB(G, curr_weight, target_weight, 2,1);
4588        newRing = currRing;
4589        delete next_weight;
4590        break;
4591      }
4592      endwalks = 1;
4593    }
4594
4595    for(i=nV-1; i>=0; i--)
4596    {
4597      //(*extra_curr_weight)[i] = (*curr_weight)[i];
4598      (*curr_weight)[i] = (*next_weight)[i];
4599    }
4600    delete next_weight;
4601  }
4602#ifdef TEST_OVERFLOW
4603 TEST_OVERFLOW_OI:
4604#endif
4605  rChangeCurrRing(XXRing);
4606  G = idrMoveR(G, newRing,currRing);
4607  delete ivNull;
4608  delete exivlp;
4609
4610#ifdef TIME_TEST
4611  /*Print("\n// \"Main procedure\"  took %d steps dnd %.2f sec. Overflow_Error (%d)",
4612        nwalk, ((double) tproc)/1000000, nOverflow_Error);
4613*/
4614  TimeStringFractal(xftinput, tostd, xtif, xtstd, xtextra,xtlift, xtred,xtnw);
4615
4616  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
4617  //Print("\n// Overflow_Error? (%d)", nOverflow_Error);
4618  Print("\n// Awalk2 took %d steps!!", nstep);
4619#endif
4620
4621  return(G);
4622}
4623
4624
4625/**************************************
4626 * perturb the matrix order of  "lex" *
4627 **************************************/
4628static intvec* NewVectorlp(ideal I)
4629{
4630  int nV = currRing->N;
4631  intvec* iv_wlp =  MivMatrixOrderlp(nV);
4632  intvec* result = Mfpertvector(I, iv_wlp);
4633  delete iv_wlp;
4634  return result;
4635}
4636
4637int ngleich;
4638intvec* Xsigma;
4639intvec* Xtau;
4640int xn;
4641intvec* Xivinput;
4642intvec* Xivlp;
4643
4644
4645/********************************
4646 * compute a next weight vector *
4647 ********************************/
4648static intvec* MWalkRandomNextWeight(ideal G, intvec* orig_M, intvec* target_weight,
4649       int weight_rad, int pert_deg)
4650{
4651  assume(currRing != NULL && orig_M != NULL &&
4652         target_weight != NULL && G->m[0] != NULL);
4653
4654  //BOOLEAN nError = Overflow_Error;
4655  Overflow_Error = FALSE;
4656
4657  BOOLEAN found_random_weight = FALSE;
4658  int i,nV = currRing->N;
4659  intvec* curr_weight = new intvec(nV);
4660
4661  for(i=0; i<nV; i++)
4662  {
4663    (*curr_weight)[i] = (*orig_M)[i];
4664  }
4665
4666  int k=0,weight_norm;
4667  intvec* next_weight;
4668  intvec* next_weight1 = MkInterRedNextWeight(curr_weight,target_weight,G);
4669  intvec* next_weight2 = new intvec(nV);
4670  intvec* next_weight22 = new intvec(nV);
4671  intvec* result = new intvec(nV);
4672  intvec* curr_weight1;
4673  ideal G_test, G_test1, G_test2;
4674
4675  //try to find a random next weight vector "next_weight2"
4676  if(weight_rad > 0){ while(k<10)
4677  {
4678    weight_norm = 0;
4679    while(weight_norm == 0)
4680    {
4681
4682      for(i=0; i<nV; i++)
4683      {
4684        (*next_weight2)[i] = rand() % 60000 - 30000;
4685        weight_norm = weight_norm + (*next_weight2)[i]*(*next_weight2)[i];
4686      }
4687      weight_norm = 1 + floor(sqrt(weight_norm));
4688    }
4689
4690    for(i=0; i<nV; i++)
4691    {
4692      if((*next_weight2)[i] < 0)
4693      {
4694        (*next_weight2)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4695      }
4696      else
4697      {
4698        (*next_weight2)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4699      }
4700    }
4701   
4702    if(test_w_in_ConeCC(G,next_weight2) == 1)
4703    {
4704      if(maxlengthpoly(MwalkInitialForm(G,next_weight2))<2)
4705      {
4706        next_weight2 = MkInterRedNextWeight(next_weight2,target_weight,G);
4707      }
4708/*
4709      if(MivAbsMax(next_weight2)>1147483647)
4710      {
4711        for(i=0; i<nV; i++)
4712        {
4713          (*next_weight22)[i] = (*next_weight2)[i];
4714        }
4715        i = 0;
4716        // reduce the size of the maximal entry of the vector
4717        while(test_w_in_ConeCC(G,next_weight22) == 1)
4718        {
4719          (*next_weight2)[i] = (*next_weight22)[i];
4720          i = MivAbsMaxArg(next_weight22);
4721          (*next_weight22)[i] = floor(0.1*(*next_weight22)[i] + 0.5);
4722        }
4723        delete next_weight22;
4724      }
4725*/
4726      G_test2 = MwalkInitialForm(G, next_weight2);
4727      found_random_weight = TRUE;
4728      break;
4729    }
4730    k++;
4731  }}
4732Print("\n MWalkRandomNextWeight: compute perurbation...\n");
4733  // compute "perturbed" next weight vector
4734  if(pert_deg > 1)
4735  {
4736    curr_weight1 = MPertVectors(G,orig_M,pert_deg);
4737    next_weight = MkInterRedNextWeight(curr_weight1,target_weight,G);
4738    delete curr_weight1;
4739  }
4740  else
4741  {
4742    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4743  }
4744  if(MivSame(curr_weight,next_weight)==1 || Overflow_Error == TRUE)
4745  { 
4746    Overflow_Error = FALSE;
4747    delete next_weight;
4748    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4749  }
4750  G_test=MwalkInitialForm(G,next_weight);
4751  G_test1=MwalkInitialForm(G,next_weight1);
4752Print("\n MWalkRandomNextWeight: finished...\n");
4753  // compare next weights
4754  if(Overflow_Error == FALSE)
4755  {
4756    if(found_random_weight == TRUE)
4757    {
4758    // random next weight vector found
4759      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4760      {
4761        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test1))
4762        {
4763          for(i=0; i<nV; i++)
4764          {
4765            (*result)[i] = (*next_weight2)[i];
4766          }
4767        }
4768        else
4769        {
4770          for(i=0; i<nV; i++)
4771          {
4772            (*result)[i] = (*next_weight1)[i];
4773          }
4774        }   
4775      }
4776      else
4777      {
4778        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4779        {
4780          for(i=0; i<nV; i++)
4781          {
4782            (*result)[i] = (*next_weight2)[i];
4783          }
4784        }
4785        else
4786        {
4787          for(i=0; i<nV; i++)
4788          {
4789            (*result)[i] = (*next_weight)[i];
4790          }
4791        }
4792      }
4793    }
4794    else
4795    {
4796      // no random next weight vector found
4797      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4798      {
4799       for(i=0; i<nV; i++)
4800        {
4801          (*result)[i] = (*next_weight1)[i];
4802        }
4803      }
4804      else
4805      {
4806        for(i=0; i<nV; i++)
4807        {
4808          (*result)[i] = (*next_weight)[i];
4809        }
4810      }
4811    }
4812  }
4813  else
4814  {
4815    Overflow_Error = FALSE;
4816    if(found_random_weight == TRUE)
4817    {
4818      if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4819      {
4820        for(i=1; i<nV; i++)
4821        {
4822          (*result)[i] = (*next_weight2)[i];
4823        }
4824      }
4825      else
4826      {
4827        for(i=0; i<nV; i++)
4828        {
4829          (*result)[i] = (*next_weight)[i];
4830        }
4831      }
4832    }
4833    else
4834    {
4835      for(i=0; i<nV; i++)
4836      {
4837        (*result)[i] = (*next_weight)[i];
4838      }
4839    }
4840  }
4841 // delete curr_weight1;
4842  delete next_weight;
4843  delete next_weight2;
4844  idDelete(&G_test);
4845  idDelete(&G_test1);
4846  if(found_random_weight == TRUE)
4847  {
4848    idDelete(&G_test2);
4849  }
4850  if(test_w_in_ConeCC(G, result) == 1 && MivSame(curr_weight,result)==0)
4851  { 
4852    delete curr_weight;
4853    delete next_weight1;
4854    return result;
4855  }
4856  else
4857  {
4858    delete curr_weight;
4859    delete result;
4860    return next_weight1;
4861  }
4862}
4863
4864
4865/***************************************************************************
4866 * The procedur REC_GB_Mwalk computes a GB for <G> w.r.t. the weight order *
4867 * otw, where G is a reduced GB w.r.t. the weight order cw.                *
4868 * The new procedure Mwalk calls REC_GB.                                   *
4869 ***************************************************************************/
4870static ideal REC_GB_Mwalk(ideal G, intvec* curr_weight, intvec* orig_target_weight,
4871                          int tp_deg, int npwinc)
4872{
4873  BOOLEAN nError = Overflow_Error;
4874  Overflow_Error = FALSE;
4875
4876  int i,  nV = currRing->N;
4877  int nwalk=0, endwalks=0, nnwinC=1, nlast = 0;
4878  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4879  ring newRing, oldRing, TargetRing;
4880  intvec* target_weight;
4881  intvec* ivNull = new intvec(nV);
4882#ifndef BUCHBERGER_ALG
4883  intvec* hilb_func;
4884  // to avoid (1,0,...,0) as the target vector
4885  intvec* last_omega = new intvec(nV);
4886  for(i=nV-1; i>0; i--)
4887  {
4888    (*last_omega)[i] = 1;
4889  }
4890  (*last_omega)[0] = 10000;
4891#endif
4892  BOOLEAN isGB = FALSE;
4893
4894  ring EXXRing = currRing;
4895
4896  // compute a pertubed weight vector of the target weight vector
4897  if(tp_deg > 1 && tp_deg <= nV)
4898  {
4899    ideal H0 = idHeadCC(G);
4900    if (rParameter(currRing) != NULL)
4901    {
4902      DefRingPar(orig_target_weight);
4903    }
4904    else
4905    {
4906      rChangeCurrRing(VMrDefault(orig_target_weight));
4907    }
4908    TargetRing = currRing;
4909    ssG = idrMoveR(G,EXXRing,currRing);
4910
4911    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4912    ideal H1 = idHeadCC(ssG);
4913    id_Delete(&H0,EXXRing);
4914
4915    if(test_G_GB_walk(H0_tmp,H1)==1)
4916    {
4917      //Print("\n//REC_GB_Mwalk: input in %d-th recursive is a GB!\n",tp_deg);
4918      idDelete(&H0_tmp);
4919      idDelete(&H1);
4920      G = ssG;
4921      ssG = NULL;
4922      newRing = currRing;
4923      delete ivNull;
4924      if(npwinc == 0)
4925      {
4926        isGB = TRUE;
4927        goto KSTD_Finish;
4928      }
4929      else
4930      {
4931        goto LastGB_Finish;
4932      }
4933    }
4934    idDelete(&H0_tmp);
4935    idDelete(&H1);
4936
4937    target_weight  = MPertVectors(ssG, MivMatrixOrder(orig_target_weight), tp_deg);
4938
4939    rChangeCurrRing(EXXRing);
4940    G = idrMoveR(ssG, TargetRing,currRing);
4941  }
4942
4943  while(1)
4944  {
4945    nwalk ++;
4946    nstep++;
4947    if(nwalk == 1)
4948    {
4949      goto NEXT_STEP;
4950    }
4951    //Print("\n//REC_GB_Mwalk: Entering the %d-th step in the %d-th recursive:\n",nwalk,tp_deg);
4952    to = clock();
4953    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4954    Gomega = MwalkInitialForm(G, curr_weight);
4955    xtif = xtif + clock()-to;
4956
4957#ifndef  BUCHBERGER_ALG
4958    if(isNolVector(curr_weight) == 0)
4959    {
4960      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4961    }
4962    else
4963    {
4964      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4965    }
4966#endif
4967
4968    oldRing = currRing;
4969
4970    // define a new ring with ordering "(a(curr_weight),lp)
4971    if (rParameter(currRing) != NULL)
4972    {
4973      DefRingPar(curr_weight);
4974    }
4975    else
4976    {
4977      rChangeCurrRing(VMrDefault(curr_weight));
4978    }
4979    newRing = currRing;
4980    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4981
4982    to = clock();
4983    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4984#ifdef  BUCHBERGER_ALG
4985    M = MstdhomCC(Gomega1);
4986#else
4987    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4988    delete hilb_func;
4989#endif
4990    xtstd = xtstd + clock() - to;
4991
4992    // change the ring to oldRing
4993    rChangeCurrRing(oldRing);
4994
4995    M1 =  idrMoveR(M, newRing,currRing);
4996    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4997
4998    to = clock();
4999    F = MLifttwoIdeal(Gomega2, M1, G);
5000    xtlift = xtlift + clock() -to;
5001
5002    idDelete(&M1);
5003    idDelete(&Gomega2);
5004    idDelete(&G);
5005
5006
5007    // change the ring to newRing
5008    rChangeCurrRing(newRing);
5009    F1 = idrMoveR(F, oldRing,currRing);
5010
5011    to = clock();
5012    // reduce the Groebner basis <G> w.r.t. new ring
5013    G = kInterRedCC(F1, NULL);
5014    xtred = xtred + clock() -to;
5015
5016    idDelete(&F1);
5017
5018    if(endwalks == 1)
5019    {
5020      break;
5021    }
5022  NEXT_STEP:
5023    to = clock();
5024    // compute a next weight vector
5025    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
5026
5027
5028    xtnw = xtnw + clock() - to;
5029
5030#ifdef PRINT_VECTORS
5031    MivString(curr_weight, target_weight, next_weight);
5032#endif
5033
5034    if(Overflow_Error == TRUE)
5035    {
5036      //PrintS("\n//REC_GB_Mwalk: The computed vector does NOT stay in the correct cone!!\n");
5037      nnwinC = 0;
5038      if(tp_deg == nV)
5039      {
5040        nlast = 1;
5041      }
5042      delete next_weight;
5043      break;
5044    }
5045    if(MivComp(next_weight, ivNull) == 1)
5046    {
5047      newRing = currRing;
5048      delete next_weight;
5049      break;
5050    }
5051
5052    if(MivComp(next_weight, target_weight) == 1)
5053    {
5054      if(tp_deg == nV)
5055      {
5056        endwalks = 1;
5057      }
5058      else
5059      {
5060        G = REC_GB_Mwalk(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
5061        newRing = currRing;
5062        delete next_weight;
5063        break;
5064      }
5065    }
5066
5067    for(i=nV-1; i>=0; i--)
5068    {
5069      (*curr_weight)[i] = (*next_weight)[i];
5070    }
5071    delete next_weight;
5072  }
5073
5074  delete ivNull;
5075
5076  if(tp_deg != nV)
5077  {
5078    newRing = currRing;
5079
5080    if (rParameter(currRing) != NULL)
5081    {
5082      DefRingPar(orig_target_weight);
5083    }
5084    else
5085    {
5086      rChangeCurrRing(VMrDefault(orig_target_weight));
5087    }
5088    F1 = idrMoveR(G, newRing,currRing);
5089
5090    if(nnwinC == 0)
5091    {
5092      F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
5093    }
5094    else
5095    {
5096      if(test_w_in_ConeCC(F1, target_weight) != 1)
5097      {
5098        F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight,tp_deg+1,nnwinC);
5099      }
5100    }
5101    delete target_weight;
5102
5103    TargetRing = currRing;
5104    rChangeCurrRing(EXXRing);
5105    result = idrMoveR(F1, TargetRing,currRing);
5106  }
5107  else
5108  {
5109    if(nlast == 1)
5110    {
5111      if (rParameter(currRing) != NULL)
5112      {
5113        DefRingPar(orig_target_weight);
5114      }
5115      else
5116      {
5117        rChangeCurrRing(VMrDefault(orig_target_weight));
5118      }
5119    KSTD_Finish:
5120      if(isGB == FALSE)
5121      {
5122        F1 = idrMoveR(G, newRing,currRing);
5123      }
5124      else
5125      {
5126        F1 = G;
5127      }
5128      to=clock();
5129      // apply Buchberger alg to compute a red. GB of F1
5130      G = MstdCC(F1);
5131      xtextra=clock()-to;
5132      idDelete(&F1);
5133      newRing = currRing;
5134    }
5135
5136  LastGB_Finish:
5137    rChangeCurrRing(EXXRing);
5138    result = idrMoveR(G, newRing,currRing);
5139  }
5140
5141  if(Overflow_Error == FALSE)
5142    {
5143    Overflow_Error = nError;
5144    }
5145#ifndef BUCHBERGER_ALG
5146  delete last_omega;
5147#endif
5148  return(result);
5149}
5150
5151
5152// THE NEW GROEBNER WALK ALGORITHM
5153// Groebnerwalk with a recursive "second" alternative GW, called REC_GB_Mwalk that only computes the last reduced GB
5154ideal MwalkAlt(ideal Go, intvec* curr_weight, intvec* target_weight)
5155{
5156  Set_Error(FALSE);
5157  Overflow_Error = FALSE;
5158  //Print("// pSetm_Error = (%d)", ErrorCheck());
5159
5160  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5161  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5162  tinput = clock();
5163  clock_t tim;
5164  nstep=0;
5165  int i;
5166  int nV = currRing->N;
5167  int nwalk=0;
5168  int endwalks=0;
5169
5170  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
5171
5172  ring newRing, oldRing;
5173  intvec* ivNull = new intvec(nV);
5174  intvec* exivlp = Mivlp(nV);
5175#ifndef BUCHBERGER_ALG
5176  intvec* hilb_func;
5177#endif
5178  intvec* tmp_weight = new intvec(nV);
5179  for(i=nV-1; i>=0; i--)
5180    (*tmp_weight)[i] = (*curr_weight)[i];
5181
5182   // to avoid (1,0,...,0) as the target vector
5183  intvec* last_omega = new intvec(nV);
5184  for(i=nV-1; i>0; i--)
5185    (*last_omega)[i] = 1;
5186  (*last_omega)[0] = 10000;
5187
5188  ring XXRing = currRing;
5189
5190  to = clock();
5191  // the monomial ordering of this current ring would be "dp"
5192  G = MstdCC(Go);
5193  tostd = clock()-to;
5194
5195  if(currRing->order[0] == ringorder_a)
5196    goto NEXT_VECTOR;
5197
5198  while(1)
5199  {
5200    nwalk ++;
5201    nstep ++;
5202    to = clock();
5203    // compute an initial form ideal of <G> w.r.t. "curr_vector"
5204    Gomega = MwalkInitialForm(G, curr_weight);
5205    tif = tif + clock()-to;
5206    oldRing = currRing;
5207
5208    if(endwalks == 1)
5209    {
5210      /* compute a reduced Groebner basis of Gomega w.r.t. >>_cw by
5211         the recursive changed perturbation walk alg. */
5212      tim = clock();
5213#ifdef CHECK_IDEAL_MWALK
5214        Print("\n// **** Groebnerwalk took %d steps and ", nwalk);
5215        PrintS("\n// **** call the rec. Pert. Walk to compute a red GB of:");
5216        idString(Gomega, "Gomega");
5217#endif
5218
5219      if(MivSame(exivlp, target_weight)==1)
5220        M = REC_GB_Mwalk(idCopy(Gomega), tmp_weight, curr_weight, 2,1);
5221      else
5222        goto NORMAL_GW;
5223#ifdef TIME_TEST
5224        Print("\n//  time for the last std(Gw)  = %.2f sec",
5225        ((double) (clock()-tim)/1000000));
5226#endif
5227/*
5228#ifdef CHECK_IDEAL_MWALK
5229      idElements(Gomega, "G_omega");
5230      headidString(Gomega, "Gw");
5231      idElements(M, "M");
5232      //headidString(M, "M");
5233#endif
5234*/
5235      to = clock();
5236      F = MLifttwoIdeal(Gomega, M, G);
5237      xtlift = xtlift + clock() - to;
5238
5239      idDelete(&Gomega);
5240      idDelete(&M);
5241      idDelete(&G);
5242
5243      oldRing = currRing;
5244
5245      // create a new ring newRing
5246       if (rParameter(currRing) != NULL)
5247       {
5248         DefRingPar(curr_weight);
5249       }
5250       else
5251       {
5252         rChangeCurrRing(VMrDefault(curr_weight));
5253       }
5254      newRing = currRing;
5255      F1 = idrMoveR(F, oldRing,currRing);
5256    }
5257    else
5258    {
5259    NORMAL_GW:
5260#ifndef  BUCHBERGER_ALG
5261      if(isNolVector(curr_weight) == 0)
5262      {
5263        hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5264      }
5265      else
5266      {
5267        hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5268      }
5269#endif // BUCHBERGER_ALG
5270
5271      // define a new ring that its ordering is "(a(curr_weight),lp)
5272      if (rParameter(currRing) != NULL)
5273      {
5274        DefRingPar(curr_weight);
5275      }
5276      else
5277      {
5278        rChangeCurrRing(VMrDefault(curr_weight));
5279      }
5280      newRing = currRing;
5281      Gomega1 = idrMoveR(Gomega, oldRing,currRing);
5282
5283      to = clock();
5284      // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5285#ifdef  BUCHBERGER_ALG
5286      M = MstdhomCC(Gomega1);
5287#else
5288      M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5289      delete hilb_func;
5290#endif
5291      tstd = tstd + clock() - to;
5292
5293      // change the ring to oldRing
5294      rChangeCurrRing(oldRing);
5295      M1 =  idrMoveR(M, newRing,currRing);
5296      Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
5297
5298      to = clock();
5299      // compute a representation of the generators of submod (M) with respect
5300      // to those of mod (Gomega).
5301      // Gomega is a reduced Groebner basis w.r.t. the current ring.
5302      F = MLifttwoIdeal(Gomega2, M1, G);
5303      tlift = tlift + clock() - to;
5304
5305      idDelete(&M1);
5306      idDelete(&Gomega2);
5307      idDelete(&G);
5308
5309      // change the ring to newRing
5310      rChangeCurrRing(newRing);
5311      F1 = idrMoveR(F, oldRing,currRing);
5312    }
5313
5314    to = clock();
5315    // reduce the Groebner basis <G> w.r.t. new ring
5316    G = kInterRedCC(F1, NULL);
5317    if(endwalks != 1)
5318    {
5319      tred = tred + clock() - to;
5320    }
5321    else
5322    {
5323      xtred = xtred + clock() - to;
5324    }
5325    idDelete(&F1);
5326    if(endwalks == 1)
5327    {
5328      break;
5329    }
5330  NEXT_VECTOR:
5331    to = clock();
5332    // compute a next weight vector
5333    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
5334    tnw = tnw + clock() - to;
5335#ifdef PRINT_VECTORS
5336    MivString(curr_weight, target_weight, next_weight);
5337#endif
5338
5339    //if(test_w_in_ConeCC(G, next_weight) != 1)
5340    if(Overflow_Error == TRUE)
5341    {
5342      newRing = currRing;
5343      PrintS("\n// ** The computed vector does NOT stay in Cone!!\n");
5344
5345      if (rParameter(currRing) != NULL)
5346      {
5347        DefRingPar(target_weight);
5348      }
5349      else
5350      {
5351        rChangeCurrRing(VMrDefault(target_weight));
5352      }
5353      F1 = idrMoveR(G, newRing,currRing);
5354      G = MstdCC(F1);
5355      idDelete(&F1);
5356
5357      newRing = currRing;
5358      break;
5359    }
5360
5361    if(MivComp(next_weight, ivNull) == 1)
5362    {
5363      newRing = currRing;
5364      delete next_weight;
5365      break;
5366    }
5367    if(MivComp(next_weight, target_weight) == 1)
5368    {
5369      endwalks = 1;
5370    }
5371    for(i=nV-1; i>=0; i--)
5372    {
5373      (*tmp_weight)[i] = (*curr_weight)[i];
5374      (*curr_weight)[i] = (*next_weight)[i];
5375    }
5376    delete next_weight;
5377  }
5378  rChangeCurrRing(XXRing);
5379  G = idrMoveR(G, newRing,currRing);
5380
5381  delete tmp_weight;
5382  delete ivNull;
5383  delete exivlp;
5384
5385#ifdef TIME_TEST
5386  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5387
5388  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5389  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5390#endif
5391  return(G);
5392}
5393
5394/*******************************
5395 * THE GROEBNER WALK ALGORITHM *
5396 *******************************/
5397ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M,
5398            ring baseRing, int reduction, int printout)
5399{
5400  // save current options
5401  BITSET save1 = si_opt_1;
5402  if(reduction == 0)
5403  {
5404    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5405    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5406  }
5407  Set_Error(FALSE);
5408  Overflow_Error = FALSE;
5409  //BOOLEAN endwalks = FALSE;
5410#ifdef TIME_TEST
5411  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5412  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5413  tinput = clock();
5414  clock_t tim;
5415#endif
5416  nstep=0;
5417  int i,nwalk;
5418  int nV = baseRing->N;
5419
5420  ideal Gomega, M, F, FF, Gomega1, Gomega2, M1;
5421  ring newRing;
5422  ring XXRing = baseRing;
5423  ring targetRing;
5424  intvec* ivNull = new intvec(nV);
5425  intvec* curr_weight = new intvec(nV);
5426  intvec* target_weight = new intvec(nV);
5427  intvec* exivlp = Mivlp(nV);
5428/*
5429  intvec* tmp_weight = new intvec(nV);
5430  for(i=0; i<nV; i++)
5431  {
5432    (*tmp_weight)[i] = (*orig_M)[i];
5433  }
5434*/
5435  for(i=0; i<nV; i++)
5436  {
5437    (*curr_weight)[i] = (*orig_M)[i];
5438    (*target_weight)[i] = (*target_M)[i];
5439  }
5440#ifndef BUCHBERGER_ALG
5441  intvec* hilb_func;
5442   // to avoid (1,0,...,0) as the target vector
5443  intvec* last_omega = new intvec(nV);
5444  for(i=nV-1; i>0; i--)
5445  {
5446    (*last_omega)[i] = 1;
5447  }
5448  (*last_omega)[0] = 10000;
5449#endif
5450  rComplete(currRing);
5451#ifdef CHECK_IDEAL_MWALK
5452  if(printout > 2)
5453  {
5454    idString(Go,"//** Mwalk: Go");
5455  }
5456#endif
5457
5458  if(target_M->length() == nV)
5459  {
5460   // define the target ring
5461    targetRing = VMrDefault(target_weight);
5462  }
5463  else
5464  {
5465    targetRing = VMatrDefault(target_M);
5466  }
5467  if(orig_M->length() == nV)
5468  {
5469    // define a new ring with ordering "(a(curr_weight),lp)
5470    newRing = VMrDefault(curr_weight);
5471  }
5472  else
5473  {
5474    newRing = VMatrDefault(orig_M);
5475  }
5476  rChangeCurrRing(newRing);
5477
5478#ifdef TIME_TEST
5479  to = clock();
5480#endif
5481  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5482#ifdef TIME_TEST
5483  tostd = clock()-to;
5484#endif
5485
5486  baseRing = currRing;
5487  nwalk = 0;
5488
5489  while(1)
5490  {
5491    nwalk ++;
5492    nstep ++;
5493    //compute an initial form ideal of <G> w.r.t. "curr_vector"
5494#ifdef TIME_TEST
5495    to = clock();
5496#endif
5497    Gomega = MwalkInitialForm(G, curr_weight);
5498#ifdef TIME_TEST
5499    tif = tif + clock()-to;
5500#endif
5501
5502#ifdef CHECK_IDEAL_MWALK
5503    if(printout > 1)
5504    {
5505      idString(Gomega,"//** Mwalk: Gomega");
5506    }
5507#endif
5508
5509    if(reduction == 0)
5510    {
5511      FF = middleOfCone(G,Gomega);
5512      if(FF != NULL)
5513      {
5514      PrintS("middle of Cone");
5515        idDelete(&G);
5516        G = idCopy(FF);
5517        idDelete(&FF);
5518        goto NEXT_VECTOR;
5519      } 
5520    }
5521
5522#ifndef  BUCHBERGER_ALG
5523    if(isNolVector(curr_weight) == 0)
5524    {
5525      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5526    }   
5527    else
5528    {
5529      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5530    }
5531#endif
5532
5533    if(nwalk == 1)
5534    {
5535      if(orig_M->length() == nV)
5536      {
5537        // define a new ring with ordering "(a(curr_weight),lp)
5538        newRing = VMrDefault(curr_weight);
5539      }
5540      else
5541      {
5542        newRing = VMatrDefault(orig_M);
5543      }
5544    }
5545    else
5546    {
5547     if(target_M->length() == nV)
5548     {
5549       //define a new ring with ordering "(a(curr_weight),lp)"
5550       newRing = VMrDefault(curr_weight);
5551     }
5552     else
5553     {
5554       //define a new ring with matrix ordering
5555       newRing = VMatrRefine(target_M,curr_weight);
5556     }
5557    }
5558    rChangeCurrRing(newRing);
5559    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5560    idDelete(&Gomega);
5561    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5562#ifdef TIME_TEST
5563    to = clock();
5564#endif
5565#ifndef  BUCHBERGER_ALG
5566    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5567    delete hilb_func;
5568#else
5569    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5570#endif
5571#ifdef TIME_TEST
5572    tstd = tstd + clock() - to;
5573#endif
5574    idSkipZeroes(M);
5575#ifdef CHECK_IDEAL_MWALK
5576    if(printout > 2)
5577    {
5578      idString(M, "//** Mwalk: M");
5579    }
5580#endif
5581    //change the ring to baseRing
5582    rChangeCurrRing(baseRing);
5583    M1 =  idrMoveR(M, newRing,currRing);
5584    idDelete(&M);
5585    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5586    idDelete(&Gomega1);
5587#ifdef TIME_TEST
5588    to = clock();
5589#endif
5590    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5591    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5592    F = MLifttwoIdeal(Gomega2, M1, G);
5593#ifdef TIME_TEST
5594    tlift = tlift + clock() - to;
5595#endif
5596#ifdef CHECK_IDEAL_MWALK
5597    if(printout > 2)
5598    {
5599      idString(F, "//** Mwalk: F");
5600    }
5601#endif
5602    idDelete(&Gomega2);
5603    idDelete(&M1);
5604
5605    rChangeCurrRing(newRing); // change the ring to newRing
5606    G = idrMoveR(F,baseRing,currRing);
5607    idDelete(&F);
5608    idSkipZeroes(G);
5609
5610#ifdef CHECK_IDEAL_MWALK
5611    if(printout > 2)
5612    {
5613      idString(G, "//** Mwalk: G");
5614    }
5615#endif
5616
5617    rChangeCurrRing(targetRing);
5618    G = idrMoveR(G,newRing,currRing);
5619    // test whether target cone is reached
5620    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5621    {
5622      baseRing = currRing;
5623      break;
5624      //endwalks = TRUE;
5625    }
5626
5627    rChangeCurrRing(newRing);
5628    G = idrMoveR(G,targetRing,currRing);
5629    baseRing = currRing;
5630
5631    NEXT_VECTOR:
5632#ifdef TIME_TEST
5633    to = clock();
5634#endif
5635    intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5636#ifdef TIME_TEST
5637    tnw = tnw + clock() - to;
5638#endif
5639#ifdef PRINT_VECTORS
5640    if(printout > 0)
5641    {
5642      MivString(curr_weight, target_weight, next_weight);
5643    }
5644#endif
5645    if(reduction ==0)
5646    {
5647      if(MivComp(curr_weight,next_weight)==1)
5648      {
5649        break;
5650      }
5651    }
5652    if(MivComp(target_weight,curr_weight) == 1)
5653    {
5654      break;
5655    }
5656
5657    for(i=nV-1; i>=0; i--)
5658    {
5659      //(*tmp_weight)[i] = (*curr_weight)[i];
5660      (*curr_weight)[i] = (*next_weight)[i];
5661    }
5662    delete next_weight;
5663  }
5664  rChangeCurrRing(XXRing);
5665  ideal result = idrMoveR(G,baseRing,currRing);
5666  idDelete(&Go);
5667  idDelete(&G);
5668  //delete tmp_weight;
5669  delete ivNull;
5670  delete exivlp;
5671#ifndef BUCHBERGER_ALG
5672  delete last_omega;
5673#endif
5674#ifdef TIME_TEST
5675  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5676  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5677  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5678#endif
5679  Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
5680  si_opt_1 = save1; //set original options
5681  return(result);
5682}
5683
5684// THE RANDOM WALK ALGORITHM
5685ideal Mrwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad, int pert_deg,
5686             int reduction, int printout)
5687{
5688  BITSET save1 = si_opt_1; // save current options
5689  if(reduction == 0)
5690  {
5691    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5692    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5693  }
5694
5695  Set_Error(FALSE);
5696  Overflow_Error = FALSE;
5697  BOOLEAN endwalks = FALSE;
5698#ifdef TIME_TEST
5699  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5700  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5701  tinput = clock();
5702  clock_t tim;
5703#endif
5704  nstep=0;
5705  int i,nwalk;//polylength;
5706  int nV = currRing->N;
5707
5708  //check that weight radius is valid
5709  if(weight_rad < 0)
5710  {
5711    Werror("Invalid radius.\n");
5712    return NULL;
5713  }
5714
5715  //check that perturbation degree is valid
5716  if(pert_deg > nV || pert_deg < 1)
5717  {
5718    Werror("Invalid perturbation degree.\n");
5719    return NULL;
5720  }
5721
5722  ideal Gomega, M, F,FF, Gomega1, Gomega2, M1;
5723  ring newRing;
5724  ring targetRing;
5725  ring baseRing = currRing;
5726  ring XXRing = currRing;
5727  intvec* iv_M;
5728  intvec* ivNull = new intvec(nV);
5729  intvec* curr_weight = new intvec(nV);
5730  intvec* target_weight = new intvec(nV);
5731  intvec* next_weight= new intvec(nV);
5732
5733  for(i=0; i<nV; i++)
5734  {
5735    (*curr_weight)[i] = (*orig_M)[i];
5736    (*target_weight)[i] = (*target_M)[i];
5737  }
5738
5739#ifndef BUCHBERGER_ALG
5740  intvec* hilb_func;
5741   // to avoid (1,0,...,0) as the target vector
5742  intvec* last_omega = new intvec(nV);
5743  for(i=nV-1; i>0; i--)
5744  {
5745    (*last_omega)[i] = 1;
5746  }
5747  (*last_omega)[0] = 10000;
5748#endif
5749  rComplete(currRing);
5750
5751  if(target_M->length() == nV)
5752  {
5753    targetRing = VMrDefault(target_weight); // define the target ring
5754  }
5755  else
5756  {
5757    targetRing = VMatrDefault(target_M);
5758  }
5759  if(orig_M->length() == nV)
5760  {
5761    newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5762  }
5763  else
5764  {
5765    newRing = VMatrDefault(orig_M);
5766  }
5767  rChangeCurrRing(newRing);
5768#ifdef TIME_TEST
5769  to = clock();
5770#endif
5771  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5772#ifdef TIME_TEST
5773  tostd = clock()-to;
5774#endif
5775  baseRing = currRing;
5776  nwalk = 0;
5777
5778#ifdef TIME_TEST
5779  to = clock();
5780#endif
5781  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5782#ifdef TIME_TEST
5783  tif = tif + clock()-to; //time for computing initial form ideal
5784#endif
5785
5786  while(1)
5787  {
5788    nwalk ++;
5789    nstep ++;
5790#ifdef CHECK_IDEAL_MWALK
5791    if(printout > 1)
5792    {
5793      idString(Gomega,"//** Mrwalk: Gomega");
5794    }
5795#endif
5796    if(reduction == 0)
5797    {
5798      FF = middleOfCone(G,Gomega);
5799      if(FF != NULL)
5800      {
5801        idDelete(&G);
5802        G = idCopy(FF);
5803        idDelete(&FF);
5804        goto NEXT_VECTOR;
5805      } 
5806    }
5807#ifndef  BUCHBERGER_ALG
5808    if(isNolVector(curr_weight) == 0)
5809    {
5810      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5811    }   
5812    else
5813    {
5814      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5815    }
5816#endif
5817    if(nwalk == 1)
5818    {
5819      if(orig_M->length() == nV)
5820      {
5821        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5822      }
5823      else
5824      {
5825        newRing = VMatrDefault(orig_M);
5826      }
5827    }
5828    else
5829    {
5830     if(target_M->length() == nV)
5831     {
5832       newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5833     }
5834     else
5835     {
5836       newRing = VMatrRefine(target_M,curr_weight);
5837     }
5838    }
5839    rChangeCurrRing(newRing);
5840    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5841    idDelete(&Gomega);
5842    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5843#ifdef TIME_TEST
5844    to = clock();
5845#endif
5846#ifndef BUCHBERGER_ALG
5847    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5848    delete hilb_func;
5849#else
5850    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5851#endif
5852#ifdef TIME_TEST
5853    tstd = tstd + clock() - to;
5854#endif
5855    idSkipZeroes(M);
5856#ifdef CHECK_IDEAL_MWALK
5857    if(printout > 2)
5858    {
5859      idString(M, "//** Mrwalk: M");
5860    }
5861#endif
5862    //change the ring to baseRing
5863    rChangeCurrRing(baseRing);
5864    M1 =  idrMoveR(M, newRing,currRing);
5865    idDelete(&M);
5866    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5867    idDelete(&Gomega1);
5868#ifdef TIME_TEST
5869    to = clock();
5870#endif
5871    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5872    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5873    F = MLifttwoIdeal(Gomega2, M1, G);
5874#ifdef TIME_TEST
5875    tlift = tlift + clock() - to;
5876#endif
5877#ifdef CHECK_IDEAL_MWALK
5878    if(printout > 2)
5879    {
5880      idString(F,"//** Mrwalk: F");
5881    }
5882#endif
5883    idDelete(&Gomega2);
5884    idDelete(&M1);
5885    rChangeCurrRing(newRing); // change the ring to newRing
5886    G = idrMoveR(F,baseRing,currRing);
5887    idDelete(&F);
5888    baseRing = currRing;
5889#ifdef TIME_TEST
5890    to = clock();
5891    tstd = tstd + clock() - to;
5892#endif
5893    idSkipZeroes(G);
5894#ifdef CHECK_IDEAL_MWALK
5895    if(printout > 2)
5896    {
5897      idString(G,"//** Mrwalk: G");
5898    }
5899#endif
5900
5901    rChangeCurrRing(targetRing);
5902    G = idrMoveR(G,newRing,currRing);
5903
5904    // test whether target cone is reached
5905    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5906    {
5907      baseRing = currRing;
5908      break;
5909    }
5910
5911    rChangeCurrRing(newRing);
5912    G = idrMoveR(G,targetRing,currRing);
5913    baseRing = currRing;
5914
5915    NEXT_VECTOR:
5916#ifdef TIME_TEST
5917    to = clock();
5918#endif
5919    next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5920#ifdef TIME_TEST
5921    tnw = tnw + clock() - to;
5922#endif
5923
5924#ifdef TIME_TEST
5925    to = clock();
5926#endif
5927    Gomega = MwalkInitialForm(G, next_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5928#ifdef TIME_TEST
5929    tif = tif + clock()-to; //time for computing initial form ideal
5930#endif
5931
5932    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
5933    //polylength = lengthpoly(Gomega);
5934    if(lengthpoly(Gomega) > 0)
5935    {
5936      //there is a polynomial in Gomega with at least 3 monomials,
5937      //low-dimensional facet of the cone
5938      delete next_weight;
5939      if(target_M->length() == nV)
5940      {
5941        iv_M = MivMatrixOrder(curr_weight);
5942      }
5943      else
5944      {
5945        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
5946      }
5947#ifdef TIME_TEST
5948      to = clock();
5949#endif
5950      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, pert_deg);
5951#ifdef TIME_TEST
5952      tnw = tnw + clock() - to;
5953#endif
5954      idDelete(&Gomega);
5955#ifdef TIME_TEST
5956      to = clock();
5957#endif
5958      Gomega = MwalkInitialForm(G, next_weight);
5959#ifdef TIME_TEST
5960      tif = tif + clock()-to; //time for computing initial form ideal
5961#endif
5962      delete iv_M;
5963    }
5964
5965    // test whether target weight vector is reached
5966    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)
5967    {
5968      baseRing = currRing;
5969      delete next_weight;
5970      break;
5971    }
5972    if(reduction ==0)
5973    {
5974      if(MivComp(curr_weight,next_weight)==1)
5975      {
5976        break;
5977      }
5978    }
5979#ifdef PRINT_VECTORS
5980    if(printout > 0)
5981    {
5982      MivString(curr_weight, target_weight, next_weight);
5983    }
5984#endif
5985
5986    for(i=nV-1; i>=0; i--)
5987    {
5988      (*curr_weight)[i] = (*next_weight)[i];
5989    }
5990    delete next_weight;
5991  }
5992  baseRing = currRing;
5993  rChangeCurrRing(XXRing);
5994  ideal result = idrMoveR(G,baseRing,currRing);
5995  idDelete(&G);
5996  delete ivNull;
5997#ifndef BUCHBERGER_ALG
5998  delete last_omega;
5999#endif
6000  Print("\n//** Mrwalk: Groebner Walk took %d steps.\n", nstep);
6001#ifdef TIME_TEST
6002  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
6003  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6004  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
6005#endif
6006  si_opt_1 = save1; //set original options
6007  return(result);
6008}
6009
6010/**************************************************************/
6011/*     Implementation of the perturbation walk algorithm      */
6012/**************************************************************/
6013/* If the perturbed target weight vector or an intermediate weight vector
6014   doesn't stay in the correct Groebner cone, we have only
6015   a reduced Groebner basis for the given ideal with respect to
6016   a monomial order which differs to the given order.
6017   Then we have to compute the wanted  reduced Groebner basis for it.
6018   For this, we can use
6019   1) the improved Buchberger algorithm or
6020   2) the changed perturbation walk algorithm with a decreased degree.
6021*/
6022// if nP = 0 use kStd, else call LastGB
6023ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,
6024             intvec* target_weight, int nP, int reduction, int printout)
6025{
6026  BITSET save1 = si_opt_1; // save current options
6027  if(reduction == 0)
6028  {
6029    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6030    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6031  }
6032  Set_Error(FALSE  );
6033  Overflow_Error = FALSE;
6034  //Print("// pSetm_Error = (%d)", ErrorCheck());
6035#ifdef TIME_TEST
6036  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6037  xtextra=0;
6038  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6039  tinput = clock();
6040
6041  clock_t tim;
6042#endif
6043  nstep = 0;
6044  int i, ntwC=1, ntestw=1,  nV = currRing->N;
6045
6046  //check that perturbation degree is valid
6047  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6048  {
6049    Werror("Invalid perturbation degree.\n");
6050    return NULL;
6051  }
6052
6053  BOOLEAN endwalks = FALSE;
6054  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6055  ring newRing, oldRing, TargetRing;
6056  intvec* iv_M_dp;
6057  intvec* iv_M_lp;
6058  intvec* exivlp = Mivlp(nV);
6059  intvec* orig_target = target_weight;
6060  intvec* pert_target_vector = target_weight;
6061  intvec* ivNull = new intvec(nV);
6062  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6063#ifndef BUCHBERGER_ALG
6064  intvec* hilb_func;
6065#endif
6066  intvec* next_weight;
6067
6068  // to avoid (1,0,...,0) as the target vector
6069  intvec* last_omega = new intvec(nV);
6070  for(i=nV-1; i>0; i--)
6071    (*last_omega)[i] = 1;
6072  (*last_omega)[0] = 10000;
6073
6074  ring XXRing = currRing;
6075#ifdef TIME_TEST
6076  to = clock();
6077#endif
6078  // perturbs the original vector
6079  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6080  {
6081    G = MstdCC(Go);
6082#ifdef TIME_TEST
6083    tostd = clock()-to;
6084#endif
6085    if(op_deg != 1){
6086      iv_M_dp = MivMatrixOrderdp(nV);
6087      //ivString(iv_M_dp, "iv_M_dp");
6088      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6089    }
6090  }
6091  else
6092  {
6093    //define ring order := (a(curr_weight),lp);
6094    if (rParameter(currRing) != NULL)
6095      DefRingPar(curr_weight);
6096    else
6097      rChangeCurrRing(VMrDefault(curr_weight));
6098
6099    G = idrMoveR(Go, XXRing,currRing);
6100    G = MstdCC(G);
6101#ifdef TIME_TEST
6102    tostd = clock()-to;
6103#endif
6104    if(op_deg != 1){
6105      iv_M_dp = MivMatrixOrder(curr_weight);
6106      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6107    }
6108  }
6109  delete iv_dp;
6110  if(op_deg != 1) delete iv_M_dp;
6111
6112  ring HelpRing = currRing;
6113
6114  // perturbs the target weight vector
6115  if(tp_deg > 1 && tp_deg <= nV)
6116  {
6117    if (rParameter(currRing) != NULL)
6118      DefRingPar(target_weight);
6119    else
6120      rChangeCurrRing(VMrDefault(target_weight));
6121
6122    TargetRing = currRing;
6123    ssG = idrMoveR(G,HelpRing,currRing);
6124    if(MivSame(target_weight, exivlp) == 1)
6125    {
6126      iv_M_lp = MivMatrixOrderlp(nV);
6127      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6128    }
6129    else
6130    {
6131      iv_M_lp = MivMatrixOrder(target_weight);
6132      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6133    }
6134    delete iv_M_lp;
6135    pert_target_vector = target_weight;
6136    rChangeCurrRing(HelpRing);
6137    G = idrMoveR(ssG, TargetRing,currRing);
6138  }
6139  if(printout > 0)
6140  {
6141    Print("\n//** Mpwalk: Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6142#ifdef PRINT_VECTORS
6143    ivString(curr_weight, "//** Mpwalk: new current weight");
6144    ivString(target_weight, "//** Mpwalk: new target weight");
6145#endif
6146  }
6147  while(1)
6148  {
6149    nstep ++;
6150#ifdef TIME_TEST
6151    to = clock();
6152#endif
6153    // compute an initial form ideal of <G> w.r.t. the weight vector
6154    // "curr_weight"
6155    Gomega = MwalkInitialForm(G, curr_weight);
6156#ifdef TIME_TEST
6157    tif = tif + clock()-to;
6158#endif
6159#ifdef CHECK_IDEAL_MWALK
6160    if(printout > 1)
6161    {
6162      idString(Gomega,"//** Mpwalk: Gomega");
6163    }
6164#endif
6165    if(reduction == 0 && nstep > 1)
6166    {
6167/*
6168      // check whether weight vector is in the interior of the cone
6169      while(1)
6170      {
6171        FF = middleOfCone(G,Gomega);
6172        if(FF != NULL)
6173        {
6174          idDelete(&G);
6175          G = idCopy(FF);
6176          idDelete(&FF);
6177          next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
6178#ifdef PRINT_VECTORS
6179          if(printout > 0)
6180          {
6181            MivString(curr_weight, target_weight, next_weight);
6182          }
6183#endif
6184        }
6185        else
6186        {
6187          break;
6188        }
6189        for(i=nV-1; i>=0; i--)
6190        {
6191          (*curr_weight)[i] = (*next_weight)[i];
6192        }
6193        Gomega = MwalkInitialForm(G, curr_weight);
6194#ifdef CHECK_IDEAL_MWALK
6195        if(printout > 1)
6196        {
6197          idString(Gomega,"//** Mpwalk: Gomega");
6198        }
6199#endif
6200      }
6201*/
6202      FF = middleOfCone(G,Gomega);
6203      if(FF != NULL)
6204      {
6205        idDelete(&G);
6206        G = idCopy(FF);
6207        idDelete(&FF); 
6208        goto NEXT_VECTOR;
6209      }
6210    }
6211
6212#ifdef ENDWALKS
6213    if(endwalks == TRUE)
6214    {
6215      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6216/*
6217      idElements(G, "G");
6218      headidString(G, "G");
6219*/
6220    }
6221#endif
6222
6223#ifndef  BUCHBERGER_ALG
6224    if(isNolVector(curr_weight) == 0)
6225      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6226    else
6227      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6228#endif // BUCHBERGER_ALG
6229
6230    oldRing = currRing;
6231
6232    // define a new ring with ordering "(a(curr_weight),lp)
6233    if (rParameter(currRing) != NULL)
6234      DefRingPar(curr_weight);
6235    else
6236      rChangeCurrRing(VMrDefault(curr_weight));
6237
6238    newRing = currRing;
6239    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6240
6241#ifdef ENDWALKS
6242    if(endwalks==TRUE)
6243    {
6244      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6245/*
6246      idElements(Gomega1, "Gw");
6247      headidString(Gomega1, "headGw");
6248*/
6249      PrintS("\n// compute a rGB of Gw:\n");
6250#ifndef  BUCHBERGER_ALG
6251      ivString(hilb_func, "w");
6252#endif
6253    }
6254#endif
6255#ifdef TIME_TEST
6256    tim = clock();
6257    to = clock();
6258#endif
6259    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6260#ifdef  BUCHBERGER_ALG
6261    M = MstdhomCC(Gomega1);
6262#else
6263    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6264    delete hilb_func;
6265#endif
6266
6267    if(endwalks == TRUE)
6268    {
6269#ifdef TIME_TEST
6270      xtstd = xtstd+clock()-to;
6271#endif
6272#ifdef ENDWALKS
6273      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6274            ((double) clock())/1000000 -((double)tim) /1000000);
6275#endif
6276    }
6277    else
6278    {
6279#ifdef TIME_TEST
6280      tstd=tstd+clock()-to;
6281#endif
6282    }
6283#ifdef CHECK_IDEAL_MWALK
6284    if(printout > 2)
6285    {
6286      idString(M,"//** Mpwalk: M");
6287    }
6288#endif
6289    // change the ring to oldRing
6290    rChangeCurrRing(oldRing);
6291    M1 =  idrMoveR(M, newRing,currRing);
6292    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6293#ifdef TIME_TEST
6294    to=clock();
6295#endif
6296    /* compute a representation of the generators of submod (M)
6297       with respect to those of mod (Gomega).
6298       Gomega is a reduced Groebner basis w.r.t. the current ring */
6299    F = MLifttwoIdeal(Gomega2, M1, G);
6300#ifdef TIME_TEST
6301    if(endwalks == FALSE)
6302      tlift = tlift+clock()-to;
6303    else
6304      xtlift=clock()-to;
6305#endif
6306#ifdef CHECK_IDEAL_MWALK
6307    if(printout > 2)
6308    {
6309      idString(F,"//** Mpwalk: F");
6310    }
6311#endif
6312
6313    idDelete(&M1);
6314    idDelete(&Gomega2);
6315    idDelete(&G);
6316
6317    // change the ring to newRing
6318    rChangeCurrRing(newRing);
6319    if(reduction == 0)
6320    {
6321      G = idrMoveR(F,oldRing,currRing);
6322    }
6323    else
6324    {
6325      F1 = idrMoveR(F, oldRing,currRing);
6326      if(printout > 2)
6327      {
6328        PrintS("\n //** Mpwalk: reduce the Groebner basis.\n");
6329      }
6330#ifdef TIME_TEST
6331      to=clock();
6332#endif
6333      G = kInterRedCC(F1, NULL);
6334#ifdef TIME_TEST
6335      if(endwalks == FALSE)
6336        tred = tred+clock()-to;
6337      else
6338        xtred=clock()-to;
6339#endif
6340      idDelete(&F1);
6341    }
6342    if(endwalks == TRUE)
6343      break;
6344
6345    NEXT_VECTOR:
6346#ifdef TIME_TEST
6347    to=clock();
6348#endif
6349    // compute a next weight vector
6350    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6351#ifdef TIME_TEST
6352    tnw=tnw+clock()-to;
6353#endif
6354#ifdef PRINT_VECTORS
6355    if(printout > 0)
6356    {
6357      MivString(curr_weight, target_weight, next_weight);
6358    }
6359#endif
6360
6361    if(Overflow_Error == TRUE)
6362    {
6363      ntwC = 0;
6364      //ntestomega = 1;
6365      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6366      //idElements(G, "G");
6367      delete next_weight;
6368      goto FINISH_160302;
6369    }
6370    if(MivComp(next_weight, ivNull) == 1){
6371      newRing = currRing;
6372      delete next_weight;
6373      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6374      break;
6375    }
6376    if(MivComp(next_weight, target_weight) == 1)
6377      endwalks = TRUE;
6378
6379    for(i=nV-1; i>=0; i--)
6380      (*curr_weight)[i] = (*next_weight)[i];
6381
6382    delete next_weight;
6383  }//end of while-loop
6384
6385  if(tp_deg != 1)
6386  {
6387  FINISH_160302:
6388    if(MivSame(orig_target, exivlp) == 1)
6389      if (rParameter(currRing) != NULL)
6390        DefRingParlp();
6391      else
6392        VMrDefaultlp();
6393    else
6394      if (rParameter(currRing) != NULL)
6395        DefRingPar(orig_target);
6396      else
6397        rChangeCurrRing(VMrDefault(orig_target));
6398
6399    TargetRing=currRing;
6400    F1 = idrMoveR(G, newRing,currRing);
6401/*
6402#ifdef CHECK_IDEAL_MWALK
6403      headidString(G, "G");
6404#endif
6405*/
6406
6407    // check whether the pertubed target vector stays in the correct cone
6408    if(ntwC != 0){
6409      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6410    }
6411
6412    if( ntestw != 1 || ntwC == 0)
6413    {
6414      if(ntestw != 1 && printout >2)
6415      {
6416        ivString(pert_target_vector, "tau");
6417        PrintS("\n// ** perturbed target vector doesn't stay in cone!!");
6418        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6419        //idElements(F1, "G");
6420      }
6421      // LastGB is "better" than the kStd subroutine
6422      to=clock();
6423      ideal eF1;
6424      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1){
6425        // PrintS("\n// ** calls \"std\" to compute a GB");
6426        eF1 = MstdCC(F1);
6427        idDelete(&F1);
6428      }
6429      else {
6430        // PrintS("\n// ** calls \"LastGB\" to compute a GB");
6431        rChangeCurrRing(newRing);
6432        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6433        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6434        F2=NULL;
6435      }
6436      xtextra=clock()-to;
6437      ring exTargetRing = currRing;
6438
6439      rChangeCurrRing(XXRing);
6440      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6441    }
6442    else{
6443      rChangeCurrRing(XXRing);
6444      Eresult = idrMoveR(F1, TargetRing,currRing);
6445    }
6446  }
6447  else {
6448    rChangeCurrRing(XXRing);
6449    Eresult = idrMoveR(G, newRing,currRing);
6450  }
6451  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6452  delete ivNull;
6453  if(tp_deg != 1)
6454    delete target_weight;
6455
6456  if(op_deg != 1 )
6457    delete curr_weight;
6458
6459  delete exivlp;
6460  delete last_omega;
6461
6462#ifdef TIME_TEST
6463  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6464             tnw+xtnw);
6465
6466  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6467  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6468#endif
6469  Print("\n//** Mpwalk: Perturbation Walk took %d steps.\n", nstep);
6470  return(Eresult);
6471}
6472
6473/*******************************************************
6474 * THE PERTURBATION WALK ALGORITHM WITH RANDOM ELEMENT *
6475 *******************************************************/
6476ideal Mprwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad,
6477              int op_deg, int tp_deg, int nP, int reduction, int printout)
6478{
6479  BITSET save1 = si_opt_1; // save current options
6480  if(reduction == 0)
6481  {
6482    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6483    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6484  }
6485  Set_Error(FALSE);
6486  Overflow_Error = FALSE;
6487  //Print("// pSetm_Error = (%d)", ErrorCheck());
6488#ifdef TIME_TEST
6489  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6490  xtextra=0;
6491  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6492  tinput = clock();
6493
6494  clock_t tim;
6495#endif
6496  nstep = 0;
6497  int i, ntwC=1, ntestw=1, nV = currRing->N; //polylength
6498
6499  //check that weight radius is valid
6500  if(weight_rad < 0)
6501  {
6502    Werror("Invalid radius.\n");
6503    return NULL;
6504  }
6505
6506  //check that perturbation degree is valid
6507  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6508  {
6509    Werror("Invalid perturbation degree.\n");
6510    return NULL;
6511  }
6512
6513  BOOLEAN endwalks = FALSE;
6514
6515  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6516  ring newRing, oldRing, TargetRing;
6517  intvec* iv_M;
6518  intvec* iv_M_dp;
6519  intvec* iv_M_lp;
6520  intvec* exivlp = Mivlp(nV);
6521  intvec* curr_weight = new intvec(nV);
6522  intvec* target_weight = new intvec(nV);
6523  for(i=0; i<nV; i++)
6524  {
6525    (*curr_weight)[i] = (*orig_M)[i];
6526    (*target_weight)[i] = (*target_M)[i];
6527  }
6528  intvec* orig_target = target_weight;
6529  intvec* pert_target_vector = target_weight;
6530  intvec* ivNull = new intvec(nV);
6531  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6532#ifndef BUCHBERGER_ALG
6533  intvec* hilb_func;
6534#endif
6535  intvec* next_weight;
6536
6537  // to avoid (1,0,...,0) as the target vector
6538  intvec* last_omega = new intvec(nV);
6539  for(i=nV-1; i>0; i--)
6540    (*last_omega)[i] = 1;
6541  (*last_omega)[0] = 10000;
6542
6543  ring XXRing = currRing;
6544
6545  // perturbs the original vector
6546  if(orig_M->length() == nV)
6547  {
6548    if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6549    {
6550#ifdef TIME_TEST
6551  to = clock();
6552#endif
6553      G = MstdCC(Go);
6554#ifdef TIME_TEST
6555      tostd = clock()-to;
6556#endif
6557      if(op_deg != 1)
6558      {
6559        iv_M_dp = MivMatrixOrderdp(nV);
6560        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6561      }
6562    }
6563    else
6564    {
6565      //define ring order := (a(curr_weight),lp);
6566      if (rParameter(currRing) != NULL)
6567        DefRingPar(curr_weight);
6568      else
6569        rChangeCurrRing(VMrDefault(curr_weight));
6570
6571      G = idrMoveR(Go, XXRing,currRing);
6572#ifdef TIME_TEST
6573  to = clock();
6574#endif
6575      G = MstdCC(G);
6576#ifdef TIME_TEST
6577      tostd = clock()-to;
6578#endif
6579      if(op_deg != 1)
6580      {
6581        iv_M_dp = MivMatrixOrder(curr_weight);
6582        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6583      }
6584    }
6585  }
6586  else
6587  {
6588    rChangeCurrRing(VMatrDefault(orig_M));
6589    G = idrMoveR(Go, XXRing,currRing);
6590#ifdef TIME_TEST
6591    to = clock();
6592#endif
6593    G = MstdCC(G);
6594#ifdef TIME_TEST
6595    tostd = clock()-to;
6596#endif
6597    if(op_deg != 1)
6598    {
6599      curr_weight = MPertVectors(G, orig_M, op_deg);
6600    }
6601  }
6602
6603  delete iv_dp;
6604  if(op_deg != 1) delete iv_M_dp;
6605
6606  ring HelpRing = currRing;
6607
6608  // perturbs the target weight vector
6609  if(target_M->length() == nV)
6610  {
6611    if(tp_deg > 1 && tp_deg <= nV)
6612    {
6613      if (rParameter(currRing) != NULL)
6614        DefRingPar(target_weight);
6615      else
6616        rChangeCurrRing(VMrDefault(target_weight));
6617
6618      TargetRing = currRing;
6619      ssG = idrMoveR(G,HelpRing,currRing);
6620      if(MivSame(target_weight, exivlp) == 1)
6621      {
6622        iv_M_lp = MivMatrixOrderlp(nV);
6623        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6624      }
6625      else
6626      {
6627        iv_M_lp = MivMatrixOrder(target_weight);
6628        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6629      }
6630      delete iv_M_lp;
6631      pert_target_vector = target_weight;
6632      rChangeCurrRing(HelpRing);
6633      G = idrMoveR(ssG, TargetRing,currRing);
6634    }
6635  }
6636  else
6637  {
6638    if(tp_deg > 1 && tp_deg <= nV)
6639    {
6640      rChangeCurrRing(VMatrDefault(target_M));
6641      TargetRing = currRing;
6642      ssG = idrMoveR(G,HelpRing,currRing);
6643      target_weight = MPertVectors(ssG, target_M, tp_deg);
6644    }
6645  }
6646  if(printout > 0)
6647  {
6648    Print("\n//** Mprwalk: Random Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6649    ivString(curr_weight, "//** Mprwalk: new current weight");
6650    ivString(target_weight, "//** Mprwalk: new target weight");
6651  }
6652
6653#ifdef TIME_TEST
6654  to = clock();
6655#endif
6656  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
6657#ifdef TIME_TEST
6658  tif = tif + clock()-to; //time for computing initial form ideal
6659#endif
6660
6661  while(1)
6662  {
6663    nstep ++;
6664#ifdef CHECK_IDEAL_MWALK
6665    if(printout > 1)
6666    {
6667      idString(Gomega,"//** Mprwalk: Gomega");
6668    }
6669#endif
6670
6671    if(reduction == 0 && nstep > 1)
6672    {
6673/*
6674      // check whether weight vector is in the interior of the cone
6675      while(1)
6676      {
6677        FF = middleOfCone(G,Gomega);
6678        if(FF != NULL)
6679        {
6680          idDelete(&G);
6681          G = idCopy(FF);
6682          idDelete(&FF);
6683          next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
6684#ifdef PRINT_VECTORS
6685          if(printout > 0)
6686          {
6687            MivString(curr_weight, target_weight, next_weight);
6688          }
6689#endif
6690        }
6691        else
6692        {
6693          break;
6694        }
6695        for(i=nV-1; i>=0; i--)
6696        {
6697          (*curr_weight)[i] = (*next_weight)[i];
6698        }
6699        Gomega = MwalkInitialForm(G, curr_weight);
6700#ifdef CHECK_IDEAL_MWALK
6701        if(printout > 1)
6702        {
6703          idString(Gomega,"//** Mprwalk: Gomega");
6704        }
6705#endif
6706      }
6707*/
6708      FF = middleOfCone(G,Gomega);
6709      if(FF != NULL)
6710      {
6711        idDelete(&G);
6712        G = idCopy(FF);
6713        idDelete(&FF); 
6714        goto NEXT_VECTOR;
6715      } 
6716    }
6717
6718#ifdef ENDWALKS
6719    if(endwalks == TRUE)
6720    {
6721      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6722/*
6723      idElements(G, "G");
6724      headidString(G, "G");
6725*/
6726    }
6727#endif
6728
6729#ifndef  BUCHBERGER_ALG
6730    if(isNolVector(curr_weight) == 0)
6731      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6732    else
6733      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6734#endif // BUCHBERGER_ALG
6735
6736    oldRing = currRing;
6737
6738    if(target_M->length() == nV)
6739    {
6740      // define a new ring with ordering "(a(curr_weight),lp)
6741      if (rParameter(currRing) != NULL)
6742        DefRingPar(curr_weight);
6743      else
6744        rChangeCurrRing(VMrDefault(curr_weight));
6745    }
6746    else
6747    {
6748      rChangeCurrRing(VMatrRefine(target_M,curr_weight));
6749    }
6750    newRing = currRing;
6751    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6752#ifdef ENDWALKS
6753    if(endwalks == TRUE)
6754    {
6755      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6756/*
6757      idElements(Gomega1, "Gw");
6758      headidString(Gomega1, "headGw");
6759*/
6760      PrintS("\n// compute a rGB of Gw:\n");
6761
6762#ifndef  BUCHBERGER_ALG
6763      ivString(hilb_func, "w");
6764#endif
6765    }
6766#endif
6767#ifdef TIME_TEST
6768    tim = clock();
6769    to = clock();
6770#endif
6771    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6772#ifdef  BUCHBERGER_ALG
6773    M = MstdhomCC(Gomega1);
6774#else
6775    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6776    delete hilb_func;
6777#endif
6778#ifdef CHECK_IDEAL_MWALK
6779    if(printout > 2)
6780    {
6781      idString(M,"//** Mprwalk: M");
6782    }
6783#endif
6784#ifdef TIME_TEST
6785    if(endwalks == TRUE)
6786    {
6787      xtstd = xtstd+clock()-to;
6788#ifdef ENDWALKS
6789      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6790            ((double) clock())/1000000 -((double)tim) /1000000);
6791#endif
6792    }
6793    else
6794      tstd=tstd+clock()-to;
6795#endif
6796    /* change the ring to oldRing */
6797    rChangeCurrRing(oldRing);
6798    M1 =  idrMoveR(M, newRing,currRing);
6799    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6800#ifdef TIME_TEST
6801    to=clock();
6802#endif
6803    /* compute a representation of the generators of submod (M)
6804       with respect to those of mod (Gomega).
6805       Gomega is a reduced Groebner basis w.r.t. the current ring */
6806    F = MLifttwoIdeal(Gomega2, M1, G);
6807#ifdef TIME_TEST
6808    if(endwalks == FALSE)
6809      tlift = tlift+clock()-to;
6810    else
6811      xtlift=clock()-to;
6812#endif
6813#ifdef CHECK_IDEAL_MWALK
6814    if(printout > 2)
6815    {
6816      idString(F,"//** Mprwalk: F");
6817    }
6818#endif
6819
6820    idDelete(&M1);
6821    idDelete(&Gomega2);
6822    idDelete(&G);
6823
6824    // change the ring to newRing
6825    rChangeCurrRing(newRing);
6826    if(reduction == 0)
6827    {
6828      G = idrMoveR(F,oldRing,currRing);
6829    }
6830    else
6831    {
6832      F1 = idrMoveR(F, oldRing,currRing);
6833      if(printout > 2)
6834      {
6835        PrintS("\n //** Mprwalk: reduce the Groebner basis.\n");
6836      }
6837#ifdef TIME_TEST
6838      to=clock();
6839#endif
6840      G = kInterRedCC(F1, NULL);
6841#ifdef TIME_TEST
6842      if(endwalks == FALSE)
6843        tred = tred+clock()-to;
6844      else
6845        xtred=clock()-to;
6846#endif
6847      idDelete(&F1);
6848    }
6849
6850    if(endwalks == TRUE)
6851      break;
6852
6853    NEXT_VECTOR:
6854#ifdef TIME_TEST
6855    to = clock();
6856#endif
6857    next_weight = next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6858#ifdef TIME_TEST
6859    tnw = tnw + clock() - to;
6860#endif
6861
6862#ifdef TIME_TEST
6863    to = clock();
6864#endif
6865    // compute an initial form ideal of <G> w.r.t. "next_vector"
6866    Gomega = MwalkInitialForm(G, next_weight);
6867#ifdef TIME_TEST
6868    tif = tif + clock()-to; //time for computing initial form ideal
6869#endif
6870
6871    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
6872    if(lengthpoly(Gomega) > 0)
6873    {
6874      Print("\n there is a polynomial in Gomega with at least 3 monomials,\n");
6875      // low-dimensional facet of the cone
6876      delete next_weight;
6877      if(target_M->length() == nV)
6878      {
6879        iv_M = MivMatrixOrder(curr_weight);
6880      }
6881      else
6882      {
6883        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
6884      }
6885#ifdef TIME_TEST
6886      to = clock();
6887#endif
6888      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, op_deg);
6889#ifdef TIME_TEST
6890      tnw = tnw + clock() - to;
6891#endif
6892      idDelete(&Gomega);
6893#ifdef TIME_TEST
6894      to = clock();
6895#endif
6896      Gomega = MwalkInitialForm(G, next_weight);
6897#ifdef TIME_TEST
6898      tif = tif + clock()-to; //time for computing initial form ideal
6899#endif
6900  Print("delete\n");
6901      delete iv_M;
6902    }
6903
6904/*
6905    to=clock();
6906    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6907    if(polylength > 0)
6908    {
6909      if(printout > 2)
6910      {
6911        Print("\n //**Mprwalk: there is a polynomial in Gomega with at least 3 monomials, low-dimensional facet of the cone.\n");
6912      }
6913      delete next_weight;
6914      next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, op_deg);
6915    }
6916    tnw=tnw+clock()-to;
6917*/
6918#ifdef PRINT_VECTORS
6919    if(printout > 0)
6920    {
6921      MivString(curr_weight, target_weight, next_weight);
6922    }
6923#endif
6924
6925    if(Overflow_Error == TRUE)
6926    {
6927      ntwC = 0;
6928      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6929      //idElements(G, "G");
6930      delete next_weight;
6931      goto FINISH_160302;
6932    }
6933    if(MivComp(next_weight, ivNull) == 1){
6934      newRing = currRing;
6935      delete next_weight;
6936      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6937      break;
6938    }
6939    if(MivComp(next_weight, target_weight) == 1)
6940      endwalks = TRUE;
6941
6942    for(i=nV-1; i>=0; i--)
6943      (*curr_weight)[i] = (*next_weight)[i];
6944
6945    delete next_weight;
6946  }// end of while-loop
6947
6948  if(tp_deg != 1)
6949  {
6950    FINISH_160302:
6951    if(target_M->length() == nV)
6952    {
6953      if(MivSame(orig_target, exivlp) == 1)
6954        if (rParameter(currRing) != NULL)
6955          DefRingParlp();
6956        else
6957          VMrDefaultlp();
6958      else
6959        if (rParameter(currRing) != NULL)
6960          DefRingPar(orig_target);
6961        else
6962          rChangeCurrRing(VMrDefault(orig_target));
6963    }
6964    else
6965    {
6966      rChangeCurrRing(VMatrDefault(target_M));
6967    }
6968    TargetRing=currRing;
6969    F1 = idrMoveR(G, newRing,currRing);
6970
6971    // check whether the pertubed target vector stays in the correct cone
6972    if(ntwC != 0)
6973    {
6974      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6975    }
6976    if(ntestw != 1 || ntwC == 0)
6977    {
6978      if(ntestw != 1 && printout > 2)
6979      {
6980#ifdef PRINT_VECTORS
6981        ivString(pert_target_vector, "tau");
6982#endif
6983        PrintS("\n// **Mprwalk: perturbed target vector doesn't stay in cone.");
6984        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6985        //idElements(F1, "G");
6986      }
6987      // LastGB is "better" than the kStd subroutine
6988#ifdef TIME_TEST
6989      to=clock();
6990#endif
6991      ideal eF1;
6992      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1 || target_M->length() != nV)
6993      {
6994        if(printout > 2)
6995        {
6996          PrintS("\n// ** Mprwalk: Call \"std\" to compute a Groebner basis.\n");
6997        }
6998        eF1 = MstdCC(F1);
6999        idDelete(&F1);
7000      }
7001      else
7002      {
7003        if(printout > 2)
7004        {
7005          PrintS("\n// **Mprwalk: Call \"LastGB\" to compute a Groebner basis.\n");
7006        }
7007        rChangeCurrRing(newRing);
7008        ideal F2 = idrMoveR(F1, TargetRing,currRing);
7009        eF1 = LastGB(F2, curr_weight, tp_deg-1);
7010        F2=NULL;
7011      }
7012#ifdef TIME_TEST
7013      xtextra=clock()-to;
7014#endif
7015      ring exTargetRing = currRing;
7016
7017      rChangeCurrRing(XXRing);
7018      Eresult = idrMoveR(eF1, exTargetRing,currRing);
7019    }
7020    else
7021    {
7022      rChangeCurrRing(XXRing);
7023      Eresult = idrMoveR(F1, TargetRing,currRing);
7024    }
7025  }
7026  else
7027  {
7028    rChangeCurrRing(XXRing);
7029    Eresult = idrMoveR(G, newRing,currRing);
7030  }
7031  si_opt_1 = save1; //set original options, e. g. option(RedSB)
7032  delete ivNull;
7033  if(tp_deg != 1)
7034    delete target_weight;
7035
7036  if(op_deg != 1 )
7037    delete curr_weight;
7038
7039  delete exivlp;
7040  delete last_omega;
7041
7042#ifdef TIME_TEST
7043  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
7044             tnw+xtnw);
7045
7046  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
7047  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
7048#endif
7049  Print("\n//** Mprwalk: Perturbation Walk took %d steps.\n", nstep);
7050  return(Eresult);
7051}
7052
7053intvec* XivNull;
7054
7055// define a matrix (1 ... 1)
7056intvec* MMatrixone(int nV)
7057{
7058  int i,j;
7059  intvec* ivM = new intvec(nV*nV);
7060
7061  for(i=0; i<nV; i++)
7062    for(j=0; j<nV; j++)
7063    (*ivM)[i*nV + j] = 1;
7064
7065  return(ivM);
7066}
7067
7068int nnflow;
7069int Xcall;
7070int Xngleich;
7071
7072/***********************************************************************
7073 * Perturb the start weight vector at the top level, i.e. nlev = 1     *
7074 ***********************************************************************/
7075static ideal rec_fractal_call(ideal G, int nlev, intvec* ivtarget,
7076             int reduction, int printout)
7077{
7078  Overflow_Error =  FALSE;
7079  if(printout >0)
7080  {
7081    Print("\n\n// Entering the %d-th recursion:", nlev);
7082  }
7083  int i, nV = currRing->N;
7084  ring new_ring, testring;
7085  //ring extoRing;
7086  ideal Gomega, Gomega1, Gomega2, FF, F, F1, Gresult, Gresult1, G1, Gt;
7087  int nwalks = 0;
7088  intvec* Mwlp;
7089#ifndef BUCHBERGER_ALG
7090  intvec* hilb_func;
7091#endif
7092  //intvec* extXtau;
7093  intvec* next_vect;
7094  intvec* omega2 = new intvec(nV);
7095  intvec* omtmp = new intvec(nV);
7096  //intvec* altomega = new intvec(nV);
7097
7098  for(i = nV -1; i>0; i--)
7099  {
7100    (*omtmp)[i] = (*ivtarget)[i];
7101  }
7102  //BOOLEAN isnewtarget = FALSE;
7103
7104  // to avoid (1,0,...,0) as the target vector (Hans)
7105  intvec* last_omega = new intvec(nV);
7106  for(i=nV-1; i>0; i--)
7107    (*last_omega)[i] = 1;
7108  (*last_omega)[0] = 10000;
7109
7110  intvec* omega = new intvec(nV);
7111  for(i=0; i<nV; i++) {
7112    if(Xsigma->length() == nV)
7113      (*omega)[i] =  (*Xsigma)[i];
7114    else
7115      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
7116
7117    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7118  }
7119
7120   if(nlev == 1)  Xcall = 1;
7121   else Xcall = 0;
7122
7123  ring oRing = currRing;
7124
7125  while(1)
7126  {
7127#ifdef FIRST_STEP_FRACTAL
7128    // perturb the current weight vector only on the top level or
7129    // after perturbation of the both vectors, nlev = 2 as the top level
7130    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
7131      if(islengthpoly2(G) == 1)
7132      {
7133        Mwlp = MivWeightOrderlp(omega);
7134        Xsigma = Mfpertvector(G, Mwlp);
7135        delete Mwlp;
7136        Overflow_Error = FALSE;
7137      }
7138#endif
7139    nwalks ++;
7140    NEXT_VECTOR_FRACTAL:
7141#ifdef TIME_TEST
7142    to=clock();
7143#endif
7144    // determine the next border
7145    next_vect = MkInterRedNextWeight(omega,omega2,G);
7146#ifdef TIME_TEST
7147    xtnw=xtnw+clock()-to;
7148#endif
7149    oRing = currRing;
7150
7151    // We only perturb the current target vector at the recursion level 1
7152    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
7153      if (MivComp(next_vect, omega2) == 1)
7154      {
7155        // to dispense with taking initial (and lifting/interreducing
7156        // after the call of recursion
7157        if(printout > 0)
7158        {
7159          Print("\n//** rec_fractal_call: Perturb the both vectors with degree %d.",nlev);
7160          //idElements(G, "G");
7161        }
7162
7163        Xngleich = 1;
7164        nlev +=1;
7165
7166        if(ivtarget->length() == nV)
7167        {
7168          if (rParameter(currRing) != NULL)
7169            DefRingPar(omtmp);
7170          else
7171            rChangeCurrRing(VMrDefault(omtmp));
7172        }
7173        else
7174        {
7175          rChangeCurrRing(VMatrDefault(ivtarget));
7176        }
7177        testring = currRing;
7178        Gt = idrMoveR(G, oRing,currRing);
7179
7180        // perturb the original target vector w.r.t. the current GB
7181        if(ivtarget->length() == nV)
7182        {
7183          delete Xtau;
7184          Xtau = NewVectorlp(Gt);
7185        }
7186        else
7187        {
7188          delete Xtau;
7189          Xtau = Mfpertvector(Gt,ivtarget);
7190        }
7191
7192        rChangeCurrRing(oRing);
7193        G = idrMoveR(Gt, testring,currRing);
7194
7195        // perturb the current vector w.r.t. the current GB
7196        Mwlp = MivWeightOrderlp(omega);
7197        Xsigma = Mfpertvector(G, Mwlp);
7198        delete Mwlp;
7199
7200        for(i=nV-1; i>=0; i--) {
7201          (*omega2)[i] = (*Xtau)[nV+i];
7202          (*omega)[i] = (*Xsigma)[nV+i];
7203        }
7204
7205        delete next_vect;
7206#ifdef TIME_TEST
7207        to=clock();
7208#endif
7209        // to avoid the value of Overflow_Error that occur in Mfpertvector
7210        Overflow_Error = FALSE;
7211        next_vect = MkInterRedNextWeight(omega,omega2,G);
7212#ifdef TIME_TEST
7213        xtnw=xtnw+clock()-to;
7214#endif
7215      }// end of (if MivComp(next_vect, omega2) == 1)
7216
7217#ifdef PRINT_VECTORS
7218      if(printout > 0)
7219      {
7220        MivString(omega, omega2, next_vect);
7221      }
7222#endif
7223
7224    // check whether the the computed vector is in the correct cone.
7225    // If no, compute the reduced Groebner basis of an omega-homogeneous
7226    // ideal with Buchberger's algorithm and stop this recursion step
7227    if(Overflow_Error == TRUE || test_w_in_ConeCC(G, next_vect) != 1)  //e.g. Example s7, cyc6
7228    {
7229      delete next_vect;
7230      if(ivtarget->length() == nV)
7231      {
7232        if (rParameter(currRing) != NULL)
7233          DefRingPar(omtmp);
7234        else
7235          rChangeCurrRing(VMrDefault(omtmp));
7236      }
7237      else
7238      {
7239        rChangeCurrRing(VMatrDefault(ivtarget));
7240      }
7241#ifdef TEST_OVERFLOW
7242      Gt = idrMoveR(G, oRing,currRing);
7243      Gt = NULL; return(Gt);
7244#endif
7245      if(printout > 0)
7246      {
7247        Print("\n//** rec_fractal_call: Applying Buchberger's algorithm in ring r = %s;",
7248              rString(currRing));
7249      }
7250#ifdef TIME_TEST
7251      to=clock();
7252#endif
7253      Gt = idrMoveR(G, oRing,currRing);
7254      G1 = MstdCC(Gt);
7255#ifdef TIME_TEST
7256      xtextra=xtextra+clock()-to;
7257#endif
7258      Gt = NULL;
7259
7260      delete omega2;
7261      //delete altomega;
7262      if(printout > 0)
7263      {
7264        Print("\n//** rec_fractal_call: Overflow. Leaving the %d-th recursion with %d steps.\n",
7265              nlev, nwalks);
7266        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7267      }
7268
7269      nnflow ++;
7270      Overflow_Error = FALSE;
7271      return (G1);
7272    }
7273
7274    /* If the perturbed target vector stays in the correct cone,
7275       return the current GB,
7276       otherwise, return the computed  GB by the Buchberger-algorithm.
7277       Then we update the perturbed target vectors w.r.t. this GB. */
7278
7279    /* the computed vector is equal to the origin vector, since
7280       t is not defined */
7281    if (MivComp(next_vect, XivNull) == 1)
7282    {
7283      if(ivtarget->length() == nV)
7284      {
7285        if (rParameter(currRing) != NULL)
7286          DefRingPar(omtmp);
7287        else
7288          rChangeCurrRing(VMrDefault(omtmp));
7289      }
7290      else
7291      {
7292        rChangeCurrRing(VMatrDefault(ivtarget));
7293      }
7294
7295      testring = currRing;
7296      Gt = idrMoveR(G, oRing,currRing);
7297
7298      if(test_w_in_ConeCC(Gt, omega2) == 1)
7299      {
7300        delete omega2;
7301        delete next_vect;
7302        //delete altomega;
7303        if(printout > 0)
7304        {
7305          Print("\n//** rec_fractal_call: Correct cone. Leaving the %d-th recursion with %d steps.\n",
7306              nlev, nwalks);
7307        }
7308        return (Gt);
7309      }
7310      else
7311      {
7312        if(printout > 0)
7313        {
7314          Print("\n//** rec_fractal_call: Wrong cone. Tau doesn't stay in the correct cone.\n");
7315        }
7316
7317#ifndef  MSTDCC_FRACTAL
7318        intvec* Xtautmp;
7319        if(ivtarget->length() == nV)
7320        {
7321          Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
7322        }
7323        else
7324        {
7325          Xtautmp = Mfpertvector(Gt, ivtarget);
7326        }
7327#ifdef TEST_OVERFLOW
7328      if(Overflow_Error == TRUE)
7329      Gt = NULL; return(Gt);
7330#endif
7331
7332        if(MivSame(Xtau, Xtautmp) == 1)
7333        {
7334          if(printout > 0)
7335          {
7336            Print("\n//** rec_fractal_call: Updated vectors are equal to the old vectors.\n");
7337          }
7338          delete Xtautmp;
7339          goto FRACTAL_MSTDCC;
7340        }
7341
7342        Xtau = Xtautmp;
7343        Xtautmp = NULL;
7344
7345        for(i=nV-1; i>=0; i--)
7346          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7347
7348        rChangeCurrRing(oRing);
7349        G = idrMoveR(Gt, testring,currRing);
7350
7351        goto NEXT_VECTOR_FRACTAL;
7352#endif
7353
7354      FRACTAL_MSTDCC:
7355        if(printout > 0)
7356        {
7357          Print("\n//** rec_fractal_call: Wrong cone. Applying Buchberger's algorithm in ring = %s.\n",
7358                rString(currRing));
7359        }
7360#ifdef TIME_TEST
7361        to=clock();
7362#endif
7363        G = MstdCC(Gt);
7364#ifdef TIME_TEST
7365        xtextra=xtextra+clock()-to;
7366#endif
7367        oRing = currRing;
7368
7369        // update the original target vector w.r.t. the current GB
7370        if(ivtarget->length() == nV)
7371        {
7372          if(MivSame(Xivinput, Xivlp) == 1)
7373            if (rParameter(currRing) != NULL)
7374              DefRingParlp();
7375            else
7376              VMrDefaultlp();
7377          else
7378            if (rParameter(currRing) != NULL)
7379              DefRingPar(Xivinput);
7380            else
7381              rChangeCurrRing(VMrDefault(Xivinput));
7382        }
7383        else
7384        {
7385          rChangeCurrRing(VMatrRefine(ivtarget,Xivinput));
7386        }
7387        testring = currRing;
7388        Gt = idrMoveR(G, oRing,currRing);
7389
7390        // perturb the original target vector w.r.t. the current GB
7391        if(ivtarget->length() == nV)
7392        {
7393          delete Xtau;
7394          Xtau = NewVectorlp(Gt);
7395        }
7396        else
7397        {
7398          delete Xtau;
7399          Xtau = Mfpertvector(Gt,ivtarget);
7400        }
7401
7402        rChangeCurrRing(oRing);
7403        G = idrMoveR(Gt, testring,currRing);
7404
7405        delete omega2;
7406        delete next_vect;
7407        //delete altomega;
7408        if(printout > 0)
7409        {
7410          Print("\n//** rec_fractal_call: Vectors updated. Leaving the %d-th recursion with %d steps.\n",
7411              nlev, nwalks);
7412          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7413        }
7414        if(Overflow_Error == TRUE)
7415          nnflow ++;
7416
7417        Overflow_Error = FALSE;
7418        return(G);
7419      }
7420    }// end of (if next_vect==nullvector)
7421
7422    for(i=nV-1; i>=0; i--) {
7423      //(*altomega)[i] = (*omega)[i];
7424      (*omega)[i] = (*next_vect)[i];
7425    }
7426    delete next_vect;
7427#ifdef TIME_TEST
7428    to=clock();
7429#endif
7430    // Take the initial form of <G> w.r.t. omega
7431    Gomega = MwalkInitialForm(G, omega);
7432#ifdef TIME_TEST
7433    xtif=xtif+clock()-to;
7434#endif
7435#ifdef CHECK_IDEAL_MWALK
7436    if(printout > 1)
7437    {
7438      idString(Gomega,"//** rec_fractal_call: Gomega");
7439    }
7440#endif
7441    if(reduction == 0)
7442    {
7443      // Check whether the intermediate weight vector lies in the interior of the cone.
7444      // If so, only perform reductions. Otherwise apply Buchberger's algorithm.
7445      FF = middleOfCone(G,Gomega);
7446      if( FF != NULL)
7447      {
7448        idDelete(&G);
7449        G = idCopy(FF);
7450        idDelete(&FF);
7451        // Compue next vector.
7452        goto NEXT_VECTOR_FRACTAL;
7453      } 
7454    }
7455
7456#ifndef  BUCHBERGER_ALG
7457    if(isNolVector(omega) == 0)
7458      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
7459    else
7460      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
7461#endif
7462
7463    if(ivtarget->length() == nV)
7464    {
7465      if (rParameter(currRing) != NULL)
7466        DefRingPar(omega);
7467      else
7468        rChangeCurrRing(VMrDefault(omega));
7469    }
7470    else
7471    {
7472      rChangeCurrRing(VMatrRefine(ivtarget,omega));
7473    }
7474    Gomega1 = idrMoveR(Gomega, oRing,currRing);
7475
7476    // Maximal recursion depth, to compute a red. GB
7477    // Fractal walk with the alternative recursion
7478    // alternative recursion
7479    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
7480    {
7481      if(printout > 1)
7482      {
7483        Print("\n//** rec_fractal_call: Maximal recursion depth.\n");
7484      }
7485#ifdef TIME_TEST
7486      to=clock();
7487#endif
7488#ifdef  BUCHBERGER_ALG
7489      Gresult = MstdhomCC(Gomega1);
7490#else
7491      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
7492      delete hilb_func;
7493#endif
7494#ifdef TIME_TEST
7495      xtstd=xtstd+clock()-to;
7496#endif
7497    }
7498    else
7499    {
7500      rChangeCurrRing(oRing);
7501      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
7502      Gresult = rec_fractal_call(idCopy(Gomega1),nlev+1,omega,reduction,printout);
7503    }
7504#ifdef CHECK_IDEAL_MWALK
7505    if(printout > 2)
7506    {
7507      idString(Gresult,"//** rec_fractal_call: M");
7508    }
7509#endif
7510    //convert a Groebner basis from a ring to another ring
7511    new_ring = currRing;
7512
7513    rChangeCurrRing(oRing);
7514    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
7515    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
7516#ifdef TIME_TEST
7517    to=clock();
7518#endif
7519    // Lifting process
7520    F = MLifttwoIdeal(Gomega2, Gresult1, G);
7521#ifdef TIME_TEST
7522    xtlift=xtlift+clock()-to;
7523#endif
7524#ifdef CHECK_IDEAL_MWALK
7525    if(printout > 2)
7526    {
7527      idString(F,"//** rec_fractal_call: F");
7528    }
7529#endif
7530    idDelete(&Gresult1);
7531    idDelete(&Gomega2);
7532    idDelete(&G);
7533
7534    rChangeCurrRing(new_ring);
7535    G = idrMoveR(F,oRing,currRing);
7536/*
7537    F1 = idrMoveR(F, oRing,currRing);
7538#ifdef TIME_TEST
7539    to=clock();
7540#endif
7541    // Interreduce G
7542    G = kInterRedCC(F1, NULL);
7543#ifdef TIME_TEST
7544    xtred=xtred+clock()-to;
7545#endif
7546    idDelete(&F1);
7547*/
7548  }
7549}
7550
7551/************************************************************************
7552 * Perturb the start weight vector at the top level with random element *
7553 ************************************************************************/
7554static ideal rec_r_fractal_call(ideal G, int nlev, intvec* ivtarget,
7555                int weight_rad, int reduction, int printout)
7556{
7557  Overflow_Error =  FALSE;
7558  //Print("\n\n// Entering the %d-th recursion:", nlev);
7559
7560  int nwalks = 0,i,nV=currRing->N;//polylength
7561  ring new_ring, testring;
7562  //ring extoRing;
7563  ideal Gomega, Gomega1, Gomega2, F, FF, F1, Gresult, Gresult1, G1, Gt;
7564  intvec* Mwlp;
7565#ifndef BUCHBERGER_ALG
7566  intvec* hilb_func;
7567#endif
7568//  intvec* extXtau;
7569  intvec* next_vect;
7570  intvec* iv_M;
7571  intvec* omega2 = new intvec(nV);
7572  intvec* omtmp = new intvec(nV);
7573  intvec* altomega = new intvec(nV);
7574
7575  //BOOLEAN isnewtarget = FALSE;
7576
7577  for(i = nV -1; i>0; i--)
7578  {
7579    (*omtmp)[i] = (*ivtarget)[i];
7580  }
7581  // to avoid (1,0,...,0) as the target vector (Hans)
7582  intvec* last_omega = new intvec(nV);
7583  for(i=nV-1; i>0; i--)
7584    (*last_omega)[i] = 1;
7585  (*last_omega)[0] = 10000;
7586
7587  intvec* omega = new intvec(nV);
7588  for(i=0; i<nV; i++) {
7589    if(Xsigma->length() == nV)
7590      (*omega)[i] =  (*Xsigma)[i];
7591    else
7592      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
7593
7594    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7595  }
7596
7597   if(nlev == 1)  Xcall = 1;
7598   else Xcall = 0;
7599
7600  ring oRing = currRing;
7601
7602  while(1)
7603  {
7604#ifdef FIRST_STEP_FRACTAL
7605    /*
7606    perturb the current weight vector only on the top level or
7607    after perturbation of the both vectors, nlev = 2 as the top level
7608    */
7609    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
7610      if(islengthpoly2(G) == 1)
7611      {
7612        Mwlp = MivWeightOrderlp(omega);
7613        Xsigma = Mfpertvector(G, Mwlp);
7614        delete Mwlp;
7615        Overflow_Error = FALSE;
7616      }
7617#endif
7618    nwalks ++;
7619    NEXT_VECTOR_FRACTAL:
7620#ifdef TIME_TEST
7621    to=clock();
7622#endif
7623    /* determine the next border */
7624    next_vect = MkInterRedNextWeight(omega,omega2,G);
7625#ifdef TIME_TEST
7626    xtnw=xtnw+clock()-to;
7627#endif
7628    if(lengthpoly(MwalkInitialForm(G, next_vect)) > 0 && G->m[0] != NULL)
7629    {
7630      if(printout > 0)
7631      {
7632        PrintS("\n**// rec_r_fractal_call: there is a polynomial in Gomega with at least 3 monomials.\n");
7633      }
7634      delete next_vect;
7635      iv_M = MivMatrixOrder(omega);
7636#ifdef TIME_TEST
7637      to=clock();
7638#endif
7639      next_vect = MWalkRandomNextWeight(G,iv_M,omega2,weight_rad,nlev);
7640#ifdef TIME_TEST
7641      xtnw=xtnw+clock()-to;
7642#endif
7643      if(isNegNolVector(next_vect) == 1)
7644      {
7645        delete next_vect;
7646#ifdef TIME_TEST
7647        to=clock();
7648#endif
7649        next_vect = MkInterRedNextWeight(omega,omega2,G);
7650#ifdef TIME_TEST
7651        xtnw=xtnw+clock()-to;
7652#endif
7653      }
7654    }
7655    oRing = currRing;
7656
7657    // We only perturb the current target vector at the recursion  level 1
7658    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
7659      if (MivComp(next_vect, omega2) == 1)
7660      {
7661        // to dispense with taking initials and lifting/interreducing
7662        // after the call of recursion.
7663        if(printout > 0)
7664        {
7665          Print("\n//** rec_r_fractal_call: Perturb both vectors with degree %d.",nlev);
7666          //idElements(G, "G");
7667        }
7668        Xngleich = 1;
7669        nlev +=1;
7670        if(ivtarget->length() == nV)
7671        {
7672          if (rParameter(currRing) != NULL)
7673            DefRingPar(omtmp);
7674          else
7675            rChangeCurrRing(VMrDefault(omtmp));
7676        }
7677        else
7678        {
7679          rChangeCurrRing(VMatrDefault(ivtarget));
7680        }
7681        testring = currRing;
7682        Gt = idrMoveR(G, oRing,currRing);
7683
7684        // perturb the original target vector w.r.t. the current GB
7685        if(ivtarget->length() == nV)
7686        {
7687          delete Xtau;
7688          Xtau = NewVectorlp(Gt);
7689        }
7690        else
7691        {
7692          delete Xtau;
7693          Xtau = Mfpertvector(Gt,ivtarget);
7694        }
7695
7696        rChangeCurrRing(oRing);
7697        G = idrMoveR(Gt,testring,currRing);
7698
7699        // perturb the current vector w.r.t. the current GB
7700        Mwlp = MivWeightOrderlp(omega);
7701        if(ivtarget->length() > nV)
7702        {
7703          delete Mwlp;
7704          Mwlp = MivMatrixOrderRefine(omega,ivtarget);
7705        }
7706        Xsigma = Mfpertvector(G, Mwlp);
7707        delete Mwlp;
7708
7709        for(i=nV-1; i>=0; i--)
7710        {
7711          (*omega2)[i] = (*Xtau)[nV+i];
7712          (*omega)[i] = (*Xsigma)[nV+i];
7713        }
7714
7715        delete next_vect;
7716
7717   //to avoid the value of Overflow_Error that occur in Mfpertvector
7718        Overflow_Error = FALSE;
7719#ifdef TIME_TEST
7720        to=clock();
7721#endif
7722        next_vect = MkInterRedNextWeight(omega,omega2,G);
7723#ifdef TIME_TEST
7724        xtnw=xtnw+clock()-to;
7725#endif
7726        if(lengthpoly(MwalkInitialForm(G, next_vect)) > 0 && G->m[0] != NULL)
7727        {
7728          // there is a polynomial in Gomega with at least 3 monomials
7729          iv_M = MivMatrixOrder(omega);
7730          delete next_vect;
7731#ifdef TIME_TEST
7732          to=clock();
7733#endif
7734          next_vect = MWalkRandomNextWeight(G,iv_M,omega2,weight_rad,nlev);
7735#ifdef TIME_TEST
7736          xtnw=xtnw+clock()-to;
7737#endif
7738          delete iv_M;
7739          if(isNegNolVector(next_vect) == 1)
7740          {
7741            delete next_vect;
7742#ifdef TIME_TEST
7743            to=clock();
7744#endif
7745            next_vect = MkInterRedNextWeight(omega,omega2,G);
7746#ifdef TIME_TEST
7747        xtnw=xtnw+clock()-to;
7748#endif
7749          }
7750        }
7751      }
7752#ifdef PRINT_VECTORS
7753      if(printout > 0)
7754      {
7755        MivString(omega, omega2, next_vect);
7756      }
7757#endif
7758
7759/*     check whether the the computed vector is in the correct cone
7760       If no, the reduced GB of an omega-homogeneous ideal will be
7761       computed by Buchberger algorithm and stop this recursion step
7762*/
7763    if(Overflow_Error == TRUE || test_w_in_ConeCC(G,next_vect) != 1)//e.g. Example s7, cyc6
7764    {
7765      delete next_vect;
7766      if(ivtarget->length() == nV)
7767      {
7768        if (rParameter(currRing) != NULL)
7769        {
7770          DefRingPar(omtmp);
7771        }
7772        else
7773        {
7774          rChangeCurrRing(VMrDefault(omtmp));
7775        }
7776      }
7777      else
7778      {
7779        rChangeCurrRing(VMatrDefault(ivtarget));
7780      }
7781#ifdef TEST_OVERFLOW
7782      Gt = idrMoveR(G, oRing,currRing);
7783      Gt = NULL;
7784      return(Gt);
7785#endif
7786      if(printout > 0)
7787      {
7788        Print("\n//** rec_r_fractal_call: applying Buchberger's algorithm in ring r = %s;",
7789              rString(currRing));
7790      }
7791      Gt = idrMoveR(G, oRing,currRing);
7792#ifdef TIME_TEST
7793      to=clock();
7794#endif
7795      G1 = MstdCC(Gt);
7796#ifdef TIME_TEST
7797      xtextra=xtextra+clock()-to;
7798#endif
7799      Gt = NULL;
7800
7801      delete omega2;
7802      delete altomega;
7803      if(printout > 0)
7804      {
7805        Print("\n//** rec_r_fractal_call: Leaving the %d-th recursion with %d steps.\n",
7806              nlev, nwalks);
7807        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7808      }
7809      nnflow ++;
7810      Overflow_Error = FALSE;
7811      return (G1);
7812    }
7813    /*
7814       If the perturbed target vector stays in the correct cone,
7815       return the current Groebner basis.
7816       Otherwise, return the Groebner basis computed with Buchberger's
7817       algorithm.
7818       Then we update the perturbed target vectors w.r.t. this GB.
7819    */
7820    if (MivComp(next_vect, XivNull) == 1)
7821    {
7822      // The computed vector is equal to the origin vector,
7823      // because t is not defined
7824      if(ivtarget->length() == nV)
7825      {
7826        if (rParameter(currRing) != NULL)
7827          DefRingPar(omtmp);
7828        else
7829          rChangeCurrRing(VMrDefault(omtmp));
7830      }
7831      else
7832      {
7833        rChangeCurrRing(VMatrDefault(ivtarget));
7834      }
7835      testring = currRing;
7836      Gt = idrMoveR(G, oRing,currRing);
7837
7838      if(test_w_in_ConeCC(Gt, omega2) == 1)
7839      {
7840        delete omega2;
7841        delete next_vect;
7842        delete altomega;
7843        if(printout > 0)
7844        {
7845          Print("\n//** rec_r_fractal_call: Leaving the %d-th recursion with %d steps.\n",
7846                nlev, nwalks);
7847          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7848        }
7849        return (Gt);
7850      }
7851      else
7852      { 
7853        if(printout > 0)
7854        {
7855          Print("\n//** rec_r_fractal_call: target weight doesn't stay in the correct cone.\n");
7856        }
7857
7858#ifndef  MSTDCC_FRACTAL
7859#ifdef PRINT_VECTORS
7860        if(printout > 0)
7861        {
7862          ivString(Xtau, "old Xtau");
7863        }
7864#endif
7865        intvec* Xtautmp;
7866        if(ivtarget->length() == nV)
7867        {
7868          Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
7869        }
7870        else
7871        {
7872          Xtautmp = Mfpertvector(Gt, ivtarget);
7873        }
7874#ifdef TEST_OVERFLOW
7875      if(Overflow_Error == TRUE)
7876      Gt = NULL; return(Gt);
7877#endif
7878
7879        if(MivSame(Xtau, Xtautmp) == 1)
7880        {
7881          //PrintS("\n// Update vectors are equal to the old vectors!!");
7882          delete Xtautmp;
7883          goto FRACTAL_MSTDCC;
7884        }
7885
7886        Xtau = Xtautmp;
7887        Xtautmp = NULL;
7888#ifdef PRINT_VECTORS
7889        if(printout > 0)
7890        {
7891          ivString(Xtau, "new  Xtau");
7892        }
7893#endif
7894
7895        for(i=nV-1; i>=0; i--)
7896          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
7897
7898        //Print("\n//  ring tau = %s;", rString(currRing));
7899        rChangeCurrRing(oRing);
7900        G = idrMoveR(Gt, testring,currRing);
7901
7902        goto NEXT_VECTOR_FRACTAL;
7903#endif
7904
7905      FRACTAL_MSTDCC:
7906        if(printout > 0)
7907        {
7908          Print("\n//** rec_r_fractal_call: apply Buchberger's algorithm in ring = %s.\n",
7909                rString(currRing));
7910        }
7911#ifdef TIME_TEST
7912        to=clock();
7913#endif
7914        G = MstdCC(Gt);
7915#ifdef TIME_TEST
7916        xtextra=xtextra+clock()-to;
7917#endif
7918        oRing = currRing;
7919
7920        // update the original target vector w.r.t. the current GB
7921        if(ivtarget->length() == nV)
7922        {
7923          if(MivSame(Xivinput, Xivlp) == 1)
7924            if (rParameter(currRing) != NULL)
7925              DefRingParlp();
7926            else
7927              VMrDefaultlp();
7928          else
7929            if (rParameter(currRing) != NULL)
7930              DefRingPar(Xivinput);
7931            else
7932              rChangeCurrRing(VMrDefault(Xivinput));
7933        }
7934        else
7935        {
7936          rChangeCurrRing(VMatrRefine(ivtarget,Xivinput));
7937        }
7938        testring = currRing;
7939        Gt = idrMoveR(G, oRing,currRing);
7940
7941        // perturb the original target vector w.r.t. the current GB
7942        if(ivtarget->length() == nV)
7943        {
7944          delete Xtau;
7945          Xtau = NewVectorlp(Gt);
7946        }
7947        else
7948        {
7949          delete Xtau;
7950          Xtau = Mfpertvector(Gt,ivtarget);
7951        }
7952
7953        rChangeCurrRing(oRing);
7954        G = idrMoveR(Gt, testring,currRing);
7955
7956        delete omega2;
7957        delete next_vect;
7958        delete altomega;
7959        if(printout > 0)
7960        {
7961          Print("\n//** rec_r_fractal_call: Leaving the %d-th recursion with %d steps.\n",
7962                nlev,nwalks);
7963          //Print(" ** Overflow_Error? (%d)", Overflow_Error);
7964        }
7965        if(Overflow_Error == TRUE)
7966          nnflow ++;
7967
7968        Overflow_Error = FALSE;
7969        return(G);
7970      }
7971    } //end of if(MivComp(next_vect, XivNull) == 1)
7972
7973    for(i=nV-1; i>=0; i--)
7974    {
7975      (*altomega)[i] = (*omega)[i];
7976      (*omega)[i] = (*next_vect)[i];
7977    }
7978    delete next_vect;
7979#ifdef TIME_TEST
7980    to=clock();
7981#endif
7982    // Take the initial form of <G> w.r.t. omega
7983    Gomega = MwalkInitialForm(G, omega);
7984#ifdef TIME_TEST
7985    xtif=xtif+clock()-to;
7986#endif
7987    //polylength = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
7988    //polylength = lengthpoly(Gomega);
7989#ifdef CHECK_IDEAL_MWALK
7990    if(printout > 1)
7991    {
7992      idString(Gomega,"//** rec_r_fractal_call: Gomega");
7993    }
7994#endif
7995    if(reduction == 0)
7996    {
7997      /* Check whether the intermediate weight vector lies in the interior of the cone.
7998       * If so, only perform reductions. Otherwise apply Buchberger's algorithm. */
7999      FF = middleOfCone(G,Gomega);
8000      if( FF != NULL)
8001      {
8002        idDelete(&G);
8003        G = idCopy(FF);
8004        idDelete(&FF);
8005        /* Compue next vector. */
8006        goto NEXT_VECTOR_FRACTAL;
8007      } 
8008    }
8009
8010#ifndef  BUCHBERGER_ALG
8011    if(isNolVector(omega) == 0)
8012      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
8013    else
8014      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
8015#endif
8016    if(ivtarget->length() == nV)
8017    {
8018      if (rParameter(currRing) != NULL)
8019        DefRingPar(omega);
8020      else
8021        rChangeCurrRing(VMrDefault(omega));
8022    }
8023    else
8024    {
8025      rChangeCurrRing(VMatrRefine(ivtarget,omega));
8026    }
8027    Gomega1 = idrMoveR(Gomega, oRing,currRing);
8028
8029    // Maximal recursion depth, to compute a red. GB
8030    // Fractal walk with the alternative recursion
8031    // alternative recursion
8032    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
8033    {
8034#ifdef TIME_TEST
8035      to=clock();
8036#endif
8037#ifdef  BUCHBERGER_ALG
8038      Gresult = MstdhomCC(Gomega1);
8039#else
8040      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
8041      delete hilb_func;
8042#endif
8043#ifdef TIME_TEST
8044      xtstd=xtstd+clock()-to;
8045#endif
8046    }
8047    else
8048    {
8049      rChangeCurrRing(oRing);
8050      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
8051      Gresult = rec_r_fractal_call(idCopy(Gomega1),nlev+1,omega,weight_rad,reduction,printout);
8052    }
8053#ifdef CHECK_IDEAL_MWALK
8054    if(printout > 2)
8055    {
8056      idString(Gresult,"//** rec_r_fractal_call: M");
8057    }
8058#endif
8059    //convert a Groebner basis from a ring to another ring
8060    new_ring = currRing;
8061
8062    rChangeCurrRing(oRing);
8063    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
8064    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
8065#ifdef TIME_TEST
8066    to=clock();
8067#endif
8068    // Lifting process
8069    F = MLifttwoIdeal(Gomega2, Gresult1, G);
8070#ifdef TIME_TEST
8071    xtlift=xtlift+clock()-to;
8072#endif
8073#ifdef CHECK_IDEAL_MWALK
8074    if(printout > 2)
8075    {
8076      idString(F,"//** rec_r_fractal_call: F");
8077    }
8078#endif
8079    idDelete(&Gresult1);
8080    idDelete(&Gomega2);
8081    idDelete(&G);
8082
8083    rChangeCurrRing(new_ring);
8084    //F1 = idrMoveR(F, oRing,currRing);
8085    G = idrMoveR(F,oRing,currRing);
8086/*
8087#ifdef TIME_TEST
8088    to=clock();
8089#endif
8090    // Interreduce G
8091    G = kInterRedCC(F1, NULL);
8092#ifdef TIME_TEST
8093    xtred=xtred+clock()-to;
8094#endif
8095    idDelete(&F1);
8096*/
8097  }
8098}
8099
8100
8101/*******************************************************************************
8102 * The implementation of the fractal walk algorithm                            *
8103 *                                                                             *
8104 * The main procedur Mfwalk calls the recursive Subroutine                     *
8105 * rec_fractal_call to compute the wanted Groebner basis.                      *
8106 * At the main procedur we compute the reduced Groebner basis w.r.t. a "fast"  *
8107 * order, e.g. "dp" and a sequence of weight vectors which are row vectors     *
8108 * of a matrix. This matrix defines the given monomial order, e.g. "lp"        *
8109 *******************************************************************************/
8110ideal Mfwalk(ideal G, intvec* ivstart, intvec* ivtarget,
8111             int reduction, int printout)
8112{
8113  BITSET save1 = si_opt_1; // save current options
8114  if(reduction == 0)
8115  {
8116    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
8117    //si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
8118  }
8119  Set_Error(FALSE);
8120  Overflow_Error = FALSE;
8121  //Print("// pSetm_Error = (%d)", ErrorCheck());
8122  //Print("\n// ring ro = %s;", rString(currRing));
8123
8124  nnflow = 0;
8125  Xngleich = 0;
8126  Xcall = 0;
8127#ifdef TIME_TEST
8128  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
8129  xftinput = clock();
8130#endif
8131  ring  oldRing = currRing;
8132  int i, nV = currRing->N;
8133  XivNull = new intvec(nV);
8134  Xivinput = ivtarget;
8135  ngleich = 0;
8136#ifdef TIME_TEST
8137  to=clock();
8138#endif
8139  ideal I = MstdCC(G);
8140  G = NULL;
8141#ifdef TIME_TEST
8142  xftostd=clock()-to;
8143#endif
8144  Xsigma = ivstart;
8145
8146  Xnlev=nV;
8147
8148#ifdef FIRST_STEP_FRACTAL
8149  ideal Gw = MwalkInitialForm(I, ivstart);
8150  for(i=IDELEMS(Gw)-1; i>=0; i--)
8151  {
8152    if((Gw->m[i]!=NULL) // len >=0
8153    && (Gw->m[i]->next!=NULL) // len >=1
8154    && (Gw->m[i]->next->next!=NULL)) // len >=2
8155    {
8156      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
8157      intvec* Mdp;
8158      if(ivstart->length() == nV)
8159      {
8160        if(MivSame(ivstart, iv_dp) != 1)
8161          Mdp = MivWeightOrderdp(ivstart);
8162        else
8163          Mdp = MivMatrixOrderdp(nV);
8164      }
8165      else
8166      {
8167        Mdp = ivstart;
8168      }
8169
8170      Xsigma = Mfpertvector(I, Mdp);
8171      Overflow_Error = FALSE;
8172
8173      delete Mdp;
8174      delete iv_dp;
8175      break;
8176    }
8177  }
8178  idDelete(&Gw);
8179#endif
8180
8181  ideal I1;
8182  intvec* Mlp;
8183  Xivlp = Mivlp(nV);
8184
8185  if(ivtarget->length() == nV)
8186  {
8187    if(MivComp(ivtarget, Xivlp)  != 1)
8188    {
8189      if (rParameter(currRing) != NULL)
8190        DefRingPar(ivtarget);
8191      else
8192        rChangeCurrRing(VMrDefault(ivtarget));
8193
8194      I1 = idrMoveR(I, oldRing,currRing);
8195      Mlp = MivWeightOrderlp(ivtarget);
8196      Xtau = Mfpertvector(I1, Mlp);
8197    }
8198    else
8199    {
8200      if (rParameter(currRing) != NULL)
8201        DefRingParlp();
8202      else
8203        VMrDefaultlp();
8204
8205      I1 = idrMoveR(I, oldRing,currRing);
8206      Mlp =  MivMatrixOrderlp(nV);
8207      Xtau = Mfpertvector(I1, Mlp);
8208    }
8209  }
8210  else
8211  {
8212    rChangeCurrRing(VMatrDefault(ivtarget));
8213    I1 = idrMoveR(I,oldRing,currRing);
8214    Mlp =  ivtarget;
8215    Xtau = Mfpertvector(I1, Mlp);
8216  }
8217  delete Mlp;
8218  Overflow_Error = FALSE;
8219
8220  //ivString(Xsigma, "Xsigma");
8221  //ivString(Xtau, "Xtau");
8222
8223  id_Delete(&I, oldRing);
8224  ring tRing = currRing;
8225  if(ivtarget->length() == nV)
8226  {
8227    if (rParameter(currRing) != NULL)
8228      DefRingPar(ivstart);
8229    else
8230      rChangeCurrRing(VMrDefault(ivstart));
8231  }
8232  else
8233  {
8234    rChangeCurrRing(VMatrDefault(ivstart));
8235  }
8236
8237  I = idrMoveR(I1,tRing,currRing);
8238#ifdef TIME_TEST
8239  to=clock();
8240#endif
8241  ideal J = MstdCC(I);
8242  idDelete(&I);
8243#ifdef TIME_TEST
8244  xftostd=xftostd+clock()-to;
8245#endif
8246  ideal resF;
8247  ring helpRing = currRing;
8248
8249  J = rec_fractal_call(J,1,ivtarget,reduction,printout);
8250
8251  rChangeCurrRing(oldRing);
8252  resF = idrMoveR(J, helpRing,currRing);
8253  idSkipZeroes(resF);
8254
8255  si_opt_1 = save1; //set original options, e. g. option(RedSB)
8256  delete Xivlp;
8257  delete Xsigma;
8258  delete Xtau;
8259  delete XivNull;
8260
8261#ifdef TIME_TEST
8262  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
8263                    xtlift, xtred, xtnw);
8264
8265
8266  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
8267  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8268  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
8269#endif
8270
8271  return(resF);
8272}
8273
8274/*******************************************************************************
8275 * The implementation of the fractal walk algorithm with random element        *
8276 *                                                                             *
8277 * The main procedur Mfwalk calls the recursive Subroutine                     *
8278 * rec_r_fractal_call to compute the wanted Groebner basis.                    *
8279 * At the main procedure we compute the reduced Groebner basis w.r.t. a "fast" *
8280 * order, e.g. "dp" and a sequence of weight vectors which are row vectors     *
8281 * of a matrix. This matrix defines the given monomial order, e.g. "lp"        *
8282 *******************************************************************************/
8283ideal Mfrwalk(ideal G, intvec* ivstart, intvec* ivtarget,
8284              int weight_rad, int reduction, int printout)
8285{
8286  BITSET save1 = si_opt_1; // save current options
8287  //check that weight radius is valid
8288  if(weight_rad < 0)
8289  {
8290    Werror("Invalid radius.\n");
8291    return NULL;
8292  }
8293  if(reduction == 0)
8294  {
8295    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
8296    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
8297  }
8298  Set_Error(FALSE);
8299  Overflow_Error = FALSE;
8300  //Print("// pSetm_Error = (%d)", ErrorCheck());
8301  //Print("\n// ring ro = %s;", rString(currRing));
8302
8303  nnflow = 0;
8304  Xngleich = 0;
8305  Xcall = 0;
8306#ifdef TIME_TEST
8307  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
8308  xftinput = clock();
8309#endif
8310  ring  oldRing = currRing;
8311  int i, nV = currRing->N;
8312  XivNull = new intvec(nV);
8313  Xivinput = ivtarget;
8314  ngleich = 0;
8315#ifdef TIME_TEST
8316  to=clock();
8317#endif
8318  ideal I = MstdCC(G);
8319  G = NULL;
8320#ifdef TIME_TEST
8321  xftostd=clock()-to;
8322#endif
8323  Xsigma = ivstart;
8324
8325  Xnlev=nV;
8326
8327#ifdef FIRST_STEP_FRACTAL
8328  ideal Gw = MwalkInitialForm(I, ivstart);
8329  for(i=IDELEMS(Gw)-1; i>=0; i--)
8330  {
8331    if((Gw->m[i]!=NULL) // len >=0
8332    && (Gw->m[i]->next!=NULL) // len >=1
8333    && (Gw->m[i]->next->next!=NULL)) // len >=2
8334    {
8335      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
8336      intvec* Mdp;
8337      if(ivstart->length() == nV)
8338      {
8339        if(MivSame(ivstart, iv_dp) != 1)
8340          Mdp = MivWeightOrderdp(ivstart);
8341        else
8342          Mdp = MivMatrixOrderdp(nV);
8343      }
8344      else
8345      {
8346        Mdp = ivstart;
8347      }
8348
8349      Xsigma = Mfpertvector(I, Mdp);
8350      Overflow_Error = FALSE;
8351
8352      delete Mdp;
8353      delete iv_dp;
8354      break;
8355    }
8356  }
8357  idDelete(&Gw);
8358#endif
8359
8360  ideal I1;
8361  intvec* Mlp;
8362  Xivlp = Mivlp(nV);
8363
8364  if(ivtarget->length() == nV)
8365  {
8366    if(MivComp(ivtarget, Xivlp)  != 1)
8367    {
8368      if (rParameter(currRing) != NULL)
8369        DefRingPar(ivtarget);
8370      else
8371        rChangeCurrRing(VMrDefault(ivtarget));
8372
8373      I1 = idrMoveR(I, oldRing,currRing);
8374      Mlp = MivWeightOrderlp(ivtarget);
8375      Xtau = Mfpertvector(I1, Mlp);
8376    }
8377    else
8378    {
8379      if (rParameter(currRing) != NULL)
8380        DefRingParlp();
8381      else
8382        VMrDefaultlp();
8383
8384      I1 = idrMoveR(I, oldRing,currRing);
8385      Mlp =  MivMatrixOrderlp(nV);
8386      Xtau = Mfpertvector(I1, Mlp);
8387    }
8388  }
8389  else
8390  {
8391    rChangeCurrRing(VMatrDefault(ivtarget));
8392    I1 = idrMoveR(I,oldRing,currRing);
8393    Mlp =  ivtarget;
8394    Xtau = Mfpertvector(I1, Mlp);
8395  }
8396  delete Mlp;
8397  Overflow_Error = FALSE;
8398
8399  //ivString(Xsigma, "Xsigma");
8400  //ivString(Xtau, "Xtau");
8401
8402  id_Delete(&I, oldRing);
8403  ring tRing = currRing;
8404  if(ivtarget->length() == nV)
8405  {
8406    if (rParameter(currRing) != NULL)
8407      DefRingPar(ivstart);
8408    else
8409      rChangeCurrRing(VMrDefault(ivstart));
8410  }
8411  else
8412  {
8413    rChangeCurrRing(VMatrDefault(ivstart));
8414  }
8415
8416  I = idrMoveR(I1,tRing,currRing);
8417#ifdef TIME_TEST
8418  to=clock();
8419#endif
8420  ideal J = MstdCC(I);
8421  idDelete(&I);
8422#ifdef TIME_TEST
8423  xftostd=xftostd+clock()-to;
8424#endif
8425  ideal resF;
8426  ring helpRing = currRing;
8427
8428  J = rec_r_fractal_call(J,1,ivtarget,weight_rad,reduction,printout);
8429
8430  rChangeCurrRing(oldRing);
8431  resF = idrMoveR(J, helpRing,currRing);
8432  idSkipZeroes(resF);
8433
8434  si_opt_1 = save1; //set original options, e. g. option(RedSB)
8435  delete Xivlp;
8436  delete Xsigma;
8437  delete Xtau;
8438  delete XivNull;
8439
8440#ifdef TIME_TEST
8441  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
8442                    xtlift, xtred, xtnw);
8443
8444
8445 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
8446  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8447  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
8448#endif
8449
8450  return(resF);
8451}
8452
8453/*******************************************************
8454 * Tran's algorithm                                    *
8455 *                                                     *
8456 * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
8457 *******************************************************/
8458ideal TranMImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP)
8459{
8460#ifdef TIME_TEST
8461  clock_t mtim = clock();
8462#endif
8463  Set_Error(FALSE  );
8464  Overflow_Error =  FALSE;
8465  //Print("// pSetm_Error = (%d)", ErrorCheck());
8466  //Print("\n// ring ro = %s;", rString(currRing));
8467
8468  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
8469#ifdef TIME_TEST
8470  clock_t tinput = clock();
8471#endif
8472  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
8473  int *npert=(int*)omAlloc(2*nV*sizeof(int));
8474  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
8475  //ring endRing;
8476  ring newRing, oldRing, lpRing;
8477  intvec* next_weight;
8478  intvec* ivNull = new intvec(nV); //define (0,...,0)
8479  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
8480  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
8481  ideal H0;
8482  //ideal  H1;
8483  ideal H2, Glp;
8484  int nGB, endwalks = 0,  nwalkpert=0,  npertstep=0;
8485  intvec* Mlp =  MivMatrixOrderlp(nV);
8486  intvec* vector_tmp = new intvec(nV);
8487#ifndef BUCHBERGER_ALG
8488  intvec* hilb_func;
8489#endif
8490  // to avoid (1,0,...,0) as the target vector
8491  intvec* last_omega = new intvec(nV);
8492  for(i=nV-1; i>0; i--)
8493    (*last_omega)[i] = 1;
8494  (*last_omega)[0] = 10000;
8495
8496  //  intvec* extra_curr_weight = new intvec(nV);
8497  intvec* target_weight = new intvec(nV);
8498  for(i=nV-1; i>=0; i--)
8499    (*target_weight)[i] = (*target_tmp)[i];
8500
8501  ring XXRing = currRing;
8502  newRing = currRing;
8503
8504  to=clock();
8505  // compute a red. GB w.r.t. the help ring
8506  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) = "dp"
8507    G = MstdCC(G);
8508  else
8509  {
8510    //rOrdStr(currRing) = (a(.c_w..),lp,C)
8511    if (rParameter(currRing) != NULL)
8512      DefRingPar(curr_weight);
8513    else
8514      rChangeCurrRing(VMrDefault(curr_weight));
8515    G = idrMoveR(G, XXRing,currRing);
8516    G = MstdCC(G);
8517  }
8518  tostd=clock()-to;
8519
8520#ifdef REPRESENTATION_OF_SIGMA
8521  ideal Gw = MwalkInitialForm(G, curr_weight);
8522
8523  if(islengthpoly2(Gw)==1)
8524  {
8525    intvec* MDp;
8526    if(MivComp(curr_weight, iv_dp) == 1)
8527      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
8528    else
8529      MDp = MivWeightOrderlp(curr_weight);
8530
8531    curr_weight = RepresentationMatrix_Dp(G, MDp);
8532
8533    delete MDp;
8534
8535    ring exring = currRing;
8536
8537    if (rParameter(currRing) != NULL)
8538      DefRingPar(curr_weight);
8539    else
8540      rChangeCurrRing(VMrDefault(curr_weight));
8541    to=clock();
8542    Gw = idrMoveR(G, exring,currRing);
8543    G = MstdCC(Gw);
8544    Gw = NULL;
8545    tostd=tostd+clock()-to;
8546    //ivString(curr_weight,"rep. sigma");
8547    goto COMPUTE_NEW_VECTOR;
8548  }
8549
8550  idDelete(&Gw);
8551  delete iv_dp;
8552#endif
8553
8554
8555  while(1)
8556  {
8557    to=clock();
8558    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
8559    Gomega = MwalkInitialForm(G, curr_weight);
8560    tif=tif+clock()-to;
8561
8562#ifndef  BUCHBERGER_ALG
8563    if(isNolVector(curr_weight) == 0)
8564      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
8565    else
8566      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
8567#endif // BUCHBERGER_ALG
8568
8569    oldRing = currRing;
8570
8571    /* define a new ring that its ordering is "(a(curr_weight),lp) */
8572    if (rParameter(currRing) != NULL)
8573      DefRingPar(curr_weight);
8574    else
8575      rChangeCurrRing(VMrDefault(curr_weight));
8576
8577    newRing = currRing;
8578    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
8579
8580    to=clock();
8581    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
8582#ifdef  BUCHBERGER_ALG
8583    M = MstdhomCC(Gomega1);
8584#else
8585    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
8586    delete hilb_func;
8587#endif // BUCHBERGER_ALG
8588    tstd=tstd+clock()-to;
8589
8590    /* change the ring to oldRing */
8591    rChangeCurrRing(oldRing);
8592    M1 =  idrMoveR(M, newRing,currRing);
8593    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
8594
8595    to=clock();
8596    /* compute a representation of the generators of submod (M)
8597       with respect to those of mod (Gomega).
8598       Gomega is a reduced Groebner basis w.r.t. the current ring */
8599    F = MLifttwoIdeal(Gomega2, M1, G);
8600    tlift=tlift+clock()-to;
8601
8602    idDelete(&M1);
8603    idDelete(&Gomega2);
8604    idDelete(&G);
8605
8606    /* change the ring to newRing */
8607    rChangeCurrRing(newRing);
8608    F1 = idrMoveR(F, oldRing,currRing);
8609
8610    to=clock();
8611    /* reduce the Groebner basis <G> w.r.t. new ring */
8612    G = kInterRedCC(F1, NULL);
8613    tred=tred+clock()-to;
8614    idDelete(&F1);
8615
8616
8617  COMPUTE_NEW_VECTOR:
8618    newRing = currRing;
8619    nwalk++;
8620    nwalkpert++;
8621    to=clock();
8622    // compute a next weight vector
8623    next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
8624    tnw=tnw+clock()-to;
8625#ifdef PRINT_VECTORS
8626    MivString(curr_weight, target_weight, next_weight);
8627#endif
8628
8629
8630    /* check whether the computed intermediate weight vector is in
8631       the correct cone; sometimes it is very big e.g. s7, cyc7.
8632       If it is NOT in the correct cone, then compute directly
8633       a reduced Groebner basis with respect to the lexicographic ordering
8634       for the known Groebner basis that it is computed in the last step.
8635    */
8636    //if(test_w_in_ConeCC(G, next_weight) != 1)
8637    if(Overflow_Error == TRUE)
8638    {
8639    OMEGA_OVERFLOW_TRAN_NEW:
8640      //Print("\n//  takes %d steps!", nwalk-1);
8641      //Print("\n//ring lastRing = %s;", rString(currRing));
8642#ifdef TEST_OVERFLOW
8643      goto  BE_FINISH;
8644#endif
8645/*
8646#ifdef CHECK_IDEAL_MWALK
8647      idElements(G, "G");
8648      //headidString(G, "G");
8649#endif
8650*/
8651      if(MivSame(target_tmp, iv_lp) == 1)
8652        if (rParameter(currRing) != NULL)
8653          DefRingParlp();
8654        else
8655          VMrDefaultlp();
8656      else
8657        if (rParameter(currRing) != NULL)
8658          DefRingPar(target_tmp);
8659        else
8660          rChangeCurrRing(VMrDefault(target_tmp));
8661
8662      lpRing = currRing;
8663      G1 = idrMoveR(G, newRing,currRing);
8664
8665      to=clock();
8666      /*apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>*/
8667      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0){
8668        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
8669        G = MstdCC(G1);//no result for qnt1
8670      }
8671      else {
8672        rChangeCurrRing(newRing);
8673        G1 = idrMoveR(G1, lpRing,currRing);
8674
8675        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
8676        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
8677
8678        rChangeCurrRing(lpRing);
8679        G = idrMoveR(G, newRing,currRing);
8680      }
8681      textra=clock()-to;
8682      npert[endwalks]=nwalk-npert_tmp;
8683      npert_tmp = nwalk;
8684      endwalks ++;
8685      break;
8686    }
8687
8688    /* check whether the computed Groebner basis is really a Groebner basis.
8689       If not, we perturb the target vector with the maximal "perturbation"
8690       degree.*/
8691    if(MivComp(next_weight, target_weight) == 1 ||
8692       MivComp(next_weight, curr_weight) == 1 )
8693    {
8694      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
8695
8696
8697      //compute the number of perturbations and its step
8698      npert[endwalks]=nwalk-npert_tmp;
8699      npert_tmp = nwalk;
8700
8701      endwalks ++;
8702
8703      /*it is very important if the walk only uses one step, e.g. Fate, liu*/
8704      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1){
8705        rChangeCurrRing(XXRing);
8706        G = idrMoveR(G, newRing,currRing);
8707        goto FINISH;
8708      }
8709      H0 = id_Head(G,currRing);
8710
8711      if(MivSame(target_tmp, iv_lp) == 1)
8712        if (rParameter(currRing) != NULL)
8713          DefRingParlp();
8714        else
8715          VMrDefaultlp();
8716      else
8717        if (rParameter(currRing) != NULL)
8718          DefRingPar(target_tmp);
8719        else
8720          rChangeCurrRing(VMrDefault(target_tmp));
8721
8722      lpRing = currRing;
8723      Glp = idrMoveR(G, newRing,currRing);
8724      H2 = idrMoveR(H0, newRing,currRing);
8725
8726      /* Apply Lemma 2.2 in Collart et. al (1997) to check whether
8727         cone(k-1) is equal to cone(k) */
8728      nGB = 1;
8729      for(i=IDELEMS(Glp)-1; i>=0; i--)
8730      {
8731        poly t;
8732        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
8733        {
8734          pDelete(&t);
8735          idDelete(&H2);//5.5.02
8736          nGB = 0; //i.e. Glp is no reduced Groebner basis
8737          break;
8738        }
8739        pDelete(&t);
8740      }
8741
8742      idDelete(&H2);//5.5.02
8743
8744      if(nGB == 1)
8745      {
8746        G = Glp;
8747        Glp = NULL;
8748        break;
8749      }
8750
8751       /* perturb the target weight vector, if the vector target_tmp
8752          stays in many cones */
8753      poly p;
8754      BOOLEAN plength3 = FALSE;
8755      for(i=IDELEMS(Glp)-1; i>=0; i--)
8756      {
8757        p = MpolyInitialForm(Glp->m[i], target_tmp);
8758        if(p->next != NULL &&
8759           p->next->next != NULL &&
8760           p->next->next->next != NULL)
8761        {
8762          Overflow_Error = FALSE;
8763
8764          for(i=0; i<nV; i++)
8765            (*vector_tmp)[i] = (*target_weight)[i];
8766
8767          delete target_weight;
8768          target_weight = MPertVectors(Glp, Mlp, nV);
8769
8770          if(MivComp(vector_tmp, target_weight)==1)
8771          {
8772            //PrintS("\n// The old and new representaion vector are the same!!");
8773            G = Glp;
8774            newRing = currRing;
8775            goto OMEGA_OVERFLOW_TRAN_NEW;
8776           }
8777
8778          if(Overflow_Error == TRUE)
8779          {
8780            rChangeCurrRing(newRing);
8781            G = idrMoveR(Glp, lpRing,currRing);
8782            goto OMEGA_OVERFLOW_TRAN_NEW;
8783          }
8784
8785          plength3 = TRUE;
8786          pDelete(&p);
8787          break;
8788        }
8789        pDelete(&p);
8790      }
8791
8792      if(plength3 == FALSE)
8793      {
8794        rChangeCurrRing(newRing);
8795        G = idrMoveR(Glp, lpRing,currRing);
8796        goto TRAN_LIFTING;
8797      }
8798
8799
8800      npertstep = nwalk;
8801      nwalkpert = 1;
8802      nsteppert ++;
8803
8804      /*
8805      Print("\n// Subroutine needs (%d) steps.", nwalk);
8806      idElements(Glp, "last G in walk:");
8807      PrintS("\n// ****************************************");
8808      Print("\n// Perturb the original target vector (%d): ", nsteppert);
8809      ivString(target_weight, "new target");
8810      PrintS("\n// ****************************************\n");
8811      */
8812      rChangeCurrRing(newRing);
8813      G = idrMoveR(Glp, lpRing,currRing);
8814
8815      delete next_weight;
8816
8817      //Print("\n// ring rNEW = %s;", rString(currRing));
8818      goto COMPUTE_NEW_VECTOR;
8819    }
8820
8821  TRAN_LIFTING:
8822    for(i=nV-1; i>=0; i--)
8823      (*curr_weight)[i] = (*next_weight)[i];
8824
8825    delete next_weight;
8826  }//while
8827#ifdef TEST_OVERFLOW
8828 BE_FINISH:
8829#endif
8830  rChangeCurrRing(XXRing);
8831  G = idrMoveR(G, lpRing,currRing);
8832
8833 FINISH:
8834  delete ivNull;
8835  delete next_weight;
8836  delete iv_lp;
8837  omFree(npert);
8838
8839#ifdef TIME_TEST
8840  Print("\n// Computation took %d steps and %.2f sec",
8841        nwalk, ((double) (clock()-mtim)/1000000));
8842
8843  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
8844
8845 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
8846  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
8847#endif
8848
8849  return(G);
8850}
8851
8852#if 0
8853/*******************************************************
8854 * Tran's algorithm with random element                *
8855 *                                                     *
8856 * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
8857 *******************************************************/
8858ideal TranMrImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP, int weight_rad, int pert_deg)
8859{
8860#ifdef TIME_TEST
8861  clock_t mtim = clock();
8862#endif
8863  Set_Error(FALSE  );
8864  Overflow_Error =  FALSE;
8865  //Print("// pSetm_Error = (%d)", ErrorCheck());
8866  //Print("\n// ring ro = %s;", rString(currRing));
8867
8868  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
8869#ifdef TIME_TEST
8870  clock_t tinput = clock();
8871#endif
8872  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
8873  int *npert=(int*)omAlloc(2*nV*sizeof(int));
8874  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
8875  //ring endRing;
8876  ring newRing, oldRing, lpRing;
8877  intvec* next_weight;
8878  intvec* ivNull = new intvec(nV); //define (0,...,0)
8879  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
8880  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
8881  ideal H0;
8882  //ideal H1;
8883  ideal H2, Glp;
8884  int weight_norm, nGB, endwalks = 0,  nwalkpert=0,  npertstep=0;
8885  intvec* Mlp =  MivMatrixOrderlp(nV);
8886  intvec* vector_tmp = new intvec(nV);
8887#ifndef BUCHBERGER_ALG
8888  intvec* hilb_func;
8889#endif
8890  // to avoid (1,0,...,0) as the target vector
8891  intvec* last_omega = new intvec(nV);
8892  for(i=nV-1; i>0; i--)
8893  {
8894    (*last_omega)[i] = 1;
8895  }
8896  (*last_omega)[0] = 10000;
8897
8898//intvec* extra_curr_weight = new intvec(nV);
8899  intvec* target_weight = new intvec(nV);
8900  for(i=nV-1; i>=0; i--)
8901  {
8902    (*target_weight)[i] = (*target_tmp)[i];
8903  }
8904  ring XXRing = currRing;
8905  newRing = currRing;
8906
8907  to=clock();
8908  // compute a red. GB w.r.t. the help ring
8909  if(MivComp(curr_weight, iv_dp) == 1)
8910  {
8911    //rOrdStr(currRing) = "dp"
8912    G = MstdCC(G);
8913  }
8914  else
8915  {
8916    //rOrdStr(currRing) = (a(.c_w..),lp,C)
8917    if (rParameter(currRing) != NULL)
8918    {
8919      DefRingPar(curr_weight);
8920    }
8921    else
8922    {
8923      rChangeCurrRing(VMrDefault(curr_weight));
8924    }
8925    G = idrMoveR(G, XXRing,currRing);
8926    G = MstdCC(G);
8927  }
8928  tostd=clock()-to;
8929
8930#ifdef REPRESENTATION_OF_SIGMA
8931  ideal Gw = MwalkInitialForm(G, curr_weight);
8932
8933  if(islengthpoly2(Gw)==1)
8934  {
8935    intvec* MDp;
8936    if(MivComp(curr_weight, iv_dp) == 1)
8937    {
8938      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
8939    }
8940    else
8941    {
8942      MDp = MivWeightOrderlp(curr_weight);
8943    }
8944    curr_weight = RepresentationMatrix_Dp(G, MDp);
8945
8946    delete MDp;
8947
8948    ring exring = currRing;
8949
8950    if (rParameter(currRing) != NULL)
8951    {
8952      DefRingPar(curr_weight);
8953    }
8954    else
8955    {
8956      rChangeCurrRing(VMrDefault(curr_weight));
8957    }
8958    to=clock();
8959    Gw = idrMoveR(G, exring,currRing);
8960    G = MstdCC(Gw);
8961    Gw = NULL;
8962    tostd=tostd+clock()-to;
8963    //ivString(curr_weight,"rep. sigma");
8964    goto COMPUTE_NEW_VECTOR;
8965  }
8966
8967  idDelete(&Gw);
8968  delete iv_dp;
8969#endif
8970
8971
8972  while(1)
8973  {
8974    to=clock();
8975    // compute an initial form ideal of <G> w.r.t. "curr_vector"
8976    Gomega = MwalkInitialForm(G, curr_weight);
8977    tif=tif+clock()-to;
8978
8979#ifndef  BUCHBERGER_ALG
8980    if(isNolVector(curr_weight) == 0)
8981    {
8982      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
8983    }
8984    else
8985    {
8986      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
8987    }
8988#endif // BUCHBERGER_ALG
8989
8990    oldRing = currRing;
8991
8992    // define a new ring with ordering "(a(curr_weight),lp)
8993    if (rParameter(currRing) != NULL)
8994    {
8995      DefRingPar(curr_weight);
8996    }
8997    else
8998    {
8999      rChangeCurrRing(VMrDefault(curr_weight));
9000    }
9001    newRing = currRing;
9002    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
9003
9004    to=clock();
9005    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
9006#ifdef  BUCHBERGER_ALG
9007    M = MstdhomCC(Gomega1);
9008#else
9009    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9010    delete hilb_func;
9011#endif
9012    tstd=tstd+clock()-to;
9013
9014    // change the ring to oldRing
9015    rChangeCurrRing(oldRing);
9016    M1 =  idrMoveR(M, newRing,currRing);
9017    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9018
9019    to=clock();
9020    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega).
9021    // Gomega is a reduced Groebner basis w.r.t. the current ring
9022    F = MLifttwoIdeal(Gomega2, M1, G);
9023    tlift=tlift+clock()-to;
9024
9025    idDelete(&M1);
9026    idDelete(&Gomega2);
9027    idDelete(&G);
9028
9029    // change the ring to newRing
9030    rChangeCurrRing(newRing);
9031    F1 = idrMoveR(F, oldRing,currRing);
9032
9033    to=clock();
9034    // reduce the Groebner basis <G> w.r.t. new ring
9035    G = kInterRedCC(F1, NULL);
9036    tred=tred+clock()-to;
9037    idDelete(&F1);
9038
9039  COMPUTE_NEW_VECTOR:
9040    newRing = currRing;
9041    nwalk++;
9042    nwalkpert++;
9043    to=clock();
9044    // compute a next weight vector
9045    //next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
9046    next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, pert_deg);
9047/*
9048    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
9049
9050    if(MivComp(next_weight, target_weight) != 1)
9051    {
9052      // compute a perturbed next weight vector "next_weight1"
9053      intvec* next_weight1 = MkInterRedNextWeight(MPertVectors(G, MivMatrixOrder(curr_weight), pert_deg), target_weight, G);
9054
9055      // compare next_weight and next_weight1
9056      ideal G_test = MwalkInitialForm(G, next_weight);
9057      ideal G_test1 = MwalkInitialForm(G, next_weight1);
9058      if(IDELEMS(G_test1) <= IDELEMS(G_test))
9059      {
9060        next_weight = ivCopy(next_weight1);
9061      }
9062      delete next_weight1;
9063      // compute a random next weight vector "next_weight2"
9064      intvec* next_weight22 = ivCopy(target_weight);
9065      // Print("\n//  size of target_weight  = %d", sizeof((*target_weight)));
9066      k = 0;
9067
9068      while(test_w_in_ConeCC(G, next_weight22) == 0 && k < 11)
9069      {
9070        k++;
9071        if(k>10)
9072        {
9073          break;
9074        }
9075        weight_norm = 0;
9076        while(weight_norm == 0)
9077        {
9078          for(i=nV-1; i>=0; i--)
9079          {
9080            // Print("\n//  next_weight[%d]  = %d", i, (*next_weight)[i]);
9081            (*next_weight22)[i] = rand() % 60000 - 30000;
9082            weight_norm = weight_norm + (*next_weight22)[i]*(*next_weight22)[i];
9083          }
9084          weight_norm = 1 + floor(sqrt(weight_norm));
9085        }
9086        for(i=nV-1; i>=0; i--)
9087        {
9088          if((*next_weight22)[i] < 0)
9089          {
9090            (*next_weight22)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
9091          }
9092          else
9093          {
9094            (*next_weight22)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
9095          }
9096          // Print("\n//  next_weight22[%d]  = %d", i, (*next_weight22)[i]);
9097        }
9098      }
9099
9100      if(test_w_in_ConeCC(G, next_weight22) == 1)
9101      {
9102        // compare next_weight and next_weight2
9103        // Print("\n// ZUFALL IM KEGEL");
9104        intvec* next_weight2 = MkInterRedNextWeight(next_weight22, target_weight, G);
9105
9106        ideal G_test2 = MwalkInitialForm(G, next_weight2);
9107        if(IDELEMS(G_test2) <= IDELEMS(G_test))
9108        {
9109          if(IDELEMS(G_test2) <= IDELEMS(G_test1))
9110          {
9111             // Print("\n// ZUFALL BENUTZT!\n");
9112            next_weight = ivCopy(next_weight2);
9113          }
9114        }
9115        idDelete(&G_test2);
9116        delete next_weight2;
9117      }
9118      delete next_weight22;
9119      idDelete(&G_test);
9120      idDelete(&G_test1);
9121    }*/
9122
9123    tnw=tnw+clock()-to;
9124#ifdef PRINT_VECTORS
9125    MivString(curr_weight, target_weight, next_weight);
9126#endif
9127
9128/*   check whether the computed intermediate weight vector is in
9129     the correct cone; sometimes it is very big e.g. s7, cyc7.
9130     If it is NOT in the correct cone, then compute directly
9131     a reduced Groebner basis with respect to the lexicographic ordering
9132     for the known Groebner basis that it is computed in the last step.
9133*/
9134    //if(test_w_in_ConeCC(G, next_weight) != 1)
9135    if(Overflow_Error == TRUE)
9136    {
9137    OMEGA_OVERFLOW_TRAN_NEW:
9138      //Print("\n//  takes %d steps!", nwalk-1);
9139      //Print("\n//ring lastRing = %s;", rString(currRing));
9140#ifdef TEST_OVERFLOW
9141      goto  BE_FINISH;
9142#endif
9143
9144#ifdef CHECK_IDEAL_MWALK
9145      idElements(G, "G");
9146      //headidString(G, "G");
9147#endif
9148
9149      if(MivSame(target_tmp, iv_lp) == 1)
9150      {
9151        if (rParameter(currRing) != NULL)
9152        {
9153          DefRingParlp();
9154        }
9155        else
9156        {
9157          VMrDefaultlp();
9158        }
9159      }
9160      else
9161      {
9162        if (rParameter(currRing) != NULL)
9163        {
9164          DefRingPar(target_tmp);
9165        }
9166        else
9167        {
9168          rChangeCurrRing(VMrDefault(target_tmp));
9169        }
9170      }
9171      lpRing = currRing;
9172      G1 = idrMoveR(G, newRing,currRing);
9173
9174      to=clock();
9175      // apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>
9176      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0)
9177      {
9178        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
9179        G = MstdCC(G1);//no result for qnt1
9180      }
9181      else
9182      {
9183        rChangeCurrRing(newRing);
9184        G1 = idrMoveR(G1, lpRing,currRing);
9185
9186        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
9187        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
9188
9189        rChangeCurrRing(lpRing);
9190        G = idrMoveR(G, newRing,currRing);
9191      }
9192      textra=clock()-to;
9193      npert[endwalks]=nwalk-npert_tmp;
9194      npert_tmp = nwalk;
9195      endwalks ++;
9196      break;
9197    }
9198
9199    // check whether the computed Groebner basis is really a Groebner basis.
9200    // If not, we perturb the target vector with the maximal "perturbation" degree.
9201
9202    if(MivComp(next_weight, target_weight) == 1 || MivComp(next_weight, curr_weight) == 1 )
9203    {
9204      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
9205
9206
9207      //compute the number of perturbations and its step
9208      npert[endwalks]=nwalk-npert_tmp;
9209      npert_tmp = nwalk;
9210
9211      endwalks ++;
9212
9213      // it is very important if the walk only uses one step, e.g. Fate, liu
9214      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1)
9215      {
9216        rChangeCurrRing(XXRing);
9217        G = idrMoveR(G, newRing,currRing);
9218        goto FINISH;
9219      }
9220      H0 = id_Head(G,currRing);
9221
9222      if(MivSame(target_tmp, iv_lp) == 1)
9223      {
9224        if (rParameter(currRing) != NULL)
9225        {
9226          DefRingParlp();
9227        }
9228        else
9229        {
9230          VMrDefaultlp();
9231        }
9232      }
9233      else
9234      {
9235        if (rParameter(currRing) != NULL)
9236        {
9237          DefRingPar(target_tmp);
9238        }
9239        else
9240        {
9241          rChangeCurrRing(VMrDefault(target_tmp));
9242        }
9243      }
9244      lpRing = currRing;
9245      Glp = idrMoveR(G, newRing,currRing);
9246      H2 = idrMoveR(H0, newRing,currRing);
9247
9248      // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
9249      nGB = 1;
9250      for(i=IDELEMS(Glp)-1; i>=0; i--)
9251      {
9252        poly t;
9253        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
9254        {
9255          pDelete(&t);
9256          idDelete(&H2);//5.5.02
9257          nGB = 0; //i.e. Glp is no reduced Groebner basis
9258          break;
9259        }
9260        pDelete(&t);
9261      }
9262
9263      idDelete(&H2);//5.5.02
9264
9265      if(nGB == 1)
9266      {
9267        G = Glp;
9268        Glp = NULL;
9269        break;
9270      }
9271
9272       // perturb the target weight vector, if the vector target_tmp stays in many cones
9273      poly p;
9274      BOOLEAN plength3 = FALSE;
9275      for(i=IDELEMS(Glp)-1; i>=0; i--)
9276      {
9277        p = MpolyInitialForm(Glp->m[i], target_tmp);
9278        if(p->next != NULL &&
9279           p->next->next != NULL &&
9280           p->next->next->next != NULL)
9281        {
9282          Overflow_Error = FALSE;
9283
9284          for(i=0; i<nV; i++)
9285          {
9286            (*vector_tmp)[i] = (*target_weight)[i];
9287          }
9288          delete target_weight;
9289          target_weight = MPertVectors(Glp, Mlp, nV);
9290
9291          if(MivComp(vector_tmp, target_weight)==1)
9292          {
9293            //PrintS("\n// The old and new representaion vector are the same!!");
9294            G = Glp;
9295            newRing = currRing;
9296            goto OMEGA_OVERFLOW_TRAN_NEW;
9297           }
9298
9299          if(Overflow_Error == TRUE)
9300          {
9301            rChangeCurrRing(newRing);
9302            G = idrMoveR(Glp, lpRing,currRing);
9303            goto OMEGA_OVERFLOW_TRAN_NEW;
9304          }
9305
9306          plength3 = TRUE;
9307          pDelete(&p);
9308          break;
9309        }
9310        pDelete(&p);
9311      }
9312
9313      if(plength3 == FALSE)
9314      {
9315        rChangeCurrRing(newRing);
9316        G = idrMoveR(Glp, lpRing,currRing);
9317        goto TRAN_LIFTING;
9318      }
9319
9320
9321      npertstep = nwalk;
9322      nwalkpert = 1;
9323      nsteppert ++;
9324
9325      /*
9326      Print("\n// Subroutine needs (%d) steps.", nwalk);
9327      idElements(Glp, "last G in walk:");
9328      PrintS("\n// ****************************************");
9329      Print("\n// Perturb the original target vector (%d): ", nsteppert);
9330      ivString(target_weight, "new target");
9331      PrintS("\n// ****************************************\n");
9332      */
9333      rChangeCurrRing(newRing);
9334      G = idrMoveR(Glp, lpRing,currRing);
9335
9336      delete next_weight;
9337
9338      //Print("\n// ring rNEW = %s;", rString(currRing));
9339      goto COMPUTE_NEW_VECTOR;
9340    }
9341
9342  TRAN_LIFTING:
9343    for(i=nV-1; i>=0; i--)
9344    {
9345      (*curr_weight)[i] = (*next_weight)[i];
9346    }
9347    delete next_weight;
9348  } // end of while
9349#ifdef TEST_OVERFLOW
9350 BE_FINISH:
9351#endif
9352  rChangeCurrRing(XXRing);
9353  G = idrMoveR(G, lpRing,currRing);
9354
9355 FINISH:
9356  delete ivNull;
9357  delete next_weight;
9358  delete iv_lp;
9359  omFree(npert);
9360
9361#ifdef TIME_TEST
9362  Print("\n// Computation took %d steps and %.2f sec", nwalk, ((double) (clock()-mtim)/1000000));
9363
9364  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
9365
9366  Print("\n// pSetm_Error = (%d)", ErrorCheck());
9367  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
9368#endif
9369
9370  return(G);
9371}
9372#endif
9373
9374/*****************************************************************
9375 * compute the reduced Groebner basis of an ideal <Go> w.r.t. lp *
9376 *****************************************************************/
9377static ideal Mpwalk_MAltwalk1(ideal Go, intvec* curr_weight, int tp_deg)
9378{
9379  Overflow_Error = FALSE;
9380 // BOOLEAN nOverflow_Error = FALSE;
9381  clock_t tproc=0;
9382  clock_t tinput=clock();
9383  int i, nV = currRing->N;
9384
9385  //check that perturbation degree is valid
9386  if(tp_deg < 1 || tp_deg > nV)
9387  {
9388    Werror("Invalid perturbation degree.\n");
9389    return NULL;
9390  }
9391
9392  int nwalk=0, endwalks=0, ntestwinC=1;
9393  int tp_deg_tmp = tp_deg;
9394  ideal Gomega, M, F, G, M1, F1, Gomega1, Gomega2, G1;
9395  ring newRing, oldRing, TargetRing;
9396  intvec* next_weight;
9397  intvec* ivNull = new intvec(nV);
9398
9399  ring YXXRing = currRing;
9400
9401  intvec* iv_M_dpp = MivMatrixOrderlp(nV);
9402  intvec* target_weight;// = Mivlp(nV);
9403  ideal ssG;
9404
9405  // perturb the target vector
9406  while(1)
9407  {
9408    if(Overflow_Error == FALSE)
9409    {
9410      if (rParameter(currRing) != NULL)
9411      {
9412        DefRingParlp();
9413      }
9414      else
9415      {
9416        VMrDefaultlp();
9417      }
9418      TargetRing = currRing;
9419      ssG = idrMoveR(Go,YXXRing,currRing);
9420    }
9421    Overflow_Error = FALSE;
9422    if(tp_deg != 1)
9423    {
9424      target_weight = MPertVectors(ssG, iv_M_dpp, tp_deg);
9425    }
9426    else
9427    {
9428      target_weight = Mivlp(nV);
9429      break;
9430    }
9431    if(Overflow_Error == FALSE)
9432    {
9433      break;
9434    }
9435    Overflow_Error = TRUE;
9436    tp_deg --;
9437  }
9438  if(tp_deg != tp_deg_tmp)
9439  {
9440    Overflow_Error = TRUE;
9441    //nOverflow_Error = TRUE;
9442  }
9443
9444  //  Print("\n// tp_deg = %d", tp_deg);
9445  // ivString(target_weight, "pert target");
9446
9447  delete iv_M_dpp;
9448#ifndef  BUCHBERGER_ALG
9449  intvec* hilb_func;
9450#endif
9451  // to avoid (1,0,...,0) as the target vector
9452  intvec* last_omega = new intvec(nV);
9453  for(i=nV-1; i>0; i--)
9454  {
9455    (*last_omega)[i] = 1;
9456  }
9457  (*last_omega)[0] = 10000;
9458
9459  rChangeCurrRing(YXXRing);
9460  G = idrMoveR(ssG, TargetRing,currRing);
9461
9462  while(1)
9463  {
9464    nwalk ++;
9465    nstep ++;
9466
9467    if(nwalk==1)
9468    {
9469      goto FIRST_STEP;
9470    }
9471    to=clock();
9472    // compute an initial form ideal of <G> w.r.t. "curr_vector"
9473    Gomega = MwalkInitialForm(G, curr_weight);
9474    xtif=xtif+clock()-to;
9475
9476#ifndef  BUCHBERGER_ALG
9477    if(isNolVector(curr_weight) == 0)
9478      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
9479    else
9480      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
9481#endif
9482
9483    oldRing = currRing;
9484
9485    // define a new ring that its ordering is "(a(curr_weight),lp)
9486    if (rParameter(currRing) != NULL)
9487    {
9488      DefRingPar(curr_weight);
9489    }
9490    else
9491    {
9492      rChangeCurrRing(VMrDefault(curr_weight));
9493    }
9494    newRing = currRing;
9495    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
9496
9497#ifdef ENDWALKS
9498    if(endwalks == 1)
9499    {
9500      Print("\n//  it is  %d-th step!!", nwalk);
9501      idString(Gomega1, "Gw");
9502      PrintS("\n//  compute a rGB of Gw:");
9503    }
9504#endif
9505
9506    to=clock();
9507    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
9508#ifdef  BUCHBERGER_ALG
9509    M = MstdhomCC(Gomega1);
9510#else
9511    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9512    delete hilb_func;
9513#endif // BUCHBERGER_ALG
9514    xtstd=xtstd+clock()-to;
9515
9516    // change the ring to oldRing
9517    rChangeCurrRing(oldRing);
9518    M1 =  idrMoveR(M, newRing,currRing);
9519    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9520    to=clock();
9521
9522    // if(endwalks == 1){PrintS("\n//  Lifting is still working:");}
9523
9524    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
9525    F = MLifttwoIdeal(Gomega2, M1, G);
9526    xtlift=xtlift+clock()-to;
9527
9528    idDelete(&M1);
9529    idDelete(&Gomega2);
9530    idDelete(&G);
9531
9532    // change the ring to newRing
9533    rChangeCurrRing(newRing);
9534    F1 = idrMoveR(F, oldRing,currRing);
9535    to=clock();
9536    //if(endwalks == 1){ PrintS("\n//  InterRed is still working:");}
9537    // reduce the Groebner basis <G> w.r.t. the new ring
9538    G = kInterRedCC(F1, NULL);
9539    xtred=xtred+clock()-to;
9540    idDelete(&F1);
9541
9542    if(endwalks == 1)
9543      break;
9544
9545  FIRST_STEP:
9546    Overflow_Error=FALSE;
9547    to=clock();
9548    // compute a next weight vector
9549    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
9550    xtnw=xtnw+clock()-to;
9551#ifdef PRINT_VECTORS
9552    MivString(curr_weight, target_weight, next_weight);
9553#endif
9554
9555    if(Overflow_Error == TRUE)
9556    {
9557      delete next_weight;
9558      if(tp_deg > 1){
9559        //nOverflow_Error = Overflow_Error;
9560        tproc = tproc+clock()-tinput;
9561        //Print("\n// A subroutine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk, tp_deg-1);
9562        G1 = Mpwalk_MAltwalk1(G, curr_weight, tp_deg-1);
9563        goto MPW_Finish;
9564      }
9565      else {
9566        newRing = currRing;
9567        ntestwinC = 0;
9568        break;
9569      }
9570    }
9571
9572    if(MivComp(next_weight, ivNull) == 1)
9573    {
9574      newRing = currRing;
9575      delete next_weight;
9576      break;
9577    }
9578    if(MivComp(next_weight, target_weight) == 1)
9579    {
9580      endwalks = 1;
9581    }
9582    for(i=nV-1; i>=0; i--)
9583    {
9584      //(*extra_curr_weight)[i] = (*curr_weight)[i];
9585      (*curr_weight)[i] = (*next_weight)[i];
9586    }
9587    delete next_weight;
9588  }//while
9589
9590  // check whether the pertubed target vector is correct
9591
9592  //define and execute ring with lex. order
9593  if (rParameter(currRing) != NULL)
9594  {
9595    DefRingParlp();
9596  }
9597  else
9598  {
9599    VMrDefaultlp();
9600  }
9601  G1 = idrMoveR(G, newRing,currRing);
9602
9603  if( test_w_in_ConeCC(G1, target_weight) != 1 || ntestwinC == 0)
9604  {
9605    PrintS("\n// The perturbed target vector doesn't STAY in the correct cone!!");
9606    if(tp_deg == 1)
9607    {
9608      //Print("\n// subroutine takes %d steps and applys \"std\"", nwalk);
9609      to=clock();
9610      ideal G2 = MstdCC(G1);
9611      xtextra=xtextra+clock()-to;
9612      idDelete(&G1);
9613      G1 = G2;
9614      G2 = NULL;
9615    }
9616    else
9617    {
9618      //nOverflow_Error = Overflow_Error;
9619      tproc = tproc+clock()-tinput;
9620      // Print("\n// B subroutine takes %d steps and calls \"Mpwalk\" (1,%d) :", nwalk,  tp_deg-1);
9621      G1 = Mpwalk_MAltwalk1(G1, curr_weight, tp_deg-1);
9622    }
9623  }
9624
9625 MPW_Finish:
9626  newRing = currRing;
9627  rChangeCurrRing(YXXRing);
9628  ideal result = idrMoveR(G1, newRing,currRing);
9629
9630  delete ivNull;
9631  delete target_weight;
9632
9633  //Print("\n// \"Mpwalk\" (1,%d) took %d steps and %.2f sec. Overflow_Error (%d)", tp_deg, nwalk, ((double) clock()-tinput)/1000000, nOverflow_Error);
9634  Print("\n// Mprwalk took %d steps. Ring= %s;\n", nwalk, rString(currRing));
9635  return(result);
9636}
9637
9638/*******************************************************************
9639 * Implementation of the first alternative Groebner Walk Algorithm *
9640 *******************************************************************/
9641ideal MAltwalk1(ideal Go, int op_deg, int tp_deg, intvec* curr_weight,
9642                intvec* target_weight)
9643{
9644  Set_Error(FALSE  );
9645  Overflow_Error = FALSE;
9646#ifdef TIME_TEST
9647  BOOLEAN nOverflow_Error = FALSE;
9648#endif
9649  // Print("// pSetm_Error = (%d)", ErrorCheck());
9650
9651  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
9652  xftinput = clock();
9653  clock_t tostd, tproc;
9654
9655  nstep = 0;
9656  int i, nV = currRing->N;
9657  int nwalk=0, endwalks=0;
9658  int op_tmp = op_deg;
9659  ideal Gomega, M, F, G, Gomega1, Gomega2, M1, F1;
9660  ring newRing, oldRing;
9661  intvec* next_weight;
9662  intvec* iv_M_dp;
9663  intvec* ivNull = new intvec(nV);
9664  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
9665  intvec* exivlp = Mivlp(nV);
9666  //intvec* extra_curr_weight = new intvec(nV);
9667#ifndef  BUCHBERGER_ALG
9668  intvec* hilb_func;
9669#endif
9670  intvec* cw_tmp = curr_weight;
9671
9672  // to avoid (1,0,...,0) as the target vector
9673  intvec* last_omega = new intvec(nV);
9674  for(i=nV-1; i>0; i--)
9675  {
9676    (*last_omega)[i] = 1;
9677  }
9678  (*last_omega)[0] = 10000;
9679
9680  ring XXRing = currRing;
9681
9682  to=clock();
9683  /* compute a pertubed weight vector of the original weight vector.
9684     The perturbation degree is recursive decrease until that vector
9685     stays inn the correct cone. */
9686  while(1)
9687  {
9688    if(Overflow_Error == FALSE)
9689    {
9690      if(MivComp(curr_weight, iv_dp) == 1)
9691      {
9692      //rOrdStr(currRing) = "dp"
9693        if(op_tmp == op_deg)
9694        {
9695          G = MstdCC(Go);
9696          if(op_deg != 1)
9697          {
9698            iv_M_dp = MivMatrixOrderdp(nV);
9699          }
9700        }
9701      }
9702    }
9703    else
9704    {
9705      if(op_tmp == op_deg)
9706      {
9707        //rOrdStr(currRing) = (a(...),lp,C)
9708        if (rParameter(currRing) != NULL)
9709        {
9710          DefRingPar(cw_tmp);
9711        }
9712        else
9713        {
9714          rChangeCurrRing(VMrDefault(cw_tmp));
9715        }
9716        G = idrMoveR(Go, XXRing,currRing);
9717        G = MstdCC(G);
9718        if(op_deg != 1)
9719          iv_M_dp = MivMatrixOrder(cw_tmp);
9720      }
9721    }
9722    Overflow_Error = FALSE;
9723    if(op_deg != 1)
9724    {
9725      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
9726    }
9727    else
9728    {
9729      curr_weight =  cw_tmp;
9730      break;
9731    }
9732    if(Overflow_Error == FALSE)
9733    {
9734      break;
9735    }
9736    Overflow_Error = TRUE;
9737    op_deg --;
9738  }
9739  tostd=clock()-to;
9740
9741  if(op_tmp != 1 )
9742    delete iv_M_dp;
9743  delete iv_dp;
9744
9745  if(currRing->order[0] == ringorder_a)
9746    goto NEXT_VECTOR;
9747
9748  while(1)
9749  {
9750    nwalk ++;
9751    nstep ++;
9752
9753    to = clock();
9754    // compute an initial form ideal of <G> w.r.t. "curr_vector"
9755    Gomega = MwalkInitialForm(G, curr_weight);
9756    xtif=xtif+clock()-to;
9757#if 0
9758    if(Overflow_Error == TRUE)
9759    {
9760      for(i=nV-1; i>=0; i--)
9761        (*curr_weight)[i] = (*extra_curr_weight)[i];
9762      delete extra_curr_weight;
9763
9764      newRing = currRing;
9765      goto MSTD_ALT1;
9766    }
9767#endif
9768#ifndef  BUCHBERGER_ALG
9769    if(isNolVector(curr_weight) == 0)
9770    {
9771      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
9772    }
9773    else
9774    {
9775      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
9776    }
9777#endif // BUCHBERGER_ALG
9778
9779    oldRing = currRing;
9780
9781    // define a new ring which ordering is "(a(curr_weight),lp)
9782    if (rParameter(currRing) != NULL)
9783    {
9784      DefRingPar(curr_weight);
9785    }
9786    else
9787    {
9788      rChangeCurrRing(VMrDefault(curr_weight));
9789    }
9790    newRing = currRing;
9791    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
9792
9793    to=clock();
9794    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
9795#ifdef  BUCHBERGER_ALG
9796    M = MstdhomCC(Gomega1);
9797#else
9798    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
9799    delete hilb_func;
9800#endif // BUCHBERGER_ALG
9801    xtstd=xtstd+clock()-to;
9802
9803    // change the ring to oldRing
9804    rChangeCurrRing(oldRing);
9805    M1 =  idrMoveR(M, newRing,currRing);
9806    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
9807
9808    to=clock();
9809    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
9810    F = MLifttwoIdeal(Gomega2, M1, G);
9811    xtlift=xtlift+clock()-to;
9812
9813    idDelete(&M1);
9814    idDelete(&Gomega2);
9815    idDelete(&G);
9816
9817    // change the ring to newRing
9818    rChangeCurrRing(newRing);
9819    F1 = idrMoveR(F, oldRing,currRing);
9820
9821    to=clock();
9822    // reduce the Groebner basis <G> w.r.t. new ring
9823    G = kInterRedCC(F1, NULL);
9824    xtred=xtred+clock()-to;
9825    idDelete(&F1);
9826
9827    if(endwalks == 1)
9828    {
9829      break;
9830    }
9831  NEXT_VECTOR:
9832    to=clock();
9833    // compute a next weight vector
9834    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
9835    xtnw=xtnw+clock()-to;
9836#ifdef PRINT_VECTORS
9837    MivString(curr_weight, target_weight, next_weight);
9838#endif
9839
9840    if(Overflow_Error == TRUE)
9841    {
9842      newRing = currRing;
9843
9844      if (rParameter(currRing) != NULL)
9845      {
9846        DefRingPar(target_weight);
9847      }
9848      else
9849      {
9850        rChangeCurrRing(VMrDefault(target_weight));
9851      }
9852      F1 = idrMoveR(G, newRing,currRing);
9853      G = MstdCC(F1);
9854      idDelete(&F1);
9855      newRing = currRing;
9856      break; //for while
9857    }
9858
9859
9860    /* G is the wanted Groebner basis if next_weight == curr_weight */
9861    if(MivComp(next_weight, ivNull) == 1)
9862    {
9863      newRing = currRing;
9864      delete next_weight;
9865      break; //for while
9866    }
9867
9868    if(MivComp(next_weight, target_weight) == 1)
9869    {
9870      if(tp_deg == 1 || MivSame(target_weight, exivlp) == 0)
9871        endwalks = 1;
9872      else
9873      {
9874       // MSTD_ALT1:
9875#ifdef TIME_TEST
9876        nOverflow_Error = Overflow_Error;
9877#endif
9878        tproc = clock()-xftinput;
9879
9880        //Print("\n//  main routine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk,  tp_deg);
9881
9882        // compute the red. GB of <G> w.r.t. the lex order by the "recursive-modified" perturbation walk alg (1,tp_deg)
9883        G = Mpwalk_MAltwalk1(G, curr_weight, tp_deg);
9884        delete next_weight;
9885        break; // for while
9886      }
9887    }
9888
9889    //NOT Changed, to free memory
9890    for(i=nV-1; i>=0; i--)
9891    {
9892      //(*extra_curr_weight)[i] = (*curr_weight)[i];
9893      (*curr_weight)[i] = (*next_weight)[i];
9894    }
9895    delete next_weight;
9896  }//while
9897
9898  rChangeCurrRing(XXRing);
9899  ideal result = idrMoveR(G, newRing,currRing);
9900  id_Delete(&G, newRing);
9901
9902  delete ivNull;
9903  if(op_deg != 1 )
9904  {
9905    delete curr_weight;
9906  }
9907  delete exivlp;
9908#ifdef TIME_TEST
9909
9910  Print("\n// \"Main procedure\"  took %d steps, %.2f sec. and Overflow_Error(%d)",
9911        nwalk, ((double) tproc)/1000000, nOverflow_Error);
9912
9913  TimeStringFractal(xftinput, tostd, xtif, xtstd,xtextra, xtlift, xtred, xtnw);
9914
9915 // Print("\n// pSetm_Error = (%d)", ErrorCheck());
9916  Print("\n// Overflow_Error? (%d)", Overflow_Error);
9917  Print("\n// Awalk1 took %d steps.\n", nstep);
9918#endif
9919  return(result);
9920}
Note: See TracBrowser for help on using the repository browser.