Another way, using Henric's substitution to get an autonomous DE. The DE being first order, this reduces the solution to quadrature:
$$u'=f(u) \wedge u(x_0)=u_0 \Longrightarrow \int_{u_0} {du \over f(u)} = \int_{x_0} dx \,.$$
The use of the assumption assum
in a couple of steps is crucial to obtain valid and only valid solutions.
sub = y[x] == (u[x] - 7 x - 4)/4;
assum = 4 + 7 x + 4 y[x] < 0;
uode = DSolveChangeVariables[Inactive[DSolve][ode, y[x], x], u, x, sub] // Simplify
uprime = First@Solve[First[uode], u'[x]]
implsol = Assuming[Reduce[assum /. First@Solve[sub, y[x]], u[x]],
Integrate[1/u'[x] /. uprime /. u[x] -> u
, {u, First@SolveValues[sub /. {y[x] -> -1, x -> -1}, u[-1]], u[x]}
, Assumptions -> $Assumptions] == Integrate[1, {x, -1, x}]
]
implsol = implsol /. First@Solve[sub, u[x]] // FullSimplify
Block[{Simplify = FullSimplify},
ysols = Solve[implsol, y[x], Method -> Reduce, Assumptions -> assum]]
{ode, ic} /. DSolve`DSolveToPureFunction[ysols] //
FullSimplify[#
, Reduce[assum /. ysols // Normal, x, Reals]
, TransformationFunctions -> {Automatic
, ReplaceAll[eq_Equal :> FullSimplify[ApplySides[Exp, eq]]]}] &
The use of assum
, Reduce
, ApplySides
, and FullSimplify
above suggest the robustness required by the system to solve the problem needed some special tricks to be able to handle ProductLog
in a careful and correct way. From the beginning, I thought Mathematica was meant, not to solve every problem for us, but to be a powerful computation tool to use in our problem solving. We seem to be in that realm here.
However, below is a way to derive the assumption from the domain of the ODE, a somewhat natural thing to try, and, in this case, to derive the substitution:
assum = LogicalExpand@Reduce[
FunctionDomain[y'[x] /. Solve[ode, y'[x]], {x, y[x]}] /.
Unequal -> Function[{x, y}, x < y || x > y],
{x, y[x]}, Reals] //
Replace[#,
intervals_Or :> Pick[intervals, List @@ intervals /. icToRules[ic, y[x]]]] &
sub = Reduce[u[x] == Subtract @@ assum, y[x]]
Also, I've known for a while that DSolve
generally works by antidifferentiation, putting off the boundary conditions to the end. Antidifferentiation is easiest (or at least faster) than definite integration. So if the ode can be transformed into a form that is solvable by quadrature, as above, we can put the burden of the initial condition on Integrate
, which will work hard, and sometimes long, to integrate from the condition
$(x_0,y(x_0))$ to a general
$(x,y(x))$, making sure the right branch cuts are followed. That is not the problem here. The problem is not in integrating the ODE; rather, it's in solving the implicit solution. In an intro diff. eq. class, we usually accept the implicit solution, when solving it requires special functions. In our case at hand, we need not use Integrate
. We can use DSolve
. We can get the same implsol
as above using DSolve
to solve for x[u]
instead of for u[x]
:
xode = First@uode /. {u'[x] -> 1/x'[u], u[x] -> u, x -> x[u]}
implsol = First@First@DSolve[
{xode, x[-7] == -1}, x[u], u,
Assumptions -> assum /. First@Solve[sub, y[x]] /. u[x] -> u
] /. {x[u] -> x, u -> u[x], Rule -> Equal};
implsol = implsol /. First@Solve[sub, u[x]] // FullSimplify