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

spielwiese
Last change on this file since a2c2031 was a2c2031, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: format git-svn-id: file:///usr/local/Singular/svn/trunk@9746 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 92.6 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: dmod.lib,v 1.12 2007-01-23 15:03:30 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 ring R[1/F^s] for a natural number s.
11@* In fact, the ring R[1/F^s] has a structure of a D(R)-module, where D(R)
12@* is an n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>.
13@* Constructively, one needs to find a left ideal I = I(F^s) in D(R), such
14@* that K[x_1,...,x_n,1/F^s] is isomorphic to D(R)/I as a D(R)-module.
15@* We often write just D for D(R) and D[s] for D tensor over K with K[s]
16@* One is interested in the following data:
17@* - Ann F^s = I = I(F^s) in D(R)[s], denoted by LD in the output
18@* - global Bernstein polynomial in K[s], denoted by bs, its minimal integer root s0 and
19@*   the list of all roots of bs, which are rational, with their multiplicities is denoted by BS
20@* - Ann F^s0 = I(F^s0) in D(R), denoted by LD0 in the output (LD0 is a holonomic ideal in D(R))
21@* - an operator in D(R)[s], denoted PS such that PS*F^(s+1) = bs*F^s holds in K[x_1,...,x_n,1/F^s].
22
23@* We provide the following implementations:
24@* OT) the classical Ann F^s algorithm from Oaku and Takayama (J. Pure
25        Applied Math., 1999),
26@* LOT) Levandovskyy's modification of the Oaku-Takayama algorithm (unpublished)
27@* BM) the Ann F^s algorithm by Briancon and Maisonobe (Remarques sur
28        l'ideal de Bernstein associe a des polynomes, preprint, 2002)
29
30GUIDE:
31@* - Ann F^s = I = I(F^s) = LD in D(R)[s] can be computed by SannfsBM, SannfsOT, SannfsLOT
32@* - global Bernstein polynomial bs resp. BS in K[s] can be computed by bernsteinBM
33@* - Ann F^s0 = I(F^s0) = LD0 in D(R) can be computed by annfs0, annfsBM, annfsOT, annfsLOT
34@* - all the relevant data (LD, LD0, bs, PS) are computed by operatorBM
35
36PROCEDURES:
37
38annfs0(I,F [,eng]);    compute Ann F^s0 in D and Bernstein poly from the known Ann F^s in D[s]
39annfsBM(F[,eng]);      compute Ann F^s0 in D and Bernstein poly for a poly F (algorithm of Briancon-Maisonobe)
40annfsLOT(F[,eng]);     compute Ann F^s0 in D and Bernstein poly for a poly F (Levandovskyy modification of the Oaku-Takayama algorithm)
41annfsOT(F[,eng]);      compute Ann F^s0 in D and Bernstein poly for a poly F (algorithm of Oaku-Takayama)
42
43SannfsBM(F[,eng]);     compute Ann F^s in D[s] for a poly F (algorithm of Briancon-Maisonobe)
44SannfsLOT(F[,eng]);    compute Ann F^s in D[s] for a poly F (Levandovskyy modification of the Oaku-Takayama algorithm)
45SannfsOT(F[,eng]);     compute Ann F^s in D[s] for a poly F (algorithm of Oaku-Takayama)
46
47bernsteinBM(F[,eng]);  compute global Bernstein poly for a poly F (algorithm of Briancon-Maisonobe)
48operatorBM(F[,eng]);   compute Ann F^s, Ann F^s0, BS and PS for a poly F (algorithm of Briancon-Maisonobe)
49annfsParamBM(F[,eng]); compute the generic Ann F^s and exceptional parametric constellations for a poly F with parametric coefficients (algorithm by Briancon and Maisonobe)
50
51annfsBMI(F[,eng]);  compute Ann F^s and Bernstein ideal for a poly F=f1*..*fP (multivariate algorithm of Briancon-Maisonobe)
52
53
54AUXILIARY PROCEDURES:
55
56arrange(p);       create a poly, describing a full hyperplane arrangement
57reiffen(p,q);     create a poly, describing a Reiffen curve
58isHolonomic(M);   check whether a module is holonomic
59convloc(L);       replace global orderings with local in the ringlist L
60minIntRoot(P,fact); minimal integer root among the roots of a maximal ideal P
61";
62
63LIB "nctools.lib";
64LIB "elim.lib";
65LIB "qhmoduli.lib"; // for Max
66LIB "gkdim.lib";
67LIB "gmssing.lib";
68LIB "control.lib";  // for genericity
69
70static proc engine(ideal I, int i)
71{
72  /* std - slimgb mix */
73  ideal J;
74  if (i==0)
75  {
76    J = slimgb(I);
77  }
78  else
79  {
80    // without options -> strange! (ringlist?)
81    option(redSB);
82    option(redTail);
83    J = std(I);
84  }
85  return(J);
86}
87
88// alternative code for SannfsBM, rename from annfsBM to ALTannfsBM
89// is superfluos - will not be included in the official documentation
90proc ALTannfsBM (poly F, list #)
91"USAGE:  annfsBM(f [,eng]);  f a poly, eng an optional int
92RETURN:  ring
93PURPOSE: compute the annihilator ideal of f^s in D[s], where D is the Weyl Algebra, according to the algorithm by Briancon and Maisonobe
94NOTE:    activate this ring with the @code{setring} command. In this ring,
95@*       - the ideal LD is the annihilator of f^s.
96@*       If eng <>0, @code{std} is used for Groebner basis computations,
97@*       otherwise, and by default @code{slimgb} is used.
98@*       If printlevel=1, progress debug messages will be printed,
99@*       if printlevel>=2, all the debug messages will be printed.
100EXAMPLE: example annfsBM; shows examples
101"
102{
103  int eng = 0;
104  if ( size(#)>0 )
105  {
106    if ( typeof(#[1]) == "int" )
107    {
108      eng = int(#[1]);
109    }
110  }
111  // returns a list with a ring and an ideal LD in it
112  int ppl = printlevel-voice+2;
113  //  printf("plevel :%s, voice: %s",printlevel,voice);
114  def save = basering;
115  int N = nvars(basering);
116  int Nnew = 2*N+2;
117  int i,j;
118  string s;
119  list RL = ringlist(basering);
120  list L, Lord;
121  list tmp;
122  intvec iv;
123  L[1] = RL[1];  //char
124  L[4] = RL[4];  //char, minpoly
125  // check whether vars have admissible names
126  list Name  = RL[2];
127  list RName;
128  RName[1] = "t";
129  RName[2] = "s";
130  for (i=1; i<=N; i++)
131  {
132    for(j=1; j<=size(RName); j++)
133    {
134      if (Name[i] == RName[j])
135      {
136        ERROR("Variable names should not include t,s");
137      }
138    }
139  }
140  // now, create the names for new vars
141  list DName;
142  for (i=1; i<=N; i++)
143  {
144    DName[i] = "D"+Name[i];  //concat
145  }
146  tmp[1] = "t";
147  tmp[2] = "s";
148  list NName = tmp + Name + DName;
149  L[2]   = NName;
150  // Name, Dname will be used further
151  kill NName;
152  // block ord (lp(2),dp);
153  tmp[1]  = "lp"; // string
154  iv      = 1,1;
155  tmp[2]  = iv; //intvec
156  Lord[1] = tmp;
157  // continue with dp 1,1,1,1...
158  tmp[1]  = "dp"; // string
159  s       = "iv=";
160  for (i=1; i<=Nnew; i++)
161  {
162    s = s+"1,";
163  }
164  s[size(s)]= ";";
165  execute(s);
166  kill s;
167  tmp[2]    = iv;
168  Lord[2]   = tmp;
169  tmp[1]    = "C";
170  iv        = 0;
171  tmp[2]    = iv;
172  Lord[3]   = tmp;
173  tmp       = 0;
174  L[3]      = Lord;
175  // we are done with the list
176  def @R = ring(L);
177  setring @R;
178  matrix @D[Nnew][Nnew];
179  @D[1,2]=t;
180  for(i=1; i<=N; i++)
181  {
182    @D[2+i,N+2+i]=1;
183  }
184  // L[5] = matrix(UpOneMatrix(Nnew));
185  // L[6] = @D;
186  ncalgebra(1,@D);
187  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
188  dbprint(ppl-1, @R);
189  // create the ideal I
190  poly  F = imap(save,F);
191  ideal I = t*F+s;
192  poly p;
193  for(i=1; i<=N; i++)
194  {
195    p = t;  //t
196    p = diff(F,var(2+i))*p;
197    I = I, var(N+2+i) + p;
198  }
199  // -------- the ideal I is ready ----------
200  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
201  dbprint(ppl-1, I);
202  ideal J = engine(I,eng);
203  ideal K = nselect(J,1);
204  kill I,J;
205  dbprint(ppl,"// -1-3- t is eliminated");
206  dbprint(ppl-1, K);  //K is without t
207  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
208  // thus creating the ring @R2
209  // keep: N, i,j,s, tmp, RL
210  setring save;
211  Nnew = 2*N+1;
212  // list RL = ringlist(save);  //is defined earlier
213  kill Lord, tmp, iv;
214  L = 0;
215  list Lord, tmp;
216  intvec iv;
217  L[1] = RL[1];
218  L[4] = RL[4];  //char, minpoly
219  // check whether vars have admissible names -> done earlier
220  // list Name = RL[2]
221  // DName is defined earlier
222  tmp[1] = "s";
223  list NName = Name + DName + tmp;
224  L[2] = NName;
225  // dp ordering;
226  string s = "iv=";
227  for (i=1; i<=Nnew; i++)
228  {
229    s = s+"1,";
230  }
231  s[size(s)] = ";";
232  execute(s);
233  kill s;
234  tmp     = 0;
235  tmp[1]  = "dp";  //string
236  tmp[2]  = iv;    //intvec
237  Lord[1] = tmp;
238  tmp[1]  = "C";
239  iv      = 0;
240  tmp[2]  = iv;
241  Lord[2] = tmp;
242  tmp     = 0;
243  L[3]    = Lord;
244  // we are done with the list
245  // Add: Plural part
246  def @R2 = ring(L);
247  setring @R2;
248  matrix @D[Nnew][Nnew];
249  for (i=1; i<=N; i++)
250  {
251    @D[i,N+i]=1;
252  }
253  ncalgebra(1,@D);
254  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
255  dbprint(ppl-1, @R2);
256  ideal K = imap(@R,K);
257  option(redSB);
258  //dbprint(ppl,"// -2-2- the final cosmetic std");
259  //K = engine(K,eng);  //std does the job too
260  // total cleanup
261  kill @R;
262  ideal LD = K;
263  export LD;
264  return(@R2);
265}
266example
267{
268  "EXAMPLE:"; echo = 2;
269  ring r = 0,(x,y,z,w),Dp;
270  poly F = x^3+y^3+z^2*w;
271  printlevel = 0;
272  def A = ALTannfsBM(F);
273  setring A;
274  LD;
275}
276
277proc bernsteinBM(poly F, list #)
278"USAGE:  bernsteinBM(f [,eng]);  f a poly, eng an optional int
279RETURN:  list of roots of the Bernstein polynomial b and its multiplicies
280PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface, defined by f, according to the algorithm by Briancon and Maisonobe
281NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
282@*       otherwise, and by default @code{slimgb} is used.
283@*       If printlevel=1, progress debug messages will be printed,
284@*       if printlevel>=2, all the debug messages will be printed.
285EXAMPLE: example bernsteinBM; shows examples
286"
287{
288  int eng = 0;
289  if ( size(#)>0 )
290  {
291    if ( typeof(#[1]) == "int" )
292    {
293      eng = int(#[1]);
294    }
295  }
296  // returns a list with a ring and an ideal LD in it
297  int ppl = printlevel-voice+2;
298  //  printf("plevel :%s, voice: %s",printlevel,voice);
299  def save = basering;
300  int N = nvars(basering);
301  int Nnew = 2*N+2;
302  int i,j;
303  string s;
304  list RL = ringlist(basering);
305  list L, Lord;
306  list tmp;
307  intvec iv;
308  L[1] = RL[1];  //char
309  L[4] = RL[4];  //char, minpoly
310  // check whether vars have admissible names
311  list Name  = RL[2];
312  list RName;
313  RName[1] = "t";
314  RName[2] = "s";
315  for (i=1; i<=N; i++)
316  {
317    for(j=1; j<=size(RName); j++)
318    {
319      if (Name[i] == RName[j])
320      {
321        ERROR("Variable names should not include t,s");
322      }
323    }
324  }
325  // now, create the names for new vars
326  list DName;
327  for (i=1; i<=N; i++)
328  {
329    DName[i] = "D"+Name[i];  //concat
330  }
331  tmp[1] = "t";
332  tmp[2] = "s";
333  list NName = tmp + Name + DName;
334  L[2]   = NName;
335  // Name, Dname will be used further
336  kill NName;
337  // block ord (lp(2),dp);
338  tmp[1]  = "lp"; // string
339  iv      = 1,1;
340  tmp[2]  = iv; //intvec
341  Lord[1] = tmp;
342  // continue with dp 1,1,1,1...
343  tmp[1]  = "dp"; // string
344  s       = "iv=";
345  for (i=1; i<=Nnew; i++)
346  {
347    s = s+"1,";
348  }
349  s[size(s)]= ";";
350  execute(s);
351  kill s;
352  tmp[2]    = iv;
353  Lord[2]   = tmp;
354  tmp[1]    = "C";
355  iv        = 0;
356  tmp[2]    = iv;
357  Lord[3]   = tmp;
358  tmp       = 0;
359  L[3]      = Lord;
360  // we are done with the list
361  def @R = ring(L);
362  setring @R;
363  matrix @D[Nnew][Nnew];
364  @D[1,2]=t;
365  for(i=1; i<=N; i++)
366  {
367    @D[2+i,N+2+i]=1;
368  }
369  // L[5] = matrix(UpOneMatrix(Nnew));
370  // L[6] = @D;
371  ncalgebra(1,@D);
372  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
373  dbprint(ppl-1, @R);
374  // create the ideal I
375  poly  F = imap(save,F);
376  ideal I = t*F+s;
377  poly p;
378  for(i=1; i<=N; i++)
379  {
380    p = t;  //t
381    p = diff(F,var(2+i))*p;
382    I = I, var(N+2+i) + p;
383  }
384  // -------- the ideal I is ready ----------
385  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
386  dbprint(ppl-1, I);
387  ideal J = engine(I,eng);
388  ideal K = nselect(J,1);
389  kill I,J;
390  dbprint(ppl,"// -1-3- t is eliminated");
391  dbprint(ppl-1, K);  //K is without t
392  // ----------- the ring @R2 ------------
393  // _x, _Dx,s;  elim.ord for _x,_Dx.
394  // keep: N, i,j,s, tmp, RL
395  setring save;
396  Nnew = 2*N+1;
397  kill Lord, tmp, iv, RName;
398  list Lord, tmp;
399  intvec iv;
400  L[1] = RL[1];
401  L[4] = RL[4];  //char, minpoly
402  // check whether vars hava admissible names -> done earlier
403  // now, create the names for new var
404  tmp[1] = "s";
405  // DName is defined earlier
406  list NName = Name + DName + tmp;
407  L[2] = NName;
408  tmp = 0;
409  // block ord (dp(N),dp);
410  string s = "iv=";
411  for (i=1; i<=Nnew-1; i++)
412  {
413    s = s+"1,";
414  }
415  s[size(s)]=";";
416  execute(s);
417  tmp[1] = "dp";  //string
418  tmp[2] = iv;    //intvec
419  Lord[1] = tmp;
420  // continue with dp 1,1,1,1...
421  tmp[1] = "dp";  //string
422  s[size(s)] = ",";
423  s = s+"1;";
424  execute(s);
425  kill s;
426  kill NName;
427  tmp[2]  = iv;
428  Lord[2] = tmp;
429  tmp[1]  = "C";
430  iv      = 0;
431  tmp[2]  = iv;
432  Lord[3] = tmp;
433  tmp     = 0;
434  L[3]    = Lord;
435  // we are done with the list. Now add a Plural part
436  def @R2 = ring(L);
437  setring @R2;
438  matrix @D[Nnew][Nnew];
439  for (i=1; i<=N; i++)
440  {
441    @D[i,N+i]=1;
442  }
443  ncalgebra(1,@D);
444  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
445  dbprint(ppl-1, @R2);
446  ideal MM = maxideal(1);
447  MM = 0,s,MM;
448  map R01 = @R, MM;
449  ideal K = R01(K);
450  kill @R, R01;
451  poly F = imap(save,F);
452  K = K,F;
453  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
454  dbprint(ppl-1, K);
455  ideal M = engine(K,eng);
456  ideal K2 = nselect(M,1,Nnew-1);
457  kill K,M;
458  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
459  dbprint(ppl-1, K2);
460  // the ring @R3 and the search for minimal negative int s
461  ring @R3 = 0,s,dp;
462  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
463  ideal K3 = imap(@R2,K2);
464  kill @R2;
465  poly p = K3[1];
466  dbprint(ppl,"// -3-2- factorization");
467  list P = factorize(p);          //with constants and multiplicities
468  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
469  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
470  {
471    bs[i-1] = P[1][i];
472    m[i-1] = P[2][i];
473  }
474  // "--------- b-function factorizes into ---------";  P;
475  //int sP = minIntRoot(bs,1);
476  //dbprint(ppl,"// -3-3- minimal interger root found");
477  //dbprint(ppl-1, sP);
478  // convert factors to a list of their roots and multiplicities
479  bs =  normalize(bs);
480  bs = -subst(bs,s,0);
481  setring save;
482  ideal bs = imap(@R3,bs);
483  kill @R3;
484  list BS = bs,m;
485  return(BS);
486}
487example
488{
489  "EXAMPLE:"; echo = 2;
490  ring r = 0,(x,y,z,w),Dp;
491  poly F = x^3+y^3+z^2*w;
492  printlevel = 0;
493  bernsteinBM(F);
494}
495
496// some changes
497proc annfsBM (poly F, list #)
498"USAGE:  annfsBM(f [,eng]);  f a poly, eng an optional int
499RETURN:  ring
500PURPOSE: compute the D-module structure of basering[f^s], according
501to the algorithm by Briancon and Maisonobe
502NOTE:    activate this ring with the @code{setring} command. In this ring,
503@*       - the ideal LD is the needed D-mod structure,
504@*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
505@*       If eng <>0, @code{std} is used for Groebner basis computations,
506@*       otherwise, and by default @code{slimgb} is used.
507@*       If printlevel=1, progress debug messages will be printed,
508@*       if printlevel>=2, all the debug messages will be printed.
509EXAMPLE: example annfsBM; shows examples
510"
511{
512  int eng = 0;
513  if ( size(#)>0 )
514  {
515    if ( typeof(#[1]) == "int" )
516    {
517      eng = int(#[1]);
518    }
519  }
520  // returns a list with a ring and an ideal LD in it
521  int ppl = printlevel-voice+2;
522  //  printf("plevel :%s, voice: %s",printlevel,voice);
523  def save = basering;
524  int N = nvars(basering);
525  int Nnew = 2*N+2;
526  int i,j;
527  string s;
528  list RL = ringlist(basering);
529  list L, Lord;
530  list tmp;
531  intvec iv;
532  L[1] = RL[1];  //char
533  L[4] = RL[4];  //char, minpoly
534  // check whether vars have admissible names
535  list Name  = RL[2];
536  list RName;
537  RName[1] = "t";
538  RName[2] = "s";
539  for (i=1; i<=N; i++)
540  {
541    for(j=1; j<=size(RName); j++)
542    {
543      if (Name[i] == RName[j])
544      {
545        ERROR("Variable names should not include t,s");
546      }
547    }
548  }
549  // now, create the names for new vars
550  list DName;
551  for (i=1; i<=N; i++)
552  {
553    DName[i] = "D"+Name[i];  //concat
554  }
555  tmp[1] = "t";
556  tmp[2] = "s";
557  list NName = tmp + Name + DName;
558  L[2]   = NName;
559  // Name, Dname will be used further
560  kill NName;
561  // block ord (lp(2),dp);
562  tmp[1]  = "lp"; // string
563  iv      = 1,1;
564  tmp[2]  = iv; //intvec
565  Lord[1] = tmp;
566  // continue with dp 1,1,1,1...
567  tmp[1]  = "dp"; // string
568  s       = "iv=";
569  for (i=1; i<=Nnew; i++)
570  {
571    s = s+"1,";
572  }
573  s[size(s)]= ";";
574  execute(s);
575  kill s;
576  tmp[2]    = iv;
577  Lord[2]   = tmp;
578  tmp[1]    = "C";
579  iv        = 0;
580  tmp[2]    = iv;
581  Lord[3]   = tmp;
582  tmp       = 0;
583  L[3]      = Lord;
584  // we are done with the list
585  def @R = ring(L);
586  setring @R;
587  matrix @D[Nnew][Nnew];
588  @D[1,2]=t;
589  for(i=1; i<=N; i++)
590  {
591    @D[2+i,N+2+i]=1;
592  }
593  // L[5] = matrix(UpOneMatrix(Nnew));
594  // L[6] = @D;
595  ncalgebra(1,@D);
596  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
597  dbprint(ppl-1, @R);
598  // create the ideal I
599  poly  F = imap(save,F);
600  ideal I = t*F+s;
601  poly p;
602  for(i=1; i<=N; i++)
603  {
604    p = t;  //t
605    p = diff(F,var(2+i))*p;
606    I = I, var(N+2+i) + p;
607  }
608  // -------- the ideal I is ready ----------
609  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
610  dbprint(ppl-1, I);
611  ideal J = engine(I,eng);
612  ideal K = nselect(J,1);
613  kill I,J;
614  dbprint(ppl,"// -1-3- t is eliminated");
615  dbprint(ppl-1, K);  //K is without t
616  setring save;
617  // ----------- the ring @R2 ------------
618  // _x, _Dx,s;  elim.ord for _x,_Dx.
619  // keep: N, i,j,s, tmp, RL
620  Nnew = 2*N+1;
621  kill Lord, tmp, iv, RName;
622  list Lord, tmp;
623  intvec iv;
624  L[1] = RL[1];
625  L[4] = RL[4];  //char, minpoly
626  // check whether vars hava admissible names -> done earlier
627  // now, create the names for new var
628  tmp[1] = "s";
629  // DName is defined earlier
630  list NName = Name + DName + tmp;
631  L[2] = NName;
632  tmp = 0;
633  // block ord (dp(N),dp);
634  string s = "iv=";
635  for (i=1; i<=Nnew-1; i++)
636  {
637    s = s+"1,";
638  }
639  s[size(s)]=";";
640  execute(s);
641  tmp[1] = "dp";  //string
642  tmp[2] = iv;    //intvec
643  Lord[1] = tmp;
644  // continue with dp 1,1,1,1...
645  tmp[1] = "dp";  //string
646  s[size(s)] = ",";
647  s = s+"1;";
648  execute(s);
649  kill s;
650  kill NName;
651  tmp[2]  = iv;
652  Lord[2] = tmp;
653  tmp[1]  = "C";
654  iv      = 0;
655  tmp[2]  = iv;
656  Lord[3] = tmp;
657  tmp     = 0;
658  L[3]    = Lord;
659  // we are done with the list. Now add a Plural part
660  def @R2 = ring(L);
661  setring @R2;
662  matrix @D[Nnew][Nnew];
663  for (i=1; i<=N; i++)
664  {
665    @D[i,N+i]=1;
666  }
667  ncalgebra(1,@D);
668  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
669  dbprint(ppl-1, @R2);
670  ideal MM = maxideal(1);
671  MM = 0,s,MM;
672  map R01 = @R, MM;
673  ideal K = R01(K);
674  poly F = imap(save,F);
675  K = K,F;
676  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
677  dbprint(ppl-1, K);
678  ideal M = engine(K,eng);
679  ideal K2 = nselect(M,1,Nnew-1);
680  kill K,M;
681  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
682  dbprint(ppl-1, K2);
683  // the ring @R3 and the search for minimal negative int s
684  ring @R3 = 0,s,dp;
685  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
686  ideal K3 = imap(@R2,K2);
687  poly p = K3[1];
688  dbprint(ppl,"// -3-2- factorization");
689  list P = factorize(p);          //with constants and multiplicities
690  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
691  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
692  {
693    bs[i-1] = P[1][i];
694    m[i-1] = P[2][i];
695  }
696  // "--------- b-function factorizes into ---------";  P;
697  int sP = minIntRoot(bs,1);
698  dbprint(ppl,"// -3-3- minimal interger root found");
699  dbprint(ppl-1, sP);
700  // convert factors to a list of their roots
701  bs = normalize(bs);
702  bs = -subst(bs,s,0);
703  list BS = bs,m;
704  //TODO: sort BS!
705  // --------- substitute s found in the ideal ---------
706  // --------- going back to @R and substitute ---------
707  setring @R;
708  ideal K2 = subst(K,s,sP);
709  kill K;
710  // create the ordinary Weyl algebra and put the result into it,
711  // thus creating the ring @R4
712  // keep: N, i,j,s, tmp, RL
713  setring save;
714  Nnew = 2*N;
715  // list RL = ringlist(save);  //is defined earlier
716  kill Lord, tmp, iv;
717  L = 0;
718  list Lord, tmp;
719  intvec iv;
720  L[1] = RL[1];
721  L[4] = RL[4];  //char, minpoly
722  // check whether vars have admissible names -> done earlier
723  // list Name = RL[2]M
724  // DName is defined earlier
725  list NName = Name + DName;
726  L[2] = NName;
727  // dp ordering;
728  string s = "iv=";
729  for (i=1; i<=Nnew; i++)
730  {
731    s = s+"1,";
732  }
733  s[size(s)] = ";";
734  execute(s);
735  kill s;
736  tmp     = 0;
737  tmp[1]  = "dp";  //string
738  tmp[2]  = iv;    //intvec
739  Lord[1] = tmp;
740  tmp[1]  = "C";
741  iv      = 0;
742  tmp[2]  = iv;
743  Lord[2] = tmp;
744  tmp     = 0;
745  L[3]    = Lord;
746  // we are done with the list
747  // Add: Plural part
748  def @R4 = ring(L);
749  setring @R4;
750  matrix @D[Nnew][Nnew];
751  for (i=1; i<=N; i++)
752  {
753    @D[i,N+i]=1;
754  }
755  ncalgebra(1,@D);
756  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx) is ready");
757  dbprint(ppl-1, @R4);
758  ideal K4 = imap(@R,K2);
759  option(redSB);
760  dbprint(ppl,"// -4-2- the final cosmetic std");
761  K4 = engine(K4,eng);  //std does the job too
762  // total cleanup
763  kill @R;
764  kill @R2;
765  list BS = imap(@R3,BS);
766  export BS;
767  kill @R3;
768  ideal LD = K4;
769  export LD;
770  return(@R4);
771}
772example
773{
774  "EXAMPLE:"; echo = 2;
775  ring r = 0,(x,y,z),Dp;
776  poly F = x^3+y^3+z^3;
777  printlevel = 0;
778  def A = annfsBM(F);
779  setring A;
780  LD;
781  BS;
782}
783
784proc operatorBM(poly F, list #)
785"USAGE:  operatorBM(f [,eng]);  f a poly, eng an optional int
786RETURN:  ring
787PURPOSE: compute the B-operator and other relevant data for Ann F^s, according to the algorithm by Briancon and Maisonobe
788NOTE:    activate this ring with the @code{setring} command. In this ring D[s]
789@*       - the polynomial F is the same as the input,
790@*       - the ideal LD is the annihilator of f^s in Dn[s],
791@*       - the ideal LD0 is the needed D-mod structure, where LD0 = LD|s=s0,
792@*       - the polynomial bs is the global Bernstein polynomial of f in the variable s,
793@*       - the list BS contains all the roots with multiplicities of the global Bernstein polynomial of f,
794@*       - the polynomial PS is an operator in Dn[s] such that PS*f^(s+1) = bs*f^s.
795@*       If eng <>0, @code{std} is used for Groebner basis computations,
796@*       otherwise and by default @code{slimgb} is used.
797@*       If printlevel=1, progress debug messages will be printed,
798@*       if printlevel>=2, all the debug messages will be printed.
799EXAMPLE: example operatorBM; shows examples
800"
801{
802  int eng = 0;
803  if ( size(#)>0 )
804  {
805    if ( typeof(#[1]) == "int" )
806    {
807      eng = int(#[1]);
808    }
809  }
810  // returns a list with a ring and an ideal LD in it
811  int ppl = printlevel-voice+2;
812  //  printf("plevel :%s, voice: %s",printlevel,voice);
813  def save = basering;
814  int N = nvars(basering);
815  int Nnew = 2*N+2;
816  int i,j;
817  string s;
818  list RL = ringlist(basering);
819  list L, Lord;
820  list tmp;
821  intvec iv;
822  L[1] = RL[1];  //char
823  L[4] = RL[4];  //char, minpoly
824  // check whether vars have admissible names
825  list Name  = RL[2];
826  list RName;
827  RName[1] = "t";
828  RName[2] = "s";
829  for (i=1; i<=N; i++)
830  {
831    for(j=1; j<=size(RName); j++)
832    {
833      if (Name[i] == RName[j])
834      {
835        ERROR("Variable names should not include t,s");
836      }
837    }
838  }
839  // now, create the names for new vars
840  list DName;
841  for (i=1; i<=N; i++)
842  {
843    DName[i] = "D"+Name[i];  //concat
844  }
845  tmp[1] = "t";
846  tmp[2] = "s";
847  list NName = tmp + Name + DName;
848  L[2]   = NName;
849  // Name, Dname will be used further
850  kill NName;
851  // block ord (lp(2),dp);
852  tmp[1]  = "lp"; // string
853  iv      = 1,1;
854  tmp[2]  = iv; //intvec
855  Lord[1] = tmp;
856  // continue with dp 1,1,1,1...
857  tmp[1]  = "dp"; // string
858  s       = "iv=";
859  for (i=1; i<=Nnew; i++)
860  {
861    s = s+"1,";
862  }
863  s[size(s)]= ";";
864  execute(s);
865  kill s;
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
875  def @R = ring(L);
876  setring @R;
877  matrix @D[Nnew][Nnew];
878  @D[1,2]=t;
879  for(i=1; i<=N; i++)
880  {
881    @D[2+i,N+2+i]=1;
882  }
883  // L[5] = matrix(UpOneMatrix(Nnew));
884  // L[6] = @D;
885  ncalgebra(1,@D);
886  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
887  dbprint(ppl-1, @R);
888  // create the ideal I
889  poly  F = imap(save,F);
890  ideal I = t*F+s;
891  poly p;
892  for(i=1; i<=N; i++)
893  {
894    p = t;  //t
895    p = diff(F,var(2+i))*p;
896    I = I, var(N+2+i) + p;
897  }
898  // -------- the ideal I is ready ----------
899  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
900  dbprint(ppl-1, I);
901  ideal J = engine(I,eng);
902  ideal K = nselect(J,1);
903  kill I,J;
904  dbprint(ppl,"// -1-3- t is eliminated");
905  dbprint(ppl-1, K);  //K is without t
906  setring save;
907  // ----------- the ring @R2 ------------
908  // _x, _Dx,s;  elim.ord for _x,_Dx.
909  // keep: N, i,j,s, tmp, RL
910  Nnew = 2*N+1;
911  kill Lord, tmp, iv, RName;
912  list Lord, tmp;
913  intvec iv;
914  L[1] = RL[1];
915  L[4] = RL[4];  //char, minpoly
916  // check whether vars hava admissible names -> done earlier
917  // now, create the names for new var
918  tmp[1] = "s";
919  // DName is defined earlier
920  list NName = Name + DName + tmp;
921  L[2] = NName;
922  tmp = 0;
923  // block ord (dp(N),dp);
924  string s = "iv=";
925  for (i=1; i<=Nnew-1; i++)
926  {
927    s = s+"1,";
928  }
929  s[size(s)]=";";
930  execute(s);
931  tmp[1] = "dp";  //string
932  tmp[2] = iv;    //intvec
933  Lord[1] = tmp;
934  // continue with dp 1,1,1,1...
935  tmp[1] = "dp";  //string
936  s[size(s)] = ",";
937  s = s+"1;";
938  execute(s);
939  kill s;
940  kill NName;
941  tmp[2]  = iv;
942  Lord[2] = tmp;
943  tmp[1]  = "C";
944  iv      = 0;
945  tmp[2]  = iv;
946  Lord[3] = tmp;
947  tmp     = 0;
948  L[3]    = Lord;
949  // we are done with the list. Now add a Plural part
950  def @R2 = ring(L);
951  setring @R2;
952  matrix @D[Nnew][Nnew];
953  for (i=1; i<=N; i++)
954  {
955    @D[i,N+i]=1;
956  }
957  ncalgebra(1,@D);
958  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
959  dbprint(ppl-1, @R2);
960  ideal MM = maxideal(1);
961  MM = 0,s,MM;
962  map R01 = @R, MM;
963  ideal K = R01(K);
964  poly F = imap(save,F);
965  K = K,F;
966  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
967  dbprint(ppl-1, K);
968  ideal M = engine(K,eng);
969  ideal K2 = nselect(M,1,Nnew-1);
970  kill K,M;
971  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
972  dbprint(ppl-1, K2);
973  // the ring @R3 and the search for minimal negative int s
974  ring @R3 = 0,s,dp;
975  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
976  ideal K3 = imap(@R2,K2);
977  kill @R2;
978  poly p = K3[1];
979  dbprint(ppl,"// -3-2- factorization");
980  list P = factorize(p);          //with constants and multiplicities
981  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
982  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
983  {
984    bs[i-1] = P[1][i];
985    m[i-1]  = P[2][i];
986  }
987  // "--------- b-function factorizes into ---------";  P;
988  int sP = minIntRoot(bs,1);
989  dbprint(ppl,"// -3-3- minimal interger root found");
990  dbprint(ppl-1, sP);
991  // convert factors to a list of their roots with multiplicities
992  bs = normalize(bs);
993  bs = -subst(bs,s,0);
994  list BS = bs,m;
995  //TODO: sort BS!
996  // --------- substitute s found in the ideal ---------
997  // --------- going back to @R and substitute ---------
998  setring @R;
999  ideal K2 = subst(K,s,sP);
1000  // create Dn[s], where Dn is the ordinary Weyl algebra, and put the result into it,
1001  // thus creating the ring @R4
1002  // keep: N, i,j,s, tmp, RL
1003  setring save;
1004  Nnew = 2*N+1;
1005  // list RL = ringlist(save);  //is defined earlier
1006  kill Lord, tmp, iv;
1007  L = 0;
1008  list Lord, tmp;
1009  intvec iv;
1010  L[1] = RL[1];
1011  L[4] = RL[4];  //char, minpoly
1012  // check whether vars have admissible names -> done earlier
1013  // list Name = RL[2]
1014  // DName is defined earlier
1015  tmp[1] = "s";
1016  list NName = Name + DName + tmp;
1017  L[2] = NName;
1018  // dp ordering;
1019  string s = "iv=";
1020  for (i=1; i<=Nnew; i++)
1021  {
1022    s = s+"1,";
1023  }
1024  s[size(s)] = ";";
1025  execute(s);
1026  kill s;
1027  tmp     = 0;
1028  tmp[1]  = "dp";  //string
1029  tmp[2]  = iv;    //intvec
1030  Lord[1] = tmp;
1031  tmp[1]  = "C";
1032  iv      = 0;
1033  tmp[2]  = iv;
1034  Lord[2] = tmp;
1035  tmp     = 0;
1036  L[3]    = Lord;
1037  // we are done with the list
1038  // Add: Plural part
1039  def @R4 = ring(L);
1040  setring @R4;
1041  matrix @D[Nnew][Nnew];
1042  for (i=1; i<=N; i++)
1043  {
1044    @D[i,N+i]=1;
1045  }
1046  ncalgebra(1,@D);
1047  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx,s) is ready");
1048  dbprint(ppl-1, @R4);
1049  ideal LD0 = imap(@R,K2);
1050  ideal LD  = imap(@R,K);
1051  kill @R;
1052  poly bs = imap(@R3,p);
1053  list BS = imap(@R3,BS);
1054  kill @R3;
1055  bs = normalize(bs);
1056  poly F = imap(save,F);
1057  dbprint(ppl,"// -4-2- starting the computation of PS via lift");
1058//better liftstd, I didn't knot it works also for Plural, liftslimgb?
1059// liftstd may give extra coeffs in the resulting ideal
1060  matrix T = lift(F+LD,bs);
1061  poly PS = T[1,1];
1062  dbprint(ppl,"// -4-3- an operator PS found, PS*f^(s+1) = b(s)*f^s");
1063  dbprint(ppl-1,PS);
1064  option(redSB);
1065  dbprint(ppl,"// -4-4- the final cosmetic std");
1066  LD0 = engine(LD0,eng);  //std does the job too
1067  LD  = engine(LD,eng);
1068  export F,LD,LD0,bs,BS,PS;
1069  return(@R4);
1070}
1071example
1072{
1073  "EXAMPLE:"; echo = 2;
1074  //  ring r = 0,(x,y,z,w),Dp;
1075  ring r = 0,(x,y,z),Dp;
1076  //  poly F = x^3+y^3+z^2*w;
1077  poly F = x^3+y^3+z^3;
1078  printlevel = 0;
1079  def A = operatorBM(F);
1080  setring A;
1081  F; // the original polynomial itself
1082  LD; // generic annihilator
1083  LD0; // annihilator
1084  bs; // normalized Bernstein poly
1085  BS; // root and multiplicities of the Bernstein poly
1086  PS; // the operator, s.t. PS*F^{s+1} = bs*F^s mod LD
1087  reduce(PS*F-bs,LD); // check the property of PS
1088}
1089
1090proc annfsParamBM (poly F, list #)
1091"USAGE:  annfsParamBM(f [,eng]);  f a poly, eng an optional int
1092RETURN:  ring
1093PURPOSE: compute the generic Ann F^s and exceptional parametric constellations of a polynomial with parametric coefficients, according to the algorithm by Briancon and Maisonobe
1094NOTE:    activate this ring with the @code{setring} command. In this ring,
1095@*       - the ideal LD is the D-module structure oa Ann F^s
1096@*       - the ideal Param contains the list of the special parameters.
1097@*       If eng <>0, @code{std} is used for Groebner basis computations,
1098@*       otherwise, and by default @code{slimgb} is used.
1099@*       If printlevel=1, progress debug messages will be printed,
1100@*       if printlevel>=2, all the debug messages will be printed.
1101EXAMPLE: example annfsParamBM; shows examples
1102"
1103{
1104  //PURPOSE: compute the list of all possible Bernstein-Sato polynomials for a polynomial with parametric coefficients, according to the algorithm by Briancon and Maisonobe
1105  // @*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
1106  // ***** not implented yet ****
1107  int eng = 0;
1108  if ( size(#)>0 )
1109  {
1110    if ( typeof(#[1]) == "int" )
1111    {
1112      eng = int(#[1]);
1113    }
1114  }
1115  // returns a list with a ring and an ideal LD in it
1116  int ppl = printlevel-voice+2;
1117  //  printf("plevel :%s, voice: %s",printlevel,voice);
1118  def save = basering;
1119  int N = nvars(basering);
1120  int Nnew = 2*N+2;
1121  int i,j;
1122  string s;
1123  list RL = ringlist(basering);
1124  list L, Lord;
1125  list tmp;
1126  intvec iv;
1127  L[1] = RL[1];  //char
1128  L[4] = RL[4];  //char, minpoly
1129  // check whether vars have admissible names
1130  list Name  = RL[2];
1131  list RName;
1132  RName[1] = "t";
1133  RName[2] = "s";
1134  for (i=1; i<=N; i++)
1135  {
1136    for(j=1; j<=size(RName); j++)
1137    {
1138      if (Name[i] == RName[j])
1139      {
1140        ERROR("Variable names should not include t,s");
1141      }
1142    }
1143  }
1144  // now, create the names for new vars
1145  list DName;
1146  for (i=1; i<=N; i++)
1147  {
1148    DName[i] = "D"+Name[i];  //concat
1149  }
1150  tmp[1] = "t";
1151  tmp[2] = "s";
1152  list NName = tmp + Name + DName;
1153  L[2]   = NName;
1154  // Name, Dname will be used further
1155  kill NName;
1156  // block ord (lp(2),dp);
1157  tmp[1]  = "lp"; // string
1158  iv      = 1,1;
1159  tmp[2]  = iv; //intvec
1160  Lord[1] = tmp;
1161  // continue with dp 1,1,1,1...
1162  tmp[1]  = "dp"; // string
1163  s       = "iv=";
1164  for (i=1; i<=Nnew; i++)
1165  {
1166    s = s+"1,";
1167  }
1168  s[size(s)]= ";";
1169  execute(s);
1170  kill s;
1171  tmp[2]    = iv;
1172  Lord[2]   = tmp;
1173  tmp[1]    = "C";
1174  iv        = 0;
1175  tmp[2]    = iv;
1176  Lord[3]   = tmp;
1177  tmp       = 0;
1178  L[3]      = Lord;
1179  // we are done with the list
1180  def @R = ring(L);
1181  setring @R;
1182  matrix @D[Nnew][Nnew];
1183  @D[1,2]=t;
1184  for(i=1; i<=N; i++)
1185  {
1186    @D[2+i,N+2+i]=1;
1187  }
1188  // L[5] = matrix(UpOneMatrix(Nnew));
1189  // L[6] = @D;
1190  ncalgebra(1,@D);
1191  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
1192  dbprint(ppl-1, @R);
1193  // create the ideal I
1194  poly  F = imap(save,F);
1195  ideal I = t*F+s;
1196  poly p;
1197  for(i=1; i<=N; i++)
1198  {
1199    p = t;  //t
1200    p = diff(F,var(2+i))*p;
1201    I = I, var(N+2+i) + p;
1202  }
1203  // -------- the ideal I is ready ----------
1204  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
1205  dbprint(ppl-1, I);
1206  ideal J = engine(I,eng);
1207  ideal K = nselect(J,1);
1208  dbprint(ppl,"// -1-3- t is eliminated");
1209  dbprint(ppl-1, K);  //K is without t
1210  // ----- looking for special parameters -----
1211  dbprint(ppl,"// -2-1- starting the computation of the transformation matrix (via lift)");
1212  J = normalize(J);
1213  matrix T = lift(I,J);  //try also with liftstd
1214  kill I,J;
1215  dbprint(ppl,"// -2-2- the transformation matrix has been computed");
1216  dbprint(ppl-1, T);  //T is the transformation matrix
1217  dbprint(ppl,"// -2-3- genericity does the job");
1218  list lParam = genericity(T);
1219  int ip = size(lParam);
1220  int cip;
1221  string sParam;
1222  if (sParam[1]=="-") { sParam=""; } //genericity returns "-"
1223  // if no parameters exist in a basering
1224  for (cip=1; cip <= ip; cip++)
1225  {
1226    sParam = sParam + "," +lParam[cip];
1227  }
1228  if (size(sParam) >=2)
1229  {
1230    sParam = sParam[2..size(sParam)]; // removes the 1st colon
1231  }
1232  export sParam;
1233  kill T;
1234  dbprint(ppl,"// -2-4- the special parameters has been computed");
1235  dbprint(ppl, sParam);
1236  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
1237  // thus creating the ring @R2
1238  // keep: N, i,j,s, tmp, RL
1239  setring save;
1240  Nnew = 2*N+1;
1241  // list RL = ringlist(save);  //is defined earlier
1242  kill Lord, tmp, iv;
1243  L = 0;
1244  list Lord, tmp;
1245  intvec iv;
1246  L[1] = RL[1];
1247  L[4] = RL[4];  //char, minpoly
1248  // check whether vars have admissible names -> done earlier
1249  // list Name = RL[2]M
1250  // DName is defined earlier
1251  tmp[1] = "s";
1252  list NName = Name + DName + tmp;
1253  L[2] = NName;
1254  // dp ordering;
1255  string s = "iv=";
1256  for (i=1; i<=Nnew; i++)
1257  {
1258    s = s+"1,";
1259  }
1260  s[size(s)] = ";";
1261  execute(s);
1262  kill s;
1263  tmp     = 0;
1264  tmp[1]  = "dp";  //string
1265  tmp[2]  = iv;    //intvec
1266  Lord[1] = tmp;
1267  tmp[1]  = "C";
1268  iv      = 0;
1269  tmp[2]  = iv;
1270  Lord[2] = tmp;
1271  tmp     = 0;
1272  L[3]    = Lord;
1273  // we are done with the list
1274  // Add: Plural part
1275  def @R2 = ring(L);
1276  setring @R2;
1277  matrix @D[Nnew][Nnew];
1278  for (i=1; i<=N; i++)
1279  {
1280    @D[i,N+i]=1;
1281  }
1282  ncalgebra(1,@D);
1283  dbprint(ppl,"// -3-1- the ring @R2(_x,_Dx,s) is ready");
1284  dbprint(ppl-1, @R2);
1285  ideal K = imap(@R,K);
1286  kill @R;
1287  option(redSB);
1288  dbprint(ppl,"// -3-2- the final cosmetic std");
1289  K = engine(K,eng);  //std does the job too
1290  ideal LD = K;
1291  export LD;
1292  if (sParam[1] == ",")
1293  {
1294    sParam = sParam[2..size(sParam)];
1295  }
1296  //  || ((sParam[1] == " ") && (sParam[2] == ",")))
1297  execute("ideal Param ="+sParam+";");
1298  export Param;
1299  kill sParam;
1300  return(@R2);
1301}
1302example
1303{
1304  "EXAMPLE:"; echo = 2;
1305  ring r = (0,a,b),(x,y),Dp;
1306  poly F = x^2 - (y-a)*(y-b);
1307  printlevel = 0;
1308  def A = annfsParamBM(F);  setring A;
1309  LD;
1310  Param;
1311  setring r;
1312  poly G = x2-(y-a)^2; // try the exceptional value b=a of parameters
1313  def B = annfsParamBM(G); setring B;
1314  LD;
1315  Param;
1316}
1317
1318// *** the following example is nice, but too complicated for the documentation ***
1319//   ring r = (0,a),(x,y,z),Dp;
1320//   poly F = x^4+y^4+z^2+a*x*y*z;
1321//   printlevel = 2; //0
1322//   def A = annfsParamBM(F);
1323//   setring A;
1324//   LD;
1325//   Param;
1326
1327
1328proc annfsBMI(ideal F, list #)
1329"USAGE:  annfsBMI(F [,eng]);  F an ideal, eng an optional int
1330RETURN:  ring
1331PURPOSE: compute the D-module structure of basering[f^s] where f = F[1]*..*F[P],
1332according to the algorithm by Briancon and Maisonobe.
1333NOTE:    activate this ring with the @code{setring} command. In this ring,
1334@*       - the ideal LD is the needed D-mod structure,
1335@*       - the list BS is the Bernstein ideal of a polynomial f = F[1]*..*F[P].
1336@*       If eng <>0, @code{std} is used for Groebner basis computations,
1337@*       otherwise, and by default @code{slimgb} is used.
1338@*       If printlevel=1, progress debug messages will be printed,
1339@*       if printlevel>=2, all the debug messages will be printed.
1340EXAMPLE: example annfsBMI; shows examples
1341"
1342{
1343  int eng = 0;
1344  if ( size(#)>0 )
1345  {
1346    if ( typeof(#[1]) == "int" )
1347    {
1348      eng = int(#[1]);
1349    }
1350  }
1351  // returns a list with a ring and an ideal LD in it
1352  int ppl = printlevel-voice+2;
1353  //  printf("plevel :%s, voice: %s",printlevel,voice);
1354  def save = basering;
1355  int N = nvars(basering);
1356  int P = size(F);  //if F has some generators which are zero, int P = ncols(I);
1357  int Nnew = 2*N+2*P;
1358  int i,j;
1359  string s;
1360  list RL = ringlist(basering);
1361  list L, Lord;
1362  list tmp;
1363  intvec iv;
1364  L[1] = RL[1];  //char
1365  L[4] = RL[4];  //char, minpoly
1366  // check whether vars have admissible names
1367  list Name  = RL[2];
1368  list RName;
1369  for (j=1; j<=P; j++)
1370  {
1371    RName[j] = "t("+string(j)+")";
1372    RName[j+P] = "s("+string(j)+")";
1373  }
1374  for(i=1; i<=N; i++)
1375  {
1376    for(j=1; j<=size(RName); j++)
1377    {
1378      if (Name[i] == RName[j])
1379      { ERROR("Variable names should not include t(i),s(i)"); }
1380    }
1381  }
1382  // now, create the names for new vars
1383  list DName;
1384  for(i=1; i<=N; i++)
1385  {
1386    DName[i] = "D"+Name[i];  //concat
1387  }
1388  list NName = RName + Name + DName;
1389  L[2]   = NName;
1390  // Name, Dname will be used further
1391  kill NName;
1392  // block ord (lp(P),dp);
1393  tmp[1] = "lp";  //string
1394  s      = "iv=";
1395  for (i=1; i<=2*P; i++)
1396  {
1397    s = s+"1,";
1398  }
1399  s[size(s)]= ";";
1400  execute(s);
1401  tmp[2] = iv;  //intvec
1402  Lord[1] = tmp;
1403  // continue with dp 1,1,1,1...
1404  tmp[1] = "dp";  //string
1405  s      = "iv=";
1406  for (i=1; i<=Nnew; i++)  //actually i<=2*N
1407  {
1408    s = s+"1,";
1409  }
1410  s[size(s)]= ";";
1411  execute(s);
1412  kill s;
1413  tmp[2]  = iv;
1414  Lord[2] = tmp;
1415  tmp[1]  = "C";
1416  iv      = 0;
1417  tmp[2]  = iv;
1418  Lord[3] = tmp;
1419  tmp     = 0;
1420  L[3]    = Lord;
1421  // we are done with the list
1422  def @R = ring(L);
1423  setring @R;
1424  matrix @D[Nnew][Nnew];
1425  for (i=1; i<=P; i++)
1426  {
1427    @D[i,i+P] = t(i);
1428  }
1429  for(i=1; i<=N; i++)
1430  {
1431    @D[2*P+i,2*P+N+i] = 1;
1432  }
1433  // L[5] = matrix(UpOneMatrix(Nnew));
1434  // L[6] = @D;
1435  ncalgebra(1,@D);
1436  dbprint(ppl,"// -1-1- the ring @R(_t,_s,_x,_Dx) is ready");
1437  dbprint(ppl-1, @R);
1438  // create the ideal I
1439  ideal  F = imap(save,F);
1440  ideal I = t(1)*F[1]+s(1);
1441  for (j=2; j<=P; j++)
1442  {
1443    I = I, t(j)*F[j]+s(j);
1444  }
1445  poly p,q;
1446  for (i=1; i<=N; i++)
1447  {
1448    p=0;
1449    for (j=1; j<=P; j++)
1450    {
1451      q = t(j);
1452      q = diff(F[j],var(2*P+i))*q;
1453      p = p + q;
1454    }
1455    I = I, var(2*P+N+i) + p;
1456  }
1457  // -------- the ideal I is ready ----------
1458  dbprint(ppl,"// -1-2- starting the elimination of "+string(t(1..P))+" in @R");
1459  dbprint(ppl-1, I);
1460  ideal J = engine(I,eng);
1461  ideal K = nselect(J,1,P);
1462  kill I,J;
1463  dbprint(ppl,"// -1-3- all t(i) are eliminated");
1464  dbprint(ppl-1, K);  //K is without t(i)
1465  // ----------- the ring @R2 ------------
1466  // _x, _Dx,s;  elim.ord for _x,_Dx.
1467  // keep: N, i,j,s, tmp, RL
1468  setring save;
1469  Nnew = 2*N+P;
1470  kill Lord, tmp, iv, RName;
1471  list Lord, tmp;
1472  intvec iv;
1473  L[1] = RL[1];  //char
1474  L[4] = RL[4];  //char, minpoly
1475  // check whether vars hava admissible names -> done earlier
1476  // now, create the names for new var
1477  for (j=1; j<=P; j++)
1478  {
1479    tmp[j] = "s("+string(j)+")";
1480  }
1481  // DName is defined earlier
1482  list NName = Name + DName + tmp;
1483  L[2] = NName;
1484  tmp = 0;
1485  // block ord (dp(N),dp);
1486  string s = "iv=";
1487  for (i=1; i<=Nnew-P; i++)
1488  {
1489    s = s+"1,";
1490  }
1491  s[size(s)]=";";
1492  execute(s);
1493  tmp[1] = "dp";  //string
1494  tmp[2] = iv;    //intvec
1495  Lord[1] = tmp;
1496  // continue with dp 1,1,1,1...
1497  tmp[1] = "dp";  //string
1498  s[size(s)] = ",";
1499  for (j=1; j<=P; j++)
1500  {
1501    s = s+"1,";
1502  }
1503  s[size(s)]=";";
1504  execute(s);
1505  kill s;
1506  kill NName;
1507  tmp[2]  = iv;
1508  Lord[2] = tmp;
1509  tmp[1]  = "C";
1510  iv      = 0;
1511  tmp[2]  = iv;
1512  Lord[3] = tmp;
1513  tmp     = 0;
1514  L[3]    = Lord;
1515  // we are done with the list. Now add a Plural part
1516  def @R2 = ring(L);
1517  setring @R2;
1518  matrix @D[Nnew][Nnew];
1519  for (i=1; i<=N; i++)
1520  {
1521    @D[i,N+i]=1;
1522  }
1523  ncalgebra(1,@D);
1524  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,_s) is ready");
1525  dbprint(ppl-1, @R2);
1526//  ideal MM = maxideal(1);
1527//  MM = 0,s,MM;
1528//  map R01 = @R, MM;
1529//  ideal K = R01(K);
1530  ideal F = imap(save,F);  // maybe ideal F = R01(I); ?
1531  ideal K = imap(@R,K);    // maybe ideal K = R01(I); ?
1532  poly f=1;
1533  for (j=1; j<=P; j++)
1534  {
1535    f = f*F[j];
1536  }
1537  K = K,f;       // to compute B (Bernstein-Sato ideal)
1538  //j=2;         // for example
1539  //K = K,F[j];  // to compute Bj (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
1540  //K = K,F;     // to compute Bsigma (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
1541  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
1542  dbprint(ppl-1, K);
1543  ideal M = engine(K,eng);
1544  ideal K2 = nselect(M,1,Nnew-P);
1545  kill K,M;
1546  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
1547  dbprint(ppl-1, K2);
1548  // the ring @R3 and factorize
1549  ring @R3 = 0,s(1..P),dp;
1550  dbprint(ppl,"// -3-1- the ring @R3(_s) is ready");
1551  ideal K3 = imap(@R2,K2);
1552  if (size(K3)==1)
1553  {
1554    poly p = K3[1];
1555    dbprint(ppl,"// -3-2- factorization");
1556    // Warning: now P is an integer
1557    list Q = factorize(p);         //with constants and multiplicities
1558    ideal bs; intvec m;
1559    for (i=2; i<=size(Q[1]); i++)  //we delete Q[1][1] and Q[2][1]
1560    {
1561      bs[i-1] = Q[1][i];
1562      m[i-1]  = Q[2][i];
1563    }
1564    //  "--------- Q-ideal factorizes into ---------";  list(bs,m);
1565    list BS = bs,m;
1566  }
1567  else
1568  {
1569    // conjecture: the Bernstein ideal is principal
1570    dbprint(ppl,"// -3-2- the Bernstein ideal is not principal");
1571    ideal BS = K3;
1572  }
1573  // create the ring @R4(_x,_Dx,_s) and put the result into it,
1574  // _x, _Dx,s;  ord "dp".
1575  // keep: N, i,j,s, tmp, RL
1576  setring save;
1577  Nnew = 2*N+P;
1578  // list RL = ringlist(save);  //is defined earlier
1579  kill Lord, tmp, iv;
1580  L = 0;
1581  list Lord, tmp;
1582  intvec iv;
1583  L[1] = RL[1];  //char
1584  L[4] = RL[4];  //char, minpoly
1585  // check whether vars hava admissible names -> done earlier
1586  // now, create the names for new var
1587  for (j=1; j<=P; j++)
1588  {
1589    tmp[j] = "s("+string(j)+")";
1590  }
1591  // DName is defined earlier
1592  list NName = Name + DName + tmp;
1593  L[2] = NName;
1594  tmp = 0;
1595  // dp ordering;
1596  string s = "iv=";
1597  for (i=1; i<=Nnew; i++)
1598  {
1599    s = s+"1,";
1600  }
1601  s[size(s)]=";";
1602  execute(s);
1603  kill s;
1604  kill NName;
1605  tmp[1] = "dp";  //string
1606  tmp[2] = iv;    //intvec
1607  Lord[1] = tmp;
1608  tmp[1]  = "C";
1609  iv      = 0;
1610  tmp[2]  = iv;
1611  Lord[2] = tmp;
1612  tmp     = 0;
1613  L[3]    = Lord;
1614  // we are done with the list. Now add a Plural part
1615  def @R4 = ring(L);
1616  setring @R4;
1617  matrix @D[Nnew][Nnew];
1618  for (i=1; i<=N; i++)
1619  {
1620    @D[i,N+i]=1;
1621  }
1622  ncalgebra(1,@D);
1623  dbprint(ppl,"// -4-1- the ring @R4i(_x,_Dx,_s) is ready");
1624  dbprint(ppl-1, @R4);
1625  ideal K4 = imap(@R,K);
1626  option(redSB);
1627  dbprint(ppl,"// -4-2- the final cosmetic std");
1628  K4 = engine(K4,eng);  //std does the job too
1629  // total cleanup
1630  kill @R;
1631  kill @R2;
1632  def BS = imap(@R3,BS);
1633  export BS;
1634  kill @R3;
1635  ideal LD = K4;
1636  export LD;
1637  return(@R4);
1638}
1639example
1640{
1641  "EXAMPLE:"; echo = 2;
1642  ring r = 0,(x,y),Dp;
1643  ideal F = x,y,x+y;
1644  printlevel = 0;
1645  def A = annfsBMI(F);
1646  setring A;
1647  LD;
1648  BS;
1649}
1650
1651proc annfsOT(poly F, list #)
1652"USAGE:  annfsOT(f [,eng]);  f a poly, eng an optional int
1653RETURN:  ring
1654PURPOSE: compute the D-module structure of basering[f^s], according
1655to the algorithm by Oaku and Takayama
1656NOTE:    activate this ring with the @code{setring} command. In this ring,
1657@*       - the ideal LD is the needed D-mod structure,
1658@*       - the list BS contains roots with multiplicities of a Bernstein polynomial of f.
1659@*       If eng <>0, @code{std} is used for Groebner basis computations,
1660@*       otherwise, and by default @code{slimgb} is used.
1661@*       If printlevel=1, progress debug messages will be printed,
1662@*       if printlevel>=2, all the debug messages will be printed.
1663EXAMPLE: example annfsOT; shows examples
1664"
1665{
1666  int eng = 0;
1667  if ( size(#)>0 )
1668  {
1669    if ( typeof(#[1]) == "int" )
1670    {
1671      eng = int(#[1]);
1672    }
1673  }
1674  // returns a list with a ring and an ideal LD in it
1675  int ppl = printlevel-voice+2;
1676  //  printf("plevel :%s, voice: %s",printlevel,voice);
1677  def save = basering;
1678  int N = nvars(basering);
1679  int Nnew = 2*(N+2);
1680  int i,j;
1681  string s;
1682  list RL = ringlist(basering);
1683  list L, Lord;
1684  list tmp;
1685  intvec iv;
1686  L[1] = RL[1]; // char
1687  L[4] = RL[4]; // char, minpoly
1688  // check whether vars have admissible names
1689  list Name  = RL[2];
1690  list RName;
1691  RName[1] = "u";
1692  RName[2] = "v";
1693  RName[3] = "t";
1694  RName[4] = "Dt";
1695  for(i=1;i<=N;i++)
1696  {
1697    for(j=1; j<=size(RName);j++)
1698    {
1699      if (Name[i] == RName[j])
1700      {
1701        ERROR("Variable names should not include u,v,t,Dt");
1702      }
1703    }
1704  }
1705  // now, create the names for new vars
1706  tmp[1]     = "u";
1707  tmp[2]     = "v";
1708  list UName = tmp;
1709  list DName;
1710  for(i=1;i<=N;i++)
1711  {
1712    DName[i] = "D"+Name[i]; // concat
1713  }
1714  tmp    =  0;
1715  tmp[1] = "t";
1716  tmp[2] = "Dt";
1717  list NName = UName +  tmp + Name + DName;
1718  L[2]   = NName;
1719  tmp    = 0;
1720  // Name, Dname will be used further
1721  kill UName;
1722  kill NName;
1723  // block ord (a(1,1),dp);
1724  tmp[1]  = "a"; // string
1725  iv      = 1,1;
1726  tmp[2]  = iv; //intvec
1727  Lord[1] = tmp;
1728  // continue with dp 1,1,1,1...
1729  tmp[1]  = "dp"; // string
1730  s       = "iv=";
1731  for(i=1;i<=Nnew;i++)
1732  {
1733    s = s+"1,";
1734  }
1735  s[size(s)]= ";";
1736  execute(s);
1737  tmp[2]    = iv;
1738  Lord[2]   = tmp;
1739  tmp[1]    = "C";
1740  iv        = 0;
1741  tmp[2]    = iv;
1742  Lord[3]   = tmp;
1743  tmp       = 0;
1744  L[3]      = Lord;
1745  // we are done with the list
1746  def @R = ring(L);
1747  setring @R;
1748  matrix @D[Nnew][Nnew];
1749  @D[3,4]=1;
1750  for(i=1; i<=N; i++)
1751  {
1752    @D[4+i,N+4+i]=1;
1753  }
1754  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
1755  //  L[5] = matrix(UpOneMatrix(Nnew));
1756  //  L[6] = @D;
1757  ncalgebra(1,@D);
1758  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
1759  dbprint(ppl-1, @R);
1760  // create the ideal I
1761  poly  F = imap(save,F);
1762  ideal I = u*F-t,u*v-1;
1763  poly p;
1764  for(i=1; i<=N; i++)
1765  {
1766    p = u*Dt; // u*Dt
1767    p = diff(F,var(4+i))*p;
1768    I = I, var(N+4+i) + p;
1769  }
1770  // -------- the ideal I is ready ----------
1771  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
1772  dbprint(ppl-1, I);
1773  ideal J = engine(I,eng);
1774  ideal K = nselect(J,1,2);
1775  dbprint(ppl,"// -1-3- u,v are eliminated");
1776  dbprint(ppl-1, K);  // K is without u,v
1777  setring save;
1778  // ------------ new ring @R2 ------------------
1779  // without u,v and with the elim.ord for t,Dt
1780  // tensored with the K[s]
1781  // keep: N, i,j,s, tmp, RL
1782  Nnew = 2*N+2+1;
1783  //  list RL = ringlist(save); // is defined earlier
1784  L = 0;  //  kill L;
1785  kill Lord, tmp, iv, RName;
1786  list Lord, tmp;
1787  intvec iv;
1788  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
1789  // check whether vars have admissible names -> done earlier
1790  //  list Name  = RL[2];
1791  list RName;
1792  RName[1] = "t";
1793  RName[2] = "Dt";
1794  // now, create the names for new var (here, s only)
1795  tmp[1]     = "s";
1796  // DName is defined earlier
1797  list NName = RName + Name + DName + tmp;
1798  L[2]   = NName;
1799  tmp    = 0;
1800  // block ord (a(1,1),dp);
1801  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
1802  Lord[1] = tmp;
1803  // continue with a(1,1,1,1)...
1804  tmp[1]  = "dp"; s  = "iv=";
1805  for(i=1; i<= Nnew; i++)
1806  {
1807    s = s+"1,";
1808  }
1809  s[size(s)]= ";";  execute(s);
1810  kill NName;
1811  tmp[2]    = iv;
1812  Lord[2]   = tmp;
1813  // extra block for s
1814  // tmp[1] = "dp"; iv = 1;
1815  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
1816  //  Lord[3]   = tmp;
1817  kill s;
1818  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
1819  Lord[3]   = tmp;   tmp = 0;
1820  L[3]      = Lord;
1821  // we are done with the list. Now, add a Plural part
1822  def @R2 = ring(L);
1823  setring @R2;
1824  matrix @D[Nnew][Nnew];
1825  @D[1,2] = 1;
1826  for(i=1; i<=N; i++)
1827  {
1828    @D[2+i,2+N+i] = 1;
1829  }
1830  ncalgebra(1,@D);
1831  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
1832  dbprint(ppl-1, @R2);
1833  ideal MM = maxideal(1);
1834  MM = 0,0,MM;
1835  map R01 = @R, MM;
1836  ideal K = R01(K);
1837  //  ideal K = imap(@R,K); // names of vars are important!
1838  poly G = t*Dt+s+1; // s is a variable here
1839  K = NF(K,std(G)),G;
1840  // -------- the ideal K_(@R2) is ready ----------
1841  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
1842  dbprint(ppl-1, K);
1843  ideal M  = engine(K,eng);
1844  ideal K2 = nselect(M,1,2);
1845  dbprint(ppl,"// -2-3- t,Dt are eliminated");
1846  dbprint(ppl-1, K2);
1847  //  dbprint(ppl-1+1," -2-4- std of K2");
1848  //  option(redSB);  option(redTail);  K2 = std(K2);
1849  //  K2; // without t,Dt, and with s
1850  // -------- the ring @R3 ----------
1851  // _x, _Dx, s; elim.ord for _x,_Dx.
1852  // keep: N, i,j,s, tmp, RL
1853  setring save;
1854  Nnew = 2*N+1;
1855  //  list RL = ringlist(save); // is defined earlier
1856  //  kill L;
1857  kill Lord, tmp, iv, RName;
1858  list Lord, tmp;
1859  intvec iv;
1860  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
1861  // check whether vars have admissible names -> done earlier
1862  //  list Name  = RL[2];
1863  // now, create the names for new var (here, s only)
1864  tmp[1]     = "s";
1865  // DName is defined earlier
1866  list NName = Name + DName + tmp;
1867  L[2]   = NName;
1868  tmp    = 0;
1869  // block ord (a(1,1...),dp);
1870  string  s = "iv=";
1871  for(i=1; i<=Nnew-1; i++)
1872  {
1873    s = s+"1,";
1874  }
1875  s[size(s)]= ";";
1876  execute(s);
1877  tmp[1]  = "a"; // string
1878  tmp[2]  = iv; //intvec
1879  Lord[1] = tmp;
1880  // continue with dp 1,1,1,1...
1881  tmp[1]  = "dp"; // string
1882  s[size(s)]=","; s= s+"1;";
1883  execute(s);
1884  kill s;
1885  kill NName;
1886  tmp[2]    = iv;
1887  Lord[2]   = tmp;
1888  tmp[1]    = "C";  iv  = 0;  tmp[2] = iv;
1889  Lord[3]   = tmp;  tmp = 0;
1890  L[3]      = Lord;
1891  // we are done with the list. Now add a Plural part
1892  def @R3 = ring(L);
1893  setring @R3;
1894  matrix @D[Nnew][Nnew];
1895  for(i=1; i<=N; i++)
1896  {
1897    @D[i,N+i]=1;
1898  }
1899  ncalgebra(1,@D);
1900  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
1901  dbprint(ppl-1, @R3);
1902  ideal MM = maxideal(1);
1903  MM = 0,0,MM;
1904  map R12 = @R2, MM;
1905  ideal K = R12(K2);
1906  poly  F = imap(save,F);
1907  K = K,F;
1908  dbprint(ppl,"// -3-2- starting the elimination of _x,_Dx in @R3");
1909  dbprint(ppl-1, K);
1910  ideal M = engine(K,eng);
1911  ideal K3 = nselect(M,1,Nnew-1);
1912  dbprint(ppl,"// -3-3-  _x,_Dx are eliminated in @R3");
1913  dbprint(ppl-1, K3);
1914  // the ring @R4  and the search for minimal negative int s
1915  ring @R4 = 0,(s),dp;
1916  dbprint(ppl,"// -4-1- the ring @R4 is ready");
1917  ideal K4 = imap(@R3,K3);
1918  poly p = K4[1];
1919  dbprint(ppl,"// -4-2- factorization");
1920////  ideal P = factorize(p,1);  // without constants and multiplicities
1921  list P = factorize(p);         // with constants and multiplicities
1922  ideal bs; intvec m;            // the Bernstein polynomial is monic, so we are not interested in constants
1923  for (i=2; i<=size(P[1]); i++)  // we delete P[1][1] and P[2][1]
1924  {
1925    bs[i-1] = P[1][i];
1926    m[i-1]  = P[2][i];
1927  }
1928  //  "------ b-function factorizes into ----------";  P;
1929////  int sP  = minIntRoot(P, 1);
1930  int sP = minIntRoot(bs,1);
1931  dbprint(ppl,"// -4-3- minimal integer root found");
1932  dbprint(ppl-1, sP);
1933  // convert factors to a list of their roots
1934  // assume all factors are linear
1935////  ideal BS = normalize(P);
1936////  BS = subst(BS,s,0);
1937////  BS = -BS;
1938  bs = normalize(bs);
1939  bs = subst(bs,s,0);
1940  bs = -bs;
1941  list BS = bs,m;
1942  // TODO: sort BS!
1943  // ------ substitute s found in the ideal ------
1944  // ------- going back to @R2 and substitute --------
1945  setring @R2;
1946  ideal K3 = subst(K2,s,sP);
1947  // create the ordinary Weyl algebra and put the result into it,
1948  // thus creating the ring @R5
1949  // keep: N, i,j,s, tmp, RL
1950  setring save;
1951  Nnew = 2*N;
1952  //  list RL = ringlist(save); // is defined earlier
1953  kill Lord, tmp, iv;
1954  L = 0;
1955  list Lord, tmp;
1956  intvec iv;
1957  L[1] = RL[1];   L[4] = RL[4]; // char, minpoly
1958  // check whether vars have admissible names -> done earlier
1959  //  list Name  = RL[2];
1960  // DName is defined earlier
1961  list NName = Name + DName;
1962  L[2]   = NName;
1963  // dp ordering;
1964  string   s       = "iv=";
1965  for(i=1;i<=Nnew;i++)
1966  {
1967    s = s+"1,";
1968  }
1969  s[size(s)]= ";";
1970  execute(s);
1971  tmp     = 0;
1972  tmp[1]  = "dp"; // string
1973  tmp[2]  = iv; //intvec
1974  Lord[1] = tmp;
1975  kill s;
1976  tmp[1]    = "C";
1977  iv        = 0;
1978  tmp[2]    = iv;
1979  Lord[2]   = tmp;
1980  tmp       = 0;
1981  L[3]      = Lord;
1982  // we are done with the list
1983  // Add: Plural part
1984  def @R5 = ring(L);
1985  setring @R5;
1986  matrix @D[Nnew][Nnew];
1987  for(i=1; i<=N; i++)
1988  {
1989    @D[i,N+i]=1;
1990  }
1991  ncalgebra(1,@D);
1992  dbprint(ppl,"// -5-1- the ring @R5 is ready");
1993  dbprint(ppl-1, @R5);
1994  ideal K5 = imap(@R2,K3);
1995  option(redSB);
1996  dbprint(ppl,"// -5-2- the final cosmetic std");
1997  K5 = engine(K5,eng); // std does the job too
1998  // total cleanup
1999  kill @R;
2000  kill @R2;
2001  kill @R3;
2002////  ideal BS = imap(@R4,BS);
2003  list BS = imap(@R4,BS);
2004  export BS;
2005  ideal LD = K5;
2006  kill @R4;
2007  export LD;
2008  return(@R5);
2009}
2010example
2011{
2012  "EXAMPLE:"; echo = 2;
2013  ring r = 0,(x,y,z),Dp;
2014  poly F = x^2+y^3+z^5;
2015  printlevel = 0;
2016  def A  = annfsOT(F);
2017  setring A;
2018  LD;
2019  BS;
2020}
2021
2022
2023proc SannfsOT(poly F, list #)
2024"USAGE:  SannfsOT(f [,eng]);  f a poly, eng an optional int
2025RETURN:  ring
2026PURPOSE: compute the D-module structure of basering[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
2027NOTE:    activate this ring with the @code{setring} command.
2028@*       In the ring D[s], the ideal LD is the needed D-mod structure.
2029@*       If eng <>0, @code{std} is used for Groebner basis computations,
2030@*       otherwise, and by default @code{slimgb} is used.
2031@*       If printlevel=1, progress debug messages will be printed,
2032@*       if printlevel>=2, all the debug messages will be printed.
2033EXAMPLE: example SannfsOT; shows examples
2034"
2035{
2036  int eng = 0;
2037  if ( size(#)>0 )
2038  {
2039    if ( typeof(#[1]) == "int" )
2040    {
2041      eng = int(#[1]);
2042    }
2043  }
2044  // returns a list with a ring and an ideal LD in it
2045  int ppl = printlevel-voice+2;
2046  //  printf("plevel :%s, voice: %s",printlevel,voice);
2047  def save = basering;
2048  int N = nvars(basering);
2049  int Nnew = 2*(N+2);
2050  int i,j;
2051  string s;
2052  list RL = ringlist(basering);
2053  list L, Lord;
2054  list tmp;
2055  intvec iv;
2056  L[1] = RL[1]; // char
2057  L[4] = RL[4]; // char, minpoly
2058  // check whether vars have admissible names
2059  list Name  = RL[2];
2060  list RName;
2061  RName[1] = "u";
2062  RName[2] = "v";
2063  RName[3] = "t";
2064  RName[4] = "Dt";
2065  for(i=1;i<=N;i++)
2066  {
2067    for(j=1; j<=size(RName);j++)
2068    {
2069      if (Name[i] == RName[j])
2070      {
2071        ERROR("Variable names should not include u,v,t,Dt");
2072      }
2073    }
2074  }
2075  // now, create the names for new vars
2076  tmp[1]     = "u";
2077  tmp[2]     = "v";
2078  list UName = tmp;
2079  list DName;
2080  for(i=1;i<=N;i++)
2081  {
2082    DName[i] = "D"+Name[i]; // concat
2083  }
2084  tmp    =  0;
2085  tmp[1] = "t";
2086  tmp[2] = "Dt";
2087  list NName = UName +  tmp + Name + DName;
2088  L[2]   = NName;
2089  tmp    = 0;
2090  // Name, Dname will be used further
2091  kill UName;
2092  kill NName;
2093  // block ord (a(1,1),dp);
2094  tmp[1]  = "a"; // string
2095  iv      = 1,1;
2096  tmp[2]  = iv; //intvec
2097  Lord[1] = tmp;
2098  // continue with dp 1,1,1,1...
2099  tmp[1]  = "dp"; // string
2100  s       = "iv=";
2101  for(i=1;i<=Nnew;i++)
2102  {
2103    s = s+"1,";
2104  }
2105  s[size(s)]= ";";
2106  execute(s);
2107  tmp[2]    = iv;
2108  Lord[2]   = tmp;
2109  tmp[1]    = "C";
2110  iv        = 0;
2111  tmp[2]    = iv;
2112  Lord[3]   = tmp;
2113  tmp       = 0;
2114  L[3]      = Lord;
2115  // we are done with the list
2116  def @R = ring(L);
2117  setring @R;
2118  matrix @D[Nnew][Nnew];
2119  @D[3,4]=1;
2120  for(i=1; i<=N; i++)
2121  {
2122    @D[4+i,N+4+i]=1;
2123  }
2124  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
2125  //  L[5] = matrix(UpOneMatrix(Nnew));
2126  //  L[6] = @D;
2127  ncalgebra(1,@D);
2128  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
2129  dbprint(ppl-1, @R);
2130  // create the ideal I
2131  poly  F = imap(save,F);
2132  ideal I = u*F-t,u*v-1;
2133  poly p;
2134  for(i=1; i<=N; i++)
2135  {
2136    p = u*Dt; // u*Dt
2137    p = diff(F,var(4+i))*p;
2138    I = I, var(N+4+i) + p;
2139  }
2140  // -------- the ideal I is ready ----------
2141  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
2142  dbprint(ppl-1, I);
2143  ideal J = engine(I,eng);
2144  ideal K = nselect(J,1,2);
2145  dbprint(ppl,"// -1-3- u,v are eliminated");
2146  dbprint(ppl-1, K);  // K is without u,v
2147
2148
2149  setring save;
2150  // ------------ new ring @R2 ------------------
2151  // without u,v and with the elim.ord for t,Dt
2152  // tensored with the K[s]
2153  // keep: N, i,j,s, tmp, RL
2154  Nnew = 2*N+2+1;
2155  //  list RL = ringlist(save); // is defined earlier
2156  L = 0;  //  kill L;
2157  kill Lord, tmp, iv, RName;
2158  list Lord, tmp;
2159  intvec iv;
2160  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
2161  // check whether vars have admissible names -> done earlier
2162  //  list Name  = RL[2];
2163  list RName;
2164  RName[1] = "t";
2165  RName[2] = "Dt";
2166  // now, create the names for new var (here, s only)
2167  tmp[1]     = "s";
2168  // DName is defined earlier
2169  list NName = RName + Name + DName + tmp;
2170  L[2]   = NName;
2171  tmp    = 0;
2172  // block ord (a(1,1),dp);
2173  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
2174  Lord[1] = tmp;
2175  // continue with a(1,1,1,1)...
2176  tmp[1]  = "dp"; s  = "iv=";
2177  for(i=1; i<= Nnew; i++)
2178  {
2179    s = s+"1,";
2180  }
2181  s[size(s)]= ";";  execute(s);
2182  kill NName;
2183  tmp[2]    = iv;
2184  Lord[2]   = tmp;
2185  // extra block for s
2186  // tmp[1] = "dp"; iv = 1;
2187  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
2188  //  Lord[3]   = tmp;
2189  kill s;
2190  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
2191  Lord[3]   = tmp;   tmp = 0;
2192  L[3]      = Lord;
2193  // we are done with the list. Now, add a Plural part
2194  def @R2 = ring(L);
2195  setring @R2;
2196  matrix @D[Nnew][Nnew];
2197  @D[1,2] = 1;
2198  for(i=1; i<=N; i++)
2199  {
2200    @D[2+i,2+N+i] = 1;
2201  }
2202  ncalgebra(1,@D);
2203  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
2204  dbprint(ppl-1, @R2);
2205  ideal MM = maxideal(1);
2206  MM = 0,0,MM;
2207  map R01 = @R, MM;
2208  ideal K = R01(K);
2209  //  ideal K = imap(@R,K); // names of vars are important!
2210  poly G = t*Dt+s+1; // s is a variable here
2211  K = NF(K,std(G)),G;
2212  // -------- the ideal K_(@R2) is ready ----------
2213  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
2214  dbprint(ppl-1, K);
2215  ideal M  = engine(K,eng);
2216  ideal K2 = nselect(M,1,2);
2217  dbprint(ppl,"// -2-3- t,Dt are eliminated");
2218  dbprint(ppl-1, K2);
2219  K2 = engine(K2,eng);
2220  setring save;
2221  // ----------- the ring @R3 ------------
2222  // _x, _Dx,s;  elim.ord for _x,_Dx.
2223  // keep: N, i,j,s, tmp, RL
2224  Nnew = 2*N+1;
2225  kill Lord, tmp, iv, RName;
2226  list Lord, tmp;
2227  intvec iv;
2228  L[1] = RL[1];
2229  L[4] = RL[4];  // char, minpoly
2230  // check whether vars hava admissible names -> done earlier
2231  // now, create the names for new var
2232  tmp[1] = "s";
2233  // DName is defined earlier
2234  list NName = Name + DName + tmp;
2235  L[2] = NName;
2236  tmp = 0;
2237  // block ord (dp(N),dp);
2238  string s = "iv=";
2239  for (i=1; i<=Nnew-1; i++)
2240  {
2241    s = s+"1,";
2242  }
2243  s[size(s)]=";";
2244  execute(s);
2245  tmp[1] = "dp";  // string
2246  tmp[2] = iv;   // intvec
2247  Lord[1] = tmp;
2248  // continue with dp 1,1,1,1...
2249  tmp[1] = "dp";  // string
2250  s[size(s)] = ",";
2251  s = s+"1;";
2252  execute(s);
2253  kill s;
2254  kill NName;
2255  tmp[2]      = iv;
2256  Lord[2]     = tmp;
2257  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
2258  Lord[3]     = tmp;  tmp = 0;
2259  L[3]        = Lord;
2260  // we are done with the list. Now add a Plural part
2261  def @R3 = ring(L);
2262  setring @R3;
2263  matrix @D[Nnew][Nnew];
2264  for (i=1; i<=N; i++)
2265  {
2266    @D[i,N+i]=1;
2267  }
2268  ncalgebra(1,@D);
2269  dbprint(ppl,"//  -2-1- the ring @R3(_x,_Dx,s) is ready");
2270  dbprint(ppl-1, @R3);
2271  ideal MM = maxideal(1);
2272  MM = 0,s,MM;
2273  map R01 = @R2, MM;
2274  ideal K2 = R01(K2);
2275  // total cleanup
2276  ideal LD = K2;
2277  // make leadcoeffs positive
2278  for (i=1; i<= ncols(LD); i++)
2279  {
2280    if (leadcoef(LD[i]) <0 )
2281    {
2282      LD[i] = -LD[i];
2283    }
2284  }
2285  export LD;
2286  kill @R;
2287  kill @R2;
2288  return(@R3);
2289}
2290example
2291{
2292  "EXAMPLE:"; echo = 2;
2293  ring r = 0,(x,y,z),Dp;
2294  poly F = x^3+y^3+z^3;
2295  printlevel = 0;
2296  def A  = SannfsOT(F);
2297  setring A;
2298  LD;
2299}
2300
2301proc SannfsBM(poly F, list #)
2302"USAGE:  SannfsBM(f [,eng]);  f a poly, eng an optional int
2303RETURN:  ring
2304PURPOSE: compute the D-module structure of basering[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
2305NOTE:    activate this ring with the @code{setring} command.
2306@*       In the ring D[s], the ideal LD is the needed D-mod structure,
2307@*       If eng <>0, @code{std} is used for Groebner basis computations,
2308@*       otherwise, and by default @code{slimgb} is used.
2309@*       If printlevel=1, progress debug messages will be printed,
2310@*       if printlevel>=2, all the debug messages will be printed.
2311EXAMPLE: example SannfsBM; shows examples
2312"
2313{
2314  int eng = 0;
2315  if ( size(#)>0 )
2316  {
2317    if ( typeof(#[1]) == "int" )
2318    {
2319      eng = int(#[1]);
2320    }
2321  }
2322  // returns a list with a ring and an ideal LD in it
2323  int ppl = printlevel-voice+2;
2324  //  printf("plevel :%s, voice: %s",printlevel,voice);
2325  def save = basering;
2326  int N = nvars(basering);
2327  int Nnew = 2*N+2;
2328  int i,j;
2329  string s;
2330  list RL = ringlist(basering);
2331  list L, Lord;
2332  list tmp;
2333  intvec iv;
2334  L[1] = RL[1]; // char
2335  L[4] = RL[4]; // char, minpoly
2336  // check whether vars have admissible names
2337  list Name  = RL[2];
2338  list RName;
2339  RName[1] = "t";
2340  RName[2] = "s";
2341  for(i=1;i<=N;i++)
2342  {
2343    for(j=1; j<=size(RName);j++)
2344    {
2345      if (Name[i] == RName[j])
2346      {
2347        ERROR("Variable names should not include t,s");
2348      }
2349    }
2350  }
2351  // now, create the names for new vars
2352  list DName;
2353  for(i=1;i<=N;i++)
2354  {
2355    DName[i] = "D"+Name[i]; // concat
2356  }
2357  tmp[1] = "t";
2358  tmp[2] = "s";
2359  list NName = tmp + Name + DName;
2360  L[2]   = NName;
2361  // Name, Dname will be used further
2362  kill NName;
2363  // block ord (lp(2),dp);
2364  tmp[1]  = "lp"; // string
2365  iv      = 1,1;
2366  tmp[2]  = iv; //intvec
2367  Lord[1] = tmp;
2368  // continue with dp 1,1,1,1...
2369  tmp[1]  = "dp"; // string
2370  s       = "iv=";
2371  for(i=1;i<=Nnew;i++)
2372  {
2373    s = s+"1,";
2374  }
2375  s[size(s)]= ";";
2376  execute(s);
2377  kill s;
2378  tmp[2]    = iv;
2379  Lord[2]   = tmp;
2380  tmp[1]    = "C";
2381  iv        = 0;
2382  tmp[2]    = iv;
2383  Lord[3]   = tmp;
2384  tmp       = 0;
2385  L[3]      = Lord;
2386  // we are done with the list
2387  def @R = ring(L);
2388  setring @R;
2389  matrix @D[Nnew][Nnew];
2390  @D[1,2]=t;
2391  for(i=1; i<=N; i++)
2392  {
2393    @D[2+i,N+2+i]=1;
2394  }
2395  //  L[5] = matrix(UpOneMatrix(Nnew));
2396  //  L[6] = @D;
2397  ncalgebra(1,@D);
2398  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
2399  dbprint(ppl-1, @R);
2400  // create the ideal I
2401  poly  F = imap(save,F);
2402  ideal I = t*F+s;
2403  poly p;
2404  for(i=1; i<=N; i++)
2405  {
2406    p = t; // t
2407    p = diff(F,var(2+i))*p;
2408    I = I, var(N+2+i) + p;
2409  }
2410  // -------- the ideal I is ready ----------
2411  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
2412  dbprint(ppl-1, I);
2413  ideal J = engine(I,eng);
2414  ideal K = nselect(J,1);
2415  dbprint(ppl,"// -1-3- t is eliminated");
2416  dbprint(ppl-1, K);  // K is without t
2417  K = engine(K,eng);  // std does the job too
2418  // now, we must change the ordering
2419  // and create a ring without t, Dt
2420  setring save;
2421  // ----------- the ring @R3 ------------
2422  // _x, _Dx,s;  elim.ord for _x,_Dx.
2423  // keep: N, i,j,s, tmp, RL
2424  Nnew = 2*N+1;
2425  kill Lord, tmp, iv, RName;
2426  list Lord, tmp;
2427  intvec iv;
2428  L[1] = RL[1];
2429  L[4] = RL[4];  // char, minpoly
2430  // check whether vars hava admissible names -> done earlier
2431  // now, create the names for new var
2432  tmp[1] = "s";
2433  // DName is defined earlier
2434  list NName = Name + DName + tmp;
2435  L[2] = NName;
2436  tmp = 0;
2437  // block ord (dp(N),dp);
2438  string s = "iv=";
2439  for (i=1; i<=Nnew-1; i++)
2440  {
2441    s = s+"1,";
2442  }
2443  s[size(s)]=";";
2444  execute(s);
2445  tmp[1] = "dp";  // string
2446  tmp[2] = iv;   // intvec
2447  Lord[1] = tmp;
2448  // continue with dp 1,1,1,1...
2449  tmp[1] = "dp";  // string
2450  s[size(s)] = ",";
2451  s = s+"1;";
2452  execute(s);
2453  kill s;
2454  kill NName;
2455  tmp[2]      = iv;
2456  Lord[2]     = tmp;
2457  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
2458  Lord[3]     = tmp;  tmp = 0;
2459  L[3]        = Lord;
2460  // we are done with the list. Now add a Plural part
2461  def @R2 = ring(L);
2462  setring @R2;
2463  matrix @D[Nnew][Nnew];
2464  for (i=1; i<=N; i++)
2465  {
2466    @D[i,N+i]=1;
2467  }
2468  ncalgebra(1,@D);
2469  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
2470  dbprint(ppl-1, @R2);
2471  ideal MM = maxideal(1);
2472  MM = 0,s,MM;
2473  map R01 = @R, MM;
2474  ideal K = R01(K);
2475  // total cleanup
2476  ideal LD = K;
2477  // make leadcoeffs positive
2478  for (i=1; i<= ncols(LD); i++)
2479  {
2480    if (leadcoef(LD[i]) <0 )
2481    {
2482      LD[i] = -LD[i];
2483    }
2484  }
2485  export LD;
2486  kill @R;
2487  return(@R2);
2488}
2489example
2490{
2491  "EXAMPLE:"; echo = 2;
2492  ring r = 0,(x,y,z),Dp;
2493  poly F = x^3+y^3+z^3;
2494  printlevel = 0;
2495  def A = SannfsBM(F);
2496  setring A;
2497  LD;
2498}
2499
2500proc SannfsLOT(poly F, list #)
2501"USAGE:  SannfsLOT(f [,eng]);  f a poly, eng an optional int
2502RETURN:  ring
2503PURPOSE: compute the D-module structure of basering[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
2504NOTE:    activate this ring with the @code{setring} command.
2505@*       In the ring D[s], the ideal LD is the needed D-mod structure.
2506@*       If eng <>0, @code{std} is used for Groebner basis computations,
2507@*       otherwise, and by default @code{slimgb} is used.
2508@*       If printlevel=1, progress debug messages will be printed,
2509@*       if printlevel>=2, all the debug messages will be printed.
2510EXAMPLE: example SannfsLOT; shows examples
2511"
2512{
2513  int eng = 0;
2514  if ( size(#)>0 )
2515  {
2516    if ( typeof(#[1]) == "int" )
2517    {
2518      eng = int(#[1]);
2519    }
2520  }
2521  // returns a list with a ring and an ideal LD in it
2522  int ppl = printlevel-voice+2;
2523  //  printf("plevel :%s, voice: %s",printlevel,voice);
2524  def save = basering;
2525  int N = nvars(basering);
2526  //  int Nnew = 2*(N+2);
2527  int Nnew = 2*(N+1)+1; //removed u,v; added s
2528  int i,j;
2529  string s;
2530  list RL = ringlist(basering);
2531  list L, Lord;
2532  list tmp;
2533  intvec iv;
2534  L[1] = RL[1]; // char
2535  L[4] = RL[4]; // char, minpoly
2536  // check whether vars have admissible names
2537  list Name  = RL[2];
2538  list RName;
2539//   RName[1] = "u";
2540//   RName[2] = "v";
2541  RName[1] = "t";
2542  RName[2] = "Dt";
2543  for(i=1;i<=N;i++)
2544  {
2545    for(j=1; j<=size(RName);j++)
2546    {
2547      if (Name[i] == RName[j])
2548      {
2549        ERROR("Variable names should not include t,Dt");
2550      }
2551    }
2552  }
2553  // now, create the names for new vars
2554//   tmp[1]     = "u";
2555//   tmp[2]     = "v";
2556//   list UName = tmp;
2557  list DName;
2558  for(i=1;i<=N;i++)
2559  {
2560    DName[i] = "D"+Name[i]; // concat
2561  }
2562  tmp    =  0;
2563  tmp[1] = "t";
2564  tmp[2] = "Dt";
2565  list SName ; SName[1] = "s";
2566  //  list NName = UName +  tmp + Name + DName;
2567  list NName = tmp + Name + DName + SName;
2568  L[2]   = NName;
2569  tmp    = 0;
2570  // Name, Dname will be used further
2571  //  kill UName;
2572  kill NName;
2573  // block ord (a(1,1),dp);
2574  tmp[1]  = "a"; // string
2575  iv      = 1,1;
2576  tmp[2]  = iv; //intvec
2577  Lord[1] = tmp;
2578  // continue with dp 1,1,1,1...
2579  tmp[1]  = "dp"; // string
2580  s       = "iv=";
2581  for(i=1;i<=Nnew;i++)
2582  {
2583    s = s+"1,";
2584  }
2585  s[size(s)]= ";";
2586  execute(s);
2587  tmp[2]    = iv;
2588  Lord[2]   = tmp;
2589  tmp[1]    = "C";
2590  iv        = 0;
2591  tmp[2]    = iv;
2592  Lord[3]   = tmp;
2593  tmp       = 0;
2594  L[3]      = Lord;
2595  // we are done with the list
2596  def @R = ring(L);
2597  setring @R;
2598  matrix @D[Nnew][Nnew];
2599  @D[1,2]=1;
2600  for(i=1; i<=N; i++)
2601  {
2602    @D[2+i,N+2+i]=1;
2603  }
2604  // ADD [s,t]=-t, [s,Dt]=Dt
2605  @D[1,Nnew] = -var(1);
2606  @D[2,Nnew] = var(2);
2607  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
2608  //  L[5] = matrix(UpOneMatrix(Nnew));
2609  //  L[6] = @D;
2610  ncalgebra(1,@D);
2611  dbprint(ppl,"// -1-1- the ring @R(t,Dt,_x,_Dx,s) is ready");
2612  dbprint(ppl-1, @R);
2613  // create the ideal I
2614  poly  F = imap(save,F);
2615  //  ideal I = u*F-t,u*v-1;
2616  ideal I = F-t;
2617  poly p;
2618  for(i=1; i<=N; i++)
2619  {
2620    //    p = u*Dt; // u*Dt
2621    p = Dt;
2622    p = diff(F,var(2+i))*p;
2623    I = I, var(N+2+i) + p;
2624  }
2625  //  I = I, var(1)*var(2) + var(Nnew) +1; // reduce it with t-f!!!
2626  // t*Dt + s +1 reduced with t-f gives f*Dt + s
2627  I = I, F*var(2) + var(Nnew);
2628  // -------- the ideal I is ready ----------
2629  dbprint(ppl,"// -1-2- starting the elimination of t,Dt in @R");
2630  dbprint(ppl-1, I);
2631  ideal J = engine(I,eng);
2632  ideal K = nselect(J,1,2);
2633  dbprint(ppl,"// -1-3- t,Dt are eliminated");
2634  dbprint(ppl-1, K);  // K is without t, Dt
2635  K = engine(K,eng);  // std does the job too
2636  // now, we must change the ordering
2637  // and create a ring without t, Dt
2638  setring save;
2639  // ----------- the ring @R3 ------------
2640  // _x, _Dx,s;  elim.ord for _x,_Dx.
2641  // keep: N, i,j,s, tmp, RL
2642  Nnew = 2*N+1;
2643  kill Lord, tmp, iv, RName;
2644  list Lord, tmp;
2645  intvec iv;
2646  L[1] = RL[1];
2647  L[4] = RL[4];  // char, minpoly
2648  // check whether vars hava admissible names -> done earlier
2649  // now, create the names for new var
2650  tmp[1] = "s";
2651  // DName is defined earlier
2652  list NName = Name + DName + tmp;
2653  L[2] = NName;
2654  tmp = 0;
2655  // block ord (dp(N),dp);
2656  // string s is already defined
2657  s = "iv=";
2658  for (i=1; i<=Nnew-1; i++)
2659  {
2660    s = s+"1,";
2661  }
2662  s[size(s)]=";";
2663  execute(s);
2664  tmp[1] = "dp";  // string
2665  tmp[2] = iv;   // intvec
2666  Lord[1] = tmp;
2667  // continue with dp 1,1,1,1...
2668  tmp[1] = "dp";  // string
2669  s[size(s)] = ",";
2670  s = s+"1;";
2671  execute(s);
2672  kill s;
2673  kill NName;
2674  tmp[2]      = iv;
2675  Lord[2]     = tmp;
2676  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
2677  Lord[3]     = tmp;  tmp = 0;
2678  L[3]        = Lord;
2679  // we are done with the list. Now add a Plural part
2680  def @R2 = ring(L);
2681  setring @R2;
2682  matrix @D[Nnew][Nnew];
2683  for (i=1; i<=N; i++)
2684  {
2685    @D[i,N+i]=1;
2686  }
2687  ncalgebra(1,@D);
2688  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
2689  dbprint(ppl-1, @R2);
2690  ideal MM = maxideal(1);
2691  MM = 0,s,MM;
2692  map R01 = @R, MM;
2693  ideal K = R01(K);
2694  // total cleanup
2695  ideal LD = K;
2696  // make leadcoeffs positive
2697  for (i=1; i<= ncols(LD); i++)
2698  {
2699    if (leadcoef(LD[i]) <0 )
2700    {
2701      LD[i] = -LD[i];
2702    }
2703  }
2704  export LD;
2705  kill @R;
2706  return(@R2);
2707}
2708example
2709{
2710  "EXAMPLE:"; echo = 2;
2711  ring r = 0,(x,y,z),Dp;
2712  poly F = x^3+y^3+z^3;
2713  printlevel = 0;
2714  def A  = SannfsLOT(F);
2715  setring A;
2716  LD;
2717}
2718
2719
2720proc annfsLOT(poly F, list #)
2721"USAGE:  annfsLOT(F [,eng]);  F a poly, eng an optional int
2722RETURN:  ring
2723PURPOSE: compute the D-module structure of basering[f^s], according to the Levandovskyy's modification of the algorithm by Oaku and Takayama
2724NOTE:    activate this ring with the @code{setring} command. In this ring,
2725@*       - the ideal LD is the annihilator of f^s,
2726@*       - the list BS contains the roots with multiplicities of a Bernstein polynomial of f.
2727@*       If eng <>0, @code{std} is used for Groebner basis computations,
2728@*       otherwise, and by default @code{slimgb} is used.
2729@*       If printlevel=1, progress debug messages will be printed,
2730@*       if printlevel>=2, all the debug messages will be printed.
2731EXAMPLE: example annfsLOT; shows examples
2732"
2733{
2734  int eng = 0;
2735  if ( size(#)>0 )
2736  {
2737    if ( typeof(#[1]) == "int" )
2738    {
2739      eng = int(#[1]);
2740    }
2741  }
2742  printlevel=printlevel+1;
2743  def save = basering;
2744  def @A = SannfsLOT(F,eng);
2745  setring @A;
2746  poly F = imap(save,F);
2747  def B  = annfs0(LD,F,eng);
2748  return(B);
2749}
2750example
2751{
2752  "EXAMPLE:"; echo = 2;
2753  ring r = 0,(x,y,z),Dp;
2754  poly F = x^3+y^3+z^3;
2755  printlevel = 0;
2756  def A  = annfsLOT(F);
2757  setring A;
2758  LD;
2759  BS;
2760}
2761
2762proc annfs0(ideal I, poly F, list #)
2763"USAGE:  annfs0(I, F [,eng]);  I an ideal, F a poly, eng an optional int
2764RETURN:  ring
2765PURPOSE: compute the annihilator ideal of f^s in the Weyl Algebra, based on the
2766output of procedures SannfsBM, SannfsOT or SannfsLOT
2767NOTE:    activate this ring with the @code{setring} command. In this ring,
2768@*       - the ideal LD is the annihilator of f^s,
2769@*       - the list BS contains the roots with multiplicities of a Bernstein polynomial of f.
2770@*       If eng <>0, @code{std} is used for Groebner basis computations,
2771@*       otherwise, and by default @code{slimgb} is used.
2772@*       If printlevel=1, progress debug messages will be printed,
2773@*       if printlevel>=2, all the debug messages will be printed.
2774EXAMPLE: example annfs0; shows examples
2775"
2776{
2777  int eng = 0;
2778  if ( size(#)>0 )
2779  {
2780    if ( typeof(#[1]) == "int" )
2781    {
2782      eng = int(#[1]);
2783    }
2784  }
2785  def @R2 = basering;
2786  // we're in D_n[s], where the elim ord for s is set
2787  ideal J = NF(I,std(F));
2788  // make leadcoeffs positive
2789  int i;
2790  for (i=1; i<= ncols(J); i++)
2791  {
2792    if (leadcoef(J[i]) <0 )
2793    {
2794      J[i] = -J[i];
2795    }
2796  }
2797  J = J,F;
2798  ideal M = engine(J,eng);
2799  int Nnew = nvars(@R2);
2800  ideal K2 = nselect(M,1,Nnew-1);
2801  int ppl = printlevel-voice+2;
2802  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
2803  dbprint(ppl-1, K2);
2804  // the ring @R3 and the search for minimal negative int s
2805  ring @R3 = 0,s,dp;
2806  dbprint(ppl,"// -2-1- the ring @R3 i.e. K[s] is ready");
2807  ideal K3 = imap(@R2,K2);
2808  poly p = K3[1];
2809  dbprint(ppl,"// -2-2- factorization");
2810  //  ideal P = factorize(p,1);  //without constants and multiplicities
2811  //  "--------- b-function factorizes into ---------";   P;
2812  // convert factors to the list of their roots with mults
2813  // assume all factors are linear
2814  //  ideal BS = normalize(P);
2815  //  BS = subst(BS,s,0);
2816  //  BS = -BS;
2817  list P = factorize(p);          //with constants and multiplicities
2818  int sP = minIntRoot(P[1],1);
2819  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
2820  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
2821  {
2822    bs[i-1] = P[1][i];
2823    m[i-1] = P[2][i];
2824  }
2825  bs =  normalize(bs);
2826  bs = -subst(bs,s,0);
2827  dbprint(ppl,"// -2-3- minimal interger root found");
2828  dbprint(ppl-1, sP);
2829 //TODO: sort BS!
2830  // --------- substitute s found in the ideal ---------
2831  // --------- going back to @R and substitute ---------
2832  setring @R2;
2833  K2 = subst(I,s,sP);
2834  // create the ordinary Weyl algebra and put the result into it,
2835  // thus creating the ring @R5
2836  // keep: N, i,j,s, tmp, RL
2837  Nnew = Nnew - 1; // former 2*N;
2838  // list RL = ringlist(save);  // is defined earlier
2839  //  kill Lord, tmp, iv;
2840  list L = 0;
2841  list Lord, tmp;
2842  intvec iv;
2843  list RL = ringlist(basering);
2844  L[1] = RL[1];
2845  L[4] = RL[4];  //char, minpoly
2846  // check whether vars have admissible names -> done earlier
2847  // list Name = RL[2]M
2848  // DName is defined earlier
2849  list NName; // = RL[2]; // skip the last var 's'
2850  for (i=1; i<=Nnew; i++)
2851  {
2852    NName[i] =  RL[2][i];
2853  }
2854  L[2] = NName;
2855  // dp ordering;
2856  string s = "iv=";
2857  for (i=1; i<=Nnew; i++)
2858  {
2859    s = s+"1,";
2860  }
2861  s[size(s)] = ";";
2862  execute(s);
2863  tmp     = 0;
2864  tmp[1]  = "dp";  // string
2865  tmp[2]  = iv;  // intvec
2866  Lord[1] = tmp;
2867  kill s;
2868  tmp[1]  = "C";
2869  iv = 0;
2870  tmp[2]  = iv;
2871  Lord[2] = tmp;
2872  tmp     = 0;
2873  L[3]    = Lord;
2874  // we are done with the list
2875  // Add: Plural part
2876  def @R4 = ring(L);
2877  setring @R4;
2878  int N = Nnew/2;
2879  matrix @D[Nnew][Nnew];
2880  for (i=1; i<=N; i++)
2881  {
2882    @D[i,N+i]=1;
2883  }
2884  ncalgebra(1,@D);
2885  dbprint(ppl,"// -3-1- the ring @R4 is ready");
2886  dbprint(ppl-1, @R4);
2887  ideal K4 = imap(@R2,K2);
2888  option(redSB);
2889  dbprint(ppl,"// -3-2- the final cosmetic std");
2890  K4 = engine(K4,eng);  // std does the job too
2891  // total cleanup
2892  ideal bs = imap(@R3,bs);
2893  kill @R3;
2894  list BS = bs,m;
2895  export BS;
2896  ideal LD = K4;
2897  export LD;
2898  return(@R4);
2899}
2900example
2901{ "EXAMPLE:"; echo = 2;
2902  ring r = 0,(x,y,z),Dp;
2903  poly F = x^3+y^3+z^3;
2904  printlevel = 0;
2905  def A = SannfsBM(F);
2906  // alternatively, one can use SannfsOT or SannfsLOT
2907  setring A;
2908  LD;
2909  poly F = imap(r,F);
2910  def B  = annfs0(LD,F);
2911  setring B;
2912  LD;
2913  BS;
2914}
2915
2916// proc annfsgms(poly F, list #)
2917// "USAGE:  annfsgms(f [,eng]);  f a poly, eng an optional int
2918// ASSUME:  f has an isolated critical point at 0
2919// RETURN:  ring
2920// PURPOSE: compute the D-module structure of basering[f^s]
2921// NOTE:    activate this ring with the @code{setring} command. In this ring,
2922// @*       - the ideal LD is the needed D-mod structure,
2923// @*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
2924// @*       If eng <>0, @code{std} is used for Groebner basis computations,
2925// @*       otherwise (and by default) @code{slimgb} is used.
2926// @*       If printlevel=1, progress debug messages will be printed,
2927// @*       if printlevel>=2, all the debug messages will be printed.
2928// EXAMPLE: example annfsgms; shows examples
2929// "
2930// {
2931//   LIB "gmssing.lib";
2932//   int eng = 0;
2933//   if ( size(#)>0 )
2934//   {
2935//     if ( typeof(#[1]) == "int" )
2936//     {
2937//       eng = int(#[1]);
2938//     }
2939//   }
2940//   int ppl = printlevel-voice+2;
2941//   // returns a ring with the ideal LD in it
2942//   def save = basering;
2943//   // compute the Bernstein poly from gmssing.lib
2944//   list RL = ringlist(basering);
2945//   // in the descr. of the ordering, replace "p" by "s"
2946//   list NL = convloc(RL);
2947//   // create a ring with the ordering, converted to local
2948//   def @LR = ring(NL);
2949//   setring @LR;
2950//   poly F  = imap(save, F);
2951//   ideal B = bernstein(F)[1];
2952//   // since B may not contain (s+1) [following gmssing.lib]
2953//   // add it!
2954//   B = B,-1;
2955//   B = simplify(B,2+4); // erase zero and repeated entries
2956//   // find the minimal integer value
2957//   int   S = minIntRoot(B,0);
2958//   dbprint(ppl,"// -0- minimal integer root found");
2959//   dbprint(ppl-1,S);
2960//   setring save;
2961//   int N = nvars(basering);
2962//   int Nnew = 2*(N+2);
2963//   int i,j;
2964//   string s;
2965//   //  list RL = ringlist(basering);
2966//   list L, Lord;
2967//   list tmp;
2968//   intvec iv;
2969//   L[1] = RL[1]; // char
2970//   L[4] = RL[4]; // char, minpoly
2971//   // check whether vars have admissible names
2972//   list Name  = RL[2];
2973//   list RName;
2974//   RName[1] = "u";
2975//   RName[2] = "v";
2976//   RName[3] = "t";
2977//   RName[4] = "Dt";
2978//   for(i=1;i<=N;i++)
2979//   {
2980//     for(j=1; j<=size(RName);j++)
2981//     {
2982//       if (Name[i] == RName[j])
2983//       {
2984//         ERROR("Variable names should not include u,v,t,Dt");
2985//       }
2986//     }
2987//   }
2988//   // now, create the names for new vars
2989//   //  tmp[1]     = "u";  tmp[2]     = "v";  tmp[3]     = "t";  tmp[4]     = "Dt";
2990//   list UName = RName;
2991//   list DName;
2992//   for(i=1;i<=N;i++)
2993//   {
2994//     DName[i] = "D"+Name[i]; // concat
2995//   }
2996//   list NName = UName + Name + DName;
2997//   L[2]       = NName;
2998//   tmp        = 0;
2999//   // Name, Dname will be used further
3000//   kill UName;
3001//   kill NName;
3002//   // block ord (a(1,1),dp);
3003//   tmp[1]  = "a"; // string
3004//   iv      = 1,1;
3005//   tmp[2]  = iv; //intvec
3006//   Lord[1] = tmp;
3007//   // continue with dp 1,1,1,1...
3008//   tmp[1]  = "dp"; // string
3009//   s       = "iv=";
3010//   for(i=1; i<=Nnew; i++) // need really all vars!
3011//   {
3012//     s = s+"1,";
3013//   }
3014//   s[size(s)]= ";";
3015//   execute(s);
3016//   tmp[2]    = iv;
3017//   Lord[2]   = tmp;
3018//   tmp[1]    = "C";
3019//   iv        = 0;
3020//   tmp[2]    = iv;
3021//   Lord[3]   = tmp;
3022//   tmp       = 0;
3023//   L[3]      = Lord;
3024//   // we are done with the list
3025//   def @R = ring(L);
3026//   setring @R;
3027//   matrix @D[Nnew][Nnew];
3028//   @D[3,4] = 1; // t,Dt
3029//   for(i=1; i<=N; i++)
3030//   {
3031//     @D[4+i,4+N+i]=1;
3032//   }
3033//   //  L[5] = matrix(UpOneMatrix(Nnew));
3034//   //  L[6] = @D;
3035//   ncalgebra(1,@D);
3036//   dbprint(ppl,"// -1-1- the ring @R is ready");
3037//   dbprint(ppl-1,@R);
3038//   // create the ideal
3039//   poly F  = imap(save,F);
3040//   ideal I = u*F-t,u*v-1;
3041//   poly p;
3042//   for(i=1; i<=N; i++)
3043//   {
3044//     p = u*Dt; // u*Dt
3045//     p = diff(F,var(4+i))*p;
3046//     I = I, var(N+4+i) + p; // Dx, Dy
3047//   }
3048//   // add the relations between t,Dt and s
3049//   //  I = I, t*Dt+1+S;
3050//   // -------- the ideal I is ready ----------
3051//   dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
3052//   ideal J = engine(I,eng);
3053//   ideal K = nselect(J,1,2);
3054//   dbprint(ppl,"// -1-3- u,v are eliminated in @R");
3055//   dbprint(ppl-1,K); // without u,v: not yet our answer
3056//   //----- create a ring with elim.ord for t,Dt -------
3057//   setring save;
3058//   // ------------ new ring @R2 ------------------
3059//   // without u,v and with the elim.ord for t,Dt
3060//   // keep: N, i,j,s, tmp, RL
3061//   Nnew = 2*N+2;
3062//   //  list RL = ringlist(save); // is defined earlier
3063//   kill Lord,tmp,iv, RName;
3064//   L = 0;
3065//   list Lord, tmp;
3066//   intvec iv;
3067//   L[1] = RL[1]; // char
3068//   L[4] = RL[4]; // char, minpoly
3069//   // check whether vars have admissible names -> done earlier
3070//   //  list Name  = RL[2];
3071//   list RName;
3072//   RName[1] = "t";
3073//   RName[2] = "Dt";
3074//   // DName is defined earlier
3075//   list NName = RName + Name + DName;
3076//   L[2]   = NName;
3077//   tmp    = 0;
3078//   // block ord (a(1,1),dp);
3079//   tmp[1]  = "a"; // string
3080//   iv      = 1,1;
3081//   tmp[2]  = iv; //intvec
3082//   Lord[1] = tmp;
3083//   // continue with dp 1,1,1,1...
3084//   tmp[1]  = "dp"; // string
3085//   s       = "iv=";
3086//   for(i=1;i<=Nnew;i++)
3087//   {
3088//     s = s+"1,";
3089//   }
3090//   s[size(s)]= ";";
3091//   execute(s);
3092//   kill s;
3093//   kill NName;
3094//   tmp[2]    = iv;
3095//   Lord[2]   = tmp;
3096//   tmp[1]    = "C";
3097//   iv        = 0;
3098//   tmp[2]    = iv;
3099//   Lord[3]   = tmp;
3100//   tmp       = 0;
3101//   L[3]      = Lord;
3102//   // we are done with the list
3103//   // Add: Plural part
3104//   def @R2 = ring(L);
3105//   setring @R2;
3106//   matrix @D[Nnew][Nnew];
3107//   @D[1,2]=1;
3108//   for(i=1; i<=N; i++)
3109//   {
3110//     @D[2+i,2+N+i]=1;
3111//   }
3112//   ncalgebra(1,@D);
3113//   dbprint(ppl,"// -2-1- the ring @R2 is ready");
3114//   dbprint(ppl-1,@R2);
3115//   ideal MM = maxideal(1);
3116//   MM = 0,0,MM;
3117//   map R01 = @R, MM;
3118//   ideal K2 = R01(K);
3119//   // add the relations between t,Dt and s
3120//   //  K2       = K2, t*Dt+1+S;
3121//   poly G = t*Dt+S+1;
3122//   K2 = NF(K2,std(G)),G;
3123//   dbprint(ppl,"// -2-2- starting elimination for t,Dt in @R2");
3124//   ideal J  = engine(K2,eng);
3125//   ideal K  = nselect(J,1,2);
3126//   dbprint(ppl,"// -2-3- t,Dt are eliminated");
3127//   dbprint(ppl-1,K);
3128//   //  "------- produce a final result --------";
3129//   // ----- create the ordinary Weyl algebra and put
3130//   // ----- the result into it
3131//   // ------ create the ring @R5
3132//   // keep: N, i,j,s, tmp, RL
3133//   setring save;
3134//   Nnew = 2*N;
3135//   //  list RL = ringlist(save); // is defined earlier
3136//   kill Lord, tmp, iv;
3137//   //  kill L;
3138//   L = 0;
3139//   list Lord, tmp;
3140//   intvec iv;
3141//   L[1] = RL[1]; // char
3142//   L[4] = RL[4]; // char, minpoly
3143//   // check whether vars have admissible names -> done earlier
3144//   //  list Name  = RL[2];
3145//   // DName is defined earlier
3146//   list NName = Name + DName;
3147//   L[2]   = NName;
3148//   // dp ordering;
3149//   string   s       = "iv=";
3150//   for(i=1;i<=2*N;i++)
3151//   {
3152//     s = s+"1,";
3153//   }
3154//   s[size(s)]= ";";
3155//   execute(s);
3156//   tmp     = 0;
3157//   tmp[1]  = "dp"; // string
3158//   tmp[2]  = iv; //intvec
3159//   Lord[1] = tmp;
3160//   kill s;
3161//   tmp[1]    = "C";
3162//   iv        = 0;
3163//   tmp[2]    = iv;
3164//   Lord[2]   = tmp;
3165//   tmp       = 0;
3166//   L[3]      = Lord;
3167//   // we are done with the list
3168//   // Add: Plural part
3169//   def @R5 = ring(L);
3170//   setring @R5;
3171//   matrix @D[Nnew][Nnew];
3172//   for(i=1; i<=N; i++)
3173//   {
3174//     @D[i,N+i]=1;
3175//   }
3176//   ncalgebra(1,@D);
3177//   dbprint(ppl,"// -3-1- the ring @R5 is ready");
3178//   dbprint(ppl-1,@R5);
3179//   ideal K5 = imap(@R2,K);
3180//   option(redSB);
3181//   dbprint(ppl,"// -3-2- the final cosmetic std");
3182//   K5 = engine(K5,eng); // std does the job too
3183//   // total cleanup
3184//   kill @R;
3185//   kill @R2;
3186//   ideal LD = K5;
3187//   ideal BS = imap(@LR,B);
3188//   kill @LR;
3189//   export BS;
3190//   export LD;
3191//   return(@R5);
3192// }
3193// example
3194// {
3195//   "EXAMPLE:"; echo = 2;
3196//   ring r = 0,(x,y,z),Dp;
3197//   poly F = x^2+y^3+z^5;
3198//   def A = annfsgms(F);
3199//   setring A;
3200//   LD;
3201//   print(matrix(BS));
3202// }
3203
3204
3205proc convloc(list @NL)
3206"USAGE:  convloc(L); L a list
3207RETURN:  list
3208PURPOSE: convert a ringlist L into another ringlist,
3209where all the 'p' orderings are replaced with the 's' orderings.
3210ASSUME: L is a result of a ringlist command
3211EXAMPLE: example minIntRoot; shows examples
3212"
3213{
3214  list NL = @NL;
3215  // given a ringlist, returns a new ringlist,
3216  // where all the p-orderings are replaced with s-ord's
3217  int i,j,k,found;
3218  int nblocks = size(NL[3]);
3219  for(i=1; i<=nblocks; i++)
3220  {
3221    for(j=1; j<=size(NL[3][i]); j++)
3222    {
3223      if (typeof(NL[3][i][j]) == "string" )
3224      {
3225        found = 0;
3226        for (k=1; k<=size(NL[3][i][j]); k++)
3227        {
3228          if (NL[3][i][j][k]=="p")
3229          {
3230            NL[3][i][j][k]="s";
3231            found = 1;
3232            //    printf("replaced at %s,%s,%s",i,j,k);
3233          }
3234        }
3235      }
3236    }
3237  }
3238  return(NL);
3239}
3240example
3241{
3242  "EXAMPLE:"; echo = 2;
3243  ring r = 0,(x,y,z),(Dp(2),dp(1));
3244  list L = ringlist(r);
3245  list N = convloc(L);
3246  def rs = ring(N);
3247  setring rs;
3248  rs;
3249}
3250
3251proc minIntRoot(ideal P, int fact)
3252"USAGE:  minIntRoot(P, fact); P an ideal, fact an int
3253RETURN:  int
3254PURPOSE: minimal integer root of a maximal ideal P
3255NOTE:    if fact==1, P is the result of some 'factorize' call,
3256@*       else P is treated as the result of bernstein::gmssing.lib
3257@*       in both cases without constants and multiplicities
3258EXAMPLE: example minIntRoot; shows examples
3259"
3260{
3261  //    ideal P = factorize(p,1);
3262  // or ideal P = bernstein(F)[1];
3263  intvec vP;
3264  number nP;
3265  int i;
3266  if ( fact )
3267  {
3268    // the result comes from "factorize"
3269    P = normalize(P); // now leadcoef = 1
3270    P = lead(P)-P;
3271    // nP = leadcoef(P[i]-lead(P[i])); // for 1 var only, extract the coeff
3272  }
3273  else
3274  {
3275    // bernstein deletes -1 usually
3276    P = P, -1;
3277  }
3278  // for both situations:
3279  // now we have an ideal of fractions of type "number"
3280  int sP = size(P);
3281  for(i=1; i<=sP; i++)
3282  {
3283    nP = leadcoef(P[i]);
3284    if ( (nP - int(nP)) == 0 )
3285    {
3286      vP = vP,int(nP);
3287    }
3288  }
3289  if ( size(vP)>=2 )
3290  {
3291    vP = vP[2..size(vP)];
3292  }
3293  sP = -Max(-vP);
3294  if (sP == 0)
3295  {
3296    "Warning: zero root!";
3297  }
3298  return(sP);
3299}
3300example
3301{
3302  "EXAMPLE:"; echo = 2;
3303  ring r   = 0,(x,y),ds;
3304  poly f1  = x*y*(x+y);
3305  ideal I1 = bernstein(f1)[1]; // a local Bernstein poly
3306  minIntRoot(I1,0);
3307  poly  f2  = x2-y3;
3308  ideal I2  = bernstein(f2)[1];
3309  minIntRoot(I2,0);
3310  // now we illustrate the behaviour of factorize
3311  // together with a global ordering
3312  ring r2  = 0,x,dp;
3313  poly f3   = 9*(x+2/3)*(x+1)*(x+4/3); //global b-poly of f1=x*y*(x+y)
3314  ideal I3 = factorize(f3,1);
3315  minIntRoot(I3,1);
3316  // and a more interesting situation
3317  ring  s  = 0,(x,y,z),ds;
3318  poly  f  = x3 + y3 + z3;
3319  ideal I  = bernstein(f)[1];
3320  minIntRoot(I,0);
3321}
3322
3323proc isHolonomic(def M)
3324"USAGE:  isHolonomic(M); M an ideal/module/matrix
3325RETURN:  int, 1 if M is holonomic and 0 otherwise
3326PURPOSE: check the modules for the property of holonomy
3327NOTE:    M is holonomic, if 2*dim(M) = dim(R), where R is a
3328ground ring; dim stays for Gelfand-Kirillov dimension
3329EXAMPLE: example isHolonomic; shows examples
3330"
3331{
3332  if ( (typeof(M) != "ideal") && (typeof(M) != "module") && (typeof(M) != "matrix") )
3333  {
3334  //  print(typeof(M));
3335    ERROR("an argument of type ideal/module/matrix expected");
3336  }
3337  if (attrib(M,"isSB")!=1)
3338  {
3339    M = std(M);
3340  }
3341  int dimR = gkdim(std(0));
3342  int dimM = gkdim(M);
3343  return( (dimR==2*dimM) );
3344}
3345example
3346{
3347  "EXAMPLE:"; echo = 2;
3348  ring R = 0,(x,y),dp;
3349  poly F = x*y*(x+y);
3350  def A = annfsBM(F,0);
3351  setring A;
3352  LD;
3353  isHolonomic(LD);
3354  ideal I = std(LD[1]);
3355  I;
3356  isHolonomic(I);
3357}
3358
3359proc reiffen(int p, int q)
3360"USAGE:  reiffen(p, q);  int p, int q
3361RETURN:  ring
3362PURPOSE: set up the polynomial, describing a Reiffen curve
3363NOTE:    activate this ring with the @code{setring} command and find the
3364         curve as a polynomial RC
3365@*   a Reiffen curve is defined as F = x^p + y^q + xy^{q-1}, q >= p+1 >= 5
3366ASSUME: q >= p+1 >= 5. Otherwise an error message is returned
3367EXAMPLE: example reiffen; shows examples
3368"
3369{
3370// a Reiffen curve is defined as
3371// F = x^p + y^q +x*y^{q-1}, q \geq p+1 \geq 5
3372
3373  if ( (p<4) || (q<5) || (q-p<1) )
3374  {
3375    ERROR("Some of conditions p>=4, q>=5 or q>=p+1 is not satisfied!");
3376  }
3377  ring @r = 0,(x,y),dp;
3378  poly RC = y^q +x^p + x*y^(q-1);
3379  export RC;
3380  return(@r);
3381}
3382example
3383{
3384  "EXAMPLE:"; echo = 2;
3385  def r = reiffen(4,5);
3386  setring r;
3387  RC;
3388}
3389
3390proc arrange(int p)
3391"USAGE:  arrange(p);  int p
3392RETURN:  ring
3393PURPOSE: set up the polynomial, describing a hyperplane arrangement
3394NOTE:   must be executed in a ring
3395ASSUME: basering is present
3396EXAMPLE: example arrange; shows examples
3397"
3398{
3399  int UseBasering = 0 ;
3400  if (p<2)
3401  {
3402    ERROR("p>=2 is required!");
3403  }
3404  if ( nameof(basering)!="basering" )
3405  {
3406    if (p > nvars(basering))
3407    {
3408      ERROR("too big p");
3409    }
3410    else
3411    {
3412      def @r = basering;
3413      UseBasering = 1;
3414    }
3415  }
3416  else
3417  {
3418    // no basering found
3419    ERROR("no basering found!");
3420    //    ring @r = 0,(x(1..p)),dp;
3421  }
3422  int i,j,sI;
3423  poly  q = 1;
3424  list ar;
3425  ideal tmp;
3426  tmp = ideal(var(1));
3427  ar[1] = tmp;
3428  for (i = 2; i<=p; i++)
3429  {
3430    // add i-nary sums to the product
3431    ar = indAR(ar,i);
3432  }
3433  for (i = 1; i<=p; i++)
3434  {
3435    tmp = ar[i]; sI = size(tmp);
3436    for (j = 1; j<=sI; j++)
3437    {
3438      q = q*tmp[j];
3439    }
3440  }
3441  if (UseBasering)
3442  {
3443    return(q);
3444  }
3445  //  poly AR = q; export AR;
3446  //  return(@r);
3447}
3448example
3449{
3450  "EXAMPLE:"; echo = 2;
3451  ring X = 0,(x,y,z,t),dp;
3452  poly q = arrange(3);
3453  factorize(q,1);
3454}
3455
3456static proc indAR(list L, int n)
3457"USAGE:  indAR(L,n);  list L, int n
3458RETURN:  list
3459PURPOSE: computes arrangement inductively, using L and varn(n) as the
3460next variable
3461ASSUME: L has a structure of an arrangement
3462EXAMPLE: example indAR; shows examples
3463"
3464{
3465  if ( (n<2) || (n>nvars(basering)) )
3466  {
3467    ERROR("incorrect n");
3468  }
3469  int sl = size(L);
3470  list K;
3471  ideal tmp;
3472  poly @t = L[sl][1] + var(n); //1 elt
3473  K[sl+1] = ideal(@t);
3474  tmp = L[1]+var(n);
3475  K[1] = tmp; tmp = 0;
3476  int i,j,sI;
3477  ideal I;
3478  for(i=sl; i>=2; i--)
3479  {
3480    I = L[i-1]; sI = size(I);
3481    for(j=1; j<=sI; j++)
3482    {
3483      I[j] = I[j] + var(n);
3484    }
3485    tmp  = L[i],I;
3486    K[i] = tmp;
3487    I = 0; tmp = 0;
3488  }
3489  kill I; kill tmp;
3490  return(K);
3491}
3492example
3493{
3494  "EXAMPLE:"; echo = 2;
3495  ring r = 0,(x,y,z,t,v),dp;
3496  list L;
3497  L[1] = ideal(x);
3498  list K = indAR(L,2);
3499  K;
3500  list M = indAR(K,3);
3501  M;
3502  M = indAR(M,4);
3503  M;
3504}
3505
3506static proc exCheckGenericity()
3507{
3508  LIB "control.lib";
3509  ring r = (0,a,b,c),x,dp;
3510  poly p = (x-a)*(x-b)*(x-c);
3511  def A = annfsBM(p);
3512  setring A;
3513  ideal J = slimgb(LD);
3514  matrix T = lift(LD,J);
3515  T = normalize(T);
3516  genericity(T);
3517  // 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)
3518  // genericity: g = a2-ab-ac+b2-bc+c2 =0
3519  // g = (a -(b+c)/2)^2 + (3/4)*(b-c)^2;
3520  // g ==0 <=> a=b=c
3521  // indeed, Ann = (x-a)^2*(x*Dx+3*t*Dt+(-a)*Dx+3)
3522  // --------------------------------------------
3523  // BUT a direct computation shows
3524  // when a=b=c,
3525  // Ann = x*Dx+3*t*Dt+(-a)*Dx+3
3526}
3527
3528static proc exOT_17()
3529{
3530  // Oaku-Takayama, p.208
3531  ring R = 0,(x,y),dp;
3532  poly F = x^3-y^2; // x^2+x*y+y^2;
3533  option(prot);
3534  option(mem);
3535  //  option(redSB);
3536  def A = annfsOT(F,0);
3537  setring A;
3538  LD;
3539  gkdim(LD); // a holonomic check
3540  //  poly F = x^3-y^2; // = x^7 - y^5; // x^3-y^4; // x^5 - y^4;
3541}
3542
3543static proc exOT_16()
3544{
3545  // Oaku-Takayama, p.208
3546  ring R = 0,(x),dp;
3547  poly F = x*(1-x);
3548  option(prot);
3549  option(mem);
3550  //  option(redSB);
3551  def A = annfsOT(F,0);
3552  setring A;
3553  LD;
3554  gkdim(LD); // a holonomic check
3555}
3556
3557static proc ex_bcheck()
3558{
3559  ring R = 0,(x,y),dp;
3560  poly F = x*y*(x+y);
3561  option(prot);
3562  option(mem);
3563  int eng = 0;
3564  //  option(redSB);
3565  def A = annfsOT(F,eng);
3566  setring A;
3567  LD;
3568}
3569
3570static proc ex_bcheck2()
3571{
3572  ring R = 0,(x,y),dp;
3573  poly F = x*y*(x+y);
3574  int eng = 0;
3575  def A = annfsOT(F,eng);
3576  setring A;
3577  LD;
3578}
3579
3580static proc ex_BMI()
3581{
3582  ring r = 0,(x,y),Dp;
3583  poly F1 = (x2-y3)*(x3-y2);
3584  poly F2 = (x2-y3)*(xy4+y5+x4);
3585}
Note: See TracBrowser for help on using the repository browser.