source: git/Singular/LIB/bfct.lib @ a470eb

spielwiese
Last change on this file since a470eb was a470eb, checked in by Viktor Levandovskyy <levandov@…>, 15 years ago
*levandov: minor bugfixes and docu git-svn-id: file:///usr/local/Singular/svn/trunk@11229 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 32.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: bfct.lib,v 1.7 2008-12-09 16:50:21 levandov Exp $";
3category="Noncommutative";
4info="
5LIBRARY: bfct.lib     M. Noro's Algorithm for Bernstein-Sato polynomial
6AUTHORS: Daniel Andres, daniel.andres@math.rwth-aachen.de
7@* Viktor Levandovskyy,      levandov@math.rwth-aachen.de
8
9THEORY: Given a polynomial ring R = K[x_1,...,x_n] and a polynomial F in R,
10@*      one is interested in the global Bernstein-Sato polynomial b(s) in K[s],
11@*      defined to be the monic polynomial, satisfying a functional identity
12@*             L * f^{s+1} = b(s) f^s,   for some operator L in D[s].
13@* Here, D stands for an n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>
14@* One is interested in the following data:
15@*   global Bernstein-Sato polynomial in K[s] and
16@*   the list of all roots of b(s), which are known to be rational, with their multiplicities.
17
18MAIN PROCEDURES:
19
20bfct(f[,s,t,v]);            compute the global Bernstein-Sato polynomial of a given poly
21bfctsyz(f[,r,s,t,u,v]);     compute the global Bernstein-Sato polynomial of a given poly
22bfctann(f[,s]);             compute the global Bernstein-Sato polynomial of a given poly
23bfctonestep(f[,s,t]);       compute the global Bernstein-Sato polynomial of a given poly
24bfctideal(I,w[,s,t]);       compute the global b-function of a given ideal w.r.t. a given weight
25pintersect(f,I);            compute the intersection of the ideal generated by a given poly with a given ideal
26pintersectsyz(f,I[,p,s,t]); compute the intersection of the ideal generated by a given poly with a given ideal
27linreduce(f,I[,s]);         reduce a poly by linear reductions only
28ncsolve(I[,s]);             find and compute a linear dependency of the elements of an ideal
29
30AUXILIARY PROCEDURES:
31
32ispositive(v);   check whether all entries of an intvec are positive
33isin(l,i);       check whether an element is a member of a list
34scalarprod(v,w); compute the standard scalar product of two intvecs
35vec2poly(v[,i]); convert a coefficient vector to a poly
36
37SEE ALSO: dmod_lib, dmodapp_lib, gmssing_lib
38";
39
40
41LIB "qhmoduli.lib"; // for Max
42LIB "dmod.lib"; // for SannfsBFCT etc
43LIB "dmodapp.lib";  // for initialideal etc
44
45
46proc testbfctlib ()
47{
48  // tests all procs for consistency
49  "AUXILIARY PROCEDURES:";
50  example ispositive;
51  example isin;
52  example scalarprod;
53  example vec2poly;
54  "MAIN PROCEDURES:";
55  example bfct;
56  example bfctsyz;
57  example bfctann;
58  example bfctonestep;
59  example bfctideal;
60  example pintersect;
61  example pintersectsyz;
62  example linreduce;
63  example ncsolve;
64}
65
66
67//--------------- auxiliary procedures ---------------------------------------------------------
68
69static proc gradedWeyl (intvec u,intvec v)
70"USAGE:  gradedWeyl(u,v); u,v intvecs
71RETURN:  a ring, the associated graded ring of the basering w.r.t. u and v
72PURPOSE: compute the associated graded ring of the basering w.r.t. u and v
73EXAMPLE: example gradedWeyl; shows examples
74NOTE:    u[i] is the weight of x(i), v[i] the weight of D(i).
75@*       u+v has to be a non-negative intvec.
76"
77{
78  int i;
79  def save = basering;
80  int n = nvars(save)/2;
81  if (nrows(u)<>n || nrows(v)<>n)
82  {
83    ERROR("weight vectors have wrong dimension");
84  }
85  intvec uv,gr;
86  uv = u+v;
87  for (i=1; i<=n; i++)
88  {
89    if (uv[i]>=0)
90    {
91      if (uv[i]==0)
92      {
93        gr[i] = 0;
94      }
95      else
96      {
97        gr[i] = 1;
98      }
99    }
100    else
101    {
102      ERROR("the sum of the weight vectors has to be a non-negative intvec");
103    }
104  }
105  list l = ringlist(save);
106  list l2 = l[2];
107  matrix l6 = l[6];
108  for (i=1; i<=n; i++)
109  {
110    if (gr[i] == 1) 
111    {
112       l2[n+i] = "xi("+string(i)+")";
113       l6[i,n+i] = 0;
114    }
115  }
116  l[2] = l2;
117  l[6] = l6;
118  def G = ring(l);
119  return(G);
120}
121example
122{
123  "EXAMPLE:"; echo = 2;
124  LIB "bfct.lib";
125  ring @D = 0,(x,y,z,Dx,Dy,Dz),dp;
126  def D = Weyl();
127  setring D;
128  intvec u = -1,-1,1; intvec v = 2,1,1;
129  def G = gradedWeyl(u,v);
130  setring G; G;
131}
132
133
134proc ispositive (intvec v)
135"USAGE:  ispositive(v);  v an intvec
136RETURN:  1 if all components of v are positive, or 0 otherwise
137PURPOSE: check whether all components of an intvec are positive
138EXAMPLE: example ispositive; shows an example
139"
140{
141  int i;
142  for (i=1; i<=size(v); i++)
143  {
144    if (v[i]<=0)
145    {
146      return(0);
147      break;
148    }
149  }
150  return(1);
151}
152example
153{
154  "EXAMPLE:"; echo = 2;
155  intvec v = 1,2,3;
156  ispositive(v);
157  intvec w = 1,-2,3;
158  ispositive(w);
159}
160
161proc isin (list l, i)
162"USAGE:  isin(l,i);  l a list, i an argument of any type
163RETURN:  an int, the position of the first appearance of i in l, or 0 if i is not a member of l
164PURPOSE: check whether the second argument is a member of a list
165EXAMPLE: example isin; shows an example
166"
167{
168  int j;
169  for (j=1; j<=size(l); j++)
170  {
171    if (l[j]==i)
172    {
173      return(j);
174      break;
175    }
176  }
177  return(0);
178}
179example
180{
181  "EXAMPLE:"; echo = 2;
182  ring r = 0,x,dp;
183  list l = 1,2,3;
184  isin(l,4);
185  isin(l,2);
186}
187
188proc scalarprod (intvec v, intvec w)
189"USAGE:  scalarprod(v,w);  v,w intvecs
190RETURN:  an int, the standard scalar product of v and w
191PURPOSE: compute the scalar product of two intvecs
192NOTE:    the arguments must have the same size
193EXAMPLE: example scalarprod; shows examples
194"
195{
196  int i; int sp;
197  if (size(v)!=size(w))
198  {
199    ERROR("non-matching dimensions");
200  }
201  else
202  {
203    for (i=1; i<=size(v);i++)
204    {
205      sp = sp + v[i]*w[i];
206    }
207  }
208  return(sp);
209}
210example
211{
212  "EXAMPLE:"; echo = 2;
213  intvec v = 1,2,3;
214  intvec w = 4,5,6;
215  scalarprod(v,w);
216}
217
218
219//-------------- main procedures -------------------------------------------------------
220
221
222proc linreduce(poly f, ideal I, list #)
223"USAGE:  linreduce(f, I [,s,t]);  f a poly, I an ideal, s,t optional ints
224RETURN:  a poly obtained by linear reductions of the given poly with the given ideal
225PURPOSE: reduce a poly only by linear reductions
226NOTE:    If s<>0, a list consisting of the reduced poly and the coefficient vector of the used
227@*       reductions is returned.
228@*       If t<>0, only leading monomials are reduced, otherwise, and by default, all monomials
229@*       are reduced, if possible.
230EXAMPLE: example linreduce; shows examples
231"
232{
233  int ppl = printlevel - voice + 2;
234  int remembercoeffs = 0; // default
235  int redlm          = 0; // default
236  if (size(#)>0)
237  {
238    if (typeof(#[1])=="int" || typeof(#[1])=="number")
239    {
240      remembercoeffs = #[1];
241    }
242    if (size(#)>1)
243    {
244      if (typeof(#[2])=="int" || typeof(#[2])=="number")
245      {
246        redlm = #[2];
247      }
248    }
249  }
250  int i,j,k;
251  int sI = ncols(I);
252  ideal lmI,lcI;
253  for (i=1; i<=sI; i++)
254  {
255    lmI[i] = leadmonom(I[i]);
256    lcI[i] = leadcoef(I[i]);
257  }
258  vector v;
259  poly c;
260  int reduction = 1;
261  if (redlm == 0)
262  {
263    ideal monomf;
264    for (k=1; k<=size(f); k++)
265    {
266      monomf[k] = normalize(f[k]);
267    }
268    while (reduction == 1) // while there was a reduction
269    {
270      reduction = 0;
271      for (i=sI; i>=1; i--)
272      {
273        dbprint(ppl,"testing ideal entry:",i);
274        for (j=1; j<=size(f); j++)
275        {
276          if (monomf[j] == lmI[i])
277          {
278            c = leadcoef(f[j])/lcI[i];
279            f = f - c*I[i];
280            dbprint(ppl,"reducing poly to ",f);
281            monomf = 0;
282            for (k=1; k<=size(f); k++)
283            {
284              monomf[k] = normalize(f[k]);
285            }
286            reduction = 1;
287            if (remembercoeffs <> 0)
288            {
289              v = v - c * gen(i);
290            }
291            break;
292          }
293        }
294        if (reduction == 1)
295        {
296          break;
297        }
298      }
299    }
300  }
301  else // reduce only leading monomials
302  {
303    poly lm = leadmonom(f);
304    while (reduction == 1) // while there was a reduction
305    {
306      reduction = 0;
307      for (i=sI;i>=1;i--)
308      {
309        if (lm <> 0 && lm == lmI[i])
310        {
311          c = leadcoef(f)/lcI[i];
312          f = f - c*I[i];
313          lm = leadmonom(f);
314          reduction = 1;
315          if (remembercoeffs <> 0)
316          {
317            v = v - c * gen(i);
318          }
319        }
320      }
321    }
322  }
323  if (remembercoeffs <> 0)
324  {
325    list l = f,v;
326    return(l);
327  }
328  else
329  {
330    return(f);
331  }
332}
333example
334{
335  "EXAMPLE:"; echo = 2;
336  ring r = 0,(x,y),dp;
337  ideal I = 1,y,xy;
338  poly f = 5xy+7y+3;
339  poly g = 7x+5y+3;
340  linreduce(g,I);
341  linreduce(g,I,0,1);
342  linreduce(f,I,1);
343}
344
345proc ncsolve (ideal I, list #)
346"USAGE:  ncsolve(I[,s]);  I an ideal, s an optional int
347RETURN:  coefficient vector of a linear combination of 0 in the elements of I
348PURPOSE: compute a linear dependency between the elements of an ideal if such one exists
349NOTE:    If s<>0, @code{std} is used for Groebner basis computations,
350@*       otherwise, @code{slimgb} is used.
351@*       By default, @code{slimgb} is used in char 0 and @code{std} in char >0.
352@*       If printlevel=1, progress debug messages will be printed,
353@*       if printlevel>=2, all the debug messages will be printed.
354EXAMPLE: example ncsolve; shows examples
355"
356{
357  int whichengine     = 0; // default
358  int enginespecified = 0; // default
359  if (size(#)>0)
360  {
361    if (typeof(#[1])=="int" || typeof(#[1])=="number")
362    {
363      whichengine = int( #[1]);
364      enginespecified = 1;
365    }
366  }
367  int ppl = printlevel - voice +2;
368  int sI = ncols(I);
369  // check if we are done
370  if (I[sI]==0)
371  {
372    vector v = gen(sI);
373  }
374  else
375  {
376    // 1. introduce undefined coeffs
377    def save = basering;
378    int p = char(save);
379    if (enginespecified == 0)
380    {
381      if (p <> 0)
382      {
383        whichengine = 1;
384      }
385    }
386    ring @A = p,(@a(1..sI)),lp;
387    ring @aA = (p,@a(1..sI)), (@z),dp;
388    def @B = save + @aA;
389    setring @B;
390    ideal I = imap(save,I);
391    // 2. form the linear system for the undef coeffs
392    int i;   poly W;  ideal QQ;
393    for (i=1; i<=sI; i++)
394    {
395      W = W + @a(i)*I[i];
396    }
397    while (W!=0)
398    {
399      QQ = QQ,leadcoef(W);
400      W = W - lead(W);
401    }
402    // QQ consists of polynomial expressions in @a(i) of type number
403    setring @A;
404    ideal QQ = imap(@B,QQ);
405    // 3. this QQ is a polynomial ideal, so "solve" the system
406    dbprint(ppl, "ncsolve: starting Groebner basis computation with engine:", whichengine);
407    QQ = engine(QQ,whichengine);
408    dbprint(ppl, "QQ after engine:", QQ);
409    if (dim(QQ) == -1)
410    {
411      dbprint(ppl+1, "no solutions by ncsolve");
412      // output zeroes
413      setring save;
414      kill @A,@aA,@B;
415      return(v);
416    }
417    // 4. in order to get the numeric values
418    matrix AA = matrix(maxideal(1));
419    module MQQ = std(module(QQ));
420    AA = NF(AA,MQQ); // todo: we still receive NF warnings
421    dbprint(ppl, "AA after NF:",AA);
422    //    "AA after NF:"; print(AA);
423    for(i=1; i<=sI; i++)
424    {
425      AA = subst(AA,var(i),1);
426    }
427    dbprint(ppl, "AA after subst:",AA);
428    //    "AA after subst: "; print(AA);
429    vector v = (module(transpose(AA)))[1];
430    setring save;
431    vector v = imap(@A,v);
432    kill @A,@aA,@B;
433  }
434  return(v);
435}
436example
437{
438  "EXAMPLE:"; echo = 2;
439  ring r = 0,x,dp;
440  ideal I = x,2x;
441  ncsolve(I);
442  ideal J = x,x2;
443  ncsolve(J);
444}
445
446proc pintersect (poly s, ideal I)
447"USAGE:  pintersect(f, I);  f a poly, I an ideal
448RETURN:  coefficient vector of the monic generator of the intersection of the ideal generated by f with I
449PURPOSE: compute the intersection of an ideal with a principal ideal defined by f
450NOTE:    If the intersection is zero, this proc might not terminate.
451@*       I should be given as standard basis.
452@*       If printlevel=1, progress debug messages will be printed,
453@*       if printlevel>=2, all the debug messages will be printed.
454EXAMPLE: example pintersect; shows examples
455"
456{
457  // assume I is given in Groebner basis
458  attrib(I,"isSB",1); // set attribute for suppressing NF messages
459  int ppl = printlevel-voice+2;
460  // ---case 1: I = basering---
461  if (size(I) == 1)
462  {
463    if (simplify(I,1) == ideal(1))
464    {
465      return(gen(2)); // = s
466    }
467  }
468  def save = basering;
469  int n = nvars(save);
470  int i,j,k;
471  // ---case 2: intersection is zero---
472  intvec degs = leadexp(s);
473  intvec possdegbounds;
474  list degI;
475  i = 1;
476  while (i <= ncols(I))
477  {
478    if (i == ncols(I)+1)
479    {
480      break;
481    }
482    degI[i] = leadexp(I[i]);
483    for (j=1; j<=n; j++)
484    {
485      if (degs[j] == 0)
486      {
487        if (degI[i][j] <> 0)
488        {
489          break;
490        }
491      }
492      if (j == n)
493      {
494        k++;
495        possdegbounds[k] = Max(degI[i]);
496      }
497    }
498    i++;
499  }
500  int degbound = Min(possdegbounds);
501  dbprint(ppl,"a lower bound for the degree of the insection is:");
502  dbprint(ppl,degbound);
503  if (degbound == 0) // lm(s) does not appear in lm(I)
504  {
505    return(vector(0));
506  }
507  // ---case 3: intersection is non-trivial---
508  ideal redNI = 1;
509  vector v;
510  list l,ll;
511  l[1] = vector(0);
512  poly toNF,tobracket,newNF,rednewNF,oldNF,secNF;
513  i = 1;
514  dbprint(ppl+1,"pintersect starts...");
515  while (1)
516  {
517    dbprint(ppl,"testing degree: "+string(i));
518    if (i>1)
519    {
520      oldNF = newNF;
521      tobracket = s^(i-1) - oldNF;
522      if (tobracket==0) // todo bug in bracket?
523      {
524        toNF = 0;
525      }
526      else
527      {
528        toNF = bracket(tobracket,secNF);
529      }
530      newNF = NF(toNF+oldNF*secNF,I);  // = NF(s^i,I)
531    }
532    else
533    {
534      newNF = NF(s,I);
535      secNF = newNF;
536    }
537    ll = linreduce(newNF,redNI,1);
538    rednewNF = ll[1];
539    l[i+1] = ll[2];
540    dbprint(ppl,"newNF is:", newNF);
541    dbprint(ppl,"rednewNF is:", rednewNF);
542    if (rednewNF != 0) // no linear dependency
543    {
544      redNI[i+1] = rednewNF;
545      i++;
546    }
547    else // there is a linear dependency, hence we are done
548    {
549      dbprint(ppl+1,"the degree of the generator of the intersection is:", i);
550      break;
551    }
552  }
553  dbprint(ppl,"used linear reductions:", l);
554  // we obtain the coefficients of the generator of the intersection by the used reductions:
555  ring @R = 0,(a(1..i+1)),dp;
556  setring @R;
557  list l = imap(save,l);
558  ideal C;
559  for (j=1;j<=i+1;j++)
560  {
561    C[j] = 0;
562    for (k=1;k<=j;k++)
563    {
564      C[j] = C[j]+l[j][k]*a(k);
565    }
566  }
567  for (j=i;j>=1;j--)
568  {
569    C[i+1]= subst(C[i+1],a(j),a(j)+C[j]);
570  }
571  matrix m = coeffs(C[i+1],maxideal(1));
572  vector v = gen(i+1);
573  for (j=1;j<=i+1;j++)
574  {
575    v = v + m[j,1]*gen(j);
576  }
577  setring save;
578  v = imap(@R,v);
579  kill @R;
580  dbprint(ppl+1,"pintersect finished");
581  return(v);
582}
583example
584{
585  "EXAMPLE:"; echo = 2;
586  ring r = 0,(x,y),dp;
587  poly f = x^2+y^3+x*y^2;
588  def D = initialmalgrange(f);
589  setring D;
590  inF;
591  pintersect(t*Dt,inF);
592}
593
594proc pintersectsyz (poly s, ideal II, list #)
595"USAGE:  pintersectsyz(f, I [,p,s,t]);  f a poly, I an ideal, p, t optial ints, p a prime number
596RETURN:  coefficient vector of the monic generator of the intersection of the ideal generated by f with I
597PURPOSE: compute the intersection of an ideal with a principal ideal defined by f
598NOTE:    If the intersection is zero, this proc might not terminate.
599@*       I should be given as standard basis.
600@*       If p>0 is given, this proc computes the generator of the intersection in char p first and
601@*       then only searches for a generator of the obtained degree in the basering.
602@*       Otherwise, it searched for all degrees.
603@*       This is done by computing syzygies.
604@*       If s<>0, @code{std} is used for Groebner basis computations in char 0,
605@*       otherwise, and by default, @code{slimgb} is used.
606@*       If t<>0 and by default, @code{std} is used for Groebner basis computations in char >0,
607@*       otherwise, @code{slimgb} is used.
608@*       If printlevel=1, progress debug messages will be printed,
609@*       if printlevel>=2, all the debug messages will be printed.
610EXAMPLE: example pintersectsyz; shows examples
611"
612{
613  // assume I is given in Groebner basis
614  ideal I = II;
615  attrib(I,"isSB",1); // set attribute for suppressing NF messages
616  int ppl = printlevel-voice+2;
617  int whichengine  = 0; // default
618  int modengine    = 1; // default
619  int solveincharp = 0; // default
620  def save = basering;
621  if (size(#)>0)
622  {
623    if (typeof(#[1])=="int" || typeof(#[1])=="number")
624    {
625      solveincharp = int(#[1]);
626    }
627    if (size(#)>1)
628    {
629      if (typeof(#[2])=="int" || typeof(#[2])=="number")
630      {
631        whichengine = int(#[2]);
632      }
633      if (size(#)>2)
634      {
635        if (typeof(#[3])=="int" || typeof(#[3])=="number")
636        {
637          modengine = int(#[3]);
638        }
639      }
640    }
641  }
642  int i,j;
643  vector v;
644  poly tobracket,toNF,newNF,p;
645  ideal NI = 1;
646  newNF = NF(s,I);
647  NI[2] = newNF;
648  if (solveincharp<>0)
649  {
650    list l = ringlist(save);
651    l[1] = solveincharp;
652    matrix l5 = l[5];
653    matrix l6 = l[6];
654    def @Rp = ring(l);
655    setring @Rp;
656    list l = ringlist(@Rp);
657    l[5] = fetch(save,l5);
658    l[6] = fetch(save,l6);
659    def Rp = ring(l);
660    setring Rp;
661    kill @Rp;
662    dbprint(ppl+1,"solving in ring ", Rp);
663    vector v;
664    map phi = save,maxideal(1);
665    poly s = phi(s);
666    ideal NI = 1;
667    setring save;
668  }
669  i = 1;
670  dbprint(ppl+1,"pintersectsyz starts...");
671  dbprint(ppl+1,"with ideal I=", I);
672  while (1)
673  {
674    dbprint(ppl,"i:"+string(i));
675    if (i>1)
676    {
677      tobracket = s^(i-1)-NI[i];
678      if (tobracket!=0)
679      {
680        toNF = bracket(tobracket,NI[2]) + NI[i]*NI[2];
681      }
682      else
683      {
684        toNF = NI[i]*NI[2];
685      }
686      newNF =  NF(toNF,I);
687      NI[i+1] = newNF;
688    }
689    // look for a solution
690    dbprint(ppl,"ncsolve starts with: "+string(matrix(NI)));
691    if (solveincharp<>0) // modular method
692    {
693      setring Rp;
694      NI[i+1] = phi(newNF);
695      v = ncsolve(NI,modengine);
696      if (v!=0) // there is a modular solution
697      {
698        dbprint(ppl,"got solution in char ",solveincharp," of degree " ,i);
699        setring save;
700        v = ncsolve(NI,whichengine);
701        if (v==0)
702        {
703          break;
704        }
705      }
706      else // no modular solution
707      {
708        setring save;
709        v = 0;
710      }
711    }
712    else // non-modular method
713    {
714      v = ncsolve(NI,whichengine);
715    }
716    matrix MM[1][nrows(v)] = matrix(v);
717    dbprint(ppl,"ncsolve ready  with: "+string(MM));
718    kill MM;
719    //  "ncsolve ready with"; print(v);
720    if (v!=0)
721    {
722      // a solution:
723      //check for the reality of the solution
724      p = 0;
725      for (j=1; j<=i+1; j++)
726      {
727        p = p + v[j]*NI[j];
728      }
729      if (p!=0)
730      {
731        dbprint(ppl,"ncsolve: bad solution!");
732      }
733      else
734      {
735        dbprint(ppl,"ncsolve: got solution!");
736        // "got solution!";
737        break;
738      }
739    }
740    // no solution:
741    i++;
742  }
743  dbprint(ppl+1,"pintersectsyz finished");
744  return(v);
745}
746example
747{
748  "EXAMPLE:"; echo = 2;
749  ring r = 0,(x,y),dp;
750  poly f = x^2+y^3+x*y^2;
751  def D = initialmalgrange(f);
752  setring D;
753  inF;
754  poly s = t*Dt;
755  pintersectsyz(s,inF);
756  int p = prime(20000);
757  pintersectsyz(s,inF,p,0,0);
758}
759
760proc vec2poly (list #)
761"USAGE:  vec2poly(v [,i]);  v a vector or an intvec, i an optional int
762RETURN:  a poly with coefficient vector v
763PURPOSE: convert a coefficient vector to a poly
764NOTE:    If i>0 is given, the returned poly is an element of K[var(i)],
765@*       otherwise, and by default, @code{i=1} is used.
766@*       The first entry of v is the coefficient of 1.
767EXAMPLE: example vec2poly; shows examples
768"
769{
770  def save = basering;
771  int i,ringvar;
772  ringvar = 1; // default
773  if (size(#) > 0)
774  {
775    if (typeof(#[1])=="vector" || typeof(#[1])=="intvec")
776    {
777      def v = #[1];
778    }
779    else
780    {
781      ERROR("wrong input: expected vector/intvec expression");
782    }
783    if (size(#) > 1)
784    {
785      if (typeof(#[2])=="int" || typeof(#[2])=="number")
786      {
787        ringvar = int(#[2]);
788      }
789    }
790  }
791  if (ringvar > nvars(save))
792  {
793    ERROR("var out of range");
794  }
795  poly p;
796  for (i=1; i<=nrows(v); i++)
797  {
798    p = p + v[i]*(var(ringvar))^(i-1);
799  }
800  return(p);
801}
802example
803{
804  "EXAMPLE:"; echo = 2;
805  ring r = 0,(x,y),dp;
806  vector v = gen(1) + 3*gen(3) + 22/9*gen(4);
807  intvec iv = 3,2,1;
808  vec2poly(v,2);
809  vec2poly(iv);
810}
811
812static proc listofroots (list #)
813{
814  def save = basering;
815  int n = nvars(save);
816  int i;
817  poly p;
818  if (typeof(#[1])=="vector")
819  {
820    vector b = #[1];
821    for (i=1; i<=nrows(b); i++)
822    {
823      p = p + b[i]*(var(1))^(i-1);
824    }
825  }
826  else
827  {
828    p = #[1];
829  }
830  int substitution = int(#[2]);
831  ring S = 0,s,dp;
832  ideal J;
833  for (i=1; i<=n; i++)
834  {
835    J[i] = s;
836  }
837  map @m = save,J;
838  poly p = @m(p);
839  if (substitution == 1)
840  {
841    p = subst(p,s,-s-1);
842  }
843  // the rest of this proc is nicked from bernsteinBM from dmod.lib
844  list P = factorize(p);//with constants and multiplicities
845  ideal bs; intvec m;   //the Bernstein polynomial is monic, so we are not interested in constants
846  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
847  {
848    bs[i-1] = P[1][i];
849    m[i-1]  = P[2][i];
850  }
851  bs =  normalize(bs);
852  bs = -subst(bs,s,0);
853  setring save;
854  ideal bs = imap(S,bs);
855  kill S;
856  list BS = bs,m;
857  return(BS);
858}
859
860static proc bfctengine (poly f, int inorann, int whichengine, int methodord, int methodpintersect, int pintersectchar, int modengine, intvec u0)
861{
862  int ppl = printlevel - voice +2;
863  int i;
864  def save = basering;
865  int n = nvars(save);
866  if (inorann == 0) // bfct using initial ideal
867  {
868    def D = initialmalgrange(f,whichengine,methodord,1,u0);
869    setring D;
870    ideal J = inF;
871    kill inF;
872    poly s = t*Dt;
873  }
874  else // bfct using Ann(f^s)
875  {
876    def D = SannfsBFCT(f,whichengine);
877    setring D;
878    ideal J = LD;
879    kill LD;
880  }
881  vector b;
882  // try it modular
883  if (methodpintersect <> 0) // pintersectsyz
884  {
885    if (pintersectchar == 0) // pintersectsyz::modular
886    {
887      int lb = 30000;
888      int ub = 536870909;
889      i = 1;
890      list usedprimes;
891      while (b == 0)
892      {
893        dbprint(ppl,"number of run in the loop: "+string(i));
894        int q = prime(random(lb,ub));
895        if (isin(usedprimes,q)==0) // if q was not already used
896        {
897          usedprimes = usedprimes,q;
898          dbprint(ppl,"used prime is: "+string(q));
899          b = pintersectsyz(s,J,q,whichengine,modengine);
900        }
901        i++;
902      }
903    }
904    else // pintersectsyz::non-modular
905    {
906      b = pintersectsyz(s,J,0,whichengine);
907    }
908  }
909  else // pintersect: linreduce
910  {
911    b = pintersect(s,J);
912  }
913  setring save;
914  vector b = imap(D,b);
915  if (inorann == 0)
916  {
917    list l = listofroots(b,1);
918  }
919  else
920  {
921    list l = listofroots(b,0);
922  }
923  return(l);
924}
925
926proc bfct (poly f, list #)
927"USAGE:  bfct(f [,s,t,v]);  f a poly, s,t optional ints, v an optional intvec
928RETURN:  list of roots of the Bernstein-Sato polynomial bs(f) and their multiplicies
929PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f, according to the algorithm by Masayuki Noro
930NOTE:    In this proc, the initial Malgrange ideal is computed.
931@*       Further, a system of linear equations is solved by linear reductions.
932@*       If s<>0, @code{std} is used for Groebner basis computations,
933@*       otherwise, and by default, @code{slimgb} is used.
934@*       If t<>0, a matrix ordering is used for Groebner basis computations,
935@*       otherwise, and by default, a block ordering is used.
936@*       If v is a positive weight vector, v is used for homogenization computations,
937@*       otherwise and by default, no weights are used.
938@*       If printlevel=1, progress debug messages will be printed,
939@*       if printlevel>=2, all the debug messages will be printed.
940EXAMPLE: example bfct; shows examples
941"
942{
943  int ppl = printlevel - voice +2;
944  int i;
945  int n = nvars(basering);
946  // in # we have two switches:
947  // one for the engine used for Groebner basis computations,
948  // one for  M() ordering or its realization
949  // in # can also be the optional weight vector
950  int whichengine  = 0; // default
951  int methodord    = 0; // default
952  intvec u0        = 0; // default
953  if (size(#)>0)
954  {
955    if (typeof(#[1])=="int" || typeof(#[1])=="number")
956    {
957      whichengine = int(#[1]);
958    }
959    if (size(#)>1)
960    {
961      if (typeof(#[2])=="int" || typeof(#[2])=="number")
962      {
963        methodord = int(#[2]);
964      }
965      if (size(#)>2)
966      {
967        if (typeof(#[3])=="intvec" && size(#[3])==n && ispositive(#[3])==1)
968        {
969          u0 = #[3];
970        }
971      }
972    }
973  }
974  list b = bfctengine(f,0,whichengine,methodord,0,0,0,u0);
975  return(b);
976}
977example
978{
979  "EXAMPLE:"; echo = 2;
980  ring r = 0,(x,y),dp;
981  poly f = x^2+y^3+x*y^2;
982  bfct(f);
983  intvec v = 3,2;
984  bfct(f,1,0,v);
985}
986
987proc bfctsyz (poly f, list #)
988"USAGE:  bfctsyz(f [,r,s,t,u,v]);  f a poly, r,s,t,u optional ints, v an optional intvec
989RETURN:  list of roots of the Bernstein-Sato polynomial bs(f) and its multiplicies
990PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f, according to the algorithm by Masayuki Noro
991NOTE:    In this proc, the initial Malgrange ideal is computed.
992@*       Further, a system of linear equations is solved by computing syzygies.
993@*       If r<>0, @code{std} is used for Groebner basis computations in characteristic 0,
994@*       otherwise, and by default, @code{slimgb} is used.
995@*       If s<>0, a matrix ordering is used for Groebner basis computations,
996@*       otherwise, and by default, a block ordering is used.
997@*       If t<>0, the computation of the intersection is solely performed over charasteristic 0,
998@*       otherwise and by default, a modular method is used.
999@*       If u<>0 and by default, @code{std} is used for Groebner basis computations in characteristic >0,
1000@*       otherwise, @code{slimgb} is used.
1001@*       If v is a positive weight vector, v is used for homogenization computations,
1002@*       otherwise and by default, no weights are used.
1003@*       If printlevel=1, progress debug messages will be printed,
1004@*       if printlevel>=2, all the debug messages will be printed.
1005EXAMPLE: example bfct; shows examples
1006"
1007{
1008  int ppl = printlevel - voice +2;
1009  int i;
1010  // in # we have four switches:
1011  // one for the engine used for Groebner basis computations in char 0,
1012  // one for  M() ordering or its realization
1013  // one for a modular method when computing the intersection
1014  // and one for the engine used for Groebner basis computations in char >0
1015  // in # can also be the optional weight vector
1016  def save = basering;
1017  int n = nvars(save);
1018  int whichengine = 0; // default
1019  int methodord   = 0; // default
1020  int pintersectchar  = 0; // default
1021  int modengine   = 1; // default
1022  intvec u0       = 0; // default
1023  if (size(#)>0)
1024  {
1025    if (typeof(#[1])=="int" || typeof(#[1])=="number")
1026    {
1027      whichengine = int(#[1]);
1028    }
1029    if (size(#)>1)
1030    {
1031      if (typeof(#[2])=="int" || typeof(#[2])=="number")
1032      {
1033        methodord = int(#[2]);
1034      }
1035      if (size(#)>2)
1036      {
1037        if (typeof(#[3])=="int" || typeof(#[3])=="number")
1038        {
1039          pintersectchar = int(#[3]);
1040        }
1041        if (size(#)>3)
1042        {
1043          if (typeof(#[4])=="int" || typeof(#[4])=="number")
1044          {
1045            modengine = int(#[4]);
1046          }
1047          if (size(#)>4)
1048          {
1049            if (typeof(#[5])=="intvec" && size(#[5])==n && ispositive(#[5])==1)
1050            {
1051              u0 = #[5];
1052            }
1053          }
1054        }
1055      }
1056    }
1057  }
1058  list b = bfctengine(f,0,whichengine,methodord,1,pintersectchar,modengine,u0);
1059  return(b);
1060}
1061example
1062{
1063  "EXAMPLE:"; echo = 2;
1064  ring r = 0,(x,y),dp;
1065  poly f = x^2+y^3+x*y^2;
1066  bfctsyz(f);
1067  intvec v = 3,2;
1068  bfctsyz(f,0,1,1,0,v);
1069}
1070
1071proc bfctideal (ideal I, intvec w, list #)
1072"USAGE:  bfctideal(I,w[,s,t]);  I an ideal, w an intvec, s,t optional ints
1073RETURN:  list of roots and their multiplicies of the global b-function of I w.r.t. the weight vector (-w,w)
1074PURPOSE: compute the global b-function of an ideal according to the algorithm by M. Noro
1075NOTE:    Assume, I is an ideal in the n-th Weyl algebra where the sequence of the
1076@*       variables is x(1),...,x(n),D(1),...,D(n).
1077@*       If s<>0, @code{std} is used for Groebner basis computations in characteristic 0,
1078@*       otherwise, and by default, @code{slimgb} is used.
1079@*       If t<>0, a matrix ordering is used for Groebner basis computations,
1080@*       otherwise, and by default, a block ordering is used.
1081@*       If printlevel=1, progress debug messages will be printed,
1082@*       if printlevel>=2, all the debug messages will be printed.
1083EXAMPLE: example bfctideal; shows examples
1084"
1085{
1086  int ppl = printlevel - voice +2;
1087  int i;
1088  def save = basering;
1089  int n = nvars(save)/2;
1090  int whichengine = 0; // default
1091  int methodord   = 0; // default
1092  if (size(#)>0)
1093  {
1094    if (typeof(#[1])=="int" || typeof(#[1])=="number")
1095    {
1096      whichengine = int(#[1]);
1097    }
1098    if (size(#)>1)
1099    {
1100      if (typeof(#[2])=="int" || typeof(#[2])=="number")
1101      {
1102        methodord = int(#[2]);
1103      }
1104    }
1105  }
1106  ideal J = initialideal(I,-w,w,whichengine,methodord);
1107  poly s;
1108  for (i=1; i<=n; i++)
1109  {
1110    s = s + w[i]*var(i)*var(n+i);
1111  }
1112  vector b = pintersect(s,J);
1113  list l = listofroots(b,0);
1114  return(l);
1115}
1116example
1117{
1118  "EXAMPLE:"; echo = 2;
1119  ring @D = 0,(x,y,Dx,Dy),dp;
1120  def D = Weyl();
1121  setring D;
1122  ideal I = 3*x^2*Dy+2*y*Dx,2*x*Dx+3*y*Dy+6;
1123  intvec w1 = 1,1;
1124  intvec w2 = 1,2;
1125  intvec w3 = 2,3;
1126  bfctideal(I,w1);
1127  bfctideal(I,w2,1);
1128  bfctideal(I,w3,0,1);
1129}
1130
1131
1132proc bfctonestep (poly f,list #)
1133"USAGE:  bfctonestep(f [,s,t]);  f a poly, s,t optional ints
1134RETURN:  list of roots of the Bernstein-Sato polynomial bs(f) and its multiplicies
1135PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f, using only one Groebner basis computation
1136NOTE:    If s<>0, @code{std} is used for the Groebner basis computation, otherwise,
1137@*       and by default, @code{slimgb} is used.
1138@*       If t<>0, a matrix ordering is used for Groebner basis computations,
1139@*       otherwise, and by default, a block ordering is used.
1140@*       If printlevel=1, progress debug messages will be printed,
1141@*       if printlevel>=2, all the debug messages will be printed.
1142EXAMPLE: example bfctonestep; shows examples
1143"
1144{
1145  int ppl = printlevel - voice +2;
1146  def save = basering;
1147  int n = nvars(save);
1148  int i;
1149  int whichengine = 0; // default
1150  int methodord   = 0; // default
1151  if (size(#)>0)
1152  {
1153    if (typeof(#[1])=="int" || typeof(#[1])=="number")
1154    {
1155      whichengine = int(#[1]);
1156    }
1157    if (size(#)>1)
1158    {
1159      if (typeof(#[2])=="int" || typeof(#[2])=="number")
1160      {
1161        methodord = int(#[2]);
1162      }
1163    }
1164  }
1165  def DDh = initialidealengine("bfctonestep", whichengine, methodord, f);
1166  setring DDh;
1167  dbprint(ppl, "the initial ideal:", string(matrix(inF)));
1168  intvec tonselect = 1;
1169  for (i=3; i<=2*n+4; i++)
1170  {
1171    tonselect = tonselect,i;
1172  }
1173  inF = nselect(inF,tonselect);
1174  dbprint(ppl, "generators containing only s:", string(matrix(inF)));
1175  inF = engine(inF, whichengine); // is now a principal ideal;
1176  setring save;
1177  ideal J; J[2] = var(1);
1178  map @m = DDh,J;
1179  ideal inF = @m(inF);
1180  poly p = inF[1];
1181  list l = listofroots(p,1);
1182  return(l);
1183}
1184example
1185{
1186  "EXAMPLE:"; echo = 2;
1187  ring r = 0,(x,y),dp;
1188  poly f = x^2+y^3+x*y^2;
1189  bfctonestep(f);
1190  bfctonestep(f,1,1);
1191}
1192
1193proc bfctann (poly f, list #)
1194"USAGE:  bfctann(f [,r]);  f a poly, r an optional int
1195RETURN:  list of roots of the Bernstein-Sato polynomial bs(f) and their multiplicies
1196PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f
1197NOTE:    In this proc, ann(f^s) is computed.
1198@*       If r<>0, @code{std} is used for Groebner basis computations,
1199@*       otherwise, and by default, @code{slimgb} is used.
1200@*       If printlevel=1, progress debug messages will be printed,
1201@*       if printlevel>=2, all the debug messages will be printed.
1202EXAMPLE: example bfctann; shows examples
1203"
1204{
1205  def save = basering;
1206  int ppl = printlevel - voice + 2;
1207  int whichengine = 0; // default
1208  if (size(#)>0)
1209  {
1210    if (typeof(#[1])=="int" || typeof(#[1])=="number")
1211    {
1212      whichengine = int(#[1]);
1213    }
1214  }
1215  list b = bfctengine(f,1,whichengine,0,1,0,0,0);
1216  return(b);
1217}
1218example
1219{
1220  "EXAMPLE:"; echo = 2;
1221  ring r = 0,(x,y),dp;
1222  poly f = x^2+y^3+x*y^2;
1223  bfctann(f);
1224}
1225
1226static proc hardexamples ()
1227{
1228  //  some hard examples
1229  ring r1 = 0,(x,y,z,w),dp;
1230  // ab34
1231  poly ab34 = (z3+w4)*(3z2x+4w3y);
1232  bfct(ab34);
1233  // ha3
1234  poly ha3 = xyzw*(x+y)*(x+z)*(x+w)*(y+z+w);
1235  bfct(ha3);
1236  // ha4
1237  poly ha4 = xyzw*(x+y)*(x+z)*(x+w)*(y+z)*(y+w);
1238  bfct(ha4);
1239  // chal4: reiffen(4,5)*reiffen(5,4)
1240  ring r2 = 0,(x,y),dp;
1241  poly chal4 = (x4+xy4+y5)*(x5+x4y+y4);
1242  bfct(chal4);
1243  // (xy+z)*reiffen(4,5)
1244  ring r3 = 0,(x,y,z),dp;
1245  poly xyzreiffen45 = (xy+z)*(y4+yz4+z5);
1246  bfct(xyzreiffen45);
1247}
1248
Note: See TracBrowser for help on using the repository browser.