Remembering Previously Evaluated Function Values with Optional Argument
up vote
6
down vote
favorite
I am trying to implement a "Function That Remembers Values It Has Found" (name adjusted from the similarly named Mathematica guide (clicky here)). I have an optional argument and I believe that is giving me some issues, I know that it would be easy if I just gave the value of the optional argument when attempting to recall the function, but that seems to defeat the point of such a mechanism.
Here is an example of my problem (function anonymised for privacy reasons, it is not a function specific issue):
In[1]:= myFun[d_,m_,method_String,degrees_:False]:=
myFun[d,m,method,degrees]=foo[d,m,method,degrees];
If I run it and time it without the optional argument specified, it does not save the result.
In[2]:= Timing[myFun[2,6,"myMethod"];]
Out[2]= {1.73822, Null}
In[3]:= Timing[myFun[2,6,"myMethod"];]
Out[3]= {1.74781, Null}
So I checked with ? myFun
and saw that it had indeed been saved with the optional argument specified, so gave that a try:
In[4]:= Timing[myFun[2,6,"myMethod",False];]
Out[4]= {0.000102, Null}
Giving what would have been expected. Is there any way so that I do not have to include my optional argument, it would be a shame if it were no longer optional!
functions
add a comment |
up vote
6
down vote
favorite
I am trying to implement a "Function That Remembers Values It Has Found" (name adjusted from the similarly named Mathematica guide (clicky here)). I have an optional argument and I believe that is giving me some issues, I know that it would be easy if I just gave the value of the optional argument when attempting to recall the function, but that seems to defeat the point of such a mechanism.
Here is an example of my problem (function anonymised for privacy reasons, it is not a function specific issue):
In[1]:= myFun[d_,m_,method_String,degrees_:False]:=
myFun[d,m,method,degrees]=foo[d,m,method,degrees];
If I run it and time it without the optional argument specified, it does not save the result.
In[2]:= Timing[myFun[2,6,"myMethod"];]
Out[2]= {1.73822, Null}
In[3]:= Timing[myFun[2,6,"myMethod"];]
Out[3]= {1.74781, Null}
So I checked with ? myFun
and saw that it had indeed been saved with the optional argument specified, so gave that a try:
In[4]:= Timing[myFun[2,6,"myMethod",False];]
Out[4]= {0.000102, Null}
Giving what would have been expected. Is there any way so that I do not have to include my optional argument, it would be a shame if it were no longer optional!
functions
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I am trying to implement a "Function That Remembers Values It Has Found" (name adjusted from the similarly named Mathematica guide (clicky here)). I have an optional argument and I believe that is giving me some issues, I know that it would be easy if I just gave the value of the optional argument when attempting to recall the function, but that seems to defeat the point of such a mechanism.
Here is an example of my problem (function anonymised for privacy reasons, it is not a function specific issue):
In[1]:= myFun[d_,m_,method_String,degrees_:False]:=
myFun[d,m,method,degrees]=foo[d,m,method,degrees];
If I run it and time it without the optional argument specified, it does not save the result.
In[2]:= Timing[myFun[2,6,"myMethod"];]
Out[2]= {1.73822, Null}
In[3]:= Timing[myFun[2,6,"myMethod"];]
Out[3]= {1.74781, Null}
So I checked with ? myFun
and saw that it had indeed been saved with the optional argument specified, so gave that a try:
In[4]:= Timing[myFun[2,6,"myMethod",False];]
Out[4]= {0.000102, Null}
Giving what would have been expected. Is there any way so that I do not have to include my optional argument, it would be a shame if it were no longer optional!
functions
I am trying to implement a "Function That Remembers Values It Has Found" (name adjusted from the similarly named Mathematica guide (clicky here)). I have an optional argument and I believe that is giving me some issues, I know that it would be easy if I just gave the value of the optional argument when attempting to recall the function, but that seems to defeat the point of such a mechanism.
Here is an example of my problem (function anonymised for privacy reasons, it is not a function specific issue):
In[1]:= myFun[d_,m_,method_String,degrees_:False]:=
myFun[d,m,method,degrees]=foo[d,m,method,degrees];
If I run it and time it without the optional argument specified, it does not save the result.
In[2]:= Timing[myFun[2,6,"myMethod"];]
Out[2]= {1.73822, Null}
In[3]:= Timing[myFun[2,6,"myMethod"];]
Out[3]= {1.74781, Null}
So I checked with ? myFun
and saw that it had indeed been saved with the optional argument specified, so gave that a try:
In[4]:= Timing[myFun[2,6,"myMethod",False];]
Out[4]= {0.000102, Null}
Giving what would have been expected. Is there any way so that I do not have to include my optional argument, it would be a shame if it were no longer optional!
functions
functions
asked Nov 10 at 20:43
Daniel Wilson-Nunn
412210
412210
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
7
down vote
accepted
You can name the user-call with a pattern and use that for memoization:
call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);
call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);
The first memoizes just the call:
AbsoluteTiming[myFun2[3]]
(* {1.00087, 26} *)
AbsoluteTiming[myFun2[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun2[3, 23]] (* not memoized *)
(* {1.00064, 26} *)
The second memoizes the call, if the call was of the form myFun3[x]
, and it will memoize the call with the default, myFun3[x, 23]
, too:
AbsoluteTiming[myFun3[3]]
(* {1.00028, 26} *)
AbsoluteTiming[myFun3[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun3[3, 23]]
(* {1.*10^-6, 26} *)
The double assigment call = myFun3[x, y] =...
is innocuously redundant if the call is of the form myFun3[x, y]
.
add a comment |
up vote
6
down vote
There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:
f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))
(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)
use this:
ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten aboutPause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?
– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
You can name the user-call with a pattern and use that for memoization:
call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);
call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);
The first memoizes just the call:
AbsoluteTiming[myFun2[3]]
(* {1.00087, 26} *)
AbsoluteTiming[myFun2[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun2[3, 23]] (* not memoized *)
(* {1.00064, 26} *)
The second memoizes the call, if the call was of the form myFun3[x]
, and it will memoize the call with the default, myFun3[x, 23]
, too:
AbsoluteTiming[myFun3[3]]
(* {1.00028, 26} *)
AbsoluteTiming[myFun3[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun3[3, 23]]
(* {1.*10^-6, 26} *)
The double assigment call = myFun3[x, y] =...
is innocuously redundant if the call is of the form myFun3[x, y]
.
add a comment |
up vote
7
down vote
accepted
You can name the user-call with a pattern and use that for memoization:
call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);
call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);
The first memoizes just the call:
AbsoluteTiming[myFun2[3]]
(* {1.00087, 26} *)
AbsoluteTiming[myFun2[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun2[3, 23]] (* not memoized *)
(* {1.00064, 26} *)
The second memoizes the call, if the call was of the form myFun3[x]
, and it will memoize the call with the default, myFun3[x, 23]
, too:
AbsoluteTiming[myFun3[3]]
(* {1.00028, 26} *)
AbsoluteTiming[myFun3[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun3[3, 23]]
(* {1.*10^-6, 26} *)
The double assigment call = myFun3[x, y] =...
is innocuously redundant if the call is of the form myFun3[x, y]
.
add a comment |
up vote
7
down vote
accepted
up vote
7
down vote
accepted
You can name the user-call with a pattern and use that for memoization:
call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);
call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);
The first memoizes just the call:
AbsoluteTiming[myFun2[3]]
(* {1.00087, 26} *)
AbsoluteTiming[myFun2[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun2[3, 23]] (* not memoized *)
(* {1.00064, 26} *)
The second memoizes the call, if the call was of the form myFun3[x]
, and it will memoize the call with the default, myFun3[x, 23]
, too:
AbsoluteTiming[myFun3[3]]
(* {1.00028, 26} *)
AbsoluteTiming[myFun3[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun3[3, 23]]
(* {1.*10^-6, 26} *)
The double assigment call = myFun3[x, y] =...
is innocuously redundant if the call is of the form myFun3[x, y]
.
You can name the user-call with a pattern and use that for memoization:
call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);
call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);
The first memoizes just the call:
AbsoluteTiming[myFun2[3]]
(* {1.00087, 26} *)
AbsoluteTiming[myFun2[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun2[3, 23]] (* not memoized *)
(* {1.00064, 26} *)
The second memoizes the call, if the call was of the form myFun3[x]
, and it will memoize the call with the default, myFun3[x, 23]
, too:
AbsoluteTiming[myFun3[3]]
(* {1.00028, 26} *)
AbsoluteTiming[myFun3[3]]
(* {1.*10^-6, 26} *)
AbsoluteTiming[myFun3[3, 23]]
(* {1.*10^-6, 26} *)
The double assigment call = myFun3[x, y] =...
is innocuously redundant if the call is of the form myFun3[x, y]
.
answered Nov 10 at 22:09
Michael E2
143k11192462
143k11192462
add a comment |
add a comment |
up vote
6
down vote
There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:
f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))
(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)
use this:
ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten aboutPause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?
– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
add a comment |
up vote
6
down vote
There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:
f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))
(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)
use this:
ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten aboutPause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?
– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
add a comment |
up vote
6
down vote
up vote
6
down vote
There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:
f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))
(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)
use this:
ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))
There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:
f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))
(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)
use this:
ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))
answered Nov 10 at 21:00
Albert Retey
20.4k4391
20.4k4391
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten aboutPause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?
– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
add a comment |
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten aboutPause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?
– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Beat me to it :) +1.
– Leonid Shifrin
Nov 10 at 21:02
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten about
Pause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?– Daniel Wilson-Nunn
Nov 10 at 21:07
Thank you for this, I had been trying to include a MWE, but couldn't think of a function simple enough that would still take a while to evaluate, had completely forgotten about
Pause
. This solution is very good, but I feel it is rather disappointing that Mathematica cannot handle the optional argument here without additional prompting. Is there a reason for this that I am missing?– Daniel Wilson-Nunn
Nov 10 at 21:07
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
@DanielWilson-Nunn: as you can see from the other answer this can be handled with only one definition. Which of these solutions is preferable will depend on various details of the problem and personal preferences. You would also have to try which variant is faster if that is an issue (I tend to always try performance claims with the actual problem and never guess...)
– Albert Retey
Nov 12 at 20:54
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f185766%2fremembering-previously-evaluated-function-values-with-optional-argument%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown