7
$\begingroup$

I want to implement the recursive function

 v[n_] := v[n] = v[n-1] + f[n-1] + Random[NormalDistribution[0,s]] 

to get vel = {v[0], v[1],..., v[N]}.

I want to compute $M$ replicates of vel. How do I clear the memory of $v$ after each replicate of vel? If I don't I get the same vel repeated $M$ times.

$\endgroup$
11
  • $\begingroup$ does your recursion have a base case? $\endgroup$
    – Pillsy
    Nov 9, 2015 at 18:26
  • 1
    $\begingroup$ Welcome to Mathematica.SE! 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour and check the faqs! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$
    – user9660
    Nov 9, 2015 at 18:26
  • $\begingroup$ I think this should be reopened, because the best way to deal with this is not, IMO, clearing DownValues. $\endgroup$
    – Pillsy
    Nov 9, 2015 at 18:31
  • $\begingroup$ @Pillsy, why wouldn't it be an appropriate answer for the other question? $\endgroup$ Nov 9, 2015 at 18:33
  • $\begingroup$ Anyway, here's how to clear selected values: Scan[Composition[Unset, v], {2, 3, 7, 8}]. You can use Range[n] as the list of values to clear, thus leaving v[0] and the general rule. $\endgroup$ Nov 9, 2015 at 18:34

2 Answers 2

15
$\begingroup$

Suggested solution

If I understood the question right, then the simplest solution here would probably be to define a helper function like the following:

vv[n_] := Internal`InheritedBlock[{v}, v /@ Range[n]];

Then, you get

vel = vv[m]

and every run of vv would result in different set of values, while the values in the set will all come from the same memoization "run".

The presence of Internal`InheritedBlock guarantees that whatever values were remembered inside of it, will be cleared automatically when the execution leaves the block.

Example

For example:

ClearAll[f, v, s, vv];
s = 1;
f[x_] := x;
v[0] := 0;
v[n_] := v[n] = v[n - 1] + f[n - 1] + Random[NormalDistribution[0, s]];
vv[n_] := Internal`InheritedBlock[{v}, v /@ Range[n]];

Test:

vv[10]

(* {-0.0712327, 1.67558, 4.93819, 9.21973, 13.7199, 17.3607, 22.7843, 31.0941, 37.9027, 47.6244} *)

vv[10]

(* {-3.29625, -2.51668, -0.464889, 1.71271, 4.70297, 9.78192, 15.8081, 22.5965, 29.3856, 38.323} *)

Links

Closely related questions:

$\endgroup$
4
  • 1
    $\begingroup$ Array[v, n] could be used, too. Is there any reason why Internal`InheritedBlock[] is necessary here? $\endgroup$ Nov 9, 2015 at 18:44
  • 3
    $\begingroup$ @J.M. I added the explanation to the post. The reason is to clear the memoized values, after each run. $\endgroup$ Nov 9, 2015 at 18:49
  • $\begingroup$ I didn't see this answer before I wrote this one where I automate the process of storing and clearing cached values with a wrapper function. $\endgroup$ Oct 4, 2020 at 11:25
  • 1
    $\begingroup$ @SjoerdSmit Sure thing (it is hard to know about all the answers, probably impossible). I wouldn't vote it up if I didn't think it had novel parts, too :). I don't think there is an exact answer like yours anywhere on the site (although as I said, there are bits and pieces scattered), and I think your answer is valuable. $\endgroup$ Oct 4, 2020 at 11:37
0
$\begingroup$

You really want to define the collection of vs when you produce a realization of vel, so I'd replace this with

vel[n_] := Module[{},
  Table[
    v[k] = v[k - 1] + f[k - 1] + Random[NormalDistribution[0, s]],
  {k, 0, n}]
]

This generates a new set of vs every time you call vel[]. (The bulk of this could be replaced by NestList[], but I'm not convinced it buys much to do so.) You don't give any hints about the base case of your recursion, about s, or about what f does, so

Block[{s = 1},
  Print[vel[3]];
  Print[v[2]];
  Print[v[2]];
  Print[vel[3]];
]
v[2]
(*  {-1.39483+f[-1]+v[-1],-1.17269+f[-1]+f[0]+v[-1],-0.19439+f[-1]+f[0]+f[1]+v[-1],0.863082 +f[-1]+f[0]+f[1]+f[2]+v[-1]}  *)
(*  -0.19439+f[-1]+f[0]+f[1]+v[-1]  *)
(*  -0.19439+f[-1]+f[0]+f[1]+v[-1]  *)
(*  {-0.811165+f[-1]+v[-1],-0.959559+f[-1]+f[0]+v[-1],-2.25842+f[-1]+f[0]+f[1]+v[-1],-1.75508+f[-1]+f[0]+f[1]+f[2]+v[-1]}  *)
(*  -2.25842 + f[-1] + f[0] + f[1] + v[-1]  *)

The vs keep their values between calls to vel[] and change on each call to vel[]. If you want to reuse a vel without changing the vs, store it.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.