Checking an implicit function as a solution of a differential equation
One way is to solve for x and then follow the standard method
ode = x'[t] == (x[t] - 1) (1 - 2*x[t]);
myImplicitSolution = Log[(1 - 2 x)/(x - 1)] == t;
myExplicitSolution = x /. Solve[myImplicitSolution, x];
myExplicitSolution = x -> Function[{t}, Evaluate@myExplicitSolution];
Simplify[ode /. myExplicitSolution]
Here are a few ways that do not depend on being able to solve the implicit equation for the solution, based on differentiating the implicit equation. The key here is that the differentiated solution is linear in the derivative. Thus it can be used to eliminate the derivative from the ODE. If there is an initial condition, which is not given in the OP's example, it may be plugged into the solution and checked.
1.
Using Eliminate
reduces the ODE and differentiated solution to some measure-0 exceptions. These rule out conditions where the equations are undefined (due to division by zero or taking the logarithm of zero).
ode = x'[t] == (x[t] - 1) (1 - 2 x[t]);
implsol = Log[(2*x[t] - 1)/(x[t] - 1)] == t;
Eliminate[{ode, implsol}, {x'[t]}]
(* -1 + x[t] != 0 && -1 + 2 x[t] != 0 *)
2.
If we use Solve
, the solution should be generically true, which is indicated by the output being {{}}
.
Solve[{ode, implsol}, x[t], {x'[t]}]
Solve::fulldim: The solution set contains a full-dimensional component; use Reduce for complete solution information. >>
(* {{}} *)
3. Finally, we can rather straightforwardly solve the differentiated solution for the derivative and plug it into the ODE.
ode /. Solve[D[implsol, t], {x'[t]}] // Simplify
(* {True} *)
4.
As an alternative to (3), one can check whether the residual will simplify to zero. When you get a warning about inverse functions, branch cuts, and so forth, one might wish to check numerically as I did in DSolve for Second Order Differential to eliminate one of the solutions returned by DSolve
. That involves plugging into the residual random numbers for any parameters, the independent variable, and the dependent variable(s) and their derivatives. For a solution to the ODE, one should expect errors on the order of round-off error. In the present case, the residual simplifies symbolically to zero, which needs no numerical checking:
residual[a_ == b_] := a - b;
residual@ode /. Solve[D[implsol, t], {x'[t]}] // Simplify
(* {0} *)
If it simplifies to a function, one might try FullSimplify
or substituting random values for the independent variable t
. It is possible in some cases that due to branch cuts, the solution is invalid only on some interval, which would probably prevent the expression from simplifying down to 0
.
More examples
This ODE is from the docs for DSolve
, and DSolve
returns an implicit solution in terms of Solve
.
ode = y'[x] == y[x]^3 - ((x + 1) y[x]^2)/x;
dsol = DSolve[ode, y[x], x]
implsol = First@dsol (* should check that dsol is of the form Solve[..] *)
(*
Solve[E^(-x + 1/y[x])/x + C[1] + ExpIntegralEi[-x + 1/y[x]] == 0, y[x]]
E^(-x + 1/y[x])/x + C[1] + ExpIntegralEi[-x + 1/y[x]] == 0
*)
Methods 1-3:
Eliminate[{ode, D[implsol, x]}, y'[x]]
Solve[{ode, D[implsol, x]}, y[x], {y'[x]}]
ode /. Solve[D[implsol, x], {y'[x]}] // Simplify
(*
x != 0 && y[x] != 0 && -1 + x y[x] != 0 (* 1 *)
{{}} (* 2 *)
{True} (* 3 *)
*)
Here is another example from Solution of an ODE in implicit form:
ode = (y[x] + x - 1)*y'[x] - y[x] + 2 x + 3 == 0;
DSolve[ode, y[x], x];
implsol = First@%;
Eliminate[{ode, D[implsol, x]}, y'[x]]
Solve[{ode, D[implsol, x]}, y[x], {y'[x]}]
ode /. Solve[D[implsol, x], {y'[x]}] // Simplify
(*
11 + 8 x + 6 x^2 - 10 y[x] + 3 y[x]^2 != 0
*)
Solve::fulldim: The solution set contains a full-dimensional component; use Reduce for complete solution information.
(*
{{}}
{True}
*)