## `diff` -- differentiate an expression or a polynomial

#### Introduction

`diff(`f, x`)` computes the (partial) derivative df/dx of the function `f` with respect to the variable `x`.

#### Call(s)

`diff(f)`
`diff(f, x)`
`diff(f, x1, x2, ...)`

#### Parameters

`f` | - | an arithmetical expression or a polynomial of type `DOM_POLY`
`x, x1, x2, ...` | - | indeterminates: identifiers or indexed identifiers

#### Returns

an arithmetical expression or a polynomial.

### Overloadable:

`f`

#### Further Documentation

Section 7.1 of the MuPAD Tutorial.

#### Related Functions

`D`, `int`, `limit`, `poly`, `taylor`

#### Details

- `diff(`f, x`)` computes the derivative of the arithmetical expression (or polynomial) `f` with respect to the indeterminate `x`.
- `diff(`f, x1, x2, ...`)` is equivalent to `diff(...diff(diff(f, x1), x2)...)`, i.e., the system first differentiates `f` with respect to `x1`, then differentiates the result with respect to `x2`, and so on, i.e., it computes the partial derivative ... d/dx2 d/dx1 f. See example 3. In fact, the system internally converts nested `diff` calls into a single `diff` call with multiple arguments. See example 7.
- `diff(`f`)` returns its evaluated argument, i.e., it computes the ``zeroth'' derivative of `f`.
- Higher derivatives can be computed by using the sequence operator: If `n` is a nonnegative integer, then `diff(`f, x $ n`)` returns the nth derivative of `f` with respect to `x`. See example 4.
- The indeterminates `x, x1, x2, ...` must be either identifiers (of domain type `DOM_IDENT`) or indexed identifiers, i.e., of the form `x[n]`, where `x` is an identifier and `n` is an integer. If one of them is of a different form, then a symbolic `diff` call is returned. See example 2.
- If `f` is an arithmetical expression, then `diff` returns an arithmetical expression. If `f` is a polynomial, then `diff` returns a polynomial as well; see example 5. An exception to these rules occurs when the system is unable to compute the derivative, in which case it returns a symbolic `diff` call. See example 6.
- MuPAD does not assume that derivatives with respect to different indeterminates commute, i.e., in general `diff(`f, x1, x2`)` and `diff(`f, x2, x1`)` represent different objects. See example 8.
- Users can extend the functionality of `diff` for their own special mathematical functions via overloading. This works by turning the corresponding function into a function environment and implementing the derivation rule for the function as the `"`diff" `slot` of the function environment. See example 10.
- MuPAD has two differentiation functions: `D` and `diff`. `D` may only be applied to functions whereas `diff` is used to differentiate expressions. `D`-expressions can be rewritten into `diff`-expressions with `rewrite`. See example 9.
- `diff` is a function of the system kernel.

#### Example 1

We compute the derivative of x^2 with respect to `x`:

    >> diff(x^2, x)

                                        2 x

#### Example 2

You can differentiate with respect to an indexed identifier if the index is an integer:

    >> diff(x[1]*y + x[1]*x[r], x[1])

                                     y + x[r]

If the index is not an integer, then a symbolic `diff` call is returned:

    >> diff(x[1]*y + x[1]*x[r], x[r])

                          diff(y x[1] + x[r] x[1], x[r])

#### Example 3

You can differentiate with respect to more than one variable with a single `diff` call. In the following example, we differentiate first with respect to `x` and then with respect to `y`:

    >> diff(x^2*sin(y), x, y) = diff(diff(x^2*sin(y), x), y)

                              2 x cos(y) = 2 x cos(y)

#### Example 4

We use the sequence operator `$` to compute the third derivative of the following expression with respect to `x`:

    >> diff(sin(x)*cos(x), x $ 3)

                                       2           2
                               4 sin(x)  - 4 cos(x)

#### Example 5

