Documentation

## Remember Mechanism

MuPAD® notebooks will be removed in a future release. Use MATLAB® live scripts instead.

MATLAB live scripts support most MuPAD functionality, though there are some differences. For more information, see Convert MuPAD Notebooks to MATLAB Live Scripts.

### Why Use the Remember Mechanism

If your code calls a procedure with the same arguments more than once, avoid unnecessary reevaluations, and thus, improve performance. Instead of multiple evaluations of a procedure call with the same arguments, MuPAD® can store the results of the first procedure call in a special table. This table is called the remember table. The system stores the arguments of a procedure call as indices of the remember table entries, and the corresponding results as values of these entries. When you call a procedure using the same arguments as in previous calls, MuPAD accesses the remember table of that procedure. If the remember table contains the entry with the required arguments, MuPAD returns the value of that entry. Otherwise, MuPAD evaluates the procedure call, and writes the arguments and corresponding results to the remember table of the procedure.

Using the remember mechanism in MuPAD can significantly accelerate your computations, especially when you use recursive procedure calls. For example, create the procedure that computes the Lucas numbers. The Lucas numbers are a sequence of integers. The recursion formula that defines the `n`th Lucas number is similar to the definition of the Fibonacci numbers: The following recursive procedure returns any Lucas number:

```lucas:= proc(n:Type::PosInt) begin if n = 1 then 1 elif n = 2 then 3 else lucas(n - 1) + lucas(n - 2) end_if end_proc:```

However, if the value `n` is large, computing the `n`th Lucas number can be very slow. The number of required procedure calls is exponential. Often, the procedure calls itself with the same arguments, and it reevaluates the result in every call:

`time(lucas(35))`
` `

Using the remember mechanism eliminates these reevaluations. To enable the remember mechanism for a particular procedure, use the `prog::remember` function. This function returns a modified copy of a procedure that stores results of previous calls in the remember table:

`lucas := prog::remember(lucas):`

When you call this procedure, MuPAD accesses the remember table. If the system finds the required entry in the remember table, it returns remembered results immediately. Now, MuPAD computes the 35th and even the 100th Lucas number almost instantly:

`time(lucas(35)), time(lucas(100))`
` `

Alternatively, you can enable the remember mechanism for a particular procedure by using the option `remember` for that procedure. For example, use the option `remember` to enable the remember mechanism for the procedure `lucas`:

```lucas:= proc(n:Type::PosInt) option remember; begin if n = 1 then 1 elif n = 2 then 3 else lucas(n - 1) + lucas(n - 2) end_if end_proc:```

For further computations, delete the procedure `lucas`:

`delete lucas:`

### Remember Results Without Context

By default, the remember mechanism does not consider context information of a procedure call. Thus, the remember mechanism disregards any changes in assumptions set on the arguments of a procedure call and the number of digits used for floating-point arithmetic. By default, remember tables contain only arguments and results of procedure calls. They do not store context information. For example, create the function `f` that computes the reciprocal of a number. Use `prog::remember` to enable the remember mechanism for this function:

```f := (x)-> 1.0/x: f := prog::remember(f):```

The default number of significant digits for floating-point numbers is 10. Use the function `f` to compute the reciprocal of 3. The system displays the result with the 10-digits accuracy:

`f(3)`
` `

Now increase the number of digits to 50. Then call the function `f` with the argument 3 again. By default, MuPAD does not realize that you increased the required accuracy. The system accesses the remember table, finds the entry that corresponds to the argument 3, and returns the result previously computed for that argument. Since MuPAD must display the output with 50 digits, the last digits in the displayed result are incorrect:

```DIGITS := 50: f(3)```
` `

For further computations, restore the default value of `DIGITS` and delete `f`:

`delete DIGITS, f`

### Remember Results and Context

Although by default the remember mechanism in MuPAD disregards all context information, you can extend the `prog::remember` function call and take into account the properties of arguments and current accuracy of floating-point arithmetic. For example, create the function `f` that computes the reciprocal of a number. Use `prog::remember` to enable the remember mechanism for this function. In the `prog::remember` function call, specify the dependency function. The dependency function is the function that computes the current properties of the input arguments and the values of `DIGITS` and `ORDER`. Then `prog::remember` compares this context information with the context information used to compute the remembered values. If the context information is the same, `prog::remember` returns the remembered result. Otherwise MuPAD evaluates the current procedure call, and adds the new result to the remember table.

### Note

The option `remember` does not let you specify the dependency function. If results of a procedure depend on the context information, use the `prog::remember` function for that procedure.

