3 Solve Clairaut's equation f(x*y'-y)=g(y')
7 Daniel Zwillinger, Handbook of Differential Equations, 3rd ed
8 Academic Press, (1997), pp 216-218
11 Copyright (C) 2004 David Billinghurst
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28 put('ode1_clairaut,001,'version)$
30 /* Attempt to separate expression exp into f(x)+g(y)
31 Returns [f(x),g(y)] is this is possible
33 Adapted from SEPARABLE() in ode2.mac */
35 plusseparable(eq,x,y) := block(
36 [u,xpart:[],ypart:[],flag:false,inflag:true],
38 if atom(eq) or not(inpart(eq,0)="+") then eq: [eq],
42 else if freeof(y,u) then
46 if flag = true then return(false),
47 if xpart = [] then xpart: 0 else xpart: apply("+",xpart),
48 if ypart = [] then ypart: 0 else ypart: apply("+",ypart),
52 /* If we can write eqn as f(x*y'-y)=g(y') then the solution
53 is given implicitly by f(x*%c-y)=g(%c)
55 A singular solution may exist
58 ode1_clairaut(eq,y,x) := block(
59 [ans,%c,de,%f,%g,%p,%r,_t,sep],
60 /* substitute %p=y', %r=x*y'-y */
61 de: expand(lhs(eq)-rhs(eq)),
62 de: subst(%p,'diff(y,x),de),
63 de: ratsimp(subst((%r+y)/%p,x,de)),
64 if not(freeof(x,y,de)) then (
65 ode_disp2(" Expression not free of x and y: ",de),
68 sep:plusseparable(de,%r,%p),
70 /* Perhaps de is const+f(%p)*%r */
71 sep:plusseparable(ratsimp(de/%r),%r,%p),
72 if is(sep#false) then (
77 ode_disp2(" Expression free of x and y but can't write as f(%r)=g(%p): ",de),
78 /* Don't give up yet */
80 if _t=[] then return(false),
81 ode_disp2(" Solving for %r: ",_t),
84 if not(freeof(%r,%g)) then return(false)
86 /* Next line added to avoid testsuite failures 2003-01-02
87 Guessed the fix and should analyse it further */
88 if ( is(%f=0) ) then return(false),
89 ode_disp2(" %f: ",%f),
90 ode_disp2(" %g: ",%g),
92 ans:subst(x*%c-y,%r,%f)=subst(%c,%p,%g),
93 /* Try and solve for y */
95 if length(_t)=0 then ans:[ans] else ans:_t,
96 ans:append(ans,ode1_clairaut_singular(eq,y,x)),
100 /* Is there a singular solution to Clairaut equation eq:f(x*p-y)-g(p)=0 ?
102 Differentiate eq wrt x to get 'diff(y,x,2)*eq2=0
103 If possible, eliminate 'diff(y,x) between eq and eq2.
104 else return parametric solution in variable %t
107 ode1_clairaut_singular(eq,y,x) := block(
113 remove(u,dependency),
114 expr:subst(y,u,expr),
116 eq2:ratsimp(ratcoeff(expr,'diff(y,x,2))),
117 if not(freeof('diff(y,x,2),eq2)) then return([]),
118 expr: ratsimp(expr-eq2*'diff(y,x,2)),
119 if not(is(expr=0)) then return([]),
120 /* Try and eliminate t */
121 eq:subst(%t,'diff(y,x),eq),
122 eq2:subst(%t,'diff(y,x),eq2),
123 ans:eliminate([eq,eq2],[%t]),
124 if ( not(freeof(%t,ans)) or (ans=1) ) then return([[eq=0,eq2=0]]),