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

spielwiese
Last change on this file since 8cfee1c was 847242, checked in by Imade Sulandra <sulandra@…>, 24 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@4573 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: walk.cc,v 1.4 2000-09-07 13:39:45 sulandra 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// add two intvecs:
17intvec* walkAddIntVec(intvec* v1, intvec* v2)
18{
19  int n = v1->length();
20  int i;
21  intvec *result = new intvec(n);
22  if (v2->length() > n) n = v2->length();
23 
24  for (i=0; i<n; i++)
25  {
26    (*result)[i] = (*v1)[i] + (*v2)[i];
27  }
28 
29  return result;
30}
31
32 
33 
34
35// scalar product of weights and exponent vector of p
36// assumes that weights and exponent vector have length n
37inline long walkWeightDegree(const poly p, const int* weights,
38                             const long n)
39{
40  assume(p != NULL && weights != NULL);
41
42  long i, res = 0;
43
44  for (i=0; i<n; i++) res += pGetExp(p, i+1) * weights[i];
45
46  return res;
47}
48
49
50// returns gcd of integers a and b
51inline long gcd(const long a, const long b)
52{
53  long r, p0 = a, p1 = b;
54  assume(p0 >= 0 && p1 >= 0);
55
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
66inline 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// Returns the next Weight vector for the Groebner walk
78// Assumes monoms of polys of G are ordered decreasingly w.r.t. curr_weight
79int* walkNextWeight(const int* curr_weight,
80                    const int* target_weight,
81                    const ideal G)
82{
83  assume(currRing != NULL && target_weight != NULL && curr_weight != NULL &&
84         G != NULL);
85
86  int* diff_weight =
87    (int*)omAlloc(currRing->N*sizeof(int));
88  long j, t_zaehler = 0, t_nenner = 0;
89
90  for (j=0; j<currRing->N; j++)
91    diff_weight[j] = target_weight[j] - curr_weight[j];
92
93  for (j=0; j<IDELEMS(G); j++)
94  {
95    poly g = G->m[j];
96    if (g != 0)
97    {
98      long deg_w0_p1 = pGetOrder(g);
99      long deg_d0_p1 = walkWeightDegree(g, diff_weight, currRing->N);
100
101      pIter(g);
102
103      while (g != NULL)
104      {
105        // compute s = s_zahler / s_nenner
106        long s_zaehler = deg_w0_p1 - pGetOrder(g);
107
108        if (s_zaehler != 0)
109        {
110          long s_nenner =
111            walkWeightDegree(g, diff_weight, currRing->N) - deg_d0_p1;
112          // check for 0 < s <= 1
113          if ( (s_zaehler > 0 && s_nenner >= s_zaehler) ||
114               (s_zaehler < 0 && s_nenner <= s_zaehler) )
115          {
116            // make both positive
117            if (s_zaehler < 0)
118            {
119              s_zaehler = - s_zaehler;
120              s_nenner = - s_nenner;
121            }
122
123            // look whether s < t
124            if (t_nenner == 0 ||
125                s_zaehler*t_nenner < t_zaehler * s_nenner)
126            {
127              cancel(s_zaehler, s_nenner);
128              t_zaehler = s_zaehler;
129              t_nenner = s_nenner;
130            }
131          }
132        }
133        pIter(g);
134      }
135    }
136  }
137
138  // return if no t or if t == 1
139  if (t_nenner == 0 || t_nenner == 1)
140  {
141    omFreeSize(diff_weight, currRing->N*sizeof(int));
142    return  (int*) t_nenner;
143  }
144
145  // construct new weight vector
146  for (j=0; j<currRing->N; j++)
147    diff_weight[j] = t_nenner*curr_weight[j] + t_zaehler*diff_weight[j];
148  // and take out the content
149  long temp = diff_weight[0];
150
151  for (j=1; j<currRing->N && temp != 1; j++)
152  {
153    temp = gcd(temp, diff_weight[j]);
154    if (temp == 1) goto Finish;
155  }
156
157  for (j=0; j<currRing->N; j++)
158      diff_weight[j] = diff_weight[j] / temp;
159
160  Finish:
161  return diff_weight;
162}
163
164
165// next weight vector given weights as intvecs
166intvec* walkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G)
167{
168  assume(curr_weight->length() == currRing->N);
169  assume(target_weight->length() == currRing->N);
170
171  int* nw = walkNextWeight(curr_weight->ivGetVec(),
172                           target_weight->ivGetVec(),
173                           G);
174  intvec* next_weight;
175
176  if (nw != NULL && nw != (int*) 1)
177  {
178    next_weight = new intvec(currRing->N);
179    int *nw_i = next_weight->ivGetVec();
180    int i;
181
182    for (i=0; i<currRing->N; i++)
183      nw_i[i] = nw[i];
184    omFreeSize(nw, (currRing->N)*sizeof(int));
185  }
186  else
187  {
188    next_weight = (intvec*) nw;
189  }
190
191  return next_weight;
192}
193
194
195// returns ideals of initials (w.r.t. curr_weight) of ideal G
196// assumes that monoms are ordered by descending W-degree (w.r.t curr_weight)
197
198poly walkInitials(poly p)
199{
200  assume(p != NULL);
201
202  poly pi = pHead(p);
203  poly pr = pi;
204  long d_lm = pGetOrder(p);
205
206  pIter(p);
207
208  while (p != NULL && pGetOrder(p) == d_lm)
209  {
210    pNext(pi) = pHead(p);
211    pIter(pi);
212    pIter(p);
213  }
214
215  assume(p == NULL || pGetOrder(p) < d_lm);
216
217  pNext(pi) = NULL;
218  pTest(pr);
219  return pr;
220}
221
222ideal walkInitials(ideal G)
223{
224  ideal GI = idInit(IDELEMS(G),1);
225  int i;
226
227  for (i=0; i<IDELEMS(G); i++)
228    GI->m[i] = walkInitials(G->m[i]);
229
230  return GI;
231}
Note: See TracBrowser for help on using the repository browser.