source: git/Singular/walk.cc @ dc0898

fieker-DuValspielwiese
Last change on this file since dc0898 was 477993, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* new Makefile target: Singulart whcih enables mtrack * Macros for allocating intvecs: NewIntvec git-svn-id: file:///usr/local/Singular/svn/trunk@3767 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: walk.cc,v 1.2 1999-10-22 11:14:20 obachman Exp $ */
5/*
6* ABSTRACT: Implementation of the Groebner walk
7*/
8
9#include "mod2.h"
10#include "walk.h"
11#include "polys.h"
12#include "ideals.h"
13#include "intvec.h"
14#include "ipid.h"
15
16
17// scalar product of weights and exponent vector of p
18// assumes that weights and exponent vector have length n
19inline long walkWeightDegree(const poly p, const int* weights,
20                             const long n)
21{
22  assume(p != NULL && weights != NULL);
23
24  long i, res = 0;
25
26  for (i=0; i<n; i++) res += pGetExp(p, i+1) * weights[i];
27
28  return res;
29}
30
31
32// returns gcd of integers a and b
33inline long gcd(const long a, const long b)
34{
35  long r, p0 = a, p1 = b;
36  assume(p0 >= 0 && p1 >= 0);
37
38  while(p1 != 0)
39  {
40    r = p0 % p1;
41    p0 = p1;
42    p1 = r;
43  }
44  return p0;
45}
46
47// cancel gcd of integers zaehler and nenner
48inline void cancel(long &zaehler, long &nenner)
49{
50  assume(zaehler >= 0 && nenner > 0);
51  long g = gcd(zaehler, nenner);
52  if (g > 1)
53  {
54    zaehler = zaehler / g;
55    nenner = nenner / g;
56  }
57}
58
59// Returns the next Weight vector for the Groebner walk
60// Assumes monoms of polys of G are ordered decreasingly w.r.t. curr_weight
61int* walkNextWeight(const int* curr_weight,
62                    const int* target_weight,
63                    const ideal G)
64{
65  assume(currRing != NULL && target_weight != NULL && curr_weight != NULL &&
66         G != NULL);
67
68  int* diff_weight =
69    (int*)Alloc(currRing->N*sizeof(int));
70  long j, t_zaehler = 0, t_nenner = 0;
71
72  for (j=0; j<currRing->N; j++)
73    diff_weight[j] = target_weight[j] - curr_weight[j];
74
75  for (j=0; j<IDELEMS(G); j++)
76  {
77    poly g = G->m[j];
78    if (g != 0)
79    {
80      long deg_w0_p1 = pGetOrder(g);
81      long deg_d0_p1 = walkWeightDegree(g, diff_weight, currRing->N);
82
83      pIter(g);
84
85      while (g != NULL)
86      {
87        // compute s = s_zahler / s_nenner
88        long s_zaehler = deg_w0_p1 - pGetOrder(g);
89
90        if (s_zaehler != 0)
91        {
92          long s_nenner =
93            walkWeightDegree(g, diff_weight, currRing->N) - deg_d0_p1;
94          // check for 0 < s <= 1
95          if ( (s_zaehler > 0 && s_nenner >= s_zaehler) ||
96               (s_zaehler < 0 && s_nenner <= s_zaehler) )
97          {
98            // make both positive
99            if (s_zaehler < 0)
100            {
101              s_zaehler = - s_zaehler;
102              s_nenner = - s_nenner;
103            }
104
105            // look whether s < t
106            if (t_nenner == 0 ||
107                s_zaehler*t_nenner < t_zaehler * s_nenner)
108            {
109              cancel(s_zaehler, s_nenner);
110              t_zaehler = s_zaehler;
111              t_nenner = s_nenner;
112            }
113          }
114        }
115        pIter(g);
116      }
117    }
118  }
119
120  // return if no t or if t == 1
121  if (t_nenner == 0 || t_nenner == 1)
122  {
123    Free(diff_weight, currRing->N*sizeof(int));
124    return  (int*) t_nenner;
125  }
126
127  // construct new weight vector
128  for (j=0; j<currRing->N; j++)
129    diff_weight[j] = t_nenner*curr_weight[j] + t_zaehler*diff_weight[j];
130  // and take out the content
131  long temp = diff_weight[0];
132
133  for (j=1; j<currRing->N && temp != 1; j++)
134  {
135    temp = gcd(temp, diff_weight[j]);
136    if (temp == 1) goto Finish;
137  }
138
139  for (j=0; j<currRing->N; j++)
140      diff_weight[j] = diff_weight[j] / temp;
141
142  Finish:
143  return diff_weight;
144}
145
146
147// next weight vector given weights as intvecs
148intvec* walkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G)
149{
150  assume(curr_weight->length() == currRing->N);
151  assume(target_weight->length() == currRing->N);
152
153  int* nw = walkNextWeight(curr_weight->ivGetVec(),
154                           target_weight->ivGetVec(),
155                           G);
156  intvec* next_weight;
157
158  if (nw != NULL && nw != (int*) 1)
159  {
160    next_weight = NewIntvec1(currRing->N);
161    int *nw_i = next_weight->ivGetVec();
162    int i;
163
164    for (i=0; i<currRing->N; i++)
165      nw_i[i] = nw[i];
166    Free(nw, (currRing->N)*sizeof(int));
167  }
168  else
169  {
170    next_weight = (intvec*) nw;
171  }
172
173  return next_weight;
174}
175
176
177// returns ideals of initials (w.r.t. curr_weight) of ideal G
178// assumes that monoms are ordered by descending W-degree (w.r.t curr_weight)
179
180poly walkInitials(poly p)
181{
182  assume(p != NULL);
183
184  poly pi = pHead(p);
185  poly pr = pi;
186  long d_lm = pGetOrder(p);
187
188  pIter(p);
189
190  while (p != NULL && pGetOrder(p) == d_lm)
191  {
192    pNext(pi) = pHead(p);
193    pIter(pi);
194    pIter(p);
195  }
196
197  assume(p == NULL || pGetOrder(p) < d_lm);
198
199  pNext(pi) = NULL;
200  pTest(pr);
201  return pr;
202}
203
204ideal walkInitials(ideal G)
205{
206  ideal GI = idInit(IDELEMS(G),1);
207  int i;
208
209  for (i=0; i<IDELEMS(G); i++)
210    GI->m[i] = walkInitials(G->m[i]);
211
212  return GI;
213}
Note: See TracBrowser for help on using the repository browser.