Lazy Infinite Power Series

22 views
Skip to first unread message

Henryk Trappmann

unread,
Oct 29, 2008, 4:11:49 PM10/29/08
to sage-devel
Hello,

I developed a package to work with infinite power series.
You can work with the power series mostly like with functions, the
actual value of a coefficient is computed when requested.
For example (the working title is PowerSeriesRingI, "I" like
infinite):

sage: PQ = PowerSeriesRingI(QQ)
sage: #Predefined
PowerSeries
sage: expps = PQ.exp
sage: expps.poly(10,x)
1/362880*x^9 + 1/40320*x^8 + 1/5040*x^7 + 1/720*x^6 +
1/120*x^5 + 1/24*x^4 + 1/6*x^3 + 1/2*x^2 + x + 1
sage: expps
[1, 1, 1/2, 1/6, 1/24, 1/120, 1/720, 1/5040, 1/40320,
1/362880, 1/3628800, ...]
sage: PQ.zero
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: PQ.one
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: PQ.id
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: #finite
powerseries
sage: p = PQ([1,2,3,4])
sage: p.poly(10,x)
4*x^3 + 3*x^2 + 2*x + 1
sage: p
[1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: one = PQ([1])
sage: id = PQ([0,1])

sage: #power series are just functions that map the index to
the coefficient
sage: expps[30]
1/265252859812191058636308480000000

sage: #power series
operations
sage: p+p
[2, 4, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: p-p
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: p*p
[1, 4, 10, 20, 25, 24, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, ...]
sage: one/p
[1, -2, 1, 0, 5, -14, 13, -4, 25, -90, 121, -72, 141, -550,
965, -844, 993, ...]
sage: p.rcp()/p*p*p
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: p**2
[1, 4, 10, 20, 25, 24, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, ...]
sage: #composition only works for coefficient 0 being 0 in the
second operand
sage: dexp = expps - one
sage: expps.o(dexp)
[1, 1, 1, 5/6, 5/8, 13/30, 203/720, 877/5040, 23/224,
1007/17280, ...]

Beneath composition it can also perform (fractional) iteration
sage: #we come into interesting
regions ...
sage: dexp.o(dexp)
[0, 1, 1, 5/6, 5/8, 13/30, 203/720, 877/5040, 23/224,
1007/17280, ...]
sage: dexp.nit(2)
[0, 1, 1, 5/6, 5/8, 13/30, 203/720, 877/5040, 23/224,
1007/17280, ...]
sage: dexp.it(-1)
[0, 1, -1/2, 1/3, -1/4, 1/5, -1/6, 1/7, -1/8, 1/9, -1/10,
1/11, -1/12, ...]
sage: dexp.it(-1).o(dexp)
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]
sage: hdexp = dexp.it(1/2)
sage: hdexp
[0, 1, 1/4, 1/48, 0, 1/3840, -7/92160, 1/645120, 53/3440640,
-281/30965760, ...]
sage: #verifying that shoudl be
Zero
sage: hdexp.it(2) - dexp
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...]

My question is about making this a standard SAGE package.
Is there any guideline how to do so and what are the criteria and
requirements?

David Roe

unread,
Oct 29, 2008, 4:34:12 PM10/29/08
to sage-...@googlegroups.com
Great! This has been on my list of things I'd like to have
implemented for a while.

