0
$\begingroup$
Manipulate[g[x_] = f;
 Plot[{g[x], g[2]}, {x, -9, 9}],
 {{f, "Enter a function...", "f(x)  ="}}]

Hi, I'm relatively new to Mathematica and this is my first post on stackexchange, so forgive me for any formatting issues in my post.

I'm trying to create a program that takes a function from the user through Manipulate and plots the function. So far I've been able to do this, though my issue is that I also want to plot the horizontal line given by the function evaluated at some number (2 in this case), but I am simply getting the plot g[x]=x twice.

If I type

f = x;
g[x_] = f;

then g[x] returns x, and g[2] returns 2, which is what I am looking for. Though when I put everything in Manipulate, g[x] and g[2] both return x. I think I understand why, because g[2] calls on f, which is x, so the f is not being replaced by x prior to the substitution of 2. I just don't understand how to fix this problem.

Additionally, the Manipulate part is necessary because I want to use the same concept here in a separate project that I'm working on. In the other project I will need to take the arbitrary input function g[x_] = f and use it for other calculations within the same Manipulate block, i.e. plotting a point such as (2,g[2]+g[5]).

Thanks! :)

$\endgroup$
3
  • $\begingroup$ First execute this: Manipulate[g[x_] = f;Information["g"], {{f, "Enter a function...", "f(x) ="}}]. What you'll see is that the formal argument of g isn't actually x. That explains why g[x] and g[2] evaluate to the same thing. I'll have to fiddle with it a bit to come up with something that works and isn't ugly--unless someone else beats me to it. $\endgroup$
    – lericr
    May 19, 2022 at 20:28
  • $\begingroup$ Manipulate[g[x_] := f; Plot[Evaluate@{g[x], g[x] /. x -> 2}, {x, -9, 9}], {{f, "Enter a function...", "f(x) ="}}] $\endgroup$
    – Bob Hanlon
    May 19, 2022 at 20:42
  • $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$
    – Michael E2
    Jun 18, 2022 at 22:27

2 Answers 2

1
$\begingroup$

Manipulate does some code rewriting that is meant to make life easier for the user. Mostly it succeeds, but in this case, not really. For instance, one of its rewriting actions is to replace the Manipulate variables like f with a symbol that has two dollar signs appended like f$$. This replacement triggers a renaming of the argument of g, similar to what happens in the following (see for instance, Local variables):

With[{f = f$$}, Hold[g[x_] = f]]
(*  Hold[g[x$_] = f$$]  *)

So the argument of g becomes x$ and the variable in f$$ is x. So g[<arg>] evaluates to f$$ no matter what <arg> is, for instance, whether <arg> is x or 2 in the Plot code in the OP's Manipulate.

The renaming occurs in certain expressions that localize pattern variables, like Set. A standard way to disable renaming is to let the substitution occur within Hold[..] and then Apply Set to replace Hold (see for instance, I define a variable as local to a module BUT then the module uses its global value! Why?):

Manipulate[
 Set @@ Hold[g[x_], f]; 
 Plot[Evaluate@{g[x], g[2]}, {x, -9, 9}], {{f, Null}, 
  InputField[Dynamic@f, FieldHint -> "Enter a function of x"] &},
 {{g, g}, ControlType -> None},
 TrackedSymbols :> {f}]
$\endgroup$
0
$\begingroup$

How about something like this?

Manipulate[
  Plot[{(userFn /. x -> #) &[plotX], (userFn /. x -> #) &[2]}, {plotX, -9, 9}],
  {{userFn, x, "f(x) ="}}]

I'm not sure that using plotX rather than just x is necessary, but it clarifies the intent.

Edit

I made it too complicated. How about this:

Manipulate[
  Plot[Evaluate[{userFn, userFn /. x -> 2}], {x, -3, 3}],
  {{userFn, x, "f(x) ="}}]
$\endgroup$
1
  • $\begingroup$ Thanks a bunch! That's exactly what I was looking for :) $\endgroup$
    – dcjs34
    May 20, 2022 at 19:04

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.