# Changing the latex representation of the output of derivative.

130 views

### Oscar Lazo

Feb 6, 2012, 2:49:21 PM2/6/12
Hello

I'm working with Airy functions. Although sage can evaluate
airy_ai(1.0), it cannot form a symbolic expression like:
A*airy_ai(x)+B*airy_bi, which is what i need.

So I decided to define the symbolic functions:

ai=function('ai',x,latex_name='Ai')
bi=function('bi',x,latex_name='Bi')

this way

f=A*airy_ai(x)+B*airy_bi
f

looks nice, but I also need to use their derivatives,

un fortunately, the diff function returns a rather ugly output:
A1*D[0](ai)(x) + B1*D[0](bi)(x)

I can live with that, but I also need to be able to visualize in
typesetted form some complicated expressions involving the derivatives
of Airy functions, so I would very much prefer if diff(ai) would be
typesetted the same way as

aip=function('aip',x,latex_name='Ai\'')

Can this be done?

Thank you!

Oscar

### kcrisman

Feb 6, 2012, 3:32:33 PM2/6/12
to sage-support

> I can live with that, but I also need to be able to visualize in
> typesetted form some complicated expressions involving the derivatives
> of Airy functions, so I would very much prefer if diff(ai) would be
> typesetted the same way as
>
> aip=function('aip',x,latex_name='Ai\'')

Airy functions are in Maxima
http://maxima.sourceforge.net/docs/manual/en/maxima_15.html#Item_003a-airy_005fai
and mpmath
http://docs.sympy.org/0.7.0/modules/mpmath/functions/bessel.html#airyai
so we should be able to make them symbolic and evaluate them and get
derivatives and related integrals nicely.

See http://hg.sagemath.org/sage-main/file/tip/sage/functions/trig.py#l305
for a class definition you could mimic. I don't think there is any
other way to get custom derivatives, not on the fly, and not with
'function'.

Though if there is, that would be very useful! It would be nice to
have something like this work.

sage: F = function('ai',x)
sage: F
ai(x)
sage: G = function('aip',x)
sage: G
aip(x)
sage: F._derivative = G
---------------------------------------------------------------------------
AttributeError: 'sage.symbolic.expression.Expression' object attribute
sage: F.__setattr__('_derivative',G)
---------------------------------------------------------------------------
AttributeError: 'sage.symbolic.expression.Expression' object attribute

- kcrisman

### Oscar Lazo

Feb 6, 2012, 4:22:06 PM2/6/12
to sage-support
That worked excelent! I made the following code:

from sage.symbolic.function import BuiltinFunction
class AiryAi(BuiltinFunction):
def __init__(self):
BuiltinFunction.__init__(self, "ai",
latex_name=r"\operatorname{Ai}")
def _derivative_(self, x, diff_param=None): return aip(x)

class AiryAiPrime(BuiltinFunction):
def __init__(self):
BuiltinFunction.__init__(self, "aip",
latex_name=r"\operatorname{Ai}'")

class AiryBi(BuiltinFunction):
def __init__(self):
BuiltinFunction.__init__(self, "bi",
latex_name=r"\operatorname{Bi}")
def _derivative_(self, x, diff_param=None): return bip(x)

class AiryBiPrime(BuiltinFunction):
def __init__(self):
BuiltinFunction.__init__(self, "bip",
latex_name=r"\operatorname{Bi}'")

ai=AiryAi()
bi=AiryBi()
aip=AiryAiPrime()
bip=AiryBiPrime()
ai(x)+bi(x)+aip(x)+bip(x)

And now stuff like
f=A1*ai(k*x)+B1*bi(k*x)
f
diff(f,x).subs(x=x0)

works exactly the way I wanted.

Thank you!

Oscar

On 6 feb, 14:32, kcrisman <kcris...@gmail.com> wrote:
> > I can live with that, but I also need to be able to visualize in
> > typesetted form some complicated expressions involving the derivatives
> > of Airy functions, so I would very much prefer if diff(ai) would be
> > typesetted the same way as
>
> > aip=function('aip',x,latex_name='Ai\'')
>
> Airy functions are in Maximahttp://maxima.sourceforge.net/docs/manual/en/maxima_15.html#Item_003a...
> and mpmathhttp://docs.sympy.org/0.7.0/modules/mpmath/functions/bessel.html#airyai
> so we should be able to make them symbolic and evaluate them and get
> derivatives and related integrals nicely.
>
> Seehttp://hg.sagemath.org/sage-main/file/tip/sage/functions/trig.py#l305

### kcrisman

Feb 6, 2012, 8:37:55 PM2/6/12
to sage-support
Great!

Oscar, you have a Trac account, right? Would you mind opening up a
ticket to make these functions "symbolic", put your code up as a
"protopatch", add the ticket to an appropriate place on
http://trac.sagemath.org/sage_trac/wiki/symbolics/functions, and cc:
users kcrisman, burcin, and benjaminfjones on the ticket? Since we
have robust numerical evaluation for this, we might as well add them
in this way.

Thanks!

- kcrisman

### Oscar Lazo

Feb 7, 2012, 3:08:04 AM2/7/12
to sage-support
Done:

http://trac.sagemath.org/sage_trac/ticket/12455

I've added a patch, which should do the job, but it has a few
shortcomings:

1.-The resulting symbolic functions seem to remain on hold:

sage: airy_ai(1.0)
airy_ai(1.00000000000000)

You need to force it to evaluate:

sage: airy_ai(1.0).n()
0.135292416313

2.- This doesn't work:

sage: airy_ai(2.0).n(digits=100)
0.0349241304233

3.- There is no evaluation for airy_ai_prime or airy_bi_prime

