First: Getting the right solution
Using Internal`WithLocalSettings
to set the Method -> Reduce
option on Solve
, and adding the assumption x ∈ Reals
, we get the correct answer:
sys = {y'[x] == (1 + 2 x) Sqrt[y[x]], y[0] == 1};
With[{opts = Options[Solve]},
Internal`WithLocalSettings[
SetOptions[Solve, Method -> Reduce],
s = Assuming[x ∈ Reals,
y -> Function @@ {x, y[x] /. #} & /@ (* turn the expression into a Function *)
Simplify@DSolve[sys, y[x], x] (* Simplify the solution *)
],
SetOptions[Solve, opts]
]]
sys /. s // Simplify[#, x ∈ Reals] &
> Solve::useq: The answer found by Solve contains equational condition(s) {0==1/2 (x+x^2+Reduce`ReduceVar[2]-Sqrt[Plus[<<3>>]^2])}. A likely reason for this is that the solution set depends on branch cuts of Wolfram Language functions. >>
(*
{y -> Function[x, 1/4 (2 + x + x^2)^2]}
{True, True}
*)
Without the assumption x ∈ Reals
, we also get the right answer but in a less convenient form, with an unsimplified ConditionalExpression
alluded to in the warning message:
{y -> Function[x,
ConditionalExpression[1/4 (2 + x + x^2)^2, Sqrt[(2 + x + x^2)^2] == 2 + x + x^2]]}
Note: I prefer the Function
form of the solution s
because the derivative(s) in a differential equation sys
are automatically computed in sys /. s
. This seems convenient to me.
Second: What DSolve
is doing
I think DSolve
is doing what one normally does. It solves for the general solution and then solves the initial condition for the constant of integration. The problem is that it carries the general solution a little too far, which Chip Hurst remarked on.
s = DSolve[{y'[x] == (1 + 2 x) Sqrt[y[x]]}, y, x]
(* {{y -> Function[{x}, 1/4 (x^2 + 2 x^3 + x^4 + 2 x C[1] + 2 x^2 C[1] + C[1]^2)]}} *)
Solve[y[0] == 1 /. s, C[1]]
(* {{C[1] -> -2}, {C[1] -> 2}} *)
Note the C[1]^2
in s
. One problem at this stage is that one cannot determine which value of C[1]
is correct from the initial condition alone. You have to go back and check the ODE. So Method -> Reduce
is ineffective at this step:
Solve[y[0] == 1 /. s, C[1], Method -> Reduce]
(* {{C[1] -> -2}, {C[1] -> 2}} *)
Apparently DSolve
does not go back and check. I suppose there are reasons for this "laziness." It might take an unknown and long time to verify a potentially complicated solution, for instance. But that could be handled with TimeConstrained
and a warning message on time-out.
One can implement this strategy oneself, with or without TimeConstrained
, as follows:
s = DSolve[{y'[x] == (1 + 2 x) Sqrt[y[x]], y[0] == 1}, y, x];
Pick[s, TrueQ /@ And @@@ Simplify[sys /. s, x ∈ Reals]]
(* {{y -> Function[{x}, 1/4 (4 + 4 x + 5 x^2 + 2 x^3 + x^4)]}} *)
y[0]==1
but satisfies the differential equation only whenx <= -2 || x >= 1
. [that's the condition that allows simplifying\Sqrt[(-2 + x + x^2)^2)
to-2 + x + x^2
.] $\endgroup$