sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.36k stars 462 forks source link

symbolic derivatives should be able to have non-variable arguments #10982

Open 9dd22736-ae7b-4fcc-871e-f43b962cbafd opened 13 years ago

9dd22736-ae7b-4fcc-871e-f43b962cbafd commented 13 years ago

Here is an example from the french sagebook to compute the laplacian in polar, that no longer works with version 4.6 of Sage

sage: x, y, r, t = var('x, y, r, t'); f = function('f', x, y)
sage: F = f(x = r*cos(t), y = r*sin(t))
sage: d = (diff(F,r,2) + diff(F,t,2)/r**2 + diff(F,r)/r)
sage: d.simplify_full() 
---------------------------------------------------------------
NotImplementedError           Traceback (most recent call last)

NotImplementedError: arguments must be distinct variables

With older versions, you got it :

sage: d.simplify_full()
D[0, 0](f)(r, t) + D[1, 1](f)(r, t)

CC: @kcrisman @zimmermann6

Component: calculus

Keywords: simplify, maxima, symbolic derivative

Issue created by migration from https://trac.sagemath.org/ticket/10982

kcrisman commented 13 years ago

Changed keywords from simplify_full to simplify, maxima, symbolic derivative

kcrisman commented 13 years ago
comment:1

I don't know that this is necessarily a regression so much as having made some choices about what is 'allowed' to be a symbolic derivative. We don't allow (for reasons that are unclear to me, because I still don't understand why we changed how we represent symbolic derivatives) arguments that are not just variables, unlike here where they are expressions.

It's the conversion to Maxima that is failing, by the way.

sage: d.simplify() 
---------------------------------------------------------------
NotImplementedError           Traceback (most recent call last)

NotImplementedError: arguments must be distinct variables

This even happens with trying to simplify (send to Maxima)

sage: diff(F,r).simplify()
<boom>

This is at least tangentially related to #6840 and #6756, though probably not directly.

burcin commented 13 years ago
comment:2

AFAIK, #7377 improves the conversion of derivatives to maxima. It might fix this as well.

kcrisman commented 13 years ago
comment:3

Replying to @burcin:

AFAIK, #7377 improves the conversion of derivatives to maxima. It might fix this as well.

Nice idea! Unfortunately, it seems to have the same problem.

nbruin commented 13 years ago
comment:4

Replying to @kcrisman:

Replying to @burcin:

AFAIK, #7377 improves the conversion of derivatives to maxima. It might fix this as well.

Nice idea! Unfortunately, it seems to have the same problem.

but see #7377 comment:54 for some ideas on how to improve this. The concerns about "at" in maxima are ungrounded: It's the documentation that is wrong and this will be fixed in the new version. It would be quite straightforward to extend the support to general derivatives, including conversion to/from maxima (we'll have to see how much trouble the "at" expressions give further down the line, of course). Furthermore, the conversion is easier to do with #7377 but it's not required. You could already do this in the old setup.

kcrisman commented 13 years ago
comment:5

Thanks for that comment reference. I think you are right that this could work out. You are also right that "Sage support for functional derivatives is only rudimentary." This largely changed when the D[0] notation was introduced.

56048686-9665-4c5e-973e-6c3add3aa805 commented 12 years ago
comment:7

This seems to work for me in 5.0:


sage: x, y, r, t = var('x, y, r, t')
sage: f = function('f', x, y)
sage: F = f(x = r*cos(t), y = r*sin(t))
sage: d = (diff(F,r,2) + diff(F,t,2)/r**2 + diff(F,r)/r)
sage: d.simplify() 
(sin(t)*D[1, 1](f)(r*cos(t), r*sin(t)) + cos(t)*D[0, 1](f)(r*cos(t), r*sin(t)))*sin(t) + (sin(t)*D[0, 1](f)(r*cos(t), r*sin(t)) + cos(t)*D[0, 0](f)(r*cos(t), r*sin(t)))*cos(t) + (sin(t)*D[1](f)(r*cos(t), r*sin(t)) + cos(t)*D[0](f)(r*cos(t), r*sin(t)))/r - ((r*sin(t)*D[0, 1](f)(r*cos(t), r*sin(t)) - r*cos(t)*D[1, 1](f)(r*cos(t), r*sin(t)))*r*cos(t) - (r*sin(t)*D[0, 0](f)(r*cos(t), r*sin(t)) - r*cos(t)*D[0, 1](f)(r*cos(t), r*sin(t)))*r*sin(t) + r*sin(t)*D[1](f)(r*cos(t), r*sin(t)) + r*cos(t)*D[0](f)(r*cos(t), r*sin(t)))/r^2
sage: d.simplify_full()
D[0, 0](f)(r*cos(t), r*sin(t)) + D[1, 1](f)(r*cos(t), r*sin(t))
sage: diff(F,r).simplify()
sin(t)*D[1](f)(r*cos(t), r*sin(t)) + cos(t)*D[0](f)(r*cos(t), r*sin(t))
sage: diff(F,r).simplify_full()
sin(t)*D[1](f)(r*cos(t), r*sin(t)) + cos(t)*D[0](f)(r*cos(t), r*sin(t))

Although I'm too lazy to bisect to find out when it started working again, it'd probably be a good idea to add a doctest to make sure that it stays that way. Not quite sure where to put it, though.

56048686-9665-4c5e-973e-6c3add3aa805 commented 12 years ago
comment:8

Hmm. On second thought, I may have spoken too quickly:

D[0, 0](f)(r*cos(t), r*sin(t)) + D[1, 1](f)(r*cos(t), r*sin(t))

and

D[0, 0](f)(r, t) + D[1, 1](f)(r, t)

are a little different. Not incompatible, because the functions are abstract, but still not the same. Do we want to recover the original representation?

nbruin commented 12 years ago
comment:9

Replying to @sagetrac-dsm:

D[0, 0](f)(r, t) + D[1, 1](f)(r, t)

Wow, Sage before 4.6 was just plain wrong. We'll excuse casamayou, since superficially it looks like what one would sloppily write in a calculus book (the coordinate transformation implicitly assumed).

The formula for d is the expression for the laplacian in polar coordinates, so it should be equal to

(diff(f,x,x)+diff(f,y,y)).subs(x=r*cos(t),y=r*sin(t))

which is what 5.0 verifies.

I'm pretty sure #12796 fixed this, since this kind of computation was the point of that ticket. I think this ticket can be closed. Add a doctest if you think the current tests are insufficient.