0
$\begingroup$

I'm using Mathmatica 11.1 on Windows.

Given an expression containing a differntial equation of the form

$\qquad A\, x'(z) = C\, x''(z) - B\, x(z)$

Or

A x'[z] == -B x[z] + C x''[z]

I want to transform the expression into a standard form for an ODE, namely,

$\qquad x''(z)-\frac{A}{C}x'(z)-\frac{B}{C}x(z)=0$

Or

x''[z] - A/C x'[z] - B/C x[z] == 0

A more generalized version of this format may be represented as

$\qquad y^n(x)-a_{1}\cdot y^{n-1}(x)\cdots a_{n-1}\cdot y'(x)-a_{n}\cdot y(x)=0$

for linear ODEs, or

$\qquad y^n(x)-a_{1}\cdot y^{n-1}(x)\cdots a_{n-1}\cdot y'(x)-a_{n}\cdot y(x)=p(x)$

for non-linear ODES, where $p(x)$ may be some non-linear function on x, such as $sin(x)$ or $1/x$.


I have attempted to address this by using StandardForm and NonlinearStateSpaceModel, amongst other ways, and have not yet been able to convert the expression.

I would prefer a solution that is generalized and would function for any given ODE however, this may or may not be practical.


$\endgroup$
  • $\begingroup$ Generalized, including nonlinear equations? E.g. Apply[Equal, Solve[a x'[z] == -b x[z] + c x''[z]^2, {x''[z]}], {2}] -- is it how you'd like? $\endgroup$ – Michael E2 Mar 2 '19 at 0:42
  • $\begingroup$ @MichaelE2, no, that does not present the format that I am looking for $\endgroup$ – Taylor Scott Mar 7 '19 at 21:38
  • $\begingroup$ What would be the desired form in that case, given that it's nonlinear? $\endgroup$ – Michael E2 Mar 7 '19 at 21:45
  • $\begingroup$ @MichaelE2, I have added some clarifications to the question, but generally, if the ODE is non-linear, then the non-linear aspect of the equation should be moved to the RHS of the expression. $\endgroup$ – Taylor Scott Mar 7 '19 at 21:57
  • $\begingroup$ The term linear applied to ODE usually means the equation is linear in the "dependent variables" $y(x)$ and its derivatives, that is, an equation of the form $\sum a_k(x) y^{(k)}(x) = p(x)$; the coefficients $a_k(x)$ and $p(x)$ may be any functions of $x$. Nonlinear equations have dependent variables in nonlinear functions such as $\sin(y(x))$ or x''[z]^2. It seems you are considering only the special case of linear ODES with constant coefficients, not any given ODE such as the one in my comment. That's fine; I just wanted to know since the accepted answer deals only with this special case. $\endgroup$ – Michael E2 Mar 8 '19 at 0:07
4
$\begingroup$

A little clunky, but this should work pretty generally:

standardForm[eqn_Equal] := Module[{equation = # - eqn[[1]] & /@ eqn},
  equation = Collect[#, _''[_]] & /@ equation;
  #/First@Cases[equation, a_ _''[_] :> a, Infinity] & /@ equation // Apart // Expand
 ]

Note: as of V11.3, # - eqn[[1]] & /@ eqn can be replaced with SubtractSides[eqn, First@eqn].

Then,

standardForm[a x'[z] == -c x''[z] - b x[z] + d x''[z]]
(* 0 == (b*x[z])/(c - d) + (a*Derivative[1][x][z])/(c - d) + Derivative[2][x][z] *)

Explanation:

In the first step,

eqn = a x'[z] == -c x''[z] - b x[z] + d x''[z];
equation = # - eqn[[1]] & /@ eqn
(* 0 == -b x[z] - a x'[z] - c x''[z] + d x''[z] *)

we move everything to the right-hand side. In the second step,

equation = Collect[#, _''[_]] & /@ equation
(* 0 == -b x[z] - a x'[z] + (-c + d) x''[z] *)

we collect all the instances of x''[z] so that we can extract the coefficient in the next step,

First@Cases[equation, a_ _''[_] :> a, Infinity]
(* -c + d *)

in order to then divide both sides of the equation by this value:

#/First@Cases[equation, a_ _''[_] :> a, Infinity] & /@ equation // Apart // Expand
(* 0 == b x[z]/(c - d) + a x'[z]/(c - d) + x''[z] *)

The // Apart // Expand is there to make sure that the cancellation occurs in the coefficient of the x''[z] term.

$\endgroup$
  • 1
    $\begingroup$ @TaylorScott. Added some explanation. $\endgroup$ – march Mar 1 '19 at 17:36
  • $\begingroup$ That's a perfect explanation, thank you :) $\endgroup$ – Taylor Scott Mar 1 '19 at 17:37
  • 2
    $\begingroup$ As of V11.3 we have SubtractSides[eqn, First@eqn]. $\endgroup$ – Michael E2 Mar 8 '19 at 1:42
1
$\begingroup$

Another way, easily generalized for linear ODEs:

depvars = NestList[D[#, z] &, x[z], 2]; (* {x[z], x'[z], x''[z]} *)
ca = CoefficientArrays[
   Subtract @@ Solve[a x'[z] == -b x[z] + c x''[z] + p[z], x''[z]][[1, 1]],
   depvars];
Last@ca.depvars == -First@ca
(*  -((b x[z])/c) - (a x'[z])/c + x''[z] == -(p[z]/c)  *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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