source: git/Singular/walk.cc @ b075f5

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