source: git/kernel/walk.cc @ 788529d

spielwiese
Last change on this file since 788529d was 35aab3, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6879, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6880 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 29.6 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: walk.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
5/*
6* ABSTRACT: Implementation of the Groebner walk
7*/
8
9/* includes */
10#include "mod2.h"
11#include "walk.h"
12#include "polys.h"
13#include "ideals.h"
14#include "intvec.h"
15#include "ipid.h"
16#include "tok.h"
17#include <omalloc.h>
18#include "febase.h"
19#include "numbers.h"
20#include "ipid.h"
21#include "ring.h"
22#include "kstd1.h"
23#include "matpol.h"
24#include "weight.h"
25#include "intvec.h"
26#include "syz.h"
27#include "lists.h"
28#include "prCopy.h"
29#include <string.h>
30#include "structs.h"
31#include "longalg.h"
32#ifdef HAVE_FACTORY
33#include "clapsing.h"
34#endif
35
36static void* idString(ideal L)
37{
38  int i;
39  printf("//ideal Itmp: ");
40  for(i=0; i<IDELEMS(L); i++)
41    printf(" %s, ", pString(L->m[i]));
42  printf("\n");
43}
44
45
46// returns gcd of integers a and b
47static inline long gcd(const long a, const long b)
48{
49  long r, p0 = a, p1 = b;
50  //assume(p0 >= 0 && p1 >= 0);
51  if(p0 < 0)
52    p0 = -p0;
53
54  if(p1 < 0)
55    p1 = -p1;
56  while(p1 != 0)
57  {
58    r = p0 % p1;
59    p0 = p1;
60    p1 = r;
61  }
62  return p0;
63}
64
65// cancel gcd of integers zaehler and nenner
66static inline void cancel(long &zaehler, long &nenner)
67{
68  assume(zaehler >= 0 && nenner > 0);
69  long g = gcd(zaehler, nenner);
70  if (g > 1)
71  {
72    zaehler = zaehler / g;
73    nenner = nenner / g;
74  }
75}
76
77/********************************************************************
78 * compute a weight degree of a monomial p w.r.t. a weight_vector   *
79 ********************************************************************/
80static inline int MLmWeightedDegree(const poly p, intvec* weight)
81{
82  int i, d = 0;
83
84  for (i=1; i<=pVariables; i++)
85    d += pGetExp(p, i) * (*weight)[i-1];
86
87  return d;
88}
89
90/********************************************************************
91 * compute a weight degree of a polynomial p w.r.t. a weight_vector *
92 ********************************************************************/
93static inline int MwalkWeightDegree(poly p, intvec* weight_vector)
94{
95  assume(weight_vector->length() >= pVariables);
96  int max = 0, maxtemp;
97  poly hp;
98
99  while(p != NULL)
100  {
101    hp = pHead(p);
102    pIter(p);
103    maxtemp = MLmWeightedDegree(hp, weight_vector);
104
105    if (maxtemp > max)
106      max = maxtemp;
107  }
108  return max;
109}
110
111/*****************************************************************************
112 * return an initial form of the polynom g w.r.t. a weight vector curr_weight *
113 *****************************************************************************/
114static poly MpolyInitialForm(poly g, intvec* curr_weight)
115{
116  if(g == NULL)
117    return g;
118
119  int maxtmp, max = 0;
120  poly in_w_g = NULL, hg;
121
122  while(g != NULL)
123  {
124    hg = pHead(g);
125    pIter(g);
126    maxtmp = MwalkWeightDegree(hg, curr_weight);
127
128    if(maxtmp > max)
129    {
130      max = maxtmp;
131      in_w_g = hg;
132    } else {
133      if(maxtmp == max)
134        in_w_g = pAdd(in_w_g, hg);
135    }
136  }
137  return in_w_g;
138}
139
140
141/*****************************************************************************
142 * compute the initial form of an ideal "G" w.r.t. weight vector curr_weight *
143 ****************************************************************************/
144ideal MwalkInitialForm(ideal G, intvec* curr_weight)
145{
146  int i;
147  int nG = IDELEMS(G);
148  ideal Gomega  = idInit(nG, G->rank);
149
150  for(i=0; i<nG; i++)
151    Gomega->m[i] = MpolyInitialForm(G->m[i], curr_weight);
152
153  //return Gomega;
154  ideal result = idCopy(Gomega);
155  idDelete(&Gomega);
156  return result;
157}
158
159/************************************************************************
160 * test that does the weight vector iv exist in the cone of the ideal G *
161 *            i.e. does in(in_w(g)) =? in(g), for all g in G            *
162 ************************************************************************/
163void* test_w_in_Cone(ideal G, intvec* iv)
164{
165  int nG = IDELEMS(G);
166  int i;
167  BOOLEAN ok = TRUE;
168  poly mi, in_mi,  gi;
169  for(i=0; i<nG; i++)
170  {
171    mi = MpolyInitialForm(G->m[i], iv);
172    in_mi = pHead(mi);
173    gi = pHead(G->m[i]);
174    if(pEqualPolys(in_mi, gi) != ok)
175    {
176      printf("//ring Test_W_in_Cone = %s ;\n", rString(currRing));
177      printf("//the computed next weight vector doesn't exist in the cone\n");
178      break;
179    }
180  }
181}
182
183//compute a least common multiple of two integers
184static inline long Mlcm(long &i1, long &i2)
185{
186  long temp = gcd(i1, i2);
187  return ((i1*i2) / temp);
188}
189
190
191/***************************************************
192 * return  the dot product of two intvecs a and b  *
193 ***************************************************/
194static inline long  MivDotProduct(intvec* a, intvec* b)
195{
196  assume( a->length() ==  b->length());
197  int i, n = a->length();
198  long result = 0;
199
200  for(i=0; i<n; i++)
201    result += (*a)[i] * (*b)[i];
202
203  return result;
204}
205
206
207/**21.10.00*******************************************
208 * return the "intvec" lead exponent of a polynomial *
209 *****************************************************/
210static intvec* MExpPol(poly f)
211{
212  int nR = currRing->N;
213
214  intvec* result = new intvec(nR);
215  int i;
216
217  for(i=0; i<nR; i++)
218    (*result)[i] = pGetExp(f,i+1);
219
220  intvec *res = ivCopy(result);
221  omFree((ADDRESS) result);
222  return res;
223}
224
225
226/***23-24.10.00******************************************
227 * compute a division of two monoms, "a" by a monom "b" *
228 *    i.e. leading term of two polynoms a and b         *
229 ********************************************************/
230static poly MpDiv(poly a, poly b)
231{
232  assume (b != NULL);
233  BOOLEAN ok = TRUE;
234
235  if(a == NULL)
236    return a;
237
238  int nR = currRing->N;
239
240  number nn = (number) omAllocBin(rnumber_bin);
241
242  poly  ptmp, ppotenz;
243  poly result = pISet(1);
244
245  intvec* iva = MExpPol(a);  //head exponent of a
246  intvec* ivb = MExpPol(b);  //head exponent of a
247
248  int nab;
249  for(int i=0; i<nR; i++)
250  {
251    nab = (*iva)[i] - (*ivb)[i];
252    // b does not divide a
253    if(nab < 0)
254    {
255      result = NULL;
256      return result;
257    }
258    //define a polynomial which is a variable of the basering
259    ptmp = (poly) pmInit(currRing->names[i], ok);  //p:=xi
260    ppotenz = pPower(ptmp, nab);
261    result = pMult(result, ppotenz);
262  }
263  nn = nDiv(pGetCoeff(a), pGetCoeff(b));
264  result = pMult_nn(result, nn);
265  nDelete(&nn);
266
267  return result;
268}
269
270
271/***24.10.00 *****************************************
272 *      compute a product of two monoms a and b      *
273 *      i.e. leading term of two polynoms a and b    *
274 *****************************************************/
275static poly MpMult(poly a, poly b)
276{
277  if(a == NULL || b == NULL)
278    return a;
279
280  int nR = currRing->N;
281  BOOLEAN ok = TRUE;
282
283  poly  ptmp, ppotenz;
284  poly result = pISet(1);  // result := 1
285  intvec* ivab = ivAdd(MExpPol(a), MExpPol(b));
286
287  for(int i=0; i<nR; i++)
288  {
289    //define a polynomial which is a variable of the basering
290    ptmp = pmInit(currRing->names[i], ok);
291    ppotenz = pPower(ptmp, (*ivab)[i]);
292    result = pMult(result, ppotenz);
293  }
294  number nn = nMult(pGetCoeff(a), pGetCoeff(b));
295  result = pMult_nn(result, nn);
296
297  return result;
298}
299
300
301poly  MivSame(intvec* u , intvec* v)
302{
303  assume(u->length() == v->length());
304
305  int i, niv = u->length();
306
307  for (i=0; i<niv; i++)
308    if ((*u)[i] != (*v)[i])
309      return pISet(1);
310
311  return (poly) NULL;
312}
313
314poly  M3ivSame(intvec* temp, intvec* u , intvec* v)
315{
316  assume(temp->length() == u->length() && u->length() == v->length());
317
318  if(MivSame(temp, u) == NULL)
319    return (poly) NULL;
320  if(MivSame(temp, v) == NULL)
321    return pISet(1);
322  return pISet(2);
323}
324
325
326/************************
327 *  Define a monom x^iv *
328 ************************/
329poly MPolVar(intvec* iv)
330{
331  int i, niv = pVariables;
332
333  poly ptemp = pOne();
334  poly pvar, ppotenz;
335  BOOLEAN ok = TRUE;
336
337  for(i=0; i<niv; i++)
338  {
339    pvar = (poly) pmInit(currRing->names[i], ok);  //p:=x_i
340    ppotenz = pPower(pvar, (*iv)[i]);
341    ptemp = pMult(ptemp, ppotenz);
342  }
343  return ptemp;
344}
345
346
347/* compute a Groebner basis of an ideal */
348ideal Mstd(ideal G)
349{
350  G = kStd(G, NULL, testHomog, NULL);
351  G = kInterRed(G, NULL);//5.02
352  idSkipZeroes(G);
353  return G;
354}
355
356/* compute a Groebner basis of a homogenoues ideal */
357ideal Mstdhom(ideal G)
358{
359  G = kStd(G, NULL, isHomog, NULL);
360  G = kInterRed(G, NULL);//21.02
361  idSkipZeroes(G);
362  return G;
363}
364
365/* compute a reduced Groebner basis of a Groebner basis */
366ideal MkInterRed(ideal G)
367{
368  if(G == NULL)
369    return G;
370
371  G = kInterRed(G, NULL);
372  idSkipZeroes(G);
373  return G;
374}
375
376
377/*****************************************************
378 *              PERTURBATION WALK                    *
379 *****************************************************/
380
381/***************************************
382* create an ordering matrix as intvec  *
383****************************************/
384intvec* MivMatrixOrder(intvec* iv)
385{
386  int i,j;
387  int nR = currRing->N;
388  intvec* ivm = new intvec(nR*nR);
389
390  for(i=0; i<nR; i++)
391    (*ivm)[i] = (*iv)[i];
392
393  for(i=1; i<nR; i++)
394    (*ivm)[i*nR+i-1] = (int) 1;
395
396  return ivm;
397}
398
399static intvec* MivMatUnit(void)
400{
401  int nR = currRing->N;
402  intvec* ivm = new intvec(nR);
403
404  (*ivm)[0] = 1;
405
406  return ivm;
407}
408
409/* return iv = (1, ..., 1) */
410intvec* Mivdp(int nR)
411{
412  int i;
413  intvec* ivm = new intvec(nR);
414
415  for(i=0; i<nR; i++)
416    (*ivm)[i] = 1;
417
418  return ivm;
419}
420
421/* return iv = (1,0, ..., 0) */
422intvec* Mivlp(int nR)
423{
424  int i;
425  intvec* ivm = new intvec(nR);
426  (*ivm)[0] = 1;
427
428  return ivm;
429}
430
431intvec* Mivdp0(int nR)
432{
433  int i;
434  intvec* ivm = new intvec(nR);
435  (*ivm)[nR-1] = 0;
436  for(i=0; i<nR-1; i++)
437    (*ivm)[i] = 1;
438
439  return ivm;
440}
441
442/*****************************************************************************
443* If target_ord = intmat(A1, ..., An) then calculate the perturbation        *
444* vectors                                                                    *
445*   tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg     *
446* where                                                                      *
447*      inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                    *
448* intmat target_ord is an integer order matrix of the monomial ordering of   *
449* basering.                                                                  *
450* This programm computes a perturbated vector with a p_deg perturbation      *
451* degree which smaller than the numbers of varibles                          *
452******************************************************************************/
453/* ivtarget is a matrix of a degree reverse lex. order */
454intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg)
455{
456  int nV = currRing->N;
457  //assume(pdeg <= nV && pdeg >= 0);
458
459  int i, j;
460  intvec* pert_vector =  new intvec(nV);
461
462  //Checking that the perturbated degree is valid
463  if(pdeg > nV || pdeg <= 0)
464  {
465    WerrorS("The perturbed degree is wrong!!");
466    return pert_vector;
467  }
468  for(i=0; i<nV; i++)
469    (*pert_vector)[i]=(*ivtarget)[i];
470
471  if(pdeg == 1)
472    return pert_vector;
473
474  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
475  // where the Ai are the i-te rows of the matrix target_ord.
476
477  int ntemp, maxAi, maxA=0;
478  //for(i=1; i<pdeg; i++)
479  for(i=0; i<pdeg; i++) //for "dp"
480  {
481    maxAi = (*ivtarget)[i*nV];
482    for(j=i*nV+1; j<(i+1)*nV; j++)
483    {
484      ntemp = (*ivtarget)[j];
485      if(ntemp > maxAi)
486        maxAi = ntemp;
487    }
488    maxA += maxAi;
489  }
490
491  // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G.
492  int inveps, tot_deg = 0, maxdeg;
493
494  intvec* ivUnit = Mivdp(nV);//19.02
495  for(i=0; i<IDELEMS(G); i++)
496  {
497    //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
498    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
499    if (maxdeg > tot_deg )
500      tot_deg = maxdeg;
501  }
502  inveps = (tot_deg * maxA) + 1;
503
504  // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
505  // pert_vector := A1
506  for ( i=1; i < pdeg; i++ )
507    for(j=0; j<nV; j++)
508       (*pert_vector)[j] = inveps*(*pert_vector)[j] + (*ivtarget)[i*nV+j];
509
510
511  int temp = (*pert_vector)[0];
512  for(i=1; i<nV; i++)
513  {
514    temp = gcd(temp, (*pert_vector)[i]);
515    if(temp == 1)
516      break;
517  }
518  if(temp != 1)
519    for(i=0; i<nV; i++)
520      (*pert_vector)[i] = (*pert_vector)[i] / temp;
521
522  //test_w_in_Cone(G, pert_vector);
523  return pert_vector;
524}
525
526/* ivtarget is a matrix of the lex. order */
527intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg)
528{
529  int nV = currRing->N;
530  //assume(pdeg <= nV && pdeg >= 0);
531
532  int i, j;
533  intvec* pert_vector =  new intvec(nV);
534
535  //Checking that the perturbated degree is valid
536  if(pdeg > nV || pdeg <= 0)
537  {
538    WerrorS("The perturbed degree is wrong!!");
539    return pert_vector;
540  }
541  for(i=0; i<nV; i++)
542    (*pert_vector)[i]=(*ivtarget)[i];
543
544  if(pdeg == 1)
545    return pert_vector;
546
547  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
548  // where the Ai are the i-te rows of the matrix target_ord.
549  int ntemp, maxAi, maxA=0;
550  for(i=1; i<pdeg; i++)
551  //for(i=0; i<pdeg; i++) //for "dp"
552  {
553    maxAi = (*ivtarget)[i*nV];
554    for(j=i*nV+1; j<(i+1)*nV; j++)
555    {
556      ntemp = (*ivtarget)[j];
557      if(ntemp > maxAi)
558        maxAi = ntemp;
559    }
560    maxA += maxAi;
561  }
562
563  // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G.
564  int inveps, tot_deg = 0, maxdeg;
565
566  intvec* ivUnit = Mivdp(nV);//19.02
567  for(i=0; i<IDELEMS(G); i++)
568  {
569    //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
570    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
571    if (maxdeg > tot_deg )
572      tot_deg = maxdeg;
573  }
574  inveps = (tot_deg * maxA) + 1;
575
576  // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
577
578  for ( i=1; i < pdeg; i++ )
579    for(j=0; j<nV; j++)
580      (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j];
581
582  int temp = (*pert_vector)[0];
583  for(i=1; i<nV; i++)
584  {
585    temp = gcd(temp, (*pert_vector)[i]);
586    if(temp == 1)
587      break;
588  }
589  if(temp != 1)
590    for(i=0; i<nV; i++)
591      (*pert_vector)[i] = (*pert_vector)[i] / temp;
592
593  //test_w_in_Cone(G, pert_vector);
594  return pert_vector;
595}
596
597
598/***************************************************************
599 *                    FRACTAL WALK                             *
600 ***************************************************************/
601
602/*****  define a lexicographic order matrix as intvec  ********/
603intvec* MivMatrixOrderlp(int nV)
604{
605  int i;
606  intvec* ivM = new intvec(nV*nV);
607
608  for(i=0; i<nV; i++)
609    (*ivM)[i*nV + i] = 1;
610
611  return(ivM);
612}
613
614intvec* MivMatrixOrderdp(int nV)
615{
616  int i;
617  intvec* ivM = new intvec(nV*nV);
618
619  for(i=0; i<nV; i++)
620    (*ivM)[i] = 1;
621
622  for(i=1; i<nV; i++)
623    (*ivM)[(i+1)*nV - i] = -1;
624
625  return(ivM);
626}
627
628//creates an intvec of the monomial order Wp(ivstart)
629intvec* MivWeightOrderlp(intvec* ivstart)
630{
631  int i;
632  int nV = ivstart->length();
633  intvec* ivM = new intvec(nV*nV);
634
635  for(i=0; i<nV; i++)
636    (*ivM)[i] = (*ivstart)[i];
637
638  for(i=1; i<nV; i++)
639    (*ivM)[i*nV + i-1] = 1;
640
641  return(ivM);
642}
643
644intvec* MivWeightOrderdp(intvec* ivstart)
645{
646  int i;
647  int nV = ivstart->length();
648  intvec* ivM = new intvec(nV*nV);
649
650  for(i=0; i<nV; i++)
651    (*ivM)[i] = (*ivstart)[i];
652
653  for(i=0; i<nV; i++)
654    (*ivM)[nV+i] = 1;
655
656  for(i=2; i<nV; i++)
657    (*ivM)[(i+1)*nV - i] = -1;
658
659  return(ivM);
660}
661
662intvec* MivUnit(int nV)
663{
664  int i;
665  intvec* ivM = new intvec(nV);
666
667  for(i=0; i<nV; i++)
668    (*ivM)[i] = 1;
669
670  return(ivM);
671}
672
673/************************************************************************
674*  compute a perturbed weight vector of a matrix order w.r.t. an ideal  *
675*************************************************************************/
676intvec* Mfpertvector(ideal G, intvec* ivtarget)
677//intvec* Mfpertvector(ideal G)
678{
679  int i, j;
680  int nV = currRing->N;
681  int niv = nV*nV;
682
683  // Calculate max1 = Max(A2) + Max(A3) + ... + Max(AnV),
684  // where the Ai are the i-te rows of the matrix 'targer_ord'.
685  int ntemp, maxAi, maxA=0;
686  for(i=1; i<nV; i++) //30.03
687    //for(i=0; i<nV; i++) //for "dp"
688  {
689    maxAi = (*ivtarget)[i*nV];
690    for(j=i*nV+1; j<(i+1)*nV; j++)
691    {
692      ntemp = (*ivtarget)[j];
693      if(ntemp > maxAi)
694        maxAi = ntemp;
695    }
696    maxA = maxA + maxAi;
697  }
698  intvec* ivUnit = Mivdp(nV);
699
700  // Calculate inveps = 1/eps, where 1/eps > deg(p)*max1 for all p in G.
701  int inveps, tot_deg = 0, maxdeg;
702  for(i=0; i<IDELEMS(G); i++)
703  {
704    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
705    //maxdeg = pTotaldegree(G->m[i]);
706    if (maxdeg > tot_deg )
707      tot_deg = maxdeg;
708  }
709  inveps = (tot_deg * maxA) + 1;
710
711  // Calculate the perturbed target orders:
712  intvec* ivtemp = new intvec(nV);
713  intvec* pert_vector = new intvec(niv);
714  for(i=0; i<nV; i++)
715  {
716    ntemp = (*ivtarget)[i];
717    (* ivtemp)[i] = ntemp;
718    (* pert_vector)[i] = ntemp;
719  }
720  for(i=1; i<nV; i++)
721  {
722    for(j=0; j<nV; j++)
723      (* ivtemp)[j] = inveps*(*ivtemp)[j] + (*ivtarget)[i*nV+j];
724    for(j=0; j<nV; j++)
725      (* pert_vector)[i*nV+j] = (* ivtemp)[j];
726  }
727  omFree((ADDRESS)ivtemp);
728  return pert_vector;
729}
730
731
732/**********************************************************************
733 *  computes a transformation matrix as an ideal L
734    an i-th element of L is a representasion of an i-th element M w.r.t.
735    the generators of Gomega
736********************************************************************/
737
738ideal MidLift(ideal Gomega, ideal M)
739{
740  //M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
741  //return M;
742  //17.04.01
743  ideal Mtmp = idInit(IDELEMS(M),1);
744  Mtmp = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
745  idSkipZeroes(Mtmp);
746  M = idCopy(Mtmp);
747
748  omFree((ADDRESS)Mtmp);
749  return M;
750}
751
752/****************************************************************
753 * Multiplikation of two ideals by elementwise                  *
754 * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) *
755 ****************************************************************/
756ideal MidMultLift(ideal A, ideal B)
757{
758  int mA = IDELEMS(A), mB = IDELEMS(B);
759  ideal result;
760
761  if(A==NULL || B==NULL)
762    return result;
763
764  if(mB < mA)
765  {
766    mA = mB;
767    result = idInit(mA, 1);
768  }
769  else
770  result = idInit(mA, 1);
771
772  int i, k=0;
773  for(i=0; i<mA; i++)
774    if(A->m[i] != NULL)
775    {
776      result->m[k] = pMult(pCopy(A->m[i]), pCopy(B->m[i]));
777      k++;
778    }
779
780  //idSkipZeroes(result); //walkalp_CON
781  ideal res = idCopy(result);
782  idDelete(&result);
783  return res;
784}
785
786//computes a  multiplication of two ideals L and G, ie. L[i]*G[i]
787ideal MLiftLmalG(ideal L, ideal G)
788{
789  int i, j;
790  ideal Gtemp = idInit(IDELEMS(L),1);
791  ideal mG = idInit(IDELEMS(G),1);
792  poly pGtmp = NULL, pmG;
793  ideal T;
794
795  for(i=0; i<IDELEMS(L); i++)
796  {
797    T = idVec2Ideal(L->m[i]);
798    mG = MidMultLift(T,G);
799    idSkipZeroes(mG);
800
801    for(j=0; j<IDELEMS(mG); j++)
802    {
803      pGtmp = pAdd(pGtmp, mG->m[j]);
804    }
805    Gtemp->m[i] = pCopy(pGtmp);
806  }
807  idSkipZeroes(Gtemp);
808
809  //compute a reduced Groebner basis of GF
810  //Gtemp = kInterRed(Gtemp, NULL);
811  L = idCopy(Gtemp);
812
813  omFree((ADDRESS)mG);
814  omFree((ADDRESS)Gtemp);
815  return L;
816}
817
818/*********************************************************************
819 * G is a red. Groebner basis w.r.t. <_1                             *
820 * Gomega is an initial form ideal of <G> w.r.t. a weight vector w   *
821 * M is a subideal of <Gomega> and M selft is a red. Groebner basis  *
822 *    of the ideal <Gomega> w.r.t. <_w                               *
823 * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega  *
824 * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i*
825 ********************************************************************/
826 /* MidLift + MLiftLmalG */
827ideal MLiftLmalGNew(ideal Gomega, ideal M, ideal G)
828{
829  int i, j;
830  M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
831  int nM = IDELEMS(M);
832  ideal Gtemp = idInit(IDELEMS(M),1);
833  ideal mG = idInit(IDELEMS(G),1);
834  poly pmG, pGtmp = NULL;
835  ideal T;
836
837  for(i=0; i<nM; i++)
838  {
839    T = idVec2Ideal(M->m[i]);
840    mG = MidMultLift(T, G);
841
842    for(j=0; j<IDELEMS(mG); j++)
843      pGtmp = pAdd(pGtmp, mG->m[j]);
844
845    Gtemp->m[i] = pCopy(pGtmp);
846  }
847  idSkipZeroes(Gtemp);
848
849  M = idCopy(Gtemp);
850
851  omFree((ADDRESS)mG);
852  omFree((ADDRESS)Gtemp);
853  return M;
854}
855
856/******************************************************************************
857 * compute a next weight vector on the line from curr_weight to target_weight *
858 * and it still stays in the cone of the ideal G where the curr_weight too    *
859 *****************************************************************************/
860intvec* MwalkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G)
861{
862  assume(currRing != NULL && curr_weight != NULL &&
863         target_weight != NULL && G != NULL);
864
865  int nRing = currRing->N;
866  int nG = IDELEMS(G);
867  intvec* ivtemp;
868
869  long t_zaehler = 0, t_nenner = 0;
870  long s_zaehler, s_nenner, temp, MwWd;
871  long deg_w0_p1, deg_d0_p1;
872  int j;
873
874  intvec* diff_weight = ivSub(target_weight, curr_weight);
875  poly g;
876  for (j=0; j<nG; j++)
877  {
878    g = G->m[j];
879    if (g != NULL)
880    {
881      ivtemp = MExpPol(g);
882      deg_w0_p1 = MivDotProduct(ivtemp, curr_weight);
883      deg_d0_p1 = MivDotProduct(ivtemp, diff_weight);
884
885      pIter(g);
886
887      while (g != NULL)
888      {
889        //s_zaehler = deg_w0_p1 - pGetOrder(g);
890        ivtemp = MExpPol(g);
891        MwWd = MivDotProduct(ivtemp, curr_weight);
892        s_zaehler = deg_w0_p1 - MwWd;
893
894        if (s_zaehler != 0)
895        {
896          //s_nenner = MwalkWeightDegree(g, diff_weight) - deg_d0_p1;
897          MwWd = MivDotProduct(ivtemp, diff_weight);
898          s_nenner = MwWd - deg_d0_p1;
899
900          // check for 0 < s <= 1
901          if ( (s_zaehler > 0 && s_nenner >= s_zaehler) ||
902               (s_zaehler < 0 && s_nenner <= s_zaehler) )
903          {
904            // make both positive
905            if (s_zaehler < 0)
906            {
907              s_zaehler = - s_zaehler;
908              s_nenner = - s_nenner;
909            }
910
911            // compute a simply fraction of s
912            cancel(s_zaehler, s_nenner);
913
914            if(t_nenner != 0)
915            {
916              if(s_zaehler * t_nenner < s_nenner * t_zaehler)
917              {
918                t_nenner = s_nenner;
919                t_zaehler = s_zaehler;
920              } 
921            }
922            else
923            {
924              t_nenner = s_nenner;
925              t_zaehler = s_zaehler;
926            }
927          }
928        }
929        pIter(g); //g = g - pHead(g);
930      }
931    }
932  }
933  if(t_nenner == 0)
934  {
935    diff_weight = ivCopy(curr_weight);
936    return diff_weight;
937  }
938
939  if(t_nenner == 1 && t_zaehler == 1)
940  {
941    diff_weight = ivCopy(target_weight);
942    return diff_weight;
943  }
944
945  // construct a new weight vector
946  for (j=0; j<nRing; j++)
947  {
948    (*diff_weight)[j] = t_nenner*(*curr_weight)[j] +
949      t_zaehler*(*diff_weight)[j];
950  }
951
952  // and take out the content
953  temp = (*diff_weight)[0];
954  if(temp != 1)
955    for (j=1; j<nRing; j++)
956    {
957      temp = gcd(temp, (*diff_weight)[j]);
958      if (temp == 1)
959        return diff_weight;
960    }
961
962  for (j=0; j<nRing; j++)
963      (*diff_weight)[j] = (*diff_weight)[j] / temp;
964
965  return diff_weight;
966}
967
968/* Condition: poly f must be divided by the ideal G */
969/* Let f = h1g1+...+hsgs, then the result is (h1, ... ,hs) */
970static ideal MNormalForm(poly f, ideal G)
971{
972  int nG = IDELEMS(G);
973  ideal lmG = idInit(nG, 1);
974  ideal result = idInit(nG, 1);
975  int i, ind=0, ncheck=0;
976
977  for(i=0; i<nG; i++)
978  {
979    lmG->m[i] = pHead(G->m[i]);
980    result->m[i] = NULL;
981  }
982
983  poly h = f;
984  poly lmh, q, pmax = pISet(1), quot, qtmp=NULL;
985  int ntest = 0;
986  while(h != NULL)
987  {
988    lmh = pHead(h);
989    for(i=0; i<nG; i++)
990    {
991      q = MpDiv(lmh, lmG->m[i]);
992
993      if(q != NULL)
994      {
995          if(ncheck == 0)
996          {
997            result->m[i] = pCopy(pAdd(result->m[i], q));
998            h = pSub(h, pMult(q, pCopy(G->m[i])));
999            break;
1000          }
1001          else {
1002            h = pSub(f, pMult(q, pCopy(G->m[i])));
1003            if(quot != NULL)
1004            {
1005              ntest = 1;
1006              qtmp = q;
1007              ind = i;
1008              ncheck = 0;
1009            }
1010          }
1011      }
1012    }
1013    if(i==nG)
1014    {
1015      f = h;
1016      pIter(h);
1017      ncheck = 1;
1018    }
1019
1020    if(ntest == 1)
1021    {
1022      result->m[ind] = pCopy(pAdd(result->m[ind], qtmp));
1023      ntest = 0;
1024    }
1025  }
1026  ideal rest = idCopy(result);
1027  idDelete(&result);
1028  idDelete(&lmG);
1029  return rest;
1030}
1031
1032/* GW is an initial form of the ideal G w.r.t. a weight vector */
1033/* polynom f is divided by the ideal GW                        */
1034/* Let f := h_1.gw_1 + ... + h_s.gw_s, then the result is      */
1035/*          h_1.g_1 + ... + h_s.g_s                            */
1036static poly MpolyConversion(poly f, ideal GW, ideal G)
1037{
1038  ideal H = MNormalForm(f, GW);
1039  ideal HG = MidMultLift(H, G);
1040
1041  poly result = NULL;
1042  int i;
1043  int nG = IDELEMS(G);
1044
1045  for(i=0; i<nG; i++)
1046   result = pCopy(pAdd(result, HG->m[i]));
1047
1048  return result;
1049}
1050
1051/* GW is an initial form of the ideal G w.r.t. a weight vector */
1052/* Each polynom f of the ideal M is divided by the ideal GW    */
1053/* Let m_i := h_1.gw_1 + ... + h_s.gw_s, then the i-th polynom */
1054/* of result is  f_i := h_1.g_1 + ... + h_s.g_s                */
1055ideal MidealConversion(ideal M, ideal GW, ideal G)
1056{
1057  int nM = IDELEMS(M);
1058  int i;
1059
1060  for(i=0; i<nM; i++)
1061  {
1062    M->m[i] = MpolyConversion(M->m[i], GW, G);
1063  }
1064  ideal result = idCopy(M);
1065  return result;
1066}
1067
1068/* check that the monomial f is reduced by a monomial ideal G */
1069static inline int MCheckpRedId(poly f, ideal G)
1070{
1071  int nG = IDELEMS(G);
1072  int i;
1073  poly q;
1074
1075  for(i=0; i<nG; i++)
1076  {
1077    q = MpDiv(f, G->m[i]);
1078    if(q != NULL)
1079      return 0;
1080  }
1081  return 1;
1082}
1083
1084poly MpReduceId(poly f, ideal GO)
1085{
1086  ideal G = idCopy(GO);
1087  int nG = IDELEMS(G);
1088  int i, pcheck;
1089  ideal HG = idInit(nG, 1);
1090
1091  for(i=0; i<nG; i++)
1092    HG->m[i] = pHead(G->m[i]);
1093
1094  poly h = f;
1095  poly lmh, q,qg, result = NULL;
1096
1097  while(h!=NULL)
1098  {
1099    f = pCopy( h);
1100    lmh = pHead(h);
1101
1102    if(MCheckpRedId(lmh, HG) != 0)
1103    {
1104      result = pCopy(pAdd(result, lmh));
1105      pIter(h);
1106    }
1107    else
1108      for(i=0; i<nG; i++)
1109      {
1110        q = MpDiv(lmh, HG->m[i]);
1111        if(q != NULL)
1112        {
1113          f = pAdd(result, f);
1114          qg = pMult(q, G->m[i]);
1115          h = pSub(f, qg);
1116          result = NULL;
1117
1118          lmh = pHead(h);
1119          pcheck = MCheckpRedId(lmh, HG);
1120          if(pcheck != 0)
1121          {
1122            break;
1123          }
1124        }
1125      }
1126 }
1127 idDelete(&HG);
1128 return result;
1129}
1130
1131/* return f, if a head term of f is not divided by a head ideal M */
1132static poly MpMinimId(poly f, ideal M)
1133{
1134  int nM = IDELEMS(M);
1135  ideal HM = idInit(nM, 1);
1136  int i, pcheck;
1137
1138  for(i=0; i<nM; i++)
1139    HM->m[i] = pCopy(M->m[i]);
1140
1141  poly result = pCopy(f);
1142  poly hf=pHead(f), q, qtmp, h=f;
1143
1144  if(MCheckpRedId(pHead(f), HM) != 0)
1145    goto FINISH;
1146
1147  while(1)
1148  {
1149    for(i=0; i<nM; i++)
1150    {
1151      q = MpDiv(hf, HM->m[i]);
1152      if(q != NULL)
1153        {
1154          qtmp = pMult(q, M->m[i]);
1155          h = pSub(h, qtmp);
1156
1157          hf = pHead(h);
1158          pcheck = MCheckpRedId(hf, HM);
1159          if(pcheck != 0)
1160          {
1161            result = pCopy(h);
1162            goto FINISH;       
1163          }
1164          break;
1165        }
1166    }
1167 }
1168
1169 FINISH:
1170 idDelete(&HM);
1171 return result;
1172}
1173
1174/* return a minimal ideal of an ideal M */
1175ideal MidMinimId(ideal M)
1176{
1177  int i,j=0;
1178  ideal result = idInit(IDELEMS(M),1);
1179  poly pmin;
1180  for(i=0; i<IDELEMS(M); i++)
1181  {
1182    ideal Mtmp = idCopy(M);
1183    Mtmp->m[j] = NULL;
1184    idSkipZeroes(Mtmp);
1185    pmin = MpMinimId(pCopy(M->m[i]), Mtmp);
1186    M->m[i] = pCopy(pmin);
1187    result->m[j] = pmin;
1188    if(pmin == NULL)
1189    {
1190      i--;
1191      j--;
1192      idSkipZeroes(M);
1193    }
1194    j++;
1195    idDelete(&Mtmp);
1196  }
1197  idSkipZeroes(result);
1198  ideal res = idCopy(result);
1199  idDelete(&result);
1200  return res;
1201}
1202
1203
1204ideal MidMinBase(ideal G)
1205{
1206  if(G == NULL)
1207    return G;
1208
1209    intvec * wth;
1210    lists re = min_std(G,currQuotient,(tHomog)TRUE,&wth,NULL,0,3);
1211    G = (ideal)re->m[1].data;
1212    re->m[1].data = NULL;
1213    re->m[1].rtyp = NONE;
1214    re->Clean();
1215
1216  return G;
1217}
1218
1219
1220/* compute a Groebner basis of a homogenoues ideal */
1221ideal MNWstdhomRed(ideal G, intvec* iv)
1222{
1223
1224  ideal Gomega = MwalkInitialForm(G, iv);
1225  G = kStd(Gomega, NULL, isHomog, NULL);
1226  Gomega = MkInterRed(G);
1227
1228  return Gomega;
1229}
1230
1231/*****************************************************************************
1232* If target_ord = intmat(A1,..., An) then calculate the perturbation vectors *
1233*     tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg   *
1234* where                                                                      *
1235*     inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                     *
1236* and                                                                        *
1237*     p_deg <= the number of variables of a basering                         *
1238******************************************************************************/
1239intvec* Mfivpert(ideal G, intvec* target, int p_deg)
1240{
1241  int i, j;
1242  int nV = currRing->N;
1243
1244  //Checking that the perturbation degree is valid
1245  if(p_deg > nV || p_deg <= 0)
1246  {
1247    WerrorS("The perturbed degree is wrong!!");
1248    return NULL;
1249  }
1250
1251  // Calculate max_el_rows = Max(A2)+Max(A3)+...+Max(Ap_deg),
1252  //    where the Ai are the rows of the target-order matrix.
1253  int nmax = 0, maxAi, ntemp;
1254
1255  for(i=1; i < p_deg; i++)
1256  {
1257    maxAi = (*target)[i*nV];
1258    for(j=1; j < nV; j++)
1259    {
1260      ntemp = (*target)[i*nV + j];
1261      if(ntemp > maxAi)
1262        maxAi = ntemp;
1263    }
1264    nmax += maxAi;
1265  }
1266
1267  // Calculate inv_eps := 1/eps, where 1/eps > deg(p)*max_el_rows
1268  //        for all p in G.
1269  int inv_eps, degG, max_deg=0;
1270  intvec* ivUnit = Mivdp(nV);
1271
1272  for (i=0; i<IDELEMS(G); i++)
1273  {
1274    degG = MwalkWeightDegree(G->m[i], ivUnit);
1275    if(degG > max_deg)
1276      max_deg = degG;
1277  }
1278  inv_eps = (max_deg * nmax) + 1;
1279
1280
1281  // Calculate the perturbed target order:
1282  // Since a weight vector in Singular has to be in integral, we compute
1283  // tau_p_deg = inv_eps^(p_deg-1)*A1 - inv_eps^(p_deg-2)*A2+...+A_p_deg,
1284
1285  intvec* ivtemp = new intvec(nV);
1286  intvec* pert_vector = new intvec(nV);
1287
1288  for(i=0; i<nV; i++)
1289  {
1290    ntemp = (*target)[i];
1291    (* ivtemp)[i] = ntemp;
1292    (* pert_vector)[i] = ntemp;
1293  }
1294
1295  for(i=1; i<p_deg; i++)
1296  {
1297    for(j=0; j<nV; j++)
1298      (* ivtemp)[j] = inv_eps*(*ivtemp)[j] + (*target)[i*nV+j];
1299
1300    pert_vector = ivtemp;
1301  }
1302  omFree((ADDRESS) ivtemp);
1303  return pert_vector;
1304}
1305
1306ideal MpHeadIdeal(ideal G)
1307{
1308  int i, nG = IDELEMS(G);
1309  ideal result = idInit(nG,1);
1310
1311  for(i=0; i<nG; i++)
1312  {
1313    result->m[i] = pHead(G->m[i]);
1314  }
1315
1316  ideal res = idCopy(result);
1317  idDelete(&result);
1318  return res;
1319}
1320
1321void* checkideal(ideal G)
1322{
1323  int i;
1324  printf("//** Size(G)= %d, and ", IDELEMS(G));
1325
1326  for(i=0; i<IDELEMS(G); i++)
1327  {
1328    printf("G[%d] = %d, ", i, pLength(G->m[i]));
1329  }
1330  printf("\n");
1331}
1332
Note: See TracBrowser for help on using the repository browser.