# Documentation

### This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the English verison of the page.

To view all translated materals including this page, select Japan from the country navigator on the bottom of this page.

# level

Evaluate an object with a specified substitution depth

MuPAD® notebooks are not recommended. 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.

## Syntax

```level(`object`)
level(`object`, `n`)
```

## Description

`level(object, n)` evaluates `object` with substitution depth `n`.

When a MuPAD® object is evaluated, identifiers occurring in it are replaced by their values. This happens recursively, i.e., if the values themselves contain identifiers, then these are replaced as well. `level` serves to evaluate an object with a specified recursion depth for this substitution process.

With `level(object, 0)`, `object` is evaluated without replacing any identifier occurring in it by its value. In most cases, but not always, this equivalent to `hold(object)`, and `object` is returned unevaluated. See Example 3.

With `level(object, 1)`, all identifiers occurring in `object` are replaced by their values, but not recursively, and then all function calls in the result of the substitution are executed. This is how objects are evaluated within a procedure by default.

The call `level(object)` is equivalent to ```level(object, MAXLEVEL)```, i.e., identifiers occurring in `object` are recursively replaced by their values up to substitution depth ```MAXLEVEL - 1```, and an error occurs if the substitution depth `MAXLEVEL` is reached. Usually, this leads to a complete evaluation of `object`. See Example 1.

You can use `level` without a second argument to request the complete evaluation of an object not containing local variables or formal parameters within a procedure. This may be necessary since by default, objects are evaluated with substitution depth `1` within procedures. See Example 2.

Otherwise, it should never be necessary to use `level`.

### Note

`level` does not affect the evaluation of local variables and formal parameters, of type `DOM_VAR`, in procedures. When such a local variable occurs in `object`, then it is always replaced by its value, independent of the value of `n`, and the value is not further recursively evaluated. See Example 2.

`level` works by temporarily setting the value of `LEVEL` to `n`, or to 231 - 1 if `n` is not given. However, the value of `MAXLEVEL` remains unchanged. If the substitution depth `MAXLEVEL` is reached, then an error message is returned. See `LEVEL` and `MAXLEVEL` for more information on these environment variables.

In contrast to most other functions, `level` does not flatten its first argument if it is an expression sequence. See Example 5.

`level` does not recursively descend into `arrays`, `tables`, `matrices` or `polynomials`. Use the call `map(object, eval)` to evaluate the entries of an array, a table, a matrix or ```mapcoeffs(object, eval)``` to evaluate the coefficients of a polynomial. See Example 4 and Example 6.

Further information concerning the evaluation of arrays, tables, matrices or polynomials can be found on the `eval` help page.

The maximal substitution depth of `level` depends on the environment variable `MAXLEVEL`, while the maximum evaluation depth of the function `eval` depends on the environment variable `LEVEL`. See Example 7.

Because `eval` evaluates the result again there is a difference between evaluating an expression with depth n by `level` in comparison with `eval`. See Example 7.

As mentioned `level` does not affect the evaluation of local variables and formal parameters, of type `DOM_VAR`, in procedures. Here `eval` behaves different. See Example 7 and the `eval` help page for more information.

The result of `level(hold(x))` is always `x`, because a full evaluation of `hold(x)` leads to `x`. The same does not hold for `eval(hold(x))`, because `eval` first evaluates its argument and then evaluates the result again.

The evaluation of elements of a user-defined domain depends on the implementation of the domain. Usually domain elements remain unevaluated by `level`. If the domain has a slot `"evaluate"`, the corresponding slot routine is called with the domain element as argument at each evaluation, and hence it is called once when `level` is invoked. Cf. Example 8.

## Examples

### Example 1

We demonstrate the effect of `level` for various values of the second parameter:

```delete a0, a1, a2, a3, a4, b: b := b + 1: a0 := a1: a1 := a2 + 2: a2 := a3 + a4: a3 := a4^2: a4 := 5:```
```hold(a0), hold(a0 + a2), hold(b); level(a0, 0), level(a0 + a2, 0), level(b, 0); level(a0, 1), level(a0 + a2, 1), level(b, 1); level(a0, 2), level(a0 + a2, 2), level(b, 2); level(a0, 3), level(a0 + a2, 3), level(b, 3); level(a0, 4), level(a0 + a2, 4), level(b, 4); level(a0, 5), level(a0 + a2, 5), level(b, 5); level(a0, 6), level(a0 + a2, 6), level(b, 6);```

Evaluating `object` by just typing `object` at the command prompt is equivalent to `level(object, LEVEL)`:

```LEVEL := 2: MAXLEVEL := 4: a0, a2, b; level(a0, LEVEL), level(a2, LEVEL), level(b, LEVEL)```

If the second argument is omitted, then this corresponds to a complete evaluation up to substitution depth ```MAXLEVEL - 1```:

