doc ///
  Key
      "Canonical Series Tutorial"
  Headline
      Computing series solutions to regular holonomic systems
  Description
    Text
      If D/I is a regular holonomic D-module, the solutions of the system of differential equations
      I can be written as Nilsson series (Puiseux series with logarithms).
      The constructive version of this result is the canonical series method
      [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST, Sections 2.5, 2.6")@].
      In this tutorial, we illustrate an implementation of this method.

    Text
      If the input ideal I is not regular, this method is not guaranteed to produce convergent
      series, or even holonomicRank(I) formal power series solutions of I. There currently exists
      no computational method to verify whether D/I is a regular holonomic D-module.
      In the case of GKZ systems, regularity has been characterized in terms of the input matrix.

    Text
      Contains the following functions:

    Text
      Currently, this contains the computation of exponents with respect to a weight vector. Completing the canonical series computation is in the future.
      To compute the exponents for a D-ideal I with respect to w, do as follows.
      Compute the initial ideal of I with respect to w.
      Introduce the subring of D consisting of polynomials in
      $\theta_1 = x_1 \partial_1, ... , \theta_n= x_n \partial_n$. This is a commutative polynomial subring of D,
      referred to here as thetaRing.
      The indicial ideal of I with respect to w is produced by extending the initial ideal to the ring of
      differential operators with rational function coefficients, and contract to thetaRing. The exponents of I
      with respect to w are the roots of the indicial ideal, counted with multiplicities.

    Example
     R1 = QQ[z]
     W1 = makeWA R1
     a=1/2
     b=3
     c=5/3
     J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b) -- the Gauss hypergeometric equation, exponents 0, 1-c
     cssExpts(J,{1})
     inw(J,{-1,1})
     distraction(oo,QQ[s])
     factor oo_0
     c=1  -- Now we have a single exponent of multiplicity 2
     J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b)
     cssExpts(J,{1})
     cssExptsMult(J,{1})
    Text
      The first step is to rewrite elements of the initial ideal in a terms of the thetaRing, in a way that will allow us to easily
      extend and contract see [SST]
    Example
      R2 = QQ[x_1..x_3]
      W2 = makeWA R2
      gens W2
      thetaRing = QQ[t_1,t_2,t_3] -- sets variable names t_i = x_i\dx_i
      f1= x_1*dx_1 -- this element already belongs to thetaRing
      distraction(f1,thetaRing)  -- checks out
      f2 = x_1^3*dx_1^3 -- this is a descending factorial in the theta variables
      distraction(f2,thetaRing)
      factor oo	  -- now it looks like a descending factorial
      f = x_1^2*x_2^2*x_3*dx_1*dx_2^2*dx_3^2
      distraction(f,thetaRing)
    Text
      Here is an example that can be continued when more functions are implemented.
      This is worked out as [page 138, ex 3.5.3, SST].
    Example
      A = matrix{{1,1,1},{0,1,2}}
      I = gkz(A,{10,8})
      holonomicRank(I)
      cssExpts(I,{1,0,0})
    Text
      In this case, the series corresponding to the exponent
      (2,8,0) is logarithm-free (actually, this is a hypergeometric polynomial),
      while the series corresponding to (0,12,-2) has logarithms.
      [SST, page 138] has the polynomial, and four terms of the logarithmic series.
  Subnodes
    "cssExpts"
    "cssExptsMult"
    "cssLeadTerm"
    "distraction"
    "indicialIdeal"
    "isTorusFixed"
    "solveFrobeniusIdeal"
///

doc ///
   Key
     distraction
     (distraction, Ideal, Ring)
     (distraction, RingElement, Ring)
   Headline
     the image in the thetaRing of a torus-fixed element or ideal in a Weyl algebra
   Usage
     distraction(I,thetaRing)
     distraction(f,thetaRing)
   Inputs
     I:Ideal
     f:RingElement
     thetaRing:PolynomialRing
       a stand in for the subring $k[\theta]$ generated by @TT "theta = x*dx"@
   Outputs
     :{Ideal,RingElement}
       that results from intersecting with the thetaRing of D, as in
       [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Lemma 2.3.1] to I.
   Description
    Text
      Given a monomial $x^u \partial^v$, this function rewrites it as a product $x^a p(\theta) \partial^b$,
      where $\theta_i = x_i \partial_i$ for $i = 1,\dots, n$. This is a step in a procedure for checking
      that D-ideal is torus-fixed, and is used in the @TO isTorusFixed@ routine.

      Given a torus fixed $D$-ideal, this function computes the distraction as in [SST, Corollary 2.3.5].
      This is necessary to compute indicial ideals [SST, Theorem 2.3.9, Corollary 2.3.5];
      the roots of the indicial ideals are the exponents of the starting terms of canonical series
      solutions of regular holonomic D-ideals.
    Example
      R1 = QQ[z]
      W1 = makeWA R1
      a=1/2
      b=3
      c=5/3
      J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b) -- the Gauss hypergeometric equation, exponents 0, 1-c
      cssExpts(J,{1})
      K = inw(J,{-1,1})
      distraction(K,QQ[s])
