Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Help

  • To: mathgroup at smc.vnet.net
  • Subject: [mg92369] Re: Help
  • From: "jwmerrill at gmail.com" <jwmerrill at gmail.com>
  • Date: Mon, 29 Sep 2008 07:08:02 -0400 (EDT)
  • References: <gbjmbb$3ah$1@smc.vnet.net> <48DDBD6E.4080304@gmail.com>

On Sep 27, 6:49 am, "Rui Rojo" <rui.r... at gmail.com> wrote:
> Thanks a lot :) .
> I'll go on bothering, feel free not to answer, hehe...
>
> I'm trying to understand how all this works.
> If I put in a variable an expression, like
> expr = 2*x+65-t;
> then I can't use it in certain situations because mathematica seems to
> expect to "see" the x and t, but in some others I can.
> for example
> expr = 2*x+65-t; Animate[Plot[expr, {x, 0, 4}], {t, 0, 5}];
> doesn't work...
> neither does:
> ran={x, 0, 4}; Plot[Sin[x], ran]
> but
> Clear[expr];expr=2+x;Plot[expr, {x, 0, 4}]
> does work.
> In some of the places where it doesn't work, you seem to be able to sort =
the
> problem by declaring expr[x_, etc]=etc etc and then using expr[x, etc].=
..
> but not all the times... in the case of ran, it doesn't work either.
> How exactly does all of this work, or where can I read about it? i can't
> find anything clear in the Help...
> Is there any way to tell mathematica: "ok, heere replace expr for what yo=
u
> have stored, imagine instead of expr it says what i read when i type expr
> and press shift+enter"... or how do you think i should manage all this? j=
ust
> guessing, testing and changing?

Hi Rui,

The confusion is caused by the fact that Plot does not evaluate its
arguments in quite the same way that many other functions do.  Plot
has the attribute HoldAll, which means that it doesn't immediately
evaluate it's arguments.

In[1]:= Attributes[Plot]

Out[1]= {HoldAll, Protected}

Consider reading the tutorial on Attributes, and then as much of
"Evaluation of Expressions" as you can stomach.  As an aside, as your
understanding progresses, you'll want to read up on and deeply
understand manipulation of lists and pattern matching.  These are the
foundations of Mathematica.  Anyway, back to your problem.  We can
make our own function with the attribute HoldAll.  First the usual
way:

In[2]:= ran = {x, 0, 4};
f[ran]
Out[3]= f[{x, 0, 4}]

The definition of ran is automatically substituted here.  Now with
HoldAll:

In[4]:= Attributes[f]
Out[4]= {}

In[5]:= SetAttributes[f, HoldAll]

In[6]:= Attributes[f]
Out[6]= {HoldAll}

In[7]:= f[ran]
Out[7]= f[ran]

Now the definition of ran is not automatically substituted.  In order
to get the substitution to happen, we can use Evaluate

In[8]:= f[Evaluate[ran]]
Out[8]= f[{x, 0, 4}]

And indeed, this is what you need to do for Plot:

In[9]:= Plot[Sin[x], Evaluate[ran]]

This also solves your "Onda" question below:

> so i put in a for loop something like
> Onda+= Sin[blabla]
> now I have my wave pack stored in Onda, but I want to make it a function =
and
> I can't... If I do f[x_, t_]:=Onda
> it doesn't work :S

In[1]:= onda = Sin[x];
onda += Sin[3 x];

In[3]:= g[x_] := onda

In[4]:= g[5]
Out[4]= Sin[x] + Sin[3 x]

In[5]:= g[x_] := Evaluate[onda]

In[6]:= g[5]
Out[6]= Sin[5] + Sin[15]

Just like Plot, the SetDelayed operator, :=, has attribute HoldAll.
The Set operator does not have attribute HoldAll, so you can actually
do

In[9]:= g[x_] = onda;

In[10]:= g[5]
Out[10]= Sin[5] + Sin[15]

Incidentally, once you've read up on list manipulation, it might feel
more natural to avoid the += and For loop, and just do something like
this:

In[14]:= onda = Plus @@ Table[1/w*Sin[w x], {w, 1, 9, 2}]
Out[14]= Sin[x] + 1/3 Sin[3 x] + 1/5 Sin[5 x] + 1/7 Sin[7 x] +
 1/9 Sin[9 x]

The case of Animate is a little more challenging.  It also has
attribute HoldAll.  Take a look at the difference between the
following (since the output is graphical, you'll need to paste this
into your own session to see what I'm talking about):

In[35]:= expr = 2*x + 65 - t
Out[35]= 65 - t + 2 x

In[36]:= Animate[expr, {t, 0, 5}]

In[37]:= Animate[Evaluate[expr], {t, 0, 5}]

The trouble with putting Plot inside Animate is that both of them have
attribute HoldAll.  If you put an Evaluate around the first argument
of Plot, it doesn't fire because it is still being held by Animate.
We can see the same thing happening if we put a call to plot inside
our HoldAll function f:

In[55]:= f[Plot[Evaluate[expr], {x, 0, 4}]]
Out[55]= f[Plot[Evaluate[expr], {x, 0, 4}]]

On the other hand, wrapping Plot in Evaluate makes it try to plot
before it has a value of t, which gives you a blank plot.  So I
actually don't see any easy way to get around this just using
strategically placed Evaluate calls.  In hairy cases like these
(actually in lots of cases), the With statement is helpful:

In[57]:= With[{expr = 2*x + 65 - t},
 Animate[Plot[expr, {x, 0, 4}], {t, 0, 5}]]

produces a fine looking animation.  Or if you don't want to type in
the actual expression right there, you can use the somewhat odd
looking:

In[58]:= With[{expr = expr},
 Animate[Plot[expr, {x, 0, 4}], {t, 0, 5}]]

You'll find that many of the other numerical functions like
NIntegrate, FindMinimum, and FindRoot also have the attribute HoldAll,
and thus also sometimes benefit from a strategically placed Evaluate
call, or a With wrapper.

Regards,

Jason Merrill


  • Prev by Date: Re: Help
  • Next by Date: Re: Re: How to debug init.m?
  • Previous by thread: Re: Help
  • Next by thread: Workbench complains about an invalid LinkObject number