source: git/Singular/walk.cc @ 567abae

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