# Extracting coefficients from a partial differential equation

Frequently, I come across the following problem: How to rewrite a complicated partial differential equation in a more clear way? I would like to create some order by collecting terms that are equal.

For example, this rather messy equation $0 = \frac{1}{4} l^4 m^4 y F^{(0,1)}(x,y)-6 l^2 M^2 y F^{(0,1)}(x,y)+\Lambda F^{(0,1)}(x,y)$,

can be written more clear as

$0 = \text{newform} = a_{0001} F^{(0,1)}(x,y)+a_{0101} y F^{(0,1)}(x,y)$

with $a_{0101}=\frac{l^4 m^4}{4}-6 l^2 M^2$ and $a_{0001}=\Lambda$.

My question is how to determine the coefficients from a given PDE? To make it more tangible, suppose I have a partial differential equation of f(x,y) that is quadratic in f and has order 6 derivatives in derivatives. It can be written as

$0 = \sum_{i,j,k,l} a_{i j k l} x^i y^{j}F^{(k,l)}(x,y) + \sum_{i,j,k,l,m,n} b_{i j k l m n} x^i y^{j}F^{(k,l)}(x,y)F^{(m,n)}(x,y)$

I want to use Mathematica to

1. Rewrite the PDE into the above form; i.e. replace calculate all the coefficients
2. Do not include terms with that have a zero coefficient in this new form
3. Create a replacement rule for each coefficient.
4. Check that this new form of writing eq is indeed equivalent.

How can I do this? If point 1 - 3 are established, then point 4 is easy: Just check that the following adds up to zero

oldform - newform /. substitutionrule


To give you an idea, these are some of the terms that appear in my PDE. $\small{l^4 m^4 F(x,y) -57 l^4 \Lambda M^2 F(x,y) + l^4 m^4 y F^{(0,1)}(x,y)+ 57 l^4 \Lambda M^2 y F^{(0,1)}(x,y)-24 l^2 M^2 y F^{(0,1)}(x,y)}$ $+ \small{2 M^2 y^8 F^{(0,1)}(x,y) F^{(0,5)}(x,y)-4 M^2 y^8 F^{(2,4)}(x,y)+4 M^2 y^6 F(x,y) F^{(0,4)}(x,y) = 0}$

Here is the InputForm of this 'toy PDE'

eqn = l^4*m^4*F[x, y] - 57*l^4*Lambda*M^2*F[x, y] + l^4*m^4*y*Derivative[0, 1][F][x, y]
- 24*l^2*M^2*y*Derivative[0, 1][F][x, y]
+ 57*l^4*Lambda*M^2*y*Derivative[0, 1][F][x, y]
+ 4*M^2*y^6*F[x, y]*Derivative[0, 4][F][x, y]
+  2*M^2*y^8*Derivative[0, 1][F][x, y]*Derivative[0, 5][F][x, y]
- 4*M^2*y^8*Derivative[2, 4][F][x, y]


And more convenient to copy into a notebook is this form

eqn = l^4*m^4*F[x, y] - 57*l^4*Lambda*M^2*F[x, y] + l^4*m^4*y*Derivative[0, 1][F][x, y] - 4*l^2*M^2*y*Derivative[0, 1][F][x, y] +  57*l^4*Lambda*M^2*y*Derivative[0, 1][F][x, y] + 4*M^2*y^6*F[x, y]*Derivative[0, 4][F][x, y] +  2*M^2*y^8*Derivative[0, 1][F][x,y]*Derivative[0, 5][F][x, y] - 4*M^2*y^8*Derivative[2, 4][F][x, y]


Update:

Pillsy gave a nice solution that does exactly (1)-(4). To see what kind of powers of x, y, $\partial_x$ and $\partial_y$ are contained in the example PDE I use his code, and I add

Total[coeffRules /. {(a[i_, j_, k_, l_] -> coeff_) :>
Subscript[a, i, j, k, l]*x^i*y^j*
Derivative[k, l][F], (b[i_, j_, k_, l_, m_, n_] -> coeff_) :>
Subscript[b, i, j, k, l, m, n]*x^i*y^j*
Derivative[k, l][F] Derivative[m, n][F]}]


This gives $\small{y^8 a_{0,8,2,4} F^{(2,4)}+3 y a_{0,1,0,1} F^{(0,1)}+2 F a_{0,0,0,0}+y^8 b_{0,8,0,1,0,5} F^{(0,1)} F^{(0,5)}+F y^6 b_{0,6,0,0,0,4} F^{(0,4)}}$

Now it is much easer to see what kind of PDE this is. There is one more thing I would like to ask. How can I avoid the double counting of terms that results for example in the factor 3 in $3 y a_{0,1,0,1} F^{(0,1)}$?

This works, I think

% /. {Times[a_Integer, b_] -> b, Times[b_, a_Integer] -> b}


