source: git/kernel/hilb.cc @ 6a9f2e

spielwiese
Last change on this file since 6a9f2e was 762407, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
config.h is for sources files only FIX: config.h should only be used by source (not from inside kernel/mod2.h!) NOTE: each source file should better include mod2.h right after config.h, while headers should better not include mod2.h.
  • Property mode set to 100644
File size: 9.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6*  ABSTRACT -  Hilbert series
7*/
8
9#include "config.h"
10#include <kernel/mod2.h>
11#include <kernel/structs.h>
12#include <kernel/febase.h>
13#include <omalloc/omalloc.h>
14#include <kernel/polys.h>
15#include <misc/intvec.h>
16#include <kernel/hutil.h>
17#include <kernel/stairc.h>
18
19static int  **Qpol;
20static int  *Q0, *Ql;
21static int  hLength;
22
23static int hMinModulweight(intvec *modulweight)
24{
25  int i,j,k;
26
27  if(modulweight==NULL) return 0;
28  j=(*modulweight)[0];
29  for(i=modulweight->rows()-1;i!=0;i--)
30  {
31    k=(*modulweight)[i];
32    if(k<j) j=k;
33  }
34  return j;
35}
36
37static void hHilbEst(scfmon stc, int Nstc, varset var, int Nvar)
38{
39  int  i, j;
40  int  x, y, z = 1;
41  int  *p;
42  for (i = Nvar; i>0; i--)
43  {
44    x = 0;
45    for (j = 0; j < Nstc; j++)
46    {
47      y = stc[j][var[i]];
48      if (y > x)
49        x = y;
50    }
51    z += x;
52    j = i - 1;
53    if (z > Ql[j])
54    {
55      if (z>(MAX_INT_VAL)/2)
56      {
57       Werror("interal arrays too big");
58       return;
59      }
60      p = (int *)omAlloc((unsigned long)z * sizeof(int));
61      if (Ql[j]!=0)
62      {
63        if (j==0)
64          memcpy(p, Qpol[j], Ql[j] * sizeof(int));
65        omFreeSize((ADDRESS)Qpol[j], Ql[j] * sizeof(int));
66      }
67      if (j==0)
68      {
69        for (x = Ql[j]; x < z; x++)
70          p[x] = 0;
71      }
72      Ql[j] = z;
73      Qpol[j] = p;
74    }
75  }
76}
77
78static int  *hAddHilb(int Nv, int x, int *pol, int *lp)
79{
80  int  l = *lp, ln, i;
81  int  *pon;
82  *lp = ln = l + x;
83  pon = Qpol[Nv];
84  memcpy(pon, pol, l * sizeof(int));
85  if (l > x)
86  {
87    for (i = x; i < l; i++)
88      pon[i] -= pol[i - x];
89    for (i = l; i < ln; i++)
90      pon[i] = -pol[i - x];
91  }
92  else
93  {
94    for (i = l; i < x; i++)
95      pon[i] = 0;
96    for (i = x; i < ln; i++)
97      pon[i] = -pol[i - x];
98  }
99  return pon;
100}
101
102static void hLastHilb(scmon pure, int Nv, varset var, int *pol, int lp)
103{
104  int  l = lp, x, i, j;
105  int  *p, *pl;
106  p = pol;
107  for (i = Nv; i>0; i--)
108  {
109    x = pure[var[i + 1]];
110    if (x!=0)
111      p = hAddHilb(i, x, p, &l);
112  }
113  pl = *Qpol;
114  j = Q0[Nv + 1];
115  for (i = 0; i < l; i++)
116    pl[i + j] += p[i];
117  x = pure[var[1]];
118  if (x!=0)
119  {
120    j += x;
121    for (i = 0; i < l; i++)
122      pl[i + j] -= p[i];
123  }
124  j += l;
125  if (j > hLength)
126    hLength = j;
127}
128
129static void hHilbStep(scmon pure, scfmon stc, int Nstc, varset var,
130 int Nvar, int *pol, int Lpol)
131{
132  int  iv = Nvar -1, ln, a, a0, a1, b, i;
133  int  x, x0;
134  scmon pn;
135  scfmon sn;
136  int  *pon;
137  if (Nstc==0)
138  {
139    hLastHilb(pure, iv, var, pol, Lpol);
140    return;
141  }
142  x = a = 0;
143  pn = hGetpure(pure);
144  sn = hGetmem(Nstc, stc, stcmem[iv]);
145  hStepS(sn, Nstc, var, Nvar, &a, &x);
146  Q0[iv] = Q0[Nvar];
147  ln = Lpol;
148  pon = pol;
149  if (a == Nstc)
150  {
151    x = pure[var[Nvar]];
152    if (x!=0)
153      pon = hAddHilb(iv, x, pon, &ln);
154    hHilbStep(pn, sn, a, var, iv, pon, ln);
155    return;
156  }
157  else
158  {
159    pon = hAddHilb(iv, x, pon, &ln);
160    hHilbStep(pn, sn, a, var, iv, pon, ln);
161  }
162  b = a;
163  x0 = 0;
164  loop
165  {
166    Q0[iv] += (x - x0);
167    a0 = a;
168    x0 = x;
169    hStepS(sn, Nstc, var, Nvar, &a, &x);
170    hElimS(sn, &b, a0, a, var, iv);
171    a1 = a;
172    hPure(sn, a0, &a1, var, iv, pn, &i);
173    hLex2S(sn, b, a0, a1, var, iv, hwork);
174    b += (a1 - a0);
175    ln = Lpol;
176    if (a < Nstc)
177    {
178      pon = hAddHilb(iv, x - x0, pol, &ln);
179      hHilbStep(pn, sn, b, var, iv, pon, ln);
180    }
181    else
182    {
183      x = pure[var[Nvar]];
184      if (x!=0)
185        pon = hAddHilb(iv, x - x0, pol, &ln);
186      else
187        pon = pol;
188      hHilbStep(pn, sn, b, var, iv, pon, ln);
189      return;
190    }
191  }
192}
193
194/*
195*basic routines
196*/
197static void hWDegree(intvec *wdegree)
198{
199  int i, k;
200  int x;
201
202  for (i=(currRing->N); i; i--)
203  {
204    x = (*wdegree)[i-1];
205    if (x != 1)
206    {
207      for (k=hNexist-1; k>=0; k--)
208      {
209        hexist[k][i] *= x;
210      }
211    }
212  }
213}
214
215static intvec * hSeries(ideal S, intvec *modulweight,
216                int notstc, intvec *wdegree, ideal Q, ring tailRing)
217{
218  intvec *work, *hseries1=NULL;
219  int  mc;
220  int  p0;
221  int  i, j, k, l, ii, mw;
222  hexist = hInit(S, Q, &hNexist, tailRing);
223  if (hNexist==0)
224  {
225    hseries1=new intvec(2);
226    (*hseries1)[0]=1;
227    (*hseries1)[1]=0;
228    return hseries1;
229  }
230
231  #if 0
232  if (wdegree == NULL)
233    hWeight();
234  else
235    hWDegree(wdegree);
236  #else
237  if (wdegree != NULL) hWDegree(wdegree);
238  #endif
239
240  p0 = 1;
241  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
242  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
243  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
244  stcmem = hCreate((currRing->N) - 1);
245  Qpol = (int **)omAlloc(((currRing->N) + 1) * sizeof(int *));
246  Ql = (int *)omAlloc0(((currRing->N) + 1) * sizeof(int));
247  Q0 = (int *)omAlloc(((currRing->N) + 1) * sizeof(int));
248  *Qpol = NULL;
249  hLength = k = j = 0;
250  mc = hisModule;
251  if (mc!=0)
252  {
253    mw = hMinModulweight(modulweight);
254    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
255  }
256  else
257  {
258    mw = 0;
259    hstc = hexist;
260    hNstc = hNexist;
261  }
262  loop
263  {
264    if (mc!=0)
265    {
266      hComp(hexist, hNexist, mc, hstc, &hNstc);
267      if (modulweight != NULL)
268        j = (*modulweight)[mc-1]-mw;
269    }
270    if (hNstc!=0)
271    {
272      hNvar = (currRing->N);
273      for (i = hNvar; i>=0; i--)
274        hvar[i] = i;
275      //if (notstc) // TODO: no mon divides another
276        hStaircase(hstc, &hNstc, hvar, hNvar);
277      hSupp(hstc, hNstc, hvar, &hNvar);
278      if (hNvar!=0)
279      {
280        if ((hNvar > 2) && (hNstc > 10))
281          hOrdSupp(hstc, hNstc, hvar, hNvar);
282        hHilbEst(hstc, hNstc, hvar, hNvar);
283        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
284        hPure(hstc, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
285        hLexS(hstc, hNstc, hvar, hNvar);
286        Q0[hNvar] = 0;
287        hHilbStep(hpure, hstc, hNstc, hvar, hNvar, &p0, 1);
288      }
289    }
290    else
291    {
292      if(*Qpol!=NULL)
293        (**Qpol)++;
294      else
295      {
296        *Qpol = (int *)omAlloc(sizeof(int));
297        hLength = *Ql = **Qpol = 1;
298      }
299    }
300    if (*Qpol!=NULL)
301    {
302      i = hLength;
303      while ((i > 0) && ((*Qpol)[i - 1] == 0))
304        i--;
305      if (i > 0)
306      {
307        l = i + j;
308        if (l > k)
309        {
310          work = new intvec(l);
311          for (ii=0; ii<k; ii++)
312            (*work)[ii] = (*hseries1)[ii];
313          if (hseries1 != NULL)
314            delete hseries1;
315          hseries1 = work;
316          k = l;
317        }
318        while (i > 0)
319        {
320          (*hseries1)[i + j - 1] += (*Qpol)[i - 1];
321          (*Qpol)[i - 1] = 0;
322          i--;
323        }
324      }
325    }
326    mc--;
327    if (mc <= 0)
328      break;
329  }
330  if (k==0)
331  {
332    hseries1=new intvec(2);
333    (*hseries1)[0]=0;
334    (*hseries1)[1]=0;
335  }
336  else
337  {
338    l = k+1;
339    while ((*hseries1)[l-2]==0) l--;
340    if (l!=k)
341    {
342      work = new intvec(l);
343      for (ii=l-2; ii>=0; ii--)
344        (*work)[ii] = (*hseries1)[ii];
345      delete hseries1;
346      hseries1 = work;
347    }
348    (*hseries1)[l-1] = mw;
349  }
350  for (i = 0; i <= (currRing->N); i++)
351  {
352    if (Ql[i]!=0)
353      omFreeSize((ADDRESS)Qpol[i], Ql[i] * sizeof(int));
354  }
355  omFreeSize((ADDRESS)Q0, ((currRing->N) + 1) * sizeof(int));
356  omFreeSize((ADDRESS)Ql, ((currRing->N) + 1) * sizeof(int));
357  omFreeSize((ADDRESS)Qpol, ((currRing->N) + 1) * sizeof(int *));
358  hKill(stcmem, (currRing->N) - 1);
359  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
360  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
361  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
362  hDelete(hexist, hNexist);
363  if (hisModule!=0)
364    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
365  return hseries1;
366}
367
368
369intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q, ring tailRing)
370{
371  return hSeries(S, modulweight, 0, wdegree, Q, tailRing);
372}
373
374intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
375{
376  return hSeries(S, modulweight, 1, wdegree, Q, tailRing);
377}
378
379intvec * hSecondSeries(intvec *hseries1)
380{
381  intvec *work, *hseries2;
382  int i, j, k, s, t, l;
383  if (hseries1 == NULL)
384    return NULL;
385  work = new intvec(hseries1);
386  k = l = work->length()-1;
387  s = 0;
388  for (i = k-1; i >= 0; i--)
389    s += (*work)[i];
390  loop
391  {
392    if ((s != 0) || (k == 1))
393      break;
394    s = 0;
395    t = (*work)[k-1];
396    k--;
397    for (i = k-1; i >= 0; i--)
398    {
399      j = (*work)[i];
400      (*work)[i] = -t;
401      s += t;
402      t += j;
403    }
404  }
405  hseries2 = new intvec(k+1);
406  for (i = k-1; i >= 0; i--)
407    (*hseries2)[i] = (*work)[i];
408  (*hseries2)[k] = (*work)[l];
409  delete work;
410  return hseries2;
411}
412
413void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu)
414{
415  int m, i, j, k;
416  *co = *mu = 0;
417  if ((s1 == NULL) || (s2 == NULL))
418    return;
419  i = s1->length();
420  j = s2->length();
421  if (j > i)
422    return;
423  m = 0;
424  for(k=j-2; k>=0; k--)
425    m += (*s2)[k];
426  *mu = m;
427  *co = i - j;
428}
429
430static void hPrintHilb(intvec *hseries)
431{
432  int  i, j, l, k;
433  if (hseries == NULL)
434    return;
435  l = hseries->length()-1;
436  k = (*hseries)[l];
437  for (i = 0; i < l; i++)
438  {
439    j = (*hseries)[i];
440    if (j != 0)
441    {
442      Print("//  %8d t^%d\n", j, i+k);
443    }
444  }
445}
446
447/*
448*caller
449*/
450void hLookSeries(ideal S, intvec *modulweight, ideal Q)
451{
452  int co, mu, l;
453  intvec *hseries2;
454  intvec *hseries1 = hFirstSeries(S, modulweight, Q);
455  hPrintHilb(hseries1);
456  l = hseries1->length()-1;
457  if (l > 1)
458    hseries2 = hSecondSeries(hseries1);
459  else
460    hseries2 = hseries1;
461  hDegreeSeries(hseries1, hseries2, &co, &mu);
462  PrintLn();
463  hPrintHilb(hseries2);
464  if ((l == 1) &&(mu == 0))
465    scPrintDegree((currRing->N)+1, 0);
466  else
467    scPrintDegree(co, mu);
468  if (l>1)
469    delete hseries1;
470  delete hseries2;
471}
472
Note: See TracBrowser for help on using the repository browser.