# algebra of differential operators

I'm trying to use Sage to check if an explicit function satisfies a PDE. As an example, I would like to be able to apply the operator $\prod_{n=1}^5(t \frac{\partial}{\partial t} - n)$ to $zt e^{t/z}$. What are my options for doing this in Sage?

I found a relevant post on this site, which almost does what I want, but not quite. In the context of that post, I'd like to be able to do something like this:

def Dt(f):
return t*f.derivative(t)

operator = prod([ Dt - n-1 for n in range(5) ])
operator(z*t*exp(t/z))


But of course, this doesn't work. Thanks!

To be clear, I'm asking about the following operator: $$\prod_{n=1}^5(t \frac{\partial}{\partial t} - n) = (t\frac{\partial}{\partial t} - 1)(t\frac{\partial}{\partial t}-2)(t\frac{\partial}{\partial t}-3)$$ $$=\bigg(t\frac{\partial}{\partial t}-1\bigg)\bigg(\big(t\frac{\partial}{\partial t} + t^2 \frac{\partial^2}{\partial t^2}\big) - 5t\frac{\partial}{\partial t} + 6\bigg)$$ $$= \ldots$$ I don't want to finish the expansion by hand. I want Sage to do it for me, and then apply the whole mess to the function $zt e^{t/z}$.

edit retag close merge delete

If you want the composition of the operators, perhaps the 5 in your last expression is actually a 2 ?

( 2014-06-18 12:56:25 +0100 )edit

Sort by » oldest newest most voted

Here is an implementation combining the other two ideas here:

var('t,z')

def op(func,variable,n_max):
"""
Input a function, a variable, and a number
Returns operator applied to function
"""
output = func
for i in range(1,n_max+1):
output = variable*output.derivative(variable) - i*output

return output


If you just want to see the operator, you can apply op to a symbolic function:

sage: symb_f = function('f',t)

sage: op(symb_f,t,2)  # the first two operators composed
t^2*D[0, 0](f)(t) - 2*t*D[0](f)(t) + 2*f(t)

sage: op(symb_f,t,3)  # the first three operators composed
t^3*D[0, 0, 0](f)(t) - 3*t^2*D[0, 0](f)(t) + 6*t*D[0](f)(t) - 6*f(t)


Here's how to use it for your example:

sage: g = op(z*t*exp(t/z),t,5)
sage: g
t^5*(t*e^(t/z)/z^4 + 5*e^(t/z)/z^3) - 5*t^4*(t*e^(t/z)/z^3 + 4*e^(t/z)/z^2) + 20*t^3*(t*e^(t/z)/z^2 + 3*e^(t/z)/z) - 60*t^2*(t*e^(t/z)/z + 2*e^(t/z)) - 120*t*z*e^(t/z) + 120*(t*e^(t/z) + z*e^(t/z))*t


You can simplify symbolic expressions like this:

sage: g.simplify_full()
t^6*e^(t/z)/z^4

more

Thanks! This is a great solution.

( 2014-06-18 16:12:38 +0100 )edit

I've attached some code below that defines your operator in a way that lets it operate on polynomials (it is the operator "op" after the code is run). However, I'm pretty new to Sage, so I'm not sure how to make it act on exponential functions. (Also, since I'm new to Sage, this might be a bad way to make this operator, but it does seem to work, at least.)

RR = PolynomialRing(QQ,'t')
t = RR.gens()[0]

id = lambda x : x
def comp(a,b):
return lambda x: a(b(x))

def Dtn(n):
return lambda f: t*f.derivative(t) - n*f

op = id
for n in range(5):
optmp = op
op = comp(optmp,Dtn(n+1))

more

Indeed, python functions like Df do not like to be added to integers like n-1, or multiplied together.

Is there a reason not to do the computation in a single step ?

sage: var('t z')
sage: f = z*t*exp(t/z)
sage: prod([ t*f.derivative(t) - n-1 for n in range(5) ])
((t*e^(t/z) + z*e^(t/z))*t - 1)*((t*e^(t/z) + z*e^(t/z))*t - 2)*((t*e^(t/z) + z*e^(t/z))*t - 3)*((t*e^(t/z) + z*e^(t/z))*t - 4)*((t*e^(t/z) + z*e^(t/z))*t - 5)

more

1

This is not what I meant. I've added a clarification in my post. Is the clarification clearer?

( 2014-06-12 21:23:22 +0100 )edit

Ah -- you do not want the _product_ of these operators, but their composite (each one applied to the ones to its right)

( 2014-06-18 08:42:11 +0100 )edit

Here is a way to apply a polynomial P in a differential operator D to a function f.

def polydop(P,D,f):
ff = f
g(t) = 0
for c in P.coeffs():
g = (g + c * ff).expand()
ff = D(ff).expand()
return g


To illustrate it on your example, define

• the differential operator:

sage: def D(f):
....:    return t*f.derivative(t)

• the polynomial (in a suitable polynomial ring):

sage: R = PolynomialRing(QQ,'x')
sage: x = R.gen()
sage: P = prod(x-n for n in xrange(1,6))

• and the function:

sage: f(t,z) = z*t*exp(t/z)


and get the following result:

sage: g = polydop(P,D,f)
sage: g
(t, z) |--> t^6*e^(t/z)/z^4

more