3

I tried to solve for an non-Hookean spring's motion, but the output from Mathematica is weird. It seems that there is inverse functions involved.

DSolve[{x''[t] + x[t]^3 == 0}, x[t], t]
Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>
Out[1] = {{x[t] -> -I 2^(1/4) Sqrt[-(1/Sqrt[C[1]])] Sqrt[C[1]]
 JacobiSN[Sqrt[
 Sqrt[2] t^2 Sqrt[C[1]] + 2 Sqrt[2] t Sqrt[C[1]] C[2] + 
  Sqrt[2] Sqrt[C[1]] C[2]^2]/Sqrt[2], -1]}, {x[t] -> I 2^(1/4) Sqrt[-(1/Sqrt[C[1]])] Sqrt[C[1]] JacobiSN[Sqrt[Sqrt[2] t^2 Sqrt[C[1]] + 2 Sqrt[2] t Sqrt[C[1]] C[2] + 
  Sqrt[2] Sqrt[C[1]] C[2]^2]/Sqrt[2], -1]}}

If you try Reduce, Mathematica will then give you no output at all, which makes sense because the output is not an equality or inequality.

Also, I added initial values into DSolve, but I'm unable to obtain the answer.

In[1]:= DSolve[{x''[t] + x[t]^3 == 0, x[0] == d, x'[0] == 0}, x[t], t]
Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>
DSolve::bvfail: For some branches of the general solution, unable to solve the conditions. >>
DSolve::bvfail: For some branches of the general solution, unable to solve the conditions. >>
Out[1]= {}
bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
  • 1
    Welcome to MathematicaSE. Please add your Mathematic code instead of screen shots, use the { } of the editor to input code and the Image button do add images. – Karsten7 Oct 19 '14 at 04:08

3 Answers3

7

Well, that was easy:

Block[{Simplify = FullSimplify},
  DSolve[{x''[t] + x[t]^3 == 0, x'[0] == 0, x[0] == x0}, x[t], t]
  ] // FullSimplify
(*
  {{x[t] -> x0 JacobiCD[(t x0)/Sqrt[2], -1]}}
*)

DSolve uses Simplify to check the solution, and Simplify is not up to the task. So I used Block to replace it with FullSimplify, which will reduce the DE to True after DSolve substitutes the solution. Perhaps the Method option could be used, but there are no clues to how to use it.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Wow, dude! You're awesome! – George Zhang Oct 21 '14 at 23:50
  • Hey Michael, your answer is concise and super helpful. However, I still don't understand how it works. For example, why does FullSimplify[DSolve[{x''[t] + x[t]^3 == 0, x'[0] == 0, x[0] == x0}, x[t], t]] doesn't work? What's special about the Block[] command? What is the mechanism of Block[{Simplify = FullSimplify, expr]? – George Zhang Oct 22 '14 at 00:01
  • 1
    Block is a way to give a symbol a local definition that applies only within the Block. Inside the block, any call to Simplify actually calls FullSimplify, even inside the DSolve code, which is where it is needed. Calling FullSimplify outside of DSolve only simplifies the result (which I also did). Look it up in Help or see this question. – Michael E2 Oct 22 '14 at 02:26
  • Then here comes my question. How did you know that the Simplify is called inside the DSolve function and that by using FullSimplify instead we can solve the problem? Is it shown in the documentation center of Mathematica? – George Zhang Oct 23 '14 at 14:04
  • @GeorgeZhang In some sense luck: foo = Trace[DSolve[{x''[t] + x[t]^3 == 0, x[0] == d, x'[0] == 0}, x[t], t], TraceInternal -> True]. Now DSolve uses Integrate (of course, maybe), so look for Integrate in the 7GB of output by mapping FreeQ[Integrate] over parts of foo. Try this: NestWhile[Extract[#, Last@Position[FreeQ[Integrate] /@ #, False]] &, foo, ListQ]. (Not exactly how I did it, but hindsight is golden.) When I saw the answer to DE, I then just had to hunt down where it was rejected (in the same way with FreeQ). – Michael E2 Oct 23 '14 at 16:29
5

Instead of giving screenshots you should copy your code and paste to this section properly. Ok, now I give a general approach to solve this problem.

In[1]:= DSolve[x''[t] + x[t] == 0, x[t], t]

Out[1]= {{x[t] -> C[1] Cos[t] + C[2] Sin[t]}}

Well, Mathematica does the job well and easy. Your problem shouldn't be that hard. Let's see:

In[2]:= eqn = x''[t] == -x[t]^3; sol = DSolve[eqn, x, t]

During evaluation of In[2]:= Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>

Out[2]= {{x -> 
   Function[{t}, -I 2^(1/4) Sqrt[-(1/Sqrt[C[1]])] Sqrt[C[1]]
      JacobiSN[Sqrt[
      Sqrt[2] t^2 Sqrt[C[1]] + 2 Sqrt[2] t Sqrt[C[1]] C[2] + 
       Sqrt[2] Sqrt[C[1]] C[2]^2]/Sqrt[2], -1]]}, {x -> 
   Function[{t}, 
    I 2^(1/4) Sqrt[-(1/Sqrt[C[1]])] Sqrt[C[1]]
      JacobiSN[Sqrt[
      Sqrt[2] t^2 Sqrt[C[1]] + 2 Sqrt[2] t Sqrt[C[1]] C[2] + 
       Sqrt[2] Sqrt[C[1]] C[2]^2]/Sqrt[2], -1]]}}

What happened? I wanted an easy output! Ok, actually, this type of DE does not explicitly depend on t or x'[t]. In order to reduce this equation to first order ODE with independent var x, Mathematica needs (and uses) inverse functions. You see JacobiSN at Out[2] which is the inverse of EllipticK. Solve uses JacobiSN to find an expression for x[t]. Here is the plot of the solutions:

Plot[Evaluate[
  x[t] /. {sol[[1]], sol[[2]]} /. {C[1] -> 1, C[2] -> 3}], {t, -5, 
  5},
 AxesLabel -> {"time", "displacement"},
 Filling -> {1 -> {2}}]

enter image description here

You can change the coefficients C[1] and C[2], and see the resulting plots.

Serhan Aya
  • 63
  • 4
  • This is super helpful! However, I still don't know what should I do if I want to solve for solution with initial values because if I just include IVs in DSolve command, Mathematica just simply refuses to do it. – George Zhang Oct 19 '14 at 19:13
  • Also, I tried your solution and find the Evaluation[] command really makes a difference. If I don't include it in my plot command, like Plot[x[t] /. {sol[[1]], sol[[2]]} /. {C[1] -> 1, C[2] -> 3}, {t, -5, 5}, AxesLabel -> {"time", "displacement"}, Filling -> {1 -> {2}}], the graph I get is not correctly filled.
    But, when I computed Evaluate[x[t] /. {sol[[1]], sol[[2]]} /. {C[1] -> 1, C[2] -> 3}] and x[t] /. {sol[[1]], sol[[2]]} /. {C[1] -> 1, C[2] -> 3}, there is no different between the output of these two commands. I'm confused. Could you explain why the Evaluate matters?
    – George Zhang Oct 20 '14 at 14:54
  • The list x[t] in has attribute HoldAll. Plot evaluates the Table separately. As you saw when you tried the Plot command without Evaluate, the two functions of x[t] are treated as one function and thus they have same colours and the are between them is not filled. – Serhan Aya Oct 20 '14 at 17:30
2

Higher-order, nonlinear differential equation are usually difficult. We can solve the general equation and try to solve the initial condition for the constants of integration.

sol = DSolve[{x''[t] + x[t]^3 == 0}, x, t];

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>

If the initial condition is x[0] == x0, x'[0] == p0, then these determine the first two coefficients of the Taylor series. So let's get the first two Taylor coefficients in three steps: First the coefficients of the series, which turn out to have simplifications that Simplify does not perform by default. Second, take the -1s out of the powers, which will cancel out the Is. Finally replace the constants of integration by simpler parameters.

ivterms = Simplify[CoefficientList[Normal@Series[
     x[t] /. First[sol],
     {t, 0, 1}],
   t],
  {C[1], C[2]} ∈ Reals];
ivterms = ivterms /. Power[Times[-1, e__], n_] :> I^(2 n) Power[Times[e]];
  (* Inverse replacement: {c1 -> C[1]C[2]^4, c2 -> C[2]} *)
ivterms = 
 ivterms /. {Power[C[1], n_] :> c1^n/Abs[C[2]]^(4 n)} /. {Power[
     Abs[C[2]], n_?EvenQ] -> c2^n, C[2] -> c2}
(*
  {(2^(1/4) c2^2 JacobiSN[c1^(1/4)/2^(1/4), -1])/Sqrt[c1], 
   (c1^(3/4) JacobiCN[c1^(1/4)/2^(1/4), -1] JacobiDN[c1^(1/4)/2^(1/4), -1])/c2^3}
*)

Solve the initial condition: First case, p0 = 0.

Solve[First@ivterms == x0, {c2}]
Solve[Last@ivterms == 0 /. #, {c1}] & /@ %
(*
  {{c2 -> -((c1^(1/4) Sqrt[x0])/(2^(1/8) Sqrt[JacobiSN[c1^(1/4)/2^(1/4), -1]]))},
   {c2 -> (c1^(1/4) Sqrt[x0])/(2^(1/8) Sqrt[JacobiSN[c1^(1/4)/2^(1/4), -1]])}}
*)

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. >>

(*
  {{{c1 -> 0}, {c1 -> 2 EllipticK[-1]^4}}, {{c1 -> 0}, {c1 ->  2 EllipticK[-1]^4}}}
*)

Second case: generic p0. Unfortunately, we can't solve exactly for c1.

Solve[First@ivterms == x0, {c2}]
Solve[Last@ivterms == p0, {c1}]
(*
  {{c2 -> -((c1^(1/4) Sqrt[x0])/(2^(1/8) Sqrt[JacobiSN[c1^(1/4)/2^(1/4), -1]]))},
   {c2 -> (c1^(1/4) Sqrt[x0])/(2^(1/8) Sqrt[JacobiSN[c1^(1/4)/2^(1/4), -1]])}}
*)

Solve::nsmet: This system cannot be solved with the methods available to Solve. >>

So one is left with using FindRoot to numerically solve for c1 for a given numerical initial condition.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Thanks a lot! However, if I use Maple to solve this IV problem, I can just include the IVs in my "dsolve" command and get answer right after execution. The fail of Mathematica in this case is very likely due to its rigorousness. But if it can be done in Maple in one step, I just want to know if there is easier way in Mathematica than tons of code and manual manipulation. – George Zhang Oct 20 '14 at 14:44
  • @GeorgeZhang Does the new answer do what you desire? – Michael E2 Oct 21 '14 at 02:16
  • Yeah, the new one is exactly what I want! Guys, thanks for your help! – George Zhang Oct 21 '14 at 23:50