Remembering Previously Evaluated Function Values with Optional Argument

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
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!










share|improve this question

























    up vote
    3
    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!










    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      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!










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 3 hours ago









      Daniel Wilson-Nunn

      397110




      397110




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          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))





          share|improve this answer




















          • Beat me to it :) +1.
            – Leonid Shifrin
            3 hours ago










          • 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
            3 hours ago


















          up vote
          2
          down vote













          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].






          share|improve this answer




















            Your Answer





            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "387"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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






























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            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))





            share|improve this answer




















            • Beat me to it :) +1.
              – Leonid Shifrin
              3 hours ago










            • 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
              3 hours ago















            up vote
            4
            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))





            share|improve this answer




















            • Beat me to it :) +1.
              – Leonid Shifrin
              3 hours ago










            • 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
              3 hours ago













            up vote
            4
            down vote










            up vote
            4
            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))





            share|improve this answer












            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))






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 3 hours ago









            Albert Retey

            20.3k4391




            20.3k4391











            • Beat me to it :) +1.
              – Leonid Shifrin
              3 hours ago










            • 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
              3 hours ago

















            • Beat me to it :) +1.
              – Leonid Shifrin
              3 hours ago










            • 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
              3 hours ago
















            Beat me to it :) +1.
            – Leonid Shifrin
            3 hours ago




            Beat me to it :) +1.
            – Leonid Shifrin
            3 hours ago












            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
            3 hours ago





            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
            3 hours ago











            up vote
            2
            down vote













            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].






            share|improve this answer
























              up vote
              2
              down vote













              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].






              share|improve this answer






















                up vote
                2
                down vote










                up vote
                2
                down vote









                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].






                share|improve this answer












                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].







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 2 hours ago









                Michael E2

                143k11192460




                143k11192460



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay