MathGroup Archive 2011

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

Search the Archive

Re: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)

  • To: mathgroup at smc.vnet.net
  • Subject: [mg116131] Re: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)
  • From: Albert Retey <awnl at gmx-topmail.de>
  • Date: Thu, 3 Feb 2011 05:28:37 -0500 (EST)

Am 02.02.2011 12:13, schrieb Guido Walter Pettinari:
> Dear Mathematica group,
> 
> I would like to ask you a simple question that, if answered, would
> make my life much easier :-)
> 
> Does anybody know how to trigger a warning/error message whenever a
> particular symbol is used as an iterator? By iterator, I mean the
> second argument of functions like Plot, Table, Sum, i.e. the "i" in
> Table [ i^2,  {i, 10} ]
> 
> I am looking for this feature since I get errors/unmeaning results
> whenever I use as an iterator a variable already defined in some other
> part of the code (which I may have forgot of).
> E.g., this happens with NDSolve.  Take the following example:
> 
> tmin = 0;
> tmax = 1;
> sol[a_] := NDSolve [ {y'[t] == a y[t], y[0] == 1},  y,  {t, tmin,
> tmax} ]
> exp[a_, t_] := y[t] /. sol[a]
> 
> The following Plot command does not work:
> Plot[exp[2, t], {t, tmin, tmax}]
> while changing the iterator name works:
> Plot[exp[2, x], {x, tmin, tmax}]
> 
> I know that (i) the first Plot command does not work because Plot
> (like Table and Sum) has the HoldAll attribute, and (ii) using the
> Evaluate function on exp[2, t] solves the problem.
> 
> However, say that I publish a package that uses a variable in the same
> way I use "t" in the above example.  How does the user of the package
> know that she should not use that variable to iterate?  It would be
> nice if she gets a warning message whenever she tries to do so.
> 
> I guess that a workaround would be to use a Unique[] symbol, either as
> an iterator or as, say, the NDSolve independent variable.... do you
> think this is doable?

I'm not sure whether I oversee a complication in your question, but I
think proper localization of the variables used in your functions would
be the cleanest way to solve this: it wouldn't ever be necessary to warn
the user to not use a particular symbol. This is just one way to avoid
the problem altogether:

tmin = 0;
tmax = 1;
ClearAll[sol];
sol[a_, tt_] := Block[{y, t},
  y[tt] /.
   First[NDSolve[{y'[t] == a y[t], y[0] == 1}, y, {t, tmin, tmax}]]
  ]

Plot[sol[2, t], {t, tmin, tmax}]

But I think an even better approach would be to just return a function
(or InterpolatingFunction) with no argument and to not redo the NDSolve
for every of the t you want to plot, like so:

tmin = 0;
tmax = 1;
sol[a_] := sol[a] = Module[{y,t},
  y /. First[NDSolve[{y'[t] == a y[t], y[0] == 1}, y, {t, tmin, tmax}]]
  ]

you could make a plot then like this:

Plot[sol[2][t], {t, tmin, tmax}]

but you could also do stuff like this:

sol4 = sol[4];

Plot[sol4[t],{t,tmin,tmax}]
Integrate[sol4[t],{t,tmin,tmax}]

note that that will all work with only one call to NDSolve...

hth,

albert





  • Prev by Date: Re: Mystifying Scoping of Piecewise Variable?
  • Next by Date: Re: finding area in ListContourPlot
  • Previous by thread: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)
  • Next by thread: Re: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)