# Problem with internal variable of a Module which returns the solution of an NDSolve command. y$25947 → InterpilatingFunction[…] I will try to give a minimal example of my problem. Say I define the following function, spitting out an NDSolve result, using Module: f[case : True | False] := Module[{x, rhs}, If[case, rhs[x_] = y[x] Cos[x + y[x]], rhs[x_] = y[x] ]; NDSolve[{y'[x] == rhs[x], y[0] == 1}, y, {x, 0, 30}] ]  The argument of f thereby specifies the right hand side of the differential equation: If the argument it True, the right hand side is y[x] Cos[x + y[x]], if it is False, it is just y[x]. Now, the way I defined it above, everything works fine, and the result is displayed as the usual {{y → InterpolatingFunction[...]}}  output of NDSolve. However y is a global variable, so I would like to protect it inside my function by adding y to the set of local variables:  f[case : True | False] := Module[{x, y, rhs}, If[case, rhs[x_] = y[x] Cos[x + y[x]], rhs[x_] = y[x] ]; NDSolve[{y'[x] == rhs[x], y[0] == 1}, y, {x, 0, 30}] ]  If I run the function now, it would still produce the correct solution curves. However the output is now displayed for example as {{y$25947 → InterpolatingFunction[...]}}


where the concrete number after the dollar sign changes every time I execute.

So something is going wrong. I am not sure what, and how to fix it.

Thanks for help!

• "However y is a global variable, so I would like to protect it inside my function..." Just curious, but what problem does y being a global variable cause? Apr 8 '20 at 15:28
• No problem, as long as one keeps the overview of what variables are used inside ones functions. In order of not having to keep this overview, I wanted to make it a local variable. Apr 8 '20 at 16:29

Try this

ClearAll[f];
f[case : True | False] :=
Module[{x, y, rhs},
If[case, rhs[x_] = y[x] Cos[x + y[x]], rhs[x_] = y[x]];
y /. First@NDSolve[{y'[x] == rhs[x], y[0] == 1}, y, {x, 0, 30}]]


Then if you run

intp = f[True]


you will get an interpolation function you can use elsewhere

Plot[intp[x], {x, 0, 30}]


Hope that helps

The variables that you make local to the module, y in this case, are changed to have a unique number attached to them. This stops them interfering with variables outside the module. If you output the variable then you see how it was formulated within the module.

• I suppose that works, thanks! Do you know by any chance what exactly went wrong? It would be good to understand, so I can avoid making similar mistakes. Apr 8 '20 at 15:05
• @Britzel I have added a comment to show how it works. Let me know if you need more . You can also look up Block and With which are variants on Module handling internal variables in different manners.
– Hugh
Apr 8 '20 at 15:25
• This makes a lot of sense. Thanks for the explanation! Also, I will check Block and With indeed. I was not aware of those. Cheers! Apr 8 '20 at 16:27
• With any newer version of Mathematica you could also use NDSolveValue which would make your could a bit shorter and probably clearer. It seems to be made for exactly that use-case... Apr 9 '20 at 23:44

You could use a formal symbol inside f to avoid problems, since it can't be assigned a value.

f[case : True | False] := Module[{x, rhs},
If[case, rhs[x_] = \[FormalY][x] Cos[x + \[FormalY][x]], rhs[x_] = \[FormalY][x]];
NDSolve[{\[FormalY]'[x] == rhs[x], \[FormalY][0] == 1}, \[FormalY], {x, 0, 30}]]

(* trying to break it -- fails! *)
\[FormalY] = 1;
f[True]
(* Set::wrsym Symbol \[FormalY] is Protected. *)


• Good solution! Thanks a lot! Apr 9 '20 at 15:01