source: git/Singular/walk.cc @ dc4782

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