# using memoization with conditional statement

I would like some advice about the use of memoization in conjunction with conditional statements. Let me try to explain my problem:

I am constructing a function depending on a number of parameters. Given a set of values I first need to check if they meet certain conditions and then calculate the value of the function like so:

myfunction[V_,a_,b_,c_]:=Block[
{v1},
If[TrueQ[a<b]&&TrueQ[b>c],Abort[]];
a*V^2+b*V+c
]


The reason why I am constructing the function this way is because I need to study the variation of myfunction with V for different values of the parameters a, b and c and eventually plot some dependencies. So what I would like to have is to stop the evaluation of the function if the set of parameters a, b and c does not meet the conditions and if they do to plot the variation with V (this case is the easy part).

In its current form myfunction evaluates without a problem, but is quite slow. Having the If evaluated for every value of V when plotting the function, is very time consuming, considering that it only needs to be evaluated once.

So I thought I found the solution when I read about memoization. I have tried to rewrite the function like this:

myfunction[V_,a_,b_,c_]:=Block[
{v1,memo},
memo:=memo=If[TrueQ[a<b]&&TrueQ[b>c],Abort[],0.];
a*V^2+b*V+c
]


But it is not working. The Abort[] is never evaluated, only when TrueQ is False memo becomes 0 and that's all.

Is there a way to accomplish this?

Let me know if you need more details.

Update:

Thank you very much for your comments. Following ybeltukov's suggestion I have tried the following:

created a function

ExistCond[a_,b_,c_]=Block[
{some parameters},
definitions;
TrueQ[a<b]&&TrueQ[b>c](*main conditions to be satisfied*)
];


then use it as follows with myfunction:

myfunction[V_,a_,b_,c_]/;ExistCond[a,b,c]:=myfunction[V,a,b,c]=Block[
{extra parameters},
definitions;
a*V^2+b*V+c
];


Unfortunately when I plot myfunction it takes a long time first time I evaluate the plot and alas, the second time is very fast. But this is not what I intended. I was expecting that If the conditions in ExistCond evaluate to True then for the rest of the values of V, ExistCond is not evaluated again. I have a feeling I am confusing how memoization works.

• myfunction[V_, a_, b_, c_] /; a < b && b > c := myfunction[V, a, b, c] = a*V^2 + b*V + c;? Oct 18, 2014 at 12:17
• /; is more convenient for conditions. For example, see my recent answer with conditions and memoization . Oct 18, 2014 at 12:18
• @belisarius or a bit more compact: mem : myfunction[V_, a_, b_, c_] /; a < b && b > c := mem = a*V^2 + b*V + c; Oct 18, 2014 at 12:20
• note for this simple example it may not be apparent if a solution has successfully avoided reevaluating the function definition for each V. For testing purpose you might want to use a fuction like (Pause;a V^2+b V+c) Oct 18, 2014 at 12:42
• Based on your last update, perhaps you need to memoize ExistCond[] instead Oct 18, 2014 at 13:46

I'd do something like this:

myfunction[V_, a_, b_, c_] :=
Block[{v1},
If[TrueQ[a < b] && TrueQ[b > c],
Abort[],
(* else *)
myFunction[v1_, a, b, c] = a*v1^2 + b*v1 + c;
myFunction[V, a, b, c]
]];


It is similar to my answer here. Basically, you memoize on some of the arguments.

Edit: revision - for this to work properly you need to evaluate the expression inside the function:

 myfun[a_,b_,c_]/; a < b && b > c:=
myfun[a,b,c]=Function[{V}, Evaluate[ function code ] ]


usage is then for example:

 Plot[myfun[a,b,c][V],{V,0,1}]


if you need the Abort you can simply do

  myfun[a_,b_,c_]:=Abort[]


which will naturally catch anything missed by the conditional definition

Specific example:

Suppose we have a function with an expensive part that depends only on some of the parameters:

 f[a_, x_] /; a>0  := NIntegrate[ Cos[a  t ]^2 , {t, 0, Pi }]  ( x + a );
Table[ Table[ f[a, x] , {x, 100}] , {a, 50}] // Timing // First


82.321728

now memorize the function for each different a:

 Clear[f];
f[a_] /; a > 0 := f[a] = Function[{x},
Evaluate[  NIntegrate[ Cos[a  t ]^2 , {t, 0, Pi }]  ( x + a ) ]];
f[a_] := Abort[];
Table[ Table[ f[a][ x] , {x, 100}] , {a, 50}] // Timing // First


0.015600

 f


\$Abort

@LeonidShifrin's approach of course works as well. Mine is a smidge faster, i suspect because because the /; pattern test beats the explicit If[].

• I have tried that, after seeing your and ybeltukov's answer (how do you reference a name?) but it doesn't seem to be what I am looking for (see the updated post!) Oct 18, 2014 at 13:36