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$

1 Answer 1

3
$\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] 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.