(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 50108, 1551] NotebookOptionsPosition[ 43319, 1324] NotebookOutlinePosition[ 43728, 1342] CellTagsIndexPosition[ 43685, 1339] WindowFrame->Normal ContainsDynamic->True *) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell["Preliminary remarks", "Subsection", CellChangeTimes->{ 3.418392861640566*^9, {3.418398051644497*^9, 3.4183980746760416`*^9}}, FontWeight->"Plain"], Cell["\<\ This notebook illustrates the use of the package < Cache > . This package \ allows one to automatically create cached versions of functions of a single \ argument, with internal cache which keeps a given fixed number of results of \ the most recent function calls. If the function is called on one of these \ arguments, it is not recomputed afresh, but instead the cached value is used. \ I assume that the package is placed in directory where the system can find \ it. \ \>", "Text", CellChangeTimes->{{3.4183980853480535`*^9, 3.418398266022241*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Loading the package", "Subsection", CellChangeTimes->{{3.41839806280089*^9, 3.418398068066582*^9}}, FontWeight->"Plain"], Cell[BoxData[ RowBox[{"<<", "Cache`"}]], "Input", CellChangeTimes->{{3.418392939625939*^9, 3.4183929445478773`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"?", "Cache`*"}]], "Code", CellChangeTimes->{{3.418393101362384*^9, 3.4183931051905584`*^9}}], Cell[BoxData[ DynamicModuleBox[{Typeset`open$$ = True}, PaneSelectorBox[{False-> RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["Cache`", "InfoHeading"]}], True->GridBox[{ { RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["Cache`", "InfoHeading"]}]}, {GridBox[{ { ButtonBox["BufferSize", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`BufferSize"}, ButtonNote->"Cache`"], ButtonBox["DestroyCached", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`DestroyCached"}, ButtonNote->"Cache`"], ButtonBox["MakeCached", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`MakeCached"}, ButtonNote->"Cache`"]}, { ButtonBox["Cache", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`Cache"}, ButtonNote->"Cache`"], ButtonBox["EmptyCache", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`EmptyCache"}, ButtonNote->"Cache`"], ""}, { ButtonBox["CreateCacheFunction", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`CreateCacheFunction"}, ButtonNote->"Cache`"], ButtonBox["IndependentCache", BaseStyle->"InformationLink", ButtonData:>{"Info3418403116-3101082", "Cache`IndependentCache"}, ButtonNote->"Cache`"], ""} }, DefaultBaseStyle->"InfoGrid", GridBoxItemSize->{"Columns" -> {{ Scaled[0.31666666666666665`]}}}]} }, GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}}]}, Dynamic[Typeset`open$$], ImageSize->Automatic]]], "Print", "InfoCell", CellChangeTimes->{3.4183995176476364`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["A test function", "Subsection", CellChangeTimes->{{3.418396115291587*^9, 3.4183961183697515`*^9}}, FontWeight->"Plain"], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", RowBox[{"f", ",", "fn"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", "?", "EvenQ"}], "]"}], ":=", RowBox[{"x", "^", "2"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", "?", "OddQ"}], "]"}], ":=", RowBox[{"x", "^", "3"}]}], ";"}]}], "Input", CellChangeTimes->{{3.4183927525766697`*^9, 3.418392759170504*^9}, { 3.4183928462028685`*^9, 3.4183928504997983`*^9}, {3.4183933869129143`*^9, 3.418393387506672*^9}, {3.418393432350996*^9, 3.4183934506949806`*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Creating the cached function(s)", "Subsection", CellChangeTimes->{{3.4183949339014654`*^9, 3.4183949417921915`*^9}}, FontWeight->"Plain"], Cell["\<\ Here we create a cached version of our function, with the cache size equal \ to 15 :\ \>", "Text", CellChangeTimes->{{3.4183934024912386`*^9, 3.418393420491469*^9}, { 3.4183934538981466`*^9, 3.4183934835079007`*^9}}], Cell[BoxData[ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fn", ",", "15"}], "]"}]], "Code"], Cell["It produces the same results as < f > would :", "Text", CellChangeTimes->{{3.4183936176346173`*^9, 3.4183936395255227`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{"fn", "/@", RowBox[{"Range", "[", "50", "]"}]}], "\n"}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375", ",", "256", ",", "4913", ",", "324", ",", "6859", ",", "400", ",", "9261", ",", "484", ",", "12167", ",", "576", ",", "15625", ",", "676", ",", "19683", ",", "784", ",", "24389", ",", "900", ",", "29791", ",", "1024", ",", "35937", ",", "1156", ",", "42875", ",", "1296", ",", "50653", ",", "1444", ",", "59319", ",", "1600", ",", "68921", ",", "1764", ",", "79507", ",", "1936", ",", "91125", ",", "2116", ",", "103823", ",", "2304", ",", "117649", ",", "2500"}], "}"}]], "Output", CellChangeTimes->{3.4183930923310184`*^9, 3.418393195707342*^9, 3.4183935042425413`*^9, 3.418396131713672*^9, 3.4183995238977165`*^9}] }, Open ]], Cell["\<\ We can look inside the cache to see which values are cached currently, by \ using < CreateCacheFunction > . It will create a brand new function with the \ name which we provide, which will store the same values as those currently in \ the cache :\ \>", "Text", CellChangeTimes->{{3.418393648135008*^9, 3.418393668479018*^9}, { 3.4183937095889196`*^9, 3.4183937577457857`*^9}}], Cell[BoxData[ RowBox[{"CreateCacheFunction", "[", RowBox[{"fn", ",", "testfn"}], "]"}]], "Code"], Cell["We can check :", "Text", CellChangeTimes->{{3.418393784730506*^9, 3.4183937889024343`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{"DownValues", "[", "testfn", "]"}], "\n"}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "36", "]"}], "]"}], "\[RuleDelayed]", "1296"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "37", "]"}], "]"}], "\[RuleDelayed]", "50653"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "38", "]"}], "]"}], "\[RuleDelayed]", "1444"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "39", "]"}], "]"}], "\[RuleDelayed]", "59319"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "40", "]"}], "]"}], "\[RuleDelayed]", "1600"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "41", "]"}], "]"}], "\[RuleDelayed]", "68921"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "42", "]"}], "]"}], "\[RuleDelayed]", "1764"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "43", "]"}], "]"}], "\[RuleDelayed]", "79507"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "44", "]"}], "]"}], "\[RuleDelayed]", "1936"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "45", "]"}], "]"}], "\[RuleDelayed]", "91125"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "46", "]"}], "]"}], "\[RuleDelayed]", "2116"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "47", "]"}], "]"}], "\[RuleDelayed]", "103823"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "48", "]"}], "]"}], "\[RuleDelayed]", "2304"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "49", "]"}], "]"}], "\[RuleDelayed]", "117649"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "50", "]"}], "]"}], "\[RuleDelayed]", "2500"}]}], "}"}]], "Output", CellChangeTimes->{3.418393115206311*^9, 3.4183937723553476`*^9, 3.4183961343855815`*^9, 3.4183995239445925`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["\<\ Ways to clear the cache or remove the cached function definitions\ \>", "Subsection", CellChangeTimes->{{3.418394952292326*^9, 3.4183949677300234`*^9}}, FontWeight->"Plain"], Cell["We can clear the cache by using < EmptyCache > function :", "Text", CellChangeTimes->{{3.4183937998400745`*^9, 3.418393842246867*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"EmptyCache", "[", "fn", "]"}], ";"}]], "Input", CellChangeTimes->{{3.4183938508407273`*^9, 3.4183938594345875`*^9}}], Cell["\<\ By calling CreateCacheFunction again, we can look inside the cache and make \ sure that it is cleared : \ \>", "Text", CellChangeTimes->{{3.4183938624815016`*^9, 3.418393901763254*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"CreateCacheFunction", "[", RowBox[{"fn", ",", "testfn"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{"DownValues", "[", "testfn", "]"}]}], "Input", CellChangeTimes->{{3.4183939113415017`*^9, 3.418393921294754*^9}}], Cell[BoxData[ RowBox[{"{", "}"}]], "Output", CellChangeTimes->{3.4183939190447254`*^9, 3.418396141151293*^9, 3.4183995290852833`*^9}] }, Open ]], Cell["\<\ Once we run the cached function again, the cache will be again populated : \ \>", "Text", CellChangeTimes->{{3.418393933544911*^9, 3.4183939648265615`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fn", "/@", RowBox[{"Range", "[", "20", "]"}]}]], "Input", CellChangeTimes->{{3.4183939700141277`*^9, 3.418393978092356*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375", ",", "256", ",", "4913", ",", "324", ",", "6859", ",", "400"}], "}"}]], "Output", CellChangeTimes->{3.4183939796861267`*^9, 3.4183961411825438`*^9, 3.4183995291165333`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"CreateCacheFunction", "[", RowBox[{"fn", ",", "testfn"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{"DownValues", "[", "testfn", "]"}]}], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "6", "]"}], "]"}], "\[RuleDelayed]", "36"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "7", "]"}], "]"}], "\[RuleDelayed]", "343"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "8", "]"}], "]"}], "\[RuleDelayed]", "64"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "9", "]"}], "]"}], "\[RuleDelayed]", "729"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "10", "]"}], "]"}], "\[RuleDelayed]", "100"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "11", "]"}], "]"}], "\[RuleDelayed]", "1331"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "12", "]"}], "]"}], "\[RuleDelayed]", "144"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "13", "]"}], "]"}], "\[RuleDelayed]", "2197"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "14", "]"}], "]"}], "\[RuleDelayed]", "196"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "15", "]"}], "]"}], "\[RuleDelayed]", "3375"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "16", "]"}], "]"}], "\[RuleDelayed]", "256"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "17", "]"}], "]"}], "\[RuleDelayed]", "4913"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "18", "]"}], "]"}], "\[RuleDelayed]", "324"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "19", "]"}], "]"}], "\[RuleDelayed]", "6859"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "20", "]"}], "]"}], "\[RuleDelayed]", "400"}]}], "}"}]], "Output", CellChangeTimes->{3.418393986920594*^9, 3.4183961412137938`*^9, 3.4183995291477838`*^9}] }, Open ]], Cell["\<\ If we want to remove completely both the internal cache and the cached \ function definition, we can use DestroyCached :\ \>", "Text", CellChangeTimes->{{3.418394013389683*^9, 3.4183940599059033`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"DestroyCached", "[", "fn", "]"}], "\n"}]], "Code"], Cell["\<\ We can check that there are no definitions associated with < fn > any more :\ \>", "Text", CellChangeTimes->{{3.4183940701247845`*^9, 3.418394103312709*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fn", "/@", RowBox[{"Range", "[", "10", "]"}]}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{"fn", "[", "1", "]"}], ",", RowBox[{"fn", "[", "2", "]"}], ",", RowBox[{"fn", "[", "3", "]"}], ",", RowBox[{"fn", "[", "4", "]"}], ",", RowBox[{"fn", "[", "5", "]"}], ",", RowBox[{"fn", "[", "6", "]"}], ",", RowBox[{"fn", "[", "7", "]"}], ",", RowBox[{"fn", "[", "8", "]"}], ",", RowBox[{"fn", "[", "9", "]"}], ",", RowBox[{"fn", "[", "10", "]"}]}], "}"}]], "Output", CellChangeTimes->{3.418393133394044*^9, 3.4183961412762947`*^9, 3.418399529194659*^9}] }, Open ]], Cell["\<\ Another way to clear the existing cache values is simply to call MakeCached \ once again with the same name for the cached function - this will \ automatically remove the old cache values :\ \>", "Text", CellChangeTimes->{{3.4183946326007338`*^9, 3.4183947021797495`*^9}}], Cell["\<\ We create a cached function and populate the cache as before :\ \>", "Text", CellChangeTimes->{{3.4183948171187205`*^9, 3.418394841072152*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fn", ",", "10"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{"fn", "/@", RowBox[{"Range", "[", "15", "]"}]}]}], "Input", CellChangeTimes->{{3.418394711257991*^9, 3.4183947233518953`*^9}, 3.418394783712043*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375"}], "}"}]], "Output", CellChangeTimes->{3.418394799587246*^9, 3.4183961413075447`*^9, 3.4183995292259097`*^9}] }, Open ]], Cell["We can once again inspect the cache :", "Text", CellChangeTimes->{{3.418394849337883*^9, 3.4183948602598977`*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"CreateCacheFunction", "[", RowBox[{"fn", ",", "testfn"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{"DownValues", "[", "testfn", "]"}]}], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "6", "]"}], "]"}], "\[RuleDelayed]", "36"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "7", "]"}], "]"}], "\[RuleDelayed]", "343"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "8", "]"}], "]"}], "\[RuleDelayed]", "64"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "9", "]"}], "]"}], "\[RuleDelayed]", "729"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "10", "]"}], "]"}], "\[RuleDelayed]", "100"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "11", "]"}], "]"}], "\[RuleDelayed]", "1331"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "12", "]"}], "]"}], "\[RuleDelayed]", "144"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "13", "]"}], "]"}], "\[RuleDelayed]", "2197"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "14", "]"}], "]"}], "\[RuleDelayed]", "196"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfn", "[", "15", "]"}], "]"}], "\[RuleDelayed]", "3375"}]}], "}"}]], "Output", CellChangeTimes->{{3.4183947596023593`*^9, 3.418394770586875*^9}, 3.4183948008685126`*^9, 3.4183961413387957`*^9, 3.418399529272785*^9}] }, Open ]], Cell["\<\ Now we call MakeCached once again, and the cache is automatically cleared :\ \>", "Text", CellChangeTimes->{{3.4183948707756577`*^9, 3.418394907479252*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fn", ",", "10"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"CreateCacheFunction", "[", RowBox[{"fn", ",", "testfn"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{"DownValues", "[", "testfn", "]"}]}], "Input", CellChangeTimes->{{3.418394810946767*^9, 3.418394811149894*^9}, { 3.4183948665724783`*^9, 3.4183948696037674`*^9}}], Cell[BoxData[ RowBox[{"{", "}"}]], "Output", CellChangeTimes->{3.4183948115405245`*^9, 3.4183961413856707`*^9, 3.418399529304036*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["\<\ What happens when the cache is not properly cleared, and also on independent \ caches.\ \>", "Subsection", CellChangeTimes->{{3.418395024855755*^9, 3.4183950513873444`*^9}}, FontWeight->"Plain"], Cell["\<\ Now we create 3 cached functions for the same original function < f > . \ \>", "Text", CellChangeTimes->{{3.418394132156828*^9, 3.4183941783761697`*^9}}], Cell[BoxData[ RowBox[{"\n", RowBox[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fn", ",", "10"}], "]"}], ";"}], "\n", RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fn1", ",", "10"}], "]"}], ";"}], "\n", RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fnind", ",", "10", ",", RowBox[{"IndependentCache", "->", "True"}]}], "]"}], ";"}], "\n"}]}]], "Code", CellChangeTimes->{{3.418394123234839*^9, 3.418394130141177*^9}}], Cell["\<\ The first two functions are identical, but the last one is created with an \ option IndependentCache -> True, and thus is supposed to be independent of \ the possible future changes in the definition of the original function < f > \ . We run some tests now :\ \>", "Text", CellChangeTimes->{{3.4183941838137393`*^9, 3.418394257158428*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fn", "/@", RowBox[{"Range", "[", "30", "]"}]}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375", ",", "256", ",", "4913", ",", "324", ",", "6859", ",", "400", ",", "9261", ",", "484", ",", "12167", ",", "576", ",", "15625", ",", "676", ",", "19683", ",", "784", ",", "24389", ",", "900"}], "}"}]], "Output", CellChangeTimes->{3.4183932405829163`*^9, 3.418394262611623*^9, 3.4183961548858438`*^9, 3.4183995385072784`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{"fn1", "/@", RowBox[{"Range", "[", "30", "]"}]}], "\n"}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375", ",", "256", ",", "4913", ",", "324", ",", "6859", ",", "400", ",", "9261", ",", "484", ",", "12167", ",", "576", ",", "15625", ",", "676", ",", "19683", ",", "784", ",", "24389", ",", "900"}], "}"}]], "Output", CellChangeTimes->{3.418393244114211*^9, 3.418394263549135*^9, 3.418396154917094*^9, 3.418399538538529*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fnind", "/@", RowBox[{"Range", "[", "30", "]"}]}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "27", ",", "16", ",", "125", ",", "36", ",", "343", ",", "64", ",", "729", ",", "100", ",", "1331", ",", "144", ",", "2197", ",", "196", ",", "3375", ",", "256", ",", "4913", ",", "324", ",", "6859", ",", "400", ",", "9261", ",", "484", ",", "12167", ",", "576", ",", "15625", ",", "676", ",", "19683", ",", "784", ",", "24389", ",", "900"}], "}"}]], "Output", CellChangeTimes->{3.41839324753613*^9, 3.4183942644866467`*^9, 3.4183961549483447`*^9, 3.4183995385854044`*^9}] }, Open ]], Cell["\<\ So far so good. We now change the definition of the original function\ \>", "Text", CellChangeTimes->{{3.418394268986705*^9, 3.4183942727211275`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", "f", "]"}], ";"}], "\n", RowBox[{ RowBox[{ RowBox[{"f", "[", "x_", "]"}], ":=", "x"}], ";"}]}], "Code", CellChangeTimes->{{3.418394277314936*^9, 3.418394280971233*^9}}], Cell["\<\ The first version does not work correctly, since the first few values are \ taken from the cache which was created for a previous definition for . The \ mistake was not to clear the cache before performing a new computation with \ the same cached function\ \>", "Text", CellChangeTimes->{3.418394302737137*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fn", "/@", RowBox[{"Range", "[", RowBox[{"30", ",", "1", ",", RowBox[{"-", "1"}]}], "]"}]}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "900", ",", "24389", ",", "784", ",", "19683", ",", "676", ",", "15625", ",", "576", ",", "12167", ",", "484", ",", "9261", ",", "20", ",", "19", ",", "18", ",", "17", ",", "16", ",", "15", ",", "14", ",", "13", ",", "12", ",", "11", ",", "10", ",", "9", ",", "8", ",", "7", ",", "6", ",", "5", ",", "4", ",", "3", ",", "2", ",", "1"}], "}"}]], "Output", CellChangeTimes->{3.418393264895727*^9, 3.4183942852681627`*^9, 3.41839615499522*^9, 3.4183995386322803`*^9}] }, Open ]], Cell["\<\ For this version of the chached function, we emptied the cache, and then it \ works fine\ \>", "Text", CellChangeTimes->{3.4183943066278114`*^9}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"EmptyCache", "[", "fn1", "]"}], ";"}], "\n", RowBox[{"fn1", "/@", RowBox[{"Range", "[", RowBox[{"30", ",", "1", ",", RowBox[{"-", "1"}]}], "]"}]}]}], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "30", ",", "29", ",", "28", ",", "27", ",", "26", ",", "25", ",", "24", ",", "23", ",", "22", ",", "21", ",", "20", ",", "19", ",", "18", ",", "17", ",", "16", ",", "15", ",", "14", ",", "13", ",", "12", ",", "11", ",", "10", ",", "9", ",", "8", ",", "7", ",", "6", ",", "5", ",", "4", ",", "3", ",", "2", ",", "1"}], "}"}]], "Output", CellChangeTimes->{3.418393271223933*^9, 3.418394308643462*^9, 3.418396155042096*^9, 3.4183995386635303`*^9}] }, Open ]], Cell["\<\ This version was created as independent of the subsequent changes in the \ original function. Therefore, for it there is no problem in this case - it \ still computes the values that correspond to the previous (destroyed now) \ definitions of the original function .\ \>", "Text", CellChangeTimes->{{3.4183943176435776`*^9, 3.4183943626597786`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fnind", "/@", RowBox[{"Range", "[", RowBox[{"30", ",", "1", ",", RowBox[{"-", "1"}]}], "]"}]}]], "Code", CellChangeTimes->{{3.418393288927285*^9, 3.4183932896460443`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ "900", ",", "24389", ",", "784", ",", "19683", ",", "676", ",", "15625", ",", "576", ",", "12167", ",", "484", ",", "9261", ",", "400", ",", "6859", ",", "324", ",", "4913", ",", "256", ",", "3375", ",", "196", ",", "2197", ",", "144", ",", "1331", ",", "100", ",", "729", ",", "64", ",", "343", ",", "36", ",", "125", ",", "16", ",", "27", ",", "4", ",", "1"}], "}"}]], "Output", CellChangeTimes->{{3.418393279333412*^9, 3.418393290021049*^9}, 3.4183943155341754`*^9, 3.418396155073346*^9, 3.4183995386947813`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"DestroyCached", "/@", RowBox[{"{", RowBox[{"fn", ",", "fn1", ",", "fnind"}], "}"}]}]], "Input", CellChangeTimes->{{3.418394474348708*^9, 3.418394482833192*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"Null", ",", "Null", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{3.4183944836457024`*^9, 3.4183961551045966`*^9, 3.4183995387416563`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Pure functions", "Subsection", CellChangeTimes->{{3.418395096841051*^9, 3.418395100184844*^9}}, FontWeight->"Plain"], Cell["Here we try to create a cached version for a pure function", "Text", CellChangeTimes->{{3.4183943771130886`*^9, 3.4183943968789663`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{ RowBox[{ RowBox[{"#", "^", "2"}], "&"}], ",", "fnpure", ",", "10"}], "]"}], ";"}]], "Code"], Cell["We can see that it works fine with this one :", "Text"], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"fnpure", "/@", RowBox[{"Range", "[", "50", "]"}]}]], "Code"], Cell[BoxData[ RowBox[{"{", RowBox[{ "1", ",", "4", ",", "9", ",", "16", ",", "25", ",", "36", ",", "49", ",", "64", ",", "81", ",", "100", ",", "121", ",", "144", ",", "169", ",", "196", ",", "225", ",", "256", ",", "289", ",", "324", ",", "361", ",", "400", ",", "441", ",", "484", ",", "529", ",", "576", ",", "625", ",", "676", ",", "729", ",", "784", ",", "841", ",", "900", ",", "961", ",", "1024", ",", "1089", ",", "1156", ",", "1225", ",", "1296", ",", "1369", ",", "1444", ",", "1521", ",", "1600", ",", "1681", ",", "1764", ",", "1849", ",", "1936", ",", "2025", ",", "2116", ",", "2209", ",", "2304", ",", "2401", ",", "2500"}], "}"}]], "Output", CellChangeTimes->{3.4183933060993795`*^9, 3.4183950817314825`*^9, 3.41839617137043*^9, 3.418399552413707*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"CreateCacheFunction", "[", RowBox[{"fnpure", ",", "testfnpure"}], "]"}], ";"}], "\n", RowBox[{"DownValues", "[", "testfnpure", "]"}]}], "Code", CellChangeTimes->{{3.4183950739188824`*^9, 3.418395074778269*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "41", "]"}], "]"}], "\[RuleDelayed]", "1681"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "42", "]"}], "]"}], "\[RuleDelayed]", "1764"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "43", "]"}], "]"}], "\[RuleDelayed]", "1849"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "44", "]"}], "]"}], "\[RuleDelayed]", "1936"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "45", "]"}], "]"}], "\[RuleDelayed]", "2025"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "46", "]"}], "]"}], "\[RuleDelayed]", "2116"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "47", "]"}], "]"}], "\[RuleDelayed]", "2209"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "48", "]"}], "]"}], "\[RuleDelayed]", "2304"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "49", "]"}], "]"}], "\[RuleDelayed]", "2401"}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"testfnpure", "[", "50", "]"}], "]"}], "\[RuleDelayed]", "2500"}]}], "}"}]], "Output", CellChangeTimes->{{3.418395077918934*^9, 3.418395082543993*^9}, 3.4183961714173055`*^9, 3.4183995524605823`*^9}] }, Open ]], Cell["\<\ Here we attempt to create an independent cache function with a pure function. \ The error message is issued as it should (since we don't allow to create \ independent cache functions with pure functions. The main reason is that pure functions are often used \ to embed some fixed parameters for functions with multiple arguments, which then will introduce hidden \ dependencies despite the claim of independence of the cache. Such dependencies can of course be also \ introduced with a pattern-defined functions - the problem of cache independence is so far generally unresolved.\ \ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{ RowBox[{ RowBox[{"#", "^", "2"}], "&"}], ",", "fnpureind", ",", "10", ",", RowBox[{"IndependentCache", "->", "True"}]}], "]"}], ";"}]], "Code"], Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "::", "\<\"badopt\"\>"}], RowBox[{ ":", " "}], "\<\"The option \\!\\(IndependentCache\\) can not be used with \ an input \\nfunction being a pure function\"\>"}]], "Message", "MSG", CellChangeTimes->{3.4183933366310205`*^9, 3.418396172323567*^9, 3.418399553382469*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Other functions", "Subsection", CellChangeTimes->{{3.4183963297005816`*^9, 3.418396333856885*^9}}, FontWeight->"Plain"], Cell[TextData[StyleBox["Here we define a function through SubValues:", FontWeight->"Plain"]], "Text", CellChangeTimes->{{3.4183962190116644`*^9, 3.4183962444807405`*^9}}, FontWeight->"Bold"], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"g", "[", "h", "]"}], "[", "x_", "]"}], ":=", RowBox[{"x", "^", "3"}]}]], "Code"], Cell["\<\ Our convention is that this definition is not acceptable to be used by \ MakeCached - only functions defined with DownValues or pure functions are \ supported :\ \>", "Text", CellChangeTimes->{{3.418396246887021*^9, 3.4183963114190974`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"MakeCached", "[", RowBox[{ RowBox[{"g", "[", "h", "]"}], ",", "hdtestf", ",", "10"}], "]"}]], "Code"], Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "::", "\<\"badfun\"\>"}], RowBox[{ ":", " "}], "\<\"The first argument of MakeCached must have a head Function \ or Symbol\"\>"}]], "Message", "MSG", CellChangeTimes->{3.418396173104827*^9, 3.4183995606169367`*^9}], Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "::", "\<\"badarg\"\>"}], RowBox[{ ":", " "}], "\<\"Something is wrong with the types and/or \\nnumber of \ arguments. MakeCached expects three arguments plus possibly\\nan \ option\"\>"}]], "Message", "MSG", CellChangeTimes->{3.418396173104827*^9, 3.4183995612731953`*^9}], Cell[BoxData[ RowBox[{"MakeCached", "[", RowBox[{ RowBox[{"g", "[", "h", "]"}], ",", "hdtestf", ",", "10"}], "]"}]], "Output",\ CellChangeTimes->{3.4183933449436274`*^9, 3.4183961737767105`*^9, 3.4183995613044453`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Performance", "Subsection", CellChangeTimes->{{3.418396391779501*^9, 3.418396394498286*^9}}, FontWeight->"Plain"], Cell["Here we define some simple test function,", "Text", CellChangeTimes->{{3.418397946955657*^9, 3.4183979577057943`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", RowBox[{"f", ",", "fmemo"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", "x_", "]"}], ":=", RowBox[{"x", "^", "2"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"fmemo", "[", "x_", "]"}], ":=", RowBox[{ RowBox[{"fmemo", "[", "x", "]"}], "=", RowBox[{"x", "^", "2"}]}]}], ";"}]}], "Input", CellChangeTimes->{{3.4183965180779924`*^9, 3.418396534046947*^9}, { 3.4183965739224577`*^9, 3.418396593016452*^9}}], Cell["and its \"memoized\" analog.", "Text", CellChangeTimes->{{3.418397960080825*^9, 3.4183979717059736`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"testlist", " ", "=", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{"Random", "[", RowBox[{"Integer", ",", RowBox[{"{", RowBox[{"1", ",", "500"}], "}"}]}], "]"}], ",", RowBox[{"{", "10000", "}"}]}], "]"}]}], ";"}]], "Input", CellChangeTimes->{{3.418396536671981*^9, 3.4183965657817283`*^9}, { 3.418396651251572*^9, 3.418396665923635*^9}}], Cell["Let us perform some timing measurements :", "Text", CellChangeTimes->{{3.4183979765341606`*^9, 3.418397987096796*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"res1", "=", RowBox[{"f", "/@", "testlist"}]}], ")"}], ";"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.418396568938019*^9, 3.418396569969282*^9}, { 3.418396601782189*^9, 3.4183966406733117`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.03099999999999993`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{{3.418396613516714*^9, 3.4183966895489373`*^9}, 3.4183969828339415`*^9, {3.418399568523288*^9, 3.418399587617282*^9}}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"res2", "=", " ", RowBox[{"fmemo", "/@", "testlist"}]}], ")"}], ";"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.4183966158292437`*^9, 3.418396624860609*^9}, { 3.4183969708806634`*^9, 3.4183969767557383`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.03099999999999979`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{ 3.4183966258137465`*^9, {3.4183966794863086`*^9, 3.418396700049072*^9}, { 3.4183969775213737`*^9, 3.418396983662077*^9}, {3.4183995686014137`*^9, 3.418399587679783*^9}}] }, Open ]], Cell["We now make a cached version of < f > and compute the same :", "Text", CellChangeTimes->{{3.418396962364929*^9, 3.4183969663649807`*^9}, { 3.418396997334127*^9, 3.418397014693724*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"f", ",", "fc", ",", "500"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"res3", " ", "=", " ", RowBox[{"fc", "/@", "testlist"}]}], ")"}], ";"}], "//", "Timing"}]}], "Input", CellChangeTimes->{{3.4183967414246016`*^9, 3.418396750424717*^9}, { 3.4183970240063434`*^9, 3.4183970345221033`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.3749999999999999`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{{3.4183967544091425`*^9, 3.4183968022535048`*^9}, 3.4183970359127455`*^9, {3.4183995689920435`*^9, 3.418399588086038*^9}}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"res1", "===", "res2", "===", "res3"}]], "Input", CellChangeTimes->{{3.41839721474316*^9, 3.4183972207432365`*^9}}], Cell[BoxData["True"], "Output", CellChangeTimes->{ 3.4183972210869913`*^9, {3.4183995690545444`*^9, 3.4183995881329136`*^9}}] }, Open ]], Cell["\<\ This shows the pure overhead as compared to the f[x_] := f[x] = rhs idiom - \ it is about 10 times in this particular example. In this case, then, it is \ advanatgeous to use the latter if possible in terms of memory, and also in \ this case it does not pay off to use cache since the original function is not \ computationally intensive - it takes just a little longer to recompute it \ than to fetch it from the cache.\ \>", "Text", CellChangeTimes->{{3.4183968073473206`*^9, 3.4183969461147213`*^9}, { 3.4183970536942234`*^9, 3.418397058959916*^9}}], Cell["\<\ Here we consider an operation which is more computationally - intensive :\ \>", "Text", CellChangeTimes->{{3.4183973098850026`*^9, 3.418397333275927*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", "g", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"g", "[", "x_", "]"}], ":=", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", RowBox[{"sum", " ", "=", " ", "0"}], "}"}], ",", RowBox[{ RowBox[{"Do", "[", RowBox[{ RowBox[{"sum", "+=", RowBox[{"x", "^", "i"}]}], ",", RowBox[{"{", RowBox[{"i", ",", "100"}], "}"}]}], "]"}], ";", "sum"}]}], "]"}]}], ";"}]}], "Input", CellChangeTimes->{{3.4183970639443545`*^9, 3.4183971709925995`*^9}}], Cell["The test list for it :", "Text", CellChangeTimes->{{3.418397344447945*^9, 3.418397348666749*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"gtestlist", " ", "=", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{"Random", "[", RowBox[{"Integer", ",", RowBox[{"{", RowBox[{"1", ",", "100"}], "}"}]}], "]"}], ",", RowBox[{"{", "2000", "}"}]}], "]"}]}], ";"}]], "Input", CellChangeTimes->{{3.418397173211378*^9, 3.4183971950397825`*^9}, { 3.418397255149927*^9, 3.418397255243678*^9}}], Cell["The direct application :", "Text", CellChangeTimes->{{3.41839735813562*^9, 3.4183973625731773`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"gres1", " ", "=", " ", RowBox[{"g", "/@", "gtestlist"}]}], ")"}], ";"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.418397209743096*^9, 3.4183972490873494`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"2.25`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{{3.418397250790496*^9, 3.418397258962476*^9}, { 3.418399571226447*^9, 3.4183995907579474`*^9}}] }, Open ]], Cell["The application based on cache :", "Text", CellChangeTimes->{{3.4183973688701324`*^9, 3.4183973759014726`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"g", ",", "gc", ",", "100"}], "]"}], ";"}]], "Input", CellChangeTimes->{{3.418397281259636*^9, 3.4183972854628153`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"gres2", " ", "=", " ", RowBox[{"gc", "/@", "gtestlist"}]}], ")"}], ";"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.4183972951504393`*^9, 3.418397297056713*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.1720000000000002`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{ 3.418397297806723*^9, {3.418399571507701*^9, 3.418399592039214*^9}}] }, Open ]], Cell["The results are the same of course :", "Text", CellChangeTimes->{{3.418397392589186*^9, 3.418397401229922*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"gres1", "===", "gres2"}]], "Input", CellChangeTimes->{{3.418397382339055*^9, 3.418397387542247*^9}}], Cell[BoxData["True"], "Output", CellChangeTimes->{ 3.418397388042253*^9, {3.4183995715389514`*^9, 3.4183995931329775`*^9}}] }, Open ]], Cell["\<\ In this example, we gained an order of magnitude by using cache. Of course, \ the use of the simple memoization idiom will be still faster :\ \>", "Text", CellChangeTimes->{{3.418397407261249*^9, 3.4183974444179745`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", "gmemo", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"gmemo", "[", "x_", "]"}], ":=", RowBox[{ RowBox[{"gmemo", "[", "x", "]"}], "=", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", RowBox[{"sum", " ", "=", " ", "0"}], "}"}], ",", RowBox[{ RowBox[{"Do", "[", RowBox[{ RowBox[{"sum", "+=", RowBox[{"x", "^", "i"}]}], ",", RowBox[{"{", RowBox[{"i", ",", "100"}], "}"}]}], "]"}], ";", "sum"}]}], "]"}]}]}], ";"}]}], "Input", CellChangeTimes->{{3.4183974589337854`*^9, 3.4183974684651575`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"gres3", " ", "=", " ", RowBox[{"gmemo", "/@", "gtestlist"}]}], ")"}], ";"}], "//", "Timing"}]], "Input", CellChangeTimes->{{3.418397485684128*^9, 3.4183974894185505`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.12500000000000003`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{ 3.418397492418589*^9, {3.4183995716952033`*^9, 3.41839959371111*^9}}] }, Open ]], Cell["\<\ But here already the speed - up is not that sgnificant, since the computed \ function itself is now the most expensive operation. The advantage of using \ cache w.r.t the simple idiom f[x_] := f[x] = rhs is that in this case, the \ memory used in the calculation to store the cached results can be controlled. \ While it is not directly implemented so far, one can equipp our functions \ with more sophisticated run - time memory control and cache size adjustment.\ \>", "Text", CellChangeTimes->{{3.41839749524675*^9, 3.4183976572331986`*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Cache size and BufferSize option", "Subsection", CellChangeTimes->{{3.4183979060332584`*^9, 3.4183979139239845`*^9}}, FontWeight->"Plain"], Cell["We loose the speed advantage if our cache is too small :", "Text", CellChangeTimes->{{3.4183967509559736`*^9, 3.418396756706047*^9}, { 3.4183977337966785`*^9, 3.4183977466562185`*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"g", ",", "gc1", ",", "10"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"gres4", " ", "=", " ", RowBox[{"gc1", "/@", "gtestlist"}]}], ")"}], ";"}], "//", "Timing"}]}], "Input", CellChangeTimes->{{3.4183976920148935`*^9, 3.4183977090151114`*^9}, { 3.4183977543750668`*^9, 3.4183977544375677`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"2.1559999999999997`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{3.418397712593282*^9, 3.418399609164433*^9}] }, Open ]], Cell["\<\ We can however still maintain a small cache size if we use the option \ BufferSize, which allows cache to grow large temporarily but then the buffer \ is cleared every time when the cache size reaches the threshold value, which \ is equal to cachesize + BufferSize.\ \>", "Text", CellChangeTimes->{{3.4183977615314083`*^9, 3.4183978605951767`*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"MakeCached", "[", RowBox[{"g", ",", "gc1", ",", "10", ",", RowBox[{"BufferSize", "\[Rule]", "100"}]}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"gres2", " ", "=", " ", RowBox[{"gc1", "/@", "gtestlist"}]}], ")"}], ";"}], "//", "Timing"}]}], "Input", CellChangeTimes->{{3.418397720390257*^9, 3.4183977264528346`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"0.1719999999999992`", ",", "Null"}], "}"}]], "Output", CellChangeTimes->{3.4183977278122272`*^9, 3.4183996094300613`*^9}] }, Open ]], Cell["In this way, we recover the previous speed - up.", "Text", CellChangeTimes->{{3.418397866188998*^9, 3.41839788118919*^9}}] }, Open ]] }, AutoGeneratedPackage->None, WindowSize->{1272, 837}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, ShowSelection->True, Magnification->2., FrontEndVersion->"6.0 for Microsoft Windows (32-bit) (March 13, 2008)", StyleDefinitions->"Default.nb" ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[590, 23, 156, 3, 72, "Subsection"], Cell[749, 28, 564, 11, 220, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[1350, 44, 128, 2, 72, "Subsection"], Cell[1481, 48, 118, 2, 57, "Input"], Cell[CellGroupData[{ Cell[1624, 54, 117, 2, 89, "Code"], Cell[1744, 58, 2019, 53, 153, "Print"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[3812, 117, 127, 2, 72, "Subsection"], Cell[3942, 121, 626, 16, 126, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[4605, 142, 145, 2, 72, "Subsection"], Cell[4753, 146, 230, 5, 55, "Text"], Cell[4986, 153, 97, 2, 89, "Code"], Cell[5086, 157, 132, 1, 55, "Text"], Cell[CellGroupData[{ Cell[5243, 162, 103, 3, 124, "Code"], Cell[5349, 167, 865, 13, 160, "Output"] }, Open ]], Cell[6229, 183, 389, 7, 121, "Text"], Cell[6621, 192, 100, 2, 89, "Code"], Cell[6724, 196, 98, 1, 55, "Text"], Cell[CellGroupData[{ Cell[6847, 201, 86, 2, 124, "Code"], Cell[6936, 205, 2143, 64, 296, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[9128, 275, 185, 4, 72, "Subsection"], Cell[9316, 281, 141, 1, 55, "Text"], Cell[9460, 284, 152, 3, 57, "Input"], Cell[9615, 289, 196, 4, 55, "Text"], Cell[CellGroupData[{ Cell[9836, 297, 259, 5, 92, "Input"], Cell[10098, 304, 138, 3, 82, "Output"] }, Open ]], Cell[10251, 310, 167, 3, 55, "Text"], Cell[CellGroupData[{ Cell[10443, 317, 152, 3, 57, "Input"], Cell[10598, 322, 400, 8, 117, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[11035, 335, 191, 4, 92, "Input"], Cell[11229, 341, 2094, 64, 321, "Output"] }, Open ]], Cell[13338, 408, 212, 4, 88, "Text"], Cell[13553, 414, 85, 2, 124, "Code"], Cell[13641, 418, 168, 3, 55, "Text"], Cell[CellGroupData[{ Cell[13834, 425, 83, 2, 89, "Code"], Cell[13920, 429, 545, 14, 82, "Output"] }, Open ]], Cell[14480, 446, 283, 5, 88, "Text"], Cell[14766, 453, 155, 3, 55, "Text"], Cell[CellGroupData[{ Cell[14946, 460, 298, 7, 92, "Input"], Cell[15247, 469, 332, 7, 82, "Output"] }, Open ]], Cell[15594, 479, 121, 1, 55, "Text"], Cell[CellGroupData[{ Cell[15740, 484, 191, 4, 92, "Input"], Cell[15934, 490, 1491, 44, 219, "Output"] }, Open ]], Cell[17440, 537, 167, 3, 55, "Text"], Cell[CellGroupData[{ Cell[17632, 544, 428, 9, 126, "Input"], Cell[18063, 555, 138, 3, 82, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[18250, 564, 206, 5, 72, "Subsection"], Cell[18459, 571, 164, 3, 55, "Text"], Cell[18626, 576, 503, 14, 226, "Code"], Cell[19132, 592, 350, 6, 121, "Text"], Cell[CellGroupData[{ Cell[19507, 602, 83, 2, 89, "Code"], Cell[19593, 606, 558, 10, 117, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[20188, 621, 104, 3, 124, "Code"], Cell[20295, 626, 552, 10, 117, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[20884, 641, 86, 2, 89, "Code"], Cell[20973, 645, 557, 10, 117, "Output"] }, Open ]], Cell[21545, 658, 161, 3, 55, "Text"], Cell[21709, 663, 225, 6, 124, "Code"], Cell[21937, 671, 324, 6, 121, "Text"], Cell[CellGroupData[{ Cell[22286, 681, 137, 4, 89, "Code"], Cell[22426, 687, 526, 9, 117, "Output"] }, Open ]], Cell[22967, 699, 156, 4, 55, "Text"], Cell[CellGroupData[{ Cell[23148, 707, 207, 6, 124, "Code"], Cell[23358, 715, 506, 9, 117, "Output"] }, Open ]], Cell[23879, 727, 366, 6, 121, "Text"], Cell[CellGroupData[{ Cell[24270, 737, 208, 5, 89, "Code"], Cell[24481, 744, 581, 10, 117, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[25099, 759, 192, 4, 57, "Input"], Cell[25294, 765, 187, 4, 82, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[25530, 775, 124, 2, 72, "Subsection"], Cell[25657, 779, 145, 1, 55, "Text"], Cell[25805, 782, 169, 6, 89, "Code"], Cell[25977, 790, 61, 0, 55, "Text"], Cell[CellGroupData[{ Cell[26063, 794, 87, 2, 89, "Code"], Cell[26153, 798, 809, 13, 185, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[26999, 816, 253, 5, 124, "Code"], Cell[27255, 823, 1531, 44, 219, "Output"] }, Open ]], Cell[28801, 870, 611, 13, 220, "Text"], Cell[CellGroupData[{ Cell[29437, 887, 223, 6, 89, "Code"], Cell[29663, 895, 325, 7, 78, "Message"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[30037, 908, 127, 2, 72, "Subsection"], Cell[30167, 912, 193, 3, 55, "Text"], Cell[30363, 917, 130, 4, 89, "Code"], Cell[30496, 923, 252, 5, 88, "Text"], Cell[CellGroupData[{ Cell[30773, 932, 131, 3, 89, "Code"], Cell[30907, 937, 268, 6, 43, "Message"], Cell[31178, 945, 327, 7, 112, "Message"], Cell[31508, 954, 230, 6, 82, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[31787, 966, 121, 2, 72, "Subsection"], Cell[31911, 970, 125, 1, 55, "Text"], Cell[32039, 973, 534, 15, 126, "Input"], Cell[32576, 990, 112, 1, 55, "Text"], Cell[32691, 993, 417, 11, 57, "Input"], Cell[33111, 1006, 125, 1, 55, "Text"], Cell[CellGroupData[{ Cell[33261, 1011, 279, 8, 57, "Input"], Cell[33543, 1021, 237, 4, 82, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[33817, 1030, 292, 8, 57, "Input"], Cell[34112, 1040, 294, 6, 82, "Output"] }, Open ]], Cell[34421, 1049, 193, 2, 55, "Text"], Cell[CellGroupData[{ Cell[34639, 1055, 418, 12, 92, "Input"], Cell[35060, 1069, 240, 4, 82, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[35337, 1078, 139, 2, 57, "Input"], Cell[35479, 1082, 128, 2, 82, "Output"] }, Open ]], Cell[35622, 1087, 566, 9, 154, "Text"], Cell[36191, 1098, 165, 3, 55, "Text"], Cell[36359, 1103, 586, 18, 92, "Input"], Cell[36948, 1123, 104, 1, 55, "Text"], Cell[37055, 1126, 417, 11, 57, "Input"], Cell[37475, 1139, 107, 1, 55, "Text"], Cell[CellGroupData[{ Cell[37607, 1144, 242, 7, 57, "Input"], Cell[37852, 1153, 197, 4, 82, "Output"] }, Open ]], Cell[38064, 1160, 118, 1, 55, "Text"], Cell[38185, 1163, 186, 4, 57, "Input"], Cell[CellGroupData[{ Cell[38396, 1171, 243, 7, 57, "Input"], Cell[38642, 1180, 185, 4, 82, "Output"] }, Open ]], Cell[38842, 1187, 118, 1, 55, "Text"], Cell[CellGroupData[{ Cell[38985, 1192, 125, 2, 57, "Input"], Cell[39113, 1196, 126, 2, 82, "Output"] }, Open ]], Cell[39254, 1201, 232, 4, 88, "Text"], Cell[39489, 1207, 666, 20, 92, "Input"], Cell[CellGroupData[{ Cell[40180, 1231, 246, 7, 57, "Input"], Cell[40429, 1240, 187, 4, 82, "Output"] }, Open ]], Cell[40631, 1247, 555, 8, 187, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[41223, 1260, 146, 2, 72, "Subsection"], Cell[41372, 1264, 193, 2, 55, "Text"], Cell[CellGroupData[{ Cell[41590, 1270, 423, 12, 92, "Input"], Cell[42016, 1284, 158, 3, 82, "Output"] }, Open ]], Cell[42189, 1290, 360, 6, 121, "Text"], Cell[CellGroupData[{ Cell[42574, 1300, 420, 12, 92, "Input"], Cell[42997, 1314, 162, 3, 82, "Output"] }, Open ]], Cell[43174, 1320, 129, 1, 55, "Text"] }, Open ]] } ] *) (* End of internal cache information *)