In this example, the dependency function is a list that checks both the properties of input arguments and the value of `DIGITS`:

```f := (x)-> 1.0/x: f := prog::remember(f, () -> [property::depends(args()), DIGITS]):```

The default number of significant digits for floating-point numbers is 10. Use the function `f` to compute the reciprocal of 3. The system displays the result with the 10-digits accuracy:

`f(3)`
` `

If you set the number of digits to 50, and then call the function `f` with the same argument 3, `prog::remember` realizes that the number of digits has changed. Instead of returning the previous result stored in the remember table, the system reevaluates the result and updates the remember table:

```DIGITS := 50: f(3)```
` `

For further computations, restore the default value of `DIGITS` and delete `f`:

`delete DIGITS, f`

### Clear Remember Tables

In some cases, the remember mechanism can lead to incorrect results. For example, if a nested procedure uses the remember mechanism, and you redefine the inner procedure, MuPAD does not recognize the changes and does not reevaluate the procedure call.

Create the following procedure `f` as a wrapper for the MuPAD `heaviside` function. Use `prog::remember` to enable the remember mechanism for the procedure `f`:

```f := proc(x) begin heaviside(x) end: f := prog::remember(f):```

Now compute the Heaviside function for the values -10, 0, and 10. MuPAD uses the value `heaviside(0)=1/2`:

`f(-10), f(0), f(10)`
` `

You can define a different value for `heaviside(0)`. First, use the `unprotect` function to be able to overwrite the value of `heaviside`. Then, assign the new value to `heaviside(0)`:

```unprotect(heaviside): heaviside(0):= 0:```

Despite the new value `heaviside(0) = 0`, the wrapper procedure `f` returns the old value 1/2:

`f(0)`
` `

The result of the procedure call `f(0)` does not change because the system does not reevaluate this result. It finds the result in the remember table of the procedure `f` and returns that result. To display the content of the remember table, call the wrapper procedure `f` with the `Remember` option as a first argument and the `Print` option as a second argument. The value 106 in the second column is the value of `MAXEFFORT` used during computations.

`f(Remember, Print)`
` `

To force reevaluation of the procedure calls of `f`, clear the remember table of that procedure. To clear the remember table, call `f` with the `Remember` option as a first argument and the `Clear` option as a second argument:

`f(Remember, Clear):`

Now `f` returns the correct result:

`f(0)`
` `

If you use the option `remember`, you also can clear the remember table and force reevaluation. For example, rewrite the procedure `f` as follows:

```f := proc(x) option remember; begin heaviside(x) end: f(0)```
` `

Now restore the `heaviside` function to its default definition:

`heaviside(0):= 1/2:`

To clear a remember table created by the option `remember`, use the `forget` function:

```forget(f): f(0)```
` `

Use the `protect` function with the `ProtectLevelError` option to prevent further changes to `heaviside`. Also, delete the procedure `f`:

```protect(heaviside, ProtectLevelError): delete f```

### Potential Problems Related to the Remember Mechanism

The remember mechanism is a powerful tool for improving performance of MuPAD procedures. Nevertheless, you can encounter some problems when using this mechanism:

• Remember tables are efficient only if the access time of the remember table is significantly less than the time needed to evaluate the result. If a remember table is very large, evaluation can be computationally cheaper than accessing the result stored in the remember table.

• Storing large remember tables requires a large amount of memory. Especially, remember tables created with the option `remember` can grow very large, and significantly reduce available memory. The number of entries in remember tables created by `prog::remember` is limited. When the number of entries in a remember table created by `prog::remember` reaches the maximum number, the system removes a group of older entries.

• Using `prog::remember` or the option `remember` for nonrecurring procedure calls can significantly decrease code performance. Avoid using the remember mechanism for nonrecurring procedure calls, especially if the arguments are numerical.

• If you change the properties of input arguments or modify the variables `DIGITS` or `ORDER`, the remember mechanism ignores these changes by default. See Remembering Results Without Context.

• In some cases you must clear the remember table of a procedure to enforce reevaluation and avoid incorrect results. For example, clearing the remember table can be necessary when a procedure changes global variables or if global variables affect the results of a procedure. See Clearing Remember Tables.

• Many predefined MuPAD functions have special values stored in their remember tables. Therefore, clearing the remember tables of predefined MuPAD functions is not recommended. Note that the `forget` function does not error when you call it for a predefined MuPAD function.

#### Mathematical Modeling with Symbolic Math Toolbox

Get examples and videos