///

doc ///
   Key
     indicialIdeal
     (indicialIdeal, Ideal, List)
   Headline
     the image in the thetaRing of an indicial ideal in a Weyl algebra
   Usage
     indicialIdeal(I,w)
   Inputs
     I:Ideal
       in a WeylAlgebra that is torus-fixed
     w:List
       (generic) weights for $I$, of length half the number of variables in the Weyl algebra
   Outputs
     :Ideal
       that results from intersecting with the thetaRing of D with the result of extending
       the ideal in_(-w,w)(I) with the rational function
       field in the Weyl algebra variables, as in
       [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Theorem 2.3.9] to I.
   Description
    Text
      This computes the distraction of a torus fixed D-ideal [SST, Corollary 2.3.5].
      This is necessary to compute indicial ideals [SST, Theorem 2.3.9, Corollary 2.3.5];
      the roots of the indicial ideals are the exponents of the starting terms of canonical series
      solutions of regular holonomic D-ideals.
    Example
      R1 = QQ[z]
      W1 = makeWA R1
      a=1/2
      b=3
      c=5/3
      J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b) -- the Gauss hypergeometric equation, exponents 0, 1-c
      cssExpts(J,{1})
      K = inw(J,{-1,1})
      distraction(K,QQ[s])
      -- FIXME
      -- indicialIdeal(J,{-11}) -- returns the same answer as the previous distraction command
///

doc ///
   Key
     cssExpts
     (cssExpts, Ideal, List)
   Headline
     the exponents of the canonical series solutions of I in the direction of a weight vector
   Usage
     cssExpts(I,w)
   Inputs
     I:Ideal
       (regular) holonomic ideal in the Weyl algebra
     w:List
       (generic) weights for $I$, of length half the number of variables in the Weyl algebra
   Outputs
     :List
       of exponents of the exponents of the canonical series solutions of I
       in the direction of (-w,w), as in
       [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Theorem 2.3.11].
   Description
    Text
      There are examples in the tutorial that can be moved here.
      Code
      Pre
    Example
      R1 = QQ[z]
      W1 = makeWA R1
      a=1/2
      b=3
      c=5/3
      J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b) -- the Gauss hypergeometric equation, exponents 0, 1-c
      cssExpts(J,{1})
///

doc ///
   Key
     cssExptsMult
     (cssExptsMult, Ideal, List)
   Headline
     the exponents and multiplicities of the canonical series solutions
   Usage
     cssExptsMult(I,w)
   Inputs
     I:Ideal
       (regular) holonomic ideal in the Weyl algebra
     w:List
       (generic) weights for $I$, of length half the number of variables in the Weyl algebra
   Outputs
     :List
       of exponents of the starting exponents of the canonical series solutions of I
       in the direction of (-w,w), as in
       [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Theorem 2.3.11],
       together with their multiplicities.
   Description
    Text
      There are examples in the tutorial that can be moved here.
    Example
      R1 = QQ[z]
      W1 = makeWA R1
      a=1/2
      b=3
      c=5/3
      J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b) -- the Gauss hypergeometric equation, exponents 0, 1-c
      cssExpts(J,{1})
      c=1  -- Now we have a single exponent of multiplicity 2
      J = ideal(z*(1-z)*dz^2+(c-(a+b+1)*z)*dz-a*b)
      cssExpts(J,{1})
      cssExptsMult(J,{1})
///

doc ///
   Key
     isTorusFixed
     (isTorusFixed, Ideal)
   Headline
     checks if an ideal in a Weyl algebra is torus-fixed
   Usage
     isTorusFixed I
   Inputs
     I:Ideal
       in a WeylAlgebra
   Outputs
     :Boolean
       true if I is torus-fixed, false if not
   Description
    Text
       There is a natural action of the n-dimensional algebraic torus on $D$
       where $t \in (\mathbb{C}^*)^n$ acts on $\partial_i$ as $t_i\partial_i$ and on
       $x_i$ as $t_i^{-1}x_i$. The function isTorusFixed verifies whether a D-ideal is
       invariant under this action.

       See [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@],
       just before Lemma 2.3.1.
    Example
       W = makeWA(QQ[x_1,x_2])
       b = 2
       I = ideal(x_1*dx_1*(x_1*dx_1+b), x_1*dx_1*(x_2*dx_2+b),
	   x_2*dx_2*(x_1*dx_1+b), x_2*dx_2*(x_2*dx_2+b))
       isTorusFixed I
