FindRoot and symbolic evaluation

Following the Symbolic evaluation documentation, I am trying to solve the equation: $$y'(x) = a*y(x), \quad y(0)=1$$ where I later fix a via FindRoot, requiring that $$y(2) = 2$$:

ftest[unknown_?NumberQ] := First[y[2] /. NDSolve[{y'[x] == unknown*y[x], y[0] == 1}, y, {x, 0, 4}]]
FindRoot[ftest[k] - 2, {k, 0, 4}]


This works well, but for some reason, replacing the "k" by "x" inside the Findroot outputs errors? I tried opening a new notebook and/or using Clear, but that did not solve the problem. Why does Mathematica treat x differently?

You're using x within your ftest function, which is getting replaced by FindRoot. To fix this, you need to scope your ftest function. The following works:

ftest[unknown_?NumberQ] :=
Module[{x},
First[y[2] /.
NDSolve[{y'[x] == unknown*y[x], y[0] == 1}, y, {x, 0, 4}]]]
FindRoot[ftest[x] - 2, {x, 0, 4}]


If you read the error message your code outputs, you see something like NDSolve::dsvar: 0. cannot be used as a variable. FindRoot appears to be replacing the x in NDSolve[..., {x, 0, 4}] with 0, resulting in NDSolve[..., {0, 0, 4}], which is where it's trying to use 0 as a variable. Thus, you need to scope your inner x with a Module so that it doesn't get replaced.

• The OP might note also that ftest[x] translates to the ODE y'[x] == x*y[x], which is quite a bit different than when unknown is a constant. However, in this case, as Carl points out, FindRoot replaces x by a number globally. This is what is meant by this line in the docs: "FindRoot...effectively uses Block to localize variables." – Michael E2 Jan 7 at 13:57
• I see. I thought that inside function definition, the variables are automatically made local. Thank you very much for the reply. – Patrick.B Jan 7 at 15:32
• @MichaelE2 Thanks a lot for the clarification. I don't have an extremely strong knowledge of the scoping mechanisms myself! – Carl Lange Jan 7 at 15:58