source: git/Singular/walk.cc @ fd1b1be

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