# How to correct this, f[a_] := FindRoot[eq == 0, {x, 0.5}], where eq contains a parameter $a$, without using eq[a]?

I want to solve an equation with a parameter $a$, and define the result as a function of $a$. It is something like this:

f[a_] := FindRoot[x^2 + 2 x + a == 0, {x, 0.5}]
f[0.2]
(* -> {x -> -0.105573} *)


The equation I want to solve is a large expression, so I do not want to put it explicitly inside the FindRoot. But this does not work:

eq := x^2 + 2 x + a;
f[a_] := FindRoot[eq == 0, {x, 0.5}]
f[0.2]
(* -> FindRoot::nlnum: The function value {1.25 +a} is not a list of numbers with dimensions {1} at {x} = {0.5}. *)


I do not want to define the equation as eq[a], because this equation is also used to do other things, for which it is better to just use eq. The following ways also do not work:

f[a_] := FindRoot[Evaluate[eq] == 0, {x, 0.5}]
f[a_] := Evaluate[FindRoot[eq == 0, {x, 0.5}]]


(However, if we want to solve the above equation analytically, f[a_] := Evaluate[Solve[eq == 0, x]] works, and f[a_] := Solve[Evaluate[eq] == 0, x] does not. How to explain this?)

-
I think it is a duplicate of: Explicit use of Evaluate not behaving the way I expect it to. Well it is if your question is only " How to explain this?". –  Kuba May 25 at 12:29

To achieve what you want, you can use the following

eq := x^2 + 2 x + a;
Function[f[a_] := FindRoot[# == 0, {x, 0.5}]][eq]


to define your f.

-
Wow!... Interesting crazy code injection. This is the kind of operations that make new users get in a non excited state about Mathematica. –  Murta May 25 at 14:35

As an alternative to halirutan's answer, you could define f like this

eq := x^2 + 2 x + a;
Unevaluated[
f[a_] := FindRoot[eq == 0, {x, 0.5}]
] /. OwnValues[eq]


Using Unevaluated in the first argument of ReplaceAll like this is similar to, but avoids, With. You cannot use With here, because With will try to prevent that the a in a_ and the a in eq match.

Note that here eq is never really evaluated, so that we even get a solution if x has a value.

Also ReleaseHold is totally pro (x cannot have a value now)

eq := x^2 + 2 x + a;
Clear@f
ReleaseHold@
Hold[SetDelayed][f[a_], Hold[FindRoot][eq == 0, {x, 0.5}]]
f[0.2]


{x -> -0.105573}

-
Very nice, thanks ;) I was thinking about this but I forgot about OwnValues. I think it's the first time I see it can be really useful :) #newbie –  Kuba May 26 at 20:55
@Kuba Well, I saw you use ReleaseHold today too, which is totally pro :P. Actually I could probably use that here :P –  Jacob Akkerboom May 26 at 21:07
My version with ReleaseHold was not working, I was not aware about sneaky little With renaming variables. I'm glad you can't see deleted answers :P my is full of pro solutions like: With[{e = eq}, ToExpression[ MakeBoxes[f[a_] := FindRoot[e == 0, {x, 0.5}]] /. "a\$_" -> "a_"] ] –  Kuba May 26 at 21:24
@Kuba as long as you are the first to answer, it is ok to show off your knowledge of functions that are not really necessary, don't you think :P? I agree With is quite sneaky. The behaviour is mentioned in the docs under With>possible issues, though. –  Jacob Akkerboom May 27 at 7:16
oh thank you, now I'm feeling better :P –  Kuba May 27 at 7:19