3.14 How to check if single ODE is valid?

This is very much the same as above, but this function returns True if the ode is syntactically valid, else false. Can be used just to check if the ode is valid before using it.

It takes in the ode and the function \(y(x)\) and returns either true or false.

#March 15, 2024 
 
export is_valid_single_ode :=proc(ode_in::`=`,func::function(name))::truefalse; 
    local x:=op(1,func),y:=op(0,func); 
    local ode:=ode_in; 
    local dep_variables_found::list; 
    local item; 
 
    if nops(func)<>1 then RETURN(false); fi; 
 
    if not has(ode,diff) then ode:=convert(ode,diff); fi; 
 
    if `or`(not has(ode,diff), not has(ode,x), not has(ode,func))  then 
       RETURN(false); 
    fi; 
 
    try 
        dep_variables_found := PDEtools:-Library:-GetDepVars([y],ode); 
    catch: 
       RETURN(false); 
    end try; 
 
    map( X-> `if`( `or`(not type(X,function), op(1,X) <> x) ,RETURN(false),NULL), 
       dep_variables_found 
    ); 
 
    #check there is no y on its own. Should always be y(x) 
    if nops(indets(ode,identical(y))) <> 0 then 
       RETURN(false); 
    fi; 
 
    RETURN(true); 
end proc:
 

Example usages

 
is_valid_single_ode(diff(y(x),x)+sin(x)=0, y(x) ) 
 
       true
 

To test, do

 
L:=[[3*(D@@2)(y)(x)+diff(y(x),x)+1=sin(x),y(x),true], 
                 [diff(y(x),x)^2=z,y(x),true], 
                 [diff(y(x),x)^2=z,y(x),true], 
                 [diff(y(x),x)^2=y(x)^2,y(x),true], 
                 [diff(y(x),x)=y(z)^2,y(x),false], 
                 [1/diff(y(x),x)=y(x)^2,y(x),true], 
                 [y(x)=1,y(x),false], 
                 [diff(y(x),z)=1,y(x),false], 
                 [D(y)(x)=1,y(x),true], 
                 [(D@@2)(y)(x)+diff(y(x),x)=sin(x),y(x),true], 
                 [diff(y(x),x)+diff(y(z),z)=1,y(x),false], 
                 [diff(y(x),x)+diff(g(z),z)=1,y(x),true] 
                 ]: 
 
map(X->evalb(is_valid_single_ode(X[1],X[2])=X[3]),L); 
if andmap(x->evalb(x=true),%) then 
   print("all tests passed"); 
else 
   print("WARNING, not all tests passed"); 
fi; 
 
#gives 
 
 [true, true, true, true, true, true, true, true, true, true, true, true] 
                       "all tests passed"