power series classes

16 views
Skip to first unread message

Alex Ghitza

unread,
Jul 12, 2009, 10:14:43 AM7/12/09
to sage-...@googlegroups.com
Hi,

There is the basic PowerSeries class defined in
rings/power_series_ring_element.pyx, and then there's the derived
class PowerSeries_poly, defined in rings/power_series_poly.pyx.
However, I have not been able to come up with a single instance of
PowerSeries that is *not* an instance of PowerSeries_poly.

Should I be able to? What is the difference between the two classes,
from both the user and developer points of view?

Best,
Alex


--
Alex Ghitza -- Lecturer in Mathematics -- The University of Melbourne
-- Australia -- http://www.ms.unimelb.edu.au/~aghitza/

David Roe

unread,
Jul 12, 2009, 6:14:28 PM7/12/09
to sage-...@googlegroups.com
Currently there are no classes in sage inheriting form PowerSeries other than PowerSeries_poly.  But one could write a lazy power series class that used the same basic interface as PowerSeries, using lists or python functions, and define "class PowerSeries_lazy(PowerSeries)".  I think that's the distinction.
David

Alex Ghitza

unread,
Jul 12, 2009, 8:04:54 PM7/12/09
to sage-...@googlegroups.com
On Mon, Jul 13, 2009 at 8:14 AM, David Roe<ro...@math.harvard.edu> wrote:
> Currently there are no classes in sage inheriting form PowerSeries other
> than PowerSeries_poly.  But one could write a lazy power series class that
> used the same basic interface as PowerSeries, using lists or python
> functions, and define "class PowerSeries_lazy(PowerSeries)".  I think that's
> the distinction.

Aha, that makes sense. So here's my problem: I'm working on trac 111,
i.e. change all the .copy() methods to __copy__(). Having done this
in power_series_poly.pyx, I am now getting a doctest failure in
power_series_ring_element.pyx, namely

sage: copy(f) is f # !!! ok since power series are immutable.
Expected:
True
Got:
False


This is because PowerSeries already has a __copy__() method which just
returns self, while the __copy__() method of PowerSeries_poly actually
returns a copy. The doctest is failing because f is a
PowerSeries_poly and hence the derived method is used.

So I'm not sure what to do. I cannot change the doctest because I
can't construct a PowerSeries which is not a PowerSeries_poly. My
thought now is to make PowerSeries.__copy__() return
NotImplementedError and have all derived classes override it.

Is this reasonable? Is there a better solution I don't see now?

David Roe

unread,
Jul 12, 2009, 8:20:08 PM7/12/09
to sage-...@googlegroups.com
Sounds reasonable to me.
David

William Stein

unread,
Jul 12, 2009, 8:23:01 PM7/12/09
to sage-devel
2009/7/12 Alex Ghitza <agh...@gmail.com>:

There are a few questions here.

1. If all instances of a class C are immutable, is reasonable for
__copy__ to just return self?

2. Are all instances of PowerSeries going to be immutable? Or, are we
someday going to have a class PowerSeries_mutable?


Regarding 1, fortunately Python itself provides some help with this question.

sage: import copy
sage: a = int(903840823)
sage: copy.copy(a) is a
True
sage: a = float(2.39494)
sage: copy.copy(a) is a
True
sage: a = 'hi there'
sage: copy.copy(a) is a
True

I.e., the answer to question 1 is a resounding "yes!".

Regarding question 2, note that power series are already secretly mutable:

sage: R.<x> = QQ[]
sage: f = x^3 + 3*x - 1
sage: f._unsafe_mutate(1, 10)
sage: f
x^3 + 10*x - 1
sage: R.<x> = QQ[[]]
sage: f = x^3 + 3*x - 1 + O(x^5)
sage: f._unsafe_mutate(1, 10); f
-1 + 10*x + x^3 + O(x^5)

The function _unsafe_mutate is there because long ago polynomials and
power series were trivially mutable, i.e., this used to work:

sage: f[1] = 1100

and David Harvey implemented some nice code that used this. Then in
late 2006 we went through and made many basic objects immutable in
Sage, since mutable objects should *never* be hashable, or many basic
Python algorithms break. All parents were made immutable, as were a
wide range of elements (with the notable exception of matrices and
vectors, which can now be both immutable or mutable).

Anyway, when changing things to immutable, I didn't want to break
David's fine code, so _unsafe_mutate -- whose unsafeness should be
clear -- was introduced.

The upshot of all this is that one almost always really wants
polynomials and power series to be immutable, in which case __copy__
returning self is perfectly fine. Sometimes mutating
polynomials/powerseries is very useful for certain algorithms though.

So I would say the answer to 2 is a not resounding "yes" for now, with
the caveat that one can simply do a little code refactoring later of
mutable polynomials and power series are introduced. Given that I've
not seen a single remark on any Sage list about
mutability/immutability of power series and polynomials during the
last 3 years, I doubt that the lack of mutability being fully
supported (like it is for matrices) is a serious problem.

-- William

Alex Ghitza

unread,
Jul 12, 2009, 9:09:59 PM7/12/09
to sage-...@googlegroups.com
Thanks for the detailed explanation!

If I understood correctly, you suggest that I remove __copy__() from
the derived class PowerSeries_poly, and leave in place the __copy__ of
PowerSeries that just returns self. This would do the correct thing
for the currently unique derived class, and if someone eventually
implements PowerSeries_mutable, they can override __copy__ with the
appropriate thing.


Alex

--

William Stein

unread,
Jul 12, 2009, 9:18:04 PM7/12/09
to sage-devel
2009/7/12 Alex Ghitza <agh...@gmail.com>:

>
> Thanks for the detailed explanation!
>
> If I understood correctly, you suggest that I remove __copy__() from
> the derived class PowerSeries_poly, and leave in place the __copy__ of
> PowerSeries that just returns self.  This would do the correct thing
> for the currently unique derived class, and if someone eventually
> implements PowerSeries_mutable, they can override __copy__ with the
> appropriate thing.

Yep, that's what I said in a very long-winded way.

-- William

Reply all
Reply to author
Forward
0 new messages