source: git/Singular/LIB/dmod.lib @ 2956123

spielwiese
Last change on this file since 2956123 was 0c02db, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: doc git-svn-id: file:///usr/local/Singular/svn/trunk@10442 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 118.0 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: dmod.lib,v 1.22 2007-11-27 11:08:51 Singular Exp $";
3category="Noncommutative";
4info="
5LIBRARY: dmod.lib     Algorithms for algebraic D-modules
6AUTHORS: Viktor Levandovskyy,     levandov@risc.uni-linz.ac.at
7@*       Jorge Martin Morales,    jorge@unizar.es
8
9THEORY: Given a polynomial ring R = K[x_1,...,x_n] and a polynomial F in R,
10@*      one is interested in the R[1/F]-module of rank one, generated by F^s
11@*      for a natural number s.
12@* In fact, the module R[1/F]*F^s has a structure of a D(R)[s]-module, where D(R)
13@* is an n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1> and
14@* D(R)[s] = D(R) tensored with K[s] over K.
15@* Constructively, one needs to find a left ideal I = I(F^s) in D(R), such
16@* that K[x_1,...,x_n,1/F]*F^s is isomorphic to D(R)/I as a D(R)-module.
17@* We often write just D for D(R) and D[s] for D(R)[s].
18@* One is interested in the following data:
19@* - Ann F^s = I = I(F^s) in D(R)[s], denoted by LD in the output
20@* - global Bernstein polynomial in K[s], denoted by bs, its minimal integer root s0 and
21@*   the list of all roots of bs, which are rational, with their multiplicities is denoted by BS
22@* - Ann F^s0 = I(F^s0) in D(R), denoted by LD0 in the output (LD0 is a holonomic ideal in D(R))
23@* - Ann^(1) F^s in D(R)[s], denoted by LD1 (logarithmic derivations)
24@* - an operator in D(R)[s], denoted by PS, such that PS*F^(s+1) = bs*F^s holds in K[x_1,...,x_n,1/F^s].
25
26@* We provide the following implementations:
27@* OT) the classical Ann F^s algorithm from Oaku and Takayama (J. Pure
28        Applied Math., 1999),
29@* LOT) Levandovskyy's modification of the Oaku-Takayama algorithm (unpublished)
30@* BM) the Ann F^s algorithm by Briancon and Maisonobe (Remarques sur
31        l'ideal de Bernstein associe a des polynomes, preprint, 2002)
32
33GUIDE:
34@* - Ann F^s = I = I(F^s) = LD in D(R)[s] can be computed by SannfsBM, SannfsOT, SannfsLOT
35@* - Ann^(1) F^s in D(R)[s] can be computed by Sannfslog
36@* - global Bernstein polynomial bs resp. BS in K[s] can be computed by bernsteinBM
37@* - Ann F^s0 = I(F^s0) = LD0 in D(R) can be computed by annfs0, annfsBM, annfsOT, annfsLOT
38@* - all the relevant data (LD, LD0, bs, PS) are computed by operatorBM
39
40MAIN PROCEDURES:
41
42annfs(F[,S,eng]);       compute Ann F^s0 in D and Bernstein poly for a poly F
43Sannfs(F[,S,eng]);      compute Ann F^s in D[s] for a poly F
44Sannfslog(F[,eng]);     compute Ann^(1) F^s in D[s] for a poly F
45bernsteinBM(F[,eng]);   compute global Bernstein poly for a poly F (algorithm of Briancon-Maisonobe)
46operatorBM(F[,eng]);    compute Ann F^s, Ann F^s0, BS and PS for a poly F (algorithm of Briancon-Maisonobe)
47annfsParamBM(F[,eng]);  compute the generic Ann F^s (algorithm by Briancon and Maisonobe) and exceptional parametric constellations for a poly F with parametric coefficients
48annfsBMI(F[,eng]);      compute Ann F^s and Bernstein ideal for a poly F=f1*..*fP (multivariate algorithm of Briancon-Maisonobe)
49checkRoot(F,a[,S,eng]); check if a given rational is a root of the global Bernstein polynomial of F and compute its multiplicity
50
51SECONDARY PROCEDURES FOR D-MODULES:
52
53annfsBM(F[,eng]);          compute Ann F^s0 in D and Bernstein poly for a poly F (algorithm of Briancon-Maisonobe)
54annfsLOT(F[,eng]);         compute Ann F^s0 in D and Bernstein poly for a poly F (Levandovskyy modification of the Oaku-Takayama algorithm)
55annfsOT(F[,eng]);          compute Ann F^s0 in D and Bernstein poly for a poly F (algorithm of Oaku-Takayama)
56SannfsBM(F[,eng]);         compute Ann F^s in D[s] for a poly F (algorithm of Briancon-Maisonobe)
57SannfsLOT(F[,eng]);        compute Ann F^s in D[s] for a poly F (Levandovskyy modification of the Oaku-Takayama algorithm)
58SannfsOT(F[,eng]);         compute Ann F^s in D[s] for a poly F (algorithm of Oaku-Takayama)
59annfs0(I,F [,eng]);        compute Ann F^s0 in D and Bernstein poly from the known Ann F^s in D[s]
60checkRoot1(I,F,a[,eng]);   check whether a rational is a root of the global Bernstein polynomial of F from the known Ann F^s in D[s]
61checkRoot2(I,F,a[,eng]);   check whether a rational is a root of the global Bernstein polynomial of F and compute its multiplicity from the known Ann F^s in D[s]
62checkFactor(I,F,qs[,eng]); check whether a polynomial qs in K[s] is a factor of the global Bernstein polynomial of F from the known Ann F^s in D[s]
63
64AUXILIARY PROCEDURES:
65
66arrange(p);         create a poly, describing a full hyperplane arrangement
67reiffen(p,q);       create a poly, describing a Reiffen curve
68isHolonomic(M);     check whether a module is holonomic
69convloc(L);         replace global orderings with local in the ringlist L
70minIntRoot(P,fact); minimal integer root among the roots of a maximal ideal P
71varnum(s);          the number of the variable with the name s
72
73SEE ALSO: gmssing_lib
74";
75
76LIB "nctools.lib";
77LIB "elim.lib";
78LIB "qhmoduli.lib"; // for Max
79LIB "gkdim.lib";
80LIB "gmssing.lib";
81LIB "control.lib";  // for genericity
82
83proc tstdmodlib()
84{
85  /* tests all procs for consistency */
86  /* adding the new proc, add it here */
87
88  "MAIN PROCEDURES:";
89  example annfs;
90  example annfs0;
91  example Sannfs;
92  example Sannfslog;
93  example bernsteinBM;
94  example operatorBM;
95  example annfspecial;
96  example annfsParamBM;
97  example annfsBMI;
98  example checkRoot;
99  "SECONDARY D-MOD PROCEDURES:";
100  example annfsBM;
101  example annfsLOT;
102  example annfsOT;
103  example SannfsBM;
104  example SannfsLOT;
105  example SannfsOT;
106  example annfs0;
107  example checkRoot1;
108  example checkRoot2;
109  example checkFactor;
110}
111
112static proc engine(ideal I, int i)
113{
114  /* std - slimgb mix */
115  ideal J;
116  if (i==0)
117  {
118    J = slimgb(I);
119  }
120  else
121  {
122    // without options -> strange! (ringlist?)
123    option(redSB);
124    option(redTail);
125    J = std(I);
126  }
127  return(J);
128}
129
130
131// new top-level procedures
132proc annfs(poly F, list #)
133"USAGE:  annfs(f [,S,eng]);  f a poly, S a string, eng an optional int
134RETURN:  ring
135PURPOSE: compute the D-module structure of basering[1/f]*f^s with the algorithm given in S and with the Groebner basis engine given in 'eng'
136NOTE:    activate the output ring with the @code{setring} command.
137@*       The value of a string S can be
138@*       'bm' (default) - for the algorithm of Briancon and Maisonobe,
139@*       'ot'  - for the algorithm of Oaku and Takayama,
140@*       'lot' - for the Levandovskyy's modification of the algorithm of Oaku and Takayama.
141@*       If eng <>0, @code{std} is used for Groebner basis computations,
142@*       otherwise and by default @code{slimgb} is used.
143@*       In the output ring:
144@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
145@*       - the list  BS is the list of roots and multiplicities of a Bernstein polynomial of f.
146@*       If @code{printlevel}=1, progress debug messages will be printed,
147@*       if @code{printlevel}>=2, all the debug messages will be printed.
148EXAMPLE: example annfs; shows examples
149"
150{
151  int eng = 0;
152  int chs = 0; // choice
153  string algo = "bm";
154  string st;
155  if ( size(#)>0 )
156  {
157   if ( typeof(#[1]) == "string" )
158   {
159     st = string(#[1]);
160     if ( (st == "BM") || (st == "Bm") || (st == "bM") ||(st == "bm"))
161     {
162       algo = "bm";
163       chs  = 1;
164     }
165     if ( (st == "OT") || (st == "Ot") || (st == "oT") || (st == "ot"))
166     {
167       algo = "ot";
168       chs  = 1;
169     }
170     if ( (st == "LOT") || (st == "lOT") || (st == "Lot") || (st == "lot"))
171     {
172       algo = "lot";
173       chs  = 1;
174     }
175     if (chs != 1)
176     {
177       // incorrect value of S
178       print("Incorrect algorithm given, proceed with the default BM");
179       algo = "bm";
180     }
181     // second arg
182     if (size(#)>1)
183     {
184       // exists 2nd arg
185       if ( typeof(#[2]) == "int" )
186       {
187         // the case: given alg, given engine
188         eng = int(#[2]);
189       }
190       else
191       {
192         eng = 0;
193       }
194     }
195     else
196     {
197       // no second arg
198       eng = 0;
199     }
200   }
201   else
202   {
203     if ( typeof(#[1]) == "int" )
204     {
205     // the case: default alg, engine
206     eng = int(#[1]);
207     //      algo = "bm";  //is already set
208     }
209     else
210     {
211       // incorr. 1st arg
212       algo = "bm";
213     }
214   }
215  }
216
217   // size(#)=0, i.e. there is no algorithm and no engine given
218   //  eng = 0; algo = "bm";  //are already set
219   // int ppl = printlevel-voice+2;
220
221  int old_printlevel = printlevel;
222  printlevel=printlevel+1;
223  def save = basering;
224  if ( algo=="ot")
225  {
226    def @A = annfsOT(F,eng);
227  }
228  else
229  {
230    if ( algo=="lot")
231    {
232      def @A = annfsLOT(F,eng);
233    }
234    else
235    {
236      // bm = default
237      def @A = annfsBM(F,eng);
238    }
239  }
240  printlevel = old_printlevel;
241  return(@A);
242}
243example
244{
245  "EXAMPLE:"; echo = 2;
246  ring r = 0,(x,y,z),Dp;
247  poly F = z*x^2+y^3;
248  printlevel = 0;
249  def A  = annfs(F); // here, the default BM algorithm will be used
250  setring A;
251  LD;
252  BS;
253}
254
255
256proc Sannfs(poly F, list #)
257"USAGE:  Sannfs(f [,S,eng]);  f a poly, S a string, eng an optional int
258RETURN:  ring
259PURPOSE: compute the D-module structure of basering[f^s] with the algorithm given in S and with the Groebner basis engine given in eng
260NOTE:    activate the output ring with the @code{setring} command.
261@*       The value of a string S can be
262@*       'bm' (default) - for the algorithm of  Briancon and Maisonobe,
263@*       'lot' - for the Levandovskyy's modification of the algorithm of Oaku and Takayama,
264@*       'ot'  - for the algorithm of Oaku and Takayama.
265@*       If eng <>0, @code{std} is used for Groebner basis computations,
266@*       otherwise, and by default @code{slimgb} is used.
267@*       In the output ring:
268@*       - the ideal LD is the needed D-module structure.
269@*       If @code{printlevel}=1, progress debug messages will be printed,
270@*       if @code{printlevel}>=2, all the debug messages will be printed.
271EXAMPLE: example Sannfs; shows examples
272"
273{
274  int eng = 0;
275  int chs = 0; // choice
276  string algo = "bm";
277  string st;
278  if ( size(#)>0 )
279  {
280   if ( typeof(#[1]) == "string" )
281   {
282     st = string(#[1]);
283     if ( (st == "BM") || (st == "Bm") || (st == "bM") ||(st == "bm"))
284     {
285       algo = "bm";
286       chs  = 1;
287     }
288     if ( (st == "OT") || (st == "Ot") || (st == "oT") || (st == "ot"))
289     {
290       algo = "ot";
291       chs  = 1;
292     }
293     if ( (st == "LOT") || (st == "lOT") || (st == "Lot") || (st == "lot"))
294     {
295       algo = "lot";
296       chs  = 1;
297     }
298     if (chs != 1)
299     {
300       // incorrect value of S
301       print("Incorrect algorithm given, proceed with the default BM");
302       algo = "bm";
303     }
304     // second arg
305     if (size(#)>1)
306     {
307       // exists 2nd arg
308       if ( typeof(#[2]) == "int" )
309       {
310         // the case: given alg, given engine
311         eng = int(#[2]);
312       }
313       else
314       {
315         eng = 0;
316       }
317     }
318     else
319     {
320       // no second arg
321       eng = 0;
322     }
323   }
324   else
325   {
326     if ( typeof(#[1]) == "int" )
327     {
328     // the case: default alg, engine
329     eng = int(#[1]);
330     //      algo = "bm";  //is already set
331     }
332     else
333     {
334       // incorr. 1st arg
335       algo = "bm";
336     }
337   }
338  }
339  // size(#)=0, i.e. there is no algorithm and no engine given
340  //  eng = 0; algo = "bm";  //are already set
341  // int ppl = printlevel-voice+2;
342  printlevel=printlevel+1;
343  def save = basering;
344  if ( algo=="ot")
345  {
346    def @A = SannfsOT(F,eng);
347  }
348  else
349  {
350    if ( algo=="lot")
351    {
352      def @A = SannfsLOT(F,eng);
353    }
354    else
355    {
356      // bm = default
357      def @A = SannfsBM(F,eng);
358    }
359  }
360  printlevel=printlevel-1;
361  return(@A);
362}
363example
364{
365  "EXAMPLE:"; echo = 2;
366  ring r = 0,(x,y,z),Dp;
367  poly F = x^3+y^3+z^3;
368  printlevel = 0;
369  def A  = Sannfs(F); // here, the default BM algorithm will be used
370  setring A;
371  LD;
372}
373
374proc Sannfslog (poly F, list #)
375"USAGE:  Sannfslog(f [,eng]);  f a poly, eng an optional int
376RETURN:  ring
377PURPOSE: compute the D-module structure of basering[1/f]*f^s, where D is the Weyl algebra
378NOTE:    activate this ring with the @code{setring} command.
379@*       In the ring D[s], the ideal LD1 is generated by the elements in Ann F^s in D[s] coming from logarithmic derivations.
380@*       If eng <>0, @code{std} is used for Groebner basis computations,
381@*       otherwise, and by default @code{slimgb} is used.
382@*       If printlevel=1, progress debug messages will be printed,
383@*       if printlevel>=2, all the debug messages will be printed.
384EXAMPLE: example Sannfslog; shows examples
385"
386{
387  int eng = 0;
388  if ( size(#)>0 )
389  {
390    if ( typeof(#[1]) == "int" )
391    {
392      eng = int(#[1]);
393    }
394  }
395  int ppl = printlevel-voice+2;
396  def save = basering;
397  int N = nvars(basering);
398  int Nnew = 2*N+1;
399  int i;
400  string s;
401  list RL = ringlist(basering);
402  list L, Lord;
403  list tmp;
404  intvec iv;
405  L[1] = RL[1]; // char
406  L[4] = RL[4]; // char, minpoly
407  // check whether vars have admissible names
408  list Name = RL[2];
409  for (i=1; i<=N; i++)
410  {
411    if (Name[i] == "s")
412    {
413      ERROR("Variable names should not include s");
414    }
415  }
416  // the ideal I
417  ideal I = -F, jacob(F);
418  dbprint(ppl,"// -1-1- starting the computation of syz(-F,_Dx(F))");
419  dbprint(ppl-1, I);
420  matrix M = syz(I);
421  M = transpose(M);  // it is more usefull working with columns
422  dbprint(ppl,"// -1-2- the module syz(-F,_Dx(F)) has been computed");
423  dbprint(ppl-1, M);
424  // ------------ the ring @R ------------
425  // _x, _Dx, s;  elim.ord for _x,_Dx.
426  // now, create the names for new vars
427  list DName;
428  for (i=1; i<=N; i++)
429  {
430    DName[i] = "D"+Name[i]; // concat
431  }
432  tmp[1] = "s";
433  list NName;
434  for (i=1; i<=N; i++)
435  {
436    NName[2*i-1] = Name[i];
437    NName[2*i] = DName[i];
438    //NName[2*i-1] = DName[i];
439    //NName[2*i] = Name[i];
440  }
441  NName[Nnew] = tmp[1];
442  L[2] = NName;
443  tmp = 0;
444  // block ord (a(1,1),a(0,0,1,1),...,dp);
445  //list("a",intvec(1,1)), list("a",intvec(0,0,1,1)), ...
446  tmp[1] = "a";  // string
447  for (i=1; i<=N; i++)
448  {
449    iv[2*i-1] = 1;
450    iv[2*i]   = 1;
451    tmp[2]    = iv;  iv = 0;  // intvec
452    Lord[i]   = tmp;
453  }
454  //list("dp",intvec(1,1,1,1,1,...))
455  s = "iv=";
456  for (i=1; i<=Nnew; i++)
457  {
458    s = s+"1,";
459  }
460  s[size(s)]=";";
461  execute(s);
462  kill s;
463  tmp[1] = "dp";  // string
464  tmp[2] = iv;    // intvec
465  Lord[N+1] = tmp;
466  //list("C",intvec(0))
467  tmp[1] = "C";  // string
468  iv = 0;
469  tmp[2] = iv;   // intvec
470  Lord[N+2] = tmp;
471  tmp = 0;
472  L[3]    = Lord;
473  // we are done with the list. Now add a Plural part
474  def @R@ = ring(L);
475  setring @R@;
476  matrix @D[Nnew][Nnew];
477  for (i=1; i<=N; i++)
478  {
479    @D[2*i-1,2*i]=1;
480    //@D[2*i-1,2*i]=-1;
481  }
482  def @R = nc_algebra(1,@D);
483  setring @R;
484  kill @R@;
485  dbprint(ppl,"// -2-1- the ring @R(_x,_Dx,s) is ready");
486  dbprint(ppl-1, @R);
487  matrix M = imap(save,M);
488  // now, create the vector [-s,_Dx]
489  vector v = [-s];  // now s is a variable
490  for (i=1; i<=N; i++)
491  {
492    v = v + var(2*i)*gen(i+1);
493    //v = v + var(2*i-1)*gen(i+1);
494  }
495  ideal J = ideal(M*v);
496  // make leadcoeffs positive
497  for (i=1; i<= ncols(J); i++)
498  {
499    if ( leadcoef(J[i])<0 )
500    {
501      J[i] = -J[i];
502    }
503  }
504  ideal LD1 = J;
505  kill J;
506  export LD1;
507  return(@R);
508}
509example
510{
511  "EXAMPLE:"; echo = 2;
512  ring r = 0,(x,y),Dp;
513  poly F = x^4+y^5+x*y^4;
514  printlevel = 0;
515  def A  = Sannfslog(F);
516  setring A;
517  LD1;
518}
519
520
521// alternative code for SannfsBM, renamed from annfsBM to ALTannfsBM
522// is superfluos - will not be included in the official documentation
523proc ALTannfsBM (poly F, list #)
524"USAGE:  ALTannfsBM(f [,eng]);  f a poly, eng an optional int
525RETURN:  ring
526PURPOSE: compute the annihilator ideal of f^s in D[s], where D is the Weyl Algebra, according to the algorithm by Briancon and Maisonobe
527NOTE:    activate this ring with the @code{setring} command. In this ring,
528@*       - the ideal LD is the annihilator of f^s.
529@*       If eng <>0, @code{std} is used for Groebner basis computations,
530@*       otherwise, and by default @code{slimgb} is used.
531@*       If printlevel=1, progress debug messages will be printed,
532@*       if printlevel>=2, all the debug messages will be printed.
533EXAMPLE: example ALTannfsBM; shows examples
534"
535{
536  int eng = 0;
537  if ( size(#)>0 )
538  {
539    if ( typeof(#[1]) == "int" )
540    {
541      eng = int(#[1]);
542    }
543  }
544  // returns a list with a ring and an ideal LD in it
545  int ppl = printlevel-voice+2;
546  //  printf("plevel :%s, voice: %s",printlevel,voice);
547  def save = basering;
548  int N = nvars(basering);
549  int Nnew = 2*N+2;
550  int i,j;
551  string s;
552  list RL = ringlist(basering);
553  list L, Lord;
554  list tmp;
555  intvec iv;
556  L[1] = RL[1];  //char
557  L[4] = RL[4];  //char, minpoly
558  // check whether vars have admissible names
559  list Name  = RL[2];
560  list RName;
561  RName[1] = "t";
562  RName[2] = "s";
563  for (i=1; i<=N; i++)
564  {
565    for(j=1; j<=size(RName); j++)
566    {
567      if (Name[i] == RName[j])
568      {
569        ERROR("Variable names should not include t,s");
570      }
571    }
572  }
573  // now, create the names for new vars
574  list DName;
575  for (i=1; i<=N; i++)
576  {
577    DName[i] = "D"+Name[i];  //concat
578  }
579  tmp[1] = "t";
580  tmp[2] = "s";
581  list NName = tmp + Name + DName;
582  L[2]   = NName;
583  // Name, Dname will be used further
584  kill NName;
585  // block ord (lp(2),dp);
586  tmp[1]  = "lp"; // string
587  iv      = 1,1;
588  tmp[2]  = iv; //intvec
589  Lord[1] = tmp;
590  // continue with dp 1,1,1,1...
591  tmp[1]  = "dp"; // string
592  s       = "iv=";
593  for (i=1; i<=Nnew; i++)
594  {
595    s = s+"1,";
596  }
597  s[size(s)]= ";";
598  execute(s);
599  kill s;
600  tmp[2]    = iv;
601  Lord[2]   = tmp;
602  tmp[1]    = "C";
603  iv        = 0;
604  tmp[2]    = iv;
605  Lord[3]   = tmp;
606  tmp       = 0;
607  L[3]      = Lord;
608  // we are done with the list
609  def @R@ = ring(L);
610  setring @R@;
611  matrix @D[Nnew][Nnew];
612  @D[1,2]=t;
613  for(i=1; i<=N; i++)
614  {
615    @D[2+i,N+2+i]=1;
616  }
617  // L[5] = matrix(UpOneMatrix(Nnew));
618  // L[6] = @D;
619  def @R = nc_algebra(1,@D);
620  setring @R;
621  kill @R@;
622  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
623  dbprint(ppl-1, @R);
624  // create the ideal I
625  poly  F = imap(save,F);
626  ideal I = t*F+s;
627  poly p;
628  for(i=1; i<=N; i++)
629  {
630    p = t;  //t
631    p = diff(F,var(2+i))*p;
632    I = I, var(N+2+i) + p;
633  }
634  // -------- the ideal I is ready ----------
635  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
636  dbprint(ppl-1, I);
637  ideal J = engine(I,eng);
638  ideal K = nselect(J,1);
639  kill I,J;
640  dbprint(ppl,"// -1-3- t is eliminated");
641  dbprint(ppl-1, K);  //K is without t
642  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
643  // thus creating the ring @R2
644  // keep: N, i,j,s, tmp, RL
645  setring save;
646  Nnew = 2*N+1;
647  // list RL = ringlist(save);  //is defined earlier
648  kill Lord, tmp, iv;
649  L = 0;
650  list Lord, tmp;
651  intvec iv;
652  L[1] = RL[1];
653  L[4] = RL[4];  //char, minpoly
654  // check whether vars have admissible names -> done earlier
655  // list Name = RL[2]
656  // DName is defined earlier
657  tmp[1] = "s";
658  list NName = Name + DName + tmp;
659  L[2] = NName;
660  // dp ordering;
661  string s = "iv=";
662  for (i=1; i<=Nnew; i++)
663  {
664    s = s+"1,";
665  }
666  s[size(s)] = ";";
667  execute(s);
668  kill s;
669  tmp     = 0;
670  tmp[1]  = "dp";  //string
671  tmp[2]  = iv;    //intvec
672  Lord[1] = tmp;
673  tmp[1]  = "C";
674  iv      = 0;
675  tmp[2]  = iv;
676  Lord[2] = tmp;
677  tmp     = 0;
678  L[3]    = Lord;
679  // we are done with the list
680  // Add: Plural part
681  def @R2@ = ring(L);
682  setring @R2@;
683  matrix @D[Nnew][Nnew];
684  for (i=1; i<=N; i++)
685  {
686    @D[i,N+i]=1;
687  }
688  def @R2 = nc_algebra(1,@D);
689  setring @R2;
690  kill @R2@;
691  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
692  dbprint(ppl-1, @R2);
693  ideal K = imap(@R,K);
694  option(redSB);
695  //dbprint(ppl,"// -2-2- the final cosmetic std");
696  //K = engine(K,eng);  //std does the job too
697  // total cleanup
698  kill @R;
699  ideal LD = K;
700  export LD;
701  return(@R2);
702}
703example
704{
705  "EXAMPLE:"; echo = 2;
706  ring r = 0,(x,y,z,w),Dp;
707  poly F = x^3+y^3+z^2*w;
708  printlevel = 0;
709  def A = ALTannfsBM(F);
710  setring A;
711  LD;
712}
713
714proc bernsteinBM(poly F, list #)
715"USAGE:  bernsteinBM(f [,eng]);  f a poly, eng an optional int
716RETURN:  list of roots of the Bernstein polynomial b and its multiplicies
717PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f, according to the algorithm by Briancon and Maisonobe
718NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
719@*       otherwise, and by default @code{slimgb} is used.
720@*       If printlevel=1, progress debug messages will be printed,
721@*       if printlevel>=2, all the debug messages will be printed.
722EXAMPLE: example bernsteinBM; shows examples
723"
724{
725  int eng = 0;
726  if ( size(#)>0 )
727  {
728    if ( typeof(#[1]) == "int" )
729    {
730      eng = int(#[1]);
731    }
732  }
733  // returns a list with a ring and an ideal LD in it
734  int ppl = printlevel-voice+2;
735  //  printf("plevel :%s, voice: %s",printlevel,voice);
736  def save = basering;
737  int N = nvars(basering);
738  int Nnew = 2*N+2;
739  int i,j;
740  string s;
741  list RL = ringlist(basering);
742  list L, Lord;
743  list tmp;
744  intvec iv;
745  L[1] = RL[1];  //char
746  L[4] = RL[4];  //char, minpoly
747  // check whether vars have admissible names
748  list Name  = RL[2];
749  list RName;
750  RName[1] = "t";
751  RName[2] = "s";
752  for (i=1; i<=N; i++)
753  {
754    for(j=1; j<=size(RName); j++)
755    {
756      if (Name[i] == RName[j])
757      {
758        ERROR("Variable names should not include t,s");
759      }
760    }
761  }
762  // now, create the names for new vars
763  list DName;
764  for (i=1; i<=N; i++)
765  {
766    DName[i] = "D"+Name[i];  //concat
767  }
768  tmp[1] = "t";
769  tmp[2] = "s";
770  list NName = tmp + Name + DName;
771  L[2]   = NName;
772  // Name, Dname will be used further
773  kill NName;
774  // block ord (lp(2),dp);
775  tmp[1]  = "lp"; // string
776  iv      = 1,1;
777  tmp[2]  = iv; //intvec
778  Lord[1] = tmp;
779  // continue with dp 1,1,1,1...
780  tmp[1]  = "dp"; // string
781  s       = "iv=";
782  for (i=1; i<=Nnew; i++)
783  {
784    s = s+"1,";
785  }
786  s[size(s)]= ";";
787  execute(s);
788  kill s;
789  tmp[2]    = iv;
790  Lord[2]   = tmp;
791  tmp[1]    = "C";
792  iv        = 0;
793  tmp[2]    = iv;
794  Lord[3]   = tmp;
795  tmp       = 0;
796  L[3]      = Lord;
797  // we are done with the list
798  def @R@ = ring(L);
799  setring @R@;
800  matrix @D[Nnew][Nnew];
801  @D[1,2]=t;
802  for(i=1; i<=N; i++)
803  {
804    @D[2+i,N+2+i]=1;
805  }
806  // L[5] = matrix(UpOneMatrix(Nnew));
807  // L[6] = @D;
808  def @R = nc_algebra(1,@D);
809  setring @R;
810  kill @R@;
811  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
812  dbprint(ppl-1, @R);
813  // create the ideal I
814  poly  F = imap(save,F);
815  ideal I = t*F+s;
816  poly p;
817  for(i=1; i<=N; i++)
818  {
819    p = t;  //t
820    p = diff(F,var(2+i))*p;
821    I = I, var(N+2+i) + p;
822  }
823  // -------- the ideal I is ready ----------
824  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
825  dbprint(ppl-1, I);
826  ideal J = engine(I,eng);
827  ideal K = nselect(J,1);
828  kill I,J;
829  dbprint(ppl,"// -1-3- t is eliminated");
830  dbprint(ppl-1, K);  //K is without t
831  // ----------- the ring @R2 ------------
832  // _x, _Dx,s;  elim.ord for _x,_Dx.
833  // keep: N, i,j,s, tmp, RL
834  setring save;
835  Nnew = 2*N+1;
836  kill Lord, tmp, iv, RName;
837  list Lord, tmp;
838  intvec iv;
839  L[1] = RL[1];
840  L[4] = RL[4];  //char, minpoly
841  // check whether vars hava admissible names -> done earlier
842  // now, create the names for new var
843  tmp[1] = "s";
844  // DName is defined earlier
845  list NName = Name + DName + tmp;
846  L[2] = NName;
847  tmp = 0;
848  // block ord (dp(N),dp);
849  string s = "iv=";
850  for (i=1; i<=Nnew-1; i++)
851  {
852    s = s+"1,";
853  }
854  s[size(s)]=";";
855  execute(s);
856  tmp[1] = "dp";  //string
857  tmp[2] = iv;    //intvec
858  Lord[1] = tmp;
859  // continue with dp 1,1,1,1...
860  tmp[1] = "dp";  //string
861  s[size(s)] = ",";
862  s = s+"1;";
863  execute(s);
864  kill s;
865  kill NName;
866  tmp[2]  = iv;
867  Lord[2] = tmp;
868  tmp[1]  = "C";
869  iv      = 0;
870  tmp[2]  = iv;
871  Lord[3] = tmp;
872  tmp     = 0;
873  L[3]    = Lord;
874  // we are done with the list. Now add a Plural part
875  def @R2@ = ring(L);
876  setring @R2@;
877  matrix @D[Nnew][Nnew];
878  for (i=1; i<=N; i++)
879  {
880    @D[i,N+i]=1;
881  }
882  def @R2 = nc_algebra(1,@D);
883  setring @R2;
884  kill @R2@;
885  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
886  dbprint(ppl-1, @R2);
887  ideal MM = maxideal(1);
888  MM = 0,s,MM;
889  map R01 = @R, MM;
890  ideal K = R01(K);
891  kill @R, R01;
892  poly F = imap(save,F);
893  K = K,F;
894  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
895  dbprint(ppl-1, K);
896  ideal M = engine(K,eng);
897  ideal K2 = nselect(M,1,Nnew-1);
898  kill K,M;
899  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
900  dbprint(ppl-1, K2);
901  // the ring @R3 and the search for minimal negative int s
902  ring @R3 = 0,s,dp;
903  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
904  ideal K3 = imap(@R2,K2);
905  kill @R2;
906  poly p = K3[1];
907  dbprint(ppl,"// -3-2- factorization");
908  list P = factorize(p);          //with constants and multiplicities
909  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
910  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
911  {
912    bs[i-1] = P[1][i];
913    m[i-1]  = P[2][i];
914  }
915  // "--------- b-function factorizes into ---------";  P;
916  //int sP = minIntRoot(bs,1);
917  //dbprint(ppl,"// -3-3- minimal integer root found");
918  //dbprint(ppl-1, sP);
919  // convert factors to a list of their roots and multiplicities
920  bs =  normalize(bs);
921  bs = -subst(bs,s,0);
922  setring save;
923  ideal bs = imap(@R3,bs);
924  kill @R3;
925  list BS = bs,m;
926  return(BS);
927}
928example
929{
930  "EXAMPLE:"; echo = 2;
931  ring r = 0,(x,y,z,w),Dp;
932  poly F = x^3+y^3+z^2*w;
933  printlevel = 0;
934  bernsteinBM(F);
935}
936
937// some changes
938proc annfsBM (poly F, list #)
939"USAGE:  annfsBM(f [,eng]);  f a poly, eng an optional int
940RETURN:  ring
941PURPOSE: compute the D-module structure of basering[1/f]*f^s, according
942to the algorithm by Briancon and Maisonobe
943NOTE:    activate this ring with the @code{setring} command. In this ring,
944@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
945@*         which is obtained by substituting the minimal integer root of a Bernstein
946@*         polynomial into the s-parametric ideal;
947@*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
948@*       If eng <>0, @code{std} is used for Groebner basis computations,
949@*       otherwise, and by default @code{slimgb} is used.
950@*       If printlevel=1, progress debug messages will be printed,
951@*       if printlevel>=2, all the debug messages will be printed.
952EXAMPLE: example annfsBM; shows examples
953"
954{
955  int eng = 0;
956  if ( size(#)>0 )
957  {
958    if ( typeof(#[1]) == "int" )
959    {
960      eng = int(#[1]);
961    }
962  }
963  // returns a list with a ring and an ideal LD in it
964  int ppl = printlevel-voice+2;
965  //  printf("plevel :%s, voice: %s",printlevel,voice);
966  def save = basering;
967  int N = nvars(basering);
968  int Nnew = 2*N+2;
969  int i,j;
970  string s;
971  list RL = ringlist(basering);
972  list L, Lord;
973  list tmp;
974  intvec iv;
975  L[1] = RL[1];  //char
976  L[4] = RL[4];  //char, minpoly
977  // check whether vars have admissible names
978  list Name  = RL[2];
979  list RName;
980  RName[1] = "t";
981  RName[2] = "s";
982  for (i=1; i<=N; i++)
983  {
984    for(j=1; j<=size(RName); j++)
985    {
986      if (Name[i] == RName[j])
987      {
988        ERROR("Variable names should not include t,s");
989      }
990    }
991  }
992  // now, create the names for new vars
993  list DName;
994  for (i=1; i<=N; i++)
995  {
996    DName[i] = "D"+Name[i];  //concat
997  }
998  tmp[1] = "t";
999  tmp[2] = "s";
1000  list NName = tmp + Name + DName;
1001  L[2]   = NName;
1002  // Name, Dname will be used further
1003  kill NName;
1004  // block ord (lp(2),dp);
1005  tmp[1]  = "lp"; // string
1006  iv      = 1,1;
1007  tmp[2]  = iv; //intvec
1008  Lord[1] = tmp;
1009  // continue with dp 1,1,1,1...
1010  tmp[1]  = "dp"; // string
1011  s       = "iv=";
1012  for (i=1; i<=Nnew; i++)
1013  {
1014    s = s+"1,";
1015  }
1016  s[size(s)]= ";";
1017  execute(s);
1018  kill s;
1019  tmp[2]    = iv;
1020  Lord[2]   = tmp;
1021  tmp[1]    = "C";
1022  iv        = 0;
1023  tmp[2]    = iv;
1024  Lord[3]   = tmp;
1025  tmp       = 0;
1026  L[3]      = Lord;
1027  // we are done with the list
1028  def @R@ = ring(L);
1029  setring @R@;
1030  matrix @D[Nnew][Nnew];
1031  @D[1,2]=t;
1032  for(i=1; i<=N; i++)
1033  {
1034    @D[2+i,N+2+i]=1;
1035  }
1036  // L[5] = matrix(UpOneMatrix(Nnew));
1037  // L[6] = @D;
1038  def @R = nc_algebra(1,@D);
1039  setring @R;
1040  kill @R@;
1041  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
1042  dbprint(ppl-1, @R);
1043  // create the ideal I
1044  poly  F = imap(save,F);
1045  ideal I = t*F+s;
1046  poly p;
1047  for(i=1; i<=N; i++)
1048  {
1049    p = t;  //t
1050    p = diff(F,var(2+i))*p;
1051    I = I, var(N+2+i) + p;
1052  }
1053  // -------- the ideal I is ready ----------
1054  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
1055  dbprint(ppl-1, I);
1056  ideal J = engine(I,eng);
1057  ideal K = nselect(J,1);
1058  kill I,J;
1059  dbprint(ppl,"// -1-3- t is eliminated");
1060  dbprint(ppl-1, K);  //K is without t
1061  setring save;
1062  // ----------- the ring @R2 ------------
1063  // _x, _Dx,s;  elim.ord for _x,_Dx.
1064  // keep: N, i,j,s, tmp, RL
1065  Nnew = 2*N+1;
1066  kill Lord, tmp, iv, RName;
1067  list Lord, tmp;
1068  intvec iv;
1069  L[1] = RL[1];
1070  L[4] = RL[4];  //char, minpoly
1071  // check whether vars hava admissible names -> done earlier
1072  // now, create the names for new var
1073  tmp[1] = "s";
1074  // DName is defined earlier
1075  list NName = Name + DName + tmp;
1076  L[2] = NName;
1077  tmp = 0;
1078  // block ord (dp(N),dp);
1079  string s = "iv=";
1080  for (i=1; i<=Nnew-1; i++)
1081  {
1082    s = s+"1,";
1083  }
1084  s[size(s)]=";";
1085  execute(s);
1086  tmp[1] = "dp";  //string
1087  tmp[2] = iv;    //intvec
1088  Lord[1] = tmp;
1089  // continue with dp 1,1,1,1...
1090  tmp[1] = "dp";  //string
1091  s[size(s)] = ",";
1092  s = s+"1;";
1093  execute(s);
1094  kill s;
1095  kill NName;
1096  tmp[2]  = iv;
1097  Lord[2] = tmp;
1098  tmp[1]  = "C";
1099  iv      = 0;
1100  tmp[2]  = iv;
1101  Lord[3] = tmp;
1102  tmp     = 0;
1103  L[3]    = Lord;
1104  // we are done with the list. Now add a Plural part
1105  def @R2@ = ring(L);
1106  setring @R2@;
1107  matrix @D[Nnew][Nnew];
1108  for (i=1; i<=N; i++)
1109  {
1110    @D[i,N+i]=1;
1111  }
1112  def @R2 = nc_algebra(1,@D);
1113  setring @R2;
1114  kill @R2@;
1115  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
1116  dbprint(ppl-1, @R2);
1117  ideal MM = maxideal(1);
1118  MM = 0,s,MM;
1119  map R01 = @R, MM;
1120  ideal K = R01(K);
1121  poly F = imap(save,F);
1122  K = K,F;
1123  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
1124  dbprint(ppl-1, K);
1125  ideal M = engine(K,eng);
1126  ideal K2 = nselect(M,1,Nnew-1);
1127  kill K,M;
1128  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
1129  dbprint(ppl-1, K2);
1130  // the ring @R3 and the search for minimal negative int s
1131  ring @R3 = 0,s,dp;
1132  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
1133  ideal K3 = imap(@R2,K2);
1134  poly p = K3[1];
1135  dbprint(ppl,"// -3-2- factorization");
1136  list P = factorize(p);          //with constants and multiplicities
1137  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
1138  for (i=2; i<= size(P[1]); i++)  //we ignore P[1][1] (constant) and P[2][1] (its mult.)
1139  {
1140    bs[i-1] = P[1][i];
1141    m[i-1]  = P[2][i];
1142  }
1143  // "--------- b-function factorizes into ---------";  P;
1144  int sP = minIntRoot(bs,1);
1145  dbprint(ppl,"// -3-3- minimal integer root found");
1146  dbprint(ppl-1, sP);
1147  // convert factors to a list of their roots
1148  bs = normalize(bs);
1149  bs = -subst(bs,s,0);
1150  list BS = bs,m;
1151  //TODO: sort BS!
1152  // --------- substitute s found in the ideal ---------
1153  // --------- going back to @R and substitute ---------
1154  setring @R;
1155  ideal K2 = subst(K,s,sP);
1156  kill K;
1157  // create the ordinary Weyl algebra and put the result into it,
1158  // thus creating the ring @R4
1159  // keep: N, i,j,s, tmp, RL
1160  setring save;
1161  Nnew = 2*N;
1162  // list RL = ringlist(save);  //is defined earlier
1163  kill Lord, tmp, iv;
1164  L = 0;
1165  list Lord, tmp;
1166  intvec iv;
1167  L[1] = RL[1];
1168  L[4] = RL[4];  //char, minpoly
1169  // check whether vars have admissible names -> done earlier
1170  // list Name = RL[2]M
1171  // DName is defined earlier
1172  list NName = Name + DName;
1173  L[2] = NName;
1174  // dp ordering;
1175  string s = "iv=";
1176  for (i=1; i<=Nnew; i++)
1177  {
1178    s = s+"1,";
1179  }
1180  s[size(s)] = ";";
1181  execute(s);
1182  kill s;
1183  tmp     = 0;
1184  tmp[1]  = "dp";  //string
1185  tmp[2]  = iv;    //intvec
1186  Lord[1] = tmp;
1187  tmp[1]  = "C";
1188  iv      = 0;
1189  tmp[2]  = iv;
1190  Lord[2] = tmp;
1191  tmp     = 0;
1192  L[3]    = Lord;
1193  // we are done with the list
1194  // Add: Plural part
1195  def @R4@ = ring(L);
1196  setring @R4@;
1197  matrix @D[Nnew][Nnew];
1198  for (i=1; i<=N; i++)
1199  {
1200    @D[i,N+i]=1;
1201  }
1202  def @R4 = nc_algebra(1,@D);
1203  setring @R4;
1204  kill @R4@;
1205  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx) is ready");
1206  dbprint(ppl-1, @R4);
1207  ideal K4 = imap(@R,K2);
1208  option(redSB);
1209  dbprint(ppl,"// -4-2- the final cosmetic std");
1210  K4 = engine(K4,eng);  //std does the job too
1211  // total cleanup
1212  kill @R;
1213  kill @R2;
1214  list BS = imap(@R3,BS);
1215  export BS;
1216  kill @R3;
1217  ideal LD = K4;
1218  export LD;
1219  return(@R4);
1220}
1221example
1222{
1223  "EXAMPLE:"; echo = 2;
1224  ring r = 0,(x,y,z),Dp;
1225  poly F = z*x^2+y^3;
1226  printlevel = 0;
1227  def A = annfsBM(F);
1228  setring A;
1229  LD;
1230  BS;
1231}
1232
1233proc operatorBM(poly F, list #)
1234"USAGE:  operatorBM(f [,eng]);  f a poly, eng an optional int
1235RETURN:  ring
1236PURPOSE: compute the B-operator and other relevant data for Ann F^s, according to the algorithm by Briancon and Maisonobe
1237NOTE:    activate this ring with the @code{setring} command. In this ring D[s]
1238@*       - the polynomial F is the same as the input,
1239@*       - the ideal LD is the annihilator of f^s in Dn[s],
1240@*       - the ideal LD0 is the needed D-mod structure, where LD0 = LD|s=s0,
1241@*       - the polynomial bs is the global Bernstein polynomial of f in the variable s,
1242@*       - the list BS contains all the roots with multiplicities of the global Bernstein polynomial of f,
1243@*       - the polynomial PS is an operator in Dn[s] such that PS*f^(s+1) = bs*f^s.
1244@*       If eng <>0, @code{std} is used for Groebner basis computations,
1245@*       otherwise and by default @code{slimgb} is used.
1246@*       If printlevel=1, progress debug messages will be printed,
1247@*       if printlevel>=2, all the debug messages will be printed.
1248EXAMPLE: example operatorBM; shows examples
1249"
1250{
1251  int eng = 0;
1252  if ( size(#)>0 )
1253  {
1254    if ( typeof(#[1]) == "int" )
1255    {
1256      eng = int(#[1]);
1257    }
1258  }
1259  // returns a list with a ring and an ideal LD in it
1260  int ppl = printlevel-voice+2;
1261  //  printf("plevel :%s, voice: %s",printlevel,voice);
1262  def save = basering;
1263  int N = nvars(basering);
1264  int Nnew = 2*N+2;
1265  int i,j;
1266  string s;
1267  list RL = ringlist(basering);
1268  list L, Lord;
1269  list tmp;
1270  intvec iv;
1271  L[1] = RL[1];  //char
1272  L[4] = RL[4];  //char, minpoly
1273  // check whether vars have admissible names
1274  list Name  = RL[2];
1275  list RName;
1276  RName[1] = "t";
1277  RName[2] = "s";
1278  for (i=1; i<=N; i++)
1279  {
1280    for(j=1; j<=size(RName); j++)
1281    {
1282      if (Name[i] == RName[j])
1283      {
1284        ERROR("Variable names should not include t,s");
1285      }
1286    }
1287  }
1288  // now, create the names for new vars
1289  list DName;
1290  for (i=1; i<=N; i++)
1291  {
1292    DName[i] = "D"+Name[i];  //concat
1293  }
1294  tmp[1] = "t";
1295  tmp[2] = "s";
1296  list NName = tmp + Name + DName;
1297  L[2]   = NName;
1298  // Name, Dname will be used further
1299  kill NName;
1300  // block ord (lp(2),dp);
1301  tmp[1]  = "lp"; // string
1302  iv      = 1,1;
1303  tmp[2]  = iv; //intvec
1304  Lord[1] = tmp;
1305  // continue with dp 1,1,1,1...
1306  tmp[1]  = "dp"; // string
1307  s       = "iv=";
1308  for (i=1; i<=Nnew; i++)
1309  {
1310    s = s+"1,";
1311  }
1312  s[size(s)]= ";";
1313  execute(s);
1314  kill s;
1315  tmp[2]    = iv;
1316  Lord[2]   = tmp;
1317  tmp[1]    = "C";
1318  iv        = 0;
1319  tmp[2]    = iv;
1320  Lord[3]   = tmp;
1321  tmp       = 0;
1322  L[3]      = Lord;
1323  // we are done with the list
1324  def @R@ = ring(L);
1325  setring @R@;
1326  matrix @D[Nnew][Nnew];
1327  @D[1,2]=t;
1328  for(i=1; i<=N; i++)
1329  {
1330    @D[2+i,N+2+i]=1;
1331  }
1332  // L[5] = matrix(UpOneMatrix(Nnew));
1333  // L[6] = @D;
1334  def @R = nc_algebra(1,@D);
1335  setring @R;
1336  kill @R@;
1337  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
1338  dbprint(ppl-1, @R);
1339  // create the ideal I
1340  poly  F = imap(save,F);
1341  ideal I = t*F+s;
1342  poly p;
1343  for(i=1; i<=N; i++)
1344  {
1345    p = t;  //t
1346    p = diff(F,var(2+i))*p;
1347    I = I, var(N+2+i) + p;
1348  }
1349  // -------- the ideal I is ready ----------
1350  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
1351  dbprint(ppl-1, I);
1352  ideal J = engine(I,eng);
1353  ideal K = nselect(J,1);
1354  kill I,J;
1355  dbprint(ppl,"// -1-3- t is eliminated");
1356  dbprint(ppl-1, K);  //K is without t
1357  setring save;
1358  // ----------- the ring @R2 ------------
1359  // _x, _Dx,s;  elim.ord for _x,_Dx.
1360  // keep: N, i,j,s, tmp, RL
1361  Nnew = 2*N+1;
1362  kill Lord, tmp, iv, RName;
1363  list Lord, tmp;
1364  intvec iv;
1365  L[1] = RL[1];
1366  L[4] = RL[4];  //char, minpoly
1367  // check whether vars hava admissible names -> done earlier
1368  // now, create the names for new var
1369  tmp[1] = "s";
1370  // DName is defined earlier
1371  list NName = Name + DName + tmp;
1372  L[2] = NName;
1373  tmp = 0;
1374  // block ord (dp(N),dp);
1375  string s = "iv=";
1376  for (i=1; i<=Nnew-1; i++)
1377  {
1378    s = s+"1,";
1379  }
1380  s[size(s)]=";";
1381  execute(s);
1382  tmp[1] = "dp";  //string
1383  tmp[2] = iv;    //intvec
1384  Lord[1] = tmp;
1385  // continue with dp 1,1,1,1...
1386  tmp[1] = "dp";  //string
1387  s[size(s)] = ",";
1388  s = s+"1;";
1389  execute(s);
1390  kill s;
1391  kill NName;
1392  tmp[2]  = iv;
1393  Lord[2] = tmp;
1394  tmp[1]  = "C";
1395  iv      = 0;
1396  tmp[2]  = iv;
1397  Lord[3] = tmp;
1398  tmp     = 0;
1399  L[3]    = Lord;
1400  // we are done with the list. Now add a Plural part
1401  def @R2@ = ring(L);
1402  setring @R2@;
1403  matrix @D[Nnew][Nnew];
1404  for (i=1; i<=N; i++)
1405  {
1406    @D[i,N+i]=1;
1407  }
1408  def @R2 = nc_algebra(1,@D);
1409  setring @R2;
1410  kill @R2@;
1411  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
1412  dbprint(ppl-1, @R2);
1413  ideal MM = maxideal(1);
1414  MM = 0,s,MM;
1415  map R01 = @R, MM;
1416  ideal K = R01(K);
1417  poly F = imap(save,F);
1418  K = K,F;
1419  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
1420  dbprint(ppl-1, K);
1421  ideal M = engine(K,eng);
1422  ideal K2 = nselect(M,1,Nnew-1);
1423  kill K,M;
1424  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
1425  dbprint(ppl-1, K2);
1426  // the ring @R3 and the search for minimal negative int s
1427  ring @R3 = 0,s,dp;
1428  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
1429  ideal K3 = imap(@R2,K2);
1430  kill @R2;
1431  poly p = K3[1];
1432  dbprint(ppl,"// -3-2- factorization");
1433  list P = factorize(p);          //with constants and multiplicities
1434  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
1435  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
1436  {
1437    bs[i-1] = P[1][i];
1438    m[i-1]  = P[2][i];
1439  }
1440  // "--------- b-function factorizes into ---------";  P;
1441  int sP = minIntRoot(bs,1);
1442  dbprint(ppl,"// -3-3- minimal integer root found");
1443  dbprint(ppl-1, sP);
1444  // convert factors to a list of their roots with multiplicities
1445  bs = normalize(bs);
1446  bs = -subst(bs,s,0);
1447  list BS = bs,m;
1448  //TODO: sort BS!
1449  // --------- substitute s found in the ideal ---------
1450  // --------- going back to @R and substitute ---------
1451  setring @R;
1452  ideal K2 = subst(K,s,sP);
1453  // create Dn[s], where Dn is the ordinary Weyl algebra, and put the result into it,
1454  // thus creating the ring @R4
1455  // keep: N, i,j,s, tmp, RL
1456  setring save;
1457  Nnew = 2*N+1;
1458  // list RL = ringlist(save);  //is defined earlier
1459  kill Lord, tmp, iv;
1460  L = 0;
1461  list Lord, tmp;
1462  intvec iv;
1463  L[1] = RL[1];
1464  L[4] = RL[4];  //char, minpoly
1465  // check whether vars have admissible names -> done earlier
1466  // list Name = RL[2]
1467  // DName is defined earlier
1468  tmp[1] = "s";
1469  list NName = Name + DName + tmp;
1470  L[2] = NName;
1471  // dp ordering;
1472  string s = "iv=";
1473  for (i=1; i<=Nnew; i++)
1474  {
1475    s = s+"1,";
1476  }
1477  s[size(s)] = ";";
1478  execute(s);
1479  kill s;
1480  tmp     = 0;
1481  tmp[1]  = "dp";  //string
1482  tmp[2]  = iv;    //intvec
1483  Lord[1] = tmp;
1484  tmp[1]  = "C";
1485  iv      = 0;
1486  tmp[2]  = iv;
1487  Lord[2] = tmp;
1488  tmp     = 0;
1489  L[3]    = Lord;
1490  // we are done with the list
1491  // Add: Plural part
1492  def @R4@ = ring(L);
1493  setring @R4@;
1494  matrix @D[Nnew][Nnew];
1495  for (i=1; i<=N; i++)
1496  {
1497    @D[i,N+i]=1;
1498  }
1499  def @R4 = nc_algebra(1,@D);
1500  setring @R4;
1501  kill @R4@;
1502  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx,s) is ready");
1503  dbprint(ppl-1, @R4);
1504  ideal LD0 = imap(@R,K2);
1505  ideal LD  = imap(@R,K);
1506  kill @R;
1507  poly bs = imap(@R3,p);
1508  list BS = imap(@R3,BS);
1509  kill @R3;
1510  bs = normalize(bs);
1511  poly F = imap(save,F);
1512  dbprint(ppl,"// -4-2- starting the computation of PS via lift");
1513//better liftstd, I didn't knot it works also for Plural, liftslimgb?
1514// liftstd may give extra coeffs in the resulting ideal
1515  matrix T = lift(F+LD,bs);
1516  poly PS = T[1,1];
1517  dbprint(ppl,"// -4-3- an operator PS found, PS*f^(s+1) = b(s)*f^s");
1518  dbprint(ppl-1,PS);
1519  option(redSB);
1520  dbprint(ppl,"// -4-4- the final cosmetic std");
1521  LD0 = engine(LD0,eng);  //std does the job too
1522  LD  = engine(LD,eng);
1523  export F,LD,LD0,bs,BS,PS;
1524  return(@R4);
1525}
1526example
1527{
1528  "EXAMPLE:"; echo = 2;
1529  //  ring r = 0,(x,y,z,w),Dp;
1530  //  poly F = x^3+y^3+z^2*w;
1531  ring r = 0,(x,y,z),Dp;
1532  poly F = x^3+y^3+z^3;
1533  printlevel = 0;
1534  def A = operatorBM(F);
1535  setring A;
1536  F; // the original polynomial itself
1537  LD; // generic annihilator
1538  LD0; // annihilator
1539  bs; // normalized Bernstein poly
1540  BS; // root and multiplicities of the Bernstein poly
1541  PS; // the operator, s.t. PS*F^{s+1} = bs*F^s mod LD
1542  reduce(PS*F-bs,LD); // check the property of PS
1543}
1544
1545proc annfsParamBM (poly F, list #)
1546"USAGE:  annfsParamBM(f [,eng]);  f a poly, eng an optional int
1547RETURN:  ring
1548PURPOSE: compute the generic Ann F^s and exceptional parametric constellations of a polynomial with parametric coefficients, according to the algorithm by Briancon and Maisonobe
1549NOTE:    activate this ring with the @code{setring} command. In this ring,
1550@*       - the ideal LD is the D-module structure oa Ann F^s
1551@*       - the ideal Param contains the list of the special parameters.
1552@*       If eng <>0, @code{std} is used for Groebner basis computations,
1553@*       otherwise, and by default @code{slimgb} is used.
1554@*       If printlevel=1, progress debug messages will be printed,
1555@*       if printlevel>=2, all the debug messages will be printed.
1556EXAMPLE: example annfsParamBM; shows examples
1557"
1558{
1559  //PURPOSE: compute the list of all possible Bernstein-Sato polynomials for a polynomial with parametric coefficients, according to the algorithm by Briancon and Maisonobe
1560  // @*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
1561  // ***** not implented yet ****
1562  int eng = 0;
1563  if ( size(#)>0 )
1564  {
1565    if ( typeof(#[1]) == "int" )
1566    {
1567      eng = int(#[1]);
1568    }
1569  }
1570  // returns a list with a ring and an ideal LD in it
1571  int ppl = printlevel-voice+2;
1572  //  printf("plevel :%s, voice: %s",printlevel,voice);
1573  def save = basering;
1574  int N = nvars(basering);
1575  int Nnew = 2*N+2;
1576  int i,j;
1577  string s;
1578  list RL = ringlist(basering);
1579  list L, Lord;
1580  list tmp;
1581  intvec iv;
1582  L[1] = RL[1];  //char
1583  L[4] = RL[4];  //char, minpoly
1584  // check whether vars have admissible names
1585  list Name  = RL[2];
1586  list RName;
1587  RName[1] = "t";
1588  RName[2] = "s";
1589  for (i=1; i<=N; i++)
1590  {
1591    for(j=1; j<=size(RName); j++)
1592    {
1593      if (Name[i] == RName[j])
1594      {
1595        ERROR("Variable names should not include t,s");
1596      }
1597    }
1598  }
1599  // now, create the names for new vars
1600  list DName;
1601  for (i=1; i<=N; i++)
1602  {
1603    DName[i] = "D"+Name[i];  //concat
1604  }
1605  tmp[1] = "t";
1606  tmp[2] = "s";
1607  list NName = tmp + Name + DName;
1608  L[2]   = NName;
1609  // Name, Dname will be used further
1610  kill NName;
1611  // block ord (lp(2),dp);
1612  tmp[1]  = "lp"; // string
1613  iv      = 1,1;
1614  tmp[2]  = iv; //intvec
1615  Lord[1] = tmp;
1616  // continue with dp 1,1,1,1...
1617  tmp[1]  = "dp"; // string
1618  s       = "iv=";
1619  for (i=1; i<=Nnew; i++)
1620  {
1621    s = s+"1,";
1622  }
1623  s[size(s)]= ";";
1624  execute(s);
1625  kill s;
1626  tmp[2]    = iv;
1627  Lord[2]   = tmp;
1628  tmp[1]    = "C";
1629  iv        = 0;
1630  tmp[2]    = iv;
1631  Lord[3]   = tmp;
1632  tmp       = 0;
1633  L[3]      = Lord;
1634  // we are done with the list
1635  def @R@ = ring(L);
1636  setring @R@;
1637  matrix @D[Nnew][Nnew];
1638  @D[1,2]=t;
1639  for(i=1; i<=N; i++)
1640  {
1641    @D[2+i,N+2+i]=1;
1642  }
1643  // L[5] = matrix(UpOneMatrix(Nnew));
1644  // L[6] = @D;
1645  def @R = nc_algebra(1,@D);
1646  setring @R;
1647  kill @R@;
1648  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
1649  dbprint(ppl-1, @R);
1650  // create the ideal I
1651  poly  F = imap(save,F);
1652  ideal I = t*F+s;
1653  poly p;
1654  for(i=1; i<=N; i++)
1655  {
1656    p = t;  //t
1657    p = diff(F,var(2+i))*p;
1658    I = I, var(N+2+i) + p;
1659  }
1660  // -------- the ideal I is ready ----------
1661  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
1662  dbprint(ppl-1, I);
1663  ideal J = engine(I,eng);
1664  ideal K = nselect(J,1);
1665  dbprint(ppl,"// -1-3- t is eliminated");
1666  dbprint(ppl-1, K);  //K is without t
1667  // ----- looking for special parameters -----
1668  dbprint(ppl,"// -2-1- starting the computation of the transformation matrix (via lift)");
1669  J = normalize(J);
1670  matrix T = lift(I,J);  //try also with liftstd
1671  kill I,J;
1672  dbprint(ppl,"// -2-2- the transformation matrix has been computed");
1673  dbprint(ppl-1, T);  //T is the transformation matrix
1674  dbprint(ppl,"// -2-3- genericity does the job");
1675  list lParam = genericity(T);
1676  int ip = size(lParam);
1677  int cip;
1678  string sParam;
1679  if (sParam[1]=="-") { sParam=""; } //genericity returns "-"
1680  // if no parameters exist in a basering
1681  for (cip=1; cip <= ip; cip++)
1682  {
1683    sParam = sParam + "," +lParam[cip];
1684  }
1685  if (size(sParam) >=2)
1686  {
1687    sParam = sParam[2..size(sParam)]; // removes the 1st colon
1688  }
1689  export sParam;
1690  kill T;
1691  dbprint(ppl,"// -2-4- the special parameters has been computed");
1692  dbprint(ppl, sParam);
1693  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
1694  // thus creating the ring @R2
1695  // keep: N, i,j,s, tmp, RL
1696  setring save;
1697  Nnew = 2*N+1;
1698  // list RL = ringlist(save);  //is defined earlier
1699  kill Lord, tmp, iv;
1700  L = 0;
1701  list Lord, tmp;
1702  intvec iv;
1703  L[1] = RL[1];
1704  L[4] = RL[4];  //char, minpoly
1705  // check whether vars have admissible names -> done earlier
1706  // list Name = RL[2]M
1707  // DName is defined earlier
1708  tmp[1] = "s";
1709  list NName = Name + DName + tmp;
1710  L[2] = NName;
1711  // dp ordering;
1712  string s = "iv=";
1713  for (i=1; i<=Nnew; i++)
1714  {
1715    s = s+"1,";
1716  }
1717  s[size(s)] = ";";
1718  execute(s);
1719  kill s;
1720  tmp     = 0;
1721  tmp[1]  = "dp";  //string
1722  tmp[2]  = iv;    //intvec
1723  Lord[1] = tmp;
1724  tmp[1]  = "C";
1725  iv      = 0;
1726  tmp[2]  = iv;
1727  Lord[2] = tmp;
1728  tmp     = 0;
1729  L[3]    = Lord;
1730  // we are done with the list
1731  // Add: Plural part
1732  def @R2@ = ring(L);
1733  setring @R2@;
1734  matrix @D[Nnew][Nnew];
1735  for (i=1; i<=N; i++)
1736  {
1737    @D[i,N+i]=1;
1738  }
1739  def @R2 = nc_algebra(1,@D);
1740  setring @R2;
1741  kill @R2@;
1742  dbprint(ppl,"// -3-1- the ring @R2(_x,_Dx,s) is ready");
1743  dbprint(ppl-1, @R2);
1744  ideal K = imap(@R,K);
1745  kill @R;
1746  option(redSB);
1747  dbprint(ppl,"// -3-2- the final cosmetic std");
1748  K = engine(K,eng);  //std does the job too
1749  ideal LD = K;
1750  export LD;
1751  if (sParam[1] == ",")
1752  {
1753    sParam = sParam[2..size(sParam)];
1754  }
1755  //  || ((sParam[1] == " ") && (sParam[2] == ",")))
1756  execute("ideal Param ="+sParam+";");
1757  export Param;
1758  kill sParam;
1759  return(@R2);
1760}
1761example
1762{
1763  "EXAMPLE:"; echo = 2;
1764  ring r = (0,a,b),(x,y),Dp;
1765  poly F = x^2 - (y-a)*(y-b);
1766  printlevel = 0;
1767  def A = annfsParamBM(F);  setring A;
1768  LD;
1769  Param;
1770  setring r;
1771  poly G = x2-(y-a)^2; // try the exceptional value b=a of parameters
1772  def B = annfsParamBM(G); setring B;
1773  LD;
1774  Param;
1775}
1776
1777// *** the following example is nice, but too complicated for the documentation ***
1778//   ring r = (0,a),(x,y,z),Dp;
1779//   poly F = x^4+y^4+z^2+a*x*y*z;
1780//   printlevel = 2; //0
1781//   def A = annfsParamBM(F);
1782//   setring A;
1783//   LD;
1784//   Param;
1785
1786
1787proc annfsBMI(ideal F, list #)
1788"USAGE:  annfsBMI(F [,eng]);  F an ideal, eng an optional int
1789RETURN:  ring
1790PURPOSE: compute the D-module structure of basering[1/f]*f^s where f = F[1]*..*F[P],
1791according to the algorithm by Briancon and Maisonobe.
1792NOTE:    activate this ring with the @code{setring} command. In this ring,
1793@*       - the ideal LD is the needed D-mod structure,
1794@*       - the list BS is the Bernstein ideal of a polynomial f = F[1]*..*F[P].
1795@*       If eng <>0, @code{std} is used for Groebner basis computations,
1796@*       otherwise, and by default @code{slimgb} is used.
1797@*       If printlevel=1, progress debug messages will be printed,
1798@*       if printlevel>=2, all the debug messages will be printed.
1799EXAMPLE: example annfsBMI; shows examples
1800"
1801{
1802  int eng = 0;
1803  if ( size(#)>0 )
1804  {
1805    if ( typeof(#[1]) == "int" )
1806    {
1807      eng = int(#[1]);
1808    }
1809  }
1810  // returns a list with a ring and an ideal LD in it
1811  int ppl = printlevel-voice+2;
1812  //  printf("plevel :%s, voice: %s",printlevel,voice);
1813  def save = basering;
1814  int N = nvars(basering);
1815  int P = size(F);  //if F has some generators which are zero, int P = ncols(I);
1816  int Nnew = 2*N+2*P;
1817  int i,j;
1818  string s;
1819  list RL = ringlist(basering);
1820  list L, Lord;
1821  list tmp;
1822  intvec iv;
1823  L[1] = RL[1];  //char
1824  L[4] = RL[4];  //char, minpoly
1825  // check whether vars have admissible names
1826  list Name  = RL[2];
1827  list RName;
1828  for (j=1; j<=P; j++)
1829  {
1830    RName[j] = "t("+string(j)+")";
1831    RName[j+P] = "s("+string(j)+")";
1832  }
1833  for(i=1; i<=N; i++)
1834  {
1835    for(j=1; j<=size(RName); j++)
1836    {
1837      if (Name[i] == RName[j])
1838      { ERROR("Variable names should not include t(i),s(i)"); }
1839    }
1840  }
1841  // now, create the names for new vars
1842  list DName;
1843  for(i=1; i<=N; i++)
1844  {
1845    DName[i] = "D"+Name[i];  //concat
1846  }
1847  list NName = RName + Name + DName;
1848  L[2]   = NName;
1849  // Name, Dname will be used further
1850  kill NName;
1851  // block ord (lp(P),dp);
1852  tmp[1] = "lp";  //string
1853  s      = "iv=";
1854  for (i=1; i<=2*P; i++)
1855  {
1856    s = s+"1,";
1857  }
1858  s[size(s)]= ";";
1859  execute(s);
1860  tmp[2] = iv;  //intvec
1861  Lord[1] = tmp;
1862  // continue with dp 1,1,1,1...
1863  tmp[1] = "dp";  //string
1864  s      = "iv=";
1865  for (i=1; i<=Nnew; i++)  //actually i<=2*N
1866  {
1867    s = s+"1,";
1868  }
1869  s[size(s)]= ";";
1870  execute(s);
1871  kill s;
1872  tmp[2]  = iv;
1873  Lord[2] = tmp;
1874  tmp[1]  = "C";
1875  iv      = 0;
1876  tmp[2]  = iv;
1877  Lord[3] = tmp;
1878  tmp     = 0;
1879  L[3]    = Lord;
1880  // we are done with the list
1881  def @R@ = ring(L);
1882  setring @R@;
1883  matrix @D[Nnew][Nnew];
1884  for (i=1; i<=P; i++)
1885  {
1886    @D[i,i+P] = t(i);
1887  }
1888  for(i=1; i<=N; i++)
1889  {
1890    @D[2*P+i,2*P+N+i] = 1;
1891  }
1892  // L[5] = matrix(UpOneMatrix(Nnew));
1893  // L[6] = @D;
1894  def @R = nc_algebra(1,@D);
1895  setring @R;
1896  kill @R@;
1897  dbprint(ppl,"// -1-1- the ring @R(_t,_s,_x,_Dx) is ready");
1898  dbprint(ppl-1, @R);
1899  // create the ideal I
1900  ideal  F = imap(save,F);
1901  ideal I = t(1)*F[1]+s(1);
1902  for (j=2; j<=P; j++)
1903  {
1904    I = I, t(j)*F[j]+s(j);
1905  }
1906  poly p,q;
1907  for (i=1; i<=N; i++)
1908  {
1909    p=0;
1910    for (j=1; j<=P; j++)
1911    {
1912      q = t(j);
1913      q = diff(F[j],var(2*P+i))*q;
1914      p = p + q;
1915    }
1916    I = I, var(2*P+N+i) + p;
1917  }
1918  // -------- the ideal I is ready ----------
1919  dbprint(ppl,"// -1-2- starting the elimination of "+string(t(1..P))+" in @R");
1920  dbprint(ppl-1, I);
1921  ideal J = engine(I,eng);
1922  ideal K = nselect(J,1,P);
1923  kill I,J;
1924  dbprint(ppl,"// -1-3- all t(i) are eliminated");
1925  dbprint(ppl-1, K);  //K is without t(i)
1926  // ----------- the ring @R2 ------------
1927  // _x, _Dx,s;  elim.ord for _x,_Dx.
1928  // keep: N, i,j,s, tmp, RL
1929  setring save;
1930  Nnew = 2*N+P;
1931  kill Lord, tmp, iv, RName;
1932  list Lord, tmp;
1933  intvec iv;
1934  L[1] = RL[1];  //char
1935  L[4] = RL[4];  //char, minpoly
1936  // check whether vars hava admissible names -> done earlier
1937  // now, create the names for new var
1938  for (j=1; j<=P; j++)
1939  {
1940    tmp[j] = "s("+string(j)+")";
1941  }
1942  // DName is defined earlier
1943  list NName = Name + DName + tmp;
1944  L[2] = NName;
1945  tmp = 0;
1946  // block ord (dp(N),dp);
1947  string s = "iv=";
1948  for (i=1; i<=Nnew-P; i++)
1949  {
1950    s = s+"1,";
1951  }
1952  s[size(s)]=";";
1953  execute(s);
1954  tmp[1] = "dp";  //string
1955  tmp[2] = iv;    //intvec
1956  Lord[1] = tmp;
1957  // continue with dp 1,1,1,1...
1958  tmp[1] = "dp";  //string
1959  s[size(s)] = ",";
1960  for (j=1; j<=P; j++)
1961  {
1962    s = s+"1,";
1963  }
1964  s[size(s)]=";";
1965  execute(s);
1966  kill s;
1967  kill NName;
1968  tmp[2]  = iv;
1969  Lord[2] = tmp;
1970  tmp[1]  = "C";
1971  iv      = 0;
1972  tmp[2]  = iv;
1973  Lord[3] = tmp;
1974  tmp     = 0;
1975  L[3]    = Lord;
1976  // we are done with the list. Now add a Plural part
1977  def @R2@ = ring(L);
1978  setring @R2@;
1979  matrix @D[Nnew][Nnew];
1980  for (i=1; i<=N; i++)
1981  {
1982    @D[i,N+i]=1;
1983  }
1984  def @R2 = nc_algebra(1,@D);
1985  setring @R2;
1986  kill @R2@;
1987  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,_s) is ready");
1988  dbprint(ppl-1, @R2);
1989//  ideal MM = maxideal(1);
1990//  MM = 0,s,MM;
1991//  map R01 = @R, MM;
1992//  ideal K = R01(K);
1993  ideal F = imap(save,F);  // maybe ideal F = R01(I); ?
1994  ideal K = imap(@R,K);    // maybe ideal K = R01(I); ?
1995  poly f=1;
1996  for (j=1; j<=P; j++)
1997  {
1998    f = f*F[j];
1999  }
2000  K = K,f;       // to compute B (Bernstein-Sato ideal)
2001  //j=2;         // for example
2002  //K = K,F[j];  // to compute Bj (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
2003  //K = K,F;     // to compute Bsigma (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
2004  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
2005  dbprint(ppl-1, K);
2006  ideal M = engine(K,eng);
2007  ideal K2 = nselect(M,1,Nnew-P);
2008  kill K,M;
2009  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
2010  dbprint(ppl-1, K2);
2011  // the ring @R3 and factorize
2012  ring @R3 = 0,s(1..P),dp;
2013  dbprint(ppl,"// -3-1- the ring @R3(_s) is ready");
2014  ideal K3 = imap(@R2,K2);
2015  if (size(K3)==1)
2016  {
2017    poly p = K3[1];
2018    dbprint(ppl,"// -3-2- factorization");
2019    // Warning: now P is an integer
2020    list Q = factorize(p);         //with constants and multiplicities
2021    ideal bs; intvec m;
2022    for (i=2; i<=size(Q[1]); i++)  //we delete Q[1][1] and Q[2][1]
2023    {
2024      bs[i-1] = Q[1][i];
2025      m[i-1]  = Q[2][i];
2026    }
2027    //  "--------- Q-ideal factorizes into ---------";  list(bs,m);
2028    list BS = bs,m;
2029  }
2030  else
2031  {
2032    // conjecture: the Bernstein ideal is principal
2033    dbprint(ppl,"// -3-2- the Bernstein ideal is not principal");
2034    ideal BS = K3;
2035  }
2036  // create the ring @R4(_x,_Dx,_s) and put the result into it,
2037  // _x, _Dx,s;  ord "dp".
2038  // keep: N, i,j,s, tmp, RL
2039  setring save;
2040  Nnew = 2*N+P;
2041  // list RL = ringlist(save);  //is defined earlier
2042  kill Lord, tmp, iv;
2043  L = 0;
2044  list Lord, tmp;
2045  intvec iv;
2046  L[1] = RL[1];  //char
2047  L[4] = RL[4];  //char, minpoly
2048  // check whether vars hava admissible names -> done earlier
2049  // now, create the names for new var
2050  for (j=1; j<=P; j++)
2051  {
2052    tmp[j] = "s("+string(j)+")";
2053  }
2054  // DName is defined earlier
2055  list NName = Name + DName + tmp;
2056  L[2] = NName;
2057  tmp = 0;
2058  // dp ordering;
2059  string s = "iv=";
2060  for (i=1; i<=Nnew; i++)
2061  {
2062    s = s+"1,";
2063  }
2064  s[size(s)]=";";
2065  execute(s);
2066  kill s;
2067  kill NName;
2068  tmp[1] = "dp";  //string
2069  tmp[2] = iv;    //intvec
2070  Lord[1] = tmp;
2071  tmp[1]  = "C";
2072  iv      = 0;
2073  tmp[2]  = iv;
2074  Lord[2] = tmp;
2075  tmp     = 0;
2076  L[3]    = Lord;
2077  // we are done with the list. Now add a Plural part
2078  def @R4@ = ring(L);
2079  setring @R4@;
2080  matrix @D[Nnew][Nnew];
2081  for (i=1; i<=N; i++)
2082  {
2083    @D[i,N+i]=1;
2084  }
2085  def @R4 = nc_algebra(1,@D);
2086  setring @R4;
2087  kill @R4@;
2088  dbprint(ppl,"// -4-1- the ring @R4i(_x,_Dx,_s) is ready");
2089  dbprint(ppl-1, @R4);
2090  ideal K4 = imap(@R,K);
2091  option(redSB);
2092  dbprint(ppl,"// -4-2- the final cosmetic std");
2093  K4 = engine(K4,eng);  //std does the job too
2094  // total cleanup
2095  kill @R;
2096  kill @R2;
2097  def BS = imap(@R3,BS);
2098  export BS;
2099  kill @R3;
2100  ideal LD = K4;
2101  export LD;
2102  return(@R4);
2103}
2104example
2105{
2106  "EXAMPLE:"; echo = 2;
2107  ring r = 0,(x,y),Dp;
2108  ideal F = x,y,x+y;
2109  printlevel = 0;
2110  def A = annfsBMI(F);
2111  setring A;
2112  LD;
2113  BS;
2114}
2115
2116proc annfsOT(poly F, list #)
2117"USAGE:  annfsOT(f [,eng]);  f a poly, eng an optional int
2118RETURN:  ring
2119PURPOSE: compute the D-module structure of basering[1/f]*f^s, according
2120to the algorithm by Oaku and Takayama
2121NOTE:    activate this ring with the @code{setring} command. In this ring,
2122@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
2123@*         which is obtained by substituting the minimal integer root of a Bernstein
2124@*         polynomial into the s-parametric ideal;
2125@*       - the list BS contains roots with multiplicities of a Bernstein polynomial of f.
2126@*       If eng <>0, @code{std} is used for Groebner basis computations,
2127@*       otherwise, and by default @code{slimgb} is used.
2128@*       If printlevel=1, progress debug messages will be printed,
2129@*       if printlevel>=2, all the debug messages will be printed.
2130EXAMPLE: example annfsOT; shows examples
2131"
2132{
2133  int eng = 0;
2134  if ( size(#)>0 )
2135  {
2136    if ( typeof(#[1]) == "int" )
2137    {
2138      eng = int(#[1]);
2139    }
2140  }
2141  // returns a list with a ring and an ideal LD in it
2142  int ppl = printlevel-voice+2;
2143  //  printf("plevel :%s, voice: %s",printlevel,voice);
2144  def save = basering;
2145  int N = nvars(basering);
2146  int Nnew = 2*(N+2);
2147  int i,j;
2148  string s;
2149  list RL = ringlist(basering);
2150  list L, Lord;
2151  list tmp;
2152  intvec iv;
2153  L[1] = RL[1]; // char
2154  L[4] = RL[4]; // char, minpoly
2155  // check whether vars have admissible names
2156  list Name  = RL[2];
2157  list RName;
2158  RName[1] = "u";
2159  RName[2] = "v";
2160  RName[3] = "t";
2161  RName[4] = "Dt";
2162  for(i=1;i<=N;i++)
2163  {
2164    for(j=1; j<=size(RName);j++)
2165    {
2166      if (Name[i] == RName[j])
2167      {
2168        ERROR("Variable names should not include u,v,t,Dt");
2169      }
2170    }
2171  }
2172  // now, create the names for new vars
2173  tmp[1]     = "u";
2174  tmp[2]     = "v";
2175  list UName = tmp;
2176  list DName;
2177  for(i=1;i<=N;i++)
2178  {
2179    DName[i] = "D"+Name[i]; // concat
2180  }
2181  tmp    =  0;
2182  tmp[1] = "t";
2183  tmp[2] = "Dt";
2184  list NName = UName +  tmp + Name + DName;
2185  L[2]   = NName;
2186  tmp    = 0;
2187  // Name, Dname will be used further
2188  kill UName;
2189  kill NName;
2190  // block ord (a(1,1),dp);
2191  tmp[1]  = "a"; // string
2192  iv      = 1,1;
2193  tmp[2]  = iv; //intvec
2194  Lord[1] = tmp;
2195  // continue with dp 1,1,1,1...
2196  tmp[1]  = "dp"; // string
2197  s       = "iv=";
2198  for(i=1;i<=Nnew;i++)
2199  {
2200    s = s+"1,";
2201  }
2202  s[size(s)]= ";";
2203  execute(s);
2204  tmp[2]    = iv;
2205  Lord[2]   = tmp;
2206  tmp[1]    = "C";
2207  iv        = 0;
2208  tmp[2]    = iv;
2209  Lord[3]   = tmp;
2210  tmp       = 0;
2211  L[3]      = Lord;
2212  // we are done with the list
2213  def @R@ = ring(L);
2214  setring @R@;
2215  matrix @D[Nnew][Nnew];
2216  @D[3,4]=1;
2217  for(i=1; i<=N; i++)
2218  {
2219    @D[4+i,N+4+i]=1;
2220  }
2221  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
2222  //  L[5] = matrix(UpOneMatrix(Nnew));
2223  //  L[6] = @D;
2224  def @R = nc_algebra(1,@D);
2225  setring @R;
2226  kill @R@;
2227  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
2228  dbprint(ppl-1, @R);
2229  // create the ideal I
2230  poly  F = imap(save,F);
2231  ideal I = u*F-t,u*v-1;
2232  poly p;
2233  for(i=1; i<=N; i++)
2234  {
2235    p = u*Dt; // u*Dt
2236    p = diff(F,var(4+i))*p;
2237    I = I, var(N+4+i) + p;
2238  }
2239  // -------- the ideal I is ready ----------
2240  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
2241  dbprint(ppl-1, I);
2242  ideal J = engine(I,eng);
2243  ideal K = nselect(J,1,2);
2244  dbprint(ppl,"// -1-3- u,v are eliminated");
2245  dbprint(ppl-1, K);  // K is without u,v
2246  setring save;
2247  // ------------ new ring @R2 ------------------
2248  // without u,v and with the elim.ord for t,Dt
2249  // tensored with the K[s]
2250  // keep: N, i,j,s, tmp, RL
2251  Nnew = 2*N+2+1;
2252  //  list RL = ringlist(save); // is defined earlier
2253  L = 0;  //  kill L;
2254  kill Lord, tmp, iv, RName;
2255  list Lord, tmp;
2256  intvec iv;
2257  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
2258  // check whether vars have admissible names -> done earlier
2259  //  list Name  = RL[2];
2260  list RName;
2261  RName[1] = "t";
2262  RName[2] = "Dt";
2263  // now, create the names for new var (here, s only)
2264  tmp[1]     = "s";
2265  // DName is defined earlier
2266  list NName = RName + Name + DName + tmp;
2267  L[2]   = NName;
2268  tmp    = 0;
2269  // block ord (a(1,1),dp);
2270  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
2271  Lord[1] = tmp;
2272  // continue with a(1,1,1,1)...
2273  tmp[1]  = "dp"; s  = "iv=";
2274  for(i=1; i<= Nnew; i++)
2275  {
2276    s = s+"1,";
2277  }
2278  s[size(s)]= ";";  execute(s);
2279  kill NName;
2280  tmp[2]    = iv;
2281  Lord[2]   = tmp;
2282  // extra block for s
2283  // tmp[1] = "dp"; iv = 1;
2284  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
2285  //  Lord[3]   = tmp;
2286  kill s;
2287  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
2288  Lord[3]   = tmp;   tmp = 0;
2289  L[3]      = Lord;
2290  // we are done with the list. Now, add a Plural part
2291  def @R2@ = ring(L);
2292  setring @R2@;
2293  matrix @D[Nnew][Nnew];
2294  @D[1,2] = 1;
2295  for(i=1; i<=N; i++)
2296  {
2297    @D[2+i,2+N+i] = 1;
2298  }
2299  def @R2 = nc_algebra(1,@D);
2300  setring @R2;
2301  kill @R2@;
2302  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
2303  dbprint(ppl-1, @R2);
2304  ideal MM = maxideal(1);
2305  MM = 0,0,MM;
2306  map R01 = @R, MM;
2307  ideal K = R01(K);
2308  //  ideal K = imap(@R,K); // names of vars are important!
2309  poly G = t*Dt+s+1; // s is a variable here
2310  K = NF(K,std(G)),G;
2311  // -------- the ideal K_(@R2) is ready ----------
2312  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
2313  dbprint(ppl-1, K);
2314  ideal M  = engine(K,eng);
2315  ideal K2 = nselect(M,1,2);
2316  dbprint(ppl,"// -2-3- t,Dt are eliminated");
2317  dbprint(ppl-1, K2);
2318  //  dbprint(ppl-1+1," -2-4- std of K2");
2319  //  option(redSB);  option(redTail);  K2 = std(K2);
2320  //  K2; // without t,Dt, and with s
2321  // -------- the ring @R3 ----------
2322  // _x, _Dx, s; elim.ord for _x,_Dx.
2323  // keep: N, i,j,s, tmp, RL
2324  setring save;
2325  Nnew = 2*N+1;
2326  //  list RL = ringlist(save); // is defined earlier
2327  //  kill L;
2328  kill Lord, tmp, iv, RName;
2329  list Lord, tmp;
2330  intvec iv;
2331  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
2332  // check whether vars have admissible names -> done earlier
2333  //  list Name  = RL[2];
2334  // now, create the names for new var (here, s only)
2335  tmp[1]     = "s";
2336  // DName is defined earlier
2337  list NName = Name + DName + tmp;
2338  L[2]   = NName;
2339  tmp    = 0;
2340  // block ord (a(1,1...),dp);
2341  string  s = "iv=";
2342  for(i=1; i<=Nnew-1; i++)
2343  {
2344    s = s+"1,";
2345  }
2346  s[size(s)]= ";";
2347  execute(s);
2348  tmp[1]  = "a"; // string
2349  tmp[2]  = iv; //intvec
2350  Lord[1] = tmp;
2351  // continue with dp 1,1,1,1...
2352  tmp[1]  = "dp"; // string
2353  s[size(s)]=","; s= s+"1;";
2354  execute(s);
2355  kill s;
2356  kill NName;
2357  tmp[2]    = iv;
2358  Lord[2]   = tmp;
2359  tmp[1]    = "C";  iv  = 0;  tmp[2] = iv;
2360  Lord[3]   = tmp;  tmp = 0;
2361  L[3]      = Lord;
2362  // we are done with the list. Now add a Plural part
2363  def @R3@ = ring(L);
2364  setring @R3@;
2365  matrix @D[Nnew][Nnew];
2366  for(i=1; i<=N; i++)
2367  {
2368    @D[i,N+i]=1;
2369  }
2370  def @R3 = nc_algebra(1,@D);
2371  setring @R3;
2372  kill @R3@;
2373  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
2374  dbprint(ppl-1, @R3);
2375  ideal MM = maxideal(1);
2376  MM = 0,0,MM;
2377  map R12 = @R2, MM;
2378  ideal K = R12(K2);
2379  poly  F = imap(save,F);
2380  K = K,F;
2381  dbprint(ppl,"// -3-2- starting the elimination of _x,_Dx in @R3");
2382  dbprint(ppl-1, K);
2383  ideal M = engine(K,eng);
2384  ideal K3 = nselect(M,1,Nnew-1);
2385  dbprint(ppl,"// -3-3-  _x,_Dx are eliminated in @R3");
2386  dbprint(ppl-1, K3);
2387  // the ring @R4  and the search for minimal negative int s
2388  ring @R4 = 0,(s),dp;
2389  dbprint(ppl,"// -4-1- the ring @R4 is ready");
2390  ideal K4 = imap(@R3,K3);
2391  poly p = K4[1];
2392  dbprint(ppl,"// -4-2- factorization");
2393////  ideal P = factorize(p,1);  // without constants and multiplicities
2394  list P = factorize(p);         // with constants and multiplicities
2395  ideal bs; intvec m;            // the Bernstein polynomial is monic, so we are not interested in constants
2396  for (i=2; i<=size(P[1]); i++)  // we delete P[1][1] and P[2][1]
2397  {
2398    bs[i-1] = P[1][i];
2399    m[i-1]  = P[2][i];
2400  }
2401  //  "------ b-function factorizes into ----------";  P;
2402////  int sP  = minIntRoot(P, 1);
2403  int sP = minIntRoot(bs,1);
2404  dbprint(ppl,"// -4-3- minimal integer root found");
2405  dbprint(ppl-1, sP);
2406  // convert factors to a list of their roots
2407  // assume all factors are linear
2408////  ideal BS = normalize(P);
2409////  BS = subst(BS,s,0);
2410////  BS = -BS;
2411  bs = normalize(bs);
2412  bs = subst(bs,s,0);
2413  bs = -bs;
2414  list BS = bs,m;
2415  // TODO: sort BS!
2416  // ------ substitute s found in the ideal ------
2417  // ------- going back to @R2 and substitute --------
2418  setring @R2;
2419  ideal K3 = subst(K2,s,sP);
2420  // create the ordinary Weyl algebra and put the result into it,
2421  // thus creating the ring @R5
2422  // keep: N, i,j,s, tmp, RL
2423  setring save;
2424  Nnew = 2*N;
2425  //  list RL = ringlist(save); // is defined earlier
2426  kill Lord, tmp, iv;
2427  L = 0;
2428  list Lord, tmp;
2429  intvec iv;
2430  L[1] = RL[1];   L[4] = RL[4]; // char, minpoly
2431  // check whether vars have admissible names -> done earlier
2432  //  list Name  = RL[2];
2433  // DName is defined earlier
2434  list NName = Name + DName;
2435  L[2]   = NName;
2436  // dp ordering;
2437  string   s       = "iv=";
2438  for(i=1;i<=Nnew;i++)
2439  {
2440    s = s+"1,";
2441  }
2442  s[size(s)]= ";";
2443  execute(s);
2444  tmp     = 0;
2445  tmp[1]  = "dp"; // string
2446  tmp[2]  = iv; //intvec
2447  Lord[1] = tmp;
2448  kill s;
2449  tmp[1]    = "C";
2450  iv        = 0;
2451  tmp[2]    = iv;
2452  Lord[2]   = tmp;
2453  tmp       = 0;
2454  L[3]      = Lord;
2455  // we are done with the list
2456  // Add: Plural part
2457  def @R5@ = ring(L);
2458  setring @R5@;
2459  matrix @D[Nnew][Nnew];
2460  for(i=1; i<=N; i++)
2461  {
2462    @D[i,N+i]=1;
2463  }
2464  def @R5 = nc_algebra(1,@D);
2465  setring @R5;
2466  kill @R5@;
2467  dbprint(ppl,"// -5-1- the ring @R5 is ready");
2468  dbprint(ppl-1, @R5);
2469  ideal K5 = imap(@R2,K3);
2470  option(redSB);
2471  dbprint(ppl,"// -5-2- the final cosmetic std");
2472  K5 = engine(K5,eng); // std does the job too
2473  // total cleanup
2474  kill @R;
2475  kill @R2;
2476  kill @R3;
2477////  ideal BS = imap(@R4,BS);
2478  list BS = imap(@R4,BS);
2479  export BS;
2480  ideal LD = K5;
2481  kill @R4;
2482  export LD;
2483  return(@R5);
2484}
2485example
2486{
2487  "EXAMPLE:"; echo = 2;
2488  ring r = 0,(x,y,z),Dp;
2489  poly F = x^2+y^3+z^5;
2490  printlevel = 0;
2491  def A  = annfsOT(F);
2492  setring A;
2493  LD;
2494  BS;
2495}
2496
2497
2498proc SannfsOT(poly F, list #)
2499"USAGE:  SannfsOT(f [,eng]);  f a poly, eng an optional int
2500RETURN:  ring
2501PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the 1st step of the algorithm by Oaku and Takayama in the ring D[s], where D is the Weyl algebra
2502NOTE:    activate this ring with the @code{setring} command.
2503@*       In the ring D[s], the ideal LD (which is NOT a Groebner basis) is the needed D-module structure.
2504@*       If eng <>0, @code{std} is used for Groebner basis computations,
2505@*       otherwise, and by default @code{slimgb} is used.
2506@*       If printlevel=1, progress debug messages will be printed,
2507@*       if printlevel>=2, all the debug messages will be printed.
2508EXAMPLE: example SannfsOT; shows examples
2509"
2510{
2511  int eng = 0;
2512  if ( size(#)>0 )
2513  {
2514    if ( typeof(#[1]) == "int" )
2515    {
2516      eng = int(#[1]);
2517    }
2518  }
2519  // returns a list with a ring and an ideal LD in it
2520  int ppl = printlevel-voice+2;
2521  //  printf("plevel :%s, voice: %s",printlevel,voice);
2522  def save = basering;
2523  int N = nvars(basering);
2524  int Nnew = 2*(N+2);
2525  int i,j;
2526  string s;
2527  list RL = ringlist(basering);
2528  list L, Lord;
2529  list tmp;
2530  intvec iv;
2531  L[1] = RL[1]; // char
2532  L[4] = RL[4]; // char, minpoly
2533  // check whether vars have admissible names
2534  list Name  = RL[2];
2535  list RName;
2536  RName[1] = "u";
2537  RName[2] = "v";
2538  RName[3] = "t";
2539  RName[4] = "Dt";
2540  for(i=1;i<=N;i++)
2541  {
2542    for(j=1; j<=size(RName);j++)
2543    {
2544      if (Name[i] == RName[j])
2545      {
2546        ERROR("Variable names should not include u,v,t,Dt");
2547      }
2548    }
2549  }
2550  // now, create the names for new vars
2551  tmp[1]     = "u";
2552  tmp[2]     = "v";
2553  list UName = tmp;
2554  list DName;
2555  for(i=1;i<=N;i++)
2556  {
2557    DName[i] = "D"+Name[i]; // concat
2558  }
2559  tmp    =  0;
2560  tmp[1] = "t";
2561  tmp[2] = "Dt";
2562  list NName = UName +  tmp + Name + DName;
2563  L[2]   = NName;
2564  tmp    = 0;
2565  // Name, Dname will be used further
2566  kill UName;
2567  kill NName;
2568  // block ord (a(1,1),dp);
2569  tmp[1]  = "a"; // string
2570  iv      = 1,1;
2571  tmp[2]  = iv; //intvec
2572  Lord[1] = tmp;
2573  // continue with dp 1,1,1,1...
2574  tmp[1]  = "dp"; // string
2575  s       = "iv=";
2576  for(i=1;i<=Nnew;i++)
2577  {
2578    s = s+"1,";
2579  }
2580  s[size(s)]= ";";
2581  execute(s);
2582  tmp[2]    = iv;
2583  Lord[2]   = tmp;
2584  tmp[1]    = "C";
2585  iv        = 0;
2586  tmp[2]    = iv;
2587  Lord[3]   = tmp;
2588  tmp       = 0;
2589  L[3]      = Lord;
2590  // we are done with the list
2591  def @R@ = ring(L);
2592  setring @R@;
2593  matrix @D[Nnew][Nnew];
2594  @D[3,4]=1;
2595  for(i=1; i<=N; i++)
2596  {
2597    @D[4+i,N+4+i]=1;
2598  }
2599  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
2600  //  L[5] = matrix(UpOneMatrix(Nnew));
2601  //  L[6] = @D;
2602  def @R =  nc_algebra(1,@D);
2603  setring @R;
2604  kill @R@;
2605  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
2606  dbprint(ppl-1, @R);
2607  // create the ideal I
2608  poly  F = imap(save,F);
2609  ideal I = u*F-t,u*v-1;
2610  poly p;
2611  for(i=1; i<=N; i++)
2612  {
2613    p = u*Dt; // u*Dt
2614    p = diff(F,var(4+i))*p;
2615    I = I, var(N+4+i) + p;
2616  }
2617  // -------- the ideal I is ready ----------
2618  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
2619  dbprint(ppl-1, I);
2620  ideal J = engine(I,eng);
2621  ideal K = nselect(J,1,2);
2622  dbprint(ppl,"// -1-3- u,v are eliminated");
2623  dbprint(ppl-1, K);  // K is without u,v
2624
2625
2626  setring save;
2627  // ------------ new ring @R2 ------------------
2628  // without u,v and with the elim.ord for t,Dt
2629  // tensored with the K[s]
2630  // keep: N, i,j,s, tmp, RL
2631  Nnew = 2*N+2+1;
2632  //  list RL = ringlist(save); // is defined earlier
2633  L = 0;  //  kill L;
2634  kill Lord, tmp, iv, RName;
2635  list Lord, tmp;
2636  intvec iv;
2637  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
2638  // check whether vars have admissible names -> done earlier
2639  //  list Name  = RL[2];
2640  list RName;
2641  RName[1] = "t";
2642  RName[2] = "Dt";
2643  // now, create the names for new var (here, s only)
2644  tmp[1]     = "s";
2645  // DName is defined earlier
2646  list NName = RName + Name + DName + tmp;
2647  L[2]   = NName;
2648  tmp    = 0;
2649  // block ord (a(1,1),dp);
2650  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
2651  Lord[1] = tmp;
2652  // continue with a(1,1,1,1)...
2653  tmp[1]  = "dp"; s  = "iv=";
2654  for(i=1; i<= Nnew; i++)
2655  {
2656    s = s+"1,";
2657  }
2658  s[size(s)]= ";";  execute(s);
2659  kill NName;
2660  tmp[2]    = iv;
2661  Lord[2]   = tmp;
2662  // extra block for s
2663  // tmp[1] = "dp"; iv = 1;
2664  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
2665  //  Lord[3]   = tmp;
2666  kill s;
2667  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
2668  Lord[3]   = tmp;   tmp = 0;
2669  L[3]      = Lord;
2670  // we are done with the list. Now, add a Plural part
2671  def @R2@ = ring(L);
2672  setring @R2@;
2673  matrix @D[Nnew][Nnew];
2674  @D[1,2] = 1;
2675  for(i=1; i<=N; i++)
2676  {
2677    @D[2+i,2+N+i] = 1;
2678  }
2679  def @R2 = nc_algebra(1,@D);
2680  setring @R2;
2681  kill @R2@;
2682  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
2683  dbprint(ppl-1, @R2);
2684  ideal MM = maxideal(1);
2685  MM = 0,0,MM;
2686  map R01 = @R, MM;
2687  ideal K = R01(K);
2688  //  ideal K = imap(@R,K); // names of vars are important!
2689  poly G = t*Dt+s+1; // s is a variable here
2690  K = NF(K,std(G)),G;
2691  // -------- the ideal K_(@R2) is ready ----------
2692  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
2693  dbprint(ppl-1, K);
2694  ideal M  = engine(K,eng);
2695  ideal K2 = nselect(M,1,2);
2696  dbprint(ppl,"// -2-3- t,Dt are eliminated");
2697  dbprint(ppl-1, K2);
2698  K2 = engine(K2,eng);
2699  setring save;
2700  // ----------- the ring @R3 ------------
2701  // _x, _Dx,s;  elim.ord for _x,_Dx.
2702  // keep: N, i,j,s, tmp, RL
2703  Nnew = 2*N+1;
2704  kill Lord, tmp, iv, RName;
2705  list Lord, tmp;
2706  intvec iv;
2707  L[1] = RL[1];
2708  L[4] = RL[4];  // char, minpoly
2709  // check whether vars hava admissible names -> done earlier
2710  // now, create the names for new var
2711  tmp[1] = "s";
2712  // DName is defined earlier
2713  list NName = Name + DName + tmp;
2714  L[2] = NName;
2715  tmp = 0;
2716  // block ord (dp(N),dp);
2717  string s = "iv=";
2718  for (i=1; i<=Nnew-1; i++)
2719  {
2720    s = s+"1,";
2721  }
2722  s[size(s)]=";";
2723  execute(s);
2724  tmp[1] = "dp";  // string
2725  tmp[2] = iv;   // intvec
2726  Lord[1] = tmp;
2727  // continue with dp 1,1,1,1...
2728  tmp[1] = "dp";  // string
2729  s[size(s)] = ",";
2730  s = s+"1;";
2731  execute(s);
2732  kill s;
2733  kill NName;
2734  tmp[2]      = iv;
2735  Lord[2]     = tmp;
2736  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
2737  Lord[3]     = tmp;  tmp = 0;
2738  L[3]        = Lord;
2739  // we are done with the list. Now add a Plural part
2740  def @R3@ = ring(L);
2741  setring @R3@;
2742  matrix @D[Nnew][Nnew];
2743  for (i=1; i<=N; i++)
2744  {
2745    @D[i,N+i]=1;
2746  }
2747  def @R3 = nc_algebra(1,@D);
2748  setring @R3;
2749  kill @R3@;
2750  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
2751  dbprint(ppl-1, @R3);
2752  ideal MM = maxideal(1);
2753  MM = 0,s,MM;
2754  map R01 = @R2, MM;
2755  ideal K2 = R01(K2);
2756  // total cleanup
2757  ideal LD = K2;
2758  // make leadcoeffs positive
2759  for (i=1; i<= ncols(LD); i++)
2760  {
2761    if (leadcoef(LD[i]) <0 )
2762    {
2763      LD[i] = -LD[i];
2764    }
2765  }
2766  export LD;
2767  kill @R;
2768  kill @R2;
2769  return(@R3);
2770}
2771example
2772{
2773  "EXAMPLE:"; echo = 2;
2774  ring r = 0,(x,y,z),Dp;
2775  poly F = x^3+y^3+z^3;
2776  printlevel = 0;
2777  def A  = SannfsOT(F);
2778  setring A;
2779  LD;
2780}
2781
2782proc SannfsBM(poly F, list #)
2783"USAGE:  SannfsBM(f [,eng]);  f a poly, eng an optional int
2784RETURN:  ring
2785PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the 1st step of the algorithm by Briancon and Maisonobe in the ring D[s], where D is the Weyl algebra
2786NOTE:    activate this ring with the @code{setring} command.
2787@*       In the ring D[s], the ideal LD (which is NOT a Groebner basis) is the needed D-module structure,
2788@*       If eng <>0, @code{std} is used for Groebner basis computations,
2789@*       otherwise, and by default @code{slimgb} is used.
2790@*       If printlevel=1, progress debug messages will be printed,
2791@*       if printlevel>=2, all the debug messages will be printed.
2792EXAMPLE: example SannfsBM; shows examples
2793"
2794{
2795  int eng = 0;
2796  if ( size(#)>0 )
2797  {
2798    if ( typeof(#[1]) == "int" )
2799    {
2800      eng = int(#[1]);
2801    }
2802  }
2803  // returns a list with a ring and an ideal LD in it
2804  int ppl = printlevel-voice+2;
2805  //  printf("plevel :%s, voice: %s",printlevel,voice);
2806  def save = basering;
2807  int N = nvars(basering);
2808  int Nnew = 2*N+2;
2809  int i,j;
2810  string s;
2811  list RL = ringlist(basering);
2812  list L, Lord;
2813  list tmp;
2814  intvec iv;
2815  L[1] = RL[1]; // char
2816  L[4] = RL[4]; // char, minpoly
2817  // check whether vars have admissible names
2818  list Name  = RL[2];
2819  list RName;
2820  RName[1] = "t";
2821  RName[2] = "s";
2822  for(i=1;i<=N;i++)
2823  {
2824    for(j=1; j<=size(RName);j++)
2825    {
2826      if (Name[i] == RName[j])
2827      {
2828        ERROR("Variable names should not include t,s");
2829      }
2830    }
2831  }
2832  // now, create the names for new vars
2833  list DName;
2834  for(i=1;i<=N;i++)
2835  {
2836    DName[i] = "D"+Name[i]; // concat
2837  }
2838  tmp[1] = "t";
2839  tmp[2] = "s";
2840  list NName = tmp + Name + DName;
2841  L[2]   = NName;
2842  // Name, Dname will be used further
2843  kill NName;
2844  // block ord (lp(2),dp);
2845  tmp[1]  = "lp"; // string
2846  iv      = 1,1;
2847  tmp[2]  = iv; //intvec
2848  Lord[1] = tmp;
2849  // continue with dp 1,1,1,1...
2850  tmp[1]  = "dp"; // string
2851  s       = "iv=";
2852  for(i=1;i<=Nnew;i++)
2853  {
2854    s = s+"1,";
2855  }
2856  s[size(s)]= ";";
2857  execute(s);
2858  kill s;
2859  tmp[2]    = iv;
2860  Lord[2]   = tmp;
2861  tmp[1]    = "C";
2862  iv        = 0;
2863  tmp[2]    = iv;
2864  Lord[3]   = tmp;
2865  tmp       = 0;
2866  L[3]      = Lord;
2867  // we are done with the list
2868  def @R@ = ring(L);
2869  setring @R@;
2870  matrix @D[Nnew][Nnew];
2871  @D[1,2]=t;
2872  for(i=1; i<=N; i++)
2873  {
2874    @D[2+i,N+2+i]=1;
2875  }
2876  //  L[5] = matrix(UpOneMatrix(Nnew));
2877  //  L[6] = @D;
2878  def @R = nc_algebra(1,@D);
2879  setring @R;
2880  kill @R@;
2881  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
2882  dbprint(ppl-1, @R);
2883  // create the ideal I
2884  poly  F = imap(save,F);
2885  ideal I = t*F+s;
2886  poly p;
2887  for(i=1; i<=N; i++)
2888  {
2889    p = t; // t
2890    p = diff(F,var(2+i))*p;
2891    I = I, var(N+2+i) + p;
2892  }
2893  // -------- the ideal I is ready ----------
2894  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
2895  dbprint(ppl-1, I);
2896  ideal J = engine(I,eng);
2897  ideal K = nselect(J,1);
2898  dbprint(ppl,"// -1-3- t is eliminated");
2899  dbprint(ppl-1, K);  // K is without t
2900  K = engine(K,eng);  // std does the job too
2901  // now, we must change the ordering
2902  // and create a ring without t, Dt
2903  //  setring S;
2904  // ----------- the ring @R3 ------------
2905  // _x, _Dx,s;  elim.ord for _x,_Dx.
2906  // keep: N, i,j,s, tmp, RL
2907  Nnew = 2*N+1;
2908  kill Lord, tmp, iv, RName;
2909  list Lord, tmp;
2910  intvec iv;
2911  list L=imap(save,L);
2912  list RL=imap(save,RL);
2913  L[1] = RL[1];
2914  L[4] = RL[4];  // char, minpoly
2915  // check whether vars hava admissible names -> done earlier
2916  // now, create the names for new var
2917  tmp[1] = "s";
2918  // DName is defined earlier
2919  list NName = Name + DName + tmp;
2920  L[2] = NName;
2921  tmp = 0;
2922  // block ord (dp(N),dp);
2923  string s = "iv=";
2924  for (i=1; i<=Nnew-1; i++)
2925  {
2926    s = s+"1,";
2927  }
2928  s[size(s)]=";";
2929  execute(s);
2930  tmp[1] = "dp";  // string
2931  tmp[2] = iv;   // intvec
2932  Lord[1] = tmp;
2933  // continue with dp 1,1,1,1...
2934  tmp[1] = "dp";  // string
2935  s[size(s)] = ",";
2936  s = s+"1;";
2937  execute(s);
2938  kill s;
2939  kill NName;
2940  tmp[2]      = iv;
2941  Lord[2]     = tmp;
2942  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
2943  Lord[3]     = tmp;  tmp = 0;
2944  L[3]        = Lord;
2945  // we are done with the list. Now add a Plural part
2946  def @R2@ = ring(L);
2947  setring @R2@;
2948  matrix @D[Nnew][Nnew];
2949  for (i=1; i<=N; i++)
2950  {
2951    @D[i,N+i]=1;
2952  }
2953  def @R2 = nc_algebra(1,@D);
2954  setring @R2;
2955  kill @R2@;
2956  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
2957  dbprint(ppl-1, @R2);
2958  ideal MM = maxideal(1);
2959  MM = 0,s,MM;
2960  map R01 = @R, MM;
2961  ideal K = R01(K);
2962  // total cleanup
2963  ideal LD = K;
2964  // make leadcoeffs positive
2965  for (i=1; i<= ncols(LD); i++)
2966  {
2967    if (leadcoef(LD[i]) <0 )
2968    {
2969      LD[i] = -LD[i];
2970    }
2971  }
2972  export LD;
2973  kill @R;
2974  return(@R2);
2975}
2976example
2977{
2978  "EXAMPLE:"; echo = 2;
2979  ring r = 0,(x,y,z),Dp;
2980  poly F = x^3+y^3+z^3;
2981  printlevel = 0;
2982  def A = SannfsBM(F);
2983  setring A;
2984  LD;
2985}
2986
2987proc SannfsLOT(poly F, list #)
2988"USAGE:  SannfsLOT(f [,eng]);  f a poly, eng an optional int
2989RETURN:  ring
2990PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the Levandovskyy's modification of the algorithm by Oaku and Takayama in the ring D[s], where D is the Weyl algebra
2991NOTE:    activate this ring with the @code{setring} command.
2992@*       In the ring D[s], the ideal LD (which is NOT a Groebner basis) is the needed D-module structure.
2993@*       If eng <>0, @code{std} is used for Groebner basis computations,
2994@*       otherwise, and by default @code{slimgb} is used.
2995@*       If printlevel=1, progress debug messages will be printed,
2996@*       if printlevel>=2, all the debug messages will be printed.
2997EXAMPLE: example SannfsLOT; shows examples
2998"
2999{
3000  int eng = 0;
3001  if ( size(#)>0 )
3002  {
3003    if ( typeof(#[1]) == "int" )
3004    {
3005      eng = int(#[1]);
3006    }
3007  }
3008  // returns a list with a ring and an ideal LD in it
3009  int ppl = printlevel-voice+2;
3010  //  printf("plevel :%s, voice: %s",printlevel,voice);
3011  def save = basering;
3012  int N = nvars(basering);
3013  //  int Nnew = 2*(N+2);
3014  int Nnew = 2*(N+1)+1; //removed u,v; added s
3015  int i,j;
3016  string s;
3017  list RL = ringlist(basering);
3018  list L, Lord;
3019  list tmp;
3020  intvec iv;
3021  L[1] = RL[1]; // char
3022  L[4] = RL[4]; // char, minpoly
3023  // check whether vars have admissible names
3024  list Name  = RL[2];
3025  list RName;
3026//   RName[1] = "u";
3027//   RName[2] = "v";
3028  RName[1] = "t";
3029  RName[2] = "Dt";
3030  for(i=1;i<=N;i++)
3031  {
3032    for(j=1; j<=size(RName);j++)
3033    {
3034      if (Name[i] == RName[j])
3035      {
3036        ERROR("Variable names should not include t,Dt");
3037      }
3038    }
3039  }
3040  // now, create the names for new vars
3041//   tmp[1]     = "u";
3042//   tmp[2]     = "v";
3043//   list UName = tmp;
3044  list DName;
3045  for(i=1;i<=N;i++)
3046  {
3047    DName[i] = "D"+Name[i]; // concat
3048  }
3049  tmp    =  0;
3050  tmp[1] = "t";
3051  tmp[2] = "Dt";
3052  list SName ; SName[1] = "s";
3053  //  list NName = UName +  tmp + Name + DName;
3054  list NName = tmp + Name + DName + SName;
3055  L[2]   = NName;
3056  tmp    = 0;
3057  // Name, Dname will be used further
3058  //  kill UName;
3059  kill NName;
3060  // block ord (a(1,1),dp);
3061  tmp[1]  = "a"; // string
3062  iv      = 1,1;
3063  tmp[2]  = iv; //intvec
3064  Lord[1] = tmp;
3065  // continue with dp 1,1,1,1...
3066  tmp[1]  = "dp"; // string
3067  s       = "iv=";
3068  for(i=1;i<=Nnew;i++)
3069  {
3070    s = s+"1,";
3071  }
3072  s[size(s)]= ";";
3073  execute(s);
3074  tmp[2]    = iv;
3075  Lord[2]   = tmp;
3076  tmp[1]    = "C";
3077  iv        = 0;
3078  tmp[2]    = iv;
3079  Lord[3]   = tmp;
3080  tmp       = 0;
3081  L[3]      = Lord;
3082  // we are done with the list
3083  def @R@ = ring(L);
3084  setring @R@;
3085  matrix @D[Nnew][Nnew];
3086  @D[1,2]=1;
3087  for(i=1; i<=N; i++)
3088  {
3089    @D[2+i,N+2+i]=1;
3090  }
3091  // ADD [s,t]=-t, [s,Dt]=Dt
3092  @D[1,Nnew] = -var(1);
3093  @D[2,Nnew] = var(2);
3094  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
3095  //  L[5] = matrix(UpOneMatrix(Nnew));
3096  //  L[6] = @D;
3097  def @R = nc_algebra(1,@D);
3098  setring @R;
3099  kill @R@;
3100  dbprint(ppl,"// -1-1- the ring @R(t,Dt,_x,_Dx,s) is ready");
3101  dbprint(ppl-1, @R);
3102  // create the ideal I
3103  poly  F = imap(save,F);
3104  //  ideal I = u*F-t,u*v-1;
3105  ideal I = F-t;
3106  poly p;
3107  for(i=1; i<=N; i++)
3108  {
3109    //    p = u*Dt; // u*Dt
3110    p = Dt;
3111    p = diff(F,var(2+i))*p;
3112    I = I, var(N+2+i) + p;
3113  }
3114  //  I = I, var(1)*var(2) + var(Nnew) +1; // reduce it with t-f!!!
3115  // t*Dt + s +1 reduced with t-f gives f*Dt + s
3116  I = I, F*var(2) + var(Nnew);
3117  // -------- the ideal I is ready ----------
3118  dbprint(ppl,"// -1-2- starting the elimination of t,Dt in @R");
3119  dbprint(ppl-1, I);
3120  ideal J = engine(I,eng);
3121  ideal K = nselect(J,1,2);
3122  dbprint(ppl,"// -1-3- t,Dt are eliminated");
3123  dbprint(ppl-1, K);  // K is without t, Dt
3124  K = engine(K,eng);  // std does the job too
3125  // now, we must change the ordering
3126  // and create a ring without t, Dt
3127  setring save;
3128  // ----------- the ring @R3 ------------
3129  // _x, _Dx,s;  elim.ord for _x,_Dx.
3130  // keep: N, i,j,s, tmp, RL
3131  Nnew = 2*N+1;
3132  kill Lord, tmp, iv, RName;
3133  list Lord, tmp;
3134  intvec iv;
3135  L[1] = RL[1];
3136  L[4] = RL[4];  // char, minpoly
3137  // check whether vars hava admissible names -> done earlier
3138  // now, create the names for new var
3139  tmp[1] = "s";
3140  // DName is defined earlier
3141  list NName = Name + DName + tmp;
3142  L[2] = NName;
3143  tmp = 0;
3144  // block ord (dp(N),dp);
3145  // string s is already defined
3146  s = "iv=";
3147  for (i=1; i<=Nnew-1; i++)
3148  {
3149    s = s+"1,";
3150  }
3151  s[size(s)]=";";
3152  execute(s);
3153  tmp[1] = "dp";  // string
3154  tmp[2] = iv;   // intvec
3155  Lord[1] = tmp;
3156  // continue with dp 1,1,1,1...
3157  tmp[1] = "dp";  // string
3158  s[size(s)] = ",";
3159  s = s+"1;";
3160  execute(s);
3161  kill s;
3162  kill NName;
3163  tmp[2]      = iv;
3164  Lord[2]     = tmp;
3165  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
3166  Lord[3]     = tmp;  tmp = 0;
3167  L[3]        = Lord;
3168  // we are done with the list. Now add a Plural part
3169  def @R2@ = ring(L);
3170  setring @R2@;
3171  matrix @D[Nnew][Nnew];
3172  for (i=1; i<=N; i++)
3173  {
3174    @D[i,N+i]=1;
3175  }
3176  def @R2 = nc_algebra(1,@D);
3177  setring @R2;
3178  kill @R2@;
3179  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
3180  dbprint(ppl-1, @R2);
3181  ideal MM = maxideal(1);
3182  MM = 0,s,MM;
3183  map R01 = @R, MM;
3184  ideal K = R01(K);
3185  // total cleanup
3186  ideal LD = K;
3187  // make leadcoeffs positive
3188  for (i=1; i<= ncols(LD); i++)
3189  {
3190    if (leadcoef(LD[i]) <0 )
3191    {
3192      LD[i] = -LD[i];
3193    }
3194  }
3195  export LD;
3196  kill @R;
3197  return(@R2);
3198}
3199example
3200{
3201  "EXAMPLE:"; echo = 2;
3202  ring r = 0,(x,y,z),Dp;
3203  poly F = x^3+y^3+z^3;
3204  printlevel = 0;
3205  def A  = SannfsLOT(F);
3206  setring A;
3207  LD;
3208}
3209
3210
3211proc annfsLOT(poly F, list #)
3212"USAGE:  annfsLOT(F [,eng]);  F a poly, eng an optional int
3213RETURN:  ring
3214PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the Levandovskyy's modification of the algorithm by Oaku and Takayama
3215NOTE:    activate this ring with the @code{setring} command. In this ring,
3216@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
3217@*         which is obtained by substituting the minimal integer root of a Bernstein
3218@*         polynomial into the s-parametric ideal;
3219@*       - the list BS contains the roots with multiplicities of a Bernstein polynomial of f.
3220@*       If eng <>0, @code{std} is used for Groebner basis computations,
3221@*       otherwise and by default @code{slimgb} is used.
3222@*       If printlevel=1, progress debug messages will be printed,
3223@*       if printlevel>=2, all the debug messages will be printed.
3224EXAMPLE: example annfsLOT; shows examples
3225"
3226{
3227  int eng = 0;
3228  if ( size(#)>0 )
3229  {
3230    if ( typeof(#[1]) == "int" )
3231    {
3232      eng = int(#[1]);
3233    }
3234  }
3235  printlevel=printlevel+1;
3236  def save = basering;
3237  def @A = SannfsLOT(F,eng);
3238  setring @A;
3239  poly F = imap(save,F);
3240  def B  = annfs0(LD,F,eng);
3241  return(B);
3242}
3243example
3244{
3245  "EXAMPLE:"; echo = 2;
3246  ring r = 0,(x,y,z),Dp;
3247  poly F = z*x^2+y^3;
3248  printlevel = 0;
3249  def A  = annfsLOT(F);
3250  setring A;
3251  LD;
3252  BS;
3253}
3254
3255proc annfs0(ideal I, poly F, list #)
3256"USAGE:  annfs0(I, F [,eng]);  I an ideal, F a poly, eng an optional int
3257RETURN:  ring
3258PURPOSE: compute the annihilator ideal of f^s in the Weyl Algebra, based on the
3259output of procedures SannfsBM, SannfsOT or SannfsLOT
3260NOTE:    activate this ring with the @code{setring} command. In this ring,
3261@*       - the ideal LD (which is a Groebner basis) is the annihilator of f^s,
3262@*       - the list BS contains the roots with multiplicities of a Bernstein polynomial of f.
3263@*       If eng <>0, @code{std} is used for Groebner basis computations,
3264@*       otherwise and by default @code{slimgb} is used.
3265@*       If printlevel=1, progress debug messages will be printed,
3266@*       if printlevel>=2, all the debug messages will be printed.
3267EXAMPLE: example annfs0; shows examples
3268"
3269{
3270  int eng = 0;
3271  if ( size(#)>0 )
3272  {
3273    if ( typeof(#[1]) == "int" )
3274    {
3275      eng = int(#[1]);
3276    }
3277  }
3278  def @R2 = basering;
3279  // we're in D_n[s], where the elim ord for s is set
3280  ideal J = NF(I,std(F));
3281  // make leadcoeffs positive
3282  int i;
3283  for (i=1; i<= ncols(J); i++)
3284  {
3285    if (leadcoef(J[i]) <0 )
3286    {
3287      J[i] = -J[i];
3288    }
3289  }
3290  J = J,F;
3291  ideal M = engine(J,eng);
3292  int Nnew = nvars(@R2);
3293  ideal K2 = nselect(M,1,Nnew-1);
3294  int ppl = printlevel-voice+2;
3295  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
3296  dbprint(ppl-1, K2);
3297  // the ring @R3 and the search for minimal negative int s
3298  ring @R3 = 0,s,dp;
3299  dbprint(ppl,"// -2-1- the ring @R3 i.e. K[s] is ready");
3300  ideal K3 = imap(@R2,K2);
3301  poly p = K3[1];
3302  dbprint(ppl,"// -2-2- factorization");
3303  //  ideal P = factorize(p,1);  //without constants and multiplicities
3304  //  "--------- b-function factorizes into ---------";   P;
3305  // convert factors to the list of their roots with mults
3306  // assume all factors are linear
3307  //  ideal BS = normalize(P);
3308  //  BS = subst(BS,s,0);
3309  //  BS = -BS;
3310  list P = factorize(p);          //with constants and multiplicities
3311  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
3312  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
3313  {
3314    bs[i-1] = P[1][i];
3315    m[i-1]  = P[2][i];
3316  }
3317  int sP = minIntRoot(bs,1);
3318  bs =  normalize(bs);
3319  bs = -subst(bs,s,0);
3320  dbprint(ppl,"// -2-3- minimal integer root found");
3321  dbprint(ppl-1, sP);
3322 //TODO: sort BS!
3323  // --------- substitute s found in the ideal ---------
3324  // --------- going back to @R and substitute ---------
3325  setring @R2;
3326  K2 = subst(I,s,sP);
3327  // create the ordinary Weyl algebra and put the result into it,
3328  // thus creating the ring @R5
3329  // keep: N, i,j,s, tmp, RL
3330  Nnew = Nnew - 1; // former 2*N;
3331  // list RL = ringlist(save);  // is defined earlier
3332  //  kill Lord, tmp, iv;
3333  list L = 0;
3334  list Lord, tmp;
3335  intvec iv;
3336  list RL = ringlist(basering);
3337  L[1] = RL[1];
3338  L[4] = RL[4];  //char, minpoly
3339  // check whether vars have admissible names -> done earlier
3340  // list Name = RL[2]M
3341  // DName is defined earlier
3342  list NName; // = RL[2]; // skip the last var 's'
3343  for (i=1; i<=Nnew; i++)
3344  {
3345    NName[i] =  RL[2][i];
3346  }
3347  L[2] = NName;
3348  // dp ordering;
3349  string s = "iv=";
3350  for (i=1; i<=Nnew; i++)
3351  {
3352    s = s+"1,";
3353  }
3354  s[size(s)] = ";";
3355  execute(s);
3356  tmp     = 0;
3357  tmp[1]  = "dp";  // string
3358  tmp[2]  = iv;  // intvec
3359  Lord[1] = tmp;
3360  kill s;
3361  tmp[1]  = "C";
3362  iv = 0;
3363  tmp[2]  = iv;
3364  Lord[2] = tmp;
3365  tmp     = 0;
3366  L[3]    = Lord;
3367  // we are done with the list
3368  // Add: Plural part
3369  def @R4@ = ring(L);
3370  setring @R4@;
3371  int N = Nnew/2;
3372  matrix @D[Nnew][Nnew];
3373  for (i=1; i<=N; i++)
3374  {
3375    @D[i,N+i]=1;
3376  }
3377  def @R4 = nc_algebra(1,@D);
3378  setring @R4;
3379  kill @R4@;
3380  dbprint(ppl,"// -3-1- the ring @R4 is ready");
3381  dbprint(ppl-1, @R4);
3382  ideal K4 = imap(@R2,K2);
3383  option(redSB);
3384  dbprint(ppl,"// -3-2- the final cosmetic std");
3385  K4 = engine(K4,eng);  // std does the job too
3386  // total cleanup
3387  ideal bs = imap(@R3,bs);
3388  kill @R3;
3389  list BS = bs,m;
3390  export BS;
3391  ideal LD = K4;
3392  export LD;
3393  return(@R4);
3394}
3395example
3396{ "EXAMPLE:"; echo = 2;
3397  ring r = 0,(x,y,z),Dp;
3398  poly F = x^3+y^3+z^3;
3399  printlevel = 0;
3400  def A = SannfsBM(F);
3401  // alternatively, one can use SannfsOT or SannfsLOT
3402  setring A;
3403  LD;
3404  poly F = imap(r,F);
3405  def B  = annfs0(LD,F);
3406  setring B;
3407  LD;
3408  BS;
3409}
3410
3411// proc annfsgms(poly F, list #)
3412// "USAGE:  annfsgms(f [,eng]);  f a poly, eng an optional int
3413// ASSUME:  f has an isolated critical point at 0
3414// RETURN:  ring
3415// PURPOSE: compute the D-module structure of basering[1/f]*f^s
3416// NOTE:    activate this ring with the @code{setring} command. In this ring,
3417// @*       - the ideal LD is the needed D-mod structure,
3418// @*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
3419// @*       If eng <>0, @code{std} is used for Groebner basis computations,
3420// @*       otherwise (and by default) @code{slimgb} is used.
3421// @*       If printlevel=1, progress debug messages will be printed,
3422// @*       if printlevel>=2, all the debug messages will be printed.
3423// EXAMPLE: example annfsgms; shows examples
3424// "
3425// {
3426//   LIB "gmssing.lib";
3427//   int eng = 0;
3428//   if ( size(#)>0 )
3429//   {
3430//     if ( typeof(#[1]) == "int" )
3431//     {
3432//       eng = int(#[1]);
3433//     }
3434//   }
3435//   int ppl = printlevel-voice+2;
3436//   // returns a ring with the ideal LD in it
3437//   def save = basering;
3438//   // compute the Bernstein poly from gmssing.lib
3439//   list RL = ringlist(basering);
3440//   // in the descr. of the ordering, replace "p" by "s"
3441//   list NL = convloc(RL);
3442//   // create a ring with the ordering, converted to local
3443//   def @LR = ring(NL);
3444//   setring @LR;
3445//   poly F  = imap(save, F);
3446//   ideal B = bernstein(F)[1];
3447//   // since B may not contain (s+1) [following gmssing.lib]
3448//   // add it!
3449//   B = B,-1;
3450//   B = simplify(B,2+4); // erase zero and repeated entries
3451//   // find the minimal integer value
3452//   int   S = minIntRoot(B,0);
3453//   dbprint(ppl,"// -0- minimal integer root found");
3454//   dbprint(ppl-1,S);
3455//   setring save;
3456//   int N = nvars(basering);
3457//   int Nnew = 2*(N+2);
3458//   int i,j;
3459//   string s;
3460//   //  list RL = ringlist(basering);
3461//   list L, Lord;
3462//   list tmp;
3463//   intvec iv;
3464//   L[1] = RL[1]; // char
3465//   L[4] = RL[4]; // char, minpoly
3466//   // check whether vars have admissible names
3467//   list Name  = RL[2];
3468//   list RName;
3469//   RName[1] = "u";
3470//   RName[2] = "v";
3471//   RName[3] = "t";
3472//   RName[4] = "Dt";
3473//   for(i=1;i<=N;i++)
3474//   {
3475//     for(j=1; j<=size(RName);j++)
3476//     {
3477//       if (Name[i] == RName[j])
3478//       {
3479//         ERROR("Variable names should not include u,v,t,Dt");
3480//       }
3481//     }
3482//   }
3483//   // now, create the names for new vars
3484//   //  tmp[1]     = "u";  tmp[2]     = "v";  tmp[3]     = "t";  tmp[4]     = "Dt";
3485//   list UName = RName;
3486//   list DName;
3487//   for(i=1;i<=N;i++)
3488//   {
3489//     DName[i] = "D"+Name[i]; // concat
3490//   }
3491//   list NName = UName + Name + DName;
3492//   L[2]       = NName;
3493//   tmp        = 0;
3494//   // Name, Dname will be used further
3495//   kill UName;
3496//   kill NName;
3497//   // block ord (a(1,1),dp);
3498//   tmp[1]  = "a"; // string
3499//   iv      = 1,1;
3500//   tmp[2]  = iv; //intvec
3501//   Lord[1] = tmp;
3502//   // continue with dp 1,1,1,1...
3503//   tmp[1]  = "dp"; // string
3504//   s       = "iv=";
3505//   for(i=1; i<=Nnew; i++) // need really all vars!
3506//   {
3507//     s = s+"1,";
3508//   }
3509//   s[size(s)]= ";";
3510//   execute(s);
3511//   tmp[2]    = iv;
3512//   Lord[2]   = tmp;
3513//   tmp[1]    = "C";
3514//   iv        = 0;
3515//   tmp[2]    = iv;
3516//   Lord[3]   = tmp;
3517//   tmp       = 0;
3518//   L[3]      = Lord;
3519//   // we are done with the list
3520//   def @R = ring(L);
3521//   setring @R;
3522//   matrix @D[Nnew][Nnew];
3523//   @D[3,4] = 1; // t,Dt
3524//   for(i=1; i<=N; i++)
3525//   {
3526//     @D[4+i,4+N+i]=1;
3527//   }
3528//   //  L[5] = matrix(UpOneMatrix(Nnew));
3529//   //  L[6] = @D;
3530//   nc_algebra(1,@D);
3531//   dbprint(ppl,"// -1-1- the ring @R is ready");
3532//   dbprint(ppl-1,@R);
3533//   // create the ideal
3534//   poly F  = imap(save,F);
3535//   ideal I = u*F-t,u*v-1;
3536//   poly p;
3537//   for(i=1; i<=N; i++)
3538//   {
3539//     p = u*Dt; // u*Dt
3540//     p = diff(F,var(4+i))*p;
3541//     I = I, var(N+4+i) + p; // Dx, Dy
3542//   }
3543//   // add the relations between t,Dt and s
3544//   //  I = I, t*Dt+1+S;
3545//   // -------- the ideal I is ready ----------
3546//   dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
3547//   ideal J = engine(I,eng);
3548//   ideal K = nselect(J,1,2);
3549//   dbprint(ppl,"// -1-3- u,v are eliminated in @R");
3550//   dbprint(ppl-1,K); // without u,v: not yet our answer
3551//   //----- create a ring with elim.ord for t,Dt -------
3552//   setring save;
3553//   // ------------ new ring @R2 ------------------
3554//   // without u,v and with the elim.ord for t,Dt
3555//   // keep: N, i,j,s, tmp, RL
3556//   Nnew = 2*N+2;
3557//   //  list RL = ringlist(save); // is defined earlier
3558//   kill Lord,tmp,iv, RName;
3559//   L = 0;
3560//   list Lord, tmp;
3561//   intvec iv;
3562//   L[1] = RL[1]; // char
3563//   L[4] = RL[4]; // char, minpoly
3564//   // check whether vars have admissible names -> done earlier
3565//   //  list Name  = RL[2];
3566//   list RName;
3567//   RName[1] = "t";
3568//   RName[2] = "Dt";
3569//   // DName is defined earlier
3570//   list NName = RName + Name + DName;
3571//   L[2]   = NName;
3572//   tmp    = 0;
3573//   // block ord (a(1,1),dp);
3574//   tmp[1]  = "a"; // string
3575//   iv      = 1,1;
3576//   tmp[2]  = iv; //intvec
3577//   Lord[1] = tmp;
3578//   // continue with dp 1,1,1,1...
3579//   tmp[1]  = "dp"; // string
3580//   s       = "iv=";
3581//   for(i=1;i<=Nnew;i++)
3582//   {
3583//     s = s+"1,";
3584//   }
3585//   s[size(s)]= ";";
3586//   execute(s);
3587//   kill s;
3588//   kill NName;
3589//   tmp[2]    = iv;
3590//   Lord[2]   = tmp;
3591//   tmp[1]    = "C";
3592//   iv        = 0;
3593//   tmp[2]    = iv;
3594//   Lord[3]   = tmp;
3595//   tmp       = 0;
3596//   L[3]      = Lord;
3597//   // we are done with the list
3598//   // Add: Plural part
3599//   def @R2 = ring(L);
3600//   setring @R2;
3601//   matrix @D[Nnew][Nnew];
3602//   @D[1,2]=1;
3603//   for(i=1; i<=N; i++)
3604//   {
3605//     @D[2+i,2+N+i]=1;
3606//   }
3607//   nc_algebra(1,@D);
3608//   dbprint(ppl,"// -2-1- the ring @R2 is ready");
3609//   dbprint(ppl-1,@R2);
3610//   ideal MM = maxideal(1);
3611//   MM = 0,0,MM;
3612//   map R01 = @R, MM;
3613//   ideal K2 = R01(K);
3614//   // add the relations between t,Dt and s
3615//   //  K2       = K2, t*Dt+1+S;
3616//   poly G = t*Dt+S+1;
3617//   K2 = NF(K2,std(G)),G;
3618//   dbprint(ppl,"// -2-2- starting elimination for t,Dt in @R2");
3619//   ideal J  = engine(K2,eng);
3620//   ideal K  = nselect(J,1,2);
3621//   dbprint(ppl,"// -2-3- t,Dt are eliminated");
3622//   dbprint(ppl-1,K);
3623//   //  "------- produce a final result --------";
3624//   // ----- create the ordinary Weyl algebra and put
3625//   // ----- the result into it
3626//   // ------ create the ring @R5
3627//   // keep: N, i,j,s, tmp, RL
3628//   setring save;
3629//   Nnew = 2*N;
3630//   //  list RL = ringlist(save); // is defined earlier
3631//   kill Lord, tmp, iv;
3632//   //  kill L;
3633//   L = 0;
3634//   list Lord, tmp;
3635//   intvec iv;
3636//   L[1] = RL[1]; // char
3637//   L[4] = RL[4]; // char, minpoly
3638//   // check whether vars have admissible names -> done earlier
3639//   //  list Name  = RL[2];
3640//   // DName is defined earlier
3641//   list NName = Name + DName;
3642//   L[2]   = NName;
3643//   // dp ordering;
3644//   string   s       = "iv=";
3645//   for(i=1;i<=2*N;i++)
3646//   {
3647//     s = s+"1,";
3648//   }
3649//   s[size(s)]= ";";
3650//   execute(s);
3651//   tmp     = 0;
3652//   tmp[1]  = "dp"; // string
3653//   tmp[2]  = iv; //intvec
3654//   Lord[1] = tmp;
3655//   kill s;
3656//   tmp[1]    = "C";
3657//   iv        = 0;
3658//   tmp[2]    = iv;
3659//   Lord[2]   = tmp;
3660//   tmp       = 0;
3661//   L[3]      = Lord;
3662//   // we are done with the list
3663//   // Add: Plural part
3664//   def @R5 = ring(L);
3665//   setring @R5;
3666//   matrix @D[Nnew][Nnew];
3667//   for(i=1; i<=N; i++)
3668//   {
3669//     @D[i,N+i]=1;
3670//   }
3671//   nc_algebra(1,@D);
3672//   dbprint(ppl,"// -3-1- the ring @R5 is ready");
3673//   dbprint(ppl-1,@R5);
3674//   ideal K5 = imap(@R2,K);
3675//   option(redSB);
3676//   dbprint(ppl,"// -3-2- the final cosmetic std");
3677//   K5 = engine(K5,eng); // std does the job too
3678//   // total cleanup
3679//   kill @R;
3680//   kill @R2;
3681//   ideal LD = K5;
3682//   ideal BS = imap(@LR,B);
3683//   kill @LR;
3684//   export BS;
3685//   export LD;
3686//   return(@R5);
3687// }
3688// example
3689// {
3690//   "EXAMPLE:"; echo = 2;
3691//   ring r = 0,(x,y,z),Dp;
3692//   poly F = x^2+y^3+z^5;
3693//   def A = annfsgms(F);
3694//   setring A;
3695//   LD;
3696//   print(matrix(BS));
3697// }
3698
3699
3700proc convloc(list @NL)
3701"USAGE:  convloc(L); L a list
3702RETURN:  list
3703PURPOSE: convert a ringlist L into another ringlist,
3704where all the 'p' orderings are replaced with the 's' orderings.
3705ASSUME: L is a result of a ringlist command
3706EXAMPLE: example convloc; shows examples
3707"
3708{
3709  list NL = @NL;
3710  // given a ringlist, returns a new ringlist,
3711  // where all the p-orderings are replaced with s-ord's
3712  int i,j,k,found;
3713  int nblocks = size(NL[3]);
3714  for(i=1; i<=nblocks; i++)
3715  {
3716    for(j=1; j<=size(NL[3][i]); j++)
3717    {
3718      if (typeof(NL[3][i][j]) == "string" )
3719      {
3720        found = 0;
3721        for (k=1; k<=size(NL[3][i][j]); k++)
3722        {
3723          if (NL[3][i][j][k]=="p")
3724          {
3725            NL[3][i][j][k]="s";
3726            found = 1;
3727            //    printf("replaced at %s,%s,%s",i,j,k);
3728          }
3729        }
3730      }
3731    }
3732  }
3733  return(NL);
3734}
3735example
3736{
3737  "EXAMPLE:"; echo = 2;
3738  ring r = 0,(x,y,z),(Dp(2),dp(1));
3739  list L = ringlist(r);
3740  list N = convloc(L);
3741  def rs = ring(N);
3742  setring rs;
3743  rs;
3744}
3745
3746proc annfspecial(ideal I, poly F, int mir, number n)
3747"USAGE:  annfspecial(I,F,mir,s0);  I an ideal, F a poly, int mir, number s0
3748RETURN:  ideal
3749PURPOSE: compute the annihilator ideal of f^s0 in the Weyl Algebra for a rational number s0
3750ASSUME:  the basering contains 's' as a variable
3751NOTE:    We assume that the basering is D[s],
3752@*          ideal I is the Ann F^s in D[s] (obtained with e.g. SannfsBM, SannfsLOT, SannfsOT)
3753@*          integer 'mir' is the minimal integer root of the Bernstein polynomial of F
3754@*          and the number s0 is rational.
3755@*       We compute the real annihilator for any value of s0 (both generic and exceptional).
3756@*       The implementation goes along the lines of Saito-Sturmfels-Takayama, Alg. 5.3.15
3757@*       If printlevel=1, progress debug messages will be printed,
3758@*       if printlevel>=2, all the debug messages will be printed.
3759EXAMPLE: example annfspecial; shows examples
3760"
3761{
3762  int ppl = printlevel-voice+2;
3763  //  int mir =  minIntRoot(L[1],0);
3764  int ns   = varnum("s");
3765  if (!ns)
3766  {
3767    ERROR("Variable s expected in the ideal AnnFs");
3768  }
3769  int d;
3770  ideal P = subst(I,var(ns),n);
3771  if (denominator(n) == 1)
3772  {
3773    // n is fraction-free
3774    d = int(numerator(n));
3775    if ( (!d) && (n!=0))
3776    {
3777      ERROR("no parametric special values are allowed");
3778    }
3779    d = d - mir;
3780    if (d>0)
3781    {
3782      dbprint(ppl,"// -1-1- starting syzygy computations");
3783      matrix J[1][1] = F^d;
3784      dbprint(ppl-1,"// -1-1-1- of the polynomial ideal");
3785      dbprint(ppl-1,J);
3786      matrix K[1][size(I)] = subst(I,var(ns),mir);
3787      dbprint(ppl-1,"// -1-1-2- modulo ideal:");
3788      dbprint(ppl-1, K);
3789      module M = modulo(J,K);
3790      dbprint(ppl-1,"// -1-1-3- getting the result:");
3791      dbprint(ppl-1, M);
3792      P  = P, ideal(M);
3793      dbprint(ppl,"// -1-2- finished syzygy computations");
3794    }
3795    else
3796    {
3797      dbprint(ppl,"// -1-1- d<=0, no syzygy computations needed");
3798      dbprint(ppl-1,"// -1-2- for d =");
3799      dbprint(ppl-1, d);
3800    }
3801  }
3802  // also the else case: d<=0 or n is not an integer
3803  dbprint(ppl,"// -2-1- starting final Groebner basis");
3804  P = groebner(P);
3805  dbprint(ppl,"// -2-2- finished final Groebner basis");
3806  return(P);
3807}
3808example
3809{
3810  "EXAMPLE:"; echo = 2;
3811  ring r = 0,(x,y),dp;
3812  poly F = x3-y2;
3813  def  B = annfs(F);  setring B;
3814  minIntRoot(BS[1],0);
3815  // So, the minimal integer root is -1
3816  setring r;
3817  def  A = SannfsBM(F);
3818  setring A;
3819  poly F = x3-y2;
3820  annfspecial(LD,F,-1,3/4); // generic root
3821  annfspecial(LD,F,-1,-2);  // integer but still generic root
3822  annfspecial(LD,F,-1,1);   // exceptional root
3823}
3824
3825static proc new_ex_annfspecial()
3826{
3827  //another example for annfspecial: x3+y3+z3
3828  ring r = 0,(x,y,z),dp;
3829  poly F =  x3+y3+z3;
3830  def  B = annfs(F);  setring B;
3831  minIntRoot(BS[1],0);
3832  // So, the minimal integer root is -1
3833  setring r;
3834  def  A = SannfsBM(F);
3835  setring A;
3836  poly F =  x3+y3+z3;
3837  annfspecial(LD,F,-1,3/4); // generic root
3838  annfspecial(LD,F,-1,-2);  // integer but still generic root
3839  annfspecial(LD,F,-1,1);   // exceptional root
3840}
3841
3842proc minIntRoot(ideal P, int fact)
3843"USAGE:  minIntRoot(P, fact); P an ideal, fact an int
3844RETURN:  int
3845PURPOSE: minimal integer root of a maximal ideal P
3846NOTE:    if fact==1, P is the result of some 'factorize' call,
3847@*       else P is treated as the result of bernstein::gmssing.lib
3848@*       in both cases without constants and multiplicities
3849EXAMPLE: example minIntRoot; shows examples
3850"
3851{
3852  //    ideal P = factorize(p,1);
3853  // or ideal P = bernstein(F)[1];
3854  intvec vP;
3855  number nP;
3856  int i;
3857  if ( fact )
3858  {
3859    // the result comes from "factorize"
3860    P = normalize(P); // now leadcoef = 1
3861    // TODO: hunt for units and kill then !!!
3862    P = lead(P)-P;
3863    // nP = leadcoef(P[i]-lead(P[i])); // for 1 var only, extract the coeff
3864  }
3865  else
3866  {
3867    // bernstein deletes -1 usually
3868    P = P, -1;
3869  }
3870  // for both situations:
3871  // now we have an ideal of fractions of type "number"
3872  int sP = size(P);
3873  for(i=1; i<=sP; i++)
3874  {
3875    nP = leadcoef(P[i]);
3876    if ( (nP - int(nP)) == 0 )
3877    {
3878      vP = vP,int(nP);
3879    }
3880  }
3881  if ( size(vP)>=2 )
3882  {
3883    vP = vP[2..size(vP)];
3884  }
3885  sP = -Max(-vP);
3886  if (sP == 0)
3887  {
3888    "Warning: zero root!";
3889  }
3890  return(sP);
3891}
3892example
3893{
3894  "EXAMPLE:"; echo = 2;
3895  ring r   = 0,(x,y),ds;
3896  poly f1  = x*y*(x+y);
3897  ideal I1 = bernstein(f1)[1]; // a local Bernstein poly
3898  minIntRoot(I1,0);
3899  poly  f2  = x2-y3;
3900  ideal I2  = bernstein(f2)[1];
3901  minIntRoot(I2,0);
3902  // now we illustrate the behaviour of factorize
3903  // together with a global ordering
3904  ring r2  = 0,x,dp;
3905  poly f3   = 9*(x+2/3)*(x+1)*(x+4/3); //global b-poly of f1=x*y*(x+y)
3906  ideal I3 = factorize(f3,1);
3907  minIntRoot(I3,1);
3908  // and a more interesting situation
3909  ring  s  = 0,(x,y,z),ds;
3910  poly  f  = x3 + y3 + z3;
3911  ideal I  = bernstein(f)[1];
3912  minIntRoot(I,0);
3913}
3914
3915proc isHolonomic(def M)
3916"USAGE:  isHolonomic(M); M an ideal/module/matrix
3917RETURN:  int, 1 if M is holonomic and 0 otherwise
3918PURPOSE: check the modules for the property of holonomy
3919NOTE:    M is holonomic, if 2*dim(M) = dim(R), where R is a
3920ground ring; dim stays for Gelfand-Kirillov dimension
3921EXAMPLE: example isHolonomic; shows examples
3922"
3923{
3924  if ( (typeof(M) != "ideal") && (typeof(M) != "module") && (typeof(M) != "matrix") )
3925  {
3926  //  print(typeof(M));
3927    ERROR("an argument of type ideal/module/matrix expected");
3928  }
3929  if (attrib(M,"isSB")!=1)
3930  {
3931    M = std(M);
3932  }
3933  int dimR = gkdim(std(0));
3934  int dimM = gkdim(M);
3935  return( (dimR==2*dimM) );
3936}
3937example
3938{
3939  "EXAMPLE:"; echo = 2;
3940  ring R = 0,(x,y),dp;
3941  poly F = x*y*(x+y);
3942  def A = annfsBM(F,0);
3943  setring A;
3944  LD;
3945  isHolonomic(LD);
3946  ideal I = std(LD[1]);
3947  I;
3948  isHolonomic(I);
3949}
3950
3951proc reiffen(int p, int q)
3952"USAGE:  reiffen(p, q);  int p, int q
3953RETURN:  ring
3954PURPOSE: set up the polynomial, describing a Reiffen curve
3955NOTE:    activate this ring with the @code{setring} command and find the
3956         curve as a polynomial RC
3957@*   a Reiffen curve is defined as F = x^p + y^q + xy^{q-1}, q >= p+1 >= 5
3958ASSUME: q >= p+1 >= 5. Otherwise an error message is returned
3959EXAMPLE: example reiffen; shows examples
3960"
3961{
3962// a Reiffen curve is defined as
3963// F = x^p + y^q +x*y^{q-1}, q \geq p+1 \geq 5
3964
3965  if ( (p<4) || (q<5) || (q-p<1) )
3966  {
3967    ERROR("Some of conditions p>=4, q>=5 or q>=p+1 is not satisfied!");
3968  }
3969  ring @r = 0,(x,y),dp;
3970  poly RC = y^q +x^p + x*y^(q-1);
3971  export RC;
3972  return(@r);
3973}
3974example
3975{
3976  "EXAMPLE:"; echo = 2;
3977  def r = reiffen(4,5);
3978  setring r;
3979  RC;
3980}
3981
3982proc arrange(int p)
3983"USAGE:  arrange(p);  int p
3984RETURN:  ring
3985PURPOSE: set up the polynomial, describing a hyperplane arrangement
3986NOTE:   must be executed in a ring
3987ASSUME: basering is present
3988EXAMPLE: example arrange; shows examples
3989"
3990{
3991  int UseBasering = 0 ;
3992  if (p<2)
3993  {
3994    ERROR("p>=2 is required!");
3995  }
3996  if ( nameof(basering)!="basering" )
3997  {
3998    if (p > nvars(basering))
3999    {
4000      ERROR("too big p");
4001    }
4002    else
4003    {
4004      def @r = basering;
4005      UseBasering = 1;
4006    }
4007  }
4008  else
4009  {
4010    // no basering found
4011    ERROR("no basering found!");
4012    //    ring @r = 0,(x(1..p)),dp;
4013  }
4014  int i,j,sI;
4015  poly  q = 1;
4016  list ar;
4017  ideal tmp;
4018  tmp = ideal(var(1));
4019  ar[1] = tmp;
4020  for (i = 2; i<=p; i++)
4021  {
4022    // add i-nary sums to the product
4023    ar = indAR(ar,i);
4024  }
4025  for (i = 1; i<=p; i++)
4026  {
4027    tmp = ar[i]; sI = size(tmp);
4028    for (j = 1; j<=sI; j++)
4029    {
4030      q = q*tmp[j];
4031    }
4032  }
4033  if (UseBasering)
4034  {
4035    return(q);
4036  }
4037  //  poly AR = q; export AR;
4038  //  return(@r);
4039}
4040example
4041{
4042  "EXAMPLE:"; echo = 2;
4043  ring X = 0,(x,y,z,t),dp;
4044  poly q = arrange(3);
4045  factorize(q,1);
4046}
4047
4048proc checkRoot(poly F, number a, list #)
4049"USAGE:  checkRoot(f,alpha [,S,eng]);  f a poly, alpha a number, S a string , eng an optional int
4050RETURN:  int
4051PURPOSE: check whether a rational is a root of the global Bernstein polynomial of f (and compute its multiplicity)
4052with the algorithm given in S and with the Groebner basis engine given in eng
4053NOTE:    The annihilator of f^s in D[s] is needed and it is computed according to the algorithm by Briancon and Maisonobe
4054@*       The value of a string S can be
4055@*       'alg1' (default) - for the algorithm 1 of J. Martin-Morales (unpublished)
4056@*       'alg2' - for the algorithm 2 of J. Martin-Morales (unpublished)
4057@*       The output int is:
4058@*       - if the algorithm 1 is chosen: 1 if -alpha is a root of the global Bernstein polynomial and 0 otherwise
4059@*       - if the algorithm 2 is chosen: the multiplicity of -alpha as a root of the global Bernstein polynomial of f.
4060@*                                       (If -alpha is not a root, the output is 0)
4061@*       If eng <>0, @code{std} is used for Groebner basis computations,
4062@*       otherwise (and by default) @code{slimgb} is used.
4063@*       If printlevel=1, progress debug messages will be printed,
4064@*       if printlevel>=2, all the debug messages will be printed.
4065EXAMPLE: example checkRoot; shows examples
4066"
4067{
4068  int eng = 0;
4069  int chs = 0; // choice
4070  string algo = "alg1";
4071  string st;
4072  if ( size(#)>0 )
4073  {
4074   if ( typeof(#[1]) == "string" )
4075   {
4076     st = string(#[1]);
4077     if ( (st == "alg1") || (st == "ALG1") || (st == "Alg1") ||(st == "aLG1"))
4078     {
4079       algo = "alg1";
4080       chs  = 1;
4081     }
4082     if ( (st == "alg2") || (st == "ALG2") || (st == "Alg2") || (st == "aLG2"))
4083     {
4084       algo = "alg2";
4085       chs  = 1;
4086     }
4087     if (chs != 1)
4088     {
4089       // incorrect value of S
4090       print("Incorrect algorithm given, proceed with the default alg1 of J. Martín-Morales");
4091       algo = "alg1";
4092     }
4093     // second arg
4094     if (size(#)>1)
4095     {
4096       // exists 2nd arg
4097       if ( typeof(#[2]) == "int" )
4098       {
4099         // the case: given alg, given engine
4100         eng = int(#[2]);
4101       }
4102       else
4103       {
4104         eng = 0;
4105       }
4106     }
4107     else
4108     {
4109       // no second arg
4110       eng = 0;
4111     }
4112   }
4113   else
4114   {
4115     if ( typeof(#[1]) == "int" )
4116     {
4117       // the case: default alg, engine
4118       eng = int(#[1]);
4119       // algo = "alg1";  //is already set
4120     }
4121     else
4122     {
4123       // incorr. 1st arg
4124       algo = "alg1";
4125     }
4126   }
4127  }
4128  // size(#)=0, i.e. there is no algorithm and no engine given
4129  //  eng = 0; algo = "alg1";  //are already set
4130  // int ppl = printlevel-voice+2;
4131  printlevel=printlevel+1;
4132  def save = basering;
4133  def @A = SannfsBM(F);
4134  setring @A;
4135  poly F = imap(save,F);
4136  number a = imap(save,a);
4137  if ( algo=="alg1")
4138  {
4139    int output = checkRoot1(LD,F,a,eng);
4140  }
4141  else
4142  {
4143    if ( algo=="alg2")
4144    {
4145      int output = checkRoot2(LD,F,a,eng);
4146    }
4147  }
4148  printlevel=printlevel-1;
4149  return(output);
4150}
4151example
4152{
4153  "EXAMPLE:"; echo = 2;
4154  printlevel=0;
4155  ring r = 0,(x,y),Dp;
4156  poly F = x^4+y^5+x*y^4;
4157  checkRoot(F,11/20);    // -11/20 is a root of bf
4158  poly G = x*y;
4159  checkRoot(G,1,"alg2"); // -1 is a root of bg with multiplicity 2
4160}
4161
4162proc checkRoot1(ideal I, poly F, number a, list #)
4163"USAGE:  checkRoot1(I,f,alpha [,eng]);  I an ideal, f a poly, alpha a number, eng an optional int
4164ASSUME:  I is the annihilator of f^s in D[s], f is a polynomial in K[_x]
4165RETURN:  int, 1 if -alpha is a root of the global Bernstein polynomial of f and 0 otherwise
4166PURPOSE: check whether a rational is a root of the global Bernstein polynomial of f
4167NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
4168@*       otherwise (and by default) @code{slimgb} is used.
4169@*       If printlevel=1, progress debug messages will be printed,
4170@*       if printlevel>=2, all the debug messages will be printed.
4171EXAMPLE: example checkRoot1; shows examples
4172"
4173{
4174  int eng = 0;
4175  if ( size(#)>0 )
4176  {
4177    if ( typeof(#[1]) == "int" )
4178    {
4179      eng = int(#[1]);
4180    }
4181  }
4182  int ppl = printlevel-voice+2;
4183  dbprint(ppl,"// -0-1- starting the procedure checkRoot1");
4184  def save = basering;
4185  int N = nvars(basering);
4186  int Nnew = N-1;
4187  int n = Nnew / 2;
4188  int i;
4189  string s;
4190  list RL = ringlist(basering);
4191  list L, Lord;
4192  list tmp;
4193  intvec iv;
4194  L[1] = RL[1];  // char
4195  L[4] = RL[4];  // char, minpoly
4196  // check whether basering is D[s]=K(_x,_Dx,s)
4197  list Name = RL[2];
4198  for (i=1; i<=n; i++)
4199  {
4200    if ( bracket(var(i+n),var(i))!=1 )
4201    {
4202      ERROR("basering should be D[s]=K(_x,_Dx,s)");
4203    }
4204  }
4205  if ( Name[N]!="s" )
4206  {
4207    ERROR("the last variable of basering should be s");
4208  }
4209  // now, create the new vars
4210  list NName;
4211  for (i=1; i<=Nnew; i++)
4212  {
4213    NName[i] = Name[i];
4214  }
4215  L[2] = NName;
4216  kill Name,NName;
4217  // block ord (dp);
4218  tmp[1] = "dp"; // string
4219  s = "iv=";
4220  for (i=1; i<=Nnew; i++)
4221  {
4222    s = s+"1,";
4223  }
4224  s[size(s)]=";";
4225  execute(s);
4226  kill s;
4227  tmp[2]  = iv;
4228  Lord[1] = tmp;
4229  tmp[1]  = "C";
4230  iv      = 0;
4231  tmp[2]  = iv;
4232  Lord[2] = tmp;
4233  tmp     = 0;
4234  L[3]    = Lord;
4235  // we are done with the list
4236  def @R@ = ring(L);
4237  setring @R@;
4238  matrix @D[Nnew][Nnew];
4239  for (i=1; i<=n; i++)
4240  {
4241    @D[i,i+n]=1;
4242  }
4243  def @R = nc_algebra(1,@D);
4244  setring @R;
4245  kill @R@;
4246  dbprint(ppl,"// -1-1- the ring @R(_x,_Dx) is ready");
4247  dbprint(ppl-1, S);
4248  // create the ideal K = ann_D[s](f^s)_{s=-alpha} + < f >
4249  setring save;
4250  ideal K = subst(I,s,-a);
4251  dbprint(ppl,"// -1-2- the variable s has been substituted by "+string(-a));
4252  dbprint(ppl-1, K);
4253  K = NF(K,std(F));
4254  // make leadcoeffs positive
4255  for (i=1; i<=ncols(K); i++)
4256  {
4257    if ( leadcoef(K[i])<0 )
4258    {
4259      K[i] = -K[i];
4260    }
4261  }
4262  K = K,F;
4263  // ------------ the ideal K is ready ------------
4264  setring @R;
4265  ideal K = imap(save,K);
4266  dbprint(ppl,"// -1-3- starting the computation of a Groebner basis of K in @R");
4267  dbprint(ppl-1, K);
4268  ideal G = engine(K,eng);
4269  dbprint(ppl,"// -1-4- the Groebner basis has been computed");
4270  dbprint(ppl-1, G);
4271  return(G[1]!=1);
4272}
4273example
4274{
4275  "EXAMPLE:"; echo = 2;
4276  ring r = 0,(x,y),Dp;
4277  poly F = x^4+y^5+x*y^4;
4278  printlevel = 0;
4279  def A = Sannfs(F);
4280  setring A;
4281  poly F = imap(r,F);
4282  checkRoot1(LD,F,31/20);   // -31/20 is not a root of bs
4283  checkRoot1(LD,F,11/20);   // -11/20 is a root of bs
4284}
4285
4286proc checkRoot2 (ideal I, poly F, number a, list #)
4287"USAGE:  checkRoot2(I,f,alpha [,eng]);  I an ideal, f a poly, alpha a number, eng an optional int
4288ASSUME:  I is the annihilator of f^s in D[s], f is a polynomial in K[_x]
4289RETURN:  int, the multiplicity of -alpha as a root of the global Bernstein polynomial of f. If -alpha is not a root, the output is 0
4290PURPOSE: check whether a rational is a root of the global Bernstein polynomial of f and compute its multiplicity from the known Ann F^s in D[s]
4291NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
4292@*       otherwise (and by default) @code{slimgb} is used.
4293@*       If printlevel=1, progress debug messages will be printed,
4294@*       if printlevel>=2, all the debug messages will be printed.
4295EXAMPLE: example checkRoot2; shows examples
4296"
4297{
4298  int eng = 0;
4299  if ( size(#)>0 )
4300  {
4301    if ( typeof(#[1]) == "int" )
4302    {
4303      eng = int(#[1]);
4304    }
4305  }
4306  int ppl = printlevel-voice+2;
4307  dbprint(ppl,"// -0-1- starting the procedure checkRoot2");
4308  def save = basering;
4309  int N = nvars(basering);
4310  int n = (N-1) / 2;
4311  int i;
4312  string s;
4313  list RL = ringlist(basering);
4314  list L, Lord;
4315  list tmp;
4316  intvec iv;
4317  L[1] = RL[1];  // char
4318  L[4] = RL[4];  // char, minpoly
4319  // check whether basering is D[s]=K(_x,_Dx,s)
4320  list Name = RL[2];
4321  for (i=1; i<=n; i++)
4322  {
4323    if ( bracket(var(i+n),var(i))!=1 )
4324    {
4325      ERROR("basering should be D[s]=K(_x,_Dx,s)");
4326    }
4327  }
4328  if ( Name[N]!="s" )
4329  {
4330    ERROR("the last variable of basering should be s");
4331  }
4332  // now, create the new vars
4333  L[2] = Name;
4334  kill Name;
4335  // block ord (dp);
4336  tmp[1] = "dp"; // string
4337  s = "iv=";
4338  for (i=1; i<=N; i++)
4339  {
4340    s = s+"1,";
4341  }
4342  s[size(s)]=";";
4343  execute(s);
4344  kill s;
4345  tmp[2]  = iv;
4346  Lord[1] = tmp;
4347  tmp[1]  = "C";
4348  iv      = 0;
4349  tmp[2]  = iv;
4350  Lord[2] = tmp;
4351  tmp     = 0;
4352  L[3]    = Lord;
4353  // we are done with the list
4354  def @R@ = ring(L);
4355  setring @R@;
4356  matrix @D[N][N];
4357  for (i=1; i<=n; i++)
4358  {
4359    @D[i,i+n]=1;
4360  }
4361  def @R = nc_algebra(1,@D);
4362  setring @R;
4363  kill @R@;
4364  dbprint(ppl,"// -1-1- the ring @R(_x,_Dx,s) is ready");
4365  dbprint(ppl-1, @R);
4366  // now, continue with the algorithm
4367  ideal I = imap(save,I);
4368  poly F = imap(save,F);
4369  number a = imap(save,a);
4370  ideal II = NF(I,std(F));
4371  // make leadcoeffs positive
4372  for (i=1; i<=ncols(II); i++)
4373  {
4374    if ( leadcoef(II[i])<0 )
4375    {
4376      II[i] = -II[i];
4377    }
4378  }
4379  ideal J,G;
4380  int m;  // the output (multiplicity)
4381  dbprint(ppl,"// -2- starting the bucle");
4382  for (i=0; i<=n; i++)  // the multiplicity has to be <= n
4383  {
4384    // create the ideal Ji = ann_D[s](f^s) + < f, (s+alpha)^{i+1} >
4385    // (s+alpha)^i in Ji <==> -alpha is a root with multiplicity >= i
4386    J = II,F,(s+a)^(i+1);
4387    // ------------ the ideal Ji is ready -----------
4388    dbprint(ppl,"// -2-"+string(i+1)+"-1- starting the computation of a Groebner basis of J"+string(i)+" in @R");
4389    dbprint(ppl-1, J);
4390    G = engine(J,eng);
4391    dbprint(ppl,"// -2-"+string(i+1)+"-2- the Groebner basis has been computed");
4392    dbprint(ppl-1, G);
4393    if ( NF((s+a)^i,G)==0 )
4394    {
4395      dbprint(ppl,"// -2-"+string(i+1)+"-3- the number "+string(-a)+" has not multiplicity "+string(i+1));
4396      m = i;
4397      break;
4398    }
4399    dbprint(ppl,"// -2-"+string(i+1)+"-3- the number "+string(-a)+" has multiplicity at least "+string(i+1));
4400  }
4401  dbprint(ppl,"// -3- the bucle has finished");
4402  return(m);
4403}
4404example
4405{
4406  "EXAMPLE:"; echo = 2;
4407  ring r = 0,(x,y,z),Dp;
4408  poly F = x*y*z;
4409  printlevel = 0;
4410  def A = Sannfs(F);
4411  setring A;
4412  poly F = imap(r,F);
4413  checkRoot2(LD,F,1);    // -1 is a root of bs with multiplicity 3
4414  checkRoot2(LD,F,1/3);  // -1/3 is not a root
4415}
4416
4417proc checkFactor(ideal I, poly F, poly q, list #)
4418"USAGE:  checkFactor(I,f,qs [,eng]);  I an ideal, f a poly, qs a poly, eng an optional int
4419ASSUME:  I is the output of Sannfs, SannfsBM, SannfsLOT or SannfsOT,
4420         f is a polynomial in K[_x], qs is a polynomial in K[s]
4421RETURN:  int, 1 if qs is a factor of the global Bernstein polynomial of f and 0 otherwise
4422PURPOSE: check whether a rational is a root of the global Bernstein polynomial of f and compute its multiplicity from the known Ann F^s in D[s]
4423NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
4424@*       otherwise (and by default) @code{slimgb} is used.
4425@*       If printlevel=1, progress debug messages will be printed,
4426@*       if printlevel>=2, all the debug messages will be printed.
4427EXAMPLE: example checkFactor; shows examples
4428"
4429{
4430  int eng = 0;
4431  if ( size(#)>0 )
4432  {
4433    if ( typeof(#[1]) == "int" )
4434    {
4435      eng = int(#[1]);
4436    }
4437  }
4438  int ppl = printlevel-voice+2;
4439  def @R2 = basering;
4440  int N = nvars(@R2);
4441  int i;
4442  // we're in D_n[s], where the elim ord for s is set
4443  dbprint(ppl,"// -0-1- starting the procedure checkFactor");
4444  dbprint(ppl,"// -1-1- the ring @R2(_x,_Dx,s) is ready");
4445  dbprint(ppl-1, @R2);
4446  // create the ideal J = ann_D[s](f^s) + < f,q >
4447  ideal J = NF(I,std(F));
4448  // make leadcoeffs positive
4449  for (i=1; i<=ncols(J); i++)
4450  {
4451    if ( leadcoef(J[i])<0 )
4452    {
4453      J[i] = -J[i];
4454    }
4455  }
4456  J = J,F,q;
4457  // ------------ the ideal J is ready -----------
4458  dbprint(ppl,"// -1-2- starting the elimination of _x,_Dx in @R2");
4459  dbprint(ppl-1, J);
4460  ideal G = engine(J,eng);
4461  ideal K = nselect(G,1,N-1);
4462  kill J,G;
4463  dbprint(ppl,"// -1-3- _x,_Dx are eliminated");
4464  dbprint(ppl-1, K);
4465  //q is a factor of bs iff K = < q >
4466  //K = normalize(K);
4467  //q = normalize(q);
4468  //return( (K[1]==q) );
4469  return( NF(K[1],std(q))==0 );
4470}
4471example
4472{
4473  "EXAMPLE:"; echo = 2;
4474  ring r = 0,(x,y),Dp;
4475  poly F = x^4+y^5+x*y^4;
4476  printlevel = 0;
4477  def A = Sannfs(F);
4478  setring A;
4479  poly F = imap(r,F);
4480  checkFactor(LD,F,20*s+31);     // -31/20 is not a root of bs
4481  checkFactor(LD,F,20*s+11);     // -11/20 is a root of bs
4482  checkFactor(LD,F,(20*s+11)^2); // the multiplicity of -11/20 is 1
4483}
4484
4485proc varnum(string s)
4486"USAGE:  varnum(s);  string s
4487RETURN:  int
4488PURPOSE: returns the number of the variable with the name s
4489among the variables of basering or 0 if there is no such variable
4490EXAMPLE: example varnum; shows examples
4491"
4492{
4493  int i;
4494  for (i=1; i<= nvars(basering); i++)
4495  {
4496    if ( string(var(i)) == s )
4497    {
4498      return(i);
4499    }
4500  }
4501  return(0);
4502}
4503example
4504{
4505  "EXAMPLE:"; echo = 2;
4506  ring X = 0,(x,y1,z(0),tTa),dp;
4507  varnum("z(0)");
4508  varnum("tTa");
4509  varnum("xyz");
4510}
4511
4512static proc indAR(list L, int n)
4513"USAGE:  indAR(L,n);  list L, int n
4514RETURN:  list
4515PURPOSE: computes arrangement inductively, using L and var(n) as the
4516next variable
4517ASSUME: L has a structure of an arrangement
4518EXAMPLE: example indAR; shows examples
4519"
4520{
4521  if ( (n<2) || (n>nvars(basering)) )
4522  {
4523    ERROR("incorrect n");
4524  }
4525  int sl = size(L);
4526  list K;
4527  ideal tmp;
4528  poly @t = L[sl][1] + var(n); //1 elt
4529  K[sl+1] = ideal(@t);
4530  tmp = L[1]+var(n);
4531  K[1] = tmp; tmp = 0;
4532  int i,j,sI;
4533  ideal I;
4534  for(i=sl; i>=2; i--)
4535  {
4536    I = L[i-1]; sI = size(I);
4537    for(j=1; j<=sI; j++)
4538    {
4539      I[j] = I[j] + var(n);
4540    }
4541    tmp  = L[i],I;
4542    K[i] = tmp;
4543    I = 0; tmp = 0;
4544  }
4545  kill I; kill tmp;
4546  return(K);
4547}
4548example
4549{
4550  "EXAMPLE:"; echo = 2;
4551  ring r = 0,(x,y,z,t,v),dp;
4552  list L;
4553  L[1] = ideal(x);
4554  list K = indAR(L,2);
4555  K;
4556  list M = indAR(K,3);
4557  M;
4558  M = indAR(M,4);
4559  M;
4560}
4561
4562static proc exCheckGenericity()
4563{
4564  LIB "control.lib";
4565  ring r = (0,a,b,c),x,dp;
4566  poly p = (x-a)*(x-b)*(x-c);
4567  def A = annfsBM(p);
4568  setring A;
4569  ideal J = slimgb(LD);
4570  matrix T = lift(LD,J);
4571  T = normalize(T);
4572  genericity(T);
4573  // Ann =x^3*Dx+3*x^2*t*Dt+(-a-b-c)*x^2*Dx+(-2*a-2*b-2*c)*x*t*Dt+3*x^2+(a*b+a*c+b*c)*x*Dx+(a*b+a*c+b*c)*t*Dt+(-2*a-2*b-2*c)*x+(-a*b*c)*Dx+(a*b+a*c+b*c)
4574  // genericity: g = a2-ab-ac+b2-bc+c2 =0
4575  // g = (a -(b+c)/2)^2 + (3/4)*(b-c)^2;
4576  // g ==0 <=> a=b=c
4577  // indeed, Ann = (x-a)^2*(x*Dx+3*t*Dt+(-a)*Dx+3)
4578  // --------------------------------------------
4579  // BUT a direct computation shows
4580  // when a=b=c,
4581  // Ann = x*Dx+3*t*Dt+(-a)*Dx+3
4582}
4583
4584static proc exOT_17()
4585{
4586  // Oaku-Takayama, p.208
4587  ring R = 0,(x,y),dp;
4588  poly F = x^3-y^2; // x^2+x*y+y^2;
4589  option(prot);
4590  option(mem);
4591  //  option(redSB);
4592  def A = annfsOT(F,0);
4593  setring A;
4594  LD;
4595  gkdim(LD); // a holonomic check
4596  //  poly F = x^3-y^2; // = x^7 - y^5; // x^3-y^4; // x^5 - y^4;
4597}
4598
4599static proc exOT_16()
4600{
4601  // Oaku-Takayama, p.208
4602  ring R = 0,(x),dp;
4603  poly F = x*(1-x);
4604  option(prot);
4605  option(mem);
4606  //  option(redSB);
4607  def A = annfsOT(F,0);
4608  setring A;
4609  LD;
4610  gkdim(LD); // a holonomic check
4611}
4612
4613static proc ex_bcheck()
4614{
4615  ring R = 0,(x,y),dp;
4616  poly F = x*y*(x+y);
4617  option(prot);
4618  option(mem);
4619  int eng = 0;
4620  //  option(redSB);
4621  def A = annfsOT(F,eng);
4622  setring A;
4623  LD;
4624}
4625
4626static proc ex_bcheck2()
4627{
4628  ring R = 0,(x,y),dp;
4629  poly F = x*y*(x+y);
4630  int eng = 0;
4631  def A = annfsBM(F,eng);
4632  setring A;
4633  LD;
4634}
4635
4636static proc ex_BMI()
4637{
4638  // a hard example
4639  ring r = 0,(x,y),Dp;
4640  poly F1 = (x2-y3)*(x3-y2);
4641  poly F2 = (x2-y3)*(xy4+y5+x4);
4642  ideal F = F1,F2;
4643  def A = annfsBMI(F);
4644  setring A;
4645  LD;
4646  BS;
4647}
4648
4649static proc ex2_BMI()
4650{
4651  // this example was believed to be intractable in 2005 by Gago-Vargas, Castro and Ucha
4652  ring r = 0,(x,y),Dp;
4653  option(prot);
4654  option(mem);
4655  ideal F = x2+y3,x3+y2;
4656  printlevel = 2;
4657  def A = annfsBMI(F);
4658  setring A;
4659  LD;
4660  BS;
4661}
4662
4663static proc ex_operatorBM()
4664{
4665  ring r = 0,(x,y,z,w),Dp;
4666  poly F = x^3+y^3+z^2*w;
4667  printlevel = 0;
4668  def A = operatorBM(F);
4669  setring A;
4670  F; // the original polynomial itself
4671  LD; // generic annihilator
4672  LD0; // annihilator
4673  bs; // normalized Bernstein poly
4674  BS; // root and multiplicities of the Bernstein poly
4675  PS; // the operator, s.t. PS*F^{s+1} = bs*F^s mod LD
4676  reduce(PS*F-bs,LD); // check the property of PS
4677}
Note: See TracBrowser for help on using the repository browser.