Clear memorized values but not symbol definition in Mathametica [duplicate] - wolfram-mathematica

I'm a bad cacher: Sometimes, when no one is watching, I'll cache results without including the full context like so:
f[x_]:=f[x]=x+a;
a=2; f[1];
DownValues[f]
Out[2]= {HoldPattern[f[1]]:>3,HoldPattern[f[x_]]:>(f[x]=x+a)}
This leads to horribly subtle bugs, and, more importantly, to the need for clearing the cache when I change the context. One way of clearing the cache is to completely Clear the symbol and repeat the definitions, but this is not really a solution.
What I would really like is a method for clearing all pattern-free DownValues associated with a symbol.
For clarity, I'll include my present solution as an answer, but if fails on two counts
It only clears DownValues with all-numeric arguments
For aesthetical reasons, I'd like to avoid using Block to grab the DownValues.
Any ideas on how to improve ClearCache?

I've made similar functions in the past (but I can't remember where).
Does the following code do all that you need?
ClearCache[f_] := DownValues[f] = DeleteCases[DownValues[f],
_?(FreeQ[First[#], Pattern] &)]
This maybe should be extended to UpValues and SubValues. And the Head of f restricted to Symbol.

Just to complement the other excellent solution: if you have a very large list of DownValues and have strict efficiency requirements for ClearCache, you can significantly speed up the process by clearing all definitions and then reconstructing only those with patterns. Here is an example:
In[1]:=
ClearCache[f_] :=
DownValues[f] = DeleteCases[DownValues[f], _?(FreeQ[First[#], Pattern] &)];
In[2]:= Clear[f];
f[x_] := f[x] = x;
In[4]:= f /# Range[1000000];
In[5]:= ClearCache[f]; // Timing
Out[5]= {7.765, Null}
In[6]:=
ClearAll[createDefs];
SetAttributes[createDefs, HoldRest];
createDefs[f_, defs_: Automatic] :=
(createDefs[f] := (Clear[f]; defs); createDefs[f]);
In[9]:= Clear[f];
createDefs[f, f[x_] := f[x] = x]
In[11]:= f /# Range[1000000];
In[12]:= Length[DownValues[f]]
Out[12]= 1000001
In[13]:= createDefs[f]; // Timing
Out[13]= {1.079, Null}
In[14]:= DownValues[f]
Out[14]= {HoldPattern[f[x_]] :> (f[x] = x)}
Note that you only have to call the createDefs once with the code that creates the pattern-based definitions of the function. All other times, you call it as createDefs[f], because it memoizes the code needed to re-create the definitions, on the first call.
It is also possible that you don't want to grow huge caches, but this is out of your control in the simple f[x_]:=f[x]=rhs approach. In other words, the cache may contain lots of unnecessary old stuff, but in this approach you can not tell old (no longer used) definitions from the new ones. I partially addressed this problem with a package I called Cache, which can be found here together with the notebook illustrating its use. It gives you more control over the size of the cache. It has its problems, but may occasionally be useful.

Once I implemented a scheme to limit the number of memoized values (and conserve memory). Search for memoization on that page. This might be useful here as well (especially considering some of the questions marked as duplicate of this one).
The code
SetAttributes[memo, HoldAll]
SetAttributes[memoStore, HoldFirst]
SetAttributes[memoVals, HoldFirst]
memoVals[_] = {};
memoStore[f_, x_] :=
With[{vals = memoVals[f]},
If[Length[vals] > 200,
f /: memoStore[f, First[vals]] =.;
memoVals[f] ^= Append[Rest[memoVals[f]], x],
memoVals[f] ^= Append[memoVals[f], x]];
f /: memoStore[f, x] = f[x]]
memo[f_Symbol][x_?NumericQ] := memoStore[f, x]
memoClearCache[f_Symbol] :=
(Scan[(f /: memoStore[f, #] =.) &, memoVals[f]];
f /: memoVals[f] =. )
Usage and description
This version works with functions that take a single numerical argument. Call memo[f][x] instead of f[x] to use a memoized version. Cached values are still associated with f, so when f is cleared, they are gone. The number of cached values is limited to 200 by default. Use memoClearCache[f] to clear all memoized values.

This is my present solution to the problem, but as mentioned in the question is doesn't strictly look for pattern-free DownValues, nor is it very elegant.
Store the DownValues for f
In[6]:= dv = DownValues[f]
Out[6]= {HoldPattern[f[1]] :> 3, HoldPattern[f[x_]] :> (f[x] = x + a)}
Find the DownValues to clear inside a Block to avoid immediate evaluation
In[7]:= dv2clear = Block[{f},
Hold#Evaluate#Cases[dv,
HoldPattern[f[args__ /; Apply[And, NumericQ /# Flatten[{args}]]]], {3}]]
Out[7]= Hold[{f[1]}]
Apply Unset to the targeted DownValues inside the held list and then release
In[8]:= Map[Unset, dv2clear, {2}]
ReleaseHold#%
Out[8]= Hold[{(f[1]) =.}]
This works fine
In[10]:= DownValues[f]
Out[10]= {HoldPattern[f[x_]] :> (f[x] = x + a)}
And can be wrapped up like so:
ClearCache[f_] := Module[{dv, dv2clear},
(* Cache downvalues for use inside block *)
dv = DownValues[f];
(* Find the downvalues to clear in Block to avoid immediate evaluation *)
dv2clear = Block[{f},Hold#Evaluate#Cases[dv,HoldPattern[
f[args__ /; Apply[And, NumericQ /# Flatten[{args}]]]], {3}]];
(* Apply Unset to the terms inside the held list and then release *)
ReleaseHold#Map[Unset, dv2clear, {2}];]

Related

Using Evaluate with a Pure Function and SetDelayed

I want to evaluate f below by passing a list to some function:
f = {z[1] z[2], z[2]^2};
a = % /. {z[1]-> #1,z[2]-> #2};
F[Z_] := Evaluate[a] & ## Z ;
So now if I try F[{1,2}] I get {2, 4} as expected. But looking closer ?F returns the definition
F[Z_] := (Evaluate[a] &) ## Z
which depends on the value of a, so if we set a=3 and then evaluate F[{1,2}], we get 3. I know that adding the last & makes the Evaluate[a] hold, but what is an elegant work around? Essentially I need to force the evaluation of Evaluate[a], mainly to improve efficiency, as a is in fact quite complicated.
Can someone please help out, and take into consideration that f has to contain an Array[z,2] given by some unknown calculation. So writing
F[Z_] := {Z[[1]]Z[[2]],Z[[2]]^2}
would not be enough, I need this to be generated automatically from our f.
Many thanks for any contribution.
Please consider asking your future questions at the dedicated StackExchange site for Mathematica.
Your questions will be much less likely to become tumbleweeds and may be viewed by many experts.
You can inject the value of a into the body of both Function and SetDelayed using With:
With[{body = a},
F[Z_] := body & ## Z
]
Check the definition:
Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) ## Z$
You'll notice Z has become Z$ due to automatic renaming within nested scoping constructs but the behavior is the same.
In the comments you said:
And again it bothers me that if the values of z[i] were changed, then this workaround would fail.
While this should not be a problem after F[Z_] is defined as above, if you wish to protect the replacement done for a you could use Formal Symbols instead of z. These are entered with e.g. Esc$zEsc for Formal z. Formal Symbols have the attribute Protected and exist specifically to avoid such conflicts as this.
This looks much better in a Notebook than it does here:
f = {\[FormalZ][1] \[FormalZ][2], \[FormalZ][2]^2};
a = f /. {\[FormalZ][1] -> #1, \[FormalZ][2] -> #2};
Another approach is to do the replacements inside a Hold expression, and protect the rules themselves from evaluation by using Unevaluated:
ClearAll[f, z, a, F, Z]
z[2] = "Fail!";
f = Hold[{z[1] z[2], z[2]^2}];
a = f /. Unevaluated[{z[1] -> #1, z[2] -> #2}] // ReleaseHold;
With[{body = a},
F[Z_] := body & ## Z
]
Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) ## Z$

Using All in MapAt in Mathematica

I often have a list of pairs, as
data = {{0,0.0},{1,12.4},{2,14.6},{3,25.1}}
and I want to do something, for instance Rescale, to all of the second elements without touching the first elements. The neatest way I know is:
Transpose[MapAt[Rescale, Transpose[data], 2]]
There must be a way to do this without so much Transposeing. My wish is for something like this to work:
MapAt[Rescale, data, {All, 2}]
But my understanding is that MapAt takes Position-style specifications instead of Part-style specifications. What's the proper solution?
To clarify,
I'm seeking a solution where I don't have to repeat myself, so lacking double Transpose or double [[All,2]], because I consider repetition a signal I'm not doing something the easiest way. However, if eliminating the repetition requires the introduction of intermediate variables or a named function or other additional complexity, maybe the transpose/untranspose solution is already correct.
Use Part:
data = {{0, 0.0}, {1, 12.4}, {2, 14.6}, {3, 25.1}}
data[[All, 2]] = Rescale # data[[All, 2]];
data
Create a copy first if you need to. (data2 = data then data2[[All, 2]] etc.)
Amending my answer to keep up with ruebenko's, this can be made into a function also:
partReplace[dat_, func_, spec__] :=
Module[{a = dat},
a[[spec]] = func # a[[spec]];
a
]
partReplace[data, Rescale, All, 2]
This is quite general is design.
I am coming late to the party, and what I will describe will differ very little with what #Mr. Wizard has, so it is best to consider this answer as a complementary to his solution. My partial excuses are that first, the function below packages things a bit differently and closer to the syntax of MapAt itself, second, it is a bit more general and has an option to use with Listable function, and third, I am reproducing my solution from the past Mathgroup thread for exactly this question, which is more than 2 years old, so I am not plagiarizing :)
So, here is the function:
ClearAll[mapAt,MappedListable];
Protect[MappedListable];
Options[mapAt] = {MappedListable -> False};
mapAt[f_, expr_, {pseq : (All | _Integer) ..}, OptionsPattern[]] :=
Module[{copy = expr},
copy[[pseq]] =
If[TrueQ[OptionValue[MappedListable]] && Head[expr] === List,
f[copy[[pseq]]],
f /# copy[[pseq]]
];
copy];
mapAt[f_, expr_, poslist_List] := MapAt[f, expr, poslist];
This is the same idea as what #Mr. Wizard used, with these differences: 1. In case when the spec is not of the prescribed form, regular MapAt will be used automatically 2. Not all functions are Listable. The solution of #Mr.Wizard assumes that either a function is Listable or we want to apply it to the entire list. In the above code, you can specify this by the MappedListable option.
I will also borrow a few examples from my answer in the above-mentioned thread:
In[18]:= mat=ConstantArray[1,{5,3}];
In[19]:= mapAt[#/10&,mat,{All,3}]
Out[19]= {{1,1,1/10},{1,1,1/10},{1,1,1/10},{1,1,1/10},{1,1,1/10}}
In[20]:= mapAt[#/10&,mat,{3,All}]
Out[20]= {{1,1,1},{1,1,1},{1/10,1/10,1/10},{1,1,1},{1,1,1}}
Testing on large lists shows that using Listability improves the performance, although not so dramatically here:
In[28]:= largemat=ConstantArray[1,{150000,15}];
In[29]:= mapAt[#/10&,largemat,{All,3}];//Timing
Out[29]= {0.203,Null}
In[30]:= mapAt[#/10&,largemat,{All,3},MappedListable->True];//Timing
Out[30]= {0.094,Null}
This is likely because for the above function (#/10&), Map (which is used internally in mapAt for the MappedListable->False (default) setting, was able to auto-compile. In the example below, the difference is more substantial:
ClearAll[f];
f[x_] := 2 x - 1;
In[54]:= mapAt[f,largemat,{All,3}];//Timing
Out[54]= {0.219,Null}
In[55]:= mapAt[f,largemat,{All,3},MappedListable->True];//Timing
Out[55]= {0.031,Null}
The point is that, while f was not declared Listable, we know that its body is built out of Listable functions, and thus it can be applied to the entire list - but OTOH it can not be auto-compiled by Map. Note that adding Listable attribute to f would have been completely wrong here and would destroy the purpose, leading to mapAt being slow in both cases.
How about
Transpose[{#[[All, 1]], Rescale[#[[All, 2]]]} &#data]
which returns what you want (ie, it does not alter data)
If no Transpose is allowed,
Thread[Join[{#[[All, 1]], Rescale[#[[All, 2]]]} &#data]]
works.
EDIT: As "shortest" is now the goal, best from me so far is:
data\[LeftDoubleBracket]All, 2\[RightDoubleBracket] = Rescale[data[[All, 2]]]
at 80 characters, which is identical to Mr.Wizard's... So vote for his answer.
Here is another approach:
op[data_List, fun_] :=
Join[data[[All, {1}]], fun[data[[All, {2}]]], 2]
op[data, Rescale]
Edit 1:
An extension from Mr.Wizard, that does not copy it's data.
SetAttributes[partReplace, HoldFirst]
partReplace[dat_, func_, spec__] := dat[[spec]] = func[dat[[spec]]];
used like this
partReplace[data, Rescale, All, 2]
Edit 2:
Or like this
ReplacePart[data, {All, 2} -> Rescale[data[[All, 2]]]]
This worked for me and a friend
In[128]:= m = {{x, sss, x}, {y, sss, y}}
Out[128]= {{2, sss, 2}, {y, sss, y}}
In[129]:= function[ins1_] := ToUpperCase[ins1];
fatmap[ins2_] := MapAt[function, ins2, 2];
In[131]:= Map[fatmap, m]
Out[131]= {{2, ToUpperCase[sss], 2}, {y, ToUpperCase[sss], y}}

Trying to get Mathematica to approximate an integral

I am trying to get Mathematica to approximate an integral that is a function of various parameters. I don't need it to be extremely precise -- the answer will be a fraction, and 5 digits would be nice, but I'd settle for as few as 2.
The problem is that there is a symbolic integral buried in the main integral, and I can't use NIntegrate on it since its symbolic.
F[x_, c_] := (1 - (1 - x)^c)^c;
a[n_, c_, x_] := F[a[n - 1, c, x], c];
a[0, c_, x_] = x;
MyIntegral[n_,c_] :=
NIntegrate[Integrate[(D[a[n,c,y],y]*y)/(1-a[n,c,x]),{y,x,1}],{x,0,1}]
Mathematica starts hanging when n is greater than 2 and c is greater than 3 or so (generally as both n and c get a little higher).
Are there any tricks for rewriting this expression so that it can be evaluated more easily? I've played with different WorkingPrecision and AccuracyGoal and PrecisionGoal options on the outer NIntegrate, but none of that helps the inner integral, which is where the problem is. In fact, for the higher values of n and c, I can't even get Mathematica to expand the inner derivative, i.e.
Expand[D[a[4,6,y],y]]
hangs.
I am using Mathematica 8 for Students.
If anyone has any tips for how I can get M. to approximate this, I would appreciate it.
Since you only want a numerical output (or that's what you'll get anyway), you can convert the symbolic integration into a numerical one using just NIntegrate as follows:
Clear[a,myIntegral]
a[n_Integer?Positive, c_Integer?Positive, x_] :=
a[n, c, x] = (1 - (1 - a[n - 1, c, x])^c)^c;
a[0, c_Integer, x_] = x;
myIntegral[n_, c_] :=
NIntegrate[D[a[n, c, y], y]*y/(1 - a[n, c, x]), {x, 0, 1}, {y, x, 1},
WorkingPrecision -> 200, PrecisionGoal -> 5]
This is much faster than performing the integration symbolically. Here's a comparison:
yoda:
myIntegral[2,2]//Timing
Out[1]= {0.088441, 0.647376595...}
myIntegral[5,2]//Timing
Out[2]= {1.10486, 0.587502888...}
rcollyer:
MyIntegral[2,2]//Timing
Out[3]= {1.0029, 0.647376}
MyIntegral[5,2]//Timing
Out[4]= {27.1697, 0.587503006...}
(* Obtained with WorkingPrecision->500, PrecisionGoal->5, MaxRecursion->20 *)
Jand's function has timings similar to rcollyer's. Of course, as you increase n, you will have to increase your WorkingPrecision way higher than this, as you've experienced in your previous question. Since you said you only need about 5 digits of precision, I've explicitly set PrecisionGoal to 5. You can change this as per your needs.
To codify the comments, I'd try the following. First, to eliminate infinite recursion with regards to the variable, n, I'd rewrite your functions as
F[x_, c_] := (1 - (1-x)^c)^c;
(* see note below *)
a[n_Integer?Positive, c_, x_] := F[a[n - 1, c, x], c];
a[0, c_, x_] = x;
that way n==0 will actually be a stopping point. The ?Positive form is a PatternTest, and useful for applying additional conditions to the parameters. I suspect the issue is that NIntegrate is re-evaluating the inner Integrate for every value of x, so I'd pull that evaluation out, like
MyIntegral[n_,c_] :=
With[{ int = Integrate[(D[a[n,c,y],y]*y)/(1-a[n,c,x]),{y,x,1}] },
NIntegrate[int,{x,0,1}]
]
where With is one of several scoping constructs specifically for creating local constants.
Your comments indicate that the inner integral takes a long time, have you tried simplifying the integrand as it is a derivative of a times a function of a? It seems like the result of a chain rule expansion to me.
Note: as per Yoda's suggestion in the comments, you can add a cacheing, or memoization, mechanism to a. Change its definition to
d:a[n_Integer?Positive, c_, x_] := d = F[a[n - 1, c, x], c];
The trick here is that in d:a[ ... ], d is a named pattern that is used again in d = F[...] cacheing the value of a for those particular parameter values.

Specifics of usage and internal work of *Set* functions

I just noticed one undocumented feature of internal work of *Set* functions in Mathematica.
Consider:
In[1]:= a := (Print["!"]; a =.; 5);
a[b] = 2;
DownValues[a]
During evaluation of In[1]:= !
Out[3]= {HoldPattern[a[b]] :> 2}
but
In[4]:= a := (Print["!"]; a =.; 5);
a[1] = 2;
DownValues[a]
During evaluation of In[4]:= !
During evaluation of In[4]:= Set::write: Tag Integer in 5[1] is Protected. >>
Out[6]= {HoldPattern[a[b]] :> 2}
What is the reason for this difference? Why a is evaluated although Set has attribute HoldFirst? For which purposes such behavior is useful?
And note also this case:
In[7]:= a := (Print["!"]; a =.; 5)
a[b] ^= 2
UpValues[b]
a[b]
During evaluation of In[7]:= !
Out[8]= 2
Out[9]= {HoldPattern[5[b]] :> 2}
Out[10]= 2
As you see, we get the working definition for 5[b] avoiding Protected attribute of the tag Integer which causes error in usual cases:
In[13]:= 5[b] = 1
During evaluation of In[13]:= Set::write: Tag Integer in 5[b] is Protected. >>
Out[13]= 1
The other way to avoid this error is to use TagSet*:
In[15]:= b /: 5[b] = 1
UpValues[b]
Out[15]= 1
Out[16]= {HoldPattern[5[b]] :> 1}
Why are these features?
Regarding my question why we can write a := (a =.; 5); a[b] = 2 while cannot a := (a =.; 5); a[1] = 2. In really in Mathematica 5 we cannot write a := (a =.; 5); a[b] = 2 too:
In[1]:=
a:=(a=.;5);a[b]=2
From In[1]:= Set::write: Tag Integer in 5[b] is Protected. More...
Out[1]=
2
(The above is copied from Mathematica 5.2)
We can see what happens internally in new versions of Mathematica when we evaluate a := (a =.; 5); a[b] = 2:
In[1]:= a:=(a=.;5);
Trace[a[b]=2,TraceOriginal->True]
Out[2]= {a[b]=2,{Set},{2},a[b]=2,{With[{JLink`Private`obj$=a},RuleCondition[$ConditionHold[$ConditionHold[JLink`CallJava`Private`setField[JLink`Private`obj$[b],2]]],Head[JLink`Private`obj$]===Symbol&&StringMatchQ[Context[JLink`Private`obj$],JLink`Objects`*]]],{With},With[{JLink`Private`obj$=a},RuleCondition[$ConditionHold[$ConditionHold[JLink`CallJava`Private`setField[JLink`Private`obj$[b],2]]],Head[JLink`Private`obj$]===Symbol&&StringMatchQ[Context[JLink`Private`obj$],JLink`Objects`*]]],{a,a=.;5,{CompoundExpression},a=.;5,{a=.,{Unset},a=.,Null},{5},5},RuleCondition[$ConditionHold[$ConditionHold[JLink`CallJava`Private`setField[5[b],2]]],Head[5]===Symbol&&StringMatchQ[Context[5],JLink`Objects`*]],{RuleCondition},{Head[5]===Symbol&&StringMatchQ[Context[5],JLink`Objects`*],{And},Head[5]===Symbol&&StringMatchQ[Context[5],JLink`Objects`*],{Head[5]===Symbol,{SameQ},{Head[5],{Head},{5},Head[5],Integer},{Symbol},Integer===Symbol,False},False},RuleCondition[$ConditionHold[$ConditionHold[JLink`CallJava`Private`setField[5[b],2]]],False],Fail},a[b]=2,{a[b],{a},{b},a[b]},2}
I was very surprised to see calls to Java in such a pure language-related operation as assigning a value to a variable. Is it reasonable to use Java for such operations at all?
Todd Gayley (Wolfram Research) has explained this behavior:
At the start, let me point out that in
Mathematica 8, J/Link no longer
overloads Set. An internal kernel
mechanism was created that, among
other things, allows J/Link to avoid
the need for special, er, "tricks"
with Set.
J/Link has overloaded Set from the
very beginning, almost twelve years
ago. This allows it support this
syntax for assigning a value to a Java
field:
javaObject#field = value
The overloaded definition of Set
causes a slowdown in assignments of
the form
_Symbol[_Symbol] = value
Of course, assignment is a fast
operation, so the slowdown is small in
real terms. Only highly specialized
types of programs are likely to be
significantly affected.
The Set overload does not cause a
call to Java on assignments that do
not involve Java objects (this would
be very costly). This can be verified
with a simple use of TracePrint on
your a[b]=c.
It does, as you note, make a slight
change in the behavior of assignments
that match _Symbol[_Symbol] = value.
Specifically, in f[_Symbol] = value, f
gets evaluated twice. This can cause
problems for code with the following
(highly unusual) form:
f := SomeProgramWithSideEffects[]
f[x] = 42
I cannot recall ever seeing "real"
code like this, or seeing a problem
reported by a user.
This is all moot now in 8.0.
Taking the case of UpSet first, this is expected behavior. One can write:
5[b] ^= 1
The assignment is made to b not the Integer 5.
Regarding Set and SetDelayed, while these have Hold attributes, they still internally evaluate expressions. This allows things such as:
p = n : (_List | _Integer | All);
f[p] := g[n]
Test:
f[25]
f[{0.1, 0.2, 0.3}]
f[All]
g[25]
g[{0.1, 0.2, 0.3}]
g[All]
One can see that heads area also evaluated. This is useful at least for UpSet:
p2 = head : (ff | gg);
p2[x] ^:= Print["Echo ", head];
ff[x]
gg[x]
Echo ff
Echo gg
It is easy to see that it happens also with Set, but less clear to me how this would be useful:
j = k;
j[5] = 3;
DownValues[k]
(* Out= {HoldPattern[k[5]] :> 3} *)
My analysis of the first part of your question was wrong. I cannot at the moment see why a[b] = 2 is accepted and a[1] = 2 is not. Perhaps at some stage of assignment the second one appears as 5[1] = 2 and a pattern check sets off an error because there are no Symbols on the LHS.
The behavour you show appears to be a bug in 7.0.1 (and possibly earlier) that was fixed in Mathematica 8. In Mathematica 8, both of your original a[b] = 2 and a[1] = 2 examples give the Set::write ... is protected error.
The problem appears to stem from the JLink-related down-value of Set that you identified. That rule implements the JLink syntax used to assign a value to the field of a Java object, e.g. object#field = value.
Set in Mathematica 8 does not have that definition. We can forcibly re-add a similar definition, thus:
Unprotect[Set]
HoldPattern[sym_Symbol[arg_Symbol]=val_] :=
With[{obj=sym}
, setField[obj[arg], val] /; Head[obj] === Symbol && StringMatchQ[Context[obj],"Something`*"]
]
After installing this definition in Mathematica 8, it now exhibits the same inconsistent behaviour as in Mathematica 7.
I presume that JLink object field assignment is now accomplished through some other means. The problematic rule looks like it potentially adds costly Head and StringMatchQ tests to every evaluation of the form a[b] = .... Good riddance?

Mathematica: How to clear the cache for a symbol, i.e. Unset pattern-free DownValues

I'm a bad cacher: Sometimes, when no one is watching, I'll cache results without including the full context like so:
f[x_]:=f[x]=x+a;
a=2; f[1];
DownValues[f]
Out[2]= {HoldPattern[f[1]]:>3,HoldPattern[f[x_]]:>(f[x]=x+a)}
This leads to horribly subtle bugs, and, more importantly, to the need for clearing the cache when I change the context. One way of clearing the cache is to completely Clear the symbol and repeat the definitions, but this is not really a solution.
What I would really like is a method for clearing all pattern-free DownValues associated with a symbol.
For clarity, I'll include my present solution as an answer, but if fails on two counts
It only clears DownValues with all-numeric arguments
For aesthetical reasons, I'd like to avoid using Block to grab the DownValues.
Any ideas on how to improve ClearCache?
I've made similar functions in the past (but I can't remember where).
Does the following code do all that you need?
ClearCache[f_] := DownValues[f] = DeleteCases[DownValues[f],
_?(FreeQ[First[#], Pattern] &)]
This maybe should be extended to UpValues and SubValues. And the Head of f restricted to Symbol.
Just to complement the other excellent solution: if you have a very large list of DownValues and have strict efficiency requirements for ClearCache, you can significantly speed up the process by clearing all definitions and then reconstructing only those with patterns. Here is an example:
In[1]:=
ClearCache[f_] :=
DownValues[f] = DeleteCases[DownValues[f], _?(FreeQ[First[#], Pattern] &)];
In[2]:= Clear[f];
f[x_] := f[x] = x;
In[4]:= f /# Range[1000000];
In[5]:= ClearCache[f]; // Timing
Out[5]= {7.765, Null}
In[6]:=
ClearAll[createDefs];
SetAttributes[createDefs, HoldRest];
createDefs[f_, defs_: Automatic] :=
(createDefs[f] := (Clear[f]; defs); createDefs[f]);
In[9]:= Clear[f];
createDefs[f, f[x_] := f[x] = x]
In[11]:= f /# Range[1000000];
In[12]:= Length[DownValues[f]]
Out[12]= 1000001
In[13]:= createDefs[f]; // Timing
Out[13]= {1.079, Null}
In[14]:= DownValues[f]
Out[14]= {HoldPattern[f[x_]] :> (f[x] = x)}
Note that you only have to call the createDefs once with the code that creates the pattern-based definitions of the function. All other times, you call it as createDefs[f], because it memoizes the code needed to re-create the definitions, on the first call.
It is also possible that you don't want to grow huge caches, but this is out of your control in the simple f[x_]:=f[x]=rhs approach. In other words, the cache may contain lots of unnecessary old stuff, but in this approach you can not tell old (no longer used) definitions from the new ones. I partially addressed this problem with a package I called Cache, which can be found here together with the notebook illustrating its use. It gives you more control over the size of the cache. It has its problems, but may occasionally be useful.
Once I implemented a scheme to limit the number of memoized values (and conserve memory). Search for memoization on that page. This might be useful here as well (especially considering some of the questions marked as duplicate of this one).
The code
SetAttributes[memo, HoldAll]
SetAttributes[memoStore, HoldFirst]
SetAttributes[memoVals, HoldFirst]
memoVals[_] = {};
memoStore[f_, x_] :=
With[{vals = memoVals[f]},
If[Length[vals] > 200,
f /: memoStore[f, First[vals]] =.;
memoVals[f] ^= Append[Rest[memoVals[f]], x],
memoVals[f] ^= Append[memoVals[f], x]];
f /: memoStore[f, x] = f[x]]
memo[f_Symbol][x_?NumericQ] := memoStore[f, x]
memoClearCache[f_Symbol] :=
(Scan[(f /: memoStore[f, #] =.) &, memoVals[f]];
f /: memoVals[f] =. )
Usage and description
This version works with functions that take a single numerical argument. Call memo[f][x] instead of f[x] to use a memoized version. Cached values are still associated with f, so when f is cleared, they are gone. The number of cached values is limited to 200 by default. Use memoClearCache[f] to clear all memoized values.
This is my present solution to the problem, but as mentioned in the question is doesn't strictly look for pattern-free DownValues, nor is it very elegant.
Store the DownValues for f
In[6]:= dv = DownValues[f]
Out[6]= {HoldPattern[f[1]] :> 3, HoldPattern[f[x_]] :> (f[x] = x + a)}
Find the DownValues to clear inside a Block to avoid immediate evaluation
In[7]:= dv2clear = Block[{f},
Hold#Evaluate#Cases[dv,
HoldPattern[f[args__ /; Apply[And, NumericQ /# Flatten[{args}]]]], {3}]]
Out[7]= Hold[{f[1]}]
Apply Unset to the targeted DownValues inside the held list and then release
In[8]:= Map[Unset, dv2clear, {2}]
ReleaseHold#%
Out[8]= Hold[{(f[1]) =.}]
This works fine
In[10]:= DownValues[f]
Out[10]= {HoldPattern[f[x_]] :> (f[x] = x + a)}
And can be wrapped up like so:
ClearCache[f_] := Module[{dv, dv2clear},
(* Cache downvalues for use inside block *)
dv = DownValues[f];
(* Find the downvalues to clear in Block to avoid immediate evaluation *)
dv2clear = Block[{f},Hold#Evaluate#Cases[dv,HoldPattern[
f[args__ /; Apply[And, NumericQ /# Flatten[{args}]]]], {3}]];
(* Apply Unset to the terms inside the held list and then release *)
ReleaseHold#Map[Unset, dv2clear, {2}];]

Resources