source: git/Singular/walk.cc @ 48ee38

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