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

spielwiese
Last change on this file since adba541 was adba541, checked in by Viktor Levandovskyy <levandov@…>, 18 years ago
*levandov: D-modules stuff: annfsOT, annfsBM, reiffen, arrange git-svn-id: file:///usr/local/Singular/svn/trunk@9055 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 32.3 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: dmod.lib,v 1.1 2006-04-03 20:44:02 levandov Exp $";
3category="Noncommutative";
4info="
5LIBRARY: dmod.lib     Algorithms for algebraic D-modules
6AUTHORS: Viktor Levandovskyy,     levandov@mathematik.uni-kl.de
7         Jorge Martin Morales,      jorge@unizar.es
8
9THEORY: Given a polynomial ring R = K[x_1,...,x_n] and a polynomial F in R, one is interested in the ring R[1/F^s] for a natural number s.
10@* In fact, the ring R[1/F^s] has a structure of a D(R)-module, where D(R) is a Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>.
11@* Constructively, one needs to find an ideal I = I(F^s) in D(R), such
12that K[x_1,...,x_n,1/F^s] is isomorphic to D(R)/I as a D(R)-module.
13@* We provide two implementations:
14@* 1) the classical Ann F^s algorithm from Oaku and Takayama (J. Pure Applied Math., 1999) and
15@* 2) the newer Ann F^s algorithm by Brianson and Maisonobe.
16
17PROCEDURES:
18annfsOT(F[,eng]);    compute Ann F^s for a poly F with the algorithm of Oaku-Takayama
19annfsBM(F[,eng]);    compute Ann F^s for a poly F with the algorithm of Brianson-Maisonobe
20reiffen(p,q);      create the polynomial, describing a Reiffen curve
21arrange(p);        create the polynomial, describing a generic hyperplane arrangement
22isHolonomic(M);    check whether a module is holonomic
23convloc(L);        replace global orderings with local in the ringlist L
24";
25// very experimental:
26// annfsgms(F[,eng]); compute Ann F^s for a poly F with the modified Oaku-Takayama
27// a new algorithm, based on the computation of a Bernstein polynomial
28// first (with the help of algorithms by Mathias Schulze, see gmssing.lib) and
29// consequent eliminations like in Oaku and Takayama.
30
31LIB "nctools.lib";
32LIB "elim.lib";
33LIB "qhmoduli.lib"; // for Max
34LIB "gkdim.lib";
35
36proc engine(ideal I, int i)
37{
38  /* std / slimgb mix */
39  ideal J;
40  if (i==0)
41  {
42    J = slimgb(I);
43  }
44  else
45  {
46    // without options -> buggy!!! (ringlist?)
47    option(redSB);
48    option(redTail);
49    J = std(I);
50  }
51  return(J);
52}
53
54proc annfsBM(poly F, list #)
55"USAGE:  annfsBM(f [,eng]);  f a poly, eng an optional int
56RETURN:  ring
57PURPOSE: compute the D-module structure of basering[f^s]
58NOTE:    activate this ring with the @code{setring} command. In this ring,
59@*       - the ideal LD is the needed D-mod structure,
60@*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
61@*       If eng <>0, @code{std} is used for Groebner basis computations,
62@*       otherwise (and by default) @code{slimgb} is used.
63@*       If printlevel=1, pogress debug messages will be printed,
64@*       if printlevel>=2, all the debug messages will be printed.
65EXAMPLE: example annfsBM; shows examples
66"
67{
68  int eng = 0;
69  if ( size(#)>0 )
70  {
71    if ( typeof(#[1]) == "int" )
72    {
73      eng = int(#[1]);
74    }     
75  }           
76  // returns a list with a ring and an ideal LD in it
77  int ppl = printlevel-voice+2;
78  //  printf("plevel :%s, voice: %s",printlevel,voice);
79  def save = basering;
80  int N = nvars(basering);
81  int Nnew = 2*N+2;
82  int i,j;
83  string s;
84  list RL = ringlist(basering);
85  list L, Lord;
86  list tmp;
87  intvec iv;
88  L[1] = RL[1]; // char
89  L[4] = RL[4]; // char, minpoly
90  // check whether vars have admissible names
91  list Name  = RL[2];
92  list RName;
93  RName[1] = "t";
94  RName[2] = "s";
95  for(i=1;i<=N;i++)
96  {
97    for(j=1; j<=size(RName);j++)
98    {
99      if (Name[i] == RName[j])
100      {
101        "Variable names should not include t,s";
102        return(0);
103      }
104    }
105  }
106  // now, create the names for new vars
107  list DName;
108  for(i=1;i<=N;i++)
109  {
110    DName[i] = "D"+Name[i]; // concat
111  }
112  tmp[1] = "t";
113  tmp[2] = "s";
114  list NName = tmp + Name + DName;
115  L[2]   = NName;
116  // Name, Dname will be used further
117  kill NName;
118  // block ord (lp(2),dp);
119  tmp[1]  = "lp"; // string
120  iv      = 1,1;
121  tmp[2]  = iv; //intvec
122  Lord[1] = tmp;
123  // continue with dp 1,1,1,1...
124  tmp[1]  = "dp"; // string
125  s       = "iv=";
126  for(i=1;i<=Nnew;i++)
127  {
128    s = s+"1,";
129  }
130  s[size(s)]= ";";
131  execute(s);
132  kill s;
133  tmp[2]    = iv;
134  Lord[2]   = tmp;
135  tmp[1]    = "C";
136  iv        = 0;
137  tmp[2]    = iv;
138  Lord[3]   = tmp;
139  tmp       = 0;
140  L[3]      = Lord;
141  // we are done with the list
142  def @R = ring(L);
143  setring @R;
144  matrix @D[Nnew][Nnew];
145  @D[1,2]=t;
146  for(i=1; i<=N; i++)
147  {
148    @D[2+i,N+2+i]=1;
149  }
150  //  L[5] = matrix(UpOneMatrix(Nnew));
151  //  L[6] = @D;
152  ncalgebra(1,@D);
153  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
154  dbprint(ppl-1, @R);
155  // create the ideal I
156  poly  F = imap(save,F);
157  ideal I = t*F+s;
158  poly p;
159  for(i=1; i<=N; i++)
160  {
161    p = t; // t
162    p = diff(F,var(2+i))*p;
163    I = I, var(N+2+i) + p;
164  }
165  // -------- the ideal I is ready ----------
166  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
167  dbprint(ppl-1, I);
168  ideal J = engine(I,eng);
169  ideal K = nselect(J,1);
170  dbprint(ppl,"// -1-3- t is eliminated");
171  dbprint(ppl-1, K);  // K is without t
172  setring save;
173  // ----------- the ring @R3 ------------
174  // _x, _Dx,s;  elim.ord for _x,_Dx.
175  // keep: N, i,j,s, tmp, RL
176  Nnew = 2*N+1;
177  kill Lord, tmp, iv, RName;
178  list Lord, tmp;
179  intvec iv;
180  L[1] = RL[1];
181  L[4] = RL[4];  // char, minpoly
182  // check whether vars hava admissible names -> done earlier
183  // now, create the names for new var
184  tmp[1] = "s";
185  // DName is defined earlier
186  list NName = Name + DName + tmp;
187  L[2] = NName;
188  tmp = 0;
189  // block ord (dp(N),dp);
190  string s = "iv=";
191  for (i=1; i<=Nnew-1; i++)
192  {
193    s = s+"1,";
194  }
195  s[size(s)]=";";
196  execute(s);
197  tmp[1] = "dp";  // string
198  tmp[2] = iv;   // intvec
199  Lord[1] = tmp;
200  // continue with dp 1,1,1,1...
201  tmp[1] = "dp";  // string
202  s[size(s)] = ",";
203  s = s+"1;";
204  execute(s);
205  kill s;
206  kill NName;
207  tmp[2]      = iv;
208  Lord[2]     = tmp;
209  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
210  Lord[3]     = tmp;  tmp = 0;
211  L[3]        = Lord;
212  // we are done with the list. Now add a Plural part
213  def @R2 = ring(L);
214  setring @R2;
215  matrix @D[Nnew][Nnew];
216  for (i=1; i<=N; i++)
217  {
218    @D[i,N+i]=1;
219  }
220  ncalgebra(1,@D);
221  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
222  dbprint(ppl-1, @R2);
223  ideal MM = maxideal(1);
224  MM = 0,s,MM;
225  map R01 = @R, MM;
226  ideal K = R01(K);
227  poly F = imap(save,F);
228  K = K,F;
229  dbprint(ppl,"//  -2-2- starting the elimination of _x,_Dx in @R2");
230  dbprint(ppl-1, K);
231  ideal M = engine(K,eng);
232  ideal K2 = nselect(M,1,Nnew-1);
233  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
234  dbprint(ppl-1, K2);
235  // the ring @R3 and the search for minimal negative int s
236  ring @R3 = 0,s,dp;
237  dbprint(ppl,"// -3-1- the ring @R3 is ready");
238  ideal K3 = imap(@R2,K2);
239  poly p = K3[1];
240  dbprint(ppl,"// -3-2- factorization");
241  ideal P = factorize(p,1);  //without constants and multiplicities
242  //  "--------- b-function factorizes into ---------";   P;
243  int sP = minIntRoot(P,1);
244  dbprint(ppl,"// -3-3- minimal interger root found");
245  dbprint(ppl-1, sP);
246  // convert factors to a list of their roots
247  // assume all factors are linear
248  ideal BS = normalize(P);
249  BS = subst(BS,s,0);
250  BS = -BS;
251  //TODO: sort BS!
252  // --------- substitute s found in the ideal ---------
253  // --------- going back to @R and substitute ---------
254  setring @R;
255  ideal K2 = subst(K,s,sP);
256  // create the ordinary Weyl algebra and put the result into it,
257  // thus creating the ring @R5
258  // keep: N, i,j,s, tmp, RL
259  setring save;
260  Nnew = 2*N;
261  // list RL = ringlist(save);  // is defined earlier
262  kill Lord, tmp, iv;
263  L = 0;
264  list Lord, tmp;
265  intvec iv;
266  L[1] = RL[1];
267  L[4] = RL[4];  //char, minpoly
268  // check whether vars have admissible names -> done earlier
269  // list Name = RL[2]M
270  // DName is defined earlier
271  list NName = Name + DName;
272  L[2] = NName;
273  // dp ordering;
274  string s = "iv=";
275  for (i=1; i<=Nnew; i++)
276  {
277    s = s+"1,";
278  }
279  s[size(s)] = ";";
280  execute(s);
281  tmp     = 0;
282  tmp[1]  = "dp";  // string
283  tmp[2]  = iv;  // intvec
284  Lord[1] = tmp;
285  kill s;
286  tmp[1]  = "C";
287  iv = 0;
288  tmp[2]  = iv;
289  Lord[2] = tmp;
290  tmp     = 0;
291  L[3]    = Lord;
292  // we are done with the list
293  // Add: Plural part
294  def @R4 = ring(L);
295  setring @R4;
296  matrix @D[Nnew][Nnew];
297  for (i=1; i<=N; i++)
298  {
299    @D[i,N+i]=1;
300  }
301  ncalgebra(1,@D);
302  dbprint(ppl,"// -4-1- the ring @R4 is ready");
303  dbprint(ppl-1, @R4);
304  ideal K4 = imap(@R,K2);
305  option(redSB);
306  dbprint(ppl,"// -4-2- the final cosmetic std");
307  K4 = engine(K4,eng);  // std does the job too
308  // total cleanup
309  kill @R;
310  kill @R2;
311  ideal BS = imap(@R3,BS);
312  export BS;
313  kill @R3;
314  ideal LD = K4;
315  export LD;
316  return(@R4);
317}
318example
319{
320  "EXAMPLE:"; echo = 2;
321  ring r = 0,(x,y,z),Dp;
322  poly F = x^2+y^3+z^5;
323  printlevel = 0;
324  def A = annfsBM(F);
325  setring A;
326  LD;
327  print(matrix(BS));
328}
329
330proc annfsOT(poly F, list #)
331"USAGE:  annfsOT(f [,eng]);  f a poly, eng an optional int
332RETURN:  ring
333PURPOSE: compute the D-module structure of basering[f^s]
334NOTE:    activate this ring with the @code{setring} command. In this ring,
335@*       - the ideal LD is the needed D-mod structure,
336@*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
337@*       If eng <>0, @code{std} is used for Groebner basis computations,
338@*       otherwise (and by default) @code{slimgb} is used.
339@*       If printlevel=1, pogress debug messages will be printed,
340@*       if printlevel>=2, all the debug messages will be printed.
341EXAMPLE: example annfsOT; shows examples
342"
343{
344  int eng = 0;
345  if ( size(#)>0 )
346  {
347    if ( typeof(#[1]) == "int" )
348    {
349      eng = int(#[1]);
350    }     
351  }             
352  // returns a list with a ring and an ideal LD in it
353  int ppl = printlevel-voice+2;
354  //  printf("plevel :%s, voice: %s",printlevel,voice);
355  def save = basering;
356  int N = nvars(basering);
357  int Nnew = 2*(N+2);
358  int i,j;
359  string s;
360  list RL = ringlist(basering);
361  list L, Lord;
362  list tmp;
363  intvec iv;
364  L[1] = RL[1]; // char
365  L[4] = RL[4]; // char, minpoly
366  // check whether vars have admissible names
367  list Name  = RL[2];
368  list RName;
369  RName[1] = "u";
370  RName[2] = "v";
371  RName[3] = "t";
372  RName[4] = "Dt";
373  for(i=1;i<=N;i++)
374  {
375    for(j=1; j<=size(RName);j++)
376    {
377      if (Name[i] == RName[j])
378      {
379        "Variable names should not include u,v,t,Dt";
380        return(0);
381      }
382    }
383  }
384  // now, create the names for new vars
385  tmp[1]     = "u";
386  tmp[2]     = "v";
387  list UName = tmp;
388  list DName;
389  for(i=1;i<=N;i++)
390  {
391    DName[i] = "D"+Name[i]; // concat
392  }
393  tmp    =  0;
394  tmp[1] = "t";
395  tmp[2] = "Dt"; 
396  list NName = UName +  tmp + Name + DName;
397  L[2]   = NName;
398  tmp    = 0;
399  // Name, Dname will be used further
400  kill UName;
401  kill NName;
402  // block ord (a(1,1),dp);
403  tmp[1]  = "a"; // string
404  iv      = 1,1;
405  tmp[2]  = iv; //intvec
406  Lord[1] = tmp;
407  // continue with dp 1,1,1,1...
408  tmp[1]  = "dp"; // string
409  s       = "iv=";
410  for(i=1;i<=Nnew;i++)
411  {
412    s = s+"1,";
413  }
414  s[size(s)]= ";";
415  execute(s);
416  tmp[2]    = iv;
417  Lord[2]   = tmp;
418  tmp[1]    = "C";
419  iv        = 0;
420  tmp[2]    = iv;
421  Lord[3]   = tmp;
422  tmp       = 0;
423  L[3]      = Lord;
424  // we are done with the list
425  def @R = ring(L);
426  setring @R;
427  matrix @D[Nnew][Nnew];
428  @D[3,4]=1;
429  for(i=1; i<=N; i++)
430  {
431    @D[4+i,N+4+i]=1;
432  }
433  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
434  //  L[5] = matrix(UpOneMatrix(Nnew));
435  //  L[6] = @D;
436  ncalgebra(1,@D);
437  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
438  dbprint(ppl-1, @R);
439  // create the ideal I
440  poly  F = imap(save,F);
441  ideal I = u*F-t,u*v-1;
442  poly p;
443  for(i=1; i<=N; i++)
444  {
445    p = u*Dt; // u*Dt
446    p = diff(F,var(4+i))*p;
447    I = I, var(N+4+i) + p;
448  }
449  // -------- the ideal I is ready ----------
450  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
451  dbprint(ppl-1, I);
452  ideal J = engine(I,eng);
453  ideal K = nselect(J,1,2);
454  dbprint(ppl,"// -1-3- u,v are eliminated");
455  dbprint(ppl-1, K);  // K is without u,v
456  setring save;
457  // ------------ new ring @R2 ------------------
458  // without u,v and with the elim.ord for t,Dt
459  // tensored with the K[s]
460  // keep: N, i,j,s, tmp, RL
461  Nnew = 2*N+2+1;
462  //  list RL = ringlist(save); // is defined earlier
463  L = 0;  //  kill L;
464  kill Lord, tmp, iv, RName;
465  list Lord, tmp;
466  intvec iv;
467  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
468  // check whether vars have admissible names -> done earlier
469  //  list Name  = RL[2];
470  list RName;
471  RName[1] = "t";
472  RName[2] = "Dt";
473  // now, create the names for new var (here, s only)
474  tmp[1]     = "s";
475  // DName is defined earlier
476  list NName = RName + Name + DName + tmp;
477  L[2]   = NName;
478  tmp    = 0;
479  // block ord (a(1,1),dp);
480  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
481  Lord[1] = tmp;
482  // continue with a(1,1,1,1)...
483  tmp[1]  = "dp"; s  = "iv=";
484  for(i=1; i<= Nnew; i++)
485  {
486    s = s+"1,";
487  }
488  s[size(s)]= ";";  execute(s);
489  kill NName;
490  tmp[2]    = iv;
491  Lord[2]   = tmp;
492  // extra block for s
493  // tmp[1] = "dp"; iv = 1;
494  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
495  //  Lord[3]   = tmp;
496  kill s;
497  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
498  Lord[3]   = tmp;   tmp = 0;
499  L[3]      = Lord;
500  // we are done with the list. Now, add a Plural part
501  def @R2 = ring(L);
502  setring @R2;
503  matrix @D[Nnew][Nnew];
504  @D[1,2] = 1;
505  for(i=1; i<=N; i++)
506  {
507    @D[2+i,2+N+i] = 1;
508  }
509  ncalgebra(1,@D);
510  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
511  dbprint(ppl-1, @R2);
512  ideal MM = maxideal(1);
513  MM = 0,0,MM;
514  map R01 = @R, MM;
515  ideal K = R01(K);
516  //  ideal K = imap(@R,K); // names of vars are important!
517  poly G = t*Dt+s+1; // s is a variable here
518  K = NF(K,std(G)),G;
519  // -------- the ideal K_(@R2) is ready ----------
520  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
521  dbprint(ppl-1, K);
522  ideal M  = engine(K,eng);
523  ideal K2 = nselect(M,1,2);
524  dbprint(ppl,"// -2-3- t,Dt are eliminated");
525  dbprint(ppl-1, K2);
526  //  dbprint(ppl-1+1," -2-4- std of K2");
527  //  option(redSB);  option(redTail);  K2 = std(K2);
528  //  K2; // without t,Dt, and with s
529  // -------- the ring @R3 ----------
530  // _x, _Dx, s; elim.ord for _x,_Dx.
531  // keep: N, i,j,s, tmp, RL
532  setring save;
533  Nnew = 2*N+1;
534  //  list RL = ringlist(save); // is defined earlier
535  //  kill L;
536  kill Lord, tmp, iv, RName;
537  list Lord, tmp;
538  intvec iv;
539  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
540  // check whether vars have admissible names -> done earlier
541  //  list Name  = RL[2];
542  // now, create the names for new var (here, s only)
543  tmp[1]     = "s";
544  // DName is defined earlier
545  list NName = Name + DName + tmp;
546  L[2]   = NName;
547  tmp    = 0;
548  // block ord (a(1,1...),dp);
549  string  s = "iv=";
550  for(i=1; i<=Nnew-1; i++)
551  {
552    s = s+"1,";
553  }
554  s[size(s)]= ";";
555  execute(s);
556  tmp[1]  = "a"; // string
557  tmp[2]  = iv; //intvec
558  Lord[1] = tmp;
559  // continue with dp 1,1,1,1...
560  tmp[1]  = "dp"; // string
561  s[size(s)]=","; s= s+"1;";
562  execute(s);
563  kill s;
564  kill NName;
565  tmp[2]    = iv;
566  Lord[2]   = tmp;
567  tmp[1]    = "C";  iv  = 0;  tmp[2] = iv;
568  Lord[3]   = tmp;  tmp = 0;
569  L[3]      = Lord;
570  // we are done with the list. Now add a Plural part
571  def @R3 = ring(L);
572  setring @R3;
573  matrix @D[Nnew][Nnew];
574  for(i=1; i<=N; i++)
575  {
576    @D[i,N+i]=1;
577  }
578  ncalgebra(1,@D);
579  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
580  dbprint(ppl-1, @R3);
581  ideal MM = maxideal(1);
582  MM = 0,0,MM;
583  map R12 = @R2, MM;
584  ideal K = R12(K2);
585  poly  F = imap(save,F);
586  K = K,F;
587  dbprint(ppl,"// -3-2- starting the elimination of _x,_Dx in @R3");
588  dbprint(ppl-1, K);
589  ideal M = engine(K,eng);
590  ideal K3 = nselect(M,1,Nnew-1);
591  dbprint(ppl,"// -3-3-  _x,_Dx are eliminated in @R3");
592  dbprint(ppl-1, K3);
593  // the ring @R4  and the search for minimal negative int s
594  ring @R4 = 0,(s),dp;
595  dbprint(ppl,"// -4-1- the ring @R4 is ready");
596  ideal K4 = imap(@R3,K3);
597  poly p = K4[1];
598  dbprint(ppl,"// -4-2- factorization");
599  ideal P = factorize(p,1); // without constants and multiplicities
600  //  "------ b-function factorizes into ----------";  P;
601  int sP  = minIntRoot(P, 1);
602  dbprint(ppl,"// -4-3- minimal integer root found");
603  dbprint(ppl-1, sP);
604  // convert factors to a list of their roots
605  // assume all factors are linear
606  ideal BS = normalize(P);
607  BS = subst(BS,s,0);
608  BS = -BS;
609  // TODO: sort BS!
610  // ------ substitute s found in the ideal ------
611  // ------- going back to @R2 and substitute --------
612  setring @R2;
613  ideal K3 = subst(K2,s,sP);
614  // create the ordinary Weyl algebra and put the result into it,
615  // thus creating the ring @R5
616  // keep: N, i,j,s, tmp, RL
617  setring save;
618  Nnew = 2*N;
619  //  list RL = ringlist(save); // is defined earlier
620  kill Lord, tmp, iv;
621  L = 0;
622  list Lord, tmp;
623  intvec iv;
624  L[1] = RL[1];   L[4] = RL[4]; // char, minpoly
625  // check whether vars have admissible names -> done earlier
626  //  list Name  = RL[2];
627  // DName is defined earlier
628  list NName = Name + DName;
629  L[2]   = NName;
630  // dp ordering;
631  string   s       = "iv=";
632  for(i=1;i<=Nnew;i++)
633  {
634    s = s+"1,";
635  }
636  s[size(s)]= ";";
637  execute(s);
638  tmp     = 0;
639  tmp[1]  = "dp"; // string
640  tmp[2]  = iv; //intvec
641  Lord[1] = tmp;
642  kill s;
643  tmp[1]    = "C";
644  iv        = 0;
645  tmp[2]    = iv;
646  Lord[2]   = tmp;
647  tmp       = 0;
648  L[3]      = Lord;
649  // we are done with the list
650  // Add: Plural part
651  def @R5 = ring(L);
652  setring @R5;
653  matrix @D[Nnew][Nnew];
654  for(i=1; i<=N; i++)
655  {
656    @D[i,N+i]=1;
657  }
658  ncalgebra(1,@D);
659  dbprint(ppl,"// -5-1- the ring @R5 is ready");
660  dbprint(ppl-1, @R5);
661  ideal K5 = imap(@R2,K3);
662  option(redSB);
663  dbprint(ppl,"// -5-2- the final cosmetic std");
664  K5 = engine(K5,eng); // std does the job too
665  // total cleanup
666  kill @R;
667  kill @R2;
668  kill @R3;
669  ideal BS = imap(@R4,BS);
670  export BS;
671  kill @R4;
672  ideal LD = K5;
673  export LD;
674  return(@R5);
675}
676example
677{
678  "EXAMPLE:"; echo = 2;
679  ring r = 0,(x,y,z),Dp;
680  poly F = x^2+y^3+z^5;
681  printlevel = 0;
682  def A  = annfsOT(F);
683  setring A;
684  LD;
685  print(matrix(BS));
686}
687
688
689proc annfsgms(poly F, list #)
690"USAGE:  annfsgms(f [,eng]);  f a poly, eng an optional int
691ASSUME:  f has an isolated critical point at 0
692RETURN:  ring
693PURPOSE: compute the D-module structure of basering[f^s]
694NOTE:    activate this ring with the @code{setring} command. In this ring,
695@*       - the ideal LD is the needed D-mod structure,
696@*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
697@*       If eng <>0, @code{std} is used for Groebner basis computations,
698@*       otherwise (and by default) @code{slimgb} is used.
699@*       If printlevel=1, pogress debug messages will be printed,
700@*       if printlevel>=2, all the debug messages will be printed.
701EXAMPLE: example annfsgms; shows examples
702"
703{
704  LIB "gmssing.lib";
705  int eng = 0;
706  if ( size(#)>0 )
707  {
708    if ( typeof(#[1]) == "int" )
709    {
710      eng = int(#[1]);
711    }     
712  }   
713  int ppl = printlevel-voice+2;
714  // returns a ring with the ideal LD in it
715  def save = basering;
716  // compute the Bernstein poly from gmssing.lib
717  list RL = ringlist(basering);
718  // in the descr. of the ordering, replace "p" by "s"
719  list NL = convloc(RL);
720  // create a ring with the ordering, converted to local
721  def @LR = ring(NL);
722  setring @LR;
723  poly F  = imap(save, F);
724  ideal B = bernstein(F)[1];
725  // since B may not contain (s+1) [following gmssing.lib]
726  // add it!
727  B = B,-1;
728  B = simplify(B,2+4); // erase zero and repeated entries
729  // find the minimal integer value
730  int   S = minIntRoot(B,0);
731  dbprint(ppl,"// -0- minimal integer root found");
732  dbprint(ppl-1,S);
733  setring save;
734  int N = nvars(basering);
735  int Nnew = 2*(N+2);
736  int i,j;
737  string s;
738  //  list RL = ringlist(basering);
739  list L, Lord;
740  list tmp;
741  intvec iv;
742  L[1] = RL[1]; // char
743  L[4] = RL[4]; // char, minpoly
744  // check whether vars have admissible names
745  list Name  = RL[2];
746  list RName;
747  RName[1] = "u";
748  RName[2] = "v";
749  RName[3] = "t";
750  RName[4] = "Dt";
751  for(i=1;i<=N;i++)
752  {
753    for(j=1; j<=size(RName);j++)
754    {
755      if (Name[i] == RName[j])
756      {
757        "Variable names should not include u,v,t,Dt";
758        return(0);
759      }
760    }
761  }
762  // now, create the names for new vars
763  //  tmp[1]     = "u";  tmp[2]     = "v";  tmp[3]     = "t";  tmp[4]     = "Dt";
764  list UName = RName;
765  list DName;
766  for(i=1;i<=N;i++)
767  {
768    DName[i] = "D"+Name[i]; // concat
769  }
770  list NName = UName + Name + DName;
771  L[2]       = NName;
772  tmp        = 0;
773  // Name, Dname will be used further
774  kill UName;
775  kill NName;
776  // block ord (a(1,1),dp);
777  tmp[1]  = "a"; // string
778  iv      = 1,1;
779  tmp[2]  = iv; //intvec
780  Lord[1] = tmp;
781  // continue with dp 1,1,1,1...
782  tmp[1]  = "dp"; // string
783  s       = "iv=";
784  for(i=1; i<=Nnew; i++) // need really all vars!
785  {
786    s = s+"1,";
787  }
788  s[size(s)]= ";";
789  execute(s);
790  tmp[2]    = iv;
791  Lord[2]   = tmp;
792  tmp[1]    = "C";
793  iv        = 0;
794  tmp[2]    = iv;
795  Lord[3]   = tmp;
796  tmp       = 0;
797  L[3]      = Lord;
798  // we are done with the list
799  def @R = ring(L);
800  setring @R;
801  matrix @D[Nnew][Nnew];
802  @D[3,4] = 1; // t,Dt
803  for(i=1; i<=N; i++)
804  {
805    @D[4+i,4+N+i]=1;
806  }
807  //  L[5] = matrix(UpOneMatrix(Nnew));
808  //  L[6] = @D;
809  ncalgebra(1,@D);
810  dbprint(ppl,"// -1-1- the ring @R is ready");
811  dbprint(ppl-1,@R);
812  // create the ideal
813  poly F  = imap(save,F);
814  ideal I = u*F-t,u*v-1;
815  poly p;
816  for(i=1; i<=N; i++)
817  {
818    p = u*Dt; // u*Dt
819    p = diff(F,var(4+i))*p;
820    I = I, var(N+4+i) + p; // Dx, Dy
821  }
822  // add the relations between t,Dt and s
823  //  I = I, t*Dt+1+S;
824  // -------- the ideal I is ready ----------
825  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
826  ideal J = engine(I,eng);
827  ideal K = nselect(J,1,2);
828  dbprint(ppl,"// -1-3- u,v are eliminated in @R");
829  dbprint(ppl-1,K); // without u,v: not yet our answer
830  //----- create a ring with elim.ord for t,Dt -------
831  setring save;
832  // ------------ new ring @R2 ------------------
833  // without u,v and with the elim.ord for t,Dt
834  // keep: N, i,j,s, tmp, RL
835  Nnew = 2*N+2;
836  //  list RL = ringlist(save); // is defined earlier
837  kill Lord,tmp,iv, RName;
838  L = 0;
839  list Lord, tmp;
840  intvec iv;
841  L[1] = RL[1]; // char
842  L[4] = RL[4]; // char, minpoly
843  // check whether vars have admissible names -> done earlier
844  //  list Name  = RL[2];
845  list RName;
846  RName[1] = "t";
847  RName[2] = "Dt";
848  // DName is defined earlier
849  list NName = RName + Name + DName;
850  L[2]   = NName;
851  tmp    = 0;
852  // block ord (a(1,1),dp);
853  tmp[1]  = "a"; // string
854  iv      = 1,1;
855  tmp[2]  = iv; //intvec
856  Lord[1] = tmp;
857  // continue with dp 1,1,1,1...
858  tmp[1]  = "dp"; // string
859  s       = "iv=";
860  for(i=1;i<=Nnew;i++)
861  {
862    s = s+"1,";
863  }
864  s[size(s)]= ";";
865  execute(s);
866  kill s;
867  kill NName;
868  tmp[2]    = iv;
869  Lord[2]   = tmp;
870  tmp[1]    = "C";
871  iv        = 0;
872  tmp[2]    = iv;
873  Lord[3]   = tmp;
874  tmp       = 0;
875  L[3]      = Lord;
876  // we are done with the list
877  // Add: Plural part
878  def @R2 = ring(L);
879  setring @R2;
880  matrix @D[Nnew][Nnew];
881  @D[1,2]=1;
882  for(i=1; i<=N; i++)
883  {
884    @D[2+i,2+N+i]=1;
885  }
886  ncalgebra(1,@D);
887  dbprint(ppl,"// -2-1- the ring @R2 is ready");
888  dbprint(ppl-1,@R2);
889  ideal MM = maxideal(1);
890  MM = 0,0,MM;
891  map R01 = @R, MM;
892  ideal K2 = R01(K);
893  // add the relations between t,Dt and s
894  //  K2       = K2, t*Dt+1+S;
895  poly G = t*Dt+S+1;
896  K2 = NF(K2,std(G)),G;
897  dbprint(ppl,"// -2-2- starting elimination for t,Dt in @R2");
898  ideal J  = engine(K2,eng);
899  ideal K  = nselect(J,1,2);
900  dbprint(ppl,"// -2-3- t,Dt are eliminated");
901  dbprint(ppl-1,K);
902  //  "------- produce a final result --------";
903  // ----- create the ordinary Weyl algebra and put
904  // ----- the result into it
905  // ------ create the ring @R5
906  // keep: N, i,j,s, tmp, RL
907  setring save;
908  Nnew = 2*N;
909  //  list RL = ringlist(save); // is defined earlier
910  kill Lord, tmp, iv;
911  //  kill L;
912  L = 0;
913  list Lord, tmp;
914  intvec iv;
915  L[1] = RL[1]; // char
916  L[4] = RL[4]; // char, minpoly
917  // check whether vars have admissible names -> done earlier
918  //  list Name  = RL[2];
919  // DName is defined earlier
920  list NName = Name + DName;
921  L[2]   = NName;
922  // dp ordering;
923  string   s       = "iv=";
924  for(i=1;i<=2*N;i++)
925  {
926    s = s+"1,";
927  }
928  s[size(s)]= ";";
929  execute(s);
930  tmp     = 0;
931  tmp[1]  = "dp"; // string
932  tmp[2]  = iv; //intvec
933  Lord[1] = tmp;
934  kill s;
935  tmp[1]    = "C";
936  iv        = 0;
937  tmp[2]    = iv;
938  Lord[2]   = tmp;
939  tmp       = 0;
940  L[3]      = Lord;
941  // we are done with the list
942  // Add: Plural part
943  def @R5 = ring(L);
944  setring @R5;
945  matrix @D[Nnew][Nnew];
946  for(i=1; i<=N; i++)
947  {
948    @D[i,N+i]=1;
949  }
950  ncalgebra(1,@D);
951  dbprint(ppl,"// -3-1- the ring @R5 is ready");
952  dbprint(ppl-1,@R5);
953  ideal K5 = imap(@R2,K);
954  option(redSB);
955  dbprint(ppl,"// -3-2- the final cosmetic std");
956  K5 = engine(K5,eng); // std does the job too
957  // total cleanup
958  kill @R;
959  kill @R2;
960  ideal LD = K5;
961  ideal BS = imap(@LR,B);
962  kill @LR;
963  export BS;
964  export LD;
965  return(@R5);
966}
967example
968{
969  "EXAMPLE:"; echo = 2;
970  ring r = 0,(x,y,z),Dp;
971  poly F = x^2+y^3+z^5;
972  def A = annfsgms(F);
973  setring A;
974  LD;
975  print(matrix(BS));
976}
977
978proc convloc(list @NL)
979"USAGE:  convloc(L); L a list
980RETURN:  list
981PURPOSE: convert a ringlist L into another ringlist,
982where all the 'p' orderings are replaced with the 's' orderings.
983ASSUME: L is a result of a ringlist command
984EXAMPLE: example minIntRoot; shows examples
985"
986{
987  list NL = @NL;
988  // given a ringlist, returns a new ringlist,
989  // where all the p-orderings are replaced with s-ord's
990  int i,j,k,found;
991  int nblocks = size(NL[3]);
992  for(i=1; i<=nblocks; i++)
993  {
994    for(j=1; j<=size(NL[3][i]); j++)
995    {
996      if (typeof(NL[3][i][j]) == "string" )
997      {
998        found = 0;
999        for (k=1; k<=size(NL[3][i][j]); k++)
1000        {
1001          if (NL[3][i][j][k]=="p")
1002          {
1003            NL[3][i][j][k]="s";
1004            found = 1;
1005            //      printf("replaced at %s,%s,%s",i,j,k);
1006          }
1007        }
1008      }
1009    }
1010  }
1011  return(NL);
1012}
1013example
1014{
1015  "EXAMPLE:"; echo = 2;
1016  ring r = 0,(x,y,z),(Dp(2),dp(1));
1017  list L = ringlist(r);
1018  list N = convloc(L);
1019  def rs = ring(N);
1020  setring rs;
1021  rs;
1022}
1023
1024
1025proc minIntRoot(ideal P, int fact)
1026"USAGE:  minIntRoot(P, fact); P an ideal, fact an int
1027RETURN:  int
1028PURPOSE: minimal integer root of a maximal ideal P
1029NOTE:    if fact==1, P is the result of some 'factorize' call,
1030@*       else P is treated as the result of bernstein::gmssing.lib
1031@*       in both cases without constants and multiplicities
1032EXAMPLE: example minIntRoot; shows examples
1033"
1034{
1035  //    ideal P = factorize(p,1);
1036  // or ideal P = bernstein(F)[1];
1037  intvec vP;
1038  number nP;
1039  int i;
1040  if ( fact )
1041  {
1042    // the result comes from "factorize"
1043    P = normalize(P); // now leadcoef = 1
1044    P = lead(P)-P;
1045    // nP = leadcoef(P[i]-lead(P[i])); // for 1 var only, extract the coeff
1046  }
1047  else
1048  {
1049    // bernstein deletes -1 usually
1050    P = P, -1;
1051  }
1052  // for both situations:
1053  // now we have an ideal of fractions of type "number" 
1054  int sP = size(P);
1055  for(i=1; i<=sP; i++)
1056  {
1057    nP = leadcoef(P[i]);
1058    if ( (nP - int(nP)) == 0 )
1059    {
1060      vP = vP,int(nP);
1061    }
1062  }
1063  if ( size(vP)>=2 )
1064  {
1065    vP = vP[2..size(vP)];
1066  }
1067  sP = -Max(-vP);
1068  if (sP == 0)
1069  {
1070    "Warning: zero root!";
1071  }
1072  return(sP);
1073}
1074example
1075{
1076  "EXAMPLE:"; echo = 2;
1077  ring r   = 0,(x,y),ds;
1078  poly f1  = x*y*(x+y);
1079  ideal I1 = bernstein(f1)[1];
1080  minIntRoot(I1,0);
1081  poly  f2  = x2-y3;
1082  ideal I2  = bernstein(f2)[1];
1083  minIntRoot(I2,0);
1084  // now we illustrate the behaviour of factorize
1085  ring r2  = 0,x,dp;
1086  poly f3   = 9*(x+2/3)*(x+1)*(x+4/3); // b-poly of f1=x*y*(x+y)
1087  ideal I3 = factorize(f3,1);
1088  minIntRoot(I3,1);
1089  // and a more interesting situation
1090  ring  s  = 0,(x,y,z),ds;
1091  poly  f  = x3 + y3 + z3;
1092  ideal I  = bernstein(f)[1];
1093  minIntRoot(I,0);
1094}
1095
1096proc isHolonomic(def M)
1097"USAGE:  isHolonomic(M); M an ideal/module/matrix
1098RETURN:  int, 1 if M is holonomic and 0 otherwise
1099PURPOSE: check the modules for the property of holonomy
1100NOTE:    M is holonomic, if 2*dim(M) = dim(R), where R is a
1101ground ring
1102EXAMPLE: example isHolonomic; shows examples
1103"
1104{
1105  if ( (typeof(M) != "ideal") || (typeof(M) != "module") || (typeof(M) != "matrix"))
1106  {
1107    ERROR("an argument of type ideal/module/matrix expected");
1108  }
1109  if (attrib(M,"isSB")!=1)
1110  {
1111    M = std(M);
1112  }
1113  int dimR = gkdim(std(0));
1114  int dimM = gkdim(M);
1115  return( (dimR==2*dimM) );
1116}
1117example
1118
1119  "EXAMPLE:"; echo = 2;
1120  ring R = 0,(x,y),dp;
1121  poly F = x*y*(x+y);
1122  def A = annfs(F,0);
1123  setring A;
1124  LD;
1125  isHolonomic(LD);
1126  ideal I = std(LD[1]);
1127  isHolonomic(I); 
1128}
1129
1130proc reiffen(int p, int q)
1131"USAGE:  reiffen(p, q);  int p, int q
1132RETURN:  ring
1133PURPOSE: set up the polynomial, describing a Reiffen curve
1134NOTE:    activate this ring with the @code{setring} command and find the curve as a polynomial RC
1135@*   a Reiffen curve is defined as F = x^p + y^q + xy^{q-1}, q >= p+1 >= 5
1136ASSUME: q >= p+1 >= 5. Otherwise an error message is returned
1137EXAMPLE: example reiffen; shows examples
1138"
1139{
1140// a Reiffen curve is defined as
1141// F = x^p + y^q +x*y^{q-1}, q \geq p+1 \geq 5
1142
1143  if ( (p<4) || (q<5) || (q-p<1) )
1144  {
1145    "Some of conditions p>=4, q>=5 or q>=p+1 is not satisfied!";
1146    return(0);
1147  }
1148  ring @r = 0,(x,y),ds;
1149  poly RC = y^q +x^p + x*y^(q-1);
1150  export RC;
1151  return(@r);
1152}
1153example
1154
1155  "EXAMPLE:"; echo = 2;
1156  def r = reiffen(4,5);
1157  setring r;
1158  RC;
1159}
1160
1161proc arrange(int p)
1162"USAGE:  arrange(p);  int p
1163RETURN:  ring
1164PURPOSE: set up the polynomial, describing a generic hyperplane arrangement
1165NOTE:   must be executed in a ring
1166ASSUME: basering is present
1167EXAMPLE: example arrange; shows examples
1168"
1169{
1170  int UseBasering = 0 ;
1171  if (p<2)
1172  {
1173    ERROR("p>=2 is required!");
1174  }
1175  if ( nameof(basering)!="basering" )
1176  {
1177    if (p > nvars(basering))
1178    {
1179      ERROR("too big p");
1180    }
1181    else
1182    {
1183      def @r = basering;
1184      UseBasering = 1;
1185    }
1186  }
1187  else
1188  {
1189    // no basering found
1190    ERROR("no basering found!");
1191    //    ring @r = 0,(x(1..p)),dp;
1192  }
1193  int i,j,sI;
1194  poly  q = 1;
1195  list ar;
1196  ideal tmp;
1197  tmp = ideal(var(1));
1198  ar[1] = tmp;
1199  for (i = 2; i<=p; i++)
1200  {
1201    // add i-nary sums to the product
1202    ar = indAR(ar,i);
1203  }
1204  for (i = 1; i<=p; i++)
1205  {
1206    tmp = ar[i]; sI = size(tmp);
1207    for (j = 1; j<=sI; j++)
1208    {
1209      q = q*tmp[j];
1210    }
1211  }
1212  if (UseBasering)
1213  {
1214    return(q);
1215  }
1216  //  poly AR = q; export AR;
1217  //  return(@r);
1218}
1219example
1220
1221  "EXAMPLE:"; echo = 2;
1222  ring X = 0,(x,y,z,t),dp;
1223  poly q = arrange(3);
1224  factorize(q,1);
1225}
1226
1227static proc indAR(list L, int n)
1228"USAGE:  indAR(L,n);  list L, int n
1229RETURN:  list
1230PURPOSE: computes arrangement inductively, using L and varn(n) as the
1231next variable
1232ASSUME: L has a structure of an arrangement
1233EXAMPLE: example indAR; shows examples
1234"
1235{
1236  if ( (n<2) || (n>nvars(basering)) )
1237  {
1238    ERROR("incorrect n");
1239  }
1240  int sl = size(L);
1241  list K;
1242  ideal tmp;
1243  poly @t = L[sl][1] + var(n); //1 elt
1244  K[sl+1] = ideal(@t);
1245  tmp = L[1]+var(n);
1246  K[1] = tmp; tmp = 0;
1247  int i,j,sI;
1248  ideal I;
1249  for(i=sl; i>=2; i--)
1250  {
1251    I = L[i-1]; sI = size(I);
1252    for(j=1; j<=sI; j++)
1253    {
1254      I[j] = I[j] + var(n);
1255    }
1256    tmp  = L[i],I;
1257    K[i] = tmp;
1258    I = 0; tmp = 0;
1259  }
1260  kill I; kill tmp;
1261  return(K);
1262}
1263example
1264
1265  "EXAMPLE:"; echo = 2;
1266  ring r = 0,(x,y,z,t,v),dp;
1267  list L;
1268  L[1] = ideal(x);
1269  list K = indAR(L,2);
1270  K;
1271  list M = indAR(K,3);
1272  M;
1273  M = indAR(M,4);
1274  M;
1275}
1276
1277static proc exCheckGenericity()
1278{
1279  LIB "control.lib";
1280  ring r = (0,a,b,c),x,dp;
1281  poly p = (x-a)*(x-b)*(x-c);
1282  def A = annfsBM(p);
1283  setring A;
1284  ideal J = slimgb(LD);
1285  matrix T = lift(LD,J);
1286  T = normalize(T);
1287  genericity(T);
1288  // Ann =x^3*Dx+3*x^2*t*Dt+(-a-b-c)*x^2*Dx+(-2*a-2*b-2*c)*x*t*Dt+3*x^2+(a*b+a*c+b*c)*x*Dx+(a*b+a*c+b*c)*t*Dt+(-2*a-2*b-2*c)*x+(-a*b*c)*Dx+(a*b+a*c+b*c)
1289  // genericity: g = a2-ab-ac+b2-bc+c2 =0
1290  // g = (a -(b+c)/2)^2 + (3/4)*(b-c)^2;
1291  // g ==0 <=> a=b=c
1292  // indeed, Ann = (x-a)^2*(x*Dx+3*t*Dt+(-a)*Dx+3)
1293  // --------------------------------------------
1294  // BUT a direct computation shows
1295  // when a=b=c,
1296  // Ann = x*Dx+3*t*Dt+(-a)*Dx+3
1297}
1298
1299static proc exOT_17()
1300{
1301  // Oaku-Takayama, p.208
1302  ring R = 0,(x,y),dp;
1303  poly F = x^3-y^2; // x^2+x*y+y^2;
1304  option(prot);
1305  option(mem);
1306  //  option(redSB);
1307  def A = annfsOT(F,0);
1308  setring A;
1309  LD;
1310  LIB "gkdim.lib";
1311  gkdim(LD); // a holonomic check
1312  //  poly F = x^3-y^2; // = x^7 - y^5; // x^3-y^4; // x^5 - y^4;
1313}
1314
1315static proc exOT_16()
1316{
1317  // Oaku-Takayama, p.208
1318  ring R = 0,(x),dp;
1319  poly F = x*(1-x);
1320  option(prot);
1321  option(mem);
1322  //  option(redSB);
1323  def A = annfsOT(F,0);
1324  setring A;
1325  LD;
1326  LIB "gkdim.lib";
1327  gkdim(LD); // a holonomic check
1328  //  poly F = x^3-y^2; // = x^7 - y^5; // x^3-y^4; // x^5 - y^4;
1329}
1330
1331static proc ex_bcheck()
1332{
1333  ring R = 0,(x,y),dp;
1334  poly F = x*y*(x+y);
1335  option(prot);
1336  option(mem);
1337  int eng = 0;
1338  //  option(redSB);
1339  def A = annfsOT(F,eng);
1340  //  def A = annfsgms(F,0);
1341  setring A;
1342  LD;
1343}
1344
1345static proc ex_bcheck2()
1346{
1347  ring R = 0,(x,y),dp;
1348  poly F = x*y*(x+y);
1349  int eng = 0;
1350  def A = annfsOT(F,eng);
1351  //  def A = annfsgms(F,0);
1352  setring A;
1353  LD;
1354}
Note: See TracBrowser for help on using the repository browser.