2
$\begingroup$

I'm trying to come up with a pattern or just implement a function DifferentialEquationQ so I can have another function assume different behaviour when it's input is a differential equation

MyFunction[x_?DifferentialEquationQ]:=...

My first attempt is to go

DifferentialEquationQ[x_]:=StringContainsQ[#, "=="] && StringContainsQ[#, "Derivative"] &[ToString[InputForm[x]]]

I really don't like this solution because I know there's certainly a better way plus maybe I can learn something new by posting. Also, I would ideally like to parameterize DifferentialEquationQ with an independent and dependant variable. So DifferentialEquationQ[y,t][ode_] would match any ode of $y(t)$.

Thanks

$\endgroup$
2
$\begingroup$

A quick and dirty attempt. Let me know if there is a bug somewhere. All bugs are fixed in the order they are recieved.


Mathematica graphics

code

The function getPatterns thanks to Carl Woll, see Using Cases and when to make input a list or not

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

The parser

(* Basic Parsing function *)
(*version alpha 1.01 Released . on April 27, 2020 at 9:38 PM*)
checkIfValidODE[odeInput_, y_[arg_], x_] := 
 Module[{ode, lhs, rhs, order, tmp, tmp0, tmp00, maxOrder, n, z, 
   independentVariables, xx, yy},

  If[Not[SameQ[arg, x]],
   Return[
    Row[{"Argument of dependent variable ", y, 
      " is not what is expected."}], Module]
   ];

  If[Not[SameQ[Head[odeInput], Equal]],
   Return[Row[{"Expected equation as input but found ", odeInput}], 
    Module]
   ];

  tmp = getPatterns[odeInput, Derivative[n_][yy_][xx_]];
  If[Length@tmp == 0,
   Return[Row[{"No derivative found in ", odeInput}], Module]
   ];

  tmp0 = Cases[tmp, Derivative[n_][yy_][xx_] :> xx];
  tmp00 = getPatterns[tmp0, Derivative[n_][yy_][xx_]];

  If [Length@tmp00 > 0,
   Return[Row[{"Nested derivatives not allowed"}], Module]
   ];

  order = Cases[tmp, Derivative[n_][y][x] :> n];
  If[order === {},
   Return[Row[{"No ", y'[x], " found in the ODE ", odeInput}], Module]
   ];

  tmp = getPatterns[odeInput, y[xx_]];
  independentVariables = Union@Cases[tmp, y[xx_] :> xx];
  If [Length@independentVariables > 1,
   Return[Row[{"Unexpected argument for ", y , " found ", y[x]}], 
    Module]
   ];

  If[Length@independentVariables == 
     1 && (First@independentVariables) =!=  x,
   Return[
    Row[{"Unexpected argument for", y , " found", independentVariables}], Module]
   ];

  Print["Input is valid ODE of order ", order]

  ]

Test code

checkIfValidODE[y'[y'[x]] == x^3, y[x], x]
checkIfValidODE[y''[x] == z, y[x], x]
checkIfValidODE[y''[x], y[x], x]
checkIfValidODE[y''[x] == 0, y[x], x]
checkIfValidODE[y''[x] == 0, y[z], x]
checkIfValidODE[y''[x] == 0, y[x], z]
checkIfValidODE[y[x] == 0, y[x], x]
checkIfValidODE[y''[x] == 0, y[x], y]
checkIfValidODE[y''[x] == Tan[y[x]], y[x], x]
checkIfValidODE[y''[x] == Tan[y[z]], y[x], x]
checkIfValidODE[1/y''[x] == Tan[y[x]], y[x], x]
checkIfValidODE[1/y''[x] == x^3, y[x], x]
checkIfValidODE[y[x] == x^3, y[x], x]
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.