I am trying to get my head around how Manipulate
evaluates functions in a Plot. I have read the introduction to Manipulate, and introduction to Dynamic, but I still can't figure it.
For my specific example, I have a function bigA
parameterised by m1
and m2
(this relates to question),
bigA[t_]:= (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
So when I try to plot it in Manipulate,
Manipulate[
Plot[bigA[t], {t, 1, 10}],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
Nothing appears. I presume this is because m1
and m2
aren't being evaluated. But I don't know what the order is supposed to be.
The thing is, this seems to work when I Evaluate
and don't plot, i.e,
Manipulate[Evaluate@bigA[t],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
So couldn't I just stick a Plot
command in there somewhere?
Answer
The problem is that inside the Manipulate
, m1
and m2
are replaced with localized versions (as in Module
) rather than assigned (as in Block
). Since the m1
and m2
from bigA
are outside the Manipulate
, and bigA[t]
is evaluated only after the replacement of m1
and m2
inside the Manipulate
, they are not affected by the manipulation.
The best solution is to give m1
and m2
as extra arguments:
bigA[t_, m1_, m2_] := (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
Manipulate[Plot[bigA[t, m1, m2], {t, 1, 10}],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
If for some reason you cannot do that, you can also use replacement rules as follows:
bigA[t_] := (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
Manipulate[Plot[bigA[t]/.{m1->mm1,m2->mm2}, {t, 1, 10}],
{{mm1, 1.4}, 0.8, 3},
{{mm2, 1.4}, 0.8, 3}]
This works because ReplaceAll
(/.
) does the replacements only after the left hand side has been evaluated, and the mm1
and mm2
are now inside the Manipulate
, so they can be properly localized.
About your edit:
By adding Evaluate@
at the beginning of the argument to Manipulate
, you override Mathematica's order of evaluation. So with
Manipulate[Evaluate@bigA[t],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
Mathematica first evaluates bigA[t]
to (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
, and only then proceeds to evaluate the Manipulate
, which therefore sees the m1
and m2
.
Now this will not work with Plot
, because the whole Plot
statement will be executed, before Manipulate
will have a chance to insert m1
and m2
. So when Plot
evaluates bigA[t]
, it will receive an expression containing m1
and m2
instead of a number, and thus produce an empty graph. This graph (which no longer contains any trace of m1
or m2
) will then be passed to Manipulate
. Of course replacing m1
and m2
at this stage doesn't work, because they already vanished.
So in essence, while without Evaluate
, m1
and m2
are substituted too late, with Evaluate@Plot
they are consumed too early.
Now you might have the idea to use Manipulate[Plot[Evaluate@bigA[t],...],...]
instead, in order to evaluate bigA[t]
(to get m1
and m2
visible) but not Plot
(because that only works after m1
and m2
got a value). However that doesn't work either, because Evaluate
only affects order of evaluation when it appears as immediate argument of the expression being evaluated. So while evaluating Manipulate
, the Evaluate
in the argument of Plot
is not considered. It will be considered at the time Plot
is evaluated, but at that time it's already too late.
Comments
Post a Comment