MathGroup Archive 2011

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

Search the Archive

Re: Interaction of Remove and Global variables in a Module

  • To: mathgroup at smc.vnet.net
  • Subject: [mg120219] Re: Interaction of Remove and Global variables in a Module
  • From: DrMajorBob <btreat1 at austin.rr.com>
  • Date: Wed, 13 Jul 2011 03:13:01 -0400 (EDT)

Removing a doesn't remove anything:

Subscript[a, 0] = 1;
Subscript[a, n_] := Subscript[a, n] = 2 Subscript[a, n - 1];

Subscript[a, 2]

4

Remove@a

?? Subscript

(* usage note omitted *)

Subscript[Removed[a],0]=1

Subscript[Removed[a],1]=2

Subscript[Removed[a],2]=4

Subscript[Removed[a],n_]:=Subscript[Removed[a],n]=2  
Subscript[Removed[a],n-1]

As you can see, Subscript still "remembers" all the values you gave to a.  
It simply can't use them.

So. There are at least three better alternatives.

First is:

ClearAll[Subscript]

??Subscript

(* usage note *)

The second (my personal favorite) is to never define Subscript as a  
function in the first place.

If what you want is subscripted variables to LOOK like subscripted  
variables, that can only happen when they don't have values, so defining  
them to have values defeats your purpose.

If you want a[n] to appear subscripted when it doesn't have a value,  
that's easy enough:

ClearAll[a,Subscript] (* just in case you ran other code before this *)
Sum[a[n]^2, {n, 10}] /. a[k_] :> Subscript[a, k]