Presumably, much of this code will be incorporated into the Sage
library. So it's not really a "package" per se. Instead, you should
make a ticket on trac (http://trac.sagemath.org/sage_trac), for which
you need an account. Then you should post Mercurial patches there,
that include both the changes to existing files and the new files that
you've created (there's a Mercurial tutorial at
http://sagemath.org/doc/prog/index.html if you need it). Then you
should have someone review the code, at which point it can be merged
into the current Sage release.
David

Martin Rubey

unread,
Oct 29, 2008, 4:48:37 PM10/29/08
to sage-...@googlegroups.com
"David Roe" <ro...@math.harvard.edu> writes:

> Great! This has been on my list of things I'd like to have
> implemented for a while.
>
> Presumably, much of this code will be incorporated into the Sage
> library. So it's not really a "package" per se. Instead, you should
> make a ticket on trac (http://trac.sagemath.org/sage_trac), for which
> you need an account. Then you should post Mercurial patches there,
> that include both the changes to existing files and the new files that
> you've created (there's a Mercurial tutorial at
> http://sagemath.org/doc/prog/index.html if you need it). Then you
> should have someone review the code, at which point it can be merged
> into the current Sage release.

As far as I know, Mike Hansen ported Ralf Hemmecke's lazy power series, too, to
python. They are not "exposed", however.

Martin

Mike Hansen

unread,
Oct 29, 2008, 6:50:22 PM10/29/08
to sage-...@googlegroups.com
Hello,

On Wed, Oct 29, 2008 at 1:48 PM, Martin Rubey <martin...@univie.ac.at> wrote:
> As far as I know, Mike Hansen ported Ralf Hemmecke's lazy power series, too, to
> python. They are not "exposed", however.

In Sage 3.1.4, LazyPowerSeriesRing is exported to the global
namespace. You can find the source here:
http://www.sagemath.org/hg/sage-main/file/3859ace86968/sage/combinat/species/series.py.
One of the nice things about (and primary motivations behind) Ralf's
code is to allow for recursively defined series by keeping track of a
lower bound on the order of all series wherever possible.

--Mike

Mike Hansen

unread,
Oct 29, 2008, 7:08:07 PM10/29/08
to sage-...@googlegroups.com

Sorry for the double post. There is definitely some work that needs
to be done on the current implementation of lazy power series in Sage
such as getting it to do scalar multiplication of series directly
instead of turning the scalar into a power series and taking the
Cauchy product (!). It would also be beneficial to implement van der
Hoeven's lazy/relaxed multiplication:
http://algo.inria.fr/seminars/sem99-00/vanderhoeven.html .

--Mike

Minh Nguyen

unread,
Oct 29, 2008, 8:08:53 PM10/29/08
to sage-...@googlegroups.com
Hi Henryk,

On Thu, Oct 30, 2008 at 7:34 AM, David Roe <ro...@math.harvard.edu> wrote:
>
> Great! This has been on my list of things I'd like to have
> implemented for a while.
>
> Presumably, much of this code will be incorporated into the Sage
> library. So it's not really a "package" per se. Instead, you should
> make a ticket on trac (http://trac.sagemath.org/sage_trac), for which
> you need an account. Then you should post Mercurial patches there,
> that include both the changes to existing files and the new files that
> you've created (there's a Mercurial tutorial at
> http://sagemath.org/doc/prog/index.html if you need it). Then you
> should have someone review the code, at which point it can be merged
> into the current Sage release.
> David
>
> On Wed, Oct 29, 2008 at 4:11 PM, Henryk Trappmann
> <bo19...@googlemail.com> wrote:
>>
>> Hello,
>>
>> I developed a package to work with infinite power series.
>> You can work with the power series mostly like with functions, the
>> actual value of a coefficient is computed when requested.
>> For example (the working title is PowerSeriesRingI, "I" like
>> infinite):

[...]


>> My question is about making this a standard SAGE package.
>> Is there any guideline how to do so and what are the criteria and
>> requirements?

I just like to add that you might find the "Sage Developer's Guide" useful:

http://www.sagemath.org/doc/prog/prog.html

Since we're working with trac and use mercurial from a Sage interface,
I strongly recommend that you use our Sage interface to mercurial, not
mercurial itself. That is, please use the family hg_sage.* of commands
for interfacing with mercurial, and not hg (which is your local copy
of mercurial). Using hg_sage.* for producing patches makes it easier
for other developers to review your code. In some cases, this can
actually expedite the review process.

Also, you might find the "Trac Guidelines for Sage" at

http://wiki.sagemath.org/TracGuidelines

useful.

--
Regards
Minh Van Nguyen

Web: http://nguyenminh2.googlepages.com
Blog: http://mvngu.wordpress.com

Henryk Trappmann

unread,
Oct 29, 2008, 8:26:49 PM10/29/08
to sage-devel


On Oct 30, 12:08 am, "Mike Hansen" <mhan...@gmail.com> wrote:
> On Wed, Oct 29, 2008 at 3:50 PM, Mike Hansen <mhan...@gmail.com> wrote:
> > Hello,
>
> > On Wed, Oct 29, 2008 at 1:48 PM, Martin Rubey <martin.ru...@univie.ac.at> wrote:
> >> As far as I know, Mike Hansen ported Ralf Hemmecke's lazy power series, too, to
> >> python. They are not "exposed", however.
>
> > In Sage 3.1.4, LazyPowerSeriesRing is exported to the global
> > namespace. You can find the source here:
> >http://www.sagemath.org/hg/sage-main/file/3859ace86968/sage/combinat/....
> > One of the nice things about (and primary motivations behind) Ralf's
> > code is to allow for recursively defined series by keeping track of a
> > lower bound on the order of all series wherever possible.

Ya, my code does that too. I even implemented formal Laurent-Series
for some operations (negative lower bound).

Many interesting things in power series manipulation are not
implemented in your LazyPowerSeriesRing, for example:
reciprocal 1/f, non-integer powers, inverse power series, non-integer
iteration, and not to mention a lot of base series (log(x+1), sin,
cos, tan, arcsin, arctan, sinh, ..., they are much slower if produced
from derivation of functions.)
I did not even find a constructor for the power series development of
a given function at a certain development point (taylor series).

So how do we continue here? There is the possibility of a merge or of
a competition, I dont know whether the latter is possible at all in
Sage (two packages with similar functionality but different
implementation). Perhaps one would put them in different topics
combinatorics vs. analysis, or something. Any good suggestions?

Mike Hansen

unread,
Oct 29, 2008, 9:07:10 PM10/29/08
to sage-...@googlegroups.com
Hi Henryk,

On Wed, Oct 29, 2008 at 5:26 PM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
> Ya, my code does that too. I even implemented formal Laurent-Series
> for some operations (negative lower bound).
>
> Many interesting things in power series manipulation are not
> implemented in your LazyPowerSeriesRing, for example:
> reciprocal 1/f, non-integer powers, inverse power series, non-integer
> iteration, and not to mention a lot of base series (log(x+1), sin,
> cos, tan, arcsin, arctan, sinh, ..., they are much slower if produced
> from derivation of functions.)
> I did not even find a constructor for the power series development of
> a given function at a certain development point (taylor series).

Yep, I didn't implement many of these things since I didn't have a
need/use for them at the time.

> So how do we continue here? There is the possibility of a merge or of
> a competition, I dont know whether the latter is possible at all in
> Sage (two packages with similar functionality but different
> implementation). Perhaps one would put them in different topics
> combinatorics vs. analysis, or something. Any good suggestions?

Is your code posted anywhere? I'm sure we can come up with a way to
merge the two implementations.

--Mike

Robert Bradshaw

unread,
Oct 29, 2008, 10:01:05 PM10/29/08
to sage-...@googlegroups.com

This is somewhat OT, but just to clarify, I never use the hg_sage.*
commands and I never have any issues. Nor do a many of the other
developers I know. For example, lots of people find mercurial queues
very useful and they are not exposed in the hg_sage interface at all.
Also, it's a lot easier to find documentation on the "unwrapped"
version.

It is important to use mercurial to make your patches integrate well
into the workflow, but hg_sage.* simply calls the command-line hg,
and so the output is byte-for-byte exactly the same.

> Also, you might find the "Trac Guidelines for Sage" at
>
> http://wiki.sagemath.org/TracGuidelines
>
> useful.

+1 to this.

More on topic, much better merge the two and have the best of both
than have competing implementations. Shouldn't this belong in sage/
rings rather than in combinat?

- Robert

William Stein

unread,
Oct 29, 2008, 10:15:01 PM10/29/08
to sage-...@googlegroups.com

By the way, I wish the queues *were* exposed via the hg_sage.*
interface.

> It is important to use mercurial to make your patches integrate well
> into the workflow, but hg_sage.* simply calls the command-line hg,
> and so the output is byte-for-byte exactly the same.

Yep.

>> Also, you might find the "Trac Guidelines for Sage" at
>>
>> http://wiki.sagemath.org/TracGuidelines
>>
>> useful.
>
> +1 to this.
>
> More on topic, much better merge the two and have the best of both
> than have competing implementations. Shouldn't this belong in sage/
> rings rather than in combinat?

+1

William

kcrisman

unread,
Oct 29, 2008, 10:35:06 PM10/29/08
to sage-devel
> By the way, I wish the queues *were* exposed via the hg_sage.*
> interface.

+1 to this, and that the documentation for it on the Wiki compared
things to action under the 'usual' commands, or that documentation for
it was under the Programmer's Guide.

- kcrisman

Dan Drake

unread,
Oct 29, 2008, 10:39:24 PM10/29/08
to sage-...@googlegroups.com
On Wed, 29 Oct 2008 at 07:01PM -0700, Robert Bradshaw wrote:
> This is somewhat OT, but just to clarify, I never use the hg_sage.*
> commands and I never have any issues. Nor do a many of the other
> developers I know. For example, lots of people find mercurial queues
> very useful and they are not exposed in the hg_sage interface at all.
> Also, it's a lot easier to find documentation on the "unwrapped"
> version.

I also simply use my system-wide Mercurial. The only problems I've ever
had with this have been of the between-keyboard-and-chair variety, and
using hg_sage wouldn't have fixed that. :)

Dan

--
--- Dan Drake <dr...@mathsci.kaist.ac.kr>
----- KAIST Department of Mathematical Sciences
------- http://mathsci.kaist.ac.kr/~drake

signature.asc

Henryk Trappmann

unread,
Oct 30, 2008, 3:49:08 AM10/30/08
to sage-devel
On Oct 30, 2:07 am, "Mike Hansen" <mhan...@gmail.com> wrote:
> Is your code posted anywhere? I'm sure we can come up with a way to
> merge the two implementations.

Yes you can see it here:
http://github.com/bo198214/hyperops/tree/master/powerseries.py

it was originally developed for a different project (so has to be
moved/renamed), but I tried to the powerseries class fairly complete.
I also included lots of tests in the documentation of the _test
method, which pass under sage -t.

Our lazy mechanism seems however very different.
While you use somehow Stream, I just have a hash table for each power
series.

As it should be more difficult to implement all the functionality of
my code into your code I propose
to take my code as a base and add functionality you need that is not
contained yet, thereby making the code more round.


On Oct 30, 3:01 am, Robert Bradshaw <rober...@math.washington.edu>
wrote:
> More on topic, much better merge the two and have the best of both
> than have competing implementations. Shouldn't this belong in sage/
> rings rather than in combinat?

Yes I agree.

I also still search a cool name instead of LazyPowerSeriesRing or
PowerSeriesRingI, any ideas?

I think it should start with PowerSeries or PS as someone who searches
for such functionality can use the tab completion then.

On the other hand the difference to the standard finite
sage.rings.power_series_ring.PowerSeriesRing should be made clear.

Robert Bradshaw

unread,
Oct 30, 2008, 4:35:15 AM10/30/08
to sage-...@googlegroups.com
On Oct 30, 2008, at 12:49 AM, Henryk Trappmann wrote:

> On Oct 30, 3:01 am, Robert Bradshaw <rober...@math.washington.edu>
> wrote:
>> More on topic, much better merge the two and have the best of both
>> than have competing implementations. Shouldn't this belong in sage/
>> rings rather than in combinat?
>
> Yes I agree.
>
> I also still search a cool name instead of LazyPowerSeriesRing or
> PowerSeriesRingI, any ideas?
>
> I think it should start with PowerSeries or PS as someone who searches
> for such functionality can use the tab completion then.
>
> On the other hand the difference to the standard finite
> sage.rings.power_series_ring.PowerSeriesRing should be made clear.

I like LazyPowerSeriesRing, but I also thing the PowerSeriesRing
constructor should take 'lazy' or infinity as a precision, creating
an actual LazyPowerSeriesRing.

- Robert

Mike Hansen

unread,
Oct 30, 2008, 4:44:19 AM10/30/08
to sage-...@googlegroups.com
Hello,

On Thu, Oct 30, 2008 at 12:49 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
> Our lazy mechanism seems however very different.
> While you use somehow Stream, I just have a hash table for each power
> series.

Actually, they're doing pretty much the same thing. A stream models
an infinite list, and you just need to provide a method for it to be
able to compute the entries. Currently, this is usually done by
providing an iterator, but it'd be trivial to make it so that it can
take a function which take in n and produces the nth coefficient on
the list.

> As it should be more difficult to implement all the functionality of
> my code into your code I propose
> to take my code as a base and add functionality you need that is not
> contained yet, thereby making the code more round.

One of the main features that I need is the ability to handle
recursively/implicitly defined power series. This is currently not
possible in your code base because the series aren't "lazy enough".
Specifically, in the constructor for your power series, you compute
coefficients and set the _val attribute.

I've looked over all of your code and would be willing to port over
all of the features not currently in Sage next Tuesday.

--Mike

John Cremona

unread,
Oct 30, 2008, 5:17:49 AM10/30/08
to sage-...@googlegroups.com
2008/10/30 Robert Bradshaw <robe...@math.washington.edu>:

>
>> Since we're working with trac and use mercurial from a Sage interface,
>> I strongly recommend that you use our Sage interface to mercurial, not
>> mercurial itself. That is, please use the family hg_sage.* of commands
>> for interfacing with mercurial, and not hg (which is your local copy
>> of mercurial). Using hg_sage.* for producing patches makes it easier
>> for other developers to review your code. In some cases, this can
>> actually expedite the review process.
>
> This is somewhat OT, but just to clarify, I never use the hg_sage.*
> commands and I never have any issues. Nor do a many of the other
> developers I know. For example, lots of people find mercurial queues
> very useful and they are not exposed in the hg_sage interface at all.
> Also, it's a lot easier to find documentation on the "unwrapped"
> version.
>

I often work on systems which don't have their own hg (and on which I
cannot install stuff), so it might be relevant to people to mention
that you can run Sage's hg via "sage -hg" from the command line. That
way you are also sure to be using the right version of hg even if your
system's version is different.

John

mabshoff

unread,
Oct 30, 2008, 5:21:29 AM10/30/08
to sage-devel


On Oct 30, 2:17 am, "John Cremona" <john.crem...@gmail.com> wrote:
> 2008/10/30 Robert Bradshaw <rober...@math.washington.edu>:
Or run "sage -sh" and Sage's hg will be the first in $PATH.

> John

Cheers,

Michael

Henryk Trappmann

unread,
Oct 30, 2008, 7:35:55 AM10/30/08
to sage-devel
On Oct 30, 9:44 am, "Mike Hansen" <mhan...@gmail.com> wrote:
> One of the main features that I need is the ability to handle
> recursively/implicitly defined power series. This is currently not
> possible in your code base because the series aren't "lazy enough".

Yes thats true. Currently if I need cached recursion (and I need it in
the code),
I do

s = PS() #uninitialized powerseries
def f(n):
#fibonacci example
if n==0 or n==1:
return 1
#do something with previous values
else:
return s[n-1] + s[n-2]

and afterwards I set the coefficients:

s.f = f

maybe this is more comfortable with Streams, I dont know.

> Specifically, in the constructor for your power series, you compute
> coefficients and set the _val attribute.

But thats pure luxury, its not really necessary.

> I've looked over all of your code and would be willing to port over
> all of the features not currently in Sage next Tuesday.

Ok, then I agree (though thats not the lazy approach ;) )

Some notes:
1. sexp should not belong to the powerseries package
2. it_matrixpower and it_mp is experimental and dont need to be ported
3. For each powerseries I additionally cached its powers (s**n), this
saves a lot of computing time in composition and iteration.

What about lazy Laurent series?
What about moving from combinat to rings?

Henryk

Mike Hansen

unread,
Oct 30, 2008, 8:14:16 AM10/30/08
to sage-...@googlegroups.com
Hi,

On Thu, Oct 30, 2008 at 4:35 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
> Yes thats true. Currently if I need cached recursion (and I need it in
> the code),
> I do
>
> s = PS() #uninitialized powerseries
> def f(n):
> #fibonacci example
> if n==0 or n==1:
> return 1
> #do something with previous values
> else:
> return s[n-1] + s[n-2]
>
> and afterwards I set the coefficients:
>
> s.f = f
>
> maybe this is more comfortable with Streams, I dont know.

When I said recursively defined streams, I meant something a little
more general. For example, if f is a power series and g is exp(f),
then g satisfies g = \int g*f'. This translates to the following code
for the exponential of power series:

g.define( (f.derivative()*g).integral(base_ring(1)) )

The benefit of this is that it reduces the complexity of
exponentiation to that of multiplication for which there are fast
algorithms. Generally, you want to reduce everything (composition,
division, logs, etc) to multiplication in order to get asymptotically
fast algorithms.

>> Specifically, in the constructor for your power series, you compute
>> coefficients and set the _val attribute.
>
> But thats pure luxury, its not really necessary.
>
>> I've looked over all of your code and would be willing to port over
>> all of the features not currently in Sage next Tuesday.
>
> Ok, then I agree (though thats not the lazy approach ;) )
>
> Some notes:
> 1. sexp should not belong to the powerseries package
> 2. it_matrixpower and it_mp is experimental and dont need to be ported
> 3. For each powerseries I additionally cached its powers (s**n), this
> saves a lot of computing time in composition and iteration.
>
> What about lazy Laurent series?