$\small{y^8 a_{0,8,2,4} F^{(2,4)}+y a_{0,1,0,1} F^{(0,1)}+F a_{0,0,0,0}+y^8 b_{0,8,0,1,0,5} F^{(0,1)} F^{(0,5)}+F y^6 b_{0,6,0,0,0,4} F^{(0,4)}}$

-
I see a -1 for my question. What could be the reason for that? How can I improve my question? – sjdh Feb 22 '12 at 11:45
I added hopefully more readable InputForm of the expression in your eq. Please check if it correctly represents the expression you intended. – kglr Feb 22 '12 at 11:52
@kguler It seems you have replaced x with 1 by a mistake. – Artes Feb 22 '12 at 12:16
@Artes, Thank you; just noticed it and fixed it. – kglr Feb 22 '12 at 12:47
@Artes thank you for the improvements. I made a mistake myself by adding a cubic term in F. I will repair it. – sjdh Feb 22 '12 at 13:46

So, this is a solvable problem, but my solution is hacky, not cookbook by any means. It involves using Apply to make algebraic expressions into lists of terms and factors, and it relies the optional levelspec arguments for Cases and DeleteCases being infinity.

Also note the use of Block to temporarily suspend the evaluation rules for Derivative, so that I can make things more regular by replacing F[x, y] with Derivative[0, 0][F][x, y]. This is a frequently useful trick when doing algebraic manipulations.

coeffRules = Block[{Derivative},
With[{terms =
Apply[List, eqn /. F[x, y] :> Derivative[0, 0][F][x, y]]},
Cases[
Flatten@Map[CoefficientRules[#, {x, y}] &, terms],

(pows_ -> rhs_) :>
With[{degs =
Flatten[Cases[rhs, Derivative[degs___][F][x, y] :> degs,
Infinity]]},
With[{args = Join[pows, degs]},
If[Length@args == 4, a @@ args, b @@ args]]
-> DeleteCases[rhs, Derivative[___][F][x, y], Infinity]]]]];


Here, coeffRules is just a list of rules for the a and b coefficients you described:

{a[0, 0, 0, 0] -> l^4 m^4, a[0, 0, 0, 0] -> -57 l^4 Lambda M^2,
a[0, 1, 0, 1] -> l^4 m^4, a[0, 1, 0, 1] -> -4 l^2 M^2,
a[0, 1, 0, 1] -> 57 l^4 Lambda M^2, b[0, 6, 0, 0, 0, 4] -> 4 M^2,
b[0, 8, 0, 1, 0, 5] -> 2 M^2, a[0, 8, 2, 4] -> -4 M^2}


You can then verify that this answer is correct like so:

In[17]:= Total[coeffRules /. {
(a[i_, j_, k_, l_] -> coeff_) :>
coeff*x^i*y^j*Derivative[k, l][F][x, y],
(b[i_, j_, k_, l_, m_, n_] -> coeff_) :>
coeff*x^i*y^j*
Derivative[k, l][F][x, y] Derivative[m, n][F][x, y]}] - eqn
Out[17]= 0


Hopefully this is enough to get you started.

EDIT to add: In reply to @sjdh's comment, you can collect all the terms with the same left-hand side using Map, GatherBy and Total:

In[69]:= gatheredRules = Map[
(#[[1, 1]] -> Total@#[[All, -1]]) &,
GatherBy[coeffRules, First]]
Out[69]= {a[0, 0, 0, 0] -> l^4 m^4 - 57 l^4 Lambda M^2,
a[0, 1, 0, 1] -> l^4 m^4 - 4 l^2 M^2 + 57 l^4 Lambda M^2,
b[0, 6, 0, 0, 0, 4] -> 4 M^2, b[0, 8, 0, 1, 0, 5] -> 2 M^2,
a[0, 8, 2, 4] -> -4 M^2}


In order to verify that this matches the original equation, use Simplify:

In[70]:= Simplify[eqn -
Total[gatheredRules /. {
(a[i_, j_, k_, l_] -> coeff_) :>
coeff*x^i*y^j* Derivative[k, l][F][x, y],
(b[i_, j_, k_, l_, m_, n_] -> coeff_) :>
coeff*x^i*y^j*Derivative[k, l][F][x, y] Derivative[m, n][F][x, y]}]]
Out[70]:= 0


The secret to doing these kind of algebraic manipulations in Mathematica is that algebraic expressions are just list structures with some fancy heads, and thus can be manipulated with exactly the same functions (like Map and Cases) as lists. Indeed, as you become more familiar with Mathematica, you'll discover that pretty much everything, from graphics to imported XML to notebooks themselves, can be manipulated this way.

-
Now there are two rules for the same coefficient: a[0, 0, 0, 0] -> l^4 m^4 and a[0, 0, 0, 0] -> -57 l^4 Lambda M^2. How can I replace them by one rule a[0, 0, 0, 0] -> l^4 m^4 + -57 l^4 Lambda M^2 ? – sjdh Feb 23 '12 at 9:50