\!\(
\*SubsuperscriptBox[\(a\), \(1\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(2\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(3\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(4\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(5\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(6\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(7\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(8\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(9\), \(2\)] +
\*SubsuperscriptBox[\(a\), \(10\), \(2\)]\)

The third alternative is not to bother With Remove, Clear, or ClearAll  
unless you need NEW definitions for a. The memory you could save is likely  
to be inconsequential.

Bobby

On Tue, 12 Jul 2011 05:59:57 -0500, Gianluca Gorni  
<gianluca.gorni at uniud.it> wrote:

>
> Suppose I define a recursive sequence
>
> a[0] = 1; a[n_] := a[n] = 2 a[n - 1]
>
> If I evaluate a[2], then its value will be kept in memory.
> When I need to clear and reuse the symbol a, I use Clear[a].
>
> Suppose now that I do it more traditional-looking:
>
> Subscript[a, 0] = 1; Subscript[a, n_] :=
>  Subscript[a, n] = 2 Subscript[a, n - 1];
>
> If I call Subscript[a, 2], its value will be remembered.
> What can I do to clear the values? Clear[a] and ClearAll[a]
> do not work. Remove[a] does work.
>
> Is there a better alternative?
>
> Best regards,
> Gianluca
>
> On 09/lug/2011, at 13.32, DrMajorBob wrote:
>
>> So far, I haven't heard a purpose for Remove that ClearAll does not  
>> serve
>> just as well... without the side-effect of "spoiling" other symbols.
>>
>> Bobby
>>
>> On Fri, 08 Jul 2011 03:53:55 -0500, Leonid Shifrin <lshifr at gmail.com>
>> wrote:
>>
>>> Brian,
>>>
>>> The problem you encountered is actually more subtle. Remember that when
>>> you
>>> use Remove (as compared to Clear or ClearAll), the symbol is completely
>>> removed
>>> from the system. This is a pretty disruptive operation. Now, what  
>>> should
>>> the system do if the symbol you are removing is referenced by some  
>>> other
>>> symbols?
>>> Keeping it there unchanged would mean that the symbol has not been
>>> really removed
>>> from the system. The solution used in Mathematica is to change a
>>> reference to a
>>> symbol
>>> (say "a") to Removed[a]. In practice, this means that, even when you
>>> re-introduce
>>> the symbol, those definitions that were involving it are still  
>>> "spoiled"
>>> and
>>> can not
>>> be used.  IMO, this is a very sensible design, but this is what leads  
>>> to
>>> the
>>> behavior
>>> that puzzled you. Have a look:
>>>
>>> f[b_]:=Module[{t},a[t_]=b*t^2;]
>>> Remove[a];
>>> ?f
>>>
>>> Global`f
>>> f[b_]:=Module[{t},Removed[a][t_]=b t^2;]
>>>
>>> What you have to do in your approach is to re-run the definition for
>>> "f", to
>>> be able to
>>> use it. This is however pretty error-prone. You can cure this by  
>>> calling
>>> Clear or ClearAll
>>> instead of Remove, but even this approach I don't consider a good
>>> practice.
>>> Even though
>>> you use "a"  as a function, calling Clear or Remove on it means that  
>>> in a
>>> way, you use
>>> it as a global variable. In this post:
>>>
>>> =
> http://stackoverflow.com/questions/6236458/plot-using-with-versus-plot-using-block-mathematica/6236808#6236808
>>>
>>> there is a lengthy discussion why making implicit dependencies on  
>>> global
>>> variables is a
>>> bad practice.
>>>
>>> Here are a few ways out. What you seem to want is to generate a  
>>> function
>>> with embedded
>>> parameters (a closure). One way is to generate a pure function and  
>>> return
>>> it:
>>>
>>> In[31]:= Clear[f];
>>> f[b_]:=Function[t,b*t^2];
>>> a = f[3];
>>> a[t]
>>> a=f[4];
>>> a[t]
>>> Remove[a];
>>> a = f[5];
>>> a[t]
>>>
>>> Out[34]= 3 t^2
>>> Out[36]= 4 t^2
>>> Out[39]= 5 t^2
>>>
>>> Another way is to explicitly pass to "f"  the symbol to which you want  
>>> to
>>> assign
>>> the definition:
>>>
>>> In[40]:= Clear[ff,a];
>>> ff[fname_Symbol,b_]:=Module[{t},fname[t_]=b*t^2;];
>>> ff[a,3];
>>> a[t]
>>> ff[a,4];
>>> a[t]
>>> Remove[a];
>>> ff[a,5];
>>> a[t]
>>>
>>> Out[43]= 3 t^2
>>> Out[45]= 4 t^2
>>> Out[48]= 5 t^2
>>>
>>> By making the function name an explicit parameter to "ff", you make the
>>> problematic
>>> situation above impossible to happen.
>>>
>>> HTH
>>>
>>> Regards,
>>> Leonid
>>>
>>>
>>>
>>>
>>>
>>> On Thu, Jul 7, 2011 at 3:28 PM, blamm64 <blamm64 at charter.net> wrote:
>>>
>>>> This is what I get for querying SetDelayed
>>>>
>>>> In[1]:= ?SetDelayed
>>>> lhs:=rhs assigns rhs to be the delayed value of lhs. rhs is maintained
>>>> in an unevaluated form. When lhs appears, it is replaced by rhs,
>>>> evaluated afresh each time.  >>
>>>>
>>>> Note particularly the above reads AFRESH EACH time.  It appears then
>>>> the following is inconsistent behavior based on the above description:
>>>>
>>>> In[2]:= f[b_]:=Module[{t},a[t_]=b*t^2;]
>>>> In[3]:= a[t]
>>>> Out[3]= a[t]
>>>> In[4]:= f[3]
>>>> In[5]:= a[t]//InputForm
>>>> Out[5]//InputForm=
>>>> 3*t^2
>>>> In[6]:= f[5]
>>>> In[7]:= a[t]//InputForm
>>>> Out[7]//InputForm=
>>>> 5*t^2
>>>> In[8]:= Remove[a]
>>>> In[9]:= f[4]
>>>> In[10]:= a[t]//InputForm
>>>> Out[10]//InputForm=
>>>> a[t]
>>>>
>>>> Apparently AFRESH is not an accurate description of how SetDelayed
>>>> operates in this case, or I am missing something about this particular
>>>> interaction of Module, Remove, and global variables inside Modules.
>>>>
>>>> However, if I go back, after executing the last line above (<a> has
>>>> been Removed), and place the cursor in the input line where <f> is
>>>> defined and hit Enter, which I thought would be identical to just
>>>> evaluating <f> AFRESH again, and then execute the <f[4]> line again,
>>>> then the global <a> definition is re-constituted.
>>>>
>>>> The documentation for Remove reads the name is no longer recognized by
>>>> Mathematica.  My understanding is that if the same name is defined
>>>> AFRESH, it will once again be recognized.
>>>>
>>>> So if anyone would let me know what I am missing, regarding why the
>>>> definition of <a> is not created AFRESH each time <f> is evaluated, I
>>>> would appreciate it.
>>>>
>>>> Please don't construe the definition of <f> as my way of
>>>> 'parameterizing' a function definition, I just use that definition to
>>>> convey the apparent inconsistency.
>>>>
>>>> -Brian L.
>>>>
>>>>
>>
>>
>> --
>> DrMajorBob at yahoo.com
>>
>
>


-- 
DrMajorBob at yahoo.com


  • Prev by Date: Re: How to write a "proper" math document
  • Next by Date: Search and replace variable name with subscript
  • Previous by thread: Re: Interaction of Remove and Global variables in a Module
  • Next by thread: Numerical optimization