Are you asking how one would implement them? What sort of features
would one require for lazy Laurent series?

> What about moving from combinat to rings?

The reason why it was in combinat/ is because I had written it for my
particular use case. There are some things that need to be done for
it to be usable in a wider setting. For example, certain things only
make sense when you have a power series over a field.

--Mike

Henryk Trappmann

unread,
Oct 30, 2008, 9:29:35 AM10/30/08
to sage-devel
On Oct 30, 1:14 pm, "Mike Hansen" <mhan...@gmail.com> wrote:
> When I said recursively defined streams, I meant something a little
> more general. For example, if f is a power series and g is exp(f),
> then g satisfies g = \int g*f'. This translates to the following code
> for the exponential of power series:
>
> g.define( (f.derivative()*g).integral(base_ring(1)) )

If that works, the better.

>
> The benefit of this is that it reduces the complexity of
> exponentiation to that of multiplication for which there are fast
> algorithms. Generally, you want to reduce everything (composition,
> division, logs, etc) to multiplication in order to get asymptotically
> fast algorithms.

Sure, but I would say functionality before performance.

> > What about lazy Laurent series?
>
> Are you asking how one would implement them? What sort of features
> would one require for lazy Laurent series?

I am asking: why not more generally implement them instead of purely
powerseries, I think they are only a slight generalization of
powerseries.

