5

How to create a Mathematica code for finding degree of a Differential Equation (ODE or PDE)?

For example;

  1. The degree of the following ODE is 2.

    eq1=(D[u[t], {t,3}])^2-D[u[t], {t,2}] u[t] +D[u[t],t]==0

  2. The degree of the following PDE is 3.

eq2=D[u[x,y], x] + (D[u[x,y], x,y])^3==0

  1. As far as I know, the degree is not defined since the PDE is not in polynomial form.

eq3=D[u[x,y], x] + Sin[D[u[x,y], x,y]]==0

  1. The degree of the following PDE is 2.

eq4=(1 + y'[x]^2)^(3/2) == y''[x]

RF_1
  • 672
  • 2
  • 7
  • 1
    for an ode, if you know Maple, you can translate this code here to Mathematica, as it works and I tested it. It is not trivial to find the degree of an ode, because ode has to be first be made rational and integral in all of its derivatives before finding the degree of the highest derivative. see also this discussion on the math forum.... – Nasser Feb 22 '23 at 08:00
  • Here is an example, what is the degree of this ode (1 + y'[x]^2)^(3/2) == y''[x] ? If you say 1, then it is wrong answer. It is degree is 2 actually. Why? Because you need first to square both sides to rationalizes all derivatives, which makes it (1 + y'[x]^2)^3 == y''[x]^2 and only now you can look at the degree of the ode. It is this step which causes difficulty. It is like making the ode a polynomial in all its derivatives. And a polynomial can only have integer exponents. Mathematica graphics – Nasser Feb 22 '23 at 08:05
  • @Nasser for the example you presented in the second comment this seems to do decent job Distribute[((1 + y'[x]^2)^(3/2) == y''[x])^2, Equal] Another interesting question, is if we can assume that there will have been some manipulations and the (o)(p).d.e will have assumed a certain form – bmf Feb 22 '23 at 08:18
  • @bmf using Distribute is interesting. I never thought to try it. If this makes all possible cases rational in derivatives, then the rest will be easy now. I have code to find degree of an ode in Mathematica (it is straight forward) , but it assumes all powers on derivatives are rational already and that is why I did not post it. I will try your trick on some test ode's to see if they work on all cases. – Nasser Feb 22 '23 at 08:22
  • @Nasser well Distribute needs to be tested and properly modified to get the correct power, but I don't see why not. What I mean is that I don't see any immediate problem. Also, this foo[expr_] := Max[0, Max[ Cases[expr, Derivative[n_] -> n, Infinity, Heads -> True]]] will get the highest derivative of the expression and as far as I can tell it's consistent - more tests are needed though – bmf Feb 22 '23 at 08:24
  • Yes, I have code already to find highest derivative also. This is not a problem also. It is the rationalization part which is the problem. I can post my test cases that I use in Maple and see if you get same result. If you then you can post this as answer. – Nasser Feb 22 '23 at 08:26
  • @Nasser I am happy to do some tests, but perhaps we should wait to see if someone else will get a full solution. – bmf Feb 22 '23 at 08:38
  • @bmf I noticed in your Distribute example, you set the power to 2 manually by inspection. In the code implementation of a solution, ofcourse this step has to be automated. – Nasser Feb 22 '23 at 08:43
  • @Nasser yes, this is what I tried to write earlier, but I don't think I was very clear about it. Somehow, there has to be some sort of pattern matching for the highest power and then an appropriate Distribute – bmf Feb 22 '23 at 08:48

3 Answers3

7

This is too long to post in comment.

These are the tests I use to finding ode degree. Could be used to verify your answers. Each list has the ode as first entry, and the degree expected. Some ode's have no defined degree. Feel free to edit this community wiki post and add your own tests to this list.

test1 = {{y'[x] == y[x]^(1/2), 1},
   {y'[x] + y''[x] == 0, 1},
   {y'[x] + y''[x]^2 == 0, 2},
   {y''[x] + y'[x]^(1/2) == y[x], 2},
   {(1 + y'[x]^2)^(3/2) == y''[x], 2},
   {3*y[x]^2*y'[x]^3 - y''[x] == Sin[x^2], 1},
   {Sqrt[1 + y'[x]^2] == y[x]*y'''[x], 2},
   {Sqrt[1 + y'[x]^2] == y[x]*y'''[x]^2, 4},
   {Sin[y'[x]] + y'''[x] + 3*x == 0, "undefined"},
   {Exp[y''[x]] + Sin[x]*y'[x] == 1, "undefined"},
   {k*y''[x]^2 == (1 + y''[x]^2)^3, 6},
   {x*y''[x]^3*y'[x] - 5*Exp[x]*y''[x] + y[x]*Log[y[x]] == 0, 3},
   {2*Log[x]*y'[x]^2 + 7*Cos[x]*y''[x]^4*y'[x]^7 + x*y[x] == 0, 4},
   {y[x] - x*y'[x] - 1/(2*y'[x]^2) == 0, 3},
   {y''[x] - a*(c + b*x + y[x])*(y'[x]^2 + 1)^(3/2) == 0, 2}
   };

To find max derivative (not degree), this is the code I use in case it is needed also.

(*This function getPatterns is thanks to Carl Woll,see https://mathematica.stackexchange.com/questions/151850/using-cases-and-when-to-make-input-a-list-or-not*)

getPatterns[expr_, pat_] := Last@Reap[expr /. a : pat :> Sow[a], _, Sequence @@ #2 &];

getMaxOrder[ode_, y_, x_] := Module[{der, n}, der = getPatterns[ode, Derivative[n_][y][x]]; Max[Cases[der, Derivative[n_][y][x] :> n]] ]

This gives against the above tests the following

getMaxOrder[First[#], y, x] & /@ tests

(* {1, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 2} *)

The definition of degree used is from Ince book

enter image description here

Update

This test table is based on definition of degree for ode suggested by Michael below which is different from the one in Ince book. So solution based on this definition should be OK also. I've updated the above to reflect this new definition.

test2 = {{y'[x] == y[x]^(1/2), 1}, 
    {y'[x] + y''[x] == 0, 1}, 
    {y'[x] + y''[x]^2 == 0, 2}, 
    {y''[x] + y'[x]^(1/2) == y[x], 1}, 
    {(1 + y'[x]^2)^(3/2) == y''[x], 1}, 
    {3*y[x]^2*y'[x]^3 - y''[x] == Sin[x^2], 1}, 
    {Sqrt[1 + y'[x]^2] == y[x]*y'''[x], 1}, 
    {Sqrt[1 + y'[x]^2] == y[x]*y'''[x]^2, 2}, 
    {Sin[y'[x]] + y'''[x] + 3*x == 0, 1}, 
    {Exp[y''[x]] + Sin[x]*y'[x] == 1, "undefined"}, 
    {k*y''[x]^2 == (1 + y''[x]^2)^3, 6}, 
    {x*y''[x]^3*y'[x] - 5*Exp[x]*y''[x] + y[x]*Log[y[x]] == 0,3}, 
    {2*Log[x]*y'[x]^2 + 7*Cos[x]*y''[x]^4*y'[x]^7 + x*y[x] == 0, 4}, 
    {y[x] - x*y'[x] - 1/(2*y'[x]^2) == 0, "undefined"}, 
    {y''[x] - a*(c + b*x + y[x])*(y'[x]^2 + 1)^(3/2) == 0, 1}, 
    {Cos[y'[x]^2] + y''[x]^2 == 0, 2}, 
    {Cos[y''[x]^2] + y'[x]^2 == 0, "undefined"}
   };
Nasser
  • 143,286
  • 11
  • 154
  • 359
  • 2
    Why is the degree of y''[x] - a*(c + b*x + y[x])*(y'[x]^2 + 1)^(3/2) == 0 1? – xzczd Feb 23 '23 at 03:26
  • @xzczd because I copied it wrong :). I used an old version of the list, which I corrected later on but was looking at the old version when I posted it. Thanks. Corrected the post. it should be degree 2. – Nasser Feb 23 '23 at 03:49
  • @Nasser thanks for this. Just a comment, when I tried LinearAlgebraPrivateZeroArrayQ[(foo[First[#]] & /@ tests) - (getMaxOrder[First[#], y, x] & /@ tests)] I got True which is good. foo is taken from the comments section under the OP. I have not figured out a way to do automatically the Distribute that I suggested – bmf Feb 23 '23 at 03:55
  • I've seen definitions that do not require the ODE to be algebraic in the lower-order dependent variables, so that the degree of Sin[y'[x]] + y'''[x] + 3*x == 0 is 1 instead of "undefined." – Michael E2 Feb 23 '23 at 13:16
  • @MichaelE2 That is possible. I am just following what seems to be the common one When an equation is polynomial in all the differential coefficients involved, the power to which the highest differential coefficient is raised is known as the degree of the equation. from Ince book. Will post screen shot. – Nasser Feb 23 '23 at 13:22
  • No screen shot necessary. I'm suggesting that there are multiple definitions used in the world. – Michael E2 Feb 23 '23 at 13:24
  • @MichaelE2 feel free to edit the wiki post if you want add the definition/reference you know about. – Nasser Feb 23 '23 at 13:25
  • 1
    I don't remember which text. I just remember the example, something like $\cos((y'')^2) + (y')^2 = 0$ (deg. undef.) vs. $\cos((y')^2) + (y'')^2 = 0$ (deg. = 2). OTOH, I've never had any use for the degree of an ODE nor does any textbook I've used or reviewed include the concept. So it's curious to me that someone is actually interested in it. According to the quoted section of Ince, $y''=\sqrt{y'}$ has no degree, only its rationalization does, according to a strict reading of the hypothesis that "the equation is polynomial." Does Ince go onand clarify this? – Michael E2 Feb 23 '23 at 13:41
  • @MichaelE2 Ok, that sounds reasonable definition also. Will add new tests table based on this definition. I have code to find degree based on this definition (since it is simpler) and will also post that. – Nasser Feb 23 '23 at 14:05
  • @MichaelE2 using your definition, what will be the degree of y[x] - x*y'[x] - 1/(2*y'[x]^2) == 0. Is it undefined? according to Ince, this will have degree 3. – Nasser Feb 23 '23 at 14:15
5

There seems to be more than one definition for degree of ode. Lets call the one in Ince book (reference given in the above wiki post) the strict definition, which require first converting the ode to polynomial in all the derivatives, and definition mentioned by Michael above from another text which we can call the non strict definition. In this definition, the ode just have to be a polynomial in the highest order term.

test2 table given in the above wiki post is based on the non strict definition. While test1 table is based on the strict definition

This code below implements non strict definition to finding the degree of an ode.

(*This function getPatterns is thanks to Carl Woll,see https://mathematica.stackexchange.com/questions/151850/using-cases-and-when-to-make-input-a-list-or-not*)

getPatterns[expr_, pat_] := Last@Reap[expr /. a : pat :> Sow[a], _, Sequence @@ #2 &];

getMaxOrder[ode_, y_Symbol, x_Symbol] := Module[{der, n}, der = getPatterns[ode, Derivative[n_][y][x]]; Max[Cases[der, Derivative[n_][y][x] :> n]] ];

getDegree[odeIn_Equal, y_Symbol, x_Symbol] := Module[{ode = First@odeIn - Last@odeIn, order, z, degree}, order = getMaxOrder[ode, y, x]; ode = ode /. Derivative[order][y][x] :> z; If[PolynomialQ[ode, z], degree = Exponent[ode, z]; , degree = "undefined" ]; degree ]

And now

data = {First[#], getMaxOrder[First[#], y, x], getDegree[First[#], y, x]} & /@ test2;
PrependTo[data, {"ode", "order", "degree"}];
Grid[data, Frame -> All]

Mathematica graphics

The table test2 can be found in the above wiki post.

Nasser
  • 143,286
  • 11
  • 154
  • 359
1

Sort of a hack is to make a string out of the full form and then extract the order of the derivatives and finally convert it back to an expression and taking the max. Here is an example:

getDeg[ex_] := Module[{str},
  str = ToString[FullForm@ex]; Print[str];
  str = StringCases[str, 
    RegularExpression["Derivative\\[(\\d,*\\s*\\d*)\\]"] :> 
     StringReplace["$1", "," -> "+"]];
  Max[Total @@@ ToExpression /@ str]
  ]

Now, as already mentioned, your examples give wrong degrees. With the above we get:

getDeg[eq1]   
3

getDeg[eq2] 2

getDeg[eq3] 2

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57
  • 2
    Thanks for your interest. But I think you find the order, not the degree. When I test your code using the differential equations given in @Nasser 's answer, the results are wrong. – RF_1 Feb 22 '23 at 13:22
  • I determine the highest derivative of the function. – Daniel Huber Feb 22 '23 at 15:18
  • 1
    To find max derivative, I think using pattern might be better. I will post the small code I use for this in the above wiki post in case you are interested in it. – Nasser Feb 22 '23 at 16:17