Comment #12 on issue 2753 by [email protected]:
series(1/cos(x/log(x)),x,0,5) does not work
http://code.google.com/p/sympy/issues/detail?id=2753
Ok, let me try to give an answer.
First of all, what is logx about? I have tried to document this in the
comments. See the beginning of power._eval_nseries and the top comment of
functions/elementary/exponential.py. Executive summary: the _eval_nseries
function has a dual purpose in sympy: for cooking up enduser series
expansions vial the series() function, and for computing limits using the
gruntz() algorithm. End users ask for certain shiny features in series()
every now and then, and people are tempted to "fix" _eval_nseries. This
almost always goes wrong, because the gruntz algorithm has very stringent
requirements on said function. So most of the time when you make things
look "good" or something then you break one of the gruntz test cases
(hopefully...).
One of the particular properties of the gruntz algorithm is that it
recursively examines parts of your expression depending on their order of
growth. One consequence of this is that when gruntz does series expansions,
the functions never contain logs of the independent variable - these have
either been taken out as "too slowly growing" or have been simplified away
by raising the independent variable to exponentials [*]. The series
expansion code has to preserve this property - and so substitutes a dummy
for logx, thereby ignoring things which "grow too slowly" [**].
The upshot is that the _eval_nseries functions are designed to work with
gruntz, and gruntz calls them with certain special properties enforced. The
_eval_nseries functions have to work in very particular ways under these
conditions.
Now we come to the series() function. Ideally, what this does is to imitate
the gruntz algorithm in calling _eval_nseries, and then brushing up the
result in such a way as to be "nice". In practice, we more or less just
take some guesses and call _eval_nseries and hope for the best. This is why
series() sometimes seems to behave/break in strange ways.
Anyhow, loads of woffling. It seems to me that you are right: series()
should pass a dummy logx parameter to _eval_nseries, and substitute back in
the end. Unfortunately, as long as _eval_nseries tacks on the order terms,
this way we lose logarithmic order factors, as you observed.
This is really related to the fact that there is no clear definition of
what series() should do; as I have said before we re-use the _eval_nseries
which behaves in very peculiar ways, and these may not always be what we
want series() to do. I'm afraid I don't know a good way to overcome this
issue, other than "(re-)design series() from scratch, make it first class,
and give it a separate implementation". For now, it seems best to me to fix
the one failing test (by removing the logx factor from the order) and
explain in the series() docstring that this behaviour is expected.
But please mind that I have not been active in the sympy community for
quite a while, others may have different opinions.
[*] I'm pretty sure this is not quite true; I don't remember all the
details. The main point here is that this algorithm works delicately to
avoid infinite recursion.
[**] Again, there is more going on here, most of which I have forgotten. I
think you never get exp(logx) terms because of the special way to algorithm
is set up, but I would have to check.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
--
You received this message because you are subscribed to the Google Groups
"sympy-issues" 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-issues.
For more options, visit https://groups.google.com/groups/opt_out.