Group Abstract Group Abstract

Message Boards Message Boards

DSolve crashes on elementary differential equations

Dear Community,
About two years ago I sent a bug report about DSolve to Support and here on Community.
It was for y'(x)=sqrt(y(x)). (which at the time returned 2 solutions)
No one at Support or here admitted there was a bug in DSolve...
But incindently the bug was corrected in the next release.
Now have a look on the notebook and watch DSolve crash on 2 elementary DE.
I sent only two examples of the bug but there are many...
ALL the DSolve functions should be greatly improved.
After all this is 14.2.1.
Kind regards,
Jean-Michel

Attachments:
3 Replies

It's not clear that there is anything you want to discuss, and you certainly don't ask any questions. What I would like to see is a way for the user to request DSolve[] to work harder, in the way we can use Reduce[] instead of Solve[], or use MaxExtraConditions in Solve[]. I think there's great value in DSolve[] being quick and generic (okay, "quick" as a design goal, even if it sometimes takes forever). But it's also the case the Mathematica can give a more robust solution in some cases, if the user is willing to let Mathematica perform operations that risk being computationally intensive.

For instance DSolve[{y'[x] == Sin[y[x]], y[0] == y0}, y, x] returns only two one-parameter families of solutions. But the ODE y'[x] == Sin[y[x]] admits the symmetries generated by {{y -> -y}, {y -> Pi-y}, {x -> x+C[1]}}. So there are infinitely many one-parameter families of solutions.

For instance, the following hacky way culls the implicit solution before it's solved, so that we can get the complete solution, which DSolve[] does not do on its own:

ode = y'[x] == Sin[y[x]];
implSOL = Trace[
  DSolve[{ode, y[0] == y0}, y, x]
  , s : HoldPattern[Solve[_, y[x], ___]] :> 
          Return[Inactivate[s, Solve], Trace]
  , TraceInternal -> True]
dsol2 = Activate[implSOL] // DSolve`DSolveToPureFunction
ode /. % // FullSimplify
(*
Solve[-ArcTanh[Cos[y[x]]]\[Equal]x+C[1],y[x]]

{{y -> Function[{x},ConditionalExpression[-ArcCos[-Tanh[x+C[1]]]+2 \[Pi] C[2], <<>>]]},
 {y -> Function[{x},ConditionalExpression[ArcCos[-Tanh[x+C[1]]]+2 \[Pi] C[2],<<>>]]}}

{ConditionalExpression[True,<<>>], ConditionalExpression[True,<<>>]}
*)

If we add assumptions that only a single one-parameter family satisfies, DSolve[y'[x] == Sin[y[x]], y, x, Assumptions -> 0 < y[x] < Pi && {x, C[1]} \[Element] Reals] still returns two families, one of which satisfies the assumptions. This does not bother me in one way, because I appreciate the difference between "if $P$ then $Q$" ( $P$ is an assumption) and "$P$ and $Q$" ( $P$ is a constraint). In another way, it bothers me that I can't add a constraint to the solution. So here is another hacky way in which we treat $Assumptions as constraints when Solve[] is called by DSolve[]:

Internal`InheritedBlock[{Solve},
 Unprotect[Solve];
 Solve[eq_, v_, opts___] /; ! TrueQ[$in] := 
  Block[{$in = True}, 
   Simplify@Solve[Flatten@{eq, $Assumptions}, v, opts]];
 Protect[Solve];
 DSolve[y'[x] == Sin[y[x]], y, x, 
  Assumptions -> 0 < y[x] < Pi && {x, C[1]} \[Element] Reals]]

(*  {{y -> Function[{x}, ArcCos[-Tanh[x + C[1]]]]}}  *)

There is no problem, theoretically, solving any IVP for this ODE. But DSolve[] fails if the initial condition cannot be satisfied by one of the two one-parameter familiar in its "general solution":

DSolve[{y'[x] == Sin[y[x]], y[0] == 3 Pi/2}, y, x, 
 Assumptions -> 0 < y[x] < Pi && {x, C[1]} \[Element] Reals]

(* DSolve::bvnul, DSolve::ifun errors  *)
(*  {}  *)

But if I add constraints to Solve[] as above, then Solve[] will find the right branch of the general solution for the IVP:

Internal`InheritedBlock[{Solve},
 Unprotect[Solve];
 Solve[eq_, v_, opts___] /; ! TrueQ[$in] := 
  Block[{$in = True}, 
   Simplify@Solve[Flatten@{eq, $Assumptions}, v, opts]];
 Protect[Solve];
 DSolve[{y'[x] == Sin[y[x]], y[0] == 3 Pi/2}, y, x, 
  Assumptions -> Pi < y[x] < 2 Pi && {x, C[1]} \[Element] Reals]]

(*  {{y -> Function[{x}, 2 \[Pi] - ArcCos[-Tanh[x]]]}}  *)

Indeed, we can find the general solution for this range of y, a solution that is not contained in the "general solution" returned by DSolve[{y'[x] == Sin[y[x]], y[0] == y0}, y, x]:

Internal`InheritedBlock[{Solve},
 Unprotect[Solve];
 Solve[eq_, v_, opts___] /; ! TrueQ[$in] := 
  Block[{$in = True}, 
   Simplify@Solve[Flatten@{eq, $Assumptions}, v, opts]];
 Protect[Solve];
 DSolve[y'[x] == Sin[y[x]], y, x, 
  Assumptions -> Pi < y[x] < 2 Pi && {x, C[1]} \[Element] Reals]]

(*  {{y -> Function[{x}, 2 \[Pi] - ArcCos[-Tanh[x + C[1]]]]}}  *)
POSTED BY: Updating Name

Is it really too much trouble to state the equations in the text of the message? And what exactly is crashing?

POSTED BY: Daniel Lichtblau

Maybe for such equations Mathematica would do better giving the implicit function version of the differential equations

Cos[y[x]] + Tanh[x + C[1]] == 0
Cosh[y[x]] + Tanh[x + C[1]] == 0

and leave it at that. Instead, it gives two partial solutions based on branches of the inverses of Cos and Cosh. I would not call this a bug, because a warning is generated about a possible loss of solutions.

POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard