1.4 Detect first order linear ode of form \(A(t) y'(t)+ B(t) y(t)=f(t)\)

And also find the values of \(A,B,f\) in the above. This can be used to parse first order ode after checking it is linear ode (linear in \(y'\) and \(y\)).

The parsing routing returns either FAIL or \(A,B,f\) if pattern is matched.

restart; 
linear_first_order_parse:=proc(ode::`=`,func::function(name),$) 
local y:=op(0,func); 
local x:=op(1,func); 
local LHS; 
local la,A,B,F; 
 
   LHS:= lhs(ode)-rhs(ode); 
   LHS:= numer(normal(LHS)); #this is needed to normalize the ode 
         #for example 1/y' + x = 0 will becomes 1+x y'  = 0, else 
         #the pattern will fail 
 
   #must collect on y and y' to get the pattern to work OK for all cases 
   LHS:= collect(LHS,diff(y(x),x)); 
   LHS:= collect(LHS,y(x)); 
 
   if patmatch(LHS,A::anything*diff(y(x),x)+B::anything*y(x)+F::anything,'la') then 
      assign(la); 
      if has(A,y(x)) then RETURN(FAIL); fi; 
      if has(B,y(x)) then RETURN(FAIL); fi; 
      if has(F,y(x)) then RETURN(FAIL); fi; 
      RETURN(A,B,F); 
   else 
      if patmatch(LHS,A::anything*diff(y(x),x)+F::anything,'la') then 
         assign(la); 
         if has(A,y(x)) then RETURN(FAIL); fi; 
         B:=0; 
         if has(F,y(x)) then RETURN(FAIL); fi; 
         RETURN(A,B,F); 
      else 
         RETURN(FAIL); 
      fi; 
   fi; 
end proc:
 

Notice that we had to check for the general case \(A y'+ B y + F\) first and if that fails then check for the specific case \(A y' + F \). This is because if \(y\) term is missing then Maple will not match the pattern. i.e. it will not give \(B=0\). So have to make separate pattern matching for the case with missing \(y\) in the ode.

For the case \(A y' + F\) Maple will match \(F=0\) if this term is missing. So we do not need to make more specialized pattern for just \(A y'\).

This is typical. We start with the most general pattern and if that fail, we go to more specialized ones.

Examples usages

ode:=1/diff(y(t),t)+t=0; 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
                            t, 0, 1 
 
                         [_quadrature] 
 
 
ode:=1/diff(y(t),t)+t=y(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
[[_homogeneous, class C], [_Abel, 2nd type, class C], _dAlembert] 
 
 
 
ode:=t*diff(y(t),t)+5=0; 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
                            t, 0, 5 
 
                         [_quadrature] 
 
ode:=t^2*diff(y(t),t)+t*y(t)=sin(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
 
                          2 
                         t , t, -sin(t) 
 
                           [_linear] 
 
ode:=y(t)*diff(y(t),t)+t*y(t)=sin(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
 
                  [[_Abel, 2nd type, class A]] 
 
ode:=sin(t)*diff(y(t),t)-99*ln(t)*y(t)=sin(t)+y(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
 
                 sin(t), -99 ln(t) - 1, -sin(t) 
 
                           [_linear] 
 
ode:=sin(t)*diff(y(t),t)-99*ln(t)*y(t)=sin(t)+9*diff(y(t),t)/t+ln(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
 
                      9 
             sin(t) - -, -99 ln(t), -ln(t) - sin(t) 
                      t 
 
                           [_linear] 
 
ode:=diff(y(t),t)-y(t)^2=sin(t); 
linear_first_order_parse(ode,y(t)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
 
                           [_Riccati]