Skip to main content

dynamic - How are parameters evaluated for a Plot in Manipulate


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

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...