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

## Integrate Custom Functions into MuPAD

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

MuPAD® provides a variety of tools for handling built-in mathematical functions such as `sin`, `cos`, `exp`, and so on. These tools implement the mathematical properties of these functions. Typical examples are the `float` conversion routine, the `diff` differentiation function, or the `expand` function, which you use to manipulate expressions:

```float(sin(1)); diff(sin(x), x, x, x); expand(sin(x + 1))```

You can say that the mathematical knowledge about the built-in functions is distributed over several system functions: `float` knows how to compute numerical approximations of the sine function, `diff` knows the derivative of the sine function, and `expand` knows the addition theorems of the trigonometric functions.

When you implement your own function, you can integrate it into the MuPAD system, making other functions aware how to work with this new function correctly. If the new function consists only of built-in MuPAD functions, then you do not need to take extra steps. All MuPAD functions interact correctly with the new function:

```f := x -> (x*sin(x)): diff(f(x), x)```

However, if you implement a function that is not composed of the standard MuPAD objects (for example, a new special function), you must distribute the knowledge about the mathematical meaning of the new function to standard MuPAD functions, such as `diff`, `expand`, `float`, and so on. This extra task is necessary for integrating the new function with the rest of the system. For example, you might want to differentiate an expression that contains both the new function and some built-in functions, and such differentiation is only possible via the MuPAD differentiation routine. Therefore, this routine must know how to handle the new symbol.

MuPAD uses function environments (domain type `DOM_FUNC_ENV`) to integrate functions into the system. A function environment stores special function attributes (`slots`) in an internal table. Whenever an overloadable system function, such as `diff`, `expand`, or `float`, encounters an object of type `DOM_FUNC_ENV`, it searches the function environment for a corresponding slot. If a system function finds the appropriate slot, it calls that slot and returns the value produced by the slot. All built-in MuPAD functions are implemented as function environments:

`domtype(sin), domtype(exp)`

You can call a function environment as you would call any MuPAD function or procedure:

`sin(1.7), exp(1.0)`

Suppose you implement the complete elliptic integral functions of the first and second kind, `K(z)` and `E(z)`. These functions appear in different contexts, such as calculating the perimeter of an ellipsis, the gravitational or electrostatic potential of a uniform ring, and the probability that a random walk in three dimensions ever goes through the origin. The elliptic integrals have the following special values:

, E(1) = 1, , .

MuPAD provides the built-in functions `ellipticE` and `ellipticK` for computing these elliptic integrals. However, you can implement your own functions for the same task. For example, write the procedures `ellipE` and `ellipK`. These procedures define the values of the elliptic integrals for special values of `x`. For all other argument values, the values of elliptic integrals are unknown, and the procedures return the symbolic expressions `ellipE(x)` and `ellipK(x)`. Use `procname` to return symbolic expressions:

```ellipE := proc(x) begin if x = 0 then PI/2 elif x = 1 then 1 else procname(x) end_if end_proc:```
```ellipK := proc(x) begin if x = 0 then PI/2 elif x = 1/2 then 8*PI^(3/2)/gamma(-1/4)^2 elif x = -1 then gamma(1/4)^2/4/sqrt(2*PI) else procname(x) end_if end_proc:```

`ellipE` and `ellipK` return special values for particular arguments. For all other arguments, they return symbolic expressions:

```ellipE(0), ellipE(1/2), ellipK(12/17), ellipK(x^2 + 1)```

The first derivatives of these elliptic integrals are as follows:

, .

The standard MuPAD differentiation function `diff` does not know about these rules. Therefore, trying to differentiate `ellipE` and `ellipK` simply returns the symbolic notations of the derivatives:

```diff(ellipE(x), x), diff(ellipK(x), x)```

To make `diff` work with the new functions, create function environments from the procedures `ellipE` and `ellipK`. In addition, function environments let you control the appearance of the symbolic function calls in outputs.

A function environment consists of three operands.

• The first operand is a procedure that computes the return value of a function call.

• The second operand is a procedure for printing a symbolic function call on the screen.

• The third operand is a table that specifies how the system functions handle symbolic function calls.

To create function environments, use `funcenv`. For example, create function environments `ellipE` and `ellipK`. Use the second argument to specify that symbolic calls to `ellipE` and `ellipK` must appear as `E` and `K` outputs:

```output_E := f -> hold(E)(op(f)): ellipE := funcenv(ellipE, output_E):```
```output_K := f -> hold(K)(op(f)): ellipK := funcenv(ellipK, output_K):```

Although `ellipE` and `ellipK` are now function environments, you can call them as you would call any other MuPAD function:

```ellipE(0), ellipE(1/2), ellipK(12/17), ellipK(x^2+1)```

The third argument `funcenv` is a table of function attributes. It tells the system functions (such as `float`, `diff`, `expand`, and so on) how to handle symbolic calls of the form `ellipE(x)` and `ellipK(x)`. You can update this table specifying the rules for the new function. For example, specify the new differentiation rules by assigning the appropriate procedures to the `diff` slot of the function environments:

```ellipE::diff := proc(f,x) local z; begin z := op(f); (ellipE(z) - ellipK(z))/(2*z) * diff(z, x) end_proc:```
```ellipK::diff := proc(f,x) local z; begin z := op(f); (ellipE(z) - (1-z)*ellipK(z))/ (2*(1-z)*z) * diff(z, x) end_proc:```

Now, whenever `f = ellipE(z)`, and `z` depends on `x`, the call `diff(f, x)` uses the procedure assigned to `ellipE::diff`:

```diff(ellipE(z), z); diff(ellipE(y(x)), x); diff(ellipE(x*sin(x)), x)```

The new differentiation routine also finds higher-order derivatives:

`diff(ellipE(x), x, x)`

Since the `taylor` function internally calls `diff`, the new differentiation routine also lets you compute Taylor expansions of the elliptic integrals:

`taylor(ellipK(x), x = 0, 6)`

If a derivative of a function contains the function itself, the integration routine has a good chance of finding symbolic integrals after you implement the `diff` attributes. For example, `int` now computes the following integrals:

`int(ellipE(x), x)`

`int(ellipK(x), x)`