DSolve solution depends on ordering of equation
This looks like a bug. Clearly the order should not make a difference. Here is another version of the problem. Putting both on the same side
lhs1 = D[g[x1, x2, x3, x4], x3];
rhs1 = D[f[x1, x2], x1];
lhs2 = D[g[x1, x2, x3, x4], x4];
rhs2 = D[f[x1, x2], x2];
Now
DSolve[{lhs1==rhs1,lhs2==rhs2},g[x1,x2,x3,x4],{x4,x3,x2,x1}]
But
DSolve[{lhs1-rhs1==0,lhs2-rhs2==0},g[x1,x2,x3,x4],{x1,x2,x3,x4}]
In Maple, the order does not affect the result
I remember seeing issue once where order of variables made difference in result, but this I remember was in integrate not dsolve? may be someone knows about this more.
This is a workaround, as requested in a comment and extended to handle the updated problem. The idea is to solve the pde system for the derivatives so that we can put the derivatives of G
on the left-hand side of the equation. There is a hard-coded internal pattern that assumes the problem will be set up this way. Solve
returns these in the form of a Rule
. Replacing Rule
by Equal
converts them back to equations, but with the derivatives on the LHS. Update: Additionally, the hard-coded pattern requires the derivatives of G
to be in a the same order as the arguments' order, that is, D[.., x0] ==..
, D[.., y0] ==..
, D[.., z0] ==..
. This can be fixed by sorting the derivatives of G
.
normal[U_] = Function[pde,
Reverse@Sort@First@Solve[pde,
Cases[Variables[pde /. Equal -> List], _?(! FreeQ[#, U] &)]] /.
Rule -> Equal];
DSolve[normal[G]@{D[F[x1, x2], x1] == D[G[x1, x2, x3, x4], x3],
D[F[x1, x2], x2] == D[G[x1, x2, x3, x4], x4]}, G, {x1, x2, x3, x4}]
N.B. We're assuming we've got a linear first-order pde system here. (A similar approach could work on higher-order systems, with some work.)
Example in the update
DSolve[normal[G]@badPDE, G, {x0, x1, y0, y1, z0, z1}]
It seems the internal code assumes in the 3D case that the equations have been set up in the order
Grad[G, {x1, y1, z1}] == V /; Curl[V, {x1, y1, z1}] == {0, 0, 0}
This suggests this change to normal
:
normal[u_, vars_] = Function[pde, First@Solve[pde, Grad[u, vars]] /. Rule -> Equal];
And this change in its usage, with the arguments being specified:
normal[G[x0, x1, y0, y1, z0, z1], {x1, y1, z1}]@badPDE
Here is another way to use normal
to fix DSolve
:
ClearAll[gradify];
SetAttributes[gradify, HoldAll];
gradify[code_DSolve] := Internal`InheritedBlock[{DSolve`DSolvePDEs},
Unprotect[DSolve`DSolvePDEs];
DSolve`DSolvePDEs[eqs_, {u_}, v : {x_, y_, z_}, c_, i_] :=
With[{gradeqs = normal[u @@ v, v]@eqs},
DSolve`DSolvePDEs[gradeqs, {u}, {x, y, z}, c, i] /; gradeqs =!= eqs];
Protect[DSolve`DSolvePDEs];
code
]
Example:
gradify@DSolve[badPDE, G, {x0, x1, y0, y1, z0, z1}]