> > What about moving from combinat to rings?
>
> The reason why it was in combinat/ is because I had written it for my
> particular use case. There are some things that need to be done for
> it to be usable in a wider setting. For example, certain things only
> make sense when you have a power series over a field.

I was also thinking about similar issues. Also some operations require
and guaranty the first coefficient to be 0.
I wonder whether to introduce a subtype for those powerseries because
it is not always decidable whether something is 0 in the base_ring.
Formal Laurent series would also form a field.
For example the formal Laurent series are a field.

Ralf Hemmecke

unread,
Oct 30, 2008, 1:06:12 PM10/30/08
to sage-...@googlegroups.com
> Formal Laurent series would also form a field.
> For example the formal Laurent series are a field.

While this is certainly true mathematically, you might run into trouble
computationally.

In a (additive and commutative) monoid M there is a (unique) x in M such
that for all m in M it holds: x + m = m.

Does that axiom hold for your implementation? Can you prove it?

Ralf

William Stein

unread,
Oct 30, 2008, 2:00:57 PM10/30/08
to sage-...@googlegroups.com

Sage is full of "fields" that aren't actually fields mathematically.
Field in Sage means "object that models a mathematical field",
but includes e.g., the "field of double precision floating point numbers",
which isn't really a field (e.g., it is finite).

-- William

Henryk Trappmann

unread,
Oct 31, 2008, 4:49:44 AM10/31/08
to sage-devel
Actually a straightforward implementation of formal Laurent series not
only models but *is* a field with 0 being (0,0,....) and 1 being
(1,0,....).
A field like QQ is a field. The only difference is that you can decide
equality in QQ but not in the formal Laurent series.
It is straight forward to show that 0 + m = m, or even that 0 is the
only series that does so.

Ralf Hemmecke

unread,
Oct 31, 2008, 5:05:12 AM10/31/08
to sage-...@googlegroups.com
> Sage is full of "fields" that aren't actually fields mathematically.
> Field in Sage means "object that models a mathematical field",
> but includes e.g., the "field of double precision floating point numbers",
> which isn't really a field (e.g., it is finite).

And + is not associative...

I guess all that hits back when time comes and one actually wants to
prove something about a program without starting a computation.

Ralf

mabshoff

unread,
Oct 31, 2008, 8:38:44 AM10/31/08
to sage-devel


On Oct 31, 2:05 am, Ralf Hemmecke <r...@hemmecke.de> wrote:
> > Sage is full of "fields" that aren't actually fields mathematically.
> > Field in Sage means "object that models a mathematical field",
> > but includes e.g., the "field of double precision floating point numbers",
> > which isn't really a field (e.g., it is finite).

Hi Ralf,

> And + is not associative...

It isn't for floats, but for "real" fields it is.

> I guess all that hits back when time comes and one actually wants to
> prove something about a program without starting a computation.

Why would that matter? Can you give an example?

> Ralf

Cheers,

Michael

Jason Grout

unread,
Oct 31, 2008, 1:31:43 PM10/31/08
to sage-...@googlegroups.com
mabshoff wrote:
>
>
> On Oct 31, 2:05 am, Ralf Hemmecke <r...@hemmecke.de> wrote:
>>> Sage is full of "fields" that aren't actually fields mathematically.
>>> Field in Sage means "object that models a mathematical field",
>>> but includes e.g., the "field of double precision floating point numbers",
>>> which isn't really a field (e.g., it is finite).
>
> Hi Ralf,
>
>> And + is not associative...
>
> It isn't for floats, but for "real" fields it is.


Where, of course, "real" does not mean "RealField", I presume :).

"real" means QQ, ZZ, etc.

Jason

mabshoff

unread,
Oct 31, 2008, 1:36:47 PM10/31/08
to sage-devel
Yes, "real" == fields where the mathematical definition is fulfilled.
IEEE floating point math is just crap that we have to live with :)

> Jason

Cheers,

Michael

Henryk Trappmann

unread,
Nov 1, 2008, 7:51:37 AM11/1/08
to sage-devel
Maybe its a bit off topic but in the line of thought:

I wonder whether the subset of the reals generated by
+,-,*,/,x^y,log_x y from {1} (that means it contains at least Q)
is decidable (i.e. whether we can decide equality for two given
expressions in the operations and 1).
For a start we could omit the log and in addition to the 4 base
operation only demand that for each two real positivie numbers x and y
also x^y is contained.

Does anyone know about research/results in that direction?

Henryk

Nicolas M. Thiery

unread,
Mar 9, 2009, 12:42:56 AM3/9/09
to sage-...@googlegroups.com
Dear Mike, dear Henryk,

What's the status of the merge of your implementations of power
series? I need a couple functionalities not yet in Mike's
implementation, and mainly:
- conversion from a polynomial
- division

On Thu, Oct 30, 2008 at 06:29:35AM -0700, Henryk Trappmann wrote:
> On Oct 30, 1:14 pm, "Mike Hansen" <mhan...@gmail.com> wrote:
> > When I said recursively defined streams, I meant something a little
> > more general. For example, if f is a power series and g is exp(f),
> > then g satisfies g = \int g*f'. This translates to the following code
> > for the exponential of power series:
> >
> > g.define( (f.derivative()*g).integral(base_ring(1)) )
>
> If that works, the better.
>
> >
> > The benefit of this is that it reduces the complexity of
> > exponentiation to that of multiplication for which there are fast
> > algorithms. Generally, you want to reduce everything (composition,
> > division, logs, etc) to multiplication in order to get asymptotically
> > fast algorithms.
>
> Sure, but I would say functionality before performance.

This approach gives both: it's a very powerful way to define most of
the operations in very few lines, while giving optimal complexity (it
can be seen as a newton iteration in disguise).

<snip>

Cheers,
Nicolas
--
Nicolas M. Thiéry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/

Henryk Trappmann

unread,
Mar 25, 2009, 9:14:55 AM3/25/09
to sage-devel
On Mar 9, 5:42 am, "Nicolas M. Thiery" <Nicolas.Thi...@u-psud.fr>
wrote:
> What's the status of the merge of your implementations of power
> series? I need a couple functionalities not yet in Mike's
> implementation, and mainly:
>  - conversion from a polynomial
>  - division

Actually I improved my powerseries package and it is ready for
incorporation into sage (after some package path modifications).
I did not get a response from Mike Hansen, who initially wanted to
port and incorporate into his package.

So I want to make it an own package. What are the next steps to
continue?

William Stein

unread,
Mar 25, 2009, 11:58:27 AM3/25/09
to sage-...@googlegroups.com

For starters, it couldn't hurt to post a link to your code so people
know what it is.

William

Henryk Trappmann

unread,
Mar 25, 2009, 12:13:39 PM3/25/09
to sage-devel

William Stein

unread,
Mar 25, 2009, 12:17:24 PM3/25/09
to sage-...@googlegroups.com
On Wed, Mar 25, 2009 at 9:13 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> http://github.com/bo198214/hyperops/raw/a5b716d48751778ffccff6769a96d9bea428b4d1/powerseries.py
>

Your doctest coverage score on that file is currently 1% but has to be
100% before it could be included in Sage:

teragon:tmp wstein$ sage -coverage powerseries.py
----------------------------------------------------------------------
powerseries.py
ERROR: Please define a s == loads(dumps(s)) doctest.
SCORE powerseries.py: 1% (2 of 122)

Missing documentation:
* decidable0(K):
* byLambda(self,f,*args,**kwargs):
* byUndefined(self,T=None):
* bySeq(self,list,start=0,**kwargs):
* f(k):
* byTaylor(self,expr,v,at=0,**kwargs):
* zero_element(self):
...

