9
$\begingroup$

NDSolve works for complex valued ODE initial value problems (IVP). However, for a simple boundary value problem (BVP) with complex coefficients it fails:

NDSolve[{x''[t] + (1 + I) Sin[x[t]] == 0, x[0] == 1, x[10] == 0}, x, {t, 0, 10}]

FindRoot::trcx: The search has encountered a complex value and the trust region step control method is only implemented for real values.

The difficulty seems to be that the internal call to FindRoot to solve the shooting method matching is trying a method (trust region step control) that is not implemented for complex numbers.

I would like to get around this by somehow telling FindRoot to use line search instead. Since there does not appear to be a way to pass this through the NDSolve options to FindRoot, I tried globally resetting the default FindRoot options:

SetOptions[FindRoot, Method -> {"Newton", "StepControl" -> "LineSearch"}]

However, a subsequent call to NDSolve returned the same error as before, i.e., a complaint about trust region step control. So it didn't use linear search!

So, my questions are:

  1. Is there a way to pass options through NDSolve to FindRoot?
  2. Why doesn't the call to SetOptions work?
  3. Is there another way to get Mathematica to solve a complex BVP? (Yes, I know I can always split the equation into real and imaginary parts, but this is rather inconvenient for the much more complicated problems I'm actually trying to solve. Besides, as a matter of principle, since Mathematica generally handles complex variables seamlessly, it seems there should be a more direct way to do this.)
$\endgroup$
  • 1
    $\begingroup$ Hi! You can format inline code and code blocks by selecting the code and clicking the {} button above the edit window. The edit window help button ? is also useful for learning how to format your questions and answers. You may also find this meta Q&A helpful $\endgroup$ – Michael E2 Aug 21 '16 at 11:23
9
$\begingroup$

The tutorial Numerical Solution of Boundary Value Problems (BVP) has a description of the suboptions to the "Shooting" method. The option you want is "ImplicitSolver":

{sol} = NDSolve[{x''[t] + (1 + I) Sin[x[t]] == 0, x[0] == 1, 
    x[10] == 0}, x, {t, 0, 10}, 
   Method -> {"Shooting", 
     "ImplicitSolver" -> {"Newton", "StepControl" -> "LineSearch"}}];

Plot[ReIm@x[t] /. sol // Evaluate, {t, 0, 10}]

Mathematica graphics

Update: The reason SetOptions does not work is that NDSolve overrides the options of FindRoot, which I think may be inferred from the output of the following:

Trace[
 NDSolve[{x''[t] + (1 + I) Sin[x[t]] == 0, x[0] == 1, x[10] == 0}, 
  x, {t, 0, 10}],
 _FindRoot,
 TraceInternal -> True]
(* {{{...some output omitted...
  {FindRoot[NDSolve`Shooting`ShootingDump`nf$337017, 
   SetPrecision[{{NDSolve`Shooting`ShootingDump`start$337017}}, 
    NDSolve`Shooting`ShootingDump`prec$337017], 
   "AccuracyGoal" -> NDSolve`Shooting`ShootingDump`ag$337017, 
   "PrecisionGoal" -> NDSolve`Shooting`ShootingDump`pg$337017, 
   "MaxIterations" -> NDSolve`Shooting`ShootingDump`maxit$337017, 
   "Method" -> NDSolve`Shooting`ShootingDump`frmethod$337017, 
   "WorkingPrecision" -> NDSolve`Shooting`ShootingDump`prec$337017]},...}}}
*)

You can add the option TraceAbove -> True if you really want to track it down. You'll see a line like

If[NDSolve`Shooting`ShootingDump`frmethod$337017 === Automatic, 
 NDSolve`Shooting`ShootingDump`frmethod$337017 = {"Newton", 
   "StepControl" -> "TrustRegion"}]
$\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.