4.- I'm not sure about how should the functions be called, some
possible schemes are

{ai,bi,aip,bip} {ai,bai,aip,baip}
{airy_ai,airy_bi,airy_ai_prime,airy_bi_prime}

And also whether the latex representation should be capitalized or
not. I chose the third scheme, and capitalized typesetting.

Cheers!

Oscar
> "protopatch", add the ticket to an appropriate place onhttp://trac.sagemath.org/sage_trac/wiki/symbolics/functions, and cc:
> users kcrisman, burcin, and benjaminfjones on the ticket? Since we
> have robust numerical evaluation for this, we might as well add them
> in this way.
>
> Thanks!
>
> - kcrisman

> "protopatch", add the ticket to an appropriate place onhttp://trac.sagemath.org/sage_trac/wiki/symbolics/functions, and cc:

### Burcin Erocal

Feb 7, 2012, 5:48:37 AM2/7/12
Hi Oscar,

On Tue, 7 Feb 2012 00:08:04 -0800 (PST)
Oscar Lazo <algebra...@gmail.com> wrote:

Thanks!

> I've added a patch, which should do the job, but it has a few
> shortcomings:
>
> 1.-The resulting symbolic functions seem to remain on hold:
>
> sage: airy_ai(1.0)
> airy_ai(1.00000000000000)
>
> You need to force it to evaluate:
>
> sage: airy_ai(1.0).n()
> 0.135292416313

You need to add an _eval_() function which calls _evalf_() if the
argument is not exact. See this patch for an example:

http://trac.sagemath.org/sage_trac/attachment/ticket/4498/trac_4498-symbolic_arg.cleanup.patch

> 2.- This doesn't work:
>
> sage: airy_ai(2.0).n(digits=100)
> 0.0349241304233

The _evalf_() function in your patch hard codes RDF. You need to do
something like this:

sage: from sage.libs.mpmath import utils as mpmath_utils
sage: import mpmath
sage: mpmath_utils.call(mpmath.airyai, 1, parent=RR)
0.135292416312881

> 3.- There is no evaluation for airy_ai_prime or airy_bi_prime

I don't think we want to have separate functions for the derivatives in
Sage. These might help you get around the printing problem for now, but
they are not useful in general.

BTW, #6244 has a patch that changes the way derivatives are printed:

http://trac.sagemath.org/sage_trac/ticket/6344#comment:2

> 4.- I'm not sure about how should the functions be called, some
> possible schemes are
>
> {ai,bi,aip,bip} {ai,bai,aip,baip}
> {airy_ai,airy_bi,airy_ai_prime,airy_bi_prime}
>
> And also whether the latex representation should be capitalized or
> not. I chose the third scheme, and capitalized typesetting.

I like airy_{a,b}i and capitalized typesetting as well.

Cheers,
Burcin

### Oscar Lazo

Feb 7, 2012, 9:56:30 AM2/7/12
to sage-support

On 7 feb, 04:48, Burcin Erocal <bur...@erocal.org> wrote:
> You need to add an _eval_() function which calls _evalf_() if the
> argument is not exact. See this patch for an example:
>
> http://trac.sagemath.org/sage_trac/attachment/ticket/4498/trac_4498-s...

Done :)

> The _evalf_() function in your patch hard codes RDF. You need to do
> something like this:
>
> sage: from sage.libs.mpmath import utils as mpmath_utils
> sage: import mpmath
> sage: mpmath_utils.call(mpmath.airyai, 1, parent=RR)
> 0.135292416312881

mpmath seems to be around 35 times faster than the RDF version, (which
was the way things were done before my patch).

> I don't think we want to have separate functions for the derivatives in
> Sage. These might help you get around the printing problem for now, but
> they are not useful in general.

I disagree here, Mathematica has got the AiryAiPrime function. And
mpmath supports calculating derivatives and integrals of arbitrary
order! I think it would be best if we could do something like:

sage: airy_ai(x)
airy_ai(x)
sage: airy_ai(x,1)
airy_ai_prime(x)
sage: airy_ai(x,-2)
airy_ai(x,-2)

that is, make a single object that returns arbitrary derivatives or
integrals.

Cheers!

Oscar

### Burcin Erocal

Feb 7, 2012, 10:15:36 AM2/7/12

You're right, I didn't know mpmath supported this. We can have a main
function that takes a single argument and another one with two
arguments to represent the derivatives. This is similar to how maple
implements the airy function:

http://www.maplesoft.com/support/help/Maple/view.aspx?path=Airy

The implementation would be similar to that of the psi function:

http://hg.sagemath.org/sage-main/file/tip/sage/functions/other.py#l810

Note that there are two symbolic functions Function_psi1 and
Function_psi2, with a regular python function names psi() that
wraps these.

You can also put the new functions in a new file sage/functions/airy.py.

Cheers,
Burcin

### Oscar Lazo

Feb 7, 2012, 5:14:55 PM2/7/12
to sage-support
On second thought, I think it would be better to use the airy equation
to calculate derivatives or order higher than 1. Like

sage: airy_ai(2,x)
x*airy_ai(x)
sage: airy_ai(3,x)
airy_ai(x)+x*airy_ai_prime(x)
sage: diff(airy_ai(x),x,2)
x*airy_ai(x)
sage: diff(airy_ai(x),x,3)
airy_ai(x)+x*airy_ai_prime(x)

which is very likey to be the way mpmath calculates higher order
derivatives. Integrals however, would be returned as:

sage: airy_ai(-1,x)
airy_ai(-1,x)
sage: integral(airy_ai(x),x)
airy_ai(-1,x)

what do you think?

Oscar