Dear all,

in the past few months, Travis and I have worked on a reimplementation of 
lazy formal power series.  With https://trac.sagemath.org/ticket/32367 its 
design and implementation
is now well-developed, and powerful enough so that I'd like to briefly 
present it here.

If you notice any shortcomings or have further feature requests, I am happy 
to hear of them!  Note that there are several other tickets on the same 
topic (all with keyword "LazyPowerSeries"), which are not yet merged, but 
almost ready.

What is it all about?

For us, a 'lazy' series ring is an 'exact' implementation of the concept of 
formal power series.  The adjective 'lazy' means that a coefficient is only 
computed on demand, whereas 'exact' means that you do not have to worry 
about precision (up to the exactness of the base ring) - in principle, all 
the coefficients can be accessed.  By default, the first few coefficients 
will be printed, and the number of coefficients printed can be set by a 
global option.

We have implemented several such rings:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: P.<q,t> = LazyPowerSeriesRing(QQ)
sage: D = LazyDirichletSeriesRing(QQ, "s")
sage: s = SymmetricFunctions(QQ).s(); S = LazySymmetricFunctions(s)
sage: nc = NonCommutativeSymmetricFunctions(QQ).Complete(); NC = 
nc.formal_series_ring()  # or anything in GradedAlgebrasWithBasis

----
Please note that, in particular, the LazyPowerSeriesRing in 
sage/combinat/species/series.py and the LazyLaurentSeriesRing in 
sage/rings/lazy_laurent_series.py have been replaced.
----

For all of these, all the operations you might expect should be available. 
 For example:

sage: sin(z)^2 + cos(z)^2
1 + O(z^7)

sage: (1/sinh(z) + 1/cosh(z))*exp(-z)
z^-1 - 2/3*z + 14/45*z^3 - 124/945*z^5 + O(z^6)

sage: f = L(lambda n: Partitions(n).cardinality(), valuation=0)
sage: f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 7*z^5 + 11*z^6 + O(z^7)

sage: ~f  # the Euler function (see ticket #34381)
1 - z - z^2 + z^5 + O(z^7)

We can efficiently compute with multivariate power series:

sage: exp(q*log(1/(1-t)))
1 + q*t + 1/2*q*t^2 + (1/2*q^2*t^2+1/3*q*t^3) + (1/2*q^2*t^3+1/4*q*t^4) + 
(1/6*q^3*t^3+11/24*q^2*t^4+1/5*q*t^5) + O(q,t)^7

Dirichlet series look and behave quite differently, but the machinery 
behind is very similar:

sage: D(moebius)^-1
1 + 1/(2^s) + 1/(3^s) + 1/(4^s) + 1/(5^s) + 1/(6^s) + 1/(7^s) + O(1/(8^s))

Finally, we can compute with symmetric functions of unbounded degree.  In 
particular, plethysms are supported:

sage: H = S(lambda n: s[n])
sage: H(H-1)
s[] + s[1] + 2*s[2] + (s[2,1]+3*s[3]) + (2*s[2,2]+2*s[3,1]+5*s[4]) + 
(s[2,2,1]+4*s[3,2]+5*s[4,1]+7*s[5]) + 
(2*s[2,2,2]+2*s[3,2,1]+2*s[3,3]+s[4,1,1]+10*s[4,2]+8*s[5,1]+11*s[6]) + O^7

One important feature, which works for all of these, is the possibility to 
define series via implicit equations:

sage: b = P.undefined(valuation=1)
sage: b.define(q + t/(1-b))
sage: b[5]
q^4*t + 10*q^3*t^2 + 30*q^2*t^3 + 35*q*t^4 + 14*t^5

This feature also works with several series that depend on each other:

sage: f = L.undefined(0)
sage: g = L.undefined(0)
sage: f.define(1 + z*g^3)
sage: g.define(1 + z*f^2)
sage: f
1 + z + 3*z^2 + 9*z^3 + 34*z^4 + 132*z^5 + 546*z^6 + O(z^7)
sage: g
1 + z + 2*z^2 + 7*z^3 + 24*z^4 + 95*z^5 + 386*z^6 + O(z^7)

Again, comments are very welcome!

Best wishes,

Martin

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sage-devel/071fb7d5-0865-4778-bfa5-ed17f204609an%40googlegroups.com.

Reply via email to