Re: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)
- To: mathgroup at smc.vnet.net
- Subject: [mg116181] Re: Protect a variable against being used as an iterator (related to the HoldAll - Evaluate problem)
- From: Guido Walter Pettinari <coccoinomane at gmail.com>
- Date: Fri, 4 Feb 2011 01:39:52 -0500 (EST)
Thank you very much for the answer! This completely solves my issue. I did not realize it was so simple, now I am little bit ashamed :-) Best regards, Guido On Feb 3, 10:28 am, Albert Retey <a... at gmx-topmail.de> wrote: > 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