operators::persistentRemember – functions with persistent remember table
The domain operators::persistentRemember provides tools to define functions with a remember table which persists between MuPAD sessions.
Creating Elements
operators::persistentRemember(f, <directory, options>)
Parameters:
f: |
The function which is to be called to calculate the result when it is not yet in the database. |
Options:
directory: |
the name of the subdirectory to use for the results of this function, as a string. The default is to use the MuPAD name of the function. A value of FAIL means to use the default value. |
Format: |
the write format: either Bin or Text. With Bin, the data are stored in MuPAD's binary format. With Text, standard ASCII format is used. The default is Bin. |
RootDirectory: |
allows for specifying an alternate root directory for the database where subdirectory will be created; the default is operators::persistentRemember::directory. |
Details:
Objects of the domain operators::persistentRemember are functions which remember their result not only from one call to another (as with the standard remember option), but also from one MuPAD session to another.
This is implemented by storing the result in a database of files. The database is organized as follows. There is a root directory (by default ".persistentRememberDataBase" in the current directory). To each function of this domain is associated a subdirectory (by default the MuPAD name of the function). Finally, for each sequence of arguments, the result is stored in a plain text file in this subdirectory whose name is obtained by adding a ".output.mu" suffix to a fingerprint of the textual representation of the arguments. The input is stored as well in a file ending with ".input.mu".
expr2text and fread are used to convert objects to and from textual representations. So, in Text mode, this package only works correctly with objects x whose domain implement expr2text properly (that is text2expr(expr2text(x)) recreates an object strictly equivalent to x).
Experience shows that the concept is good; however, the curent implementation is rather crude, and evolutions are possible upon user requests; among other things:
Entries
"directory" |
the root directory of the database. |
setDirectory – set the root directory for the database
operators::persistentRemember::setDirectory(string directory)
Specifies the root directory to be used for the database.
reset – reset the database
operators::persistentRemember::reset(dom f)
Reset the database for f.
recalculate – set the root directory for the database
operators::persistentRemember::recalculate(dom f, )
Force the recalculation of f(arguments) and writes the result into the database.
We create a function g in this domain:
f := proc(x) begin print(coucou); x^2; end:
g := operators::persistentRemember(f):
The first time, g(2) is called, the calculation is delegated to f(2):
g(2)
coucou
Later on, the result is fetched from the database:
g(2)
If g is redefined the same way in a new MuPAD session, the precalculated results will still be available.
One has to be careful with some obvious traps. First of all, redefining the internal function does not clear the persistent remember table. Here, the result of g(2) is still 4 even if f has changed:
f := x->x^3:
g := operators::persistentRemember(f):
g(2)
In such cases, one has to explicitely reset the database (or to manually destroy the corresponding files):
g::reset():
g(2)
Also, when storing results in Text format, beware of domains that do not have a proper implementation of expr2text:
Z4 := Dom::IntegerMod(4):
f2 := x->x^2:
g := operators::persistentRemember(f2, FAIL, Text):
g(Z4(3)), g(Z4(3));
The first time g was called, the result was computed properly and stored in the file using expr2text. The second time, the result was reread from the file; however this did not create back an element of Z4 as desired because the textual representation of Z4(3) does not contain all the required information for this:
x := Z4(5); expr2text(x); bool(x = text2expr(expr2text(x)));
Using the binary format is safer:
f3 := x->x^2:
g := operators::persistentRemember(f3, FAIL, Bin):
g(Z4(3)), g(Z4(3));
Changes in MuPAD 3
New Function.