source: git/Singular/walk.cc @ 8d7ca0

spielwiese
Last change on this file since 8d7ca0 was 8d7ca0, checked in by Stephan Oberfranz <oberfran@…>, 8 years ago
computation of intermediate weight adapted
  • 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 4 monomials  *
3600 **********************************************************/
3601static int lengthpoly(ideal G)
3602{
3603  int i;
3604  for(i=IDELEMS(G)-1; i>=0; i--)
3605  {
3606    if((G->m[i]!=NULL) /* len >=0 */
3607       && (G->m[i]->next!=NULL) /* len >=1 */
3608       && (G->m[i]->next->next!=NULL) /* len >=2 */
3609       && (G->m[i]->next->next->next!=NULL) /* len >=3 */
3610       && (G->m[i]->next->next->next->next!=NULL) /* len >=4*/ )
3611    {
3612      return 1;
3613    }
3614  }
3615  return 0;
3616}
3617
3618/*****************************************
3619 * return maximal polynomial length of G *
3620 *****************************************/
3621static int maxlengthpoly(ideal G)
3622{
3623  int i,k,length=0;
3624  for(i=IDELEMS(G)-1; i>=0; i--)
3625  {
3626    k = pLength(G->m[i]);
3627    if(k>length)
3628    {
3629      length = k;
3630    }
3631  }
3632  return length;
3633}
3634
3635/*********************************************************
3636 * check whether a polynomial of G has least 2 monomials *
3637**********************************************************/
3638static int islengthpoly2(ideal G)
3639{
3640  int i;
3641  for(i=IDELEMS(G)-1; i>=0; i--)
3642  {
3643    if((G->m[i]!=NULL) /* len >=0 */
3644       && (G->m[i]->next!=NULL) /* len >=1 */
3645       && (G->m[i]->next->next!=NULL)) /* len >=2 */
3646    {
3647      return 1;
3648    }
3649  }
3650  return 0;
3651}
3652
3653
3654
3655/* Implementation of the improved Groebner walk algorithm which is written
3656   by Quoc-Nam Tran (2000).
3657   One perturbs the original target weight vector, only if
3658   the next intermediate weight vector is equal to the current target weight
3659   vector. This must be repeated until the wanted reduced Groebner basis
3660   to reach.
3661   If the numbers of variables is big enough, the representation of the origin
3662   weight vector may be very big. Therefore, it is possible the intermediate
3663   weight vector doesn't stay in the correct Groebner cone.
3664   In this case we have just a reduced Groebner basis of the given ideal
3665   with respect to another monomial order. Then we have to compute
3666   a wanted reduced Groebner basis of it with respect to the given order.
3667   At the following subroutine we use the improved Buchberger algorithm or
3668   the changed perturbation walk algorithm with a decrased degree.
3669 */
3670
3671/***************************************
3672 * return the initial term of an ideal *
3673 ***************************************/
3674static ideal idHeadCC(ideal h)
3675{
3676  int i, nH =IDELEMS(h);
3677
3678  ideal m = idInit(nH,h->rank);
3679
3680  for (i=nH-1;i>=0; i--)
3681  {
3682    if (h->m[i]!=NULL)
3683    {
3684      m->m[i]=pHead(h->m[i]);
3685    }
3686  }
3687  return m;
3688}
3689
3690/**********************************************
3691 * check whether two head-ideals are the same *
3692 **********************************************/
3693static inline int test_G_GB_walk(ideal H0, ideal H1)
3694{
3695  int i, nG = IDELEMS(H0);
3696
3697  if(nG != IDELEMS(H1))
3698  {
3699    return 0;
3700  }
3701  for(i=nG-1; i>=0; i--)
3702  {
3703/*
3704    poly t;
3705    if((t=pSub(pCopy(H0->m[i]), pCopy(H1->m[i]))) != NULL)
3706    {
3707      pDelete(&t);
3708      return 0;
3709    }
3710    pDelete(&t);
3711*/
3712    if(!pEqualPolys(H0->m[i],H1->m[i]))
3713    {
3714      return 0;
3715    }
3716  }
3717  return 1;
3718}
3719
3720//unused
3721/*****************************************************
3722 * find the maximal total degree of polynomials in G *
3723 *****************************************************/
3724/*
3725static int Trandegreebound(ideal G)
3726{
3727  int i, nG = IDELEMS(G);
3728  // int np=1;
3729  int nV = currRing->N;
3730  int degtmp, result = 0;
3731  intvec* ivUnit = Mivdp(nV);
3732
3733  for(i=nG-1; i>=0; i--)
3734  {
3735    // find the maximal total degree of the polynomial G[i]
3736    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
3737    if(degtmp > result)
3738    {
3739      result = degtmp;
3740    }
3741  }
3742  delete ivUnit;
3743  return result;
3744}
3745*/
3746
3747//unused
3748/************************************************************************
3749 * perturb the weight vector iva w.r.t. the ideal G.                    *
3750 *  the monomial order of the current ring is the w_1 weight lex. order *
3751 *  define w := d^(n-1)w_1+ d^(n-2)w_2, ...+ dw_(n-1)+ w_n              *
3752 *  where d := 1 + max{totdeg(g):g in G}*m, or                          *
3753 *  d := (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;                           *
3754 ************************************************************************/
3755#if 0
3756static intvec* TranPertVector(ideal G, intvec* iva)
3757{
3758  BOOLEAN nError = Overflow_Error;
3759  Overflow_Error = FALSE;
3760
3761  int i, j;
3762  // int nG = IDELEMS(G);
3763  int nV = currRing->N;
3764
3765  // define the sequence which expresses the current monomial ordering
3766  // w_1 = iva; w_2 = (1,0,..,0); w_n = (0,...,0,1,0)
3767  intvec* ivMat = MivMatrixOrder(iva);
3768
3769  int  mtmp, m=(*iva)[0];
3770
3771  for(i=ivMat->length(); i>=0; i--)
3772  {
3773    mtmp = (*ivMat)[i];
3774    if(mtmp <0)
3775    {
3776      mtmp = -mtmp;
3777    }
3778    if(mtmp > m)
3779    {
3780      m = mtmp;
3781    }
3782  }
3783
3784  // define the maximal total degree of polynomials of G
3785  mpz_t ndeg;
3786  mpz_init(ndeg);
3787
3788 // 12 Juli 03
3789#ifndef UPPER_BOUND
3790  mpz_set_si(ndeg, Trandegreebound(G)+1);
3791#else
3792  mpz_t ztmp;
3793  mpz_init(ztmp);
3794
3795  mpz_t maxdeg;
3796  mpz_init_set_si(maxdeg, Trandegreebound(G));
3797
3798  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;//Kalkbrenner (1999)
3799  mpz_pow_ui(ztmp, maxdeg, 2);
3800  mpz_mul_ui(ztmp, ztmp, 2);
3801  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3802  mpz_add(ndeg, ztmp, maxdeg);
3803  mpz_mul_ui(ndeg, ndeg, m);
3804
3805  mpz_clear(ztmp);
3806
3807  //PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3808  //Print("\n//         where d = %d, n = %d and bound = %d", maxdeg, nV, ndeg);
3809#endif //UPPER_BOUND
3810
3811#ifdef INVEPS_SMALL_IN_TRAN
3812  if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3813  {
3814    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3815  }
3816 //PrintS("\n// choose the \"small\" inverse epsilon:");
3817 //mpz_out_str(stdout, 10, ndeg);
3818#endif
3819  mpz_t deg_tmp;
3820  mpz_init_set(deg_tmp, ndeg);
3821
3822  mpz_t *ivres=( mpz_t *) omAlloc(nV*sizeof(mpz_t));
3823  mpz_init_set_si(ivres[nV-1],1);
3824
3825  for(i=nV-2; i>=0; i--)
3826  {
3827    mpz_init_set(ivres[i], deg_tmp);
3828    mpz_mul(deg_tmp, deg_tmp, ndeg);
3829  }
3830
3831  mpz_t *ivtmp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3832  for(i=0; i<nV; i++)
3833  {
3834    mpz_init(ivtmp[i]);
3835  }
3836  mpz_t sing_int;
3837  mpz_init_set_ui(sing_int,  2147483647);
3838
3839  intvec* repr_vector = new intvec(nV);
3840
3841  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
3842  for(i=0; i<nV; i++)
3843  {
3844    for(j=0; j<nV; j++)
3845    {
3846      if( (*ivMat)[i*nV+j] >= 0 )
3847      {
3848        mpz_mul_ui(ivres[i], ivres[i], (*ivMat)[i*nV+j]);
3849      }
3850      else
3851      {
3852        mpz_mul_ui(ivres[i], ivres[i], -(*ivMat)[i*nV+j]);
3853        mpz_neg(ivres[i], ivres[i]);
3854      }
3855      mpz_add(ivtmp[j], ivtmp[j], ivres[i]);
3856    }
3857  }
3858  delete ivMat;
3859
3860  int ntrue=0;
3861  for(i=0; i<nV; i++)
3862  {
3863    (*repr_vector)[i] = mpz_get_si(ivtmp[i]);
3864    if(mpz_cmp(ivtmp[i], sing_int)>=0)
3865    {
3866      ntrue++;
3867      if(Overflow_Error == FALSE)
3868      {
3869        Overflow_Error = TRUE;
3870
3871        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3872        mpz_out_str( stdout, 10, ivtmp[i]);
3873        PrintS(" is greater than 2147483647 (max. integer representation)");
3874        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3875      }
3876    }
3877  }
3878  if(Overflow_Error == TRUE)
3879  {
3880    ivString(repr_vector, "repvector");
3881    Print("\n// %d element(s) of it are overflow!!", ntrue);
3882  }
3883
3884  if(Overflow_Error == FALSE)
3885    Overflow_Error=nError;
3886
3887  omFree(ivres);
3888  omFree(ivtmp);
3889
3890  mpz_clear(sing_int);
3891  mpz_clear(deg_tmp);
3892  mpz_clear(ndeg);
3893
3894  return repr_vector;
3895}
3896#endif
3897
3898//unused
3899#if 0
3900static intvec* TranPertVector_lp(ideal G)
3901{
3902  BOOLEAN nError = Overflow_Error;
3903  Overflow_Error = FALSE;
3904  // int j, nG = IDELEMS(G);
3905  int i;
3906  int nV = currRing->N;
3907
3908  // define the maximal total degree of polynomials of G
3909  mpz_t ndeg;
3910  mpz_init(ndeg);
3911
3912 // 12 Juli 03
3913#ifndef UPPER_BOUND
3914  mpz_set_si(ndeg, Trandegreebound(G)+1);
3915#else
3916  mpz_t ztmp;
3917  mpz_init(ztmp);
3918
3919  mpz_t maxdeg;
3920  mpz_init_set_si(maxdeg, Trandegreebound(G));
3921
3922  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg);//Kalkbrenner (1999)
3923  mpz_pow_ui(ztmp, maxdeg, 2);
3924  mpz_mul_ui(ztmp, ztmp, 2);
3925  mpz_mul_ui(maxdeg, maxdeg, nV+1);
3926  mpz_add(ndeg, ztmp, maxdeg);
3927  // PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
3928  // Print("\n//         where d = %d, n = %d and bound = %d",
3929  // mpz_get_si(maxdeg), nV, mpz_get_si(ndeg));
3930
3931 mpz_clear(ztmp);
3932
3933#endif
3934
3935#ifdef INVEPS_SMALL_IN_TRAN
3936 if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
3937    mpz_cdiv_q_ui(ndeg, ndeg, nV);
3938
3939 //PrintS("\n// choose the \"small\" inverse epsilon:");
3940 // mpz_out_str(stdout, 10, ndeg);
3941#endif
3942
3943  mpz_t deg_tmp;
3944  mpz_init_set(deg_tmp, ndeg);
3945
3946  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
3947  mpz_init_set_si(ivres[nV-1], 1);
3948
3949  for(i=nV-2; i>=0; i--)
3950  {
3951    mpz_init_set(ivres[i], deg_tmp);
3952    mpz_mul(deg_tmp, deg_tmp, ndeg);
3953  }
3954
3955  mpz_t sing_int;
3956  mpz_init_set_ui(sing_int,  2147483647);
3957
3958  intvec* repr_vector = new intvec(nV);
3959  int ntrue=0;
3960  for(i=0; i<nV; i++)
3961  {
3962    (*repr_vector)[i] = mpz_get_si(ivres[i]);
3963
3964    if(mpz_cmp(ivres[i], sing_int)>=0)
3965    {
3966      ntrue++;
3967      if(Overflow_Error == FALSE)
3968      {
3969        Overflow_Error = TRUE;
3970        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
3971        mpz_out_str( stdout, 10, ivres[i]);
3972        PrintS(" is greater than 2147483647 (max. integer representation)");
3973        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
3974      }
3975    }
3976  }
3977  if(Overflow_Error == TRUE)
3978  {
3979    ivString(repr_vector, "repvector");
3980    Print("\n// %d element(s) of it are overflow!!", ntrue);
3981  }
3982  if(Overflow_Error == FALSE)
3983    Overflow_Error = nError;
3984
3985  omFree(ivres);
3986
3987  mpz_clear(ndeg);
3988  mpz_clear(sing_int);
3989
3990  return repr_vector;
3991}
3992#endif
3993
3994//unused
3995#if 0
3996static intvec* RepresentationMatrix_Dp(ideal G, intvec* M)
3997{
3998  BOOLEAN nError = Overflow_Error;
3999  Overflow_Error = FALSE;
4000
4001  int i, j;
4002  int nV = currRing->N;
4003
4004  intvec* ivUnit = Mivdp(nV);
4005  int degtmp, maxdeg = 0;
4006
4007  for(i=IDELEMS(G)-1; i>=0; i--)
4008  {
4009    // find the maximal total degree of the polynomial G[i]
4010    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
4011    if(degtmp > maxdeg)
4012      maxdeg = degtmp;
4013  }
4014
4015  mpz_t ztmp;
4016  mpz_init_set_si(ztmp, maxdeg);
4017  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
4018  mpz_init_set_si(ivres[nV-1], 1); // (*ivres)[nV-1] = 1;
4019
4020  for(i=nV-2; i>=0; i--)
4021  {
4022    mpz_init_set(ivres[i], ztmp); //(*ivres)[i] = ztmp;
4023    mpz_mul_ui(ztmp, ztmp, maxdeg); //ztmp *=maxdeg;
4024  }
4025
4026  mpz_t *ivtmp=(mpz_t*)omAlloc(nV*sizeof(mpz_t));
4027  for(i=0; i<nV; i++)
4028    mpz_init(ivtmp[i]);
4029
4030  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
4031  for(i=0; i<nV; i++)
4032    for(j=0; j<nV; j++)
4033    {
4034      if((*M)[i*nV+j] < 0)
4035      {
4036        mpz_mul_ui(ztmp, ivres[i], -(*M)[i*nV+j]);
4037        mpz_neg(ztmp, ztmp);
4038      }
4039      else
4040        mpz_mul_ui(ztmp, ivres[i], (*M)[i*nV+j]);
4041
4042      mpz_add(ivtmp[j], ivtmp[j], ztmp);
4043    }
4044  delete ivres;
4045  mpz_t sing_int;
4046  mpz_init_set_ui(sing_int,  2147483647);
4047
4048  int ntrue=0;
4049  intvec* repvector = new intvec(nV);
4050  for(i=0; i<nV; i++)
4051  {
4052    (*repvector)[i] = mpz_get_si(ivtmp[i]);
4053    if(mpz_cmp(ivtmp[i], sing_int)>0)
4054    {
4055      ntrue++;
4056      if(Overflow_Error == FALSE)
4057      {
4058        Overflow_Error = TRUE;
4059        PrintS("\n// ** OVERFLOW in \"Repr.Matrix\": ");
4060        mpz_out_str( stdout, 10, ivtmp[i]);
4061        PrintS(" is greater than 2147483647 (max. integer representation)");
4062        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repvector)[i]);
4063      }
4064    }
4065  }
4066  if(Overflow_Error == TRUE)
4067  {
4068    ivString(repvector, "repvector");
4069    Print("\n// %d element(s) of it are overflow!!", ntrue);
4070  }
4071
4072  if(Overflow_Error == FALSE)
4073    Overflow_Error = nError;
4074
4075  mpz_clear(sing_int);
4076  mpz_clear(ztmp);
4077  omFree(ivtmp);
4078  omFree(ivres);
4079  return repvector;
4080}
4081#endif
4082
4083/*****************************************************************************
4084 * The following subroutine is the implementation of our first improved      *
4085 * Groebner walk algorithm, i.e. the first altervative algorithm.            *
4086 * First we use the Grobner walk algorithm and then we call the changed      *
4087 * perturbation walk algorithm with decreased degree, if an intermediate     *
4088 * weight vector is equal to the current target weight vector.               *
4089 * This call will be only repeated until we get the wanted reduced Groebner  *
4090 * basis or n times, where n is the numbers of variables.                    *
4091 *****************************************************************************/
4092
4093// npwinc = 0, if curr_weight doesn't stay in the correct Groebner cone
4094static ideal Rec_LastGB(ideal G, intvec* curr_weight,
4095                        intvec* orig_target_weight, int tp_deg, int npwinc)
4096{
4097  BOOLEAN nError = Overflow_Error;
4098  Overflow_Error = FALSE;
4099  // BOOLEAN nOverflow_Error = FALSE;
4100
4101  clock_t tproc=0;
4102  clock_t tinput = clock();
4103
4104  int i,  nV = currRing->N;
4105  int nwalk=0, endwalks=0, nnwinC=1;
4106  int nlast = 0;
4107  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4108  ring newRing, oldRing, TargetRing;
4109  intvec* iv_M_lp;
4110  intvec* target_weight;
4111  intvec* ivNull = new intvec(nV); //define (0,...,0)
4112  ring EXXRing = currRing;
4113  //int NEG=0; //19 juni 03
4114  intvec* next_weight;
4115#ifndef  BUCHBERGER_ALG
4116  //08 Juli 03
4117  intvec* hilb_func;
4118#endif
4119  // to avoid (1,0,...,0) as the target vector
4120  intvec* last_omega = new intvec(nV);
4121  for(i=nV-1; i>0; i--)
4122    (*last_omega)[i] = 1;
4123  (*last_omega)[0] = 10000;
4124
4125  BOOLEAN isGB = FALSE;
4126
4127  // compute a pertubed weight vector of the target weight vector
4128  if(tp_deg > 1 && tp_deg <= nV)
4129  {
4130    ideal H0 = idHeadCC(G);
4131
4132    if (rParameter (currRing) != NULL)
4133    {
4134      DefRingParlp();
4135    }
4136    else
4137    {
4138      VMrDefaultlp();
4139    }
4140    TargetRing = currRing;
4141    ssG = idrMoveR(G,EXXRing,currRing);
4142
4143    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4144    ideal H1 = idHeadCC(ssG);
4145
4146    // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
4147    if(test_G_GB_walk(H0_tmp,H1)==1)
4148    {
4149      idDelete(&H0_tmp);
4150      idDelete(&H1);
4151      G = ssG;
4152      ssG = NULL;
4153      newRing = currRing;
4154      delete ivNull;
4155
4156      if(npwinc != 0)
4157      {
4158        goto LastGB_Finish;
4159      }
4160      else
4161      {
4162        isGB = TRUE;
4163        goto KSTD_Finish;
4164      }
4165    }
4166    idDelete(&H0_tmp);
4167    idDelete(&H1);
4168
4169    iv_M_lp = MivMatrixOrderlp(nV);
4170    target_weight  = MPertVectors(ssG, iv_M_lp, tp_deg);
4171    delete iv_M_lp;
4172    //PrintS("\n// Input is not GB!!");
4173    rChangeCurrRing(EXXRing);
4174    G = idrMoveR(ssG, TargetRing,currRing);
4175
4176    if(Overflow_Error == TRUE)
4177    {
4178      //nOverflow_Error = Overflow_Error;
4179      //NEG = 1;
4180      newRing = currRing;
4181      goto JUNI_STD;
4182    }
4183  }
4184
4185  while(1)
4186  {
4187    nwalk ++;
4188    nstep++;
4189
4190    if(nwalk==1)
4191    {
4192      goto FIRST_STEP;
4193    }
4194    to=clock();
4195    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4196    Gomega = MwalkInitialForm(G, curr_weight);
4197    xtif=xtif+clock()-to;
4198
4199#ifndef  BUCHBERGER_ALG
4200    if(isNolVector(curr_weight) == 0)
4201    {
4202      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4203    }
4204    else
4205    {
4206      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4207    }
4208#endif // BUCHBERGER_ALG
4209
4210    oldRing = currRing;
4211
4212    // defiNe a new ring that its ordering is "(a(curr_weight),lp)
4213    if (rParameter(currRing) != NULL)
4214    {
4215      DefRingPar(curr_weight);
4216    }
4217    else
4218    {
4219      rChangeCurrRing(VMrDefault(curr_weight));
4220    }
4221    newRing = currRing;
4222    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4223    to=clock();
4224    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4225#ifdef  BUCHBERGER_ALG
4226    M = MstdhomCC(Gomega1);
4227#else
4228    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4229    delete hilb_func;
4230#endif // BUCHBERGER_ALG
4231    xtstd=xtstd+clock()-to;
4232    // change the ring to oldRing
4233    rChangeCurrRing(oldRing);
4234    M1 =  idrMoveR(M, newRing,currRing);
4235    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4236
4237     to=clock();
4238    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
4239    F = MLifttwoIdeal(Gomega2, M1, G);
4240    xtlift=xtlift+clock()-to;
4241    idDelete(&M1);
4242    idDelete(&Gomega2);
4243    idDelete(&G);
4244
4245    // change the ring to newRing
4246    rChangeCurrRing(newRing);
4247    F1 = idrMoveR(F, oldRing,currRing);
4248
4249    to=clock();
4250    // reduce the Groebner basis <G> w.r.t. new ring
4251    G = kInterRedCC(F1, NULL);
4252    xtred=xtred+clock()-to;
4253    idDelete(&F1);
4254
4255    if(endwalks == 1)
4256    {
4257      break;
4258    }
4259  FIRST_STEP:
4260    to=clock();
4261    Overflow_Error = FALSE;
4262    // compute a next weight vector
4263    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4264    xtnw=xtnw+clock()-to;
4265#ifdef PRINT_VECTORS
4266    MivString(curr_weight, target_weight, next_weight);
4267#endif
4268
4269    if(Overflow_Error == TRUE)
4270    {
4271      //PrintS("\n// ** The next vector does NOT stay in Cone!!\n");
4272#ifdef TEST_OVERFLOW
4273      goto  LastGB_Finish;
4274#endif
4275
4276      nnwinC = 0;
4277      if(tp_deg == nV)
4278      {
4279        nlast = 1;
4280      }
4281      delete next_weight;
4282      break;
4283    }
4284
4285    if(MivComp(next_weight, ivNull) == 1)
4286    {
4287      //newRing = currRing;
4288      delete next_weight;
4289      break;
4290    }
4291
4292    if(MivComp(next_weight, target_weight) == 1)
4293    {
4294      if(tp_deg == nV)
4295      {
4296        endwalks = 1;
4297      }
4298      else
4299      {
4300        // REC_LAST_GB_ALT2:
4301        //nOverflow_Error = Overflow_Error;
4302        tproc=tproc+clock()-tinput;
4303       
4304        Print("\n// takes %d steps and calls \"Rec_LastGB\" (%d):",
4305        nwalk, tp_deg+1);
4306       
4307        G = Rec_LastGB(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4308        newRing = currRing;
4309        delete next_weight;
4310        break;
4311      }
4312    }
4313
4314    for(i=nV-1; i>=0; i--)
4315    {
4316      (*curr_weight)[i] = (*next_weight)[i];
4317    }
4318    delete next_weight;
4319  }//while
4320
4321  delete ivNull;
4322
4323  if(tp_deg != nV)
4324  {
4325    newRing = currRing;
4326
4327    if (rParameter(currRing) != NULL)
4328    {
4329      DefRingParlp();
4330    }
4331    else
4332    {
4333      VMrDefaultlp();
4334    }
4335    F1 = idrMoveR(G, newRing,currRing);
4336
4337    if(nnwinC == 0 || test_w_in_ConeCC(F1, target_weight) != 1 )
4338    {
4339      // nOverflow_Error = Overflow_Error;
4340      Print("\n//  takes %d steps and calls \"Rec_LastGB (%d):", tp_deg+1);
4341      tproc=tproc+clock()-tinput;
4342      F1 = Rec_LastGB(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
4343    }
4344    delete target_weight;
4345
4346    TargetRing = currRing;
4347    rChangeCurrRing(EXXRing);
4348    result = idrMoveR(F1, TargetRing,currRing);
4349  }
4350  else
4351  {
4352    if(nlast == 1)
4353    {
4354      JUNI_STD:
4355
4356      newRing = currRing;
4357      if (rParameter(currRing) != NULL)
4358      {
4359        DefRingParlp();
4360      }
4361      else
4362      {
4363        VMrDefaultlp();
4364      }
4365      KSTD_Finish:
4366      if(isGB == FALSE)
4367      {
4368        F1 = idrMoveR(G, newRing,currRing);
4369      }
4370      else
4371      {
4372        F1 = G;
4373      }
4374      to=clock();
4375      // Print("\n// apply the Buchberger's alg in ring = %s",rString(currRing));
4376      // idElements(F1, "F1");
4377      G = MstdCC(F1);
4378      xtextra=xtextra+clock()-to;
4379
4380
4381      idDelete(&F1);
4382      newRing = currRing;
4383    }
4384
4385    LastGB_Finish:
4386    rChangeCurrRing(EXXRing);
4387    result = idrMoveR(G, newRing,currRing);
4388  }
4389
4390  if(Overflow_Error == FALSE)
4391    {
4392    Overflow_Error=nError;
4393    }
4394#ifdef TIME_TEST
4395   Print("\n// \"Rec_LastGB\" (%d) took %d steps and %.2f sec.Overflow_Error (%d)", tp_deg, nwalk, ((double) tproc)/1000000, nOverflow_Error);
4396#endif
4397  return(result);
4398}
4399
4400/* The following subroutine is the implementation of our second improved
4401   Groebner walk algorithm, i.e. the second altervative algorithm.
4402   First we use the Grobner walk algorithm and then we call the changed
4403   perturbation walk algorithm with increased degree, if an intermediate
4404   weight vector is equal to the current target weight vector.
4405   This call will be only repeated until we get the wanted reduced Groebner
4406   basis or n times, where n is the numbers of variables.
4407*/
4408
4409/******************************
4410 * walk + recursive LastGB    *
4411 ******************************/
4412ideal MAltwalk2(ideal Go, intvec* curr_weight, intvec* target_weight)
4413{
4414  Set_Error(FALSE);
4415  Overflow_Error = FALSE;
4416  //BOOLEAN nOverflow_Error = FALSE;
4417  //Print("// pSetm_Error = (%d)", ErrorCheck());
4418#ifdef TIME_TEST
4419  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
4420  xftinput = clock();
4421  clock_t tostd, tproc;
4422#endif
4423  nstep = 0;
4424  int i, nV = currRing->N;
4425  int nwalk=0, endwalks=0;
4426  // int nhilb = 1;
4427  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
4428  //ideal  G1;
4429  //ring endRing;
4430  ring newRing, oldRing;
4431  intvec* ivNull = new intvec(nV);
4432  intvec* next_weight;
4433  //intvec* extra_curr_weight = new intvec(nV);
4434  //intvec* hilb_func;
4435  intvec* exivlp = Mivlp(nV);
4436  ring XXRing = currRing;
4437
4438  //Print("\n// ring r_input = %s;", rString(currRing));
4439#ifdef TIME_TEST
4440  to = clock();
4441#endif
4442  /* compute the reduced Groebner basis of the given ideal w.r.t.
4443     a "fast" monomial order, e.g. degree reverse lex. order (dp) */
4444  G = MstdCC(Go);
4445#ifdef TIME_TEST
4446  tostd=clock()-to;
4447
4448  Print("\n// Computation of the first std took = %.2f sec",
4449        ((double) tostd)/1000000);
4450#endif
4451  if(currRing->order[0] == ringorder_a)
4452  {
4453    goto NEXT_VECTOR;
4454  }
4455  while(1)
4456  {
4457    nwalk ++;
4458    nstep ++;
4459#ifdef TIME_TEST
4460    to = clock();
4461#endif
4462    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
4463    Gomega = MwalkInitialForm(G, curr_weight);
4464#ifdef TIME_TEST
4465    xtif=xtif+clock()-to;
4466#endif
4467/*
4468    if(Overflow_Error == TRUE)
4469    {
4470      for(i=nV-1; i>=0; i--)
4471        (*curr_weight)[i] = (*extra_curr_weight)[i];
4472      delete extra_curr_weight;
4473      goto LAST_GB_ALT2;
4474    }
4475*/
4476    oldRing = currRing;
4477
4478    /* define a new ring that its ordering is "(a(curr_weight),lp) */
4479    if (rParameter(currRing) != NULL)
4480    {
4481      DefRingPar(curr_weight);
4482    }
4483    else
4484    {
4485      rChangeCurrRing(VMrDefault(curr_weight));
4486    }
4487    newRing = currRing;
4488    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4489#ifdef TIME_TEST
4490    to = clock();
4491#endif
4492    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
4493    M = MstdhomCC(Gomega1);
4494#ifdef TIME_TEST
4495    xtstd=xtstd+clock()-to;
4496#endif
4497    /* change the ring to oldRing */
4498    rChangeCurrRing(oldRing);
4499    M1 =  idrMoveR(M, newRing,currRing);
4500    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4501#ifdef TIME_TEST
4502    to = clock();
4503#endif
4504    /* compute the reduced Groebner basis of <G> w.r.t. "newRing"
4505       by the liftig process */
4506    F = MLifttwoIdeal(Gomega2, M1, G);
4507#ifdef TIME_TEST
4508    xtlift=xtlift+clock()-to;
4509#endif
4510    idDelete(&M1);
4511    idDelete(&Gomega2);
4512    idDelete(&G);
4513
4514    /* change the ring to newRing */
4515    rChangeCurrRing(newRing);
4516    F1 = idrMoveR(F, oldRing,currRing);
4517#ifdef TIME_TEST
4518    to = clock();
4519#endif
4520    /* reduce the Groebner basis <G> w.r.t. newRing */
4521    G = kInterRedCC(F1, NULL);
4522#ifdef TIME_TEST
4523    xtred=xtred+clock()-to;
4524#endif
4525    idDelete(&F1);
4526
4527    if(endwalks == 1)
4528      break;
4529
4530  NEXT_VECTOR:
4531#ifdef TIME_TEST
4532    to = clock();
4533#endif
4534    /* compute a next weight vector */
4535    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
4536#ifdef TIME_TEST
4537    xtnw=xtnw+clock()-to;
4538#endif
4539#ifdef PRINT_VECTORS
4540    MivString(curr_weight, target_weight, next_weight);
4541#endif
4542
4543    if(Overflow_Error == TRUE)
4544    {
4545      /*
4546        ivString(next_weight, "omega");
4547        PrintS("\n// ** The weight vector does NOT stay in Cone!!\n");
4548      */
4549#ifdef TEST_OVERFLOW
4550      goto  TEST_OVERFLOW_OI;
4551#endif
4552
4553      newRing = currRing;
4554      if (rParameter(currRing) != NULL)
4555      {
4556        DefRingPar(target_weight);
4557      }
4558      else
4559      {
4560        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
4561      }
4562      F1 = idrMoveR(G, newRing,currRing);
4563      G = MstdCC(F1);
4564      idDelete(&F1);
4565      newRing = currRing;
4566      break;
4567    }
4568
4569    if(MivComp(next_weight, ivNull) == 1)
4570    {
4571      newRing = currRing;
4572      delete next_weight;
4573      break;
4574    }
4575
4576    if(MivComp(next_weight, target_weight) == 1)
4577    {
4578      if(MivSame(target_weight, exivlp)==1)
4579      {
4580     // LAST_GB_ALT2:
4581        //nOverflow_Error = Overflow_Error;
4582#ifdef TIME_TEST
4583        tproc = clock()-xftinput;
4584#endif
4585        //Print("\n// takes %d steps and calls the recursion of level 2:",  nwalk);
4586        /* call the changed perturbation walk algorithm with degree 2 */
4587        G = Rec_LastGB(G, curr_weight, target_weight, 2,1);
4588        newRing = currRing;
4589        delete next_weight;
4590        break;
4591      }
4592      endwalks = 1;
4593    }
4594
4595    for(i=nV-1; i>=0; i--)
4596    {
4597      //(*extra_curr_weight)[i] = (*curr_weight)[i];
4598      (*curr_weight)[i] = (*next_weight)[i];
4599    }
4600    delete next_weight;
4601  }
4602#ifdef TEST_OVERFLOW
4603 TEST_OVERFLOW_OI:
4604#endif
4605  rChangeCurrRing(XXRing);
4606  G = idrMoveR(G, newRing,currRing);
4607  delete ivNull;
4608  delete exivlp;
4609
4610#ifdef TIME_TEST
4611  Print("\n// \"Main procedure\"  took %d steps dnd %.2f sec. Overflow_Error (%d)",
4612        nwalk, ((double) tproc)/1000000, nOverflow_Error);
4613
4614  TimeStringFractal(xftinput, tostd, xtif, xtstd, xtextra,xtlift, xtred,xtnw);
4615
4616  Print("\n// pSetm_Error = (%d)", ErrorCheck());
4617  //Print("\n// Overflow_Error? (%d)", nOverflow_Error);
4618  Print("\n// Awalk2 took %d steps!!", nstep);
4619#endif
4620
4621  return(G);
4622}
4623
4624
4625/**************************************
4626 * perturb the matrix order of  "lex" *
4627 **************************************/
4628static intvec* NewVectorlp(ideal I)
4629{
4630  int nV = currRing->N;
4631  intvec* iv_wlp =  MivMatrixOrderlp(nV);
4632  intvec* result = Mfpertvector(I, iv_wlp);
4633  delete iv_wlp;
4634  return result;
4635}
4636
4637int ngleich;
4638intvec* Xsigma;
4639intvec* Xtau;
4640int xn;
4641intvec* Xivinput;
4642intvec* Xivlp;
4643
4644
4645/********************************
4646 * compute a next weight vector *
4647 ********************************/
4648static intvec* MWalkRandomNextWeight(ideal G, intvec* orig_M, intvec* target_weight,
4649       int weight_rad, int pert_deg)
4650{
4651  assume(currRing != NULL && orig_M != NULL &&
4652         target_weight != NULL && G->m[0] != NULL);
4653
4654  //BOOLEAN nError = Overflow_Error;
4655  Overflow_Error = FALSE;
4656
4657  BOOLEAN found_random_weight = FALSE;
4658  int i,nV = currRing->N;
4659  intvec* curr_weight = new intvec(nV);
4660
4661  for(i=0; i<nV; i++)
4662  {
4663    (*curr_weight)[i] = (*orig_M)[i];
4664  }
4665
4666  int k=0,weight_norm;
4667  intvec* next_weight;
4668  intvec* next_weight1 = MkInterRedNextWeight(curr_weight,target_weight,G);
4669  intvec* next_weight2 = new intvec(nV);
4670  intvec* next_weight22 = new intvec(nV);
4671  intvec* result = new intvec(nV);
4672  intvec* curr_weight1;
4673  ideal G_test, G_test1, G_test2;
4674
4675  //try to find a random next weight vector "next_weight2"
4676  if(weight_rad > 0){ while(k<10)
4677  {
4678    weight_norm = 0;
4679    while(weight_norm == 0)
4680    {
4681
4682      for(i=0; i<nV; i++)
4683      {
4684        (*next_weight2)[i] = rand() % 60000 - 30000;
4685        weight_norm = weight_norm + (*next_weight2)[i]*(*next_weight2)[i];
4686      }
4687      weight_norm = 1 + floor(sqrt(weight_norm));
4688    }
4689
4690    for(i=0; i<nV; i++)
4691    {
4692      if((*next_weight2)[i] < 0)
4693      {
4694        (*next_weight2)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4695      }
4696      else
4697      {
4698        (*next_weight2)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight2)[i]/weight_norm);
4699      }
4700    }
4701   
4702    if(test_w_in_ConeCC(G,next_weight2) == 1)
4703    {
4704      if(maxlengthpoly(MwalkInitialForm(G,next_weight2))<2)
4705      {
4706        next_weight2 = MkInterRedNextWeight(next_weight2,target_weight,G);
4707      }
4708/*
4709      if(MivAbsMax(next_weight2)>1147483647)
4710      {
4711        for(i=0; i<nV; i++)
4712        {
4713          (*next_weight22)[i] = (*next_weight2)[i];
4714        }
4715        i = 0;
4716        // reduce the size of the maximal entry of the vector
4717        while(test_w_in_ConeCC(G,next_weight22) == 1)
4718        {
4719          (*next_weight2)[i] = (*next_weight22)[i];
4720          i = MivAbsMaxArg(next_weight22);
4721          (*next_weight22)[i] = floor(0.1*(*next_weight22)[i] + 0.5);
4722        }
4723        delete next_weight22;
4724      }
4725*/
4726      G_test2 = MwalkInitialForm(G, next_weight2);
4727      found_random_weight = TRUE;
4728      break;
4729    }
4730    k++;
4731  }}
4732Print("\n MWalkRandomNextWeight: compute perurbation...\n");
4733  // compute "perturbed" next weight vector
4734  if(pert_deg > 1)
4735  {
4736    curr_weight1 = MPertVectors(G,orig_M,pert_deg);
4737    next_weight = MkInterRedNextWeight(curr_weight1,target_weight,G);
4738    delete curr_weight1;
4739  }
4740  else
4741  {
4742    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4743  }
4744  if(MivSame(curr_weight,next_weight)==1 || Overflow_Error == TRUE)
4745  { 
4746    Overflow_Error = FALSE;
4747    delete next_weight;
4748    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
4749  }
4750  G_test=MwalkInitialForm(G,next_weight);
4751  G_test1=MwalkInitialForm(G,next_weight1);
4752Print("\n MWalkRandomNextWeight: finished...\n");
4753  // compare next weights
4754  if(Overflow_Error == FALSE)
4755  {
4756    if(found_random_weight == TRUE)
4757    {
4758    // random next weight vector found
4759      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4760      {
4761        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test1))
4762        {
4763          for(i=0; i<nV; i++)
4764          {
4765            (*result)[i] = (*next_weight2)[i];
4766          }
4767        }
4768        else
4769        {
4770          for(i=0; i<nV; i++)
4771          {
4772            (*result)[i] = (*next_weight1)[i];
4773          }
4774        }   
4775      }
4776      else
4777      {
4778        if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4779        {
4780          for(i=0; i<nV; i++)
4781          {
4782            (*result)[i] = (*next_weight2)[i];
4783          }
4784        }
4785        else
4786        {
4787          for(i=0; i<nV; i++)
4788          {
4789            (*result)[i] = (*next_weight)[i];
4790          }
4791        }
4792      }
4793    }
4794    else
4795    {
4796      // no random next weight vector found
4797      if(G_test1->m[0] != NULL && maxlengthpoly(G_test1) < maxlengthpoly(G_test))
4798      {
4799       for(i=0; i<nV; i++)
4800        {
4801          (*result)[i] = (*next_weight1)[i];
4802        }
4803      }
4804      else
4805      {
4806        for(i=0; i<nV; i++)
4807        {
4808          (*result)[i] = (*next_weight)[i];
4809        }
4810      }
4811    }
4812  }
4813  else
4814  {
4815    Overflow_Error = FALSE;
4816    if(found_random_weight == TRUE)
4817    {
4818      if(G_test2->m[0] != NULL && maxlengthpoly(G_test2) < maxlengthpoly(G_test))
4819      {
4820        for(i=1; i<nV; i++)
4821        {
4822          (*result)[i] = (*next_weight2)[i];
4823        }
4824      }
4825      else
4826      {
4827        for(i=0; i<nV; i++)
4828        {
4829          (*result)[i] = (*next_weight)[i];
4830        }
4831      }
4832    }
4833    else
4834    {
4835      for(i=0; i<nV; i++)
4836      {
4837        (*result)[i] = (*next_weight)[i];
4838      }
4839    }
4840  }
4841 // delete curr_weight1;
4842  delete next_weight;
4843  delete next_weight2;
4844  idDelete(&G_test);
4845  idDelete(&G_test1);
4846  if(found_random_weight == TRUE)
4847  {
4848    idDelete(&G_test2);
4849  }
4850  if(test_w_in_ConeCC(G, result) == 1 && MivSame(curr_weight,result)==0)
4851  { 
4852    delete curr_weight;
4853    delete next_weight1;
4854    return result;
4855  }
4856  else
4857  {
4858    delete curr_weight;
4859    delete result;
4860    return next_weight1;
4861  }
4862}
4863
4864
4865/***************************************************************************
4866 * The procedur REC_GB_Mwalk computes a GB for <G> w.r.t. the weight order *
4867 * otw, where G is a reduced GB w.r.t. the weight order cw.                *
4868 * The new procedure Mwalk calls REC_GB.                                   *
4869 ***************************************************************************/
4870static ideal REC_GB_Mwalk(ideal G, intvec* curr_weight, intvec* orig_target_weight,
4871                          int tp_deg, int npwinc)
4872{
4873  BOOLEAN nError = Overflow_Error;
4874  Overflow_Error = FALSE;
4875
4876  int i,  nV = currRing->N;
4877  int nwalk=0, endwalks=0, nnwinC=1, nlast = 0;
4878  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
4879  ring newRing, oldRing, TargetRing;
4880  intvec* target_weight;
4881  intvec* ivNull = new intvec(nV);
4882#ifndef BUCHBERGER_ALG
4883  intvec* hilb_func;
4884  // to avoid (1,0,...,0) as the target vector
4885  intvec* last_omega = new intvec(nV);
4886  for(i=nV-1; i>0; i--)
4887  {
4888    (*last_omega)[i] = 1;
4889  }
4890  (*last_omega)[0] = 10000;
4891#endif
4892  BOOLEAN isGB = FALSE;
4893
4894  ring EXXRing = currRing;
4895
4896  // compute a pertubed weight vector of the target weight vector
4897  if(tp_deg > 1 && tp_deg <= nV)
4898  {
4899    ideal H0 = idHeadCC(G);
4900    if (rParameter(currRing) != NULL)
4901    {
4902      DefRingPar(orig_target_weight);
4903    }
4904    else
4905    {
4906      rChangeCurrRing(VMrDefault(orig_target_weight));
4907    }
4908    TargetRing = currRing;
4909    ssG = idrMoveR(G,EXXRing,currRing);
4910
4911    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
4912    ideal H1 = idHeadCC(ssG);
4913    id_Delete(&H0,EXXRing);
4914
4915    if(test_G_GB_walk(H0_tmp,H1)==1)
4916    {
4917      //Print("\n//REC_GB_Mwalk: input in %d-th recursive is a GB!\n",tp_deg);
4918      idDelete(&H0_tmp);
4919      idDelete(&H1);
4920      G = ssG;
4921      ssG = NULL;
4922      newRing = currRing;
4923      delete ivNull;
4924      if(npwinc == 0)
4925      {
4926        isGB = TRUE;
4927        goto KSTD_Finish;
4928      }
4929      else
4930      {
4931        goto LastGB_Finish;
4932      }
4933    }
4934    idDelete(&H0_tmp);
4935    idDelete(&H1);
4936
4937    target_weight  = MPertVectors(ssG, MivMatrixOrder(orig_target_weight), tp_deg);
4938
4939    rChangeCurrRing(EXXRing);
4940    G = idrMoveR(ssG, TargetRing,currRing);
4941  }
4942
4943  while(1)
4944  {
4945    nwalk ++;
4946    nstep++;
4947    if(nwalk == 1)
4948    {
4949      goto NEXT_STEP;
4950    }
4951    //Print("\n//REC_GB_Mwalk: Entering the %d-th step in the %d-th recursive:\n",nwalk,tp_deg);
4952    to = clock();
4953    // compute an initial form ideal of <G> w.r.t. "curr_vector"
4954    Gomega = MwalkInitialForm(G, curr_weight);
4955    xtif = xtif + clock()-to;
4956
4957#ifndef  BUCHBERGER_ALG
4958    if(isNolVector(curr_weight) == 0)
4959    {
4960      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
4961    }
4962    else
4963    {
4964      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
4965    }
4966#endif
4967
4968    oldRing = currRing;
4969
4970    // define a new ring with ordering "(a(curr_weight),lp)
4971    if (rParameter(currRing) != NULL)
4972    {
4973      DefRingPar(curr_weight);
4974    }
4975    else
4976    {
4977      rChangeCurrRing(VMrDefault(curr_weight));
4978    }
4979    newRing = currRing;
4980    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
4981
4982    to = clock();
4983    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
4984#ifdef  BUCHBERGER_ALG
4985    M = MstdhomCC(Gomega1);
4986#else
4987    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
4988    delete hilb_func;
4989#endif
4990    xtstd = xtstd + clock() - to;
4991
4992    // change the ring to oldRing
4993    rChangeCurrRing(oldRing);
4994
4995    M1 =  idrMoveR(M, newRing,currRing);
4996    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
4997
4998    to = clock();
4999    F = MLifttwoIdeal(Gomega2, M1, G);
5000    xtlift = xtlift + clock() -to;
5001
5002    idDelete(&M1);
5003    idDelete(&Gomega2);
5004    idDelete(&G);
5005
5006
5007    // change the ring to newRing
5008    rChangeCurrRing(newRing);
5009    F1 = idrMoveR(F, oldRing,currRing);
5010
5011    to = clock();
5012    // reduce the Groebner basis <G> w.r.t. new ring
5013    G = kInterRedCC(F1, NULL);
5014    xtred = xtred + clock() -to;
5015
5016    idDelete(&F1);
5017
5018    if(endwalks == 1)
5019    {
5020      break;
5021    }
5022  NEXT_STEP:
5023    to = clock();
5024    // compute a next weight vector
5025    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
5026
5027
5028    xtnw = xtnw + clock() - to;
5029
5030#ifdef PRINT_VECTORS
5031    MivString(curr_weight, target_weight, next_weight);
5032#endif
5033
5034    if(Overflow_Error == TRUE)
5035    {
5036      //PrintS("\n//REC_GB_Mwalk: The computed vector does NOT stay in the correct cone!!\n");
5037      nnwinC = 0;
5038      if(tp_deg == nV)
5039      {
5040        nlast = 1;
5041      }
5042      delete next_weight;
5043      break;
5044    }
5045    if(MivComp(next_weight, ivNull) == 1)
5046    {
5047      newRing = currRing;
5048      delete next_weight;
5049      break;
5050    }
5051
5052    if(MivComp(next_weight, target_weight) == 1)
5053    {
5054      if(tp_deg == nV)
5055      {
5056        endwalks = 1;
5057      }
5058      else
5059      {
5060        G = REC_GB_Mwalk(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
5061        newRing = currRing;
5062        delete next_weight;
5063        break;
5064      }
5065    }
5066
5067    for(i=nV-1; i>=0; i--)
5068    {
5069      (*curr_weight)[i] = (*next_weight)[i];
5070    }
5071    delete next_weight;
5072  }
5073
5074  delete ivNull;
5075
5076  if(tp_deg != nV)
5077  {
5078    newRing = currRing;
5079
5080    if (rParameter(currRing) != NULL)
5081    {
5082      DefRingPar(orig_target_weight);
5083    }
5084    else
5085    {
5086      rChangeCurrRing(VMrDefault(orig_target_weight));
5087    }
5088    F1 = idrMoveR(G, newRing,currRing);
5089
5090    if(nnwinC == 0)
5091    {
5092      F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
5093    }
5094    else
5095    {
5096      if(test_w_in_ConeCC(F1, target_weight) != 1)
5097      {
5098        F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight,tp_deg+1,nnwinC);
5099      }
5100    }
5101    delete target_weight;
5102
5103    TargetRing = currRing;
5104    rChangeCurrRing(EXXRing);
5105    result = idrMoveR(F1, TargetRing,currRing);
5106  }
5107  else
5108  {
5109    if(nlast == 1)
5110    {
5111      if (rParameter(currRing) != NULL)
5112      {
5113        DefRingPar(orig_target_weight);
5114      }
5115      else
5116      {
5117        rChangeCurrRing(VMrDefault(orig_target_weight));
5118      }
5119    KSTD_Finish:
5120      if(isGB == FALSE)
5121      {
5122        F1 = idrMoveR(G, newRing,currRing);
5123      }
5124      else
5125      {
5126        F1 = G;
5127      }
5128      to=clock();
5129      // apply Buchberger alg to compute a red. GB of F1
5130      G = MstdCC(F1);
5131      xtextra=clock()-to;
5132      idDelete(&F1);
5133      newRing = currRing;
5134    }
5135
5136  LastGB_Finish:
5137    rChangeCurrRing(EXXRing);
5138    result = idrMoveR(G, newRing,currRing);
5139  }
5140
5141  if(Overflow_Error == FALSE)
5142    {
5143    Overflow_Error = nError;
5144    }
5145#ifndef BUCHBERGER_ALG
5146  delete last_omega;
5147#endif
5148  return(result);
5149}
5150
5151
5152// THE NEW GROEBNER WALK ALGORITHM
5153// Groebnerwalk with a recursive "second" alternative GW, called REC_GB_Mwalk that only computes the last reduced GB
5154ideal MwalkAlt(ideal Go, intvec* curr_weight, intvec* target_weight)
5155{
5156  Set_Error(FALSE);
5157  Overflow_Error = FALSE;
5158  //Print("// pSetm_Error = (%d)", ErrorCheck());
5159
5160  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5161  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5162  tinput = clock();
5163  clock_t tim;
5164  nstep=0;
5165  int i;
5166  int nV = currRing->N;
5167  int nwalk=0;
5168  int endwalks=0;
5169
5170  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
5171
5172  ring newRing, oldRing;
5173  intvec* ivNull = new intvec(nV);
5174  intvec* exivlp = Mivlp(nV);
5175#ifndef BUCHBERGER_ALG
5176  intvec* hilb_func;
5177#endif
5178  intvec* tmp_weight = new intvec(nV);
5179  for(i=nV-1; i>=0; i--)
5180    (*tmp_weight)[i] = (*curr_weight)[i];
5181
5182   // to avoid (1,0,...,0) as the target vector
5183  intvec* last_omega = new intvec(nV);
5184  for(i=nV-1; i>0; i--)
5185    (*last_omega)[i] = 1;
5186  (*last_omega)[0] = 10000;
5187
5188  ring XXRing = currRing;
5189
5190  to = clock();
5191  // the monomial ordering of this current ring would be "dp"
5192  G = MstdCC(Go);
5193  tostd = clock()-to;
5194
5195  if(currRing->order[0] == ringorder_a)
5196    goto NEXT_VECTOR;
5197
5198  while(1)
5199  {
5200    nwalk ++;
5201    nstep ++;
5202    to = clock();
5203    // compute an initial form ideal of <G> w.r.t. "curr_vector"
5204    Gomega = MwalkInitialForm(G, curr_weight);
5205    tif = tif + clock()-to;
5206    oldRing = currRing;
5207
5208    if(endwalks == 1)
5209    {
5210      /* compute a reduced Groebner basis of Gomega w.r.t. >>_cw by
5211         the recursive changed perturbation walk alg. */
5212      tim = clock();
5213#ifdef CHECK_IDEAL_MWALK
5214        Print("\n// **** Groebnerwalk took %d steps and ", nwalk);
5215        PrintS("\n// **** call the rec. Pert. Walk to compute a red GB of:");
5216        idString(Gomega, "Gomega");
5217#endif
5218
5219      if(MivSame(exivlp, target_weight)==1)
5220        M = REC_GB_Mwalk(idCopy(Gomega), tmp_weight, curr_weight, 2,1);
5221      else
5222        goto NORMAL_GW;
5223#ifdef TIME_TEST
5224        Print("\n//  time for the last std(Gw)  = %.2f sec",
5225        ((double) (clock()-tim)/1000000));
5226#endif
5227/*
5228#ifdef CHECK_IDEAL_MWALK
5229      idElements(Gomega, "G_omega");
5230      headidString(Gomega, "Gw");
5231      idElements(M, "M");
5232      //headidString(M, "M");
5233#endif
5234*/
5235      to = clock();
5236      F = MLifttwoIdeal(Gomega, M, G);
5237      xtlift = xtlift + clock() - to;
5238
5239      idDelete(&Gomega);
5240      idDelete(&M);
5241      idDelete(&G);
5242
5243      oldRing = currRing;
5244
5245      // create a new ring newRing
5246       if (rParameter(currRing) != NULL)
5247       {
5248         DefRingPar(curr_weight);
5249       }
5250       else
5251       {
5252         rChangeCurrRing(VMrDefault(curr_weight));
5253       }
5254      newRing = currRing;
5255      F1 = idrMoveR(F, oldRing,currRing);
5256    }
5257    else
5258    {
5259    NORMAL_GW:
5260#ifndef  BUCHBERGER_ALG
5261      if(isNolVector(curr_weight) == 0)
5262      {
5263        hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5264      }
5265      else
5266      {
5267        hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5268      }
5269#endif // BUCHBERGER_ALG
5270
5271      // define a new ring that its ordering is "(a(curr_weight),lp)
5272      if (rParameter(currRing) != NULL)
5273      {
5274        DefRingPar(curr_weight);
5275      }
5276      else
5277      {
5278        rChangeCurrRing(VMrDefault(curr_weight));
5279      }
5280      newRing = currRing;
5281      Gomega1 = idrMoveR(Gomega, oldRing,currRing);
5282
5283      to = clock();
5284      // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5285#ifdef  BUCHBERGER_ALG
5286      M = MstdhomCC(Gomega1);
5287#else
5288      M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5289      delete hilb_func;
5290#endif
5291      tstd = tstd + clock() - to;
5292
5293      // change the ring to oldRing
5294      rChangeCurrRing(oldRing);
5295      M1 =  idrMoveR(M, newRing,currRing);
5296      Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
5297
5298      to = clock();
5299      // compute a representation of the generators of submod (M) with respect
5300      // to those of mod (Gomega).
5301      // Gomega is a reduced Groebner basis w.r.t. the current ring.
5302      F = MLifttwoIdeal(Gomega2, M1, G);
5303      tlift = tlift + clock() - to;
5304
5305      idDelete(&M1);
5306      idDelete(&Gomega2);
5307      idDelete(&G);
5308
5309      // change the ring to newRing
5310      rChangeCurrRing(newRing);
5311      F1 = idrMoveR(F, oldRing,currRing);
5312    }
5313
5314    to = clock();
5315    // reduce the Groebner basis <G> w.r.t. new ring
5316    G = kInterRedCC(F1, NULL);
5317    if(endwalks != 1)
5318    {
5319      tred = tred + clock() - to;
5320    }
5321    else
5322    {
5323      xtred = xtred + clock() - to;
5324    }
5325    idDelete(&F1);
5326    if(endwalks == 1)
5327    {
5328      break;
5329    }
5330  NEXT_VECTOR:
5331    to = clock();
5332    // compute a next weight vector
5333    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
5334    tnw = tnw + clock() - to;
5335#ifdef PRINT_VECTORS
5336    MivString(curr_weight, target_weight, next_weight);
5337#endif
5338
5339    //if(test_w_in_ConeCC(G, next_weight) != 1)
5340    if(Overflow_Error == TRUE)
5341    {
5342      newRing = currRing;
5343      PrintS("\n// ** The computed vector does NOT stay in Cone!!\n");
5344
5345      if (rParameter(currRing) != NULL)
5346      {
5347        DefRingPar(target_weight);
5348      }
5349      else
5350      {
5351        rChangeCurrRing(VMrDefault(target_weight));
5352      }
5353      F1 = idrMoveR(G, newRing,currRing);
5354      G = MstdCC(F1);
5355      idDelete(&F1);
5356
5357      newRing = currRing;
5358      break;
5359    }
5360
5361    if(MivComp(next_weight, ivNull) == 1)
5362    {
5363      newRing = currRing;
5364      delete next_weight;
5365      break;
5366    }
5367    if(MivComp(next_weight, target_weight) == 1)
5368    {
5369      endwalks = 1;
5370    }
5371    for(i=nV-1; i>=0; i--)
5372    {
5373      (*tmp_weight)[i] = (*curr_weight)[i];
5374      (*curr_weight)[i] = (*next_weight)[i];
5375    }
5376    delete next_weight;
5377  }
5378  rChangeCurrRing(XXRing);
5379  G = idrMoveR(G, newRing,currRing);
5380
5381  delete tmp_weight;
5382  delete ivNull;
5383  delete exivlp;
5384
5385#ifdef TIME_TEST
5386  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5387
5388  Print("\n// pSetm_Error = (%d)", ErrorCheck());
5389  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5390#endif
5391  return(G);
5392}
5393
5394/*******************************
5395 * THE GROEBNER WALK ALGORITHM *
5396 *******************************/
5397ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M,
5398            ring baseRing, int reduction, int printout)
5399{
5400  // save current options
5401  BITSET save1 = si_opt_1;
5402  if(reduction == 0)
5403  {
5404    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5405    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5406  }
5407  Set_Error(FALSE);
5408  Overflow_Error = FALSE;
5409  //BOOLEAN endwalks = FALSE;
5410#ifdef TIME_TEST
5411  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5412  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5413  tinput = clock();
5414  clock_t tim;
5415#endif
5416  nstep=0;
5417  int i,nwalk;
5418  int nV = baseRing->N;
5419
5420  ideal Gomega, M, F, FF, Gomega1, Gomega2, M1;
5421  ring newRing;
5422  ring XXRing = baseRing;
5423  ring targetRing;
5424  intvec* ivNull = new intvec(nV);
5425  intvec* curr_weight = new intvec(nV);
5426  intvec* target_weight = new intvec(nV);
5427  intvec* exivlp = Mivlp(nV);
5428/*
5429  intvec* tmp_weight = new intvec(nV);
5430  for(i=0; i<nV; i++)
5431  {
5432    (*tmp_weight)[i] = (*orig_M)[i];
5433  }
5434*/
5435  for(i=0; i<nV; i++)
5436  {
5437    (*curr_weight)[i] = (*orig_M)[i];
5438    (*target_weight)[i] = (*target_M)[i];
5439  }
5440#ifndef BUCHBERGER_ALG
5441  intvec* hilb_func;
5442   // to avoid (1,0,...,0) as the target vector
5443  intvec* last_omega = new intvec(nV);
5444  for(i=nV-1; i>0; i--)
5445  {
5446    (*last_omega)[i] = 1;
5447  }
5448  (*last_omega)[0] = 10000;
5449#endif
5450  rComplete(currRing);
5451#ifdef CHECK_IDEAL_MWALK
5452  if(printout > 2)
5453  {
5454    idString(Go,"//** Mwalk: Go");
5455  }
5456#endif
5457
5458  if(target_M->length() == nV)
5459  {
5460   // define the target ring
5461    targetRing = VMrDefault(target_weight);
5462  }
5463  else
5464  {
5465    targetRing = VMatrDefault(target_M);
5466  }
5467  if(orig_M->length() == nV)
5468  {
5469    // define a new ring with ordering "(a(curr_weight),lp)
5470    newRing = VMrDefault(curr_weight);
5471  }
5472  else
5473  {
5474    newRing = VMatrDefault(orig_M);
5475  }
5476  rChangeCurrRing(newRing);
5477
5478#ifdef TIME_TEST
5479  to = clock();
5480#endif
5481  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5482#ifdef TIME_TEST
5483  tostd = clock()-to;
5484#endif
5485
5486  baseRing = currRing;
5487  nwalk = 0;
5488
5489  while(1)
5490  {
5491    nwalk ++;
5492    nstep ++;
5493    //compute an initial form ideal of <G> w.r.t. "curr_vector"
5494#ifdef TIME_TEST
5495    to = clock();
5496#endif
5497    Gomega = MwalkInitialForm(G, curr_weight);
5498#ifdef TIME_TEST
5499    tif = tif + clock()-to;
5500#endif
5501
5502#ifdef CHECK_IDEAL_MWALK
5503    if(printout > 1)
5504    {
5505      idString(Gomega,"//** Mwalk: Gomega");
5506    }
5507#endif
5508
5509    if(reduction == 0)
5510    {
5511      FF = middleOfCone(G,Gomega);
5512      if(FF != NULL)
5513      {
5514        idDelete(&G);
5515        G = idCopy(FF);
5516        idDelete(&FF);
5517        goto NEXT_VECTOR;
5518      } 
5519    }
5520
5521#ifndef  BUCHBERGER_ALG
5522    if(isNolVector(curr_weight) == 0)
5523    {
5524      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5525    }   
5526    else
5527    {
5528      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5529    }
5530#endif
5531
5532    if(nwalk == 1)
5533    {
5534      if(orig_M->length() == nV)
5535      {
5536        // define a new ring with ordering "(a(curr_weight),lp)
5537        newRing = VMrDefault(curr_weight);
5538      }
5539      else
5540      {
5541        newRing = VMatrDefault(orig_M);
5542      }
5543    }
5544    else
5545    {
5546     if(target_M->length() == nV)
5547     {
5548       //define a new ring with ordering "(a(curr_weight),lp)"
5549       newRing = VMrDefault(curr_weight);
5550     }
5551     else
5552     {
5553       //define a new ring with matrix ordering
5554       newRing = VMatrRefine(target_M,curr_weight);
5555     }
5556    }
5557    rChangeCurrRing(newRing);
5558    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5559    idDelete(&Gomega);
5560    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5561#ifdef TIME_TEST
5562    to = clock();
5563#endif
5564#ifndef  BUCHBERGER_ALG
5565    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5566    delete hilb_func;
5567#else
5568    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5569#endif
5570#ifdef TIME_TEST
5571    tstd = tstd + clock() - to;
5572#endif
5573    idSkipZeroes(M);
5574#ifdef CHECK_IDEAL_MWALK
5575    if(printout > 2)
5576    {
5577      idString(M, "//** Mwalk: M");
5578    }
5579#endif
5580    //change the ring to baseRing
5581    rChangeCurrRing(baseRing);
5582    M1 =  idrMoveR(M, newRing,currRing);
5583    idDelete(&M);
5584    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5585    idDelete(&Gomega1);
5586#ifdef TIME_TEST
5587    to = clock();
5588#endif
5589    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5590    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5591    F = MLifttwoIdeal(Gomega2, M1, G);
5592#ifdef TIME_TEST
5593    tlift = tlift + clock() - to;
5594#endif
5595#ifdef CHECK_IDEAL_MWALK
5596    if(printout > 2)
5597    {
5598      idString(F, "//** Mwalk: F");
5599    }
5600#endif
5601    idDelete(&Gomega2);
5602    idDelete(&M1);
5603
5604    rChangeCurrRing(newRing); // change the ring to newRing
5605    G = idrMoveR(F,baseRing,currRing);
5606    idDelete(&F);
5607    idSkipZeroes(G);
5608
5609#ifdef CHECK_IDEAL_MWALK
5610    if(printout > 2)
5611    {
5612      idString(G, "//** Mwalk: G");
5613    }
5614#endif
5615
5616    rChangeCurrRing(targetRing);
5617    G = idrMoveR(G,newRing,currRing);
5618    // test whether target cone is reached
5619    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5620    {
5621      baseRing = currRing;
5622      break;
5623      //endwalks = TRUE;
5624    }
5625
5626    rChangeCurrRing(newRing);
5627    G = idrMoveR(G,targetRing,currRing);
5628    baseRing = currRing;
5629
5630    NEXT_VECTOR:
5631#ifdef TIME_TEST
5632    to = clock();
5633#endif
5634    intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5635#ifdef TIME_TEST
5636    tnw = tnw + clock() - to;
5637#endif
5638#ifdef PRINT_VECTORS
5639    if(printout > 0)
5640    {
5641      MivString(curr_weight, target_weight, next_weight);
5642    }
5643#endif
5644    if(MivComp(target_weight,curr_weight) == 1)// || endwalks == TRUE)
5645    {
5646/*
5647#ifdef CHECK_IDEAL_MWALK
5648      if(printout > 0)
5649      {
5650        PrintS("\n//** Mwalk: entering last cone.\n");
5651      }
5652#endif
5653
5654      Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5655      if(target_M->length() == nV)
5656      {
5657        newRing = VMrDefault(target_weight); // define a new ring with ordering "(a(curr_weight),lp)
5658      }
5659      else
5660      {
5661        newRing = VMatrDefault(target_M);
5662      }
5663      rChangeCurrRing(newRing);
5664      Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5665      idDelete(&Gomega);
5666#ifdef CHECK_IDEAL_MWALK
5667      if(printout > 1)
5668      {
5669        idString(Gomega1, "//** Mwalk: Gomega");
5670      }
5671      PrintS("\n //** Mwalk: kStd(Gomega)");
5672#endif
5673      M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5674#ifdef CHECK_IDEAL_MWALK
5675      if(printout > 1)
5676      {
5677        idString(M,"//** Mwalk: M");
5678      }
5679#endif
5680      rChangeCurrRing(baseRing);
5681      M1 =  idrMoveR(M, newRing,currRing);
5682      idDelete(&M);
5683      Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5684      idDelete(&Gomega1);
5685      //PrintS("\n //** Mwalk: MLifttwoIdeal");
5686      F = MLifttwoIdeal(Gomega2, M1, G);
5687#ifdef CHECK_IDEAL_MWALK
5688      if(printout > 2)
5689      {
5690        idString(F,"//** Mwalk: F");
5691      }
5692#endif
5693      idDelete(&Gomega2);
5694      idDelete(&M1);
5695      rChangeCurrRing(newRing); // change the ring to newRing
5696      G = idrMoveR(F,baseRing,currRing);
5697      idDelete(&F);
5698      baseRing = currRing;
5699      idSkipZeroes(G);
5700#ifdef TIME_TEST
5701      to = clock();
5702#endif
5703      //PrintS("\n //**Mwalk: Interreduce");
5704      //interreduce the Groebner basis <G> w.r.t. currRing
5705      //G = kInterRedCC(G,NULL);
5706#ifdef TIME_TEST
5707      tred = tred + clock() - to;
5708#endif
5709      idSkipZeroes(G);
5710      delete next_weight;
5711*/
5712      break;
5713    }
5714
5715    for(i=nV-1; i>=0; i--)
5716    {
5717      //(*tmp_weight)[i] = (*curr_weight)[i];
5718      (*curr_weight)[i] = (*next_weight)[i];
5719    }
5720    delete next_weight;
5721  }
5722  rChangeCurrRing(XXRing);
5723  ideal result = idrMoveR(G,baseRing,currRing);
5724  idDelete(&Go);
5725  idDelete(&G);
5726  //delete tmp_weight;
5727  delete ivNull;
5728  delete exivlp;
5729#ifndef BUCHBERGER_ALG
5730  delete last_omega;
5731#endif
5732#ifdef TIME_TEST
5733  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
5734  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
5735  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
5736#endif
5737  Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
5738  si_opt_1 = save1; //set original options
5739  return(result);
5740}
5741
5742// THE RANDOM WALK ALGORITHM
5743ideal Mrwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad, int pert_deg,
5744             int reduction, int printout)
5745{
5746  BITSET save1 = si_opt_1; // save current options
5747  if(reduction == 0)
5748  {
5749    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
5750    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
5751  }
5752
5753  Set_Error(FALSE);
5754  Overflow_Error = FALSE;
5755  BOOLEAN endwalks = FALSE;
5756#ifdef TIME_TEST
5757  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
5758  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
5759  tinput = clock();
5760  clock_t tim;
5761#endif
5762  nstep=0;
5763  int i,nwalk;//polylength;
5764  int nV = currRing->N;
5765
5766  //check that weight radius is valid
5767  if(weight_rad < 0)
5768  {
5769    Werror("Invalid radius.\n");
5770    return NULL;
5771  }
5772
5773  //check that perturbation degree is valid
5774  if(pert_deg > nV || pert_deg < 1)
5775  {
5776    Werror("Invalid perturbation degree.\n");
5777    return NULL;
5778  }
5779
5780  ideal Gomega, M, F,FF, Gomega1, Gomega2, M1;
5781  ring newRing;
5782  ring targetRing;
5783  ring baseRing = currRing;
5784  ring XXRing = currRing;
5785  intvec* iv_M;
5786  intvec* ivNull = new intvec(nV);
5787  intvec* curr_weight = new intvec(nV);
5788  intvec* target_weight = new intvec(nV);
5789  intvec* next_weight= new intvec(nV);
5790
5791  for(i=0; i<nV; i++)
5792  {
5793    (*curr_weight)[i] = (*orig_M)[i];
5794    (*target_weight)[i] = (*target_M)[i];
5795  }
5796
5797#ifndef BUCHBERGER_ALG
5798  intvec* hilb_func;
5799   // to avoid (1,0,...,0) as the target vector
5800  intvec* last_omega = new intvec(nV);
5801  for(i=nV-1; i>0; i--)
5802  {
5803    (*last_omega)[i] = 1;
5804  }
5805  (*last_omega)[0] = 10000;
5806#endif
5807  rComplete(currRing);
5808
5809  if(target_M->length() == nV)
5810  {
5811    targetRing = VMrDefault(target_weight); // define the target ring
5812  }
5813  else
5814  {
5815    targetRing = VMatrDefault(target_M);
5816  }
5817  if(orig_M->length() == nV)
5818  {
5819    newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5820  }
5821  else
5822  {
5823    newRing = VMatrDefault(orig_M);
5824  }
5825  rChangeCurrRing(newRing);
5826#ifdef TIME_TEST
5827  to = clock();
5828#endif
5829  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
5830#ifdef TIME_TEST
5831  tostd = clock()-to;
5832#endif
5833  baseRing = currRing;
5834  nwalk = 0;
5835
5836#ifdef TIME_TEST
5837  to = clock();
5838#endif
5839  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5840#ifdef TIME_TEST
5841  tif = tif + clock()-to; //time for computing initial form ideal
5842#endif
5843
5844  while(1)
5845  {
5846    nwalk ++;
5847    nstep ++;
5848#ifdef CHECK_IDEAL_MWALK
5849    if(printout > 1)
5850    {
5851      idString(Gomega,"//** Mrwalk: Gomega");
5852    }
5853#endif
5854    if(reduction == 0)
5855    {
5856      FF = middleOfCone(G,Gomega);
5857      if(FF != NULL)
5858      {
5859        idDelete(&G);
5860        G = idCopy(FF);
5861        idDelete(&FF);
5862        goto NEXT_VECTOR;
5863      } 
5864    }
5865#ifndef  BUCHBERGER_ALG
5866    if(isNolVector(curr_weight) == 0)
5867    {
5868      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
5869    }   
5870    else
5871    {
5872      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
5873    }
5874#endif
5875    if(nwalk == 1)
5876    {
5877      if(orig_M->length() == nV)
5878      {
5879        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5880      }
5881      else
5882      {
5883        newRing = VMatrDefault(orig_M);
5884      }
5885    }
5886    else
5887    {
5888     if(target_M->length() == nV)
5889     {
5890       newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
5891     }
5892     else
5893     {
5894       newRing = VMatrRefine(target_M,curr_weight);
5895     }
5896    }
5897    rChangeCurrRing(newRing);
5898    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
5899    idDelete(&Gomega);
5900    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
5901#ifdef TIME_TEST
5902    to = clock();
5903#endif
5904#ifndef BUCHBERGER_ALG
5905    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
5906    delete hilb_func;
5907#else
5908    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
5909#endif
5910#ifdef TIME_TEST
5911    tstd = tstd + clock() - to;
5912#endif
5913    idSkipZeroes(M);
5914#ifdef CHECK_IDEAL_MWALK
5915    if(printout > 2)
5916    {
5917      idString(M, "//** Mrwalk: M");
5918    }
5919#endif
5920    //change the ring to baseRing
5921    rChangeCurrRing(baseRing);
5922    M1 =  idrMoveR(M, newRing,currRing);
5923    idDelete(&M);
5924    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
5925    idDelete(&Gomega1);
5926#ifdef TIME_TEST
5927    to = clock();
5928#endif
5929    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega),
5930    // where Gomega is a reduced Groebner basis w.r.t. the current ring
5931    F = MLifttwoIdeal(Gomega2, M1, G);
5932#ifdef TIME_TEST
5933    tlift = tlift + clock() - to;
5934#endif
5935#ifdef CHECK_IDEAL_MWALK
5936    if(printout > 2)
5937    {
5938      idString(F,"//** Mrwalk: F");
5939    }
5940#endif
5941    idDelete(&Gomega2);
5942    idDelete(&M1);
5943    rChangeCurrRing(newRing); // change the ring to newRing
5944    G = idrMoveR(F,baseRing,currRing);
5945    idDelete(&F);
5946    baseRing = currRing;
5947#ifdef TIME_TEST
5948    to = clock();
5949    tstd = tstd + clock() - to;
5950#endif
5951    idSkipZeroes(G);
5952#ifdef CHECK_IDEAL_MWALK
5953    if(printout > 2)
5954    {
5955      idString(G,"//** Mrwalk: G");
5956    }
5957#endif
5958
5959    rChangeCurrRing(targetRing);
5960    G = idrMoveR(G,newRing,currRing);
5961
5962    // test whether target cone is reached
5963    if(reduction !=0 && test_w_in_ConeCC(G,curr_weight) == 1)
5964    {
5965      baseRing = currRing;
5966      break;
5967    }
5968
5969    rChangeCurrRing(newRing);
5970    G = idrMoveR(G,targetRing,currRing);
5971    baseRing = currRing;
5972
5973    NEXT_VECTOR:
5974#ifdef TIME_TEST
5975    to = clock();
5976#endif
5977    next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
5978#ifdef TIME_TEST
5979    tnw = tnw + clock() - to;
5980#endif
5981
5982#ifdef TIME_TEST
5983    to = clock();
5984#endif
5985    Gomega = MwalkInitialForm(G, next_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
5986#ifdef TIME_TEST
5987    tif = tif + clock()-to; //time for computing initial form ideal
5988#endif
5989
5990    //lengthpoly(Gomega) = 1 if there is a polynomial in Gomega with at least 3 monomials and 0 otherwise
5991    //polylength = lengthpoly(Gomega);
5992    if(lengthpoly(Gomega) > 0)
5993    {
5994      //there is a polynomial in Gomega with at least 3 monomials,
5995      //low-dimensional facet of the cone
5996      delete next_weight;
5997      if(target_M->length() == nV)
5998      {
5999        iv_M = MivMatrixOrder(curr_weight);
6000      }
6001      else
6002      {
6003        iv_M = MivMatrixOrderRefine(curr_weight,target_M);
6004      }
6005#ifdef TIME_TEST
6006      to = clock();
6007#endif
6008      next_weight = MWalkRandomNextWeight(G, iv_M, target_weight, weight_rad, pert_deg);
6009#ifdef TIME_TEST
6010      tnw = tnw + clock() - to;
6011#endif
6012      idDelete(&Gomega);
6013#ifdef TIME_TEST
6014      to = clock();
6015#endif
6016      Gomega = MwalkInitialForm(G, next_weight);
6017#ifdef TIME_TEST
6018      tif = tif + clock()-to; //time for computing initial form ideal
6019#endif
6020      delete iv_M;
6021    }
6022
6023    // test whether target weight vector is reached
6024    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)
6025    {
6026      baseRing = currRing;
6027      delete next_weight;
6028      break;
6029    }
6030
6031#ifdef PRINT_VECTORS
6032    if(printout > 0)
6033    {
6034      MivString(curr_weight, target_weight, next_weight);
6035    }
6036#endif
6037
6038    for(i=nV-1; i>=0; i--)
6039    {
6040      (*curr_weight)[i] = (*next_weight)[i];
6041    }
6042    delete next_weight;
6043  }
6044  baseRing = currRing;
6045  rChangeCurrRing(XXRing);
6046  ideal result = idrMoveR(G,baseRing,currRing);
6047  idDelete(&G);
6048  delete ivNull;
6049#ifndef BUCHBERGER_ALG
6050  delete last_omega;
6051#endif
6052  Print("\n//** Mrwalk: Groebner Walk took %d steps.\n", nstep);
6053#ifdef TIME_TEST
6054  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
6055  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6056  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
6057#endif
6058  si_opt_1 = save1; //set original options
6059  return(result);
6060}
6061
6062/**************************************************************/
6063/*     Implementation of the perturbation walk algorithm      */
6064/**************************************************************/
6065/* If the perturbed target weight vector or an intermediate weight vector
6066   doesn't stay in the correct Groebner cone, we have only
6067   a reduced Groebner basis for the given ideal with respect to
6068   a monomial order which differs to the given order.
6069   Then we have to compute the wanted  reduced Groebner basis for it.
6070   For this, we can use
6071   1) the improved Buchberger algorithm or
6072   2) the changed perturbation walk algorithm with a decreased degree.
6073*/
6074// if nP = 0 use kStd, else call LastGB
6075ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,
6076             intvec* target_weight, int nP, int reduction, int printout)
6077{
6078  BITSET save1 = si_opt_1; // save current options
6079  if(reduction == 0)
6080  {
6081    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6082    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6083  }
6084  Set_Error(FALSE  );
6085  Overflow_Error = FALSE;
6086  //Print("// pSetm_Error = (%d)", ErrorCheck());
6087#ifdef TIME_TEST
6088  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6089  xtextra=0;
6090  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6091  tinput = clock();
6092
6093  clock_t tim;
6094#endif
6095  nstep = 0;
6096  int i, ntwC=1, ntestw=1,  nV = currRing->N;
6097
6098  //check that perturbation degree is valid
6099  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6100  {
6101    Werror("Invalid perturbation degree.\n");
6102    return NULL;
6103  }
6104
6105  BOOLEAN endwalks = FALSE;
6106  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6107  ring newRing, oldRing, TargetRing;
6108  intvec* iv_M_dp;
6109  intvec* iv_M_lp;
6110  intvec* exivlp = Mivlp(nV);
6111  intvec* orig_target = target_weight;
6112  intvec* pert_target_vector = target_weight;
6113  intvec* ivNull = new intvec(nV);
6114  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6115#ifndef BUCHBERGER_ALG
6116  intvec* hilb_func;
6117#endif
6118  intvec* next_weight;
6119
6120  // to avoid (1,0,...,0) as the target vector
6121  intvec* last_omega = new intvec(nV);
6122  for(i=nV-1; i>0; i--)
6123    (*last_omega)[i] = 1;
6124  (*last_omega)[0] = 10000;
6125
6126  ring XXRing = currRing;
6127#ifdef TIME_TEST
6128  to = clock();
6129#endif
6130  // perturbs the original vector
6131  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6132  {
6133    G = MstdCC(Go);
6134#ifdef TIME_TEST
6135    tostd = clock()-to;
6136#endif
6137    if(op_deg != 1){
6138      iv_M_dp = MivMatrixOrderdp(nV);
6139      //ivString(iv_M_dp, "iv_M_dp");
6140      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6141    }
6142  }
6143  else
6144  {
6145    //define ring order := (a(curr_weight),lp);
6146    if (rParameter(currRing) != NULL)
6147      DefRingPar(curr_weight);
6148    else
6149      rChangeCurrRing(VMrDefault(curr_weight));
6150
6151    G = idrMoveR(Go, XXRing,currRing);
6152    G = MstdCC(G);
6153#ifdef TIME_TEST
6154    tostd = clock()-to;
6155#endif
6156    if(op_deg != 1){
6157      iv_M_dp = MivMatrixOrder(curr_weight);
6158      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6159    }
6160  }
6161  delete iv_dp;
6162  if(op_deg != 1) delete iv_M_dp;
6163
6164  ring HelpRing = currRing;
6165
6166  // perturbs the target weight vector
6167  if(tp_deg > 1 && tp_deg <= nV)
6168  {
6169    if (rParameter(currRing) != NULL)
6170      DefRingPar(target_weight);
6171    else
6172      rChangeCurrRing(VMrDefault(target_weight));
6173
6174    TargetRing = currRing;
6175    ssG = idrMoveR(G,HelpRing,currRing);
6176    if(MivSame(target_weight, exivlp) == 1)
6177    {
6178      iv_M_lp = MivMatrixOrderlp(nV);
6179      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6180    }
6181    else
6182    {
6183      iv_M_lp = MivMatrixOrder(target_weight);
6184      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6185    }
6186    delete iv_M_lp;
6187    pert_target_vector = target_weight;
6188    rChangeCurrRing(HelpRing);
6189    G = idrMoveR(ssG, TargetRing,currRing);
6190  }
6191  if(printout > 0)
6192  {
6193    Print("\n//** Mpwalk: Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6194#ifdef PRINT_VECTORS
6195    ivString(curr_weight, "//** Mpwalk: new current weight");
6196    ivString(target_weight, "//** Mpwalk: new target weight");
6197#endif
6198  }
6199  while(1)
6200  {
6201    nstep ++;
6202#ifdef TIME_TEST
6203    to = clock();
6204#endif
6205    // compute an initial form ideal of <G> w.r.t. the weight vector
6206    // "curr_weight"
6207    Gomega = MwalkInitialForm(G, curr_weight);
6208#ifdef TIME_TEST
6209    tif = tif + clock()-to;
6210#endif
6211#ifdef CHECK_IDEAL_MWALK
6212    if(printout > 1)
6213    {
6214      idString(Gomega,"//** Mpwalk: Gomega");
6215    }
6216#endif
6217    if(reduction == 0 && nstep > 1)
6218    {
6219/*
6220      // check whether weight vector is in the interior of the cone
6221      while(1)
6222      {
6223        FF = middleOfCone(G,Gomega);
6224        if(FF != NULL)
6225        {
6226          idDelete(&G);
6227          G = idCopy(FF);
6228          idDelete(&FF);
6229          next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
6230#ifdef PRINT_VECTORS
6231          if(printout > 0)
6232          {
6233            MivString(curr_weight, target_weight, next_weight);
6234          }
6235#endif
6236        }
6237        else
6238        {
6239          break;
6240        }
6241        for(i=nV-1; i>=0; i--)
6242        {
6243          (*curr_weight)[i] = (*next_weight)[i];
6244        }
6245        Gomega = MwalkInitialForm(G, curr_weight);
6246#ifdef CHECK_IDEAL_MWALK
6247        if(printout > 1)
6248        {
6249          idString(Gomega,"//** Mpwalk: Gomega");
6250        }
6251#endif
6252      }
6253*/
6254      FF = middleOfCone(G,Gomega);
6255      if(FF != NULL)
6256      {
6257        idDelete(&G);
6258        G = idCopy(FF);
6259        idDelete(&FF); 
6260        goto NEXT_VECTOR;
6261      }
6262    }
6263
6264#ifdef ENDWALKS
6265    if(endwalks == TRUE)
6266    {
6267      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6268/*
6269      idElements(G, "G");
6270      headidString(G, "G");
6271*/
6272    }
6273#endif
6274
6275#ifndef  BUCHBERGER_ALG
6276    if(isNolVector(curr_weight) == 0)
6277      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6278    else
6279      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6280#endif // BUCHBERGER_ALG
6281
6282    oldRing = currRing;
6283
6284    // define a new ring with ordering "(a(curr_weight),lp)
6285    if (rParameter(currRing) != NULL)
6286      DefRingPar(curr_weight);
6287    else
6288      rChangeCurrRing(VMrDefault(curr_weight));
6289
6290    newRing = currRing;
6291    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6292
6293#ifdef ENDWALKS
6294    if(endwalks==TRUE)
6295    {
6296      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6297/*
6298      idElements(Gomega1, "Gw");
6299      headidString(Gomega1, "headGw");
6300*/
6301      PrintS("\n// compute a rGB of Gw:\n");
6302#ifndef  BUCHBERGER_ALG
6303      ivString(hilb_func, "w");
6304#endif
6305    }
6306#endif
6307#ifdef TIME_TEST
6308    tim = clock();
6309    to = clock();
6310#endif
6311    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6312#ifdef  BUCHBERGER_ALG
6313    M = MstdhomCC(Gomega1);
6314#else
6315    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6316    delete hilb_func;
6317#endif
6318
6319    if(endwalks == TRUE)
6320    {
6321#ifdef TIME_TEST
6322      xtstd = xtstd+clock()-to;
6323#endif
6324#ifdef ENDWALKS
6325      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6326            ((double) clock())/1000000 -((double)tim) /1000000);
6327#endif
6328    }
6329    else
6330    {
6331#ifdef TIME_TEST
6332      tstd=tstd+clock()-to;
6333#endif
6334    }
6335#ifdef CHECK_IDEAL_MWALK
6336    if(printout > 2)
6337    {
6338      idString(M,"//** Mpwalk: M");
6339    }
6340#endif
6341    // change the ring to oldRing
6342    rChangeCurrRing(oldRing);
6343    M1 =  idrMoveR(M, newRing,currRing);
6344    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
6345#ifdef TIME_TEST
6346    to=clock();
6347#endif
6348    /* compute a representation of the generators of submod (M)
6349       with respect to those of mod (Gomega).
6350       Gomega is a reduced Groebner basis w.r.t. the current ring */
6351    F = MLifttwoIdeal(Gomega2, M1, G);
6352#ifdef TIME_TEST
6353    if(endwalks == FALSE)
6354      tlift = tlift+clock()-to;
6355    else
6356      xtlift=clock()-to;
6357#endif
6358#ifdef CHECK_IDEAL_MWALK
6359    if(printout > 2)
6360    {
6361      idString(F,"//** Mpwalk: F");
6362    }
6363#endif
6364
6365    idDelete(&M1);
6366    idDelete(&Gomega2);
6367    idDelete(&G);
6368
6369    // change the ring to newRing
6370    rChangeCurrRing(newRing);
6371    if(reduction == 0)
6372    {
6373      G = idrMoveR(F,oldRing,currRing);
6374    }
6375    else
6376    {
6377      F1 = idrMoveR(F, oldRing,currRing);
6378      if(printout > 2)
6379      {
6380        PrintS("\n //** Mpwalk: reduce the Groebner basis.\n");
6381      }
6382#ifdef TIME_TEST
6383      to=clock();
6384#endif
6385      G = kInterRedCC(F1, NULL);
6386#ifdef TIME_TEST
6387      if(endwalks == FALSE)
6388        tred = tred+clock()-to;
6389      else
6390        xtred=clock()-to;
6391#endif
6392      idDelete(&F1);
6393    }
6394    if(endwalks == TRUE)
6395      break;
6396
6397    NEXT_VECTOR:
6398#ifdef TIME_TEST
6399    to=clock();
6400#endif
6401    // compute a next weight vector
6402    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
6403#ifdef TIME_TEST
6404    tnw=tnw+clock()-to;
6405#endif
6406#ifdef PRINT_VECTORS
6407    if(printout > 0)
6408    {
6409      MivString(curr_weight, target_weight, next_weight);
6410    }
6411#endif
6412
6413    if(Overflow_Error == TRUE)
6414    {
6415      ntwC = 0;
6416      //ntestomega = 1;
6417      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6418      //idElements(G, "G");
6419      delete next_weight;
6420      goto FINISH_160302;
6421    }
6422    if(MivComp(next_weight, ivNull) == 1){
6423      newRing = currRing;
6424      delete next_weight;
6425      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6426      break;
6427    }
6428    if(MivComp(next_weight, target_weight) == 1)
6429      endwalks = TRUE;
6430
6431    for(i=nV-1; i>=0; i--)
6432      (*curr_weight)[i] = (*next_weight)[i];
6433
6434    delete next_weight;
6435  }//end of while-loop
6436
6437  if(tp_deg != 1)
6438  {
6439  FINISH_160302:
6440    if(MivSame(orig_target, exivlp) == 1)
6441      if (rParameter(currRing) != NULL)
6442        DefRingParlp();
6443      else
6444        VMrDefaultlp();
6445    else
6446      if (rParameter(currRing) != NULL)
6447        DefRingPar(orig_target);
6448      else
6449        rChangeCurrRing(VMrDefault(orig_target));
6450
6451    TargetRing=currRing;
6452    F1 = idrMoveR(G, newRing,currRing);
6453/*
6454#ifdef CHECK_IDEAL_MWALK
6455      headidString(G, "G");
6456#endif
6457*/
6458
6459    // check whether the pertubed target vector stays in the correct cone
6460    if(ntwC != 0){
6461      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
6462    }
6463
6464    if( ntestw != 1 || ntwC == 0)
6465    {
6466      if(ntestw != 1 && printout >2)
6467      {
6468        ivString(pert_target_vector, "tau");
6469        PrintS("\n// ** perturbed target vector doesn't stay in cone!!");
6470        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6471        //idElements(F1, "G");
6472      }
6473      // LastGB is "better" than the kStd subroutine
6474      to=clock();
6475      ideal eF1;
6476      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1){
6477        // PrintS("\n// ** calls \"std\" to compute a GB");
6478        eF1 = MstdCC(F1);
6479        idDelete(&F1);
6480      }
6481      else {
6482        // PrintS("\n// ** calls \"LastGB\" to compute a GB");
6483        rChangeCurrRing(newRing);
6484        ideal F2 = idrMoveR(F1, TargetRing,currRing);
6485        eF1 = LastGB(F2, curr_weight, tp_deg-1);
6486        F2=NULL;
6487      }
6488      xtextra=clock()-to;
6489      ring exTargetRing = currRing;
6490
6491      rChangeCurrRing(XXRing);
6492      Eresult = idrMoveR(eF1, exTargetRing,currRing);
6493    }
6494    else{
6495      rChangeCurrRing(XXRing);
6496      Eresult = idrMoveR(F1, TargetRing,currRing);
6497    }
6498  }
6499  else {
6500    rChangeCurrRing(XXRing);
6501    Eresult = idrMoveR(G, newRing,currRing);
6502  }
6503  si_opt_1 = save1; //set original options, e. g. option(RedSB)
6504  delete ivNull;
6505  if(tp_deg != 1)
6506    delete target_weight;
6507
6508  if(op_deg != 1 )
6509    delete curr_weight;
6510
6511  delete exivlp;
6512  delete last_omega;
6513
6514#ifdef TIME_TEST
6515  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
6516             tnw+xtnw);
6517
6518  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
6519  //Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
6520#endif
6521  Print("\n//** Mpwalk: Perturbation Walk took %d steps.\n", nstep);
6522  return(Eresult);
6523}
6524
6525/*******************************************************
6526 * THE PERTURBATION WALK ALGORITHM WITH RANDOM ELEMENT *
6527 *******************************************************/
6528ideal Mprwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad,
6529              int op_deg, int tp_deg, int nP, int reduction, int printout)
6530{
6531  BITSET save1 = si_opt_1; // save current options
6532  if(reduction == 0)
6533  {
6534    si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
6535    si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
6536  }
6537  Set_Error(FALSE);
6538  Overflow_Error = FALSE;
6539  //Print("// pSetm_Error = (%d)", ErrorCheck());
6540#ifdef TIME_TEST
6541  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
6542  xtextra=0;
6543  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
6544  tinput = clock();
6545
6546  clock_t tim;
6547#endif
6548  nstep = 0;
6549  int i, ntwC=1, ntestw=1, nV = currRing->N; //polylength
6550
6551  //check that weight radius is valid
6552  if(weight_rad < 0)
6553  {
6554    Werror("Invalid radius.\n");
6555    return NULL;
6556  }
6557
6558  //check that perturbation degree is valid
6559  if(op_deg < 1 || tp_deg < 1 || op_deg > nV || tp_deg > nV)
6560  {
6561    Werror("Invalid perturbation degree.\n");
6562    return NULL;
6563  }
6564
6565  BOOLEAN endwalks = FALSE;
6566
6567  ideal Gomega, M, F, FF, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
6568  ring newRing, oldRing, TargetRing;
6569  intvec* iv_M;
6570  intvec* iv_M_dp;
6571  intvec* iv_M_lp;
6572  intvec* exivlp = Mivlp(nV);
6573  intvec* curr_weight = new intvec(nV);
6574  intvec* target_weight = new intvec(nV);
6575  for(i=0; i<nV; i++)
6576  {
6577    (*curr_weight)[i] = (*orig_M)[i];
6578    (*target_weight)[i] = (*target_M)[i];
6579  }
6580  intvec* orig_target = target_weight;
6581  intvec* pert_target_vector = target_weight;
6582  intvec* ivNull = new intvec(nV);
6583  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
6584#ifndef BUCHBERGER_ALG
6585  intvec* hilb_func;
6586#endif
6587  intvec* next_weight;
6588
6589  // to avoid (1,0,...,0) as the target vector
6590  intvec* last_omega = new intvec(nV);
6591  for(i=nV-1; i>0; i--)
6592    (*last_omega)[i] = 1;
6593  (*last_omega)[0] = 10000;
6594
6595  ring XXRing = currRing;
6596
6597  // perturbs the original vector
6598  if(orig_M->length() == nV)
6599  {
6600    if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
6601    {
6602#ifdef TIME_TEST
6603  to = clock();
6604#endif
6605      G = MstdCC(Go);
6606#ifdef TIME_TEST
6607      tostd = clock()-to;
6608#endif
6609      if(op_deg != 1)
6610      {
6611        iv_M_dp = MivMatrixOrderdp(nV);
6612        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6613      }
6614    }
6615    else
6616    {
6617      //define ring order := (a(curr_weight),lp);
6618      if (rParameter(currRing) != NULL)
6619        DefRingPar(curr_weight);
6620      else
6621        rChangeCurrRing(VMrDefault(curr_weight));
6622
6623      G = idrMoveR(Go, XXRing,currRing);
6624#ifdef TIME_TEST
6625  to = clock();
6626#endif
6627      G = MstdCC(G);
6628#ifdef TIME_TEST
6629      tostd = clock()-to;
6630#endif
6631      if(op_deg != 1)
6632      {
6633        iv_M_dp = MivMatrixOrder(curr_weight);
6634        curr_weight = MPertVectors(G, iv_M_dp, op_deg);
6635      }
6636    }
6637  }
6638  else
6639  {
6640    rChangeCurrRing(VMatrDefault(orig_M));
6641    G = idrMoveR(Go, XXRing,currRing);
6642#ifdef TIME_TEST
6643    to = clock();
6644#endif
6645    G = MstdCC(G);
6646#ifdef TIME_TEST
6647    tostd = clock()-to;
6648#endif
6649    if(op_deg != 1)
6650    {
6651      curr_weight = MPertVectors(G, orig_M, op_deg);
6652    }
6653  }
6654
6655  delete iv_dp;
6656  if(op_deg != 1) delete iv_M_dp;
6657
6658  ring HelpRing = currRing;
6659
6660  // perturbs the target weight vector
6661  if(target_M->length() == nV)
6662  {
6663    if(tp_deg > 1 && tp_deg <= nV)
6664    {
6665      if (rParameter(currRing) != NULL)
6666        DefRingPar(target_weight);
6667      else
6668        rChangeCurrRing(VMrDefault(target_weight));
6669
6670      TargetRing = currRing;
6671      ssG = idrMoveR(G,HelpRing,currRing);
6672      if(MivSame(target_weight, exivlp) == 1)
6673      {
6674        iv_M_lp = MivMatrixOrderlp(nV);
6675        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6676      }
6677      else
6678      {
6679        iv_M_lp = MivMatrixOrder(target_weight);
6680        target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
6681      }
6682      delete iv_M_lp;
6683      pert_target_vector = target_weight;
6684      rChangeCurrRing(HelpRing);
6685      G = idrMoveR(ssG, TargetRing,currRing);
6686    }
6687  }
6688  else
6689  {
6690    if(tp_deg > 1 && tp_deg <= nV)
6691    {
6692      rChangeCurrRing(VMatrDefault(target_M));
6693      TargetRing = currRing;
6694      ssG = idrMoveR(G,HelpRing,currRing);
6695      target_weight = MPertVectors(ssG, target_M, tp_deg);
6696    }
6697  }
6698  if(printout > 0)
6699  {
6700    Print("\n//** Mprwalk: Random Perturbation Walk of degree (%d,%d):",op_deg,tp_deg);
6701    ivString(curr_weight, "//** Mprwalk: new current weight");
6702    ivString(target_weight, "//** Mprwalk: new target weight");
6703  }
6704
6705#ifdef TIME_TEST
6706  to = clock();
6707#endif
6708  Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
6709#ifdef TIME_TEST
6710  tif = tif + clock()-to; //time for computing initial form ideal
6711#endif
6712
6713  while(1)
6714  {
6715    nstep ++;
6716#ifdef CHECK_IDEAL_MWALK
6717    if(printout > 1)
6718    {
6719      idString(Gomega,"//** Mprwalk: Gomega");
6720    }
6721#endif
6722
6723    if(reduction == 0 && nstep > 1)
6724    {
6725/*
6726      // check whether weight vector is in the interior of the cone
6727      while(1)
6728      {
6729        FF = middleOfCone(G,Gomega);
6730        if(FF != NULL)
6731        {
6732          idDelete(&G);
6733          G = idCopy(FF);
6734          idDelete(&FF);
6735          next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
6736#ifdef PRINT_VECTORS
6737          if(printout > 0)
6738          {
6739            MivString(curr_weight, target_weight, next_weight);
6740          }
6741#endif
6742        }
6743        else
6744        {
6745          break;
6746        }
6747        for(i=nV-1; i>=0; i--)
6748        {
6749          (*curr_weight)[i] = (*next_weight)[i];
6750        }
6751        Gomega = MwalkInitialForm(G, curr_weight);
6752#ifdef CHECK_IDEAL_MWALK
6753        if(printout > 1)
6754        {
6755          idString(Gomega,"//** Mprwalk: Gomega");
6756        }
6757#endif
6758      }
6759*/
6760      FF = middleOfCone(G,Gomega);
6761      if(FF != NULL)
6762      {
6763        idDelete(&G);
6764        G = idCopy(FF);
6765        idDelete(&FF); 
6766        goto NEXT_VECTOR;
6767      } 
6768    }
6769
6770#ifdef ENDWALKS
6771    if(endwalks == TRUE)
6772    {
6773      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6774/*
6775      idElements(G, "G");
6776      headidString(G, "G");
6777*/
6778    }
6779#endif
6780
6781#ifndef  BUCHBERGER_ALG
6782    if(isNolVector(curr_weight) == 0)
6783      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
6784    else
6785      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
6786#endif // BUCHBERGER_ALG
6787
6788    oldRing = currRing;
6789
6790    if(target_M->length() == nV)
6791    {
6792      // define a new ring with ordering "(a(curr_weight),lp)
6793      if (rParameter(currRing) != NULL)
6794        DefRingPar(curr_weight);
6795      else
6796        rChangeCurrRing(VMrDefault(curr_weight));
6797    }
6798    else
6799    {
6800      rChangeCurrRing(VMatrRefine(target_M,curr_weight));
6801    }
6802    newRing = currRing;
6803    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
6804#ifdef ENDWALKS
6805    if(endwalks == TRUE)
6806    {
6807      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
6808/*
6809      idElements(Gomega1, "Gw");
6810      headidString(Gomega1, "headGw");
6811*/
6812      PrintS("\n// compute a rGB of Gw:\n");
6813
6814#ifndef  BUCHBERGER_ALG
6815      ivString(hilb_func, "w");
6816#endif
6817    }
6818#endif
6819#ifdef TIME_TEST
6820    tim = clock();
6821    to = clock();
6822#endif
6823    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
6824#ifdef  BUCHBERGER_ALG
6825    M = MstdhomCC(Gomega1);
6826#else
6827    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
6828    delete hilb_func;
6829#endif
6830#ifdef CHECK_IDEAL_MWALK
6831    if(printout > 2)
6832    {
6833      idString(M,"//** Mprwalk: M");
6834    }
6835#endif
6836#ifdef TIME_TEST
6837    if(endwalks == TRUE)
6838    {
6839      xtstd = xtstd+clock()-to;
6840#ifdef ENDWALKS
6841      Print("\n// time for the last std(Gw)  = %.2f sec\n",
6842            ((double) clock())/1000000 -((double)tim) /1000000