6
$\begingroup$

Is there a program or built-in function that automatically separates variables for separable ODE?

Note: The separable ODE referred to in this question is after variable substitution. Therefore, I hope that mma can automatically check the given ODE and complete the variable substitution, and separate the separable ODE variables.

Example 1, making a substitution to transform the differential equation

$$ \frac{\mathrm{d} y}{\mathrm{~d} x}=\frac{x-y+1}{x+y-3} $$.

into

$$ \frac{\mathrm{d} X}{X}=\frac{1+u}{1-2 u-u^2} \mathrm{~d} u $$

Where,

$$ \left\{\begin{array}{l}X=x-1 \\ Y=y-2\end{array}\right. $$

$$ u=\frac{Y}{X} $$

Example 2, making a substitution to transform the differential equation

$$ \frac{\mathrm{d} y}{\mathrm{~d} x}=(x+y)^2 $$

into

$$ \frac{\mathrm{d} u}{\mathrm{~d} x}=1+u^2 $$

Where

$$ u=x+y $$

I would like to ask if there is a general program or built-in function that can automatically perform this task, rather than a specific program for these two ODEs.

Thanks in advance!

$\endgroup$
8
  • $\begingroup$ These DEs are not separable. They can be transformed to separable ones. It should be possible to separate separable ones. I think finding transformations is difficult. DSolve probably does it sometimes, although it might choose a different solution method in other cases. $\endgroup$ Commented Aug 16, 2024 at 13:47
  • 1
    $\begingroup$ For instance, DSolve`DSolveFirstOrderODEDump`SeparateVariables[(1 + x - y)/(-3 + x + y), x, y] returns failed, but DSolve`DSolveFirstOrderODEDump`SeparateVariables[(1 + x - y)/(-3 + x + y) /. {x -> (x + y)/Sqrt[2], y -> (x - y)/Sqrt[2]}, x, y] succeeds. $\endgroup$ Commented Aug 16, 2024 at 13:59
  • $\begingroup$ see how-to-determine-if-rhs-of-first-order-ode-is-separable-or-linear-or-neither-pa and Leonid Shifrin answer how-can-i-separate-a-separable-function But I found some cases where these do not detect. So I have added 60 more patterns in my own ode solver as extra checks. But the above should do it for most common separable ode's. btw, your odes are not separable. $\endgroup$ Commented Aug 16, 2024 at 15:43
  • 1
    $\begingroup$ automatically separates variables for separable ODE? may be there is different convention you are using for separable ode. For me, a separable ode is $y'=F(x,y)$ which can be written as $y'=f(x) g(y)$ and the goal then is to find if $F(x,y)=f(x) g(y)$ and ofcourse to find $f(x),g(y)$. The above linked to answer does that. But as I said, there are few edge cases it might not work for. But for most common odes', it works fine. $\endgroup$ Commented Aug 16, 2024 at 16:55
  • $\begingroup$ Thank you for your very valuable comments, and I ' ll take the time to study what you mentioned. For separable ODE, what I describe is not accurate enough and has been updated. $\endgroup$ Commented Aug 16, 2024 at 23:27

1 Answer 1

8
$\begingroup$

The second example

The following transforms any ode of the form $y'= (a x + b y + c)^{\frac{n}{m}}$ into separable ode $u'=a+b u^{\frac{n}{m}}$

enter image description here

Currently, this aborts if unable to do the transformation. Future version can be made more user friendly :)

Code

