source: git/Singular/LIB/dmodapp.lib @ 129f23

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