On Sat, Nov 23, 2013 at 10:53 AM, Aaron Meurer <[email protected]> wrote: >> On Nov 22, 2013, at 11:03 AM, "Ondřej Čertík" <[email protected]> >> wrote: >> >> Hi, >> >> Currently the series are represented as a regular symbolic expression, >> with the Order() instance added to it. >> >> I think we should rather represent series as a Series class, roughly >> equivalent to SeriesData in Mathematica: >> >> http://reference.wolfram.com/mathematica/ref/SeriesData.html >> >> The Series class would interact with SymPy similar to how Poly works in >> SymPy. >> The Series would represent a series expansion in one variable (I don't >> have opinions about multiple variables yet), so it would remember the >> terms in some suitable format (see below, just like for Polys, there >> are more options on the internal representation) and the order of the >> series. Then, when you print it, it will print it just like we >> currently do, with the "O(x^2)" term, though that's just how it is >> printed. > > And also remember the original expression!
If it is available (i.e. when you sum or multiply two Series, there is no original expression). > >> >> The Series would have methods like differentiate, invert, etc. >> >> If you look at how GiNaC does it: >> >> https://github.com/certik/ginac/blob/master/ginac/pseries.h >> https://github.com/certik/ginac/blob/master/ginac/pseries.cpp >> >> They have a class pseries for it. Their representation is a list of >> (coefficient, power) pairs (plus series variable and expansion point): >> >> https://github.com/certik/ginac/blob/master/ginac/pseries.h#L112 >> >> In Mathematica, they only have a list of coefficients for all powers >> from nmin/den to nmax/den (so some coefficients could be zero), plus >> series variable and expansion point. In Ginac, when they convert the >> series to an expression: >> >> https://github.com/certik/ginac/blob/master/ginac/pseries.cpp#L593 >> >> they simply attach the Order instance. >> >> Conclusion: Mathematica is using dense representation of series, while >> GiNaC is using a sparse representation (instead of a list, one can >> also use a dictionary). I currently don't know which one is better, >> maybe we should have several implementations, just like Polys. > > I don't see the point of sparse, since most series are dense. But see > what I wrote below. While most series are probably dense, e.g. even this one is dense: In [1]: (sin(x)**10).series(x, 0, 20) x**10 - 5*x**12/3 + 4*x**14/3 - 43*x**16/63 + 713*x**18/2835 + O(x**20) You can easily construct series that are sparse: In [2]: (sin(x**15)).series(x, 0, 100) x**15 - x**45/6 + x**75/120 + O(x**100) So I can definitely see that sparse representation will be faster for some examples. Ondrej > >> >> >> >> Open ideas: >> >> * I don't like that Order requires special handling in Add: >> >> https://github.com/sympy/sympy/blob/master/sympy/core/add.py#L237 >> >> So maybe we can just append Order to an expression in Add, but the >> simplification will be done by the Series class, i.e. no special >> handling in Add. So there will be a method Series.to_expr(), that >> would return an Add instance, with Order term appended. Unfortunately >> if you want to do some stuff like O(x)+O(x^2), then it wouldn't work >> if O(x) is just an Order. However, one idea could be that if we >> completely remove Order, and only have Series, then O(x) would simply >> be an instance of Series. And then just like Polys work, O(x)+O(x^2) >> would by dispatched to Series, that knows how to simplify it. >> So Add internally doesn't have to handle simplification of this, only >> "holding" the terms. >> >> * I am thinking how to implement this in CSymPy as well. Thinking >> about it helps with the design, because in CSymPy, it needs to be as >> fast as possible. So handling of Order in Add is a nono. In general, >> the best way is to always have a special algorithm+efficient >> representation for the given thing. So Add should only handle the >> usual x+x or x*x thing. Series handling should be done by a special >> class Series, that knows everything about series expansion and can use >> efficient representation (both the dense and sparse representation >> above is more efficient than just the general expression with Order >> term appended, for things like O(x)+O(x^2) or multiplication or >> inversion of series). At the same time, what's best for CSymPy might >> not necessarily be the best for SymPy. But so far it seems to me that >> we always want to have the best algorithm+datastructures in SymPy, so >> that it's fast, algorithmically. C++ then only provides a constant >> speedup, as it doesn't have the overhead of Python. >> >> * See also this: >> >> https://github.com/sympy/sympy/wiki/UD-Under-Development#series > > Also take a look at Mario's work (I think it may be buried in some > pull request). His implementation will probably be the fastest. > > Aaron Meurer > > >> >> Ondrej >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sympy" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://groups.google.com/group/sympy. >> For more options, visit https://groups.google.com/groups/opt_out. > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/sympy. > For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy. For more options, visit https://groups.google.com/groups/opt_out.
