DSolve—different solutions for same set of equations using different symbols?

Some insight can be gained by considering the two cases given in the question but without ReplaceAll and FullSimplify

DSolve[{f'[t]*g[t]^4/f[t]^4 == -1, g'[t]*g[t]^3/f[t]^3 == -3/2}, {f[t], g[t]}, t, 
    GeneratedParameters -> A]
(* {{g[t] -> Sqrt[3] A[1] ((-t + A[1]^4 A[2])^(1/3)/A[1]^(4/3))^(3/2), 
     f[t] -> (3^(1/3) (-t + A[1]^4 A[2])^(1/3))/A[1]^(4/3)}, 
    {g[t] -> A[1] (-(((-3)^(1/3) (-t + A[1]^4 A[2])^(1/3))/A[1]^(4/3)))^(3/2), 
     f[t] -> -(((-3)^(1/3) (-t + A[1]^4 A[2])^(1/3))/A[1]^(4/3))}, 
    {g[t] -> Sqrt[3] A[1] (((-1)^(2/3) (-t + A[1]^4 A[2])^(1/3))/A[1]^(4/3))^(3/2), 
     f[t] -> ((-1)^(2/3) 3^(1/3) (-t + A[1]^4 A[2])^(1/3))/A[1]^(4/3)}} *)

DSolve[{V'[t]*H[t]^4/V[t]^4 == -1, H'[t]*H[t]^3/V[t]^3 == -3/2}, {V[t], H[t]}, t, 
    GeneratedParameters -> B]
(* {{V[t] -> B[1] (-Sqrt[-3 t B[1]^3 + 2 B[2]])^(2/3), 
     H[t] -> -Sqrt[-3 t B[1]^3 + 2 B[2]]}, 
    {V[t] -> B[1] (-3 t B[1]^3 + 2 B[2])^(1/3), 
     H[t] -> Sqrt[-3 t B[1]^3 + 2 B[2]]}} *)

With the substitution,

{f[t]^-3 -> 1/ff[t], g[t]^4 -> gg[t]}

the first of these can be rewritten as

s = DSolve[Unevaluated[{-D[f[t]^-3, t] g[t]^4/3 == -1, D[g[t]^4, t] f[t]^-3/4 == -3/2}]
    /. {f[t]^-3 -> 1/ff[t], g[t]^4 -> gg[t]}, {ff[t], gg[t]}, t]
(* {{gg[t] -> C[1] (-((3 t)/C[1]) + C[2])^2, ff[t] -> -((3 t)/C[1]) + C[2]}} *)

Thus, for a given value of {C[1], C[2]}, there are three independent values of f[t] and four independent values of g[t], for a total of twelve pairs, although some may be redundant through transformations of {C[1], C[2]}.

The parameters {C[1], C[2]} can be transformed to {A[1], A[2]} and to {B[1], B[2]} by

s /. {C[1] -> A[1]^4, C[2] -> 3 A[2]}
s /. {C[1] -> B[1]^-6, C[2] -> 2 B[1]^3 B[2]}

Thus, the solution sets for the first and second cases each are different subsets of the complete set of solutions. A similar analysis can be performed, starting with a transformation of the second case.

It is natural, therefor, to attempt to obtain the complete solution set by using

SetOptions[Solve, Method -> Reduce]

Unfortunately, this has minimal impact on the results returned by DSolve.

Let us turn now to the occurrence of Root in the first solution in the question. As mentioned in my comment above, it arises from

(-1)^(2/3) 3^(1/3) // FullSimplify
(* Root[-3 + #1^3 &, 3] *)

i.e., the third solution of (#^3 - 3) & == 0. Indeed LeafCount of (-1)^(2/3) 3^(1/3) is 11, and of Root[-3 + #1^3 &, 3] is 10, so the latter is simpler in this sense.


Let me abstractly answer your question. This is a very unintuitive part of programming with symbols.

Symbols are not variables.

If you had a Python program and you changed the name of a variable, you should expect it to execute just the same as it had before. There is nothing different about using "a" or "b" or "z" as a variable name.

But if you ask Mathematica to add some symbols together:

a + z + b

It will sort them:

a + b + z

So you can see that the name of a symbol matters. It matters in a way that most programmers are not used to. It affects where the symbol gets put in a summation. This isn't a trivial change. For example, if you plan on doing a calculation with finite precision numbers, the order of addition matters.

If you change the name of a symbol, the resulting expression will be algebraically the same, but structurally it may be substantially different. If it's substantially different, then DSolve or any other symbolic function may try to solve it in a different way.

Which solution(s) I should believe?

Generally, there is no reason that both sets of solutions can't be right.

After running DSolve or NDSolve, you should try to substitute the solutions back into the original differential equation to understand them better.

You should use the solution which is most useful for you.


The solutions $x=f(t),\;y=g(t)$ of the OP's ODE parameterize the integral curves of $${dy \over dx} = {3y \over 2x}, \quad \text{or, if you prefer,} \quad 2\,{dy \over y} = 3\,{dx \over x}\,,$$ which has the general solution $$y^2 = A\,x^3\,.$$ How many solutions you get depends on which variable you solve for first, $x=f(t)$ or $y = g(t)$:

Solve[y^2 == A x^3, y]
Solve[y^2 == A x^3, x]
(*
  {{y -> -Sqrt[A] x^(3/2)},
   {y -> Sqrt[A] x^(3/2)}}

  {{x -> y^(2/3) / A^(1/3)},
   {x -> -(((-1)^(1/3) y^(2/3)) / A^(1/3))},
   {x -> ((-1)^(2/3) y^(2/3)) / A^(1/3)}}
*)

Even over the reals, solving for a square and a cube gives different numbers of solutions, two and one respectively.

Evidently, Mathematica picks which variable to solve for based on lexicographic order. This is the reason the form of the answer DSolve returns depends on the order of variables.

The OP's solutions are equivalent. One can get the relation between $A$ and the constants in each of the solutions with SolveAlways:

fgsol = DSolve[{f'[t]*g[t]^4/f[t]^4 == -1, g'[t]*g[t]^3/f[t]^3 == -3/2}, {f, g}, t];
VHsol = DSolve[{V'[t]*H[t]^4/V[t]^4 == -1, H'[t]*H[t]^3/V[t]^3 == -3/2}, {V[t], H[t]}, t];

y^2 == A x^3 /. Thread[{x, y} -> {f[t], g[t]}] /. fgsol // SolveAlways[#, t] &
y^2 == A x^3 /. Thread[{x, y} -> {V[t], H[t]}] /. VHsol // SolveAlways[#, t] &
(*
  {{A -> 0, C[1] -> 0}, {A -> C[1]^2}}
  {{C[1] -> 0, C[2] -> 0}, {A -> 1/C[1]^3}}
*)

Ignoring the trivial solutions, we see that A == C[1]^2 and A == 1/C[1]^3 respectively. It can be seen that the meaning of C[1] is different in each solution. The second constant C[2] determines the starting point on the curve of the parametrization {f[t], g[t]} (resp. {V[t], H[t]}), which will also be different in each solution.