2
$\begingroup$

I'm writing a code that tries to solve differential equations generated from some existing code. The equations so generated are often seemingly overdetermined but actually solvable: e.g.

{f'[x] == 0, f''[x] == 0 }

However, plugging this into DSolve spits the DSolve::overdet: There are fewer dependent variables than equations, so the system is overdetermined error.

These equations can of course be preprocessed by hand before feeding into DSolve. But I wonder if there is a way to automatically solve this kind of equations?

$\endgroup$
2
  • 2
    $\begingroup$ It's like we need a "DReduce[]"... $\endgroup$
    – Michael E2
    Commented Apr 18, 2022 at 16:50
  • $\begingroup$ As far as ad hoc approaches go, the most straightforward to modify the given system is DSolve[First@{f'[x] == 0, f''[x] == 0 }, f x] or simply DSolve[f'[x] == 0, f, x]. $\endgroup$
    – Michael E2
    Commented Apr 19, 2022 at 14:59

2 Answers 2

4
$\begingroup$
DSolve[{f'[x] == 0, g'[x] == 0, f'[y] == g[y]}, {f, g}, x]

(*   {{f -> Function[{x}, C[1]], g -> Function[{x}, 0]}}   *)

Or

fsol = f /. Flatten@DSolve[{f''[x] == 0}, f, x]

(*  Function[{x}, C[1] + x C[2]]    *)

sol = Flatten@Solve[fsol'[x] == 0]

(*   {C[2] -> 0}   *)

f[x_] = fsol[x] /. sol

(*   C[1]   *)
$\endgroup$
3
$\begingroup$

Here's a start (a truck fire shutdown the highway and we were stuck in the mountains; so I had some extra time and got the below to work with systems as well). Assumptions about input:

  • The systems essentially can be reduced to one equation for each dependent variable.
  • The equations are ODEs.

In this case, we may deduce the order of the desired ODE and use Solve to find it. I guess I have supposed it is obvious, at least in the examples below, that the output of dReduce may be plugged into DSolve.

dReduce // ClearAll;
iDReduce // ClearAll;

dReduce::incon = 
  "The system of differential equations is inconsistent.";
dReduce::noivar = 
  "No independent variables were specified; specify one.";
dReduce::nopde = 
  "There is more than one independent variable ``: PDEs are not implemented.";
dReduce::nodvar = 
  "No dependent variables were specified; specify one.";

dReduce[sys1_, y1_, x1_] := Module[
   {sys, y, x, dorder, redorder, res, tests = 0},
   sys = Flatten@{sys1};
   x = Flatten@{x1};
   y = Flatten@{y1 /. v_[Sequence @@ x] :> v};
   (* check inputs *)
   Switch[Length@x,
    0, Message[dReduce::noivar],
    1, tests++,
    _, Message[dReduce::nopde, x]];
   Switch[Length@y,
    0, Message[dReduce::nodvar],
    _, tests++];
   (* call the solver *)
   (dorder = 
      Flatten@Internal`ProcessEquations`DifferentialOrder[sys, x, y];
     redorder = Length@y + Total@dorder - Length@sys;
     iDReduce[sys, y, First@x, dorder, redorder]) /; tests == 2
   ];
(* adding systems made this a bit more complicated *)
iDReduce[sys_, y_, x_, dorder_, redorder_] := 
  Module[{orders, res, a},
   With[{vars = Array[a, Length@y]},
    orders = SolveValues[ (* possible target orders *)
      Join[{Total@vars == redorder}, 
       Thread[0 <= Array[a, Length@y] <= dorder]],
      vars, Integers]
    ];
   orders = SortBy[orders, -Min[#] &]; (* heuristic: avoid zero-order *)
   res = Do[ (* try each order - first to succeed wins *)
     res = Solve[
       sys,
       Flatten@MapThread[
         Table[Derivative[n][#1][x], {n, #2, #3, -1}] &,
         {y, dorder, orders[[k]]}
         ]
       ];
     If[MatchQ[res, {{__Rule} ..}],
      Return[{res, orders[[k]]}, Do]],
     {k, Length@orders}];
   With[{dvars = MapThread[Derivative[#1][#2][x] &, {Last@res, y}]},
     Thread[
       Times @@ (Thread[dvars - #] & /@
        (dvars /. First@res)) == 0] // 
      Simplify
     ] /; MatchQ[res, {{{___Rule} ...}, _}]
   ];

Examples.

OP's:

dReduce[{f'[x] == 0, f''[x] == 0}, f, x]
(*  f'[x] == 0  *)

OP's with a twist:

dReduce[{f'[x] + f''[x] == f''[x], f''[x] == 0}, f, x]
(*  {f'[x] == 0}  *)

With another twist:

dReduce[{f'''[x] + f''[x] == f''[x], f''[x] == 0}, f, x]
(*  {f''[x] == 0}  *)

Nesting D[] is an easy way to create redundant equations:

dReduce[NestList[D[#, t] &, y'[t] + y[t]^3 == 0, 3], y, t]
(*  {y[t]^3 + y'[t] == 0}  *)

Nonlinear:

dReduce[NestList[D[#, t] &, y''[t]^2 + t^2 y[t] == 0, 2], y, t]
(*  {t^2 y[t] + y''[t]^2 == 0}  *)

System:

dReduce[
 NestList[D[#, t] &, {y'[t] == x[t], x''[t] == -y[t]}, 2],
 {x,y}, t]
(*  {y[t] + x''[t] == 0, x[t] == y'[t]}  *)
$\endgroup$
1
  • $\begingroup$ TBD: Decide how to handle ConditionalExpression solutions returned by Solve. DSolve doesn't like conditions, so could simply use res = Normal@Solve[...] in iDReduce and hope for the best. $\endgroup$
    – Michael E2
    Commented Apr 19, 2022 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.