Also, you should use standard Python conventions for function names,
e.g., "byTaylor" should be "by_taylor", i.e., only use CamelCase for
class names and use lower case and underscores for function names.

William
--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

Henryk Trappmann

unread,
Mar 25, 2009, 2:26:02 PM3/25/09
to sage-devel
Oh, then I have some questions.

First how shall the class finally be named (the current name
PowerSeriesI is rather a working title):
LazyPowerSeries (conflict with Mike Hansen's package),
InfinitePowerSeries, LIPS?

and into which package should it go: sage.rings ?

shall it inherit from Ring?

Though it can also be used as a field if it is taken over a Field
(i.e. has formal laurant series properties).

William Stein

unread,
Mar 25, 2009, 2:52:25 PM3/25/09
to sage-...@googlegroups.com
On Wed, Mar 25, 2009 at 11:26 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> Oh, then I have some questions.
>
> First how shall the class finally be named (the current name
> PowerSeriesI is rather a working title):
> LazyPowerSeries (conflict with Mike Hansen's package),
> InfinitePowerSeries, LIPS?

(1) CamelCase is good for class names

(2) It isn't a problem to use the same name as a class in another file
-- there's no conflict at all in Python because of namespaces.

(3) I can't tell you what to name your class.

> and into which package should it go: sage.rings ?

Yes.

> shall it inherit from Ring?

Is it a ring? If so, then yes. Inheritance must *always* satisfy an
"is a" relationship. I.e., if you ever do

class X(Y):
...

then every instance of the class X has to be a special case of Y.
I.e., "Any X is a Y".

E.g., here, any lazy power series ring R is certainly a ring.

> Though it can also be used as a field if it is taken over a Field
> (i.e. has formal laurant series properties).

I can't tell you which to do. Field derives from Ring.

William

mabshoff

unread,
Mar 25, 2009, 3:08:13 PM3/25/09
to sage-devel


On Mar 25, 11:26 am, Henryk Trappmann <bo198...@googlemail.com> wrote:
> Oh, then I have some questions.
>
> First how shall the class finally be named (the current name
> PowerSeriesI is rather a working title):
> LazyPowerSeries (conflict with Mike Hansen's package),
> InfinitePowerSeries, LIPS?

Why can't this code be patched into Mike's LazyPowerSeries class? I
really don't think we want the same thing implemented twice in Sage
with overlapping functionality.

Cheers,

Michael

Henryk Trappmann

unread,
Mar 25, 2009, 3:31:46 PM3/25/09
to sage-devel
On Mar 25, 8:08 pm, mabshoff <mabsh...@googlemail.com> wrote:
> Why can't this code be patched into Mike's LazyPowerSeries class? I
> really don't think we want the same thing implemented twice in Sage
> with overlapping functionality.

For me its just too much effort to port all the functionality and to
retest.
My class has much more functionality than his, it makes no sense to
port it this way.
And he didnt conduct his own offer to port it completely into his
code.
Also his class resides somewhere in combinat, where I wouldnt put a
general purpose powerseries package.

The class will be called InfinitePowerSeries(Ring).

Robert Bradshaw

unread,
Mar 25, 2009, 3:36:01 PM3/25/09
to sage-...@googlegroups.com

It should inherit from Ring. Whether or not it's a field should
depend on its category, not its implementation, and can be queried
with X.is_field()

- Robert

Nicolas M. Thiery

unread,
Mar 25, 2009, 11:26:56 PM3/25/09
to sage-...@googlegroups.com
Dear Henryk, dear Mike,

On Wed, Mar 25, 2009 at 12:31:46PM -0700, Henryk Trappmann wrote:
> On Mar 25, 8:08 pm, mabshoff <mabsh...@googlemail.com> wrote:
> > Why can't this code be patched into Mike's LazyPowerSeries class? I
> > really don't think we want the same thing implemented twice in Sage
> > with overlapping functionality.
>
> For me its just too much effort to port all the functionality and to
> retest. My class has much more functionality than his, it makes no
> sense to port it this way. And he didnt conduct his own offer to
> port it completely into his code.

Mike: could you pleeeeaaaase answer this e-mail??? We really really
really don't want two separate implementations.

Henryk: could you please make sure that your implementation is as much
as possible compatible with Mike, and implements all its functionality
(or at least to make sure that the design does not prevent porting the
missing bits). Then the transition will be easy.

> Also his class resides somewhere in combinat, where I wouldnt put a
> general purpose powerseries package.

(definitely this was just a temporary accident)

> The class will be called InfinitePowerSeries(Ring).

Thanks for your work on this!

Best,

mabshoff

unread,
Mar 26, 2009, 12:07:26 AM3/26/09
to sage-devel


On Mar 25, 8:26 pm, "Nicolas M. Thiery" <Nicolas.Thi...@u-psud.fr>
wrote:
>         Dear Henryk, dear Mike,

<SNIP>

> Mike: could you pleeeeaaaase answer this e-mail???

Right now it is spring break at UW, so I expect Mike to pop up soon
again.

> We really really really don't want two separate implementations.

Well, I will not merge a second implementation as long as there is no
clear roadmap for resolving the problem. The code for the
LazyPowerSeries should not have been in combinat to begin with. The
ideal outcome of this would be a re-factored LazyPowerSeries in rings
somewhere. As is Henryk's code needs doctesting and definitely some
Sage-ization style wise, etc, so this will take some time either way.

> Henryk: could you please make sure that your implementation is as much
> as possible compatible with Mike, and implements all its functionality
> (or at least to make sure that the design does not prevent porting the
> missing bits). Then the transition will be easy.

Well, see above. Similar is not the goal here.

> > Also his class resides somewhere in combinat, where I wouldnt put a
> > general purpose powerseries package.
>
> (definitely this was just a temporary accident)
>
> > The class will be called InfinitePowerSeries(Ring).
>
> Thanks for your work on this!
>
> Best,
>                                 Nicolas

Cheers,

Michael


> --
> Nicolas M. Thiéry "Isil" <nthi...@users.sf.net>http://Nicolas.Thiery.name/

Henryk Trappmann

unread,
Mar 26, 2009, 8:58:17 AM3/26/09
to sage-devel
On Mar 26, 5:07 am, mabshoff <mabsh...@googlemail.com> wrote:
> Well, I will not merge a second implementation as long as there is no
> clear roadmap for resolving the problem.

The basic functionality of Mike's powerseries class is also contained
in my class.
That is add, multiply, power, composition, shift, differentiate and
integrate.
I also changed my implementation that now a recursive define is
possible according to Ralf Hemmecke's suggestion in this thread.
I can incorporate any additional functionality from Mike's
implementation after consulting him, also about about sage style and
conventions etc.

Is this a roadmap of resolving the problem? Or is there a special need
to start with Mike's implementation as base?

Henryk

William Stein

unread,
Mar 26, 2009, 10:52:03 AM3/26/09
to sage-...@googlegroups.com
On Thu, Mar 26, 2009 at 5:58 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> On Mar 26, 5:07 am, mabshoff <mabsh...@googlemail.com> wrote:
>> Well, I will not merge a second implementation as long as there is no
>> clear roadmap for resolving the problem.
>
> The basic functionality of Mike's powerseries class is also contained
> in my class.
> That is add, multiply, power, composition, shift, differentiate and
> integrate.
> I also changed my implementation that now a recursive define is
> possible according to Ralf Hemmecke's suggestion in this thread.
> I can incorporate any additional functionality from Mike's
> implementation after consulting him, also about about sage style and
> conventions etc.
>
> Is this a roadmap of resolving the problem?

1. Make sure your code has functionality that is >= Mike's power series code.
2. Make sure your code has 100% doctest coverage.
3. Post a Sage (Mercurial patch) to trac that adds your code, removes
Mike's code, but doesn't break anything else in Sage.
4. Get your code refereed.

> Or is there a special need to start with Mike's implementation as base?

There is no a priori special need to do that. We just don't want to
confuse users/developers with duplicated functionality.

>
> Henryk

Henryk Trappmann

unread,
Mar 26, 2009, 11:44:40 AM3/26/09
to sage-devel
On Mar 26, 3:52 pm, William Stein <wst...@gmail.com> wrote:
> 2. Make sure your code has 100% doctest coverage.

I have two questions here.
1. I work intensely with functions defined inside of methods (because
one attribute of the power series is a function. It needs to be
defined whenever a method returns a power series).
All those inner functions are listed in "missing doctests".
To add a short documentation string was no deal, but provide doctests
for all those inner functions?

2. I got a method _test which contains a whole test suite for the
class as doctest (and nothing else). These tests maybe not appropriate
to put into other doctests. However sage -coverage declares it as:
"Possibly wrong (function name doesn't occur in doctests)". Does that
count as minus?

Henryk

William Stein

unread,
Mar 26, 2009, 11:56:08 AM3/26/09
to sage-...@googlegroups.com
On Thu, Mar 26, 2009 at 8:44 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> On Mar 26, 3:52 pm, William Stein <wst...@gmail.com> wrote:
>> 2. Make sure your code has 100% doctest coverage.
>
> I have two questions here.
> 1. I work intensely with functions defined inside of methods (because
> one attribute of the power series is a function. It needs to be
> defined whenever a method returns a power series).

Does pickling actually work on power series with such attributes that
are functions?

> All those inner functions are listed in "missing doctests".
> To add a short documentation string was no deal, but provide doctests
> for all those inner functions?

Create a doctest that ends up indirectly calling the inner function,
then label it

sage: the doctest # indirect doctest

>
> 2. I got a method _test which contains a whole test suite for the
> class as doctest (and nothing else). These tests maybe not appropriate
> to put into other doctests. However sage -coverage declares it as:
> "Possibly wrong (function name doesn't occur in doctests)". Does that
> count as minus?

No, that doesn't count as a minus.

William

Nicolas M. Thiery

unread,
Mar 26, 2009, 11:25:00 PM3/26/09
to sage-...@googlegroups.com
On Thu, Mar 26, 2009 at 05:58:17AM -0700, Henryk Trappmann wrote:
>
> On Mar 26, 5:07 am, mabshoff <mabsh...@googlemail.com> wrote:
> > Well, I will not merge a second implementation as long as there is no
> > clear roadmap for resolving the problem.
>
> The basic functionality of Mike's powerseries class is also contained
> in my class.
> That is add, multiply, power, composition, shift, differentiate and
> integrate.
> I also changed my implementation that now a recursive define is
> possible according to Ralf Hemmecke's suggestion in this thread.

Great! I guess that the species code should make for a good test suite
for this feature.

> I can incorporate any additional functionality from Mike's
> implementation after consulting him, also about about sage style and
> conventions etc.
>
> Is this a roadmap of resolving the problem? Or is there a special need
> to start with Mike's implementation as base?

Following the same syntax is a definite plus unless there is a very
good reason for deviating. As for the implementation, just see this
with Mike (there might be tricks, typically around pickling) that you
might want to recycle.

Cheers,
Nicolas
--
Nicolas M. Thiéry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/

Henryk Trappmann

unread,
Mar 28, 2009, 3:17:30 AM3/28/09
to sage-devel
I reached 90% coverage and have some more questions:

1. What is pickling? Currently I get the following message if I try
dumps:
PicklingError: Can't pickle <class '__main__.FormalPowerSeries'>:
attribute lookup __main__.FormalPowerSeries failed

2. I currently work in my own repository, when is it time to switch to
the sage repository (and how is this be done). So that if people are
interested in the current state they just need to take a look at the
sage repository, and can give early feedback.

Regards,
Henryk

On Mar 27, 4:25 am, "Nicolas M. Thiery" <Nicolas.Thi...@u-psud.fr>
wrote:
> Nicolas M. Thiéry "Isil" <nthi...@users.sf.net>http://Nicolas.Thiery.name/

William Stein

unread,
Mar 28, 2009, 12:11:04 PM3/28/09
to sage-...@googlegroups.com
On Sat, Mar 28, 2009 at 12:17 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> I reached 90% coverage and have some more questions:
>
> 1. What is pickling?

http://docs.python.org/library/pickle.html

> Currently I get the following message if I try
> dumps:
> PicklingError: Can't pickle <class '__main__.FormalPowerSeries'>:
> attribute lookup __main__.FormalPowerSeries failed

I don't know without looking further at your code.

> 2. I currently work in my own repository, when is it time to switch to
> the sage repository (and how is this be done). So that if people are
> interested in the current state they just need to take a look at the
> sage repository, and can give early feedback.

There is no "sage repository". When you want to make your code
available, you post
an hg (mercurial) patch or bundle.

Henryk Trappmann

unread,
Mar 30, 2009, 9:36:17 AM3/30/09
to sage-devel
Ok, here is a first shot that has 100% coverage (except dumps):
http://github.com/bo198214/hyperops/raw/09e1da3372d7b431cdf557ffe164df9f91c08e68/formal_powerseries.py

I finally decided to name it FPSRing, for Formal Power Series Ring. It
resides in sage.rings.formal_powerseries

I hope Nicolas M. Thiery can throw a look onto it, and give me some
suggestions (public or private), while trying out what he wanted to do
with it, being my reviewer.

For me there are several open questions yet:
1. I dont know anything about coercing
2. I have no idea how to approach pickling, how to get dumps to work.
I think that the attribute functions are the problem like William
said.
3. I dont know what "sum_generator" and "product_generator" in Mike's
implementation do.
4. I dont know about formatting docstrings.
5. If I define _pow_ it cant be used with non-integer exponents, this
comes somehow from RingElement. So I instead defined __pow__. I dont
know exactly about the benefits or drawbacks of defining _operator_
instead of __operator__. I also dont know for which operators such
distinction exists, e.g. is there also a _lshift_ and _rshift_ and so
on?

Henryk

Nicolas M. Thiery

unread,
Mar 30, 2009, 10:46:16 PM3/30/09
to sage-...@googlegroups.com
Dear Henryk, dear Mike,

On Mon, Mar 30, 2009 at 06:36:17AM -0700, Henryk Trappmann wrote:
>
> Ok, here is a first shot that has 100% coverage (except dumps):
> http://github.com/bo198214/hyperops/raw/09e1da3372d7b431cdf557ffe164df9f91c08e68/formal_powerseries.py
>
> I finally decided to name it FPSRing, for Formal Power Series Ring. It
> resides in sage.rings.formal_powerseries
>
> I hope Nicolas M. Thiery can throw a look onto it, and give me some
> suggestions (public or private), while trying out what he wanted to do
> with it, being my reviewer.

Thanks for your work! I'll try to do this. But I'll be pretty busy in
the coming days ... Feel free to ping me a reminder.

Mike: I would not mind a second view on this, as you know much better
than me how the current LazyPowerSeries code work.

> For me there are several open questions yet:
> 1. I dont know anything about coercing
> 2. I have no idea how to approach pickling, how to get dumps to work.
> I think that the attribute functions are the problem like William
> said.
> 3. I dont know what "sum_generator" and "product_generator" in Mike's
> implementation do.
> 4. I dont know about formatting docstrings.
> 5. If I define _pow_ it cant be used with non-integer exponents, this
> comes somehow from RingElement. So I instead defined __pow__. I dont
> know exactly about the benefits or drawbacks of defining _operator_
> instead of __operator__. I also dont know for which operators such
> distinction exists, e.g. is there also a _lshift_ and _rshift_ and so
> on?

I let the experts answer here.

Nicolas
--
Nicolas M. Thiéry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/

Robert Bradshaw

unread,
Mar 31, 2009, 3:55:23 AM3/31/09
to sage-...@googlegroups.com
On Mar 30, 2009, at 6:36 AM, Henryk Trappmann wrote:

>
> Ok, here is a first shot that has 100% coverage (except dumps):
> http://github.com/bo198214/hyperops/raw/
> 09e1da3372d7b431cdf557ffe164df9f91c08e68/formal_powerseries.py
>
> I finally decided to name it FPSRing, for Formal Power Series Ring. It
> resides in sage.rings.formal_powerseries

I'd rather it were named the more verbose, but significantly more
explicit, FormalPowerSeriesRing. This fits better with the naming of
all the other rings, and we do have tab completion after all. (As an
aside, when I see FPS, I think of "frames per second" and I'm not
even a gammer.)

> I hope Nicolas M. Thiery can throw a look onto it, and give me some
> suggestions (public or private), while trying out what he wanted to do
> with it, being my reviewer.
>
> For me there are several open questions yet:
> 1. I dont know anything about coercing

Please see http://wiki.sagemath.org/coercion . If you this is
insufficiently clear please ask.

> 2. I have no idea how to approach pickling, how to get dumps to work.
> I think that the attribute functions are the problem like William
> said.

The basic idea is to implement a __reduce__ method, which returns a
tuple

callable, (args,to,pass,to,callable)

and then on unpickling (loads) it will return callable
(args,to,pass,to,callable) as the re-constructed object.

> 3. I dont know what "sum_generator" and "product_generator" in Mike's
> implementation do.
> 4. I dont know about formatting docstrings.

I would just open up integer.pyx, or some other file, for lots of
examples here.

> 5. If I define _pow_ it cant be used with non-integer exponents, this
> comes somehow from RingElement. So I instead defined __pow__. I dont
> know exactly about the benefits or drawbacks of defining _operator_
> instead of __operator__. I also dont know for which operators such
> distinction exists, e.g. is there also a _lshift_ and _rshift_ and so
> on?

For powering, it is simplest to override __pow__. As for the others,
see the link above, but the basic idea is that when _add_, _sub_,
_mul_, and _div_ are called, both inputs are guaranteed to have the
same parent (i.e. they both will be formal power series over the same
basering) so you don't, for example, have to worry about manually
handling if someone is trying to add an integer, or rational, etc. to
your power series. The default (Element) x.__add__(y) will coerce x
and y into the same parent if necissary, and then call x._add_(y).
There is also _rmul_ and _lmul_ which are used to implement
multiplication by a scalar.

- Robert

Ralf Hemmecke

unread,
Mar 31, 2009, 3:59:01 AM3/31/09
to sage-...@googlegroups.com
> 3. I dont know what "sum_generator" and "product_generator" in Mike's
> implementation do.

Maybe you should look at the original...

http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatsu29.html#x44-770009.2.10

and corresponding tests

http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse28.html#noweb.NW4QlDdu-30bOfK-T

Ralf

Franco Saliola

unread,
Mar 31, 2009, 4:41:48 AM3/31/09
to sage-...@googlegroups.com
On Sat, Mar 28, 2009 at 9:17 AM, Henryk Trappmann
<bo19...@googlemail.com> wrote:
>
> I reached 90% coverage and have some more questions:
>
> 1. What is pickling? Currently I get the following message if I try
> dumps:
> PicklingError: Can't pickle <class '__main__.FormalPowerSeries'>:
> attribute lookup __main__.FormalPowerSeries failed

I would guess that you are probably just loading/attaching some local
files to a Sage session. If that's correct, then that is the cause of
this problem. When you merge your code into Sage, then the error
should go away (although it may be replaced by some other error).

Take care,
Franco

--

Franco Saliola

unread,
Mar 31, 2009, 4:49:11 AM3/31/09
to sage-...@googlegroups.com
On Tue, Mar 31, 2009 at 9:55 AM, Robert Bradshaw
<robe...@math.washington.edu> wrote:
>
> On Mar 30, 2009, at 6:36 AM, Henryk Trappmann wrote:
>
>>
>> Ok, here is a first shot that has 100% coverage (except dumps):
>> http://github.com/bo198214/hyperops/raw/
>> 09e1da3372d7b431cdf557ffe164df9f91c08e68/formal_powerseries.py
>>
>> I finally decided to name it FPSRing, for Formal Power Series Ring. It
>> resides in sage.rings.formal_powerseries
>
> I'd rather it were named the more verbose, but significantly more
> explicit, FormalPowerSeriesRing. This fits better with the naming of
> all the other rings, and we do have tab completion after all.

I prefer FormalPowerSeriesRing, as well.

>> 2. I have no idea how to approach pickling, how to get dumps to work.
>> I think that the attribute functions are the problem like William
>> said.
>
> The basic idea is to implement a __reduce__ method, which returns a
> tuple
>
>     callable, (args,to,pass,to,callable)
>
> and then on unpickling (loads) it will return callable
> (args,to,pass,to,callable) as the re-constructed object.

If my guess about you loading/attaching local files was correct, then
the first thing you should do is put your code into the Sage library
and try the picking test again. The default picking/unpicking
mechanism might just work.

Franco

--

Henryk Trappmann

unread,
Mar 31, 2009, 4:54:18 AM3/31/09
to sage-devel
On Mar 31, 9:55 am, Robert Bradshaw <rober...@math.washington.edu>
wrote:
> There is also _rmul_ and _lmul_ which are used to implement  
> multiplication by a scalar.

Thats great, I was wandering how to recognize scalar multplication.

Thank you Robert.

Henryk Trappmann

unread,
Mar 31, 2009, 5:18:07 AM3/31/09
to sage-devel
On Mar 31, 10:41 am, Franco Saliola <sali...@gmail.com> wrote:
> On Sat, Mar 28, 2009 at 9:17 AM, Henryk Trappmann
> I would guess that you are probably just loading/attaching some local
> files to a Sage session. If that's correct, then that is the cause of
> this problem. When you merge your code into Sage, then the error
> should go away (although it may be replaced by some other error).

Yes you are right. Now the "correct" error about pickling attribute
functions pops up:
PicklingError: Can't pickle <type 'function'>: attribute lookup
__builtin__.function failed

I will see what I can do with the __reduce__ method, that Robert
mentioned.

But btw. I have another question about the private Sage development
process. I work the following way:
1. I edit the code in the editor
2. "load" that file into a sage session,
3. do there some commands and repeat from 1. until everything is fine.

But as you indicated you dont work by "load"ing the file.
When I however work with "import" at the sage prompt, then the changes
that I did in the file are not reflected properly.
Can you or others give me some hints about an efficient private
development cycle?

Henryk Trappmann

unread,
Mar 31, 2009, 5:27:02 AM3/31/09
to sage-devel
On Mar 31, 10:49 am, Franco Saliola <sali...@gmail.com> wrote:
> > I'd rather it were named the more verbose, but significantly more
> > explicit, FormalPowerSeriesRing. This fits better with the naming of
> > all the other rings, and we do have tab completion after all.
>
> I prefer FormalPowerSeriesRing, as well.

I have no real problem with naming it that way, actually I called it
that way in my previous version. I have however negative rememberance
when developing Java: that a whole line was filled with just two type
names. So if there are no other votes for names, I rollback the name
to "FormalPowerSeriesRing".

David Roe

unread,
Mar 31, 2009, 6:34:33 AM3/31/09
to sage-...@googlegroups.com
If you're editing files in the sage library, you need to type
sage -br
from the command line in order for your changes to be incorporated into the copy of sage that you're running (the -b builds, the -r means to start sage).

Having written a lazy p-adics class, my guess is that your pickling errors have to do with the fact that you're storing a function.  If you replace all of the local functions that you're storing with callable classes (ie a class that implements the __call__ method), you should be able to get pickling to work.
David

Henryk Trappmann

unread,
Mar 31, 2009, 7:21:28 AM3/31/09
to sage-devel
On Mar 31, 12:34 pm, David Roe <r...@math.harvard.edu> wrote:
> Having written a lazy p-adics class, my guess is that your pickling errors
> have to do with the fact that you're storing a function.  If you replace all
> of the local functions that you're storing with callable classes (ie a class
> that implements the __call__ method), you should be able to get pickling to
> work.

And this is no performance issue?

David Roe

unread,
Mar 31, 2009, 10:19:08 AM3/31/09
to sage-...@googlegroups.com
I don't think it should affect performance much.  The difference between calling a Python function and calling a Python class with a custom __call__ method shouldn't be very large.  But you can time it and see.
David

William Stein

unread,
Mar 31, 2009, 10:35:51 AM3/31/09
to sage-...@googlegroups.com
(1) You can't pickle objects with attributes that are functions. If
your code currently only works with attributes that are functions, it
will need to be rewritten. Note that callable objects are fine as
attributes (e.g., objects with a __call__ method defined).

(2) In many cases pickling is supposed to just work automatically
without having to define __reduce__. With the new coercion model
there was a 1-line bug that I found which meant pickling would never
"just work". The bug is fixed in the large patch again 3.4.1.alpha
at #5520. The fix is:
wstein@mod:~/sage/devel/sage/sage/structure$ hg diff parent_gens.pyx

diff -r e8e97f260027 sage/structure/parent_gens.pyx
--- a/sage/structure/parent_gens.pyx Thu Mar 26 12:34:13 2009 -0700
+++ b/sage/structure/parent_gens.pyx Fri Mar 27 10:08:23 2009 -0700
@@ -350,7 +350,7 @@
return d

def __setstate__(self, d):
- if self._element_constructor is not None:
+ if d.has_key('_element_constructor'):
return parent.Parent.__setstate__(self, d)
try:
self.__dict__ = d

>
>> 3. I dont know what "sum_generator" and "product_generator" in Mike's
>> implementation do.
>> 4. I dont know about formatting docstrings.
>
> I would just open up integer.pyx, or some other file, for lots of
> examples here.

+1 Also there is a very good wiki page at wiki.sagemath.org I think
on the new format.

>
>> 5. If I define _pow_ it cant be used with non-integer exponents, this
>> comes somehow from RingElement. So I instead defined __pow__. I dont
>> know exactly about the benefits or drawbacks of defining _operator_
>> instead of __operator__. I also dont know for which operators such
>> distinction exists, e.g. is there also a _lshift_ and _rshift_ and so
>> on?
>
> For powering, it is simplest to override __pow__. As for the others,
> see the link above, but the basic idea is that when _add_, _sub_,
> _mul_, and _div_ are called, both inputs are guaranteed to have the
> same parent (i.e. they both will be formal power series over the same
> basering) so you don't, for example, have to worry about manually
> handling if someone is trying to add an integer, or rational, etc. to
> your power series. The default (Element) x.__add__(y) will coerce x
> and y into the same parent if necissary, and then call x._add_(y).
> There is also _rmul_ and _lmul_ which are used to implement
> multiplication by a scalar.
>
> - Robert
>
> >
>



Henryk Trappmann

unread,
Mar 31, 2009, 10:45:13 AM3/31/09
to sage-devel
On Mar 31, 4:35 pm, William Stein <wst...@gmail.com> wrote:
> (1) You can't pickle objects with attributes that are functions.  If
> your code currently only works with attributes that are functions, it
> will need to be rewritten.  Note that callable objects are fine as
> attributes (e.g., objects with a __call__ method defined).

If that is the case, its not a big deal make it callable objects.

Thanks for the hints.

Henryk Trappmann

unread,
Mar 31, 2009, 4:26:16 PM3/31/09
to sage-devel
On Mar 31, 4:35 pm, William Stein <wst...@gmail.com> wrote:
> Note that callable objects are fine as
> attributes (e.g., objects with a __call__ method defined).

Actually I dont see how to get it to work:
I want to give a function as initialization parameter to
FormalPowerSeries.
This function needs to be stored somewhere.
If I store it inside a callable object then the callable object can
not be pickled.
I think the ability to give a function as parameter to
FormalPowerSeries is a must.
I dont want the user to declare a class that contains the function as
__call__ method and then give an instance of this class as parameter
to FormalPowerSeries (pickling would work in this case.)

Can we circumvent this?

William Stein

unread,
Mar 31, 2009, 8:57:27 PM3/31/09
to sage-...@googlegroups.com

If the user gives a Python function, then the object they made cannot
be pickled.
If they give a Python object with a __call__ method, then the power
series *can* be pickled.
Just make sure that it can be when they give an appropriate input, and
give docstrings and documentation
to explain this subtle issue.

It's not a rule that every possible thing in Sage can be pickled --
e.g., open file handles can't be pickled.
However, I just want to make sure that if I want to make pickleable
power series and I jump through the hoop
of making the coefficient function a callable object that can be
pickled, then everything else works. OK?

William

Henryk Trappmann

unread,
Apr 6, 2009, 7:49:37 AM4/6/09
to sage-devel
Now a new version is out, picklable, coerceable and 100% coverage,
though not comletely complete yet.
But getting it to pickle was really *some* effort, 60 inner functions
had to converted to "outer" classes, but now it works.

However some strange effects occured with coercing:
sage: RR.coerce_map_from(QQ) != None
True
sage: RR.coerce_map_from(int) != None
True
sage: RR.coerce_map_from(Integer) != None
False

Why is this? Same with QQ:
sage: QQ.coerce_map_from(Integer) != None
False

Then in my formal powerseries module, I defined the _coerce_map_from_
(self,T) in FormalPowerSeriesRing and
sage: FormalPowerSeriesRing(RR)._coerce_map_from_(RR)
True

but despite _lmul_ and _rmul_ do not work with RR (though
_coerce_map_from_ is definitely called and returns True).
They work however with QQ as expected. Any hints?
Here the error:

sage: FormalPowerSeriesRing(RR)([1,2,3]) * (2/3)
[0.666666666666667, 1.33333333333333, 2.00000000000000, 0, 0, 0, 0, 0,
0, ...]
sage: FormalPowerSeriesRing(RR)([1,2,3]) * 2.0
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)

/home/bo198214/.sage/temp/darkdepth/6006/
_home_bo198214__sage_init_sage_0.py in <module>()

/usr/src/sage-3.4-linux-Debian_GNU_Linux_5.0_lenny-x86_64-Linux/local/
lib/python2.5/site-packages/sage/structure/element.so in
sage.structure.element.RingElement.__mul__ (sage/structure/element.c:
8632)()

/usr/src/sage-3.4-linux-Debian_GNU_Linux_5.0_lenny-x86_64-Linux/local/
lib/python2.5/site-packages/sage/structure/coerce.so in
sage.structure.coerce.CoercionModel_cache_maps.bin_op (sage/structure/
coerce.c:5848)()

TypeError: unsupported operand parent(s) for '*':
'FormalPowerSeriesRing over Real Field with 53 bits of precision' and
'Real Field with 53 bits of precision'

Henryk Trappmann

unread,
Apr 6, 2009, 7:53:03 AM4/6/09
to sage-devel
Reply all
Reply to author
Forward
0 new messages