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
> 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
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
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
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
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
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
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
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
> 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
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
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
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
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
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
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
Where, of course, "real" does not mean "RealField", I presume :).
"real" means QQ, ZZ, etc.
Jason
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/
For starters, it couldn't hurt to post a link to your code so people
know what it is.
William
(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
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
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,
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/
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/
>
> 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
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
Ralf
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
--
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
--
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