1.2 Detect general Riccati ode \(y'=f_0(x) + f_1(x) y(x)+ f_2(x) y^2\)

This detects the general Riccati ode \(y'=f_0(x) + f_1(x) y(x)+ f_2(x) y^2\)

The input to the proc is the ode and the dependent function \(y(x)\). The parsing function will return \(f_0,f_1,f_2\) if successful match is found, or FAIL if ode does not match the expected pattern.

\(f_0,f_2\) can not be zero (i.e. missing), but \(f_1\) could be missing.

In the case \(f_1=0\), either \(f_0\) or \(f_2\) or both must be functions of \(x\). Also in the case of \(f_1=0\), if it is reduced Riccati, then it return FAIL.

In the case \(f_1\) is present and also depends on \(x\), then now \(f_0,f_2\) are both allowed not to be functions of \(x\). But if \(f_1\) present and also does not depend on \(x\), then now at least one of \(f_0,f_2\) must be function of \(x\).

general_riccati_parse:=proc(ode::`=`,func::function(name),$) 
local RHS; 
local y:=op(0,func); 
local x:=op(1,func); 
local stat; 
local la,f0,f1,f2; 
 
   stat:= reduced_riccati_parse(ode,func); 
   if stat<>FAIL then #this is reduced riccati, hence not general 
      RETURN(FAIL); 
   fi; 
 
   #now check if general riccati 
   try 
      RHS:=timelimit(30,[solve(ode,diff(y(x),x))]); 
      if nops(RHS)<>1 then RETURN(FAIL); fi; 
      RHS:=expand(RHS[1]); 
      RHS:=collect(RHS,[y(x),y(x)^2]);#must collect to insure the right form 
   catch: 
      RETURN(FAIL); 
   end try; 
 
   if patmatch(RHS,f0::anything+f1::anything*y(x)+f2::anything*y(x)^2,'la') then 
      assign(la); 
      if f0=0 or f2=0 then RETURN(FAIL); fi; 
      if has(f0,y(x)) or has(f1,y(x)) or has(f2,y(x)) then RETURN(FAIL); fi; 
 
      if has(f1,x) then 
         RETURN(f0,f1,f2); 
      else 
         if not has(f0,x) and not has(f2,x) then 
            RETURN(FAIL); 
         else 
            RETURN(f0,f1,f2); 
         fi; 
      fi; 
   else #check for f1 missing 
      if patmatch(RHS,f0::anything+f2::anything*y(x)^2,'la') then 
         assign(la); 
         if has(f0,y(x)) or has(f2,y(x)) then RETURN(FAIL); fi; 
         if not has(f0,x) and not has(f2,x) then RETURN(FAIL); fi; 
         RETURN(f0,0,f2); 
      else 
         RETURN(FAIL); 
      fi; 
   fi; 
 
end proc:
 

Example usage

ode:=diff(y(x),x)=f0(x)+f1*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                         f0(x), f1, f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0+f1(x)*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                         f0, f1(x), f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f1(x)*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                        f0(x), f1(x), f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f1(x)*y(x)+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                      f0(x), f1(x), f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                        f0(x), 0, f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=x+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                          x, 0, f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=x+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                              FAIL 
                     [[_Riccati, _special]] 
 
ode:=diff(y(x),x)=1/x+y(x)+y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                            1 
                            -, 1, 1 
                            x 
                     [_rational, _Riccati] 
 
ode:=diff(y(x),x)=1/x+y(x)+x*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                            1 
                            -, 1, x 
                            x 
                     [_rational, _Riccati] 
 
ode:=diff(y(x),x)=x*y(x)+c*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                              FAIL 
                          [_Bernoulli] 
 
ode:=diff(y(x),x)=x-1+y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                          -1 + x, 0, 1 
                           [_Riccati] 
 
ode:=diff(y(x),x)=(3+9*x+8*y(x))^(2): #this ode needs the collect 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
              81*x^2 + 54*x + 9, 144*x + 48, 64 
              [[_homogeneous, class C], _Riccati]