`level(a0)`
```Error: Recursive definition: Reached maximal evaluation level. ```
`level(a2)`

`level(b)`
```Error: Recursive definition: Reached maximal evaluation level. ```
`delete LEVEL, MAXLEVEL:`

### Example 2

We demonstrate the behavior of `level` in procedures:

```delete a, b, c: a := b: b := c: c := 42: p := proc() local x; begin x := a: print(level(x, 0), x, level(x, 2), level(x)): print(level(a, 0), a, level(a, 2), level(a)): end_proc: p()```

Since `a` is evaluated with the default substitution depth `1`, the assignment `x:=a` sets the value of the local variable `x` to the unevaluated identifier `b`. You can see that any evaluation of `x`, whether `level` is used or not, simply replaces `x` by its value `b`, but no further recursive evaluation happens. In contrast, evaluation of the identifier `a` takes place with the default substitution depth `1`, and ```level(a, 2)``` evaluates it with substitution depth `2`.

Thus `level` without a second argument can be used to request the complete evaluation of an object not containing any local variables or formal parameters.

### Example 3

There are some rare cases where `level(object, 0)` and `hold(object)` behaves different. This is the case if `object` is not an identifier, e.g., a nameless function, because `level` influences only the evaluation of identifiers:

`level((x -> x^2)(2),0), hold((x -> x^2)(2))`

For the same reason `level(object, 0)` and `hold(object)` behave differently if `object` is a local variable of a procedure:

```f:=proc() local x; begin x := 42; hold(x), level(x, 0); end_proc: f(); delete f:```

### Example 4

In contrast to lists and sets, evaluation of an array does not evaluate its entries. Thus `level` has no effect for arrays either. The same holds for tables and matrices. Use `map` to evaluate all entries of an array. On the `eval` help page further examples can be found:

```delete a, b: L := [a, b]: A := array(1..2, L): a := 1: b := 2: L, A, level(A), map(A, level), map(A, eval)```

### Example 5

The first argument of `level` may be an expression sequence, which is not flattened. However, it must be enclosed in parentheses:

```delete a, b: a := b: b := 3: level((a, b), 1); level(a, b, 1)```

```Error: Invalid number of arguments. [level] ```

### Example 6

`Polynomials` are inert when evaluated, and so `level` has no effect:

```delete a, x: p := poly(a*x, [x]): a := 2: x := 3: p, level(p)```

Use `mapcoeffs` and the function `eval` to evaluate all coefficients:

`mapcoeffs(p, eval)`

If you want to substitute a value for the indeterminate `x`, use `evalp`:

`delete x: evalp(p, x = 3)`

As you can see, the result of an `evalp` call may contain unevaluated identifiers, and you can evaluate them by an application of `eval`. It is necessary to use `eval` instead of `level` because `level` does not evaluate its result:

`eval(evalp(p, x = 3))`

### Example 7

The subtle difference between `level` and `eval` is shown. The evaluation depth of `eval` is limited by the environment variable `LEVEL`. `level` pays no attention to `LEVEL`, but rather continues evaluating its argument either as many times as the second argument implies or until it has been evaluated completely:

```delete a0, a1, a2, a3: a0 := a1 + a2: a1 := a2 + a3: a2 := a3^2 - 1: a3 := 5: LEVEL := 1: eval(a0), level(a0);```

If the evaluation depth exceeds the value of `MAXLEVEL`, an error is raised in both cases:

```delete LEVEL: MAXLEVEL := 3: level(a0);```
```Error: Recursive definition: Reached maximal evaluation level. ```
```delete LEVEL: MAXLEVEL := 3: eval(a0); delete MAXLEVEL:```
```Error: Recursive definition: Reached maximal evaluation level. ```

It is not the same evaluating an expression `ex` with `eval` and an evaluation depth n and by `level((ex, n))`, because `eval` evaluates its result:

```LEVEL := 2: eval(a0), level(a0, 2); delete LEVEL:```

`level` does not affect the evaluation of local variables of type `DOM_VAR` while `eval` evaluates them with evaluation depth `LEVEL`, which is one in a procedure:

```p := proc() local x; begin x := a0: print(eval(x), level(x)): end_proc: p()```

### Example 8

The evaluation of an element of a user-defined domain depends on the implementation of the domain. Usually it is not further evaluated:

```delete a: T := newDomain("T"): e := new(T, a): a := 1: e, level(e), map(e, level), val(e)```

If the slot `"evaluate"` exists, the corresponding slot routine is called for a domain element each time it is evaluated. We implement the routine `T::evaluate`, which simply evaluates all internal operands of its argument, for our domain `T`. The unevaluated domain element can still be accessed via `val`:

```T::evaluate := x -> new(T, eval(extop(x))): e, level(e), map(e, level), val(e);```

`delete e, T:`

## Parameters

 `object` Any MuPAD object `n` A nonnegative integer less than 231

## Return Values

Evaluated object.