source: git/Singular/LIB/dmodapp.lib @ 5887d7

spielwiese
Last change on this file since 5887d7 was 5887d7, checked in by Viktor Levandovskyy <levandov@…>, 15 years ago
*levandov: Appel definitions revisited git-svn-id: file:///usr/local/Singular/svn/trunk@11502 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 42.3 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: dmodapp.lib,v 1.20 2009-03-01 17:41:31 levandov Exp $";
3category="Noncommutative";
4info="
5LIBRARY: dmodapp.lib     Applications of algebraic D-modules
6AUTHORS: Viktor Levandovskyy,      levandov@math.rwth-aachen.de
7@*             Daniel Andres, daniel.andres@math.rwth-aachen.de
8
9GUIDE: Let R = K[x1,..xN] and D be the Weyl algebra in variables x1,..xN,d1,..dN.
10In this library there are the following procedures for algebraic D-modules:
11@* - localization of a holonomic module D/I with respect to a mult. closed set
12of all powers of a given polynomial F from R. Our aim is to compute an ideal L
13in D, such that D/L is a presentation of a localized module. Such L always exists, since
14such localizations are known to be holonomic and thus cyclic modules.
15The procedures for the localization are DLoc, SDLoc and DLoc0.
16
17@* - annihilator in Weyl algebra of a given polynomial F from R as well as of a given
18rational function G/F from Quot(R). These can be computed via annPoly resp. annRat.
19
20@* - initial form and initial ideals in Weyl algebras with respect to a given weight vector can be computed with the help of inForm, initialMalgrange, initialIdealW.
21
22@* - appelF1, appelF2 and appelF4 return ideals in parametric Weyl algebra, which
23annihilate corresponding Appel hypergeometric functions.
24
25
26MAIN PROCEDURES:
27
28annPoly(f);   annihilator of a polynomial f in the corr. Weyl algebra
29annRat(f,g);  annihilator of a rational function f/g in the corr. Weyl algebra
30DLoc(I,F);     presentation of the localization of D/I w.r.t. f^s
31SDLoc(I, F);  a generic presentation of the localization of D/I w.r.t. f^s, for D a Weyl algebra
32DLoc0(I, F);  presentation of the localization of D/I w.r.t. f^s, based on the procedure SDLoc
33
34initialMalgrange(f[,s,t,u,v]); Groebner basis of the initial Malgrange ideal for a given poly
35initialIdealW(I,u,v[,s,t]); initial ideal of a given ideal w.r.t. given weights
36inForm(f,w);     initial form of a poly/ideal w.r.t. a given weight
37isFsat(I, F);       check whether the ideal I is F-saturated
38
39AUXILIARY PROCEDURES:
40
41appelF1();      create an ideal annihilating Appel F1 function
42appelF2();      create an ideal annihilating Appel F2 function
43appelF4();      create an ideal annihilating Appel F4 function
44engine(I,i);     computes a Groebner basis with the algorithm given by i
45poly2list(f);   decompose a poly to a list of terms and exponents
46fl2poly(L,s);  reconstruct a monic univariate polynomial from its factorization
47insertGenerator(id,p[,k]); insert an element into an ideal/module
48deleteGenerator(id,k); delete the k-th element from an ideal/module
49
50
51SEE ALSO: dmod_lib, gmssing_lib, bfun_lib
52";
53
54LIB "poly.lib";
55LIB "sing.lib";
56LIB "primdec.lib";
57LIB "dmod.lib"; // loads e.g. nctools.lib
58LIB "bfun.lib"; //formerly LIB "bfct.lib";
59
60// todo: complete and include into above list
61// charVariety(I);       compute the characteristic variety of the ideal I
62// charInfo(); ???
63
64
65///////////////////////////////////////////////////////////////////////////////
66// testing for consistency of the library:
67proc testdmodapp()
68{
69  example initialIdealW;
70  example initialMalgrange;
71  example DLoc;
72  example DLoc0;
73  example SDLoc;
74  example inForm;
75  example isFsat;
76  example annRat;
77  example annPoly;
78  example appelF1;
79  example appelF2;
80  example appelF4;
81  example poly2list;
82  example fl2poly;
83  example insertGenerator;
84  example deleteGenerator;
85}
86
87
88proc initialIdealW (ideal I, intvec u, intvec v, list #)
89"USAGE:  initialIdealW(I,u,v [,s,t]);  I ideal, u,v intvecs, s,t optional ints
90RETURN:  ideal, GB of initial ideal of the input ideal wrt the weights u and v
91ASSUME: basering is the n-th Weyl algebra and the sequence of the indeterminates is x(1),...,x(n),D(1),...,D(n).
92PURPOSE: computes the initial ideal with respect to given weights.
93NOTE:    Let I be an ideal in the n-th Weyl algebra D, then
94@*       u and v understood as intvecs of weights for x(i) and D(i) respectively.
95@*       Note that the returned ideal is not an ideal in D, but an ideal in the associated
96@*       graded ring while the Groebner basis is a subset of D.
97@*       If s<>0, @code{std} is used for Groebner basis computations, otherwise,
98@*       and by default, @code{slimgb} is used.
99@*       If t<>0, a matrix ordering is used for Groebner basis computations,
100@*       otherwise, and by default, a block ordering is used.
101DISPLAY: If printlevel=1, progress debug messages will be printed,
102@*       if printlevel>=2, all the debug messages will be printed.
103EXAMPLE: example initialIdealW; shows examples
104"
105{
106  int ppl = printlevel - voice +2;
107  int i;
108  def save = basering;
109  int whichengine = 0; // default
110  int methodord   = 0; // default
111  if (size(#)>0)
112  {
113    if (typeof(#[1])=="int" || typeof(#[1])=="number")
114    {
115      whichengine = int(#[1]);
116    }
117    if (size(#)>1)
118    {
119      if (typeof(#[2])=="int" || typeof(#[2])=="number")
120      {
121        methodord = int(#[2]);
122      }
123    }
124  }
125  def D = initialIdealEngine("initialIdeal", whichengine, methodord, I, u, v);
126  ideal inF = fetch(D,inF); attrib(inF,"isSB",1);
127  return(inF);
128}
129example
130{
131  "EXAMPLE:"; echo = 2;
132  ring @D = 0,(x,Dx),dp;
133  def D = Weyl();
134  setring D;
135  intvec u = -1; intvec v = 2;
136  ideal I = x^2*Dx^2,x*Dx^4;
137  ideal J = initialIdealW(I,u,v); J;
138}
139
140proc initialMalgrange (poly f,list #)
141"USAGE:  initialMalgrange(f, [,s,t,u,v]);  f poly, s,t,u optional ints, v optional intvec
142RETURN:  ring, the Weyl algebra induced by basering, extended with vars t and Dt,
143@*       containing the ideal \"inF\", being the initial ideal of the Malgrange
144@*       ideal of f.
145PURPOSE: computes the initial Malgrange ideal of a given poly wrt the weight
146@*       vector (-1,0...,0,1,0,...,0) such that the weight of t is -1 and the
147@*       weight of Dt is 1.
148NOTE:    Activate the output ring with the @code{setring} command.
149@*       Varnames of the basering should not include t and Dt.
150@*       If s<>0, @code{std} is used for Groebner basis computations,
151@*       otherwise, and by default, @code{slimgb} is used.
152@*       If t<>0, a matrix ordering is used for Groebner basis computations,
153@*       otherwise, and by default, a block ordering is used.
154@*       If u<>0, the order of the variables is reversed.
155@*       If v is a positive weight vector, v is used for homogenization
156@*       computations, otherwise and by default, no weights are used.
157DISPLAY: If printlevel=1, progress debug messages will be printed,
158@*       if printlevel>=2, all the debug messages will be printed.
159EXAMPLE: example initialMalgrange; shows examples
160"
161{
162  int ppl = printlevel - voice +2;
163  def save = basering;
164  int n = nvars(save);
165  int whichengine = 0; // default
166  int methodord   = 0; // default
167  int reversevars = 0; // default
168  intvec u0 = 0;
169  if (size(#)>0)
170  {
171    if (typeof(#[1])=="int" || typeof(#[1])=="number")
172    {
173      whichengine = int(#[1]);
174    }
175    if (size(#)>1)
176    {
177      if (typeof(#[2])=="int" || typeof(#[2])=="number")
178      {
179        methodord = int(#[2]);
180      }
181      if (size(#)>2)
182      {
183        if (typeof(#[3])=="int" || typeof(#[3])=="number")
184        {
185          reversevars = int(#[3]);
186        }
187        if (size(#)>3)
188        {
189          if (typeof(#[4])=="intvec" && size(#[4])==n && allPositive(#[4])==1)
190          {
191            u0 = #[4];
192          }
193        }
194      }
195    }
196  }
197  if (u0 == 0)
198  {
199    u0 = 1:n;
200  }
201  def D = initialIdealEngine("initialMalgrange",whichengine, methodord, f, 0, 0, u0, reversevars);
202  setring save;
203  return(D);
204}
205example
206{
207  "EXAMPLE:"; echo = 2;
208  ring r = 0,(x,y),dp;
209  poly f = x^2+y^3+x*y^2;
210  def D = initialMalgrange(f);
211  setring D;
212  inF;
213  setring r;
214  intvec v = 3,2;
215  def D2 = initialMalgrange(f,1,0,1,v);
216  setring D2;
217  inF;
218}
219
220static proc initialIdealEngine(string calledfrom, int whichengine, int blockord, list #)
221{
222  //#[1] = f or I
223  //#[2] = u
224  //#[3] = v
225  //#[4] = u0
226  //#[5] = reversevars
227  int ppl = printlevel - voice +2;
228  def save = basering;
229  int i,n,noofvars;
230  n = nvars(save);
231  intvec uv;
232  if (calledfrom == "initialIdeal")
233  {
234    ideal I = #[1];
235    intvec u = #[2];
236    intvec v = #[3];
237    uv = u,v,0;
238    n = n/2;
239    noofvars = 2*n+1;
240  }
241  else // initialMalgrange
242  {
243    poly f = #[1];
244    uv[n+2] = 1;
245    noofvars = 2*n+3;
246    intvec u0 = #[4];
247    int reversevars = #[5];
248    ring r = 0,(x(1..n)),wp(u0);
249    poly f = fetch(save,f);
250    uv[1] = -1; uv[noofvars] = 0;
251  }
252  //  for the ordering
253  intvec @a;
254  if (calledfrom == "initialMalgrange")
255  {
256    int d = deg(f);
257    intvec weighttx = d;
258    for (i=1; i<=n; i++)
259    {
260      weighttx[i+1] = u0[n-i+1];
261    }
262    intvec weightD = 1;
263    for (i=1; i<=n; i++)
264    {
265      weightD[i+1] = d+1-u0[n-i+1];
266    }
267    @a = weighttx,weightD,1;
268  }
269  else // initialIdeal
270  {
271    @a = 1:noofvars;
272  }
273  if (blockord == 0) // default: blockordering
274  {
275    if (calledfrom == "initialMalgrange")
276    {
277      ring Dh = 0,(t,x(n..1),Dt,D(n..1),h),(a(@a),a(uv),dp(noofvars-1),lp(1));
278    }
279    else // initialIdeal
280    {
281      ring Dh = 0,(x(1..n),D(1..n),h),(a(@a),dp(noofvars-1),lp(1));
282    }
283  }
284  else // M() ordering
285  {
286    intmat @Ord[noofvars][noofvars];
287    @Ord[1,1..noofvars] = uv;
288    @Ord[2,1..noofvars] = 1:(noofvars-1);
289    for (i=1; i<=noofvars-2; i++)
290    {
291      @Ord[2+i,noofvars - i] = -1;
292    }
293    dbprint(ppl,"weights for ordering:",transpose(@a));
294    dbprint(ppl,"the ordering matrix:",@Ord);
295    if (calledfrom == "initialMalgrange")
296    {
297      ring Dh = 0,(t,x(n..1),Dt,D(n..1),h),(a(@a),M(@Ord));
298    }
299    else // initialIdeal
300    {
301      ring Dh = 0,(x(1..n),D(1..n),h),(a(@a),M(@Ord));
302    }
303  }
304  dbprint(ppl,"the ring Dh:",Dh);
305  // non-commutative relations
306  matrix @relD[noofvars][noofvars];
307  if (calledfrom == "initialMalgrange")
308  {
309    for (i=1; i<=n+1; i++) { @relD[i,n+1+i] = h^(d+1); }
310  }
311  else // initialIdeal
312  {
313    for (i=1; i<=n; i++)
314    {
315      @relD[i,n+i] = h^2;
316    }
317  }
318  dbprint(ppl,"nc relations:",@relD);
319  def DDh = nc_algebra(1,@relD);
320  setring DDh;
321  dbprint(ppl,"computing in ring",DDh);
322  ideal I;
323  if (calledfrom == "initialIdeal")
324  {
325    I = fetch(save,I);
326    I = homog(I,h);
327  }
328  else
329  {
330    poly f = imap(r,f);
331    kill r;
332    f = homog(f,h);
333    I = t-f;  // defining the Malgrange ideal
334    for (i=1; i<=n; i++)
335    {
336      I = I, D(i)+diff(f,x(i))*Dt;
337    }
338  }
339  dbprint(ppl, "starting Groebner basis computation with engine:", whichengine);
340  I = engine(I, whichengine);
341  dbprint(ppl, "finished Groebner basis computation");
342  dbprint(ppl, "I before dehomogenization is" ,I);
343  I = subst(I,h,1); // dehomogenization
344  dbprint(ppl, "I after dehomogenization is" ,I);
345  I = inForm(I,uv); // we are only interested in the initial form w.r.t. uv
346  if (calledfrom == "initialMalgrange")
347  {
348    // keep the names of the variables of the basering
349    setring save;
350    list rl = ringlist(save);
351    list varnames = rl[2];
352    for (i=1; i<=n; i++)
353    {
354      if (varnames[i] == "t")
355      {
356        ERROR("Variable names should not include t");
357      }
358    }
359    list newvarnamesrev = "t";
360    newvarnamesrev[n+2] = "Dt";
361    for (i=1; i<=n; i++)
362    {
363      newvarnamesrev[i+1] = varnames[n+1-i];
364      newvarnamesrev[i+n+2] = "D"+varnames[n+1-i];
365    }
366    rl[2]=newvarnamesrev;
367    def @Drev = ring(rl);
368    setring @Drev;
369    def Drev = Weyl(@Drev);
370    setring Drev;
371    ideal I = fetch(DDh,I);
372    kill Dh, DDh;
373    if (reversevars == 0)
374    {
375      setring save;
376      list newvarnames = "t";
377      newvarnames[n+2] = "Dt";
378      for (i=1; i<=n; i++)
379      {
380        newvarnames[i+1] = varnames[i];
381        newvarnames[i+n+2] = "D"+varnames[i];
382      }
383      rl[2] = newvarnames;
384      def @D = ring(rl);
385      setring @D;
386      def D = Weyl(@D);
387      setring D;
388      ideal I = imap(Drev,I);
389    }
390  }
391  else // initialIdeal
392  {
393    ring @D = 0,(x(1..n),D(1..n)),dp;
394    def D = Weyl(@D);
395    setring D;
396    ideal I = imap(DDh,I);
397    kill Dh,DDh;
398  }
399  dbprint(ppl, "starting cosmetic Groebner basis computation with engine:", whichengine);
400  I = engine(I, whichengine);
401  dbprint(ppl,"finished cosmetic Groebner basis computation:");
402  dbprint(ppl,"the initial ideal is:", I);
403  ideal inF = I; attrib(inF,"isSB",1);
404  export(inF);
405  return(basering);
406}
407
408proc inForm (ideal I, intvec w)
409"USAGE:  inForm(I,w);  I ideal, w intvec
410RETURN:  the initial form of I wrt the weight vector w
411PURPOSE: computes the initial form of an ideal wrt a given weight vector
412NOTE:  the size of the weight vector must be equal to the number of variables
413@*     of the basering.
414EXAMPLE: example inForm; shows examples
415"
416{
417  if (size(w) != nvars(basering))
418  {
419    ERROR("weight vector has wrong dimension");
420  }
421  if (I == 0)
422  {
423    return(I);
424  }
425  int j,i,s,m;
426  list l;
427  poly g;
428  ideal J;
429  for (j=1; j<=ncols(I); j++)
430  {
431    l = poly2list(I[j]);
432    m = scalarProd(w,l[1][1]);
433    g = l[1][2];
434    for (i=2; i<=size(l); i++)
435    {
436      s = scalarProd(w,l[i][1]);
437      if (s == m)
438      {
439        g = g + l[i][2];
440      }
441      else
442      {
443        if (s > m)
444        {
445          m = s;
446          g = l[i][2];
447        }
448      }
449    }
450    J[j] = g;
451  }
452  return(J);
453}
454example
455{
456  "EXAMPLE:"; echo = 2;
457  ring @D = 0,(x,y,Dx,Dy),dp;
458  def D = Weyl();
459  setring D;
460  poly F = 3*x^2*Dy+2*y*Dx;
461  poly G = 2*x*Dx+3*y*Dy+6;
462  ideal I = F,G;
463  intvec w1 = -1,-1,1,1;
464  intvec w2 = -1,-2,1,2;
465  intvec w3 = -2,-3,2,3;
466  inForm(I,w1);
467  inForm(I,w2);
468  inForm(I,w3);
469}
470
471/*
472
473proc charVariety(ideal I)
474"USAGE:  charVariety(I);  I an ideal
475RETURN:  ring
476PURPOSE: compute the characteristic variety of a D-module D/I
477STATUS: experimental, todo
478ASSUME: the ground ring is the Weyl algebra with x's before d's
479NOTE:    activate the output ring with the @code{setring} command.
480@*       In the output (in a commutative ring):
481@*       - the ideal CV is the characteristic variety char(I)
482@*       If @code{printlevel}=1, progress debug messages will be printed,
483@*       if @code{printlevel}>=2, all the debug messages will be printed.
484EXAMPLE: example charVariety; shows examples
485"
486{
487  // 1. introduce the weights 0, 1
488  def save = basering;
489  list LL = ringlist(save);
490  list L;
491  int i;
492  for(i=1;i<=4;i++)
493  {
494    L[i] = LL[i];
495  }
496  list OLD = L[3];
497  list NEW; list tmp;
498  tmp[1] = "a";  // string
499  intvec iv;
500  int N = nvars(basering); N = N div 2;
501  for(i=N+1; i<=2*N; i++)
502  {
503    iv[i] = 1;
504  }
505  tmp[2] = iv;
506  NEW[1] = tmp;
507  for (i=2; i<=size(OLD);i++)
508  {
509    NEW[i] = OLD[i-1];
510  }
511  L[3] = NEW;
512  list ncr =ncRelations(save);
513  matrix @C = ncr[1];
514  matrix @D = ncr[2];
515  def @U = ring(L);
516  // 2. create the commutative ring
517  setring save;
518  list CL;
519  for(i=1;i<=4;i++)
520  {
521    CL[i] = L[i];
522  }
523  CL[3] = OLD;
524  def @CU = ring(CL);
525  // comm ring is ready
526  setring @U;
527  // make @U noncommutative
528  matrix @C = imap(save,@C);
529  matrix @D = imap(save,@D);
530  def @@U = nc_algebra(@C,@D);
531  setring @@U; kill @U;
532  // 2. compute Groebner basis
533  ideal I = imap(save,I);
534  //  I = groebner(I);
535  I = slimgb(I); // a bug?
536  setring @CU;
537  ideal CV = imap(@@U,I);
538  //  CV = groebner(CV); // cosmetics
539  CV = slimgb(CV);
540  export CV;
541  return(@CU);
542}
543example
544{
545  "EXAMPLE:"; echo = 2;
546  ring r = 0,(x,y),Dp;
547  poly F = x3-y2;
548  printlevel = 0;
549  def A  = annfs(F);
550  setring A; // Weyl algebra
551  LD; // the ideal
552  def CA = charVariety(LD);
553  setring CA;
554  CV;
555  dim(CV);
556}
557
558/*
559
560// TODO
561
562/*
563proc charInfo(ideal I)
564"USAGE:  charInfo(I);  I an ideal
565RETURN:  ring
566STATUS: experimental, todo
567PURPOSE: compute the characteristic information for I
568ASSUME: the ground ring is the Weyl algebra with x's before d's
569NOTE:    activate the output ring with the @code{setring} command.
570@*       In the output (in a commutative ring):
571@*       - the ideal CV is the characteristic variety char(I)
572@*       - the ideal SL is the singular locus of char(I)
573@*       - the list PD is the primary decomposition of char(I)
574@*       If @code{printlevel}=1, progress debug messages will be printed,
575@*       if @code{printlevel}>=2, all the debug messages will be printed.
576EXAMPLE: example annfs; shows examples
577"
578{
579  def save = basering;
580  def @A = charVariety(I);
581  setring @A;
582  // run slocus
583  // run primdec
584}
585*/
586
587
588proc appelF1()
589"USAGE:  appelF1();
590RETURN:  ring
591PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F1 hypergeometric function
592NOTE: the ideal called  IAppel1 is exported to the output ring
593EXAMPLE: example appelF1; shows examples
594"
595{
596  // Appel F1, d = b', SST p.48
597  ring @r = (0,a,b,c,d),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
598  matrix @D[4][4];
599  @D[1,3]=1; @D[2,4]=1;
600  def @S = nc_algebra(1,@D);
601  setring @S;
602  ideal IAppel1 =
603    (x*Dx)*(x*Dx+y*Dy+c-1) - x*(x*Dx+y*Dy+a)*(x*Dx+b),
604    (y*Dy)*(x*Dx+y*Dy+c-1) - y*(x*Dx+y*Dy+a)*(y*Dy+d),
605    (x-y)*Dx*Dy - d*Dx + b*Dy;
606  export IAppel1;
607  kill @r;
608  return(@S);
609}
610example
611{
612  "EXAMPLE:"; echo = 2;
613  def A = appelF1();
614  setring A;
615  IAppel1;
616}
617
618proc appelF2() //(number a,b,c)
619"USAGE:  appelF2();
620RETURN:  ring
621PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F2 hypergeometric function
622NOTE: the ideal called  IAppel2 is exported to the output ring
623EXAMPLE: example appelF2; shows examples
624"
625{
626  // Appel F2, c = b', SST p.85
627  ring @r = (0,a,b,c),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
628  matrix @D[4][4];
629  @D[1,3]=1; @D[2,4]=1;
630  def @S = nc_algebra(1,@D);
631  setring @S;
632  ideal IAppel2 =
633    (x*Dx)^2 - x*(x*Dx+y*Dy+a)*(x*Dx+b),
634    (y*Dy)^2 - y*(x*Dx+y*Dy+a)*(y*Dy+c);
635  export IAppel2;
636  kill @r;
637  return(@S);
638}
639example
640{
641  "EXAMPLE:"; echo = 2;
642  def A = appelF2();
643  setring A;
644  IAppel2;
645}
646
647proc appelF4()
648"USAGE:  appelF4();
649RETURN:  ring
650PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F4 hypergeometric function
651NOTE: the ideal called  IAppel4 is exported to the output ring
652EXAMPLE: example appelF4; shows examples
653"
654{
655  // Appel F4, d = c', SST, p. 39
656  ring @r = (0,a,b,c,d),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
657  matrix @D[4][4];
658  @D[1,3]=1; @D[2,4]=1;
659  def @S = nc_algebra(1,@D);
660  setring @S;
661  ideal IAppel4 =
662    Dx*(x*Dx+c-1) - (x*Dx+y*Dy+a)*(x*Dx+y*Dy+b),
663    Dy*(y*Dy+d-1) - (x*Dx+y*Dy+a)*(x*Dx+y*Dy+b);
664  export IAppel4;
665  kill @r;
666  return(@S);
667}
668example
669{
670  "EXAMPLE:"; echo = 2;
671  def A = appelF4();
672  setring A;
673  IAppel4;
674}
675
676proc poly2list (poly f)
677"USAGE:  poly2list(f); f a poly
678RETURN:  list of exponents and corresponding terms of f
679PURPOSE: convert a polynomial to a list of exponents and corresponding terms
680EXAMPLE: example poly2list; shows examples
681"
682{
683  list l;
684  int i = 1;
685  if (f == 0) // just for the zero polynomial
686  {
687    l[1] = list(leadexp(f), lead(f));
688  }
689  else { l[size(f)] = list(); } // memory pre-allocation
690  while (f != 0)
691  {
692    l[i] = list(leadexp(f), lead(f));
693    f = f - lead(f);
694    i++;
695  }
696  return(l);
697}
698example
699{
700  "EXAMPLE:"; echo = 2;
701  ring r = 0,x,dp;
702  poly F = x;
703  poly2list(F);
704  ring r2 = 0,(x,y),dp;
705  poly F = x2y+x*y2;
706  poly2list(F);
707}
708
709proc isFsat(ideal I, poly F)
710"USAGE:  isFsat(I, F);  I an ideal, F a poly
711RETURN: int
712PURPOSE: check whether the ideal I is F-saturated
713NOTE:    1 is returned if I is F-saturated, otherwise 0 is returned.
714@*   we check indeed that Ker(D --F--> D/I) is (0)
715EXAMPLE: example isFsat; shows examples
716"
717{
718  /* checks whether I is F-saturated, that is Ke  (D -F-> D/I) is 0 */
719  /* works in any algebra */
720  /*  for simplicity : later check attrib */
721  /* returns -1 if true */
722  if (attrib(I,"isSB")!=1)
723  {
724    I = groebner(I);
725  }
726  matrix @M = matrix(I);
727  matrix @F[1][1] = F;
728  module S = modulo(@F,@M);
729  S = NF(S,I);
730  S = groebner(S);
731  return( (gkdim(S) == -1) );
732}
733example
734{
735  "EXAMPLE:"; echo = 2;
736  ring r = 0,(x,y),dp;
737  poly G = x*(x-y)*y;
738  def A = annfs(G);
739  setring A;
740  poly F = x3-y2;
741  isFsat(LD,F);
742  ideal J = LD*F;
743  isFsat(J,F);
744}
745
746proc DLoc(ideal I, poly F)
747"USAGE:  DLoc(I, F);  I an ideal, F a poly
748RETURN: nothing (exports objects instead)
749ASSUME: the basering is a Weyl algebra
750PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s
751NOTE:    In the basering, the following objects are exported:
752@*       - the ideal LD0 (which is a Groebner basis) is the presentation of the localization
753@*       - the ideal BS contains the roots with multiplicities of a Bernstein polynomial of D/I w.r.t f.
754@*       If printlevel=1, progress debug messages will be printed,
755@*       if printlevel>=2, all the debug messages will be printed.
756EXAMPLE: example DLoc; shows examples
757"
758{
759  /* runs SDLoc and DLoc0 */
760  /* assume: run from Weyl algebra */
761  int old_printlevel = printlevel;
762  printlevel=printlevel+1;
763  def @R = basering;
764  def @R2 = SDLoc(I,F);
765  setring @R2;
766  poly F = imap(@R,F);
767  def @R3 = DLoc0(LD,F);
768  setring @R3;
769  ideal bs = BS[1];
770  intvec m = BS[2];
771  setring @R;
772  ideal LD0 = imap(@R3,LD0);
773  export LD0;
774  ideal bs = imap(@R3,bs);
775  list BS; BS[1] = bs; BS[2] = m;
776  export BS;
777  kill @R3;
778  printlevel = old_printlevel;
779}
780example;
781{
782  "EXAMPLE:"; echo = 2;
783  ring r = 0,(x,y,Dx,Dy),dp;
784  def R = Weyl();    setring R;
785  poly F = x2-y3;
786  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
787  DLoc(I, x2-y3);
788  LD0;
789  BS;
790}
791
792proc DLoc0(ideal I, poly F)
793"USAGE:  DLoc0(I, F);  I an ideal, F a poly
794RETURN:  ring
795PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s, where D is a Weyl Algebra, based on the output of procedure SDLoc
796ASSUME: the basering is similar to the output ring of SDLoc procedure
797NOTE:    activate this ring with the @code{setring} command. In this ring,
798@*       - the ideal LD0 (which is a Groebner basis) is the presentation of the localization
799@*       - the ideal BS contains the roots with multiplicities of a Bernstein polynomial of D/I w.r.t f.
800@*       If printlevel=1, progress debug messages will be printed,
801@*       if printlevel>=2, all the debug messages will be printed.
802EXAMPLE: example DLoc0; shows examples
803"
804{
805  /* assume: to be run in the output ring of SDLoc */
806  /* doing: add F, eliminate vars*Dvars, factorize BS */
807  /* analogue to annfs0 */
808  def @R2 = basering;
809  // we're in D_n[s], where the elim ord for s is set
810  ideal J = NF(I,std(F));
811  // make leadcoeffs positive
812  int i;
813  for (i=1; i<= ncols(J); i++)
814  {
815    if (leadcoef(J[i]) <0 )
816    {
817      J[i] = -J[i];
818    }
819  }
820  J = J,F;
821  ideal M = groebner(J);
822  int Nnew = nvars(@R2);
823  ideal K2 = nselect(M,1..Nnew-1);
824  int ppl = printlevel-voice+2;
825  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
826  dbprint(ppl-1, K2);
827  // the ring @R3 and the search for minimal negative int s
828  ring @R3 = 0,s,dp;
829  dbprint(ppl,"// -2-1- the ring @R3 = K[s] is ready");
830  ideal K3 = imap(@R2,K2);
831  poly p = K3[1];
832  dbprint(ppl,"// -2-2- attempt the factorization");
833  list PP = factorize(p);          //with constants and multiplicities
834  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
835  for (i=2; i<= size(PP[1]); i++)  //we delete P[1][1] and P[2][1]
836  {
837    bs[i-1] = PP[1][i];
838    m[i-1]  = PP[2][i];
839  }
840  ideal bbs; int srat=0; int HasRatRoots = 0;
841  int sP;
842  for (i=1; i<= size(bs); i++)
843  {
844    if (deg(bs[i]) == 1)
845    {
846      bbs = bbs,bs[i];
847    }
848  }
849  if (size(bbs)==0)
850  {
851    dbprint(ppl-1,"// -2-3- factorization: no rational roots");
852    //    HasRatRoots = 0;
853    HasRatRoots = 1; // s0 = -1 then
854    sP = -1;
855    // todo: return ideal with no subst and a b-function unfactorized
856  }
857  else
858  {
859    // exist rational roots
860    dbprint(ppl-1,"// -2-3- factorization: rational roots found");
861    HasRatRoots = 1;
862    //    dbprint(ppl-1,bbs);
863    bbs = bbs[2..ncols(bbs)];
864    ideal P = bbs;
865    dbprint(ppl-1,P);
866    srat = size(bs) - size(bbs);
867    // define minIntRoot on linear factors or find out that it doesn't exist
868    intvec vP;
869    number nP;
870    P = normalize(P); // now leadcoef = 1
871    P = lead(P)-P;
872    sP = size(P);
873    int cnt = 0;
874    for (i=1; i<=sP; i++)
875    {
876      nP = leadcoef(P[i]);
877      if ( (nP - int(nP)) == 0 )
878      {
879        cnt++;
880        vP[cnt] = int(nP);
881      }
882    }
883//     if ( size(vP)>=2 )
884//     {
885//       vP = vP[2..size(vP)];
886//     }
887    if ( size(vP)==0 )
888    {
889      // no roots!
890      dbprint(ppl,"// -2-4- no integer root, setting s0 = -1");
891      sP = -1;
892      //      HasRatRoots = 0; // older stuff, here we do substitution
893      HasRatRoots = 1;
894    }
895    else
896    {
897      HasRatRoots = 1;
898      sP = -Max(-vP);
899      dbprint(ppl,"// -2-4- minimal integer root found");
900      dbprint(ppl-1, sP);
901      //    int sP = minIntRoot(bbs,1);
902//       P =  normalize(P);
903//       bs = -subst(bs,s,0);
904      if (sP >=0)
905      {
906        dbprint(ppl,"// -2-5- nonnegative root, setting s0 = -1");
907        sP = -1;
908      }
909      else
910      {
911        dbprint(ppl,"// -2-5- the root is negative");
912      }
913    }
914  }
915
916  if (HasRatRoots)
917  {
918    setring @R2;
919    K2 = subst(I,s,sP);
920    // IF min int root exists ->
921    // create the ordinary Weyl algebra and put the result into it,
922    // thus creating the ring @R5
923    // ELSE : return the same ring with new objects
924    // keep: N, i,j,s, tmp, RL
925    Nnew = Nnew - 1; // former 2*N;
926    // list RL = ringlist(save);  // is defined earlier
927    //  kill Lord, tmp, iv;
928    list L = 0;
929    list Lord, tmp;
930    intvec iv;
931    list RL = ringlist(basering);
932    L[1] = RL[1];
933    L[4] = RL[4];  //char, minpoly
934    // check whether vars have admissible names -> done earlier
935    // list Name = RL[2]M
936    // DName is defined earlier
937    list NName; // = RL[2]; // skip the last var 's'
938    for (i=1; i<=Nnew; i++)
939    {
940      NName[i] =  RL[2][i];
941    }
942    L[2] = NName;
943    // dp ordering;
944    string s = "iv=";
945    for (i=1; i<=Nnew; i++)
946    {
947      s = s+"1,";
948    }
949    s[size(s)] = ";";
950    execute(s);
951    tmp     = 0;
952    tmp[1]  = "dp";  // string
953    tmp[2]  = iv;  // intvec
954    Lord[1] = tmp;
955    kill s;
956    tmp[1]  = "C";
957    iv = 0;
958    tmp[2]  = iv;
959    Lord[2] = tmp;
960    tmp     = 0;
961    L[3]    = Lord;
962    // we are done with the list
963    // Add: Plural part
964    def @R4@ = ring(L);
965    setring @R4@;
966    int N = Nnew/2;
967    matrix @D[Nnew][Nnew];
968    for (i=1; i<=N; i++)
969    {
970      @D[i,N+i]=1;
971    }
972    def @R4 = nc_algebra(1,@D);
973    setring @R4;
974    kill @R4@;
975    dbprint(ppl,"// -3-1- the ring @R4 is ready");
976    dbprint(ppl-1, @R4);
977    ideal K4 = imap(@R2,K2);
978    option(redSB);
979    dbprint(ppl,"// -3-2- the final cosmetic std");
980    K4 = groebner(K4);  // std does the job too
981    // total cleanup
982    setring @R2;
983    ideal bs = imap(@R3,bs);
984    bs = -normalize(bs); // "-" for getting correct coeffs!
985    bs = subst(bs,s,0);
986    kill @R3;
987    setring @R4;
988    ideal bs = imap(@R2,bs); // only rationals are the entries
989    list BS; BS[1] = bs; BS[2] = m;
990    export BS;
991    //    list LBS = imap(@R3,LBS);
992    //    list BS; BS[1] = sbs; BS[2] = m;
993    //    BS;
994    //    export BS;
995    ideal LD0 = K4;
996    export LD0;
997    return(@R4);
998  }
999  else
1000  {
1001    /* SHOULD NEVER GET THERE */
1002    /* no rational/integer roots */
1003    /* return objects in the copy of current ring */
1004    setring @R2;
1005    ideal LD0 = I;
1006    poly BS = normalize(K2[1]);
1007    export LD0;
1008    export BS;
1009    return(@R2);
1010  }
1011}
1012example;
1013{
1014  "EXAMPLE:"; echo = 2;
1015  ring r = 0,(x,y,Dx,Dy),dp;
1016  def R = Weyl();    setring R;
1017  poly F = x2-y3;
1018  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
1019  def W = SDLoc(I,F);  setring W; // creates ideal LD
1020  def U = DLoc0(LD, x2-y3);  setring U;
1021  LD0;
1022  BS;
1023}
1024
1025
1026proc SDLoc(ideal I, poly F)
1027"USAGE:  SDLoc(I, F);  I an ideal, F a poly
1028RETURN:  ring
1029PURPOSE: compute a generic presentation of the localization of D/I w.r.t. f^s, where D is a Weyl Algebra
1030ASSUME: the basering is a Weyl algebra
1031NOTE:    activate this ring with the @code{setring} command. In this ring,
1032@*       - the ideal LD (which is a Groebner basis) is the presentation of the localization
1033@*       If printlevel=1, progress debug messages will be printed,
1034@*       if printlevel>=2, all the debug messages will be printed.
1035EXAMPLE: example SDLoc; shows examples
1036"
1037{
1038  /* analogue to Sannfs */
1039  /* printlevel >=4 gives debug info */
1040  /* assume: we're in the Weyl algebra D  in x1,x2,...,d1,d2,... */
1041  def save = basering;
1042  /* 1. create D <t, dt, s > as in LOT */
1043  /* ordering: eliminate t,dt */
1044  int ppl = printlevel-voice+2;
1045  int N = nvars(save); N = N div 2;
1046  int Nnew = 2*N + 3; // t,Dt,s
1047  int i,j;
1048  string s;
1049  list RL = ringlist(save);
1050  list L, Lord;
1051  list tmp;
1052  intvec iv;
1053  L[1] = RL[1]; // char
1054  L[4] = RL[4]; // char, minpoly
1055  // check whether vars have admissible names
1056  list Name  = RL[2];
1057  list RName;
1058  RName[1] = "@t";
1059  RName[2] = "@Dt";
1060  RName[3] = "s";
1061  for(i=1;i<=N;i++)
1062  {
1063    for(j=1; j<=size(RName);j++)
1064    {
1065      if (Name[i] == RName[j])
1066      {
1067        ERROR("Variable names should not include @t,@Dt,s");
1068      }
1069    }
1070  }
1071  // now, create the names for new vars
1072  tmp    =  0;
1073  tmp[1] = "@t";
1074  tmp[2] = "@Dt";
1075  list SName ; SName[1] = "s";
1076  list NName = tmp + Name + SName;
1077  L[2]   = NName;
1078  tmp    = 0;
1079  kill NName;
1080  // block ord (a(1,1),dp);
1081  tmp[1]  = "a"; // string
1082  iv      = 1,1;
1083  tmp[2]  = iv; //intvec
1084  Lord[1] = tmp;
1085  // continue with dp 1,1,1,1...
1086  tmp[1]  = "dp"; // string
1087  s       = "iv=";
1088  for(i=1;i<=Nnew;i++)
1089  {
1090    s = s+"1,";
1091  }
1092  s[size(s)]= ";";
1093  execute(s);
1094  tmp[2]    = iv;
1095  Lord[2]   = tmp;
1096  tmp[1]    = "C";
1097  iv        = 0;
1098  tmp[2]    = iv;
1099  Lord[3]   = tmp;
1100  tmp       = 0;
1101  L[3]      = Lord;
1102  // we are done with the list
1103  def @R@ = ring(L);
1104  setring @R@;
1105  matrix @D[Nnew][Nnew];
1106  @D[1,2]=1;
1107  for(i=1; i<=N; i++)
1108  {
1109    @D[2+i,N+2+i]=1;
1110  }
1111  // ADD [s,t]=-t, [s,Dt]=Dt
1112  @D[1,Nnew] = -var(1);
1113  @D[2,Nnew] = var(2);
1114  def @R = nc_algebra(1,@D);
1115  setring @R;
1116  kill @R@;
1117  dbprint(ppl,"// -1-1- the ring @R(t,Dt,_x,_Dx,s) is ready");
1118  dbprint(ppl-1, @R);
1119  poly  F = imap(save,F);
1120  ideal I = imap(save,I);
1121  dbprint(ppl-1, "the ideal after map:");
1122  dbprint(ppl-1, I);
1123  poly p = 0;
1124  for(i=1; i<=N; i++)
1125  {
1126    p = diff(F,var(2+i))*@Dt + var(2+N+i);
1127    dbprint(ppl-1, p);
1128    I = subst(I,var(2+N+i),p);
1129    dbprint(ppl-1, var(2+N+i));
1130    p = 0;
1131  }
1132  I = I, @t - F;
1133  // t*Dt + s +1 reduced with t-f gives f*Dt + s
1134  I = I, F*var(2) + var(Nnew);
1135  // -------- the ideal I is ready ----------
1136  dbprint(ppl,"// -1-2- starting the elimination of @t,@Dt in @R");
1137  dbprint(ppl-1, I);
1138  //  ideal J = engine(I,eng);
1139  ideal J = groebner(I);
1140  dbprint(ppl-1,"// -1-2-1- result of the  elimination of @t,@Dt in @R");
1141  dbprint(ppl-1, J);;
1142  ideal K = nselect(J,1..2);
1143  dbprint(ppl,"// -1-3- @t,@Dt are eliminated");
1144  dbprint(ppl-1, K);  // K is without t, Dt
1145  K = groebner(K);  // std does the job too
1146  // now, we must change the ordering
1147  // and create a ring without t, Dt
1148  setring save;
1149  // ----------- the ring @R3 ------------
1150  // _x, _Dx,s;  elim.ord for _x,_Dx.
1151  // keep: N, i,j,s, tmp, RL
1152  Nnew = 2*N+1;
1153  kill Lord, tmp, iv, RName;
1154  list Lord, tmp;
1155  intvec iv;
1156  L[1] = RL[1];
1157  L[4] = RL[4];  // char, minpoly
1158  // check whether vars hava admissible names -> done earlier
1159  // now, create the names for new var
1160  tmp[1] = "s";
1161  list NName = Name + tmp;
1162  L[2] = NName;
1163  tmp = 0;
1164  // block ord (dp(N),dp);
1165  // string s is already defined
1166  s = "iv=";
1167  for (i=1; i<=Nnew-1; i++)
1168  {
1169    s = s+"1,";
1170  }
1171  s[size(s)]=";";
1172  execute(s);
1173  tmp[1] = "dp";  // string
1174  tmp[2] = iv;   // intvec
1175  Lord[1] = tmp;
1176  // continue with dp 1,1,1,1...
1177  tmp[1] = "dp";  // string
1178  s[size(s)] = ",";
1179  s = s+"1;";
1180  execute(s);
1181  kill s;
1182  kill NName;
1183  tmp[2]      = iv;
1184  Lord[2]     = tmp;
1185  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
1186  Lord[3]     = tmp;  tmp = 0;
1187  L[3]        = Lord;
1188  // we are done with the list. Now add a Plural part
1189  def @R2@ = ring(L);
1190  setring @R2@;
1191  matrix @D[Nnew][Nnew];
1192  for (i=1; i<=N; i++)
1193  {
1194    @D[i,N+i]=1;
1195  }
1196  def @R2 = nc_algebra(1,@D);
1197  setring @R2;
1198  kill @R2@;
1199  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
1200  dbprint(ppl-1, @R2);
1201  ideal MM = maxideal(1);
1202  MM = 0,s,MM;
1203  map R01 = @R, MM;
1204  ideal K = R01(K);
1205  // total cleanup
1206  ideal LD = K;
1207  // make leadcoeffs positive
1208  for (i=1; i<= ncols(LD); i++)
1209  {
1210    if (leadcoef(LD[i]) <0 )
1211    {
1212      LD[i] = -LD[i];
1213    }
1214  }
1215  export LD;
1216  kill @R;
1217  return(@R2);
1218}
1219example;
1220{
1221  "EXAMPLE:"; echo = 2;
1222  ring r = 0,(x,y,Dx,Dy),dp;
1223  def R = Weyl();
1224  setring R;
1225  poly F = x2-y3;
1226  ideal I = Dx*F, Dy*F;
1227  def W = SDLoc(I,F);
1228  setring W;
1229  LD;
1230}
1231
1232proc annRat(poly g, poly f)
1233"USAGE:  annRat(g,f);  f, g polynomials
1234RETURN:  ring
1235PURPOSE: compute the ideal in Weyl algebra, annihilating the rational function g*f^{-1}
1236NOTE:    activate the output ring with the @code{setring} command.
1237@*       In the output ring:
1238@*       - the ideal LD (which is given in a Groebner basis) is the annihilator.
1239@*       If @code{printlevel}=1, progress debug messages will be printed,
1240@*       if @code{printlevel}>=2, all the debug messages will be printed.
1241EXAMPLE: example annRat; shows examples
1242"
1243{
1244  // computes the annihilator of g/f
1245  def save = basering;
1246  int ppl = printlevel-voice+2;
1247  dbprint(ppl,"// -1-[annRat] computing the ann f^s");
1248  def  @R1 = SannfsBM(f);
1249  setring @R1;
1250  poly f = imap(save,f);
1251  int i,mir;
1252  int isr = 0; // checkRoot1(LD,f,1); // roots are negative, have to enter positive int
1253  if (!isr)
1254  {
1255    // -1 is not the root
1256    // find the m.i.r iteratively
1257    mir = 0;
1258    for(i=nvars(save)+1; i>=1; i--)
1259    {
1260      isr =  checkRoot1(LD,f,i);
1261      if (isr) { mir =-i; break; }
1262    }
1263    if (mir ==0)
1264    {
1265      "No integer root found! Aborting computations, inform the authors!";
1266      return(0);
1267    }
1268    // now mir == i is m.i.r.
1269  }
1270  else
1271  {
1272    // -1 is the m.i.r
1273    mir = -1;
1274  }
1275  dbprint(ppl,"// -2-[annRat] the minimal integer root is ");
1276  dbprint(ppl-1, mir);
1277  // use annfspecial
1278  dbprint(ppl,"// -3-[annRat] running annfspecial ");
1279  ideal AF = annfspecial(LD,f,mir,-1); // ann f^{-1}
1280  //  LD = subst(LD,s,j);
1281  //  LD = engine(LD,0);
1282  // modify the ring: throw s away
1283  // output ring comes from SannfsBM
1284  list U = ringlist(@R1);
1285  list tmp; // variables
1286  for(i=1; i<=size(U[2])-1; i++)
1287  {
1288    tmp[i] = U[2][i];
1289  }
1290  U[2] = tmp;
1291  tmp = 0;
1292  tmp[1] = U[3][1]; // x,Dx block
1293  tmp[2] = U[3][3]; // module block
1294  U[3] = tmp;
1295  tmp = 0;
1296  tmp = U[1],U[2],U[3],U[4];
1297  def @R2 = ring(tmp);
1298  setring @R2;
1299  // now supply with Weyl algebra relations
1300  int N = nvars(@R2)/2;
1301  matrix @D[2*N][2*N];
1302  for(i=1; i<=N; i++)
1303  {
1304    @D[i,N+i]=1;
1305  }
1306  def @R3 = nc_algebra(1,@D);
1307  setring @R3;
1308  dbprint(ppl,"// - -[annRat] ring without s is ready:");
1309  dbprint(ppl-1,@R3);
1310  poly g = imap(save,g);
1311  matrix G[1][1] = g;
1312  matrix LL = matrix(imap(@R1,AF));
1313  kill @R1;   kill @R2;
1314  dbprint(ppl,"// -4-[annRat] running modulo");
1315  ideal LD  = modulo(G,LL);
1316  dbprint(ppl,"// -4-[annRat] running GB on the final result");
1317  LD  = engine(LD,0);
1318  export LD;
1319  return(@R3);
1320}
1321example
1322{
1323  "EXAMPLE:"; echo = 2;
1324  ring r = 0,(x,y),dp;
1325  poly g = 2*x*y;  poly f = x^2 - y^3;
1326  def B = annRat(g,f);
1327  setring B;
1328  LD;
1329  // Now, compare with the output of Macaulay2:
1330  ideal tst = 3*x*Dx + 2*y*Dy + 1, y^3*Dy^2 - x^2*Dy^2 + 6*y^2*Dy + 6*y,
13319*y^2*Dx^2*Dy - 4*y*Dy^3 + 27*y*Dx^2 + 2*Dy^2, 9*y^3*Dx^2 - 4*y^2*Dy^2 + 10*y*Dy -10;
1332 option(redSB); option(redTail);
1333 LD = groebner(LD);
1334 tst = groebner(tst);
1335 print(matrix(NF(LD,tst)));  print(matrix(NF(tst,LD)));
1336 // So, these two answers are the same
1337}
1338
1339/*
1340//static proc ex_annRat()
1341{
1342  // more complicated example for annRat
1343  ring r = 0,(x,y,z),dp;
1344  poly f = x3+y3+z3; // mir = -2
1345  poly g = x*y*z;
1346  def A = annRat(g,f);
1347  setring A;
1348}
1349*/
1350
1351proc annPoly(poly f)
1352"USAGE:  annPoly(f);  f a poly
1353RETURN:  ring
1354PURPOSE: compute the ideal in Weyl algebra, annihilating the polynomial f
1355NOTE:    activate the output ring with the @code{setring} command.
1356@*       In the output ring:
1357@*       - the ideal LD (which is given in a Groebner basis) is the annihilator.
1358@*       If @code{printlevel}=1, progress debug messages will be printed,
1359@*       if @code{printlevel}>=2, all the debug messages will be printed.
1360SEE ALSO: annRat
1361EXAMPLE: example annPoly; shows examples
1362"
1363{
1364  // computes a system of linear PDEs with polynomial coeffs for f
1365  def save = basering;
1366  list L = ringlist(save);
1367  list Name = L[2];
1368  int N = nvars(save);
1369  int i;
1370  for (i=1; i<=N; i++)
1371  {
1372    Name[N+i] = "D"+Name[i]; // concat
1373  }
1374  L[2] = Name;
1375  def @R = ring(L);
1376  setring @R;
1377  def @@R = Weyl();
1378  setring @@R;
1379  kill @R;
1380  matrix M[1][N];
1381  for (i=1; i<=N; i++)
1382  {
1383    M[1,i] = var(N+i);
1384  }
1385  matrix F[1][1] = imap(save,f);
1386  ideal I = modulo(F,M);
1387  ideal LD = groebner(I);
1388  export LD;
1389  return(@@R);
1390}
1391example
1392{
1393  "EXAMPLE:"; echo = 2;
1394  ring r = 0,(x,y,z),dp;
1395  poly f = x^2*z - y^3;
1396  def A = annPoly(f);
1397  setring A;
1398  LD;
1399  gkdim(LD); // must be 3 since LD is holonomic
1400  NF(Dy^4, LD); // must be 0 since Dy^4 clearly annihilates f
1401}
1402
1403/* DIFFERENT EXAMPLES
1404
1405//static proc exCusp()
1406{
1407  "EXAMPLE:"; echo = 2;
1408  ring r = 0,(x,y,Dx,Dy),dp;
1409  def R = Weyl();   setring R;
1410  poly F = x2-y3;
1411  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
1412  def W = SDLoc(I,F);
1413  setring W;
1414  LD;
1415  def U = DLoc0(LD,x2-y3);
1416  setring U;
1417  LD0;
1418  BS;
1419  // the same with DLoc:
1420  setring R;
1421  DLoc(I,F);
1422}
1423
1424//static proc exWalther1()
1425{
1426  // p.18 Rem 3.10
1427  ring r = 0,(x,Dx),dp;
1428  def R = nc_algebra(1,1);
1429  setring R;
1430  poly F = x;
1431  ideal I = x*Dx+1;
1432  def W = SDLoc(I,F);
1433  setring W;
1434  LD;
1435  ideal J = LD, x;
1436  eliminate(J,x*Dx); // must be [1]=s // agree!
1437  // the same result with Dloc0:
1438  def U = DLoc0(LD,x);
1439  setring U;
1440  LD0;
1441  BS;
1442}
1443
1444//static proc exWalther2()
1445{
1446  // p.19 Rem 3.10 cont'd
1447  ring r = 0,(x,Dx),dp;
1448  def R = nc_algebra(1,1);
1449  setring R;
1450  poly F = x;
1451  ideal I = (x*Dx)^2+1;
1452  def W = SDLoc(I,F);
1453  setring W;
1454  LD;
1455  ideal J = LD, x;
1456  eliminate(J,x*Dx); // must be [1]=s^2+2*s+2 // agree!
1457  // the same result with Dloc0:
1458  def U = DLoc0(LD,x);
1459  setring U;
1460  LD0;
1461  BS;
1462  // almost the same with DLoc
1463  setring R;
1464  DLoc(I,F);
1465  LD0;  BS;
1466}
1467
1468//static proc exWalther3()
1469{
1470  // can check with annFs too :-)
1471  // p.21 Ex 3.15
1472  LIB "nctools.lib";
1473  ring r = 0,(x,y,z,w,Dx,Dy,Dz,Dw),dp;
1474  def R = Weyl();
1475  setring R;
1476  poly F = x2+y2+z2+w2;
1477  ideal I = Dx,Dy,Dz,Dw;
1478  def W = SDLoc(I,F);
1479  setring W;
1480  LD;
1481  ideal J = LD, x2+y2+z2+w2;
1482  eliminate(J,x*y*z*w*Dx*Dy*Dz*Dw); // must be [1]=s^2+3*s+2 // agree
1483  ring r2 =  0,(x,y,z,w),dp;
1484  poly F = x2+y2+z2+w2;
1485  def Z = annfs(F);
1486  setring Z;
1487  LD;
1488  BS;
1489  // the same result with Dloc0:
1490  setring W;
1491  def U = DLoc0(LD,x2+y2+z2+w2);
1492  setring U;
1493  LD0;  BS;
1494  // the same result with DLoc:
1495  setring R;
1496  DLoc(I,F);
1497  LD0;  BS;
1498}
1499
1500*/
1501
1502proc engine(ideal I, int i)
1503"USAGE:  engine(I,i);  I an ideal, i an int
1504RETURN:  ideal
1505PURPOSE: compute the Groebner basis of I with the algorithm, chosen via i
1506NOTE: By default and if i=0, slimgb is used; otherwise std does the job.
1507EXAMPLE: example engine; shows examples
1508"
1509{
1510  /* std - slimgb mix */
1511  ideal J;
1512  if (i==0)
1513  {
1514    J = slimgb(I);
1515  }
1516  else
1517  {
1518    // without options -> strange! (ringlist?)
1519    option(redSB);
1520    option(redTail);
1521    J = std(I);
1522  }
1523  return(J);
1524}
1525example
1526{
1527  "EXAMPLE:"; echo = 2;
1528  ring r = 0,(x,y),Dp;
1529  ideal I  = y*(x3-y2),x*(x3-y2);
1530  engine(I,0); // uses slimgb
1531  engine(I,1); // uses std
1532}
1533
1534proc insertGenerator (list #)
1535"USAGE:  insertGenerator(id,p[,k]);  id an ideal/module, p a poly/vector, k an optional int
1536RETURN:  same as id
1537PURPOSE: insert an element into an ideal or a module
1538NOTE:    If k is given, p is inserted at position k, otherwise (and by default),
1539@*       p is inserted at the beginning.
1540EXAMPLE: example insertGenerator; shows examples
1541"
1542{
1543  if (size(#) < 2)
1544  {
1545    ERROR("insertGenerator has to be called with at least 2 arguments (ideal/module,poly/vector)");
1546  }
1547  string inp1 = typeof(#[1]);
1548  if (inp1 == "ideal" || inp1 == "module")
1549  {
1550    if (inp1 == "ideal") { ideal id = #[1]; }
1551    else { module id = #[1]; }
1552  }
1553  else { ERROR("first argument has to be of type ideal or module"); }
1554  string inp2 = typeof(#[2]);
1555  if (inp2 == "poly" || inp2 == "vector")
1556  {
1557    if (inp2 =="poly") { poly f = #[2]; }
1558    else
1559    {
1560      if (inp1 == "ideal")
1561      {
1562        ERROR("second argument has to be a poly if first argument is an ideal");
1563      }
1564      else { vector f = #[2]; }
1565    }
1566  }
1567  else { ERROR("second argument has to be of type poly/vector"); }
1568  int n = ncols(id);
1569  int k = 1; // default
1570  if (size(#)>=3)
1571  {
1572    if (typeof(#[3]) == "int")
1573    {
1574      k = #[3];
1575      if (k<=0)
1576      {
1577        ERROR("third argument has to be positive");
1578      }
1579    }
1580    else { ERROR("third argument has to be of type int"); }
1581  }
1582  execute(inp1 +" J;");
1583  if (k == 1) { J = f,id; }
1584  else
1585  {
1586    if (k>n)
1587    {
1588      J = id;
1589      J[k] = f;
1590    }
1591    else // 1<k<=n
1592    {
1593      J[1..k-1] = id[1..k-1];
1594      J[k] = f;
1595      J[k+1..n+1] = id[k..n];
1596    }
1597  }
1598  return(J);
1599}
1600example
1601{
1602  "EXAMPLE:"; echo = 2;
1603  ring r = 0,(x,y,z),dp;
1604  ideal I = x^2,z^4;
1605  insertGenerator(I,y^3);
1606  insertGenerator(I,y^3,2);
1607  module M = I;
1608  insertGenerator(M,[x^3,y^2,z],2);
1609}
1610
1611proc deleteGenerator (list #)
1612"USAGE:  deleteGenerator(id,k);  id an ideal/module, k an int
1613RETURN:  same as id
1614PURPOSE: deletes the k-th element from an ideal or a module
1615EXAMPLE: example insertGenerator; shows examples
1616"
1617{
1618  if (size(#) < 2)
1619  {
1620    ERROR("deleteGenerator has to be called with 2 arguments (ideal/module,int)");
1621  }
1622  string inp1 = typeof(#[1]);
1623  if (inp1 == "ideal" || inp1 == "module")
1624  {
1625    if (inp1 == "ideal") { ideal id = #[1]; }
1626    else { module id = #[1]; }
1627  }
1628  else { ERROR("first argument has to be of type ideal or module"); }
1629  string inp2 = typeof(#[2]);
1630  if (inp2 == "int" || inp2 == "number") { int k = int(#[2]); }
1631  else { ERROR("second argument has to be of type int"); }
1632  int n = ncols(id);
1633  if (n == 1) { ERROR(inp1+" must have more than one generator"); }
1634  if (k<=0 || k>n) { ERROR("second argument has to be in the range 1,...,"+string(n)); }
1635  execute(inp1 +" J;");
1636  if (k == 1) { J = id[2..n]; }
1637  else
1638  {
1639    if (k == n) { J = id[1..n-1]; }
1640    else
1641    {
1642      J[1..k-1] = id[1..k-1];
1643      J[k..n-1] = id[k+1..n];
1644    }
1645  }
1646  return(J);
1647}
1648example
1649{
1650  "EXAMPLE:"; echo = 2;
1651  ring r = 0,(x,y,z),dp;
1652  ideal I = x^2,y^3,z^4;
1653  deleteGenerator(I,2);
1654  module M = [x,y,z],[x2,y2,z2],[x3,y3,z3];;
1655  deleteGenerator(M,2);
1656}
1657
1658proc fl2poly(list L, string s)
1659"USAGE:  fl2poly(L,s); L a list, s a string
1660RETURN:  poly
1661PURPOSE: reconstruct a monic polynomial in one variable from its factorization
1662ASSUME:  s is a string with the name of some variable and L is supposed to consist of two entries:
1663@*         L[1] of the type ideal with the roots of a polynomial
1664@*         L[2] of the type intvec with the multiplicities of corr. roots
1665EXAMPLE: example fl2poly; shows examples
1666"
1667{
1668  if (varnum(s)==0)
1669  {
1670    ERROR("no such variable found"); return(0);
1671  }
1672  poly x = var(varnum(s));
1673  poly P = 1;
1674  int sl = size(L[1]);
1675  ideal RR = L[1];
1676  intvec IV = L[2];
1677  for(int i=1; i<= sl; i++)
1678  {
1679    P = P*((x-RR[i])^IV[i]);
1680  }
1681  return(P);
1682}
1683example
1684{
1685  "EXAMPLE:"; echo = 2;
1686  ring r = 0,(x,y,z,s),Dp;
1687  ideal I = -1,-4/3,-5/3,-2;
1688  intvec mI = 2,1,1,1;
1689  list BS = I,mI;
1690  poly p = fl2poly(BS,"s");
1691  p;
1692  factorize(p,2);
1693}
Note: See TracBrowser for help on using the repository browser.