# DSolve Solutions are sometimes not as simple as they could be

Why doesn't DSolve output a solution in a nice format?

DSolve[y'[x] == (x + y[x] + 3)^2, y[x], x]

{{y[x] -> (-3 - I) - x + 1/(-(I/2) + E^(2 I x) C[1])}}


Ugh!

Maple gives the correct answer of $y(x) = \tan(x - C) - x - 3$ with no hassle or imaginary terms.

• That's what Simplify[]/FullSimplify[] is intended for. – J. M. will be back soon May 21 '17 at 4:02
• The algorithms used in Mathematica generally operate in the complex plane and the results provided are the ones that come naturally from those algorithms. C[1]  is an arbitrary complex constant. Arbitrarily, let C[1] == -1/2 I Exp[-2 I k] – Bob Hanlon May 21 '17 at 4:53
• @J.M. but neither will actually simplify this particular solution. – A.G. Nov 13 '17 at 1:03

First, let dsol denote the Mathematica solution:

dsol = First@DSolve[y'[x] == (x + y[x] + 3)^2, y, x];
y[x] /. dsol
(* (-3 - I) - x + 1/(-(I/2) + E^(2 I x) C[1])  *)


Note that y[x] -> (-3 + I) - x is an "obvious" solution, if you happen to go looking for one with a constant derivative y'[x], and it is not contained in the form returned by Maple, except as the limit at $-i\,\infty$:

Limit[Tan[x - C[2]] - x - 3, C[2] -> -I * Infinity]
(*  (-3 + I) - x  *)


In the Mathematica solution above, it corresponds to C[1] -> 0. Quite simple. OTOH, I get the impression that some folks don't care for complex solutions, even when they're simple. :)

Another obvious solution, y[x] -> (-3 - I) - x can only be obtained from both the Maple and Mathematica solutions as a limit:

Limit[(-3 - I) - x + 1/(-(I/2) + E^(2 I x) C[1]), C[1] -> Infinity]
Limit[Tan[x - C[2]] - x - 3, C[2] -> I * Infinity]
(*  both: (-3 - I) - x  *)


However, the simpler nature of the Mathematica solution allows the projectivization of the constant C[1] -> C[1]/C[2]. Then limits are not needed, but two constants have to be injected to get a particular solution.

projsol = y[x] /. dsol /. C[1] -> C[1]/C[2] // Together // Apart
(*  (-3 - I) - x + (2 C[2])/(2 E^(2 I x) C[1] - I C[2])  *)

projsol /. {C[1] -> 0, C[2] -> 1}
projsol /. {C[1] -> 1, C[2] -> 0}
(*
(-3 + I) - x
(-3 - I) - x
*)


This is not so easy to do in the Maple solution, because it is trapped inside Tan[]. You get divide-by-zero errors if you try the straightforward method.

Interestingly, if we precondition the problem with a simple and obvious substitution, we get the Maple answer. So I guess it isn't like Mathematica "thinks" the above method is better.

toPureFunction[sol_, y_] := sol /. HoldPattern[y[x_] -> body_] :> y -> Function[{x}, body];

sub = toPureFunction[First@Solve[u[x] == x + y[x] + 3, y[x]], y];
y'[x] == (x + y[x] + 3)^2 /. sub
usol = DSolve[y'[x] == (x + y[x] + 3)^2 /. sub, u, x]
y[x] -> (y[x] /. sub) /. usol
(*
-1 + u'[x] == u[x]^2                    - transformed ODE
{{u -> Function[{x}, Tan[x + C[1]]]}}   - solution of transformed ODE
{y[x] -> -3 - x + Tan[x + C[1]]}        - back-sub.; sol. of orig. ODE
*)


You can verify the solution is valid as follows

ode = y'[x] == (x + y[x] + 3)^2;
sol = DSolve[ode, y, x]


 ode/.sol//Simplify


As to why different CAS give different looking answer, is hard to answer as it depends on many things and we users have no access to the DSolve source code to answer exactly why.

• I think the Wolf has to work on DSolve a little more. Folks will laugh and point at me if I submitted a solution bristling with "i" terms like that. Especially compared to the neat clean solution that Maple produces immediately with no need to massage the result. – Ratch May 21 '17 at 13:45