DESCRIPTION:
The zeroth order Taylor expansion of a scientifically interesting
expression is incorrectly evaluated if only the zeroth order is
requested. The correct value requires evaluating to the first order
and then ignoring the first order.
SYSTEM:
Debian GNU/Linux 11.2 (bullseye) ii maxima 5.44.0-3 amd64 Computer algebra system -- base system Maxima version: "5.44.0" Maxima build date: "2021-04-24 14:52:58" Host type: "x86_64-pc-linux-gnu" Lisp implementation type: "GNU Common Lisp (GCL)" Lisp implementation version: "GCL 2.6.12" User dir: "~/.maxima" Temp dir: "/tmp" Object dir: "~/.maxima/binary/5_44_0/gcl/GCL_2_6_12" Frontend: false
The bug also occurs for
Maxima version: "5.38.1" Lisp implementation version: "GCL 2.6.12"
REPRODUCE the bug:
/* The expression Q, depending on rr, x and y, yields a bug in 'taylor'. */ Q: (%pi^(2/3)*((-(sin(rr)*sqrt((-y^2)-x^2+1) *(1-acos(sin(rr)*sqrt((-y^2)-x^2+1))/%pi)) /sqrt(1-sin(rr)^2*((-y^2)-x^2+1))) +(sin(rr)*sqrt((-y^2)-x^2+1)*(1-(%pi-acos(sin(rr)*sqrt((-y^2)-x^2+1)))/%pi)) /sqrt(1-sin(rr)^2*((-y^2)-x^2+1)) -(sin(rr)*y*(1-acos(sin(rr)*y)/%pi))/sqrt(1-sin(rr)^2*y^2) +(sin(rr)*y*(1-(%pi-acos(sin(rr)*y))/%pi))/sqrt(1-sin(rr)^2*y^2) -(sin(rr)*x*(1-acos(sin(rr)*x)/%pi))/sqrt(1-sin(rr)^2*x^2) +(sin(rr)*x*(1-(%pi-acos(sin(rr)*x))/%pi))/sqrt(1-sin(rr)^2*x^2) -(cos(rr)*(1-acos(cos(rr))/%pi))/sqrt(1-cos(rr)^2) +(cos(rr)*(1-(%pi-acos(cos(rr)))/%pi))/sqrt(1-cos(rr)^2)+1/rr+4/%pi))/4^(1/3); /* The 0th order coefficient of the Taylor expansion around rr set to 0 should be independent of whether the expansion is made to 0th or first order. */ /* This should give 0, but instead gives (4 *%pi)^(-1/3). */ coeff(taylor(Q,rr,0,1),rr,0) - coeff(taylor(Q,rr,0,0),rr,0); /* This should give 1, but instead gives 6/5. */ coeff(taylor(Q,rr,0,1),rr,0) / coeff(taylor(Q,rr,0,0),rr,0); /* Is the greater expansion correct? Check with a few arbitrary values. This shows that coeff(taylor(Q,rr,0,1),rr,0) is very likely to be correct and coeff(taylor(Qtest,rr,0,0),rr,0) wrong. */ coeff(taylor(Q,rr,0,1),rr,0), bfloat; coeff(taylor(Q,rr,0,0),rr,0), bfloat; Qtest: Q, rr: 1e-3, x:0, y:0; taylor(Qtest,rr,0,5), bfloat;
DISCUSSION:
For the case of interest, rr
is positive, but including assume(rr > 0)
at the beginning doesn't solve the bug. Restricting to assume(rr < %pi/2)
would also be acceptable, but doesn't solve the bug either. Together these
would avoid any issues of cos
and sin
domains and invertibility.
Thanks for the bug report!
A simpler case showing the same problem is
R:(rr*cos(rr))/sqrt(1-cos(rr)^2)
.taylor(R,rr,0,0) => 0+...
whiletaylor(R,rr,0,1) => 1+...
.The problem is probably related to the square root. That's not an excuse for bad results, just a hint about where we might look to debug the problem.
Nice work in finding a much more minimal working example. :) We'll see if the solution fixes my original expression...
Interestingly,
tlimit(R,rr,0)
correctly yields1
, though it does ask the sign ofsin(rr)
-- result is the same regardless of the answer. Sadly,limit
gets this wrong -- I will file a separate bug report.Well, it looks like Q is discontinuous at rr = 0., and it's not removable. Is a Taylor series defined for such a function? Even if it is, it seems likely that Maxima's
taylor
function is going to have trouble with it.I guess we could try to make headway by only looking at one-sided limits for the function and its derivatives -- I don't know how much trouble it would be, or whether it would fix the bug observed here.
At this point I would say the bug is that
taylor
has not detected that it cannot construct a valid Taylor series for this problem.R and hence Q are only discontinuous at rr=0 if you interpret sqrt as the "positive square root". But "positive square root" is not an analytic function, and taylor, limit, etc. work on analytic functions.
The kernel of the problem is
R:(rr*cos(rr))/sqrt(1-cos(rr)^2)
. Numerical evaluation gives a negative result for rr=-.01 and a positive result for rr=.01 because it interprets sqrt as the positive square root. But as an analytic function of rr, R should stay on a consistent branch across rr=0. The simplification sqrt(x^2) => abs(x) is incorrect if you are working with analytical functions.@robert_dodier I missed that: you're right: Q is discontinuous at rr = 0. Under the Wikipedia definition [1], what counts is whether Q is infinitely differentiable or not at rr=0. It looks to me like the limit as
rr \rightarrow 0^+
is around 2.58 and asrr \rightarrow 0^-
is-\infty
, so I don't see how the lefthand and righthand first derivatives could be equal. So I agree that strictly speaking, the error intaylor
is that it did not detect the non-existence of the Taylor series.I forgot to say that the domain of interest is the positive reals, for
rr
.x
andy
are reals of max abs value 1. Since one-sided real derivatives exist (in general), it seems to me that one-sided real Taylor series should also exist.The following
gives me
6/ ( 4^(1/3) * %pi^(1/3) )
, which is the expected result for a real, positive, small (rr \ll \pi
) result. This solves my personal, immediate problem, though not the general issue.Should I file a separate wishlist item for extending
taylor
to optionally (opt-in) allow real, one-sided expansions?As for the more general issue, I guess that the behaviour of
taylor
should depend onnumer_pbranch
for cases like this one.[1] https://en.wikipedia.org/wiki/Taylor_series#Definition
The simplified expression can be made analytic across zero over the reals, it seems to me, using
signum
to compensate for not allowing analytic continuation ofsqrt
through zero.Then we have the
taylor
expansions to 0th, 1st and 5th order:So now we have
T
is analytic over the reals andtaylor(T,rr,0,0)
incorrectly gives0 + ...
instead of1 + ...
. So this does look like a bug to me.In terms of successive steps of Taylor series calculations, going from
(r^2 + ...)^(1/2)
tosignum(r) r + ...
might help to handle this - if the domain is restricted to the reals.I'm not sure what your point is here. As I said before,
taylor
ignores assumptions likerr>0
, and thesignum
simplifies away in the presence of such an assumption.As I said before, numerical evaluation is mathematically naive. It treats sqrt(1-cos(rr)^2) as though it were
abs(sin(rr))
-- using the positive square root. Of course, that is not differentiable atrr=0
, and therefore doesn't have a Taylor expansion there.As an analytical function, it is either
sin(rr)
or-sin(rr)
atrr=0
, depending which branch you're on.I agree that numerical evaluation differs from normal maths (I like the URLs that you provided in some other maxima comments). Regarding what
taylor
does and doesn't do, I'm happy to create a separate wishlist item for an option totaylor
which allows it to be evaluated in restricted domains (e.g. just the reals, or just the positive reals). Would taking into account the signs of variables require a fundamental rewrite of the whole of hayat.lisp?I was thinking of defining the function
g(x) := signum(x) * sqrt(x)
. Mathematically, this is infinitely differentiable at zero. However, the first and all greater derivatives are singular at zero. So even restricted to the reals, the Taylor series doesn't exist, it seems to me.I guess this is the reason for
taylor
ignoringsignum
:signum
is discontinuous at zero, the discontinuity is not removable, and the one-sided derivatives at zero are unequal.On the other hand, mathematically, is the function
h(x) := signum(x) * abs(sin(x))
mathematically identical tosin(x)
? I expect that there would be a mathematical problem if we want the chain rule of differentiation to hold, because the two individual functions are individually non-differentiable at zero, unless we take one-sided derivatives only. So the space of functions and some of the usual rules would have to allow special cases such as this one. Extending to https://en.wikipedia.org/wiki/Distribution_%28mathematics%29 would seem like overkill to me, and I expect would be difficult to handle in Maxima, though people who know Maxima better than me could judge that more realistically.I wonder if the following discussion could be useful for a simpler approach than distributions:
https://en.wikipedia.org/wiki/Exponentiation#Failure_of_power_and_logarithm_identities
This includes warnings such as
"one has implicitly supposed that
log exp z = z
for complex values ofz
, which is wrong, as the complex logarithm is multivalued".You are welcome to work on one-sided derivatives if you think that's useful. In many cases, you can simply remove the one-sidedness and go from there. The right derivative of abs(x) at x=0 is the same as the derivative of x for x>=0, and the same as the derivative of -x for x<0.
Currently, Maxima gives the derivative of
abs(x)
asabs(x)/x
, which is the same as the right and the left derivatives everywhere except forx=0
, where it is undefined.Last edit: Stavros Macrakis 2022-01-22
The context of this bug is our paper https://arxiv.org/abs/2201.09102 with the Maxima scripts at https://codeberg.org/boud/topoaccel . The key formula of interest is (21), summed over locations in
S^3
that have been converted to anR^4
embedding space, giving (22), where in the code we writerr
instead ofxi
. If we define the main formulathen we do not have the zeroth order bug in this case:
Both give
1/pi
as the zeroth order. The bug occurs when we do a sum - the other parts of the sum should have singularities, but not nearrr=0
. The particular instance of the bug can be seen 'in the wild' in (old) version be02b0f4:https://codeberg.org/boud/topoaccel/commit/be02b0f47c87b1d927e4b6570bb164383cb92b3f
At line 120 here:
https://codeberg.org/boud/topoaccel/src/commit/be02b0f47c87b1d927e4b6570bb164383cb92b3f/max_Mass_S3_8.m#L120
add a second line below, requesting only the zeroth order instead of the first order:
and run the full script
maxima < main_max_Mass.m > mylog
.The output will then be
Here we do have the bug:
6/(4*%pi)^(1/3)
approx 2.581 versus5/(4*%pi)^(1/3)
approx 2.151.As I was working through your example, I noticed that there's a bug in
limit
.See https://sourceforge.net/p/maxima/bugs/3932/, which is based on your dUdrr.
Maxima is returning 0 for that limit, but 1/3 for
limit(trigsimp(dUdrr)...)
.Thanks for working with us to help track down the problem.
Could you please supply a minimal stand-alone example that shows the problem?
What are the steps to reproduce the problem starting from a fresh Maxima?