source: git/Singular/LIB/bfct.lib @ 7d56875

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