match[rhs_, y_Symbol, x_Symbol, u_Symbol] := Module[{a, b, c, n, e}, If[Not[MatchQ[rhs, e_.*(a_.*x + b_.*y + c_.)^n_]], Abort[]]; {e, a, b, c, n} = rhs /. e_.*(a_.*x + b_.*y + c_.)^n_ :> {e, a, b, c, n}; D[u[x], x] == e*(b*u[x]^n + a) ] makeSeparable[ode_Equal, y_[x_], u_[x_]] := Module[{rhs}, rhs = SolveValues[ode, D[y[x], x]]; If[Length[rhs] == 0, Abort[]]; rhs = Simplify[rhs]; rhs = rhs /. y[x] -> y; Map[match[#, y, x, u] &, rhs] ] 

Test

testCases = {y'[x] == (a*x + b*y[x] + c)^(n/m), y'[x] == (x + y[x])^2, x == y[x] - y'[x]^3, y'[x]^2 == x - y[x], y'[x]^3 + x - y[x] == 0, y'[x] == (x + y[x] + 3)^2, y'[x] == (x + y[x] + 99)^(3/2), y'[x] == (5*x + 9*y[x])^5} Grid[{#, makeSeparable[#, y[x], u[x]]} & /@ testCases, Frame -> All] 

The first example

This is called homogeneous ode of class C and can be transformed to separable also using general algorithm if it is possible to find the mapping X,Y.

The following transforms $y'= \frac{a_0 x + b_0 y + c_0}{a_1 x + b_1 y + c_1} $ to separable. Little error checking is done.

enter image description here

Code

findTransformation[ode_Equal, y_Symbol, x_Symbol, fx_, fy_, u_Symbol, X_Symbol, Y_Symbol] := Module[{x0, y0, e, newODE, rhs, eq, sol}, newODE = DSolveChangeVariables[Inactive[DSolve] [ode, y[x], x], Y[X], X, {x == X + x0, y[x] == Y[X] + y0}]; newODE = newODE[[1]]; rhs = SolveValues[newODE, D[Y[X], X]]; If[Length[rhs] > 1, Abort[], rhs = Normal@First@rhs]; rhs = Normal[rhs /. Y[X] -> Y]; eq = 1 == -(X*D[rhs, X])/(Y*D[rhs, Y]); sol = SolveAlways[eq, {X, Y}]; (*solve for x0,y0*) newODE = newODE /. sol; newODE = DSolveChangeVariables[Inactive[DSolve] [newODE, Y[X], X], u[X], X, Y[X] == u[X]*X]; Solve[newODE[[1]], u'[X]] ] homogCToSep[ode_Equal, y_, x_, u_, X_, Y_] := Module[{e, rhs, z, fx, fy}, e = Map[Not@FreeQ[ode, #] &, {Abs, Piecewise}]; If[AnyTrue[e, # == True &], Abort[]]; rhs = SolveValues[ode, D[y[x], x]]; If[Length[rhs] > 1, Abort[], rhs = Normal@First@rhs]; rhs = Normal[rhs /. y[x] -> y]; fx = Normal[D[rhs, x]]; If[fx == 0, Abort[]]; fy = Normal[D[rhs, y]]; If[fy == 0, Abort[]]; findTransformation[ode, y, x, fx, fy, u, X, Y] ] 

Test

testCases = {y'[x] == (x - y[x] + 1)/(x + y[x] - 3), x^2*y'[x] == (1 + 2*x - y[x])^2, (x - a)^2*y'[x] + k*(x + y[x] - a)^2 + y[x]^2 == 0, (1 + y[x])*y'[x] == x + y[x], (1 + x + y[x])*y'[x] + 1 + 4*x + 3*y[x] == 0, y'[x] == (1 + x - 3*y[x])/(3 - x - y[x]), y'[x] == (11 - 4*x + 3*y[x])/(3 - x + y[x]), y'[x] == (-5 - x + 2*y[x])/(4 + 2*x - y[x]), (1 - 3*x + y[x])* y'[x] == 2*x - 2*y[x], (a + b + x + y[x])^2*y'[x] == 2*(a + y[x])^2, (1 - 3*x - y[x])^2* y'[x] == (1 - 2*y[x])*(3 - 6*x - 4*y[x])} Grid[{#, homogCToSep[#, y, x, u, X, Y]} & /@ testCases, Frame -> All] 

how can I output the expressions for u, X, and Y

This version returns the $X,Y$ mapping found, To obtain $u$, the newODE needs to be solved. Here is modified version of the above for the First example which now returns the $u$ ode in form that can be solve by DSolve and also returns X,Y

Version 8/17/2024

To answer comment

how can I output the expressions for u, X, and Y

findTransformation[ode_Equal,y_Symbol,x_Symbol,fx_,fy_,u_Symbol,X_Symbol,Y_Symbol]:=Module[{x0,y0,e,newODE,rhs,eq,sol},newODE=DSolveChangeVariables[Inactive[DSolve][ode,y[x],x],Y[X],X,{x==X+x0,y[x]==Y[X]+y0}]; newODE=newODE[[1]]; rhs=SolveValues[newODE,D[Y[X],X]]; If[Length[rhs]>1,Abort[],rhs=Normal@First@rhs]; rhs=Normal[rhs/. Y[X]->Y]; eq=1==-(X*D[rhs,X])/(Y*D[rhs,Y]); sol=SolveAlways[eq,{X,Y}];(*solve for x0,y0*) newODE=newODE/. sol; newODE=DSolveChangeVariables[Inactive[DSolve][newODE,Y[X],X],u[X],X,Y[X]==u[X]*X]; {First@newODE[[1]],{x==X+x0,y[x]==Y[X]+y0}/.sol} ] 

To use do

ode = y'[x] == (x - y[x] + 1)/(x + y[x] - 3); {newODE, transformation} = homogCToSep[ode, y, x, u, X, Y] 

enter image description here

To find $u$ then do

 DSolve[newODE, u[X], X] 

enter image description here

To find $y(x)$ which is the solution to original ode, we just need to reverse the transformation done, which is just algebraic operation now. This is not shown since question asked just to convert the ode to separable but this is easy to do if you want to add it to your own code.

See Y[X] == u[X]*X for the relation. Then knowing $X,Y$ we now find $y(x)$ given $u$.

$\endgroup$
7
  • $\begingroup$ Great job! It solves the two main forms of ODEs with substitutable and separable variables and is highly generalizable. Thank you! $\endgroup$ Commented Aug 18, 2024 at 0:18
  • $\begingroup$ By the way, how can I output the expressions for u, X, and Y for each ODE substitution? $\endgroup$ Commented Aug 18, 2024 at 1:08
  • 1
    $\begingroup$ @lotus2019 added version of findTransformation which now also returns the $X,Y$ mapping used to obtain the $U[X]$ ode. To find $U[X]$, need to solve this separable ode ofcourse. $\endgroup$ Commented Aug 18, 2024 at 4:55
  • $\begingroup$ I have a question: I want u in Example 1 to be a function of both x and y, but the code gives u as a function of only x. I would like the variable substitution to be: $$ u=\frac{Y}{X}=\frac{y-2}{x-1} $$Is it possible to achieve this? Thank you! $\endgroup$ Commented Aug 18, 2024 at 23:35
  • $\begingroup$ @lotus2019 Yes, but this part is not automated. But since we know that $u=\frac{Y}{X}$ and $X,Y$ are now returned back, then all what is needed is to do eq=u==Y/X; eq/.{X->x-1,Y->y-2} which gives $$ u=\frac{y-2}{x-1} $$ you could modify the code to return the mapping $X,Y$ as rules instead to make this easier to do. But everything you need is there now. If you are writing a full ode solver for this, then these things ofcourse have to be done by your functions internally. But the hard part is in finding $X,Y$ if possible, and the rest is just manipulation of symbols. $\endgroup$ Commented Aug 19, 2024 at 2:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.