`Polynomials` may be differentiated with respect to both the polynomial indeterminates (in the example below: `x`) or the parameters in the coefficients (in the example below: `a`):

    >> diff(poly(sin(a)*x^3 + 2*x, [x]), x)

                                            2
                           poly((3 sin(a)) x  + 2, [x])

    >> diff(poly(sin(a)*x^3 + 2*x, [x]), a)

                                            3
                               poly(cos(a) x , [x])

#### Example 6

The system returns the derivative of an unknown function as a symbolic `diff` call:

    >> diff(f(x) + x, x)

                                 diff(f(x), x) + 1

#### Example 7

The system internally converts nested `diff` calls into a single `diff` call with multiple arguments:

    >> diff(diff(f(x, y), x), y)

                                diff(f(x, y), x, y)

#### Example 8

The differentiation in several indeterminates does not commute:

    >> diff(f(x, y), x, y) = diff(f(x, y), y, x);
       bool(%)

                     diff(f(x, y), x, y) = diff(f(x, y), y, x)

                                       FALSE

#### Example 9

`D` may only be applied to functions whereas `diff` is applied to expressions:

    >> D(sin), diff(sin(x), x)

                                    cos, cos(x)

Applying `D` to expressions and `diff` to functions makes no sense:

    >> D(sin(x)), diff(sin, x)

                                   D(sin(x)), 0

`rewrite` allows to rewrite expressions with `D` into `diff`-expression:

    >> rewrite(D(f)(y), diff), rewrite(D(D(f))(y), diff)

                          diff(f(y), y), diff(f(y), y, y)

#### Example 10

Advanced users can extend `diff` to their own special mathematical functions (see section ``Backgrounds'' below). To this end, embed your mathematical function into a function environment `g` and implement the behavior of `diff` for this function as the `"diff"` slot of the function environment.

If a subexpression of the form `g(u, ..)` occurs in `f`, then `diff` issues the call `g::diff(g(u, ..), x)` to the slot routine to determine the derivative of `g(u, ..)` with respect to `x`.

For illustration, we show how this works for the exponential function. Of course, the function environment `exp` already has a `"diff"` slot. We call our function environment `Exp` in order not to overwrite the existing system function `exp`.

This example `"`diff"-slot implements the chain rule for the exponential function. The derivative is the original function call times the derivative of the argument:

    >> Exp := funcenv(Exp):
       Exp::diff := (f, x) -> f*diff(op(f, 1), x):
       delete x: diff(Exp(x^2), x)

                                             2
                                    2 x Exp(x )

`prog::trace` shows that the function is called with only two arguments. `Exp::diff` is called only once since the result of the second call is read from an internal cache for intermediate results in `diff`:

    >> prog::trace(Exp::diff):
       diff(Exp(x^2), x, x)

          enter 'Exp::diff'                      with args   : Exp(x^2), x
          leave 'Exp::diff'                      with result : 2*x*Exp(x^2)

                                    2       2      2
                             2 Exp(x ) + 4 x  Exp(x )

    >> prog::untrace(Exp::diff):  delete f, Exp:

#### Background

- If a subexpression of the form `g(u, ..)` occurs in `f` and `g` is a function environment, then `diff` attempts to call the slot `"diff"` of `g` to determine the derivative of `g(u, ..)` with respect to `x`. In this way, you can extend the functionality of `diff` to your own special mathematical functions.

  The slot `"diff"` is called with the arguments `g(u, ..), x`.

  If `g` does not have a slot `"diff"`, then `diff` returns the expression `diff(g(u, ..), x)` for the corresponding subexpression.

  The `"`diff"-slot is always called with exactly two arguments. If the `diff`-call has given more indeterminates, then several calls of the `"`diff"-slot are done. The results of the calls of `"`diff"-slots are cached in `diff` in order to prevent redundant function calls. See example 10.

- Similarly, if an element `d` of a library domain `T` occurs as a subexpression of `f`, then `diff` attempts to call the slot `"diff"` of that domain with `d` and the the indeterminate `x` as arguments to compute the derivative of `d` with respect to `x`.

  If the domain `T` does not have a slot `"diff"`, then `diff` considers this object as constant and returns 0 for the corresponding subexpression.

#### Changes

- `diff` no longer accepts a procedure as first argument.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000