If I have a function $f(x)$ that I only know numerically and that returns a real value for some range of values $-\infty < x \leq a$ and complex values for $a < x < \infty$, how can I precisely determine what the value of $a$ is?

I know I can generate a table of values of $f(x)$ and see when the transition occurs, but this requires quite a bit of manual work to get to a sufficient degree of precision.

Alternatively, I can try to use FindRoot in the following way (using $f(x) = \sqrt{2-x}$ as a simple example merely for illustrative purposes):

g[x_] := If[Im[Sqrt[2 - x]] == 0, 0, I]
FindRoot[g[x] == 0, {x, 2.05}]

(Note that I use I for $x > 2$ because the numerical function that I am trying to work with behaves very strangely for a certain range $a < x < b$ due to some FindRoot issues, and I don't want any of that strangeness displaying in plots of g[x] or affecting the calculation of $a$.)

But this returns the following error:

FindRoot::jsing: Encountered a singular Jacobian at the point {x} = {2.05}.
Try perturbing the initial point(s).    

I have tried to fix this issue by varying the value of g[x] for $x > 2$:

g[x_] := If[Im[Sqrt[2 - x]] == 0, 0, 2*x]

In this case, however, FindRoot does not yield the correct value for $a$, as it uses the slope of $2x$ to return $0$.

In order to use this method, then, I would need to use a function that is equal to $0$ at $a$; without already knowing $a$, however, this does not seem possible.

Is there a better method for solving this problem? Can my approach work with some tweaks? I found this question, but it also seems less precise than I would like, since Plot evaluates only at some points (of course, I could try to restrict the domain to get a better result, but again, that is more manual control than I am aiming for).

Thank you very much!

  • 1
    $\begingroup$ Is there a reason the actual function can't be posted? $\endgroup$ – ciao Jun 8 '16 at 21:57
  • $\begingroup$ @ciao It's based on an entire notebook of calculations and function definitions, so it wouldn't be easy to post it. In any case, the essence of the question is captured by using a simpler function like $\sqrt{2-x}$ (maybe someone can come up with a good numerical example) instead, so I am hoping to save everyone from needless (and potentially distracting) details! $\endgroup$ – AnInquiringMind Jun 8 '16 at 22:01
  • 1
    $\begingroup$ If you are sufficiently desperate, you could try to manually implement bisection. $\endgroup$ – J. M.'s discontentment Jun 9 '16 at 4:04
  • $\begingroup$ @J.M. That's a good idea. Are there any built-in functions that can help with this, or will I need to implement this entirely manually? Thanks! $\endgroup$ – AnInquiringMind Jun 9 '16 at 11:59
  • $\begingroup$ Either While[] or NestWhile[] might be useful. $\endgroup$ – J. M.'s discontentment Jun 9 '16 at 12:20

I can solve the toy problem with

NMaximize[{x, Im[Sqrt[2 - x]] == 0}, x]
| improve this answer | |
  • $\begingroup$ Thanks for the response! I'm trying to get this to work for my specific cases, but I think I'm running into some issues because the constraints that I need implement functions that use FindRoot and, thus, I've had to define those functions with an argument of the form x_?NumericQ. I think NMaximize is running into issues because x is not given as a number... $\endgroup$ – AnInquiringMind Jun 9 '16 at 2:47
  • $\begingroup$ Just a quick follow-up: I have had some success in implementing this method for my specific needs by using a modified function that cleans up any function messiness after it becomes (or, in theory, should become) non-real; however, I cannot get NMaximize to give me an answer closer to the upper bound than to 3 degrees of precision, even if I've tried to increase PrecisionGoal or AccuracyGoal. Not sure if there's a way to improve that. $\endgroup$ – AnInquiringMind Jun 9 '16 at 12:44

FunctionDomian and FunctionRange can solve them all!


FunctionDomain[Sqrt[2 - x],x]
FunctionRange[Sqrt[2 - x],x,y]
| improve this answer | |
  • 1
    $\begingroup$ Unfortunately, this solution will consume a lot of time if your function gets nasty...... $\endgroup$ – Wjx Jun 9 '16 at 2:25
  • $\begingroup$ Thank you for the response, but I believe that these can only be used for analytical functions. I am trying to determine the domain for a purely numerical function, and I get FunctionDomain::nmet: Unable to find the domain with the available methods. $\endgroup$ – AnInquiringMind Jun 9 '16 at 2:35
  • $\begingroup$ oh, maybe, but how can you get a result with complex number using a numerical function? N*** functions? $\endgroup$ – Wjx Jun 9 '16 at 2:37

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.