RE: Beginner question on local vars./scoping

*To*: mathgroup at smc.vnet.net*Subject*: [mg33674] RE: [mg33660] Beginner question on local vars./scoping*From*: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>*Date*: Sat, 6 Apr 2002 00:48:49 -0500 (EST)*Sender*: owner-wri-mathgroup at wolfram.com

> -----Original Message----- > From: Mark Pilloff [mailto:mdp1REMOVETHIS at uclink4.berkeley.edu] To: mathgroup at smc.vnet.net > Sent: Friday, April 05, 2002 2:41 AM > To: mathgroup at smc.vnet.net > Subject: [mg33674] [mg33660] Beginner question on local vars./scoping > > > Hi, > > I've written a function of the sort: > > function := Do some stuff > > The situation is that the 'Do some stuff' depends upon > various global vars. > but some of the 'stuff' yields the same result unless some of > the global > vars have changed. I'd like to memoize the results and have > some local vars > to function that will remember the value of the global vars > when function > was last called and only recompute if necessary. Right now I > have global > vars like lastValueOfVarSeen and lastResultOfStep2 but I'd > prefer to make > them local to function but still permanent. > > 1. How can I do this? > 2. Is there a better / more standard way to achieve the goal > described > above? > > Thanks for any help, > Mark > > > Mark, certainly the subject of your post doesn't adequately describe your problem! Or perhaps I didn't understand right... Anyway, I'll give you two suggestions, which, hopefully, might help you. I assume that you want to memorize the results of a function, let's call it f, perhaps dependent on some parameters *and* some global variables. The function will be evaluated (anew) if new values of the parameters occur *or* if one of the global variables has changed. Your (current) global variables are ValueOfVarSeen, ResultOfStep2. Proposal (1) The definitions: In[2]:= f[some_, thing_] := f[some, thing, ValueOfVarSeen, ResultOfStep2] In[3]:= f[some_, thing_, _, _] := (Print["calculated anew!"]; With[{newvalue = some * ValueOfVarSeen + thing * ResultOfStep2}, f[some, thing, ValueOfVarSeen, ResultOfStep2] := (Print["reused!"]; newvalue); newvalue]) In[4]:= f[__] := Print["storage error"] In[5]:= ?f You see: the values of the globals are stored together with the parameter values of your calculation. I have inserted some Print statements as to monitor whether stored or new values are returned. For the (tested and running!) application you may remove them. Test: In[6]:= ValueOfVarSeen = 1; ResultOfStep2 = 2; In[8]:= f[4, 5] >From In[8]:= "calculated anew!" Out[8]= 14 In[9]:= f[4, 5] >From In[9]:= "reused!" Out[9]= 14 In[10]:= ValueOfVarSeen = 2; In[11]:= f[4, 5] >From In[11]:= "calculated anew!" Out[11]= 18 In[12]:= f[5, 5] >From In[12]:= "calculated anew!" Out[12]= 20 In[13]:= f[4, 5] >From In[13]:= "reused!" Out[13]= 18 In[14]:= ValueOfVarSeen = 1; In[15]:= f[4, 5] >From In[15]:= "reused!" Out[15]= 14 In[16]:= ?f In[17]:= Quit[] A characteristic of this solution is that all calculated values are kept, such that, if you return to a prior value of a global variable, the corresponding old calculated values are returned. This may be desirable or not. If not, follow proposal (2). This is a bit more tricky: all stored values are Cleared if the function is called with changed global variables. But then the definitions are cleared too, so they have to be renewed immediately after. This is done with the conditional call to f; of course we now have to store the old global values. The definitions: In[1]:= Clear[f, ff, lastValueOfVarSeen, lastResultOfStep2] In[2]:= f[some_, thing_] /; (ValueOfVarSeen =!= lastValueOfVarSeen || ResultOfStep2 =!= lastResultOfStep2) := (Clear[ff]; ff[s_, t_] := (Print["calculated anew!"]; With[{newvalue = s * ValueOfVarSeen + t * ResultOfStep2}, ff[s, t] := (Print["reused!"]; newvalue); newvalue]); lastValueOfVarSeen = ValueOfVarSeen ; lastResultOfStep2 = ResultOfStep2; ff[some, thing]) In[3]:= f[some_, thing_] := ff[some, thing] In[4]:= ff[__] := Print["storage error"] In[5]:= ?f In[6]:= ?? ff Test: In[7]:= ValueOfVarSeen = 1; ResultOfStep2 = 2; In[9]:= f[4, 5] >From In[9]:= "calculated anew!" Out[9]= 14 In[10]:= f[4, 5] >From In[10]:= "reused!" Out[10]= 14 In[11]:= f[5, 5] >From In[11]:= "calculated anew!" Out[11]= 15 In[12]:= ValueOfVarSeen = 2; In[13]:= f[4, 5] >From In[13]:= "calculated anew!" Out[13]= 18 In[14]:= f[4, 5] >From In[14]:= "reused!" Out[14]= 18 In[15]:= ValueOfVarSeen = 1; In[16]:= f[4, 5] >From In[16]:= "calculated anew!" Out[16]= 14 In[17]:= ?ff In[18]:= Quit[] -- Hartmut Wolf