///

doc ///
   Key
     solveFrobeniusIdeal
     (solveFrobeniusIdeal, Ideal)
     (solveFrobeniusIdeal, Ideal, Ring)
   Headline
     solving Frobenius ideals
   Usage
     solveFrobeniusIdeal I
     solveFrobeniusIdeal(I, W)
   Inputs
     I:Ideal
       a Frobenius ideal which is m-primary
   Outputs
     :List
       containing monomials times logarithms of the variables
   Description
    Text
      See [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Algorithm 2.3.14].

      Here is [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Example 2.3.16]:
    Example
      R = QQ[t_1..t_5];
      I = ideal(t_1+t_2+t_3+t_4+t_5, t_1+t_2-t_4, t_2+t_3-t_4, t_1*t_3, t_2*t_4);
      solveFrobeniusIdeal I
    Example
      W = makeWeylAlgebra(QQ[x_1..x_5]);
      solveFrobeniusIdeal(I, W)
///


doc ///
   Key
     cssLeadTerm
    (cssLeadTerm, Ideal, List)
   Headline
     lead term of the canonical series solutions of I
   Usage
     cssLeadTerm(I, w)
   Inputs
     I:Ideal
       (regular) holonomic ideal in the Weyl algebra
     w:List
       (generic) weights for $I$, of length half the number of variables in the Weyl algebra
   Outputs
     :List
       containing monomials times logarithms in the variables
   Description
    Text
      This routine returns the lead terms of the canonical series solutions of $I$ with respect
      to the weight vector $w$.
      See [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Algorithm 2.3.14 and Lemma 2.5.10].

      Here is [@HREF("https://mathscinet.ams.org/mathscinet/pdf/1734566.pdf","SST")@, Example 2.3.16]:
    Example
      needsPackage "FourTiTwo"
      A = matrix{{1,1,1,1,1,1},{-2,0,0,0,0,1},{0,1,0,1,0,0},{1,1,2,0,0,1}}
      beta = {2,1,0,2}
      Hbeta = gkz(A,beta)
      w = {9,1,99999, 9999999, 3, 999}
      netList cssLeadTerm(Hbeta, w)
///

end--
restart
path = prepend("~/Projects/M2/Workshops/Workshop-2019-Minneapolis/M2/Macaulay2/packages/", path)
installPackage "HolonomicSystems"
viewHelp solveFrobeniusIdeal

restart
debug needsPackage "HolonomicSystems"
needsPackage "FourTiTwo"

A = matrix{{1,1,1,1},{0,1,3,4}}
beta = {1,2}
Hbeta = gkz(A, beta)
W = ring Hbeta
w = {2,51,999,1}
I = inw(Hbeta, -w|w)

errorDepth=2
(G, sols) = truncatedCanonicalSeries(I, w, 4)

distraction(I_0, first createThetaRing W)
distraction(I, first createThetaRing W)
indicialIdeal(I, w)
cssExptsMult(Hbeta, w)

restart
debug needsPackage "HolonomicSystems"
needsPackage "FourTiTwo"

A = matrix{{1,1,1,1,1,1},{-2,0,0,0,0,1},{0,1,0,1,0,0},{1,1,2,0,0,1}}
beta = {2,1,0,2}
Hbeta = gkz(A,beta)
W = ring Hbeta
--w = {1,2,101,9999,51,7}
w = {9,1,99999, 9999999, 3, 999}
I = inw(Hbeta, -w|w)

solveFrobeniusIdeal(distraction(I, first createThetaRing W), W)
cssExptsMult(Hbeta, w)
holonomicRank Hbeta

restart
errorDepth=2
needsPackage "Dmodules"
needsPackage "FourTiTwo"

A = matrix{{1,1,1,1,1,1},{-2,0,0,0,0,1},{0,1,0,1,0,0},{1,1,2,0,0,1}}
beta = {2,1,0,2}
Hbeta = gkz(A,beta)
--w = {1,2,101,9999,51,7}
w = {9,1,99999, 9999999, 3, 999}

cssExptsMult(Hbeta, w)
cssLeadTerm(Hbeta, w)


A = matrix{{1,1,1,1},{0,1,3,4}}
beta = {1,2}
Hbeta = gkz(A,beta)
W = ring Hbeta
w = {2,51,999,1}
I = inw(Hbeta,flatten{-w|w})

(G, sols) = truncatedCanonicalSeries(I, w, 4)
