3
$\begingroup$

Simplified starting point: I have a function of two variables

f[a_, x_] := x^2 + a^2 - 4;

and define a function that gives an x depending on a for which the equation f[a,x]==0 holds:

xsol[a_] := x /. FindRoot[f[a, x], {x, 1}];

Now I'd like to find an a for which xsol[a] has a specific value (e.g. xsol[a]==1). As I can't call xsol[a] symbolically, the following produces the FindRoot::nlnum error:

asol = a /. FindRoot[xsol[a] == 1, {a, 1}]

yet, for some reason (in this case), still gives a correct solution.

How can i find asol without receiving this error?

This example might seem somewhat stupid, as one could set x=1 in the Definition of f[x,a] and find asol. My actual problem involves three more complicated eqations and 4 variables, and the final FindRoot-call is supposed to determine whether another function of these variables can have some specific value (and thus you can't extract information from that last condition to simplify the problem, as in this example).

Note: One of my equations is transcendental. Therefore, as far as I understand, FindRoot is best used, and some built-in algorithms for equation solving won't work.

$\endgroup$
2
  • $\begingroup$ Look at the result of Plot[xsol[a], {a, -4, 4}] to understand possible difficulties. $\endgroup$
    – user64494
    Jul 21, 2021 at 12:07
  • $\begingroup$ Already did. I'd say as long as |a|<2 and 0 < x <= 2 there is nothing to worry about... $\endgroup$ Jul 21, 2021 at 13:43

1 Answer 1

2
$\begingroup$

The problem is that xsol is being passed a symbolic value (a), and the FindRoot in the definition is then complaining about being passed a symbolic value. You can avoid the error message by redefining xsol so that it does not evaluate unless it is passed a numeric value:

xsol[a_?NumericQ] := x /. FindRoot[f[a, x], {x, 1}];

{ xsol[a], xsol[1.5] }

(* xsol[a], 1.32288 *)

Calling asol with this xsol definition still returns an warning about the step size getting too small, but the FindRoot::nlnum error is eliminated.

You didn't ask, but in case you're curious: The step-size warning might be eliminated by increasing WorkingPrecision. You could also try using Method -> "Brent", which is a bracketing algorithm rather than a secant method. For that algorithm, you will need to provide two values for a in the second argument of FindRoot which are known to bracket a root; depending on the nature of your actual problem, this may or may not be feasible.

$\endgroup$
3
  • $\begingroup$ Thanks, that solves my problem. Out of even more curiosity: How would i make e.g. Maximize work, to find the maximum of xsol[a]? Maximize[xsol[a], a] threw the same error beforehand, now with ?NumericQ in the function definition just ouputs the input. $\endgroup$ Jul 21, 2021 at 15:06
  • $\begingroup$ @wunschwaschbaer: I think you want NMaximize or FindMaximum. Maximize is designed for symbolic inputs, not numeric. Beyond that, these two functions have a host of options that you can tweak to try to get better behavior. See the guides here and here, and be prepared to get lost in the weeds. $\endgroup$ Jul 21, 2021 at 15:22
  • $\begingroup$ Agh, that was a somwhat obvious mistake. Thank you! $\endgroup$ Jul 21, 2021 at 15:40

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.