Changeset dfb2c6 in git


Ignore:
Timestamp:
Mar 6, 2009, 9:32:29 PM (14 years ago)
Author:
Viktor Levandovskyy <levandov@…>
Branches:
(u'spielwiese', '5d369c3cbad1a1bf2d5c856a48fb8a30b51cec3b')
Children:
fda698647a5a06bd263906206d3ce89a87b42c0d
Parents:
2a5ce368e94b24f2bbac34de08062477cb206040
Message:
*levandov: bfun and dmodapp seriously reworked


git-svn-id: file:///usr/local/Singular/svn/trunk@11521 2c84dea3-7e68-4137-9b89-c4e89433aadc
Location:
Singular/LIB
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/bfun.lib

    r2a5ce36 rdfb2c6  
    11//////////////////////////////////////////////////////////////////////////////
    2 version="$Id: bfun.lib,v 1.2 2009-02-23 15:10:18 Singular Exp $";
     2version="$Id: bfun.lib,v 1.3 2009-03-06 20:32:28 levandov Exp $";
    33category="Noncommutative";
    44info="
     
    99THEORY: Given a polynomial ring R = K[x_1,...,x_n] and a polynomial F in R,
    1010@*      one is interested in the global b-Function (also known as Bernstein-Sato
    11 @*      polynomial) b(s) in K[s], defined to be the monic polynomial, satisfying a functional
    12 @*      identity L * F^{s+1} = b(s) F^s,   for some operator L in D[s]. Here, D stands for an
    13 @*      n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>.
     11@*      polynomial) b(s) in K[s], defined to be the monic polynomial, satisfying
     12@*      a functional identity    L * F^{s+1} = b(s) F^s,   
     13@*      for some operator L in D[s]. Here, D stands for an n-th Weyl algebra
     14@*      K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>.
    1415@*      One is interested in the following data:
    1516@*      - Bernstein-Sato polynomial b(s) in K[s],
    1617@*      - the list of its roots, which are known to be rational
    1718@*      - the multiplicities of the roots.
    18 @*      References: Saito, Sturmfels, Takayama: Groebner Deformations of Hypergeometric
    19 @*      Differential Equations (2000), Noro: An Efficient Modular Algorithm for Computing
    20 @*      the Global b-function, (2002).
     19@*
     20@*    There is a general definition of a b-function of a holonomic ideal [SST]
     21@*    (that is, an ideal I in a Weyl algebra D, such that D/I is holonomic module)
     22@*    with respect to the given weight vector. B-function b_w(s) is in K[s].
     23@*    Unlike Bernstein-Sato polynomial, general B-function with respect to
     24@*    arbitrary weights need not have rational roots at all.
     25@*
     26@*      References: [SST] Saito, Sturmfels, Takayama: Groebner Deformations of
     27@*      Hypergeometric Differential Equations (2000),
     28@*      Noro: An Efficient Modular Algorithm for Computing the Global b-function,
     29@*      (2002).
    2130
    2231
     
    2736bfctAnn(f[,s]);             computes the Bernstein-Sato polynomial of poly f
    2837bfctOneGB(f[,s,t]);         computes the Bernstein-Sato polynomial of poly f
    29 bfctIdeal(I,w[,s,t]);       computes the global b-function of ideal I w.r.t. the weight w
    30 pIntersect(f,I);            intersection of the ideal I with the subalgebra K[f] for a poly f
    31 pIntersectSyz(f,I[,p,s,t]); intersection of the ideal I with the subalgebra K[f] for a poly f
     38bfctIdeal(I,w[,s,t]);       computes the global b-function of ideal wrt weight
     39pIntersect(f,I[,s]);        intersection of ideal with subalgebra K[f] for poly f
     40pIntersectSyz(f,I[,p,s,t]); intersection of ideal with subalgebra K[f] for poly f
    3241linReduce(f,I[,s]);         reduces a poly by linear reductions only
    3342linReduceIdeal(I,[s,t]);    reduces generators of ideal by linear reductions only
    34 linSyzSolve(I[,s]);         computes a linear dependency of the elements of ideal I
     43linSyzSolve(I[,s]);         computes a linear dependency of elements of ideal I
    3544
    3645AUXILIARY PROCEDURES:
     
    4756LIB "dmod.lib";     // for SannfsBFCT etc
    4857LIB "dmodapp.lib";  // for initialIdealW etc
    49 
     58LIB "nctools.lib"; // for isWeyl etc
    5059
    5160///////////////////////////////////////////////////////////////////////////////
     
    8392"
    8493{
     94  // todo check assumption
    8595  int i;
    8696  def save = basering;
     
    137147}
    138148
     149static proc safeVarName (string s)
     150{
     151  string cv = "," + charstr(basering) + "," + varstr(basering) + ",";
     152  s = "," + s + ",";
     153  while (find(cv,s) <> 0)
     154  {
     155    s[1] = "@";
     156    s = "," + s;
     157  }
     158  s = s[2..size(s)-1];
     159  return(s)
     160}
    139161
    140162proc allPositive (intvec v)
     
    167189static proc findFirst (list l, i)
    168190"USAGE:  findFirst(l,i);  l a list, i an argument of any type
    169 RETURN:  int, the position of the first appearance of i in l, or 0 if i is not a member of l
     191RETURN:  int, the position of the first appearance of i in l,
     192@*       or 0 if i is not a member of l
    170193PURPOSE: check whether the second argument is a member of a list
    171194EXAMPLE: example findFirst; shows an example
     
    230253"USAGE:  linReduceIdeal(I [,s,t,u]); I an ideal, s,t,u optional ints
    231254RETURN:  ideal or list, linear reductum (over field) of I by its elements
    232 PURPOSE: reduce a list of polys only by linear reductions (no monomial multiplications)
    233 NOTE:    If s<>0, a list consisting of the reduced ideal and the coefficient
     255PURPOSE: reduces a list of polys only by linear reductions (no monomial
     256@*        multiplications)
     257NOTE:    If s<>0, a list consisting of the reduced ideal and the coefficient
    234258@*       vectors of the used reductions given as module is returned.
    235259@*       Otherwise (and by default), only the reduced ideal is returned.
     
    237261@*       otherwise, only leading monomials are reduced.
    238262@*       If u<>0 (and by default), the ideal is first sorted in increasing order.
    239 @*       If u is set to 0 and the given ideal is not sorted in the way described, 
     263@*       If u is set to 0 and the given ideal is not sorted in the way described,
    240264@*       the result might not be as expected.
    241265DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
     
    327351    }
    328352  } 
    329   dbprint(ppl-1,"initially sorted ideal:", I);
    330   if (remembercoeffs <> 0) { dbprint(ppl-1," used permutations:", M); }
     353  dbprint(ppl-1,"// initially sorted ideal:", I);
     354  if (remembercoeffs <> 0) { dbprint(ppl-1,"// used permutations:", M); }
    331355  // step 2: reduce leading monomials by linear reductions
    332356  poly lm,c,redpoly,maxlmJ;
     
    358382          if (lm == lmJ[j])
    359383          {
    360             dbprint(ppl-1,"reducing " + string(redpoly));
    361             dbprint(ppl-1," with " + string(J[j]));
     384            dbprint(ppl-1,"// reducing " + string(redpoly));
     385            dbprint(ppl-1,"// with " + string(J[j]));
    362386            c = leadcoef(redpoly)/leadcoef(J[j]);
    363387            redpoly = redpoly - c*J[j];
    364             dbprint(ppl-1," to " + string(redpoly));
     388            dbprint(ppl-1,"// to " + string(redpoly));
    365389            lm = leadmonom(redpoly);
    366390            ordlm = ord(lm);
     
    390414  if (redtail <> 0)
    391415  {
    392     dbprint(ppl,"finished reducing leading monomials");
     416    dbprint(ppl,"// finished reducing leading monomials");
    393417    dbprint(ppl-1,string(J));
    394     if (remembercoeffs <> 0) { dbprint(ppl-1,"used reductions:" + string(M)); }
     418    if (remembercoeffs <> 0) { dbprint(ppl-1,"// used reductions:" + string(M)); }
    395419    int k;
    396420    for (i=sZeros+1; i<=sI; i++)
     
    406430            {
    407431              c = leadcoef(J[j][k])/leadcoef(J[i]);
    408               dbprint(ppl-1,"reducing " + string(J[j]));
    409               dbprint(ppl-1," with " + string(J[i]));
     432              dbprint(ppl-1,"// reducing " + string(J[j]));
     433              dbprint(ppl-1,"// with " + string(J[i]));
    410434              J[j] = J[j] - c*J[i];
    411               dbprint(ppl-1," to " + string(J[j]));
     435              dbprint(ppl-1,"// to " + string(J[j]));
    412436              if (remembercoeffs <> 0) { M[j] = M[j] - c * M[i]; }
    413437            }
     
    442466@*       If t<>0 (and by default) all monomials are reduced (if possible),
    443467@*       otherwise, only leading monomials are reduced.
    444 @*       If u<>0 (and by default), the ideal is linearly pre-reduced, i.e. instead
    445 @*       of the given ideal, the output of @code{linReduceIdeal} is used. If u is
    446 @*       set to 0 and the given ideal does not equal the output of
    447 @*       @code{linReduceIdeal}, the result might not be as expected. 
     468@*       If u<>0 (and by default), the ideal is linearly pre-reduced, i.e.
     469@*       instead of the given ideal, the output of @code{linReduceIdeal} is used.
     470@*       If u is set to 0 and the given ideal does not equal the output of
     471@*       @code{linReduceIdeal}, the result might not be as expected.
    448472DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
    449473@*       if printlevel>=2, all the debug messages will be printed.
     
    487511      I = sortedI[1];
    488512      M = sortedI[2];
    489       dbprint(ppl-1,"prepared ideal:",I);
    490       dbprint(ppl-1," with operations:",M);
     513      dbprint(ppl-1,"// prepared ideal:" +string(I));
     514      dbprint(ppl-1,"//  with operations:" +string(M));
    491515    }
    492516    else { I = linReduceIdeal(I,0,redtail); }
     
    532556  if (redtail <> 0)
    533557  {
    534     dbprint(ppl,"finished reducing leading monomials");
     558    dbprint(ppl,"// finished reducing leading monomials");
    535559    dbprint(ppl-1,string(f));
    536     if (remembercoeffs <> 0) { dbprint(ppl-1,"used reductions:" + string(v)); }
     560    if (remembercoeffs <> 0) { dbprint(ppl-1,"// used reductions:" + string(v)); }
    537561    for (i=1; i<=sI; i++)
    538562    {
    539       dbprint(ppl,"testing ideal entry:",i);
     563      dbprint(ppl,"// testing ideal entry "+string(i));
    540564      for (j=1; j<=size(f); j++)
    541565      {
     
    546570            c = leadcoef(f[j])/lcI[i];
    547571            f = f - c*I[i];
    548             dbprint(ppl-1,"reducing with " + string(I[i]));
    549             dbprint(ppl-1," to " + string(f));
     572            dbprint(ppl-1,"// reducing with " + string(I[i]));
     573            dbprint(ppl-1,"// to " + string(f));
    550574            if (remembercoeffs <> 0) { v = v - c * M[i]; }
    551575          }
     
    581605proc linSyzSolve (ideal I, list #)
    582606"USAGE:  linSyzSolve(I[,s]);  I an ideal, s an optional int
    583 RETURN:  vector, coefficient vector of a linear combination of 0 in the elements of I
     607RETURN:  vector, coefficient vector of linear combination of 0 in elements of I
    584608PURPOSE: compute a linear dependency between the elements of an ideal
    585609@*       if such one exists
     
    613637    // ------- 1. introduce undefined coeffs ------------------
    614638    def save = basering;
     639    list RL = ringlist(save);
     640    int nv = nvars(save);
     641    int np = npars(save);
    615642    int p = char(save);
     643    string cs = "(" + charstr(save) + ")";
    616644    if (enginespecified == 0)
    617645    {
     
    621649      }
    622650    }
    623     ring @A = p,(@a(1..sI)),lp;
    624     ring @aA = (p,@a(1..sI)), (@z),dp;
    625     // TODO: BUG! WHAT IF THE ORIGINAL RING ALREADY HAS SUCH VARIABLES/PARAMETERS!!!?
    626     // TODO: YOU CAN OVERCOME THIS BY MEANS SIMILAR TO "chooseSafeVarName" FROM NEW "matrix.lib"
     651    int i;
     652    list Lvar;
     653    for (i=1; i<=sI; i++)
     654    {
     655      Lvar[i] = safeVarName("@a(" + string(i) + ")");
     656    }
     657    list L@A = RL[1..4];
     658    L@A[2] = Lvar;
     659    L@A[3] = list(list("lp",intvec(1:sI)),list("C",intvec(0)));
     660    def @A = ring(L@A);
     661    L@A[2] = list(safeVarName("@z"));
     662    L@A[3][1] = list("dp",intvec(1));
     663    if (size(L@A[1])>1)
     664    {
     665      L@A[1][2] = L@A[1][2] + Lvar;
     666      L@A[1][3][size(L@A[1][3])+1] = list("lp",intvec(1:sI));
     667    }
     668    else
     669    {
     670      L@A[1] = list(p,Lvar,list(list("lp",intvec(1:sI))),ideal(0));
     671    }
     672    def @aA = ring(L@A);
    627673    def @B = save + @aA;
    628674    setring @B;
    629675    ideal I = imap(save,I);
    630676    // ------- 2. form the linear system for the undef coeffs ---
    631     int i;  poly W;  ideal QQ;
     677    poly W;  ideal QQ;
    632678    for (i=1; i<=sI; i++)
    633679    {
    634       W = W + @a(i)*I[i];
     680      W = W + par(np+i)*I[i];
    635681    }
    636682    while (W!=0)
     
    643689    ideal QQ = imap(@B,QQ);
    644690    // ------- 3. this QQ is a polynomial ideal, so "solve" the system -----
    645     dbprint(ppl, "linSyzSolve: starting Groebner basis computation with engine:", whichengine);
     691    dbprint(ppl, "// linSyzSolve: starting Groebner basis computation with engine:", whichengine);
    646692    QQ = engine(QQ,whichengine);
    647     dbprint(ppl, "QQ after engine:", QQ);
     693    dbprint(ppl, "// QQ after engine:", QQ);
    648694    if (dim(QQ) == -1)
    649695    {
    650       dbprint(ppl+1, "no solutions by linSyzSolve");
     696      dbprint(ppl+1, "// no solutions by linSyzSolve");
    651697      // output zeroes
    652698      setring save;
     
    658704    module MQQ = std(module(QQ));
    659705    AA = NF(AA,MQQ); // todo: we still receive NF warnings
    660     dbprint(ppl, "AA after NF:",AA);
     706    dbprint(ppl, "// AA after NF:",AA);
    661707    //    "AA after NF:"; print(AA);
    662708    for(i=1; i<=sI; i++)
     
    664710      AA = subst(AA,var(i),1);
    665711    }
    666     dbprint(ppl, "AA after subst:",AA);
     712    dbprint(ppl, "// AA after subst:",AA);
    667713    //    "AA after subst: "; print(AA);
    668714    vector v = (module(transpose(AA)))[1];
     
    687733RETURN:  vector, coefficient vector of the monic polynomial
    688734PURPOSE: compute the intersection of ideal I with the subalgebra K[f]
    689 ASSUME:  I is given as Groebner basis.
     735ASSUME:  I is given as Groebner basis, basering is not a qring.
    690736NOTE:    If the intersection is zero, this proc might not terminate.
    691737@*       If s>0 is given, it is searched for the generator of the intersection
     
    696742"
    697743{
     744  def save = basering;
     745  int n = nvars(save);
     746  list RL = ringlist(save);
     747  int i,j,k;
     748  if (RL[4]<>0)
     749  {
     750    ERROR ("basering must not be a qring");
     751  }
    698752  // assume I is given in Groebner basis
    699753  if (attrib(I,"isSB") <> 1)
    700754  {
    701     print("WARNING: The input has no SB attribute!");
    702     print(" Treating it as if it were a Groebner basis and proceeding...");
     755    print("// WARNING: The input has no SB attribute!");
     756    print("// Treating it as if it were a Groebner basis and proceeding...");
    703757    attrib(I,"isSB",1); // set attribute for suppressing NF messages
    704758  }
     
    711765    }
    712766  }
    713   int ppl = printlevel-voice+1;
     767  int ppl = printlevel-voice+2;
    714768  // ---case 1: I = basering---
    715769  if (size(I) == 1)
     
    717771    if (simplify(I,2)[1] == 1)
    718772    {
    719       return(gen(2)); // = s
    720     }
    721   }
    722   def save = basering;
    723   int n = nvars(save);
    724   int i,j,k;
     773      return(gen(1)); // = 1
     774    }
     775  }
    725776  // ---case 2: intersection is zero---
    726777  intvec degs = leadexp(s);
     
    752803    return(vector(0));
    753804  } 
    754   dbprint(ppl,"a lower bound for the degree of the insection is:");
    755   dbprint(ppl,degbound);
     805  dbprint(ppl,"// lower bound for the degree of the insection is " +string(degbound));
    756806  if (degbound == 0) // lm(s) does not appear in lm(I)
    757807  {
     
    766816  poly toNF,tobracket,newNF,rednewNF,oldNF,secNF;
    767817  i = 1;
    768   dbprint(ppl+1,"pIntersect starts...");
    769818  while (1)
    770819  {
    771820    if (bound>0 && i>bound) { return(vector(0)); }
    772     dbprint(ppl,"testing degree: "+string(i));
     821    dbprint(ppl,"// Testing degree "+string(i));
    773822    if (i>1)
    774823    {
     
    793842    rednewNF = ll[1];
    794843    l[i+1] = ll[2];
    795     dbprint(ppl,"newNF is:", newNF);
    796     dbprint(ppl,"rednewNF is:", rednewNF);
     844    dbprint(ppl-1,"// newNF is: "+string(newNF));
     845    dbprint(ppl-1,"// rednewNF is: "+string(rednewNF));
    797846    if (rednewNF != 0) // no linear dependency
    798847    {
     
    802851    else // there is a linear dependency, hence we are done
    803852    {
    804       dbprint(ppl+1,"the degree of the generator of the intersection is:", i);
     853      dbprint(ppl,"// degree of the generator of the intersection is: "+string(i));
    805854      break;
    806855    }
    807856  }
    808   dbprint(ppl,"used linear reductions:", l);
    809   // we obtain the coefficients of the generator of the intersection by the used reductions:
    810   ring @R = 0,(a(1..i+1)),dp;
    811   setring @R;
     857  dbprint(ppl-1,"// used linear reductions:", l);
     858  // we obtain the coefficients of the generator by the used reductions:
     859  list Lvar;
     860  for (j=1; j<=i+1; j++)
     861  {
     862    Lvar[j] = safeVarName("a("+string(j)+")");
     863  }
     864  list Lord = list("dp",intvec(1:(i+1))),list("C",intvec(0));
     865  list L@R = RL[1..4];
     866  L@R[2] = Lvar; L@R[3] = Lord;
     867  def @R = ring(L@R); setring @R;
    812868  list l = imap(save,l);
    813869  ideal C;
     
    817873    for (k=1;k<=j;k++)
    818874    {
    819       C[j] = C[j]+l[j][k]*a(k);
     875      C[j] = C[j]+l[j][k]*var(k);
    820876    }
    821877  }
    822878  for (j=i;j>=1;j--)
    823879  {
    824     C[i+1]= subst(C[i+1],a(j),a(j)+C[j]);
     880    C[i+1]= subst(C[i+1],var(j),var(j)+C[j]);
    825881  }
    826882  matrix m = coeffs(C[i+1],maxideal(1));
     
    833889  v = imap(@R,v);
    834890  kill @R;
    835   dbprint(ppl+1,"pIntersect finished");
    836891  return(v);
    837892}
     
    849904
    850905proc pIntersectSyz (poly s, ideal II, list #)
    851 "USAGE:  pIntersectSyz(f, I [,p,s,t]);  f a poly, I an ideal, p, t optial ints, p a prime number
     906"USAGE:  pIntersectSyz(f, I [,p,s,t]);  f poly, I ideal, p,t optial ints, p prime
    852907RETURN:  vector, coefficient vector of the monic polynomial
    853908PURPOSE: compute the intersection of an ideal I with the subalgebra K[f]
    854 ASSUME:  I is given as Groebner basis.
     909ASSUME:  I is given as Groebner basis, basering is free of parameters.
    855910NOTE:    If the intersection is zero, this procedure might not terminate.
    856 @*       If p>0 is given, this proc computes the generator of the intersection in char p first
    857 @*       and then only searches for a generator of the obtained degree in the basering.
    858 @*       Otherwise, it searched for all degrees by computing syzygies.
     911@*       If p>0 is given, this proc computes the generator of the intersection in
     912@*       char p first and then only searches for a generator of the obtained
     913@*       degree in the basering. Otherwise, it searched for all degrees by
     914@*       computing syzygies.
    859915@*       If s<>0, @code{std} is used for Groebner basis computations in char 0,
    860916@*       otherwise, and by default, @code{slimgb} is used.
    861 @*       If t<>0 and by default, @code{std} is used for Groebner basis computations in char >0,
    862 @*       otherwise, @code{slimgb} is used.
     917@*       If t<>0 and by default, @code{std} is used for Groebner basis
     918@*       computations in char >0, otherwise, @code{slimgb} is used.
    863919DISPLAY: If printlevel=1, progress debug messages will be printed,
    864920@*       if printlevel>=2, all the debug messages will be printed.
     
    870926  if (attrib(I,"isSB") <> 1)
    871927  {
    872     print("WARNING: The input has no SB attribute!");
    873     print(" Treating it as if it were a Groebner basis and proceeding...");
     928    print("// WARNING: The input has no SB attribute!");
     929    print("// Treating it as if it were a Groebner basis and proceeding...");
    874930    attrib(I,"isSB",1); // set attribute for suppressing NF messages
    875931  }
     
    920976    setring Rp;
    921977    kill @Rp;
    922     dbprint(ppl+1,"solving in ring ", Rp);
     978    dbprint(ppl+1,"// solving in ring ", Rp);
    923979    vector v;
    924980    map phi = save,maxideal(1);
     
    928984  }
    929985  i = 1;
    930   dbprint(ppl+1,"pIntersectSyz starts...");
    931   dbprint(ppl+1,"with ideal I=", I);
     986  dbprint(ppl+1,"// pIntersectSyz starts...");
     987  dbprint(ppl+1,"// with ideal I=", I);
    932988  while (1)
    933989  {
    934     dbprint(ppl,"i:"+string(i));
     990    dbprint(ppl,"// i:"+string(i));
    935991    if (i>1)
    936992    {
     
    9481004    }
    9491005    // look for a solution
    950     dbprint(ppl,"linSyzSolve starts with: "+string(matrix(NI)));
     1006    dbprint(ppl,"// linSyzSolve starts with: "+string(matrix(NI)));
    9511007    if (solveincharp<>0) // modular method
    9521008    {
     
    9561012      if (v!=0) // there is a modular solution
    9571013      {
    958         dbprint(ppl,"got solution in char ",solveincharp," of degree " ,i);
     1014        dbprint(ppl,"// got solution in char "+string(solveincharp)+" of degree "+string(i));
    9591015        setring save;
    9601016        v = linSyzSolve(NI,whichengine);
     
    9751031    }
    9761032    matrix MM[1][nrows(v)] = matrix(v);
    977     dbprint(ppl,"linSyzSolve ready  with: "+string(MM));
     1033    dbprint(ppl,"// linSyzSolve ready  with: "+string(MM));
    9781034    kill MM;
    9791035    //  "linSyzSolve ready with"; print(v);
     
    9891045      if (p!=0)
    9901046      {
    991         dbprint(ppl,"linSyzSolve: bad solution!");
     1047        dbprint(ppl,"// linSyzSolve: bad solution!");
    9921048      }
    9931049      else
    9941050      {
    995         dbprint(ppl,"linSyzSolve: got solution!");
     1051        dbprint(ppl,"// linSyzSolve: got solution!");
    9961052        // "got solution!";
    9971053        break;
     
    10011057    i++;
    10021058  }
    1003   dbprint(ppl+1,"pIntersectSyz finished");
     1059  dbprint(ppl+1,"// pIntersectSyz finished");
    10041060  return(v);
    10051061}
     
    10881144  }
    10891145  int substitution = int(#[2]);
    1090   ring S = 0,s,dp;
     1146  string s = safeVarName("s");
     1147  list RL = ringlist(save); RL = RL[1..4];
     1148  RL[2] = list(s); RL[3] = list(list("dp",intvec(1)),list("C",0));
     1149  def S = ring(RL); setring S;
    10911150  ideal J;
    10921151  for (i=1; i<=n; i++)
    10931152  {
    1094     J[i] = s;
     1153    J[i] = var(1);
    10951154  }
    10961155  map @m = save,J;
     
    10981157  if (substitution == 1)
    10991158  {
    1100     p = subst(p,s,-s-1);
     1159    p = subst(p,var(1),-var(1)-1);
    11011160  }
    11021161  // the rest of this proc is nicked from bernsteinBM from dmod.lib
    11031162  list P = factorize(p);//with constants and multiplicities
    1104   ideal bs; intvec m;   //the Bernstein polynomial is monic, so we are not interested in constants
     1163  ideal bs; intvec m;   //the BS poly is monic, so we are not interested in constants
    11051164  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
    11061165  {
     
    11091168  }
    11101169  bs =  normalize(bs);
    1111   bs = -subst(bs,s,0);
     1170  bs = -subst(bs,var(1),0);
    11121171  setring save;
    11131172  ideal bs = imap(S,bs);
     
    11231182  def save = basering;
    11241183  int n = nvars(save);
     1184  if (isCommutative() == 0) { ERROR("basering must be commutative"); }
     1185  if (char(save) <> 0) { ERROR("characteristic of basering has to be 0"); }
     1186  list L = ringlist(save);
     1187  int qr;
     1188  if (L[4] <> 0) // qring
     1189  {
     1190    print("// basering is qring:");
     1191    print("// discarding the quotient and proceeding...");
     1192    L[4] = 0;
     1193    qr = 1;
     1194    def save2 = ring(L);
     1195    setring save2;
     1196    poly f = imap(save,f);
     1197  }
    11251198  if (size(variables(f)) == 0) // f is constant
    11261199  {
     
    11291202  if (inorann == 0) // bfct using initial ideal
    11301203  {
    1131     def D = initialMalgrange(f,whichengine,methodord,1,u0);
     1204    def D = initialMalgrange(f,whichengine,methodord,u0);
    11321205    setring D;
    11331206    ideal J = inF;
     
    11541227      while (b == 0)
    11551228      {
    1156         dbprint(ppl,"number of run in the loop: "+string(i));
     1229        dbprint(ppl,"// number of run in the loop: "+string(i));
    11571230        int q = prime(random(lb,ub));
    11581231        if (findFirst(usedprimes,q)==0) // if q was not already used
    11591232        {
    11601233          usedprimes = usedprimes,q;
    1161           dbprint(ppl,"used prime is: "+string(q));
     1234          dbprint(ppl,"// used prime is: "+string(q));
    11621235          b = pIntersectSyz(s,J,q,whichengine,modengine);
    11631236        }
     
    11741247    b = pIntersect(s,J);
    11751248  }
    1176   setring save;
     1249  if (qr == 1) { setring save2; }
     1250  else { setring save; }
    11771251  vector b = imap(D,b);
    1178   if (inorann == 0)
    1179   {
    1180     list l = listofroots(b,1);
    1181   }
    1182   else
    1183   {
    1184     list l = listofroots(b,0);
     1252  if (inorann == 0) { list l = listofroots(b,1); }
     1253  else              { list l = listofroots(b,0); }
     1254  if (qr == 1)
     1255  {
     1256    setring save;
     1257    list l = imap(save2,l);
    11851258  }
    11861259  return(l);
     
    11921265PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s)
    11931266@*       for the hypersurface defined by f.
    1194 ASSUME:  The basering is a commutative polynomial ring in char 0.
    1195 BACKGROUND: In this proc, the initial Malgrange ideal is computed according to the algorithm
    1196 @*       by Masayuki Noro and then a system of linear equations is solved by linear reductions.
     1267ASSUME:  The basering is commutative and of characteristic 0.
     1268BACKGROUND: In this proc, the initial Malgrange ideal is computed according to
     1269@*       the algorithm by Masayuki Noro and then a system of linear equations is
     1270@*       solved by linear reductions.
    11971271NOTE:    In the output list, the ideal contains all the roots
    11981272@*       and the intvec their multiplicities.
     
    12011275@*       If t<>0, a matrix ordering is used for Groebner basis computations,
    12021276@*       otherwise, and by default, a block ordering is used.
    1203 @*       If v is a positive weight vector, v is used for homogenization computations,
    1204 @*       otherwise and by default, no weights are used.
     1277@*       If v is a positive weight vector, v is used for homogenization
     1278@*       computations, otherwise and by default, no weights are used.
    12051279DISPLAY: If printlevel=1, progress debug messages will be printed,
    12061280@*       if printlevel>=2, all the debug messages will be printed.
     
    12531327
    12541328proc bfctSyz (poly f, list #)
    1255 "USAGE:  bfctSyz(f [,r,s,t,u,v]);  f a poly, r,s,t,u optional ints, v an optional intvec
     1329"USAGE:  bfctSyz(f [,r,s,t,u,v]);  f poly, r,s,t,u optional ints, v opt. intvec
    12561330RETURN:  list of ideal and intvec
    1257 PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) 
     1331PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s)
    12581332@*       for the hypersurface defined by f
    1259 ASSUME:  The basering is a commutative polynomial ring in char 0.
    1260 BACKGROUND: In this proc, the initial Malgrange ideal is computed according to the algorithm
    1261 @*       by Masayuki Noro and then a system of linear equations is solved by computing syzygies.
    1262 NOTE:    In the output list, the ideal contains all the roots
    1263 @*       and the intvec their multiplicities.
    1264 @*       If r<>0, @code{std} is used for GB computations in characteristic 0,
    1265 @*       otherwise, and by default, @code{slimgb} is used.
    1266 @*       If s<>0, a matrix ordering is used for GB computations, otherwise,
     1333ASSUME:  The basering is commutative and of characteristic 0.
     1334BACKGROUND: In this proc, the initial Malgrange ideal is computed according to
     1335@*       the algorithm by Masayuki Noro and then a system of linear equations is
     1336@*       solved by computing syzygies.
     1337NOTE:    In the output list, the ideal contains all the roots and the intvec
     1338@*       their multiplicities.
     1339@*       If r<>0, @code{std} is used for GB computations in characteristic 0,
     1340@*       otherwise, and by default, @code{slimgb} is used.
     1341@*       If s<>0, a matrix ordering is used for GB computations, otherwise,
    12671342@*       and by default, a block ordering is used.
    1268 @*       If t<>0, the computation of the intersection is solely performed over 
     1343@*       If t<>0, the computation of the intersection is solely performed over
    12691344@*       charasteristic 0, otherwise and by default, a modular method is used.
    1270 @*       If u<>0 and by default, @code{std} is used for GB computations in 
    1271 @*       characteristic >0, otherwise, @code{slimgb} is used. 
    1272 @*       If v is a positive weight vector, v is used for homogenization 
     1345@*       If u<>0 and by default, @code{std} is used for GB computations in
     1346@*       characteristic >0, otherwise, @code{slimgb} is used.
     1347@*       If v is a positive weight vector, v is used for homogenization
    12731348@*       computations, otherwise and by default, no weights are used.
    12741349DISPLAY: If printlevel=1, progress debug messages will be printed,
     
    12851360  // and one for the engine used for Groebner basis computations in char >0
    12861361  // in # can also be the optional weight vector
    1287   def save = basering;
    1288   int n = nvars(save);
     1362  int n = nvars(basering);
    12891363  int whichengine = 0; // default
    12901364  int methodord   = 0; // default
     
    13431417"USAGE:  bfctIdeal(I,w[,s,t]);  I an ideal, w an intvec, s,t optional ints
    13441418RETURN:  list of ideal and intvec
    1345 PURPOSE: computes the roots of the global b-function of I wrt the weight vector (-w,w).
    1346 ASSUME:  The basering is the n-th Weyl algebra in char 0, where the sequence of
    1347 @*       the variables is x(1),...,x(n),D(1),...,D(n).
    1348 BACKGROUND:  In this proc, the initial ideal of I is computed according to the algorithm by
    1349 @*       Masayuki Noro and then a system of linear equations is solved by linear reductions.
    1350 NOTE:    In the output list, the ideal contains all the roots
    1351 @*       and the intvec their multiplicities.
     1419PURPOSE: computes the roots of the global b-function of I wrt the weight (-w,w).
     1420ASSUME:  The basering is the n-th Weyl algebra in characteristic 0 and  for all
     1421@*       1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the
     1422@*       sequence of variables is given by x(1),...,x(n),D(1),...,D(n),
     1423@*       where D(i) is the differential operator belonging to x(i).
     1424@*       Further assume that I is holonomic.
     1425BACKGROUND:  In this proc, the initial ideal of I is computed according to the
     1426@*       algorithm by Masayuki Noro and then a system of linear equations is
     1427@*       solved by linear reductions.
     1428NOTE:    In the output list, the ideal contains all the roots and the intvec
     1429@*       their multiplicities.
    13521430@*       If s<>0, @code{std} is used for GB computations in characteristic 0,
    13531431@*       otherwise, and by default, @code{slimgb} is used.
     
    13791457    }
    13801458  }
     1459  if (isWeyl()==0) { ERROR("basering is not a Weyl algebra"); }
     1460  for (i=1; i<=n; i++)
     1461  {
     1462    if (bracket(var(i+n),var(i))<>1)
     1463    {
     1464      ERROR(string(var(i+n))+" is not a differential operator for " +string(var(i)));
     1465    }
     1466  }
     1467  int isH = isHolonomic(I);
     1468  if (isH<>1)
     1469  {
     1470    print("// given ideal is not holonomic");
     1471    print("// setting bound for degree of b-fubction to 10 and proceeding");
     1472    isH = 10;
     1473  }
     1474  else { isH = 0; } // no degree bound for pIntersect
    13811475  ideal J = initialIdealW(I,-w,w,whichengine,methodord);
    13821476  poly s;
     
    13851479    s = s + w[i]*var(i)*var(n+i);
    13861480  }
    1387   vector b = pIntersect(s,J);
    1388   list l = listofroots(b,0);
     1481  vector b = pIntersect(s,J,isH);
     1482  list RL = ringlist(save); RL = RL[1..4];
     1483  RL[2] = list(safeVarName("s"));
     1484  RL[3] = list(list("dp",intvec(1)),list("C",intvec(0)));
     1485  def @S = ring(RL); setring @S;
     1486  vector b = imap(save,b);
     1487  poly bs = vec2poly(b);
     1488  list l = bFactor(bs);
     1489  setring save;
     1490  list l = imap(@S,l);
    13891491  return(l);
    13901492}
     
    14071509"USAGE:  bfctOneGB(f [,s,t]);  f a poly, s,t optional ints
    14081510RETURN:  list of ideal and intvec
    1409 PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) for the 
     1511PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) for the
    14101512@*       hypersurface defined by f, using only one GB computation
    1411 ASSUME:  The basering is a commutative polynomial ring in char 0.
    1412 BACKGROUND: In this proc, the initial Malgrange ideal is computed based on the 
     1513ASSUME:  The basering is commutative and of characteristic 0.
     1514BACKGROUND: In this proc, the initial Malgrange ideal is computed based on the
    14131515@*       algorithm by Masayuki Noro and combined with an elimination ordering.
    1414 NOTE:    In the output list, the ideal contains all the roots
    1415 @*       and the intvec their multiplicities.
     1516NOTE:    In the output list, the ideal contains all the roots and the intvec
     1517@*       their multiplicities.
    14161518@*       If s<>0, @code{std} is used for the GB computation, otherwise,
    14171519@*       and by default, @code{slimgb} is used.
     
    14241526{
    14251527  int ppl = printlevel - voice +2;
     1528  if (isCommutative() == 0) { ERROR("basering must be commutative"); }
    14261529  def save = basering;
    14271530  int n = nvars(save);
     1531  if (char(save) <> 0)
     1532  {
     1533    ERROR("characteristic of basering has to be 0");
     1534  }
     1535  list L = ringlist(save);
     1536  int qr;
     1537  if (L[4] <> 0) // qring?
     1538  {
     1539    print("// basering is qring:");
     1540    print("// discarding the quotient and proceeding...");
     1541    L[4] = 0;
     1542    qr = 1;
     1543    def save2 = ring(L);
     1544    setring save2;
     1545    poly f = imap(save,f);
     1546  }
    14281547  int noofvars = 2*n+4;
    14291548  int i;
     
    14541573  if (methodord == 0) // default: block ordering
    14551574  {
    1456     ring Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),a(uv),dp(noofvars-1),lp(1));
     1575    ring @Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),a(uv),dp(noofvars-1),lp(1));
    14571576  }
    14581577  else // M() ordering
     
    14651584      @Ord[2+i,noofvars - i] = -1;
    14661585    }
    1467     dbprint(ppl,"weights for ordering:",transpose(@a));
    1468     dbprint(ppl,"the ordering matrix:",@Ord);
    1469     ring Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),M(@Ord));
    1470   }
    1471   dbprint(ppl,"the ring Dh:",Dh);
     1586    dbprint(ppl,"// weights for ordering: "+string(transpose(@a)));
     1587    dbprint(ppl,"// the ordering matrix:",@Ord);
     1588    ring @Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),M(@Ord));
     1589  }
     1590  dbprint(ppl,"// the ring Dh:",Dh);
    14721591  // non-commutative relations
    14731592  matrix @relD[noofvars][noofvars];
     
    14791598    @relD[i+2,n+3+i] = h^2;
    14801599  }
    1481   dbprint(ppl,"nc relations:",@relD);
    1482   def DDh = nc_algebra(1,@relD);
    1483   setring DDh;
    1484   dbprint(ppl,"computing in ring",DDh);
     1600  dbprint(ppl,"// nc relations:",@relD);
     1601  def Dh = nc_algebra(1,@relD);
     1602  setring Dh;
     1603  dbprint(ppl,"// computing in ring",DDh);
    14851604  ideal I;
    14861605  poly f = imap(r,f);
     
    14921611    I = I, D(i)+diff(f,x(i))*Dt;
    14931612  }
    1494   dbprint(ppl, "starting Groebner basis computation with engine:", whichengine);
     1613  dbprint(ppl, "// starting Groebner basis computation with engine: "+string(whichengine));
    14951614  I = engine(I, whichengine);
    1496   dbprint(ppl, "finished Groebner basis computation");
    1497   dbprint(ppl, "I before dehomogenization is" ,I);
     1615  dbprint(ppl, "// finished Groebner basis computation");
     1616  dbprint(ppl, "// I before dehomogenization: "+string(I));
    14981617  I = subst(I,h,1); // dehomogenization
    1499   dbprint(ppl, "I after dehomogenization is" ,I);
     1618  dbprint(ppl, "// I after dehomogenization: " +string(I));
    15001619  I = inForm(I,uv); // we are only interested in the initial form w.r.t. uv
    1501   dbprint(ppl, "the initial ideal:", string(matrix(I)));
     1620  dbprint(ppl, "// the initial ideal:", string(matrix(I)));
    15021621  intvec tonselect = 1;
    15031622  for (i=3; i<=2*n+4; i++) { tonselect = tonselect,i; }
    15041623  I = nselect(I,tonselect);
    1505   dbprint(ppl, "generators containing only s:", string(matrix(I)));
     1624  dbprint(ppl, "// generators containing only s:", string(matrix(I)));
    15061625  I = engine(I, whichengine); // is now a principal ideal;
    1507   setring save;
     1626  if (qr == 1) { setring save2; }
     1627  else { setring save; }
    15081628  ideal J; J[2] = var(1);
    1509   map @m = DDh,J;
     1629  map @m = Dh,J;
    15101630  ideal I = @m(I);
    15111631  poly p = I[1];
    15121632  list l = listofroots(p,1);
     1633  if (qr == 1)
     1634  {
     1635    setring save;
     1636    list l = imap(save2,l);
     1637  }
    15131638  return(l);
    15141639}
     
    15251650"USAGE:  bfctAnn(f [,r]);  f a poly, r an optional int
    15261651RETURN:  list of ideal and intvec
    1527 PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s)
    1528 @*       for the hypersurface defined by f
    1529 ASSUME:  The basering is a commutative polynomial ring in char 0.
     1652PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) for the
     1653@*       hypersurface defined by f.
     1654ASSUME:  The basering is commutative and of characteristic 0.
    15301655BACKGROUND: In this proc, ann(f^s) is computed and then a system of linear
    15311656@*       equations is solved by linear reductions.
    1532 NOTE:    In the output list, the ideal contains all the roots
    1533 @*       and the intvec their multiplicities.
     1657NOTE:    In the output list, the ideal contains all the roots and the intvec
     1658@*       their multiplicities.
    15341659@*       If r<>0, @code{std} is used for GB computations,
    15351660@*       otherwise, and by default, @code{slimgb} is used.
     
    15491674    }
    15501675  }
    1551   list b = bfctengine(f,1,whichengine,0,1,0,0,0);
     1676  list b = bfctengine(f,1,whichengine,0,0,0,0,0);
    15521677  return(b);
    15531678}
  • Singular/LIB/dmodapp.lib

    r2a5ce36 rdfb2c6  
    11//////////////////////////////////////////////////////////////////////////////
    2 version="$Id: dmodapp.lib,v 1.20 2009-03-01 17:41:31 levandov Exp $";
     2version="$Id: dmodapp.lib,v 1.21 2009-03-06 20:32:29 levandov Exp $";
    33category="Noncommutative";
    44info="
     
    77@*             Daniel Andres, daniel.andres@math.rwth-aachen.de
    88
    9 GUIDE: Let R = K[x1,..xN] and D be the Weyl algebra in variables x1,..xN,d1,..dN.
    10 In this library there are the following procedures for algebraic D-modules:
     9GUIDE: Let K be a field of characteristic 0, R = K[x1,..xN] and
     10@* D be the Weyl algebra in variables x1,..xN,d1,..dN.
     11@* In this library there are the following procedures for algebraic D-modules:
    1112@* - localization of a holonomic module D/I with respect to a mult. closed set
    12 of all powers of a given polynomial F from R. Our aim is to compute an ideal L
    13 in D, such that D/L is a presentation of a localized module. Such L always exists, since
    14 such localizations are known to be holonomic and thus cyclic modules.
    15 The 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
    18 rational 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
    23 annihilate corresponding Appel hypergeometric functions.
    24 
     13@* of all powers of a given polynomial F from R. Our aim is to compute an
     14@* ideal L in D, such that D/L is a presentation of a localized module. Such L
     15@* always exists, since such localizations are known to be holonomic and thus
     16@* cyclic modules. The procedures for the localization are DLoc,SDLoc and DLoc0.
     17@*
     18@* - annihilator in Weyl algebra of a given polynomial F from R as well as
     19@* of a given rational function G/F from Quot(R). These can be computed via
     20@* procedures annPoly resp. annRat.
     21@*
     22@* - initial form and initial ideals in Weyl algebras with respect to a given
     23@* weight vector can be computed with  inForm, initialMalgrange, initialIdealW.
     24@*
     25@* - appelF1, appelF2 and appelF4 return ideals in parametric Weyl algebras,
     26@* which annihilate corresponding Appel hypergeometric functions.
     27
     28REFERENCES:
     29@* (SST) Saito, Sturmfels, Takayama 'Groebner Deformations of Hypergeometric
     30@*         Differential Equations', Springer, 2000
     31@* (ONW) Oaku, Takayama, Walther 'A Localization Algorithm for D-modules', 2000
    2532
    2633MAIN PROCEDURES:
     
    2936annRat(f,g);  annihilator of a rational function f/g in the corr. Weyl algebra
    3037DLoc(I,F);     presentation of the localization of D/I w.r.t. f^s
    31 SDLoc(I, F);  a generic presentation of the localization of D/I w.r.t. f^s, for D a Weyl algebra
    32 DLoc0(I, F);  presentation of the localization of D/I w.r.t. f^s, based on the procedure SDLoc
    33 
    34 initialMalgrange(f[,s,t,u,v]); Groebner basis of the initial Malgrange ideal for a given poly
     38SDLoc(I, F);  a generic presentation of the localization of D/I w.r.t. f^s
     39DLoc0(I, F);  presentation of the localization of D/I w.r.t. f^s, based on SDLoc
     40
     41initialMalgrange(f[,s,t,v]); Groebner basis of the initial Malgrange ideal for f
    3542initialIdealW(I,u,v[,s,t]); initial ideal of a given ideal w.r.t. given weights
    3643inForm(f,w);     initial form of a poly/ideal w.r.t. a given weight
     
    3946AUXILIARY PROCEDURES:
    4047
     48bFactor(F);  computes the roots of irreducible factors of an univariate poly
    4149appelF1();      create an ideal annihilating Appel F1 function
    4250appelF2();      create an ideal annihilating Appel F2 function
     
    5765LIB "dmod.lib"; // loads e.g. nctools.lib
    5866LIB "bfun.lib"; //formerly LIB "bfct.lib";
     67LIB "nctools.lib"; // for isWeyl etc
     68LIB "gkdim.lib";
    5969
    6070// todo: complete and include into above list
     
    8393  example insertGenerator;
    8494  example deleteGenerator;
    85 }
    86 
    87 
    88 proc 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
    90 RETURN:  ideal, GB of initial ideal of the input ideal wrt the weights u and v
    91 ASSUME: basering is the n-th Weyl algebra and the sequence of the indeterminates is x(1),...,x(n),D(1),...,D(n).
    92 PURPOSE: computes the initial ideal with respect to given weights.
    93 NOTE:    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.
    101 DISPLAY: If printlevel=1, progress debug messages will be printed,
    102 @*       if printlevel>=2, all the debug messages will be printed.
    103 EXAMPLE: 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 }
    129 example
    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 
    140 proc initialMalgrange (poly f,list #)
    141 "USAGE:  initialMalgrange(f, [,s,t,u,v]);  f poly, s,t,u optional ints, v optional intvec
    142 RETURN:  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.
    145 PURPOSE: 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.
    148 NOTE:    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.
    157 DISPLAY: If printlevel=1, progress debug messages will be printed,
    158 @*       if printlevel>=2, all the debug messages will be printed.
    159 EXAMPLE: 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 }
    205 example
    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 
    220 static 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);
    40695}
    40796
     
    588277proc appelF1()
    589278"USAGE:  appelF1();
    590 RETURN:  ring
    591 PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F1 hypergeometric function
     279RETURN:  ring  (and exports an ideal into it)
     280PURPOSE: define the ideal in a parametric Weyl algebra,
     281@* which annihilates Appel F1 hypergeometric function
    592282NOTE: the ideal called  IAppel1 is exported to the output ring
    593283EXAMPLE: example appelF1; shows examples
     
    618308proc appelF2() //(number a,b,c)
    619309"USAGE:  appelF2();
    620 RETURN:  ring
    621 PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F2 hypergeometric function
     310RETURN:  ring (and exports an ideal into it)
     311PURPOSE: define the ideal in a parametric Weyl algebra,
     312@* which annihilates Appel F2 hypergeometric function
    622313NOTE: the ideal called  IAppel2 is exported to the output ring
    623314EXAMPLE: example appelF2; shows examples
     
    647338proc appelF4()
    648339"USAGE:  appelF4();
    649 RETURN:  ring
    650 PURPOSE: define the ideal in a parametric Weyl algebra, which annihilates Appel F4 hypergeometric function
     340RETURN:  ring  (and exports an ideal into it)
     341PURPOSE: define the ideal in a parametric Weyl algebra,
     342@* which annihilates Appel F4 hypergeometric function
    651343NOTE: the ideal called  IAppel4 is exported to the output ring
    652344EXAMPLE: example appelF4; shows examples
     
    750442PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s
    751443NOTE:    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,
     444@* the ideal LD0 (in Groebner basis) is the presentation of the localization
     445@* the list BS contains roots with multiplicities of Bernstein poly of (D/I)_f.
     446DISPLAY: If printlevel=1, progress debug messages will be printed,
    755447@*       if printlevel>=2, all the debug messages will be printed.
    756448EXAMPLE: example DLoc; shows examples
     
    759451  /* runs SDLoc and DLoc0 */
    760452  /* assume: run from Weyl algebra */
     453  if (dmodappassumeViolation())
     454  {
     455    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     456  }
     457  if (!isWeyl())
     458  {
     459    ERROR("Basering is not a Weyl algebra");
     460  }
     461  if (defined(LD0) || defined(BS))
     462  {
     463    ERROR("Reserved names LD0 and/or BS are used. Please rename the objects.");
     464  }
    761465  int old_printlevel = printlevel;
    762466  printlevel=printlevel+1;
     
    782486  "EXAMPLE:"; echo = 2;
    783487  ring r = 0,(x,y,Dx,Dy),dp;
    784   def R = Weyl();    setring R;
     488  def R = Weyl();    setring R; // Weyl algebra in variables x,y,Dx,Dy
    785489  poly F = x2-y3;
    786490  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;
     491  // I is not holonomic, since its dimension is not 4/2=2
     492  gkdim(I);
     493  DLoc(I, x2-y3); // exports LD0 and BS
     494  LD0; // localized module (R/I)_f is isomorphic to R/LD0
     495  BS; // description of b-function for localization
    790496}
    791497
     
    793499"USAGE:  DLoc0(I, F);  I an ideal, F a poly
    794500RETURN:  ring
    795 PURPOSE: 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
     501PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s,
     502@*           where D is a Weyl Algebra, based on the output of procedure SDLoc
    796503ASSUME: the basering is similar to the output ring of SDLoc procedure
    797504NOTE:    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,
     505@* the ideal LD0 (in Groebner basis) is the presentation of the localization
     506@* the list BS contains roots and multiplicities of Bernstein poly of (D/I)_f.
     507DISPLAY: If printlevel=1, progress debug messages will be printed,
    801508@*       if printlevel>=2, all the debug messages will be printed.
    802509EXAMPLE: example DLoc0; shows examples
    803510"
    804511{
     512  if (dmodappassumeViolation())
     513  {
     514    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     515  }
    805516  /* assume: to be run in the output ring of SDLoc */
    806517  /* doing: add F, eliminate vars*Dvars, factorize BS */
     
    976687    dbprint(ppl-1, @R4);
    977688    ideal K4 = imap(@R2,K2);
     689    intvec vopt = option(get);
    978690    option(redSB);
    979691    dbprint(ppl,"// -3-2- the final cosmetic std");
    980692    K4 = groebner(K4);  // std does the job too
     693    option(set,vopt);
    981694    // total cleanup
    982695    setring @R2;
     
    1014727  "EXAMPLE:"; echo = 2;
    1015728  ring r = 0,(x,y,Dx,Dy),dp;
    1016   def R = Weyl();    setring R;
     729  def R = Weyl();    setring R; // Weyl algebra in variables x,y,Dx,Dy
    1017730  poly F = x2-y3;
    1018731  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;
     732  // moreover I is not holonomic, since its dimension is not 2 = 4/2
     733  gkdim(I); // 3
     734  def W = SDLoc(I,F);  setring W; // creates ideal LD in W = R[s]
     735  def U = DLoc0(LD, x2-y3);  setring U; // compute in R
     736  LD0; // Groebner basis of the presentation of localization
     737  BS; // description of b-function for localization
    1023738}
    1024739
     
    1027742"USAGE:  SDLoc(I, F);  I an ideal, F a poly
    1028743RETURN:  ring
    1029 PURPOSE: compute a generic presentation of the localization of D/I w.r.t. f^s, where D is a Weyl Algebra
    1030 ASSUME: the basering is a Weyl algebra
     744PURPOSE: compute a generic presentation of the localization of D/I w.r.t. f^s
     745ASSUME: the basering D is a Weyl algebra
    1031746NOTE:    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,
     747@*  the ideal LD (in Groebner basis) is the presentation of the localization
     748DISPLAY: If printlevel=1, progress debug messages will be printed,
    1034749@*       if printlevel>=2, all the debug messages will be printed.
    1035750EXAMPLE: example SDLoc; shows examples
     
    1039754  /* printlevel >=4 gives debug info */
    1040755  /* assume: we're in the Weyl algebra D  in x1,x2,...,d1,d2,... */
     756
     757  if (dmodappassumeViolation())
     758  {
     759    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     760  }
     761  if (!isWeyl())
     762  {
     763    ERROR("Basering is not a Weyl algebra");
     764  }
    1041765  def save = basering;
    1042766  /* 1. create D <t, dt, s > as in LOT */
     
    1058782  RName[1] = "@t";
    1059783  RName[2] = "@Dt";
    1060   RName[3] = "s";
     784  RName[3] = "@s";
    1061785  for(i=1;i<=N;i++)
    1062786  {
     
    1065789      if (Name[i] == RName[j])
    1066790      {
    1067         ERROR("Variable names should not include @t,@Dt,s");
     791        ERROR("Variable names should not include @t,@Dt,@s");
    1068792      }
    1069793    }
     
    1073797  tmp[1] = "@t";
    1074798  tmp[2] = "@Dt";
    1075   list SName ; SName[1] = "s";
     799  list SName ; SName[1] = "@s";
    1076800  list NName = tmp + Name + SName;
    1077801  L[2]   = NName;
     
    1115839  setring @R;
    1116840  kill @R@;
    1117   dbprint(ppl,"// -1-1- the ring @R(t,Dt,_x,_Dx,s) is ready");
     841  dbprint(ppl,"// -1-1- the ring @R(@t,@Dt,_x,_Dx,@s) is ready");
    1118842  dbprint(ppl-1, @R);
    1119843  poly  F = imap(save,F);
     
    1132856  I = I, @t - F;
    1133857  // t*Dt + s +1 reduced with t-f gives f*Dt + s
    1134   I = I, F*var(2) + var(Nnew);
     858  I = I, F*var(2) + var(Nnew); // @s
    1135859  // -------- the ideal I is ready ----------
    1136860  dbprint(ppl,"// -1-2- starting the elimination of @t,@Dt in @R");
     
    1221945  "EXAMPLE:"; echo = 2;
    1222946  ring r = 0,(x,y,Dx,Dy),dp;
    1223   def R = Weyl();
     947  def R = Weyl(); // Weyl algebra on the variables x,y,Dx,Dy
    1224948  setring R;
    1225949  poly F = x2-y3;
    1226   ideal I = Dx*F, Dy*F;
     950  ideal I = Dx*F, Dy*F;
     951  // note, that I is not holonomic, since it's dimension is not 2
     952  gkdim(I); // 3, while dim R = 4
    1227953  def W = SDLoc(I,F);
    1228   setring W;
    1229   LD;
     954  setring W; // = R[s], where s is a new variable
     955  LD; // Groebner basis of s-parametric presentation
    1230956}
    1231957
     
    1233959"USAGE:  annRat(g,f);  f, g polynomials
    1234960RETURN:  ring
    1235 PURPOSE: compute the ideal in Weyl algebra, annihilating the rational function g*f^{-1}
    1236 NOTE:    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.
     961PURPOSE: compute the annihilator of the rational function g/f in Weyl algebra
     962NOTE: activate the output ring with the @code{setring} command.
     963@*      In the output ring, the ideal LD (in Groebner basis) is the annihilator.
     964@*      The algorithm uses the computation of ann f^{-1} via D-modules.
     965DISPLAY: If printlevel=1, progress debug messages will be printed,
     966@*       if printlevel>=2, all the debug messages will be printed.
     967SEE ALSO: annPoly
    1241968EXAMPLE: example annRat; shows examples
    1242969"
    1243970{
    1244   // computes the annihilator of g/f
     971
     972  if (dmodappassumeViolation())
     973  {
     974    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     975  }
     976
     977  // assumptions: f is not a constant
     978  if (f==0) { ERROR("Denominator cannot be zero"); }
     979  if (leadexp(f) == 0)
     980  {
     981    // f = const, so use annPoly
     982    g = g/f;
     983    def @R = annPoly(g);
     984    return(@R);
     985  }
     986    // computes the annihilator of g/f
    1245987  def save = basering;
    1246988  int ppl = printlevel-voice+2;
     
    13291071  // Now, compare with the output of Macaulay2:
    13301072  ideal tst = 3*x*Dx + 2*y*Dy + 1, y^3*Dy^2 - x^2*Dy^2 + 6*y^2*Dy + 6*y,
    1331 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;
     10739*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;
    13321074 option(redSB); option(redTail);
    13331075 LD = groebner(LD);
     
    13521094"USAGE:  annPoly(f);  f a poly
    13531095RETURN:  ring
    1354 PURPOSE: compute the ideal in Weyl algebra, annihilating the polynomial f
    1355 NOTE:    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.
     1096PURPOSE: compute the complete annihilator ideal of f in Weyl algebra
     1097NOTE:  activate the output ring with the @code{setring} command.
     1098@*   In the output ring, the ideal LD (in Groebner basis) is the annihilator.
     1099DISPLAY: If printlevel=1, progress debug messages will be printed,
     1100@*       if printlevel>=2, all the debug messages will be printed.
    13601101SEE ALSO: annRat
    13611102EXAMPLE: example annPoly; shows examples
     
    13951136  poly f = x^2*z - y^3;
    13961137  def A = annPoly(f);
    1397   setring A;
    1398   LD;
    1399   gkdim(LD); // must be 3 since LD is holonomic
     1138  setring A; // A is the 3rd Weyl algebra in 6 variables
     1139  LD; // the Groebner basis of annihilator
     1140  gkdim(LD); // must be 3 = 6/2, since A/LD is holonomic module
    14001141  NF(Dy^4, LD); // must be 0 since Dy^4 clearly annihilates f
    14011142}
     
    15001241*/
    15011242
    1502 proc engine(ideal I, int i)
    1503 "USAGE:  engine(I,i);  I an ideal, i an int
    1504 RETURN:  ideal
     1243proc engine(def I, int i)
     1244"USAGE:  engine(I,i);  I  ideal/module/matrix, i an int
     1245RETURN:  the same type as I
    15051246PURPOSE: compute the Groebner basis of I with the algorithm, chosen via i
    15061247NOTE: By default and if i=0, slimgb is used; otherwise std does the job.
     
    15091250{
    15101251  /* std - slimgb mix */
    1511   ideal J;
     1252  def J;
     1253  //  ideal J;
    15121254  if (i==0)
    15131255  {
     
    15171259  {
    15181260    // without options -> strange! (ringlist?)
     1261    intvec v = option(get);
    15191262    option(redSB);
    15201263    option(redTail);
    15211264    J = std(I);
     1265    option(set, v);
    15221266  }
    15231267  return(J);
     
    16601404RETURN:  poly
    16611405PURPOSE: reconstruct a monic polynomial in one variable from its factorization
    1662 ASSUME:  s is a string with the name of some variable and L is supposed to consist of two entries:
     1406ASSUME:  s is a string with the name of some variable and
     1407@*         L is supposed to consist of two entries:
    16631408@*         L[1] of the type ideal with the roots of a polynomial
    16641409@*         L[2] of the type intvec with the multiplicities of corr. roots
     
    16681413  if (varnum(s)==0)
    16691414  {
    1670     ERROR("no such variable found"); return(0);
     1415    ERROR("no such variable found in the basering"); return(0);
    16711416  }
    16721417  poly x = var(varnum(s));
     
    16771422  for(int i=1; i<= sl; i++)
    16781423  {
    1679     P = P*((x-RR[i])^IV[i]);
     1424    if (IV[i] > 0)
     1425    {
     1426      P = P*((x-RR[i])^IV[i]);
     1427    }
     1428    else
     1429    {
     1430      printf("Ignored the root with incorrect multiplicity %s",string(IV[i]));
     1431    }
    16801432  }
    16811433  return(P);
     
    16921444  factorize(p,2);
    16931445}
     1446
     1447static proc safeVarName (string s, string cv)
     1448{
     1449  string S;
     1450  if (cv == "v")  { S = "," + "," + varstr(basering)  + ","; }
     1451  if (cv == "c")  { S = "," + "," + charstr(basering) + ","; }
     1452  if (cv == "cv") { S = "," + charstr(basering) + "," + varstr(basering) + ","; }
     1453  s = "," + s + ",";
     1454  while (find(S,s) <> 0)
     1455  {
     1456    s[1] = "@";
     1457    s = "," + s;
     1458  }
     1459  s = s[2..size(s)-1];
     1460  return(s)
     1461}
     1462
     1463proc initialIdealW (ideal I, intvec u, intvec v, list #)
     1464"USAGE:  initialIdealW(I,u,v [,s,t]);  I ideal, u,v intvecs, s,t optional ints
     1465RETURN:  ideal, GB of initial ideal of the input ideal wrt the weights u and v
     1466ASSUME:  The basering is the n-th Weyl algebra in characteristic 0 and  for all
     1467@*       1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the
     1468@*       sequence of variables is given by x(1),...,x(n),D(1),...,D(n),
     1469@*       where D(i) is the differential operator belonging to x(i).
     1470PURPOSE: computes the initial ideal with respect to given weights.
     1471NOTE:    u and v are understood as weight vectors for x(i) and D(i)
     1472@*       respectively.
     1473@*       If s<>0, @code{std} is used for Groebner basis computations,
     1474@*       otherwise, and by default, @code{slimgb} is used.
     1475@*       If t<>0, a matrix ordering is used for Groebner basis computations,
     1476@*       otherwise, and by default, a block ordering is used.
     1477DISPLAY: If printlevel=1, progress debug messages will be printed,
     1478@*       if printlevel>=2, all the debug messages will be printed.
     1479EXAMPLE: example initialIdealW; shows examples
     1480"
     1481{
     1482
     1483  if (dmodappassumeViolation())
     1484  {
     1485    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     1486  }
     1487
     1488  if (!isWeyl())
     1489  {
     1490    ERROR("Basering is not a Weyl algebra");
     1491  }
     1492
     1493  int ppl = printlevel - voice +2;
     1494  def save = basering;
     1495  int n = nvars(save)/2;
     1496  int N = 2*n+1;
     1497  list RL = ringlist(save);
     1498  int i;
     1499  int whichengine = 0; // default
     1500  int methodord   = 0; // default
     1501  if (size(#)>0)
     1502  {
     1503    if (typeof(#[1])=="int" || typeof(#[1])=="number")
     1504    {
     1505      whichengine = int(#[1]);
     1506    }
     1507    if (size(#)>1)
     1508    {
     1509      if (typeof(#[2])=="int" || typeof(#[2])=="number")
     1510      {
     1511        methodord = int(#[2]);
     1512      }
     1513    }
     1514  }
     1515  if (char(save) <> 0) { ERROR("characteristic of basering has to be 0"); }
     1516  if (isWeyl() == 0)   { ERROR("basering is not a Weyl algebra"); }
     1517  for (i=1; i<=n; i++)
     1518  {
     1519    if (bracket(var(i+n),var(i))<>1)
     1520    {
     1521      ERROR(string(var(i+n))+" is not a differential operator for " +string(var(i)));
     1522    }
     1523  }
     1524  // 1. create  homogenized Weyl algebra
     1525  // 1.1 create ordering
     1526  intvec uv = u,v,0;
     1527  list Lord = list(list("a",intvec(1:N)));
     1528  list C0 = list("C",intvec(0));
     1529  if (methodord == 0) // default: blockordering
     1530  {
     1531    Lord[2] = list("dp",intvec(1:(N-1)));
     1532    Lord[3] = list("lp",intvec(1));
     1533    Lord[4] = C0;
     1534  }
     1535  else // M() ordering
     1536  {
     1537    intmat @Ord[N][N];
     1538    @Ord[1,1..N] = uv; @Ord[2,1..N] = 1:(N-1);
     1539    for (i=1; i<=N-2; i++) { @Ord[2+i,N - i] = -1; }
     1540    dbprint(ppl,"// the ordering matrix:",@Ord);
     1541    Lord[2] = list("M",intvec(@Ord));
     1542    Lord[3] = C0;
     1543  }
     1544  // 1.2 the new var
     1545  list Lvar = RL[2]; Lvar[N] = safeVarName("h","cv");
     1546  // 1.3 create commutative ring
     1547  list L@@Dh = RL; L@@Dh = L@@Dh[1..4];
     1548  L@@Dh[2] = Lvar; L@@Dh[3] = Lord;
     1549  def @Dh = ring(L@@Dh); kill L@@Dh;
     1550  setring @Dh;
     1551  dbprint(ppl,"// the ring @Dh:",@Dh);
     1552  // 1.4 create non-commutative relations
     1553  matrix @relD[N][N];
     1554  for (i=1; i<=n; i++) { @relD[i,n+i] = var(N)^2; }
     1555  dbprint(ppl,"// nc relations:",@relD);
     1556  def Dh = nc_algebra(1,@relD);
     1557  setring Dh; kill @Dh;
     1558  dbprint(ppl,"// computing in ring",DDh);
     1559  // 2. Compute the initial ideal
     1560  ideal I = imap(save,I);
     1561  I = homog(I,h);
     1562  // 2.1 the hard part: Groebner basis computation
     1563  dbprint(ppl, "// starting Groebner basis computation with engine: "+string(whichengine));
     1564  I = engine(I, whichengine);
     1565  dbprint(ppl, "// finished Groebner basis computation");
     1566  dbprint(ppl, "// I before dehomogenization is " +string(I));
     1567  I = subst(I,var(N),1); // dehomogenization
     1568  dbprint(ppl, "I after dehomogenization is " +string(I));
     1569  // 2.2 the initial form
     1570  I = inForm(I,uv);
     1571  setring save;
     1572  I = imap(Dh,I); kill Dh;
     1573  // 2.3 the final GB
     1574  dbprint(ppl, "// starting cosmetic Groebner basis computation with engine: "+string(whichengine));
     1575  I = engine(I, whichengine);
     1576  dbprint(ppl,"// finished cosmetic Groebner basis computation");
     1577  return(I);
     1578}
     1579example
     1580{
     1581  "EXAMPLE:"; echo = 2;
     1582  ring @D = 0,(x,Dx),dp;
     1583  def D = Weyl();
     1584  setring D;
     1585  intvec u = -1; intvec v = 2;
     1586  ideal I = x^2*Dx^2,x*Dx^4;
     1587  ideal J = initialIdealW(I,u,v); J;
     1588}
     1589
     1590proc initialMalgrange (poly f,list #)
     1591"USAGE:  initialMalgrange(f,[,s,t,v]); f poly, s,t optional ints, v opt. intvec
     1592RETURN:  ring, the Weyl algebra induced by basering, extended by two new vars
     1593PURPOSE: computes the initial Malgrange ideal of a given poly wrt the weight
     1594@*       vector (-1,0...,0,1,0,...,0) such that the weight of t is -1 and the
     1595@*       weight of Dt is 1.
     1596ASSUME:  The basering is commutative and of characteristic 0.
     1597NOTE:    Activate the output ring with the @code{setring} command.
     1598@*       The returned ring contains the ideal \"inF\", being the initial ideal
     1599@*       of the Malgrange ideal of f.
     1600@*       Varnames of the basering should not include t and Dt.
     1601@*       If s<>0, @code{std} is used for Groebner basis computations,
     1602@*       otherwise, and by default, @code{slimgb} is used.
     1603@*       If t<>0, a matrix ordering is used for Groebner basis computations,
     1604@*       otherwise, and by default, a block ordering is used.
     1605@*       If v is a positive weight vector, v is used for homogenization
     1606@*       computations, otherwise and by default, no weights are used.
     1607DISPLAY: If printlevel=1, progress debug messages will be printed,
     1608@*       if printlevel>=2, all the debug messages will be printed.
     1609EXAMPLE: example initialMalgrange; shows examples
     1610"
     1611{
     1612
     1613  if (dmodappassumeViolation())
     1614  {
     1615    ERROR("Basering is inappropriate: characteristic>0 or qring present");
     1616  }
     1617
     1618  if (!isCommutative())
     1619  {
     1620    ERROR("Basering must be commutative");
     1621  }
     1622
     1623  int ppl = printlevel - voice +2;
     1624  def save = basering;
     1625  int n = nvars(save);
     1626  int i;
     1627  int whichengine = 0; // default
     1628  int methodord   = 0; // default
     1629  intvec u0 = 0;
     1630  if (size(#)>0)
     1631  {
     1632    if (typeof(#[1])=="int" || typeof(#[1])=="number")
     1633    {
     1634      whichengine = int(#[1]);
     1635    }
     1636    if (size(#)>1)
     1637    {
     1638      if (typeof(#[2])=="int" || typeof(#[2])=="number")
     1639      {
     1640        methodord = int(#[2]);
     1641      }
     1642      if (size(#)>2)
     1643      {
     1644        if (typeof(#[3])=="intvec" && size(#[3])==n && allPositive(#[3])==1)
     1645        {
     1646          u0 = #[3];
     1647        }
     1648      }
     1649    }
     1650  }
     1651  if (u0 == 0)
     1652  {
     1653    u0 = 1:n;
     1654  }
     1655  if (isCommutative() == 0) { ERROR("basering must be commutative"); }
     1656  if (char(save) <> 0)      { ERROR("characteristic of basering has to be 0"); }
     1657  // creating the homogenized extended Weyl algebra
     1658  list RL = ringlist(save);
     1659  list C0 = list("C",intvec(0));
     1660  // 1. get the weighted degree of f
     1661  list Lord = list(list("wp",u0),C0);
     1662  list L@r = RL;
     1663  L@r[3] = Lord;
     1664  def r = ring(L@r); kill L@r;
     1665  setring r;
     1666  poly f = imap(save,f);
     1667  int d = deg(f);
     1668  setring save; kill r;
     1669  // 2. create homogenized extended Weyl algebra
     1670  int N = 2*n+3;
     1671  // 2.1 create names for vars
     1672  string vart  = safeVarName("t","cv");
     1673  string varDt = safeVarName("D"+vart,"cv");
     1674  while (varDt <> "D"+vart)
     1675  {
     1676    vart  = safeVarName("@"+vart,"cv");
     1677    varDt = safeVarName("D"+vart,"cv");
     1678  }
     1679  list Lvar,Lvarh;
     1680  Lvar[1] = vart; Lvar[n+2] = varDt;
     1681  for (i=1; i<=n; i++)
     1682  {
     1683    Lvar[i+1]   = string(var(i));
     1684    Lvar[i+n+2] = safeVarName("D" + string(var(i)),"cv");
     1685  }
     1686  Lvarh = Lvar; Lvarh[N] = safeVarName("h","cv");
     1687  //  2.2 create ordering
     1688  intvec uv,@a,weighttx,weightD;
     1689  uv[1] = -1; uv[n+2] = 1; uv[N] = 0;
     1690  weighttx = d; weightD = 1;
     1691  for (i=1; i<=n; i++)
     1692  {
     1693    weighttx[i+1] = u0[n-i+1];
     1694    weightD[i+1]  = d+1-u0[n-i+1];
     1695  }
     1696  @a = weighttx,weightD,1;
     1697  Lord[1] = list("a",@a);
     1698  if (methodord == 0) // default: block ordering
     1699  {
     1700    Lord[2] = list("a",uv);
     1701    Lord[3] = list("dp",intvec(1:(N-1)));
     1702    Lord[4] = list("lp",intvec(1));
     1703    Lord[5] = C0;
     1704  }
     1705  else // M() ordering
     1706  {
     1707    intmat @Ord[N][N];
     1708    @Ord[1,1..N] = uv; @Ord[2,1..N] = 1:(N-1);
     1709    for (i=1; i<=N-2; i++) { @Ord[2+i,N - i] = -1; }
     1710    dbprint(ppl,"// weights for ordering: "+string(transpose(@a)));
     1711    dbprint(ppl,"// the ordering matrix:",@Ord);
     1712    Lord[2] = list("M",intvec(@Ord));
     1713    Lord[3] = C0;
     1714  }
     1715  // 2.3 create commutative ring
     1716  list L@@Dh = RL;
     1717  L@@Dh[2] = Lvarh; L@@Dh[3] = Lord;
     1718  def @Dh = ring(L@@Dh); kill L@@Dh;
     1719  setring @Dh;
     1720  dbprint(ppl,"// the ring @Dh:",@Dh);
     1721  // var(1)=t, var(2..n+1) = x(1..n), var(n+2)=Dt, var(n+3..2*n+2)=D(1..n),var(2*n+3)=h
     1722  // 2.4 create non-commutative relations
     1723  matrix @relD[N][N];
     1724  for (i=1; i<=n+1; i++) { @relD[i,n+1+i] = var(N)^(d+1); }
     1725  dbprint(ppl,"// nc relations:",@relD);
     1726  def Dh = nc_algebra(1,@relD);
     1727  setring Dh; kill @Dh;
     1728  dbprint(ppl,"// computing in ring",Dh);
     1729  // 3. compute the initial ideal
     1730  poly f = imap(save,f);
     1731  f = homog(f,h);
     1732  // 3.1 create the Malgrange ideal
     1733  ideal I = var(1)-f;
     1734  for (i=1; i<=n; i++)
     1735  {
     1736    I = I, var(n+2+i)+diff(f,var(i+1))*var(n+2);
     1737  }
     1738  // 3.2 the hard part: Groebner basis computation
     1739  dbprint(ppl, "// starting Groebner basis computation with engine: "+string(whichengine));
     1740  I = engine(I, whichengine);
     1741  dbprint(ppl, "// finished Groebner basis computation");
     1742  dbprint(ppl, "// I before dehomogenization is " +string(I));
     1743  I = subst(I,var(N),1); // dehomogenization
     1744  dbprint(ppl, "// I after dehomogenization is " +string(I));
     1745  // 3.3 the initial form
     1746  I = inForm(I,uv);
     1747  // 3.4 create Weyl algebra
     1748  setring save;
     1749  Lord = list();
     1750  Lord[1] = list("dp",intvec(1:(N-1)));
     1751  Lord[2] = C0;
     1752  list L@@D = RL;
     1753  L@@D[2] = Lvar; L@@D[3] = Lord;
     1754  def @D = ring(L@@D); kill L@@D;
     1755  setring @D; def D = Weyl(); setring D;
     1756  ideal I = imap(Dh,I);
     1757  kill @D,Dh;
     1758  // 3.5 the final GB
     1759  dbprint(ppl, "// starting cosmetic Groebner basis computation with engine: "+string(whichengine));
     1760  I = engine(I, whichengine);
     1761  dbprint(ppl,"// finished cosmetic Groebner basis computation");
     1762  ideal inF = I; attrib(inF,"isSB",1);
     1763  export(inF);
     1764  return(D);
     1765}
     1766example
     1767{
     1768  "EXAMPLE:"; echo = 2;
     1769  ring r = 0,(x,y),dp;
     1770  poly f = x^2+y^3+x*y^2;
     1771  def D = initialMalgrange(f);
     1772  setring D;
     1773  inF;
     1774  setring r;
     1775  intvec v = 3,2;
     1776  def D2 = initialMalgrange(f,1,0,1,v);
     1777  setring D2;
     1778  inF;
     1779}
     1780
     1781static proc dmodappassumeViolation()
     1782{
     1783  // returns Boolean : yes/no [for assume violation]
     1784  // char K = 0
     1785  // no qring
     1786  // input poly/ideal is nonzero ?
     1787  if ( (char(basering) !=0 ) || (nvars(basering) != gkdim(std(0)) ) )
     1788  {
     1789    return(1);
     1790  }
     1791  return(0);
     1792}
     1793
     1794proc bFactor (poly F)
     1795"USAGE:  bFactor(f);  f poly
     1796RETURN:  list
     1797PURPOSE: computes the roots of irreducible factors of an univariate poly
     1798NOTE:    The output list consists of two or three entries:
     1799@*       the roots of f as ideal, their multiplicities as intvec, and,
     1800@*       if present, a third one being the product of all irreducible factors
     1801@*       of degree greater than one, given as string.
     1802DISPLAY: If printlevel=1, progress debug messages will be printed,
     1803@*       if printlevel>=2, all the debug messages will be printed.
     1804EXAMPLE: example bFactor; shows examples
     1805"
     1806{
     1807  int ppl = printlevel - voice +2;
     1808  def save = basering;
     1809  list L = variables(F);
     1810  int i = size(L);
     1811  if (i>1) { ERROR("poly has to be univariate")}
     1812  if (i == 0)
     1813  {
     1814    dbprint(ppl,"// poly is constant");
     1815    L = list(ideal(0),intvec(0),string(F));
     1816    return(L);
     1817  }
     1818  poly v = L[1];
     1819  L = ringlist(save); L = L[1..4];
     1820  L[2] = list(string(v));
     1821  L[3] = list(list("dp",intvec(1)),list("C",intvec(0)));
     1822  def @S = ring(L);
     1823  setring @S;
     1824  poly ir = 1; poly F = imap(save,F);
     1825  list L = factorize(F);
     1826  ideal I = L[1];
     1827  intvec m = L[2];
     1828  ideal II; intvec mm;
     1829  for (i=2; i<=ncols(I); i++)
     1830  {
     1831    if (deg(I[i]) > 1)
     1832    {
     1833      ir = ir * I[i]^m[i];
     1834    }
     1835    else
     1836    {
     1837      II[size(II)+1] = I[i];
     1838      mm[size(II)] = m[i];
     1839    }
     1840  }
     1841  II = normalize(II);
     1842  II = subst(II,var(1),0);
     1843  II = -II;
     1844  if (size(II)>0)
     1845  {
     1846    dbprint(ppl,"// found roots");
     1847    dbprint(ppl-1,string(II));
     1848  }
     1849  else
     1850  {
     1851    dbprint(ppl,"// found no roots");
     1852  } 
     1853  L = list(II,mm);
     1854  if (ir <> 1)
     1855  {
     1856    dbprint(ppl,"// found irreducible factors");
     1857    ir = cleardenom(ir);
     1858    dbprint(ppl-1,string(ir));
     1859    L = L + list(string(ir));
     1860  }
     1861  else
     1862  {
     1863    dbprint(ppl,"// no irreducible factors found");
     1864  } 
     1865  setring save;
     1866  L = imap(@S,L);
     1867  return(L);
     1868}
     1869example
     1870{
     1871  "EXAMPLE:"; echo = 2;
     1872  ring r = 0,(x,y),dp;
     1873  bFactor((x^2-1)^2);
     1874  bFactor((x^2+1)^2); 
     1875  bFactor((y^2+1/2)*(y+9)*(y-7));
     1876}
Note: See TracChangeset for help on using the changeset viewer.