## `D` -- differential operator for functions

#### Introduction

`D``(f)` or, alternatively, `f'` computes the derivative of the univariate function `f`.

`D``([n1, n2, ...], f)` computes the partial derivative d/dx[n1] d/dx[n2] ... f of the multivariate function f(x[1],x[2],...).

#### Call(s)

`f'` `D(f)`
`D([n1, n2, ...], f)`

#### Parameters

`f` | - | a function or a functional expression, an array, a list, a polynomial, a set, or a table
`n1, n2, ...` | - | indices: positive integers

#### Returns

a function or a functional expression, or otherwise an object of the same type as `f`.

### Overloadable:

`f`

#### Further Documentation

Section 7.1 of the MuPAD Tutorial.

#### Related Functions

`diff`, `int`, `poly`

#### Details

- `D(`f`)` returns the derivative f' of the univariate function `f`. `f'` is shorthand for `D(`f`)`.

- If `f` is a multivariate function and D[n] f denotes the partial derivative of `f` with respect to its nth argument, then `D(`[n1,n2,...],f`)` computes the partial derivative D[n1] D[n2] ... f. See example 5. In particular, `D(`[], f`)` returns `f` itself.

- `f` may be any object which can represent a function. In particular, `f` may be a complex expression built from simple functions by means of arithmetic operators, i.e., a functional expression. Any identifier different from `CATALAN`, `EULER`, and `PI` is regarded as an ``unknown'' function; the same holds for elements of kernel domains not explicitly mentioned on this page. See example 1. Any number and each of the three constant identifiers above is regarded as a constant function; see example 2.

- If `f` is a list, a set, a table, or an array, then `D` is applied to every entry of `f` (see example 3).

- If `f` is a polynomial, then it is regarded as polynomial function, the indeterminates being the arguments of the function. See example 6.

- If `f` is a function environment, a procedure, or a built-in kernel function, then `D` can compute the derivative in some cases, see ``Background'' below. If this is not possible, then a symbolic `D` call is returned.

- Nested partial derivatives (i.e., partial derivatives of partial derivatives) are simplified by flattening them. See example 7.
- The derivative of a function f--denoted by `D(f)`--and the partial derivative of f with respect to its only argument--denoted by `D([1], f)` are sharply distinguished.
- The usual rules of differentiation are implemented:
  - `D(f + g) = D(f) + D(g)`
  - `D(f * g) = f * D(g) + g * D(f)`
  - `D(1/f) = -D(f) / f^2`
  - `D(f @ g) = D(g) * D(f) @ g`
  Note that the composition of functions is written as `f@g` and not as `f(g)`.
- MuPAD has two differentiation functions: `diff` and `D`. `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 8.
- In order to express the n-th derivative of a function for symbolic n, you can use the repeated composition operator. See example 9.

#### Example 1

`D(`f`)` computes the derivative of the function `f`:

    >> D(sin), D(x -> x^2), D(id)

                                   cos, 2 id, 1

Note that `id` denotes the identity function. `D` also works for more complex functional expressions:

    >> D(sin @ exp + 2*(x -> x*ln(x)) + id^2)

                           2 id + 2 ln + exp cos@exp + 2

If `f` is an identifier without a value, then a symbolic `D` call is returned:

    >> delete f: D(f + sin)

                                    D(f) + cos

The same holds for objects of kernel type that cannot be understood as functions:

    >> D(NIL), D(point(3,2))

                              D(NIL), D(point(3, 2))

`f'` is shorthand for `D(`f`)`:

    >> (f + sin)', (x -> x^2)', id'

                                D(f) + cos, 2 id, 1

#### Example 2

Constants are regarded as constant functions:

    >> PI', 3', (1/2)'

                                      0, 0, 0

#### Example 3

The usual rules of differentiation are implemented. Note that lists and sets may also be taken as input; in this case, `D` is applied to each element of the list or set:

    >> delete f, g: D([f+g, f*g]); D({f@g, 1/f})

                          [D(f) + D(g), f D(g) + g D(f)]

                              {                D(f) }
                              { D(g) D(f)@g, - ---- }
                              {                  2  }
                              {                 f   }

#### Example 4

The derivatives of most special functions of the library can be computed. Again, `id` denotes the identity function:

    >> D(tan); D(sin*cos); D(1/sin); D(sin@cos); D(2*sin + ln)

                                        2
                                     tan  + 1

                                               2
                                  cos cos - sin

                                        cos
                                      - ----
                                           2
                                        sin

                                   -sin cos@cos

                                    1
                                    -- + 2 cos
                                    id

#### Example 5

`D` can also compute derivatives of procedures:

    >> f := x -> x^2:
       g := proc(x) begin tan(ln(x)) end:
       D(f), D(g)

                                             2
                                       tan@ln  + 1
                                 2 id, -----------
                                           id

We differentiate a function of two arguments by passing a list of indices as first argument to `D`. In the example below, we first differentiate with respect to the second argument and then differentiate the result with respect to the first argument:

    >> D([1, 2], (x, y) -> sin(x*y))

                         (x, y) -> cos(x*y) - x*y*sin(x*y)

In fact, the order of the partial derivatives is not relevant in the example above:

    >> D([2, 1], (x, y) -> sin(x*y))

                         (x, y) -> cos(x*y) - x*y*sin(x*y)

#### Example 6

A polynomial is regarded as a polynomial function:

    >> D(poly(x^2 + 3*x + 2, [x]))

                                poly(2 x + 3, [x])

We differentiate the following bivariate polynomial `f` twice with respect to its second variable `y` and once with respect to its first variable `x`:

    >> f := poly(x^3*y^3, [x, y]):
       D([1, 2, 2], f) = diff(f, y, y, x)

                            2                       2
                   poly(18 x  y, [x, y]) = poly(18 x  y, [x, y])

    >> delete f:

#### Example 7

Nested calls to `D` are flattened:

    >> D([1], D([2], f))

                                   D([1, 2], f)

However, this does not hold for calls with only one argument, since `D(f)` and `D([1], f)` are not considered to be the same:

    >> D(D(f))

                                      D(D(f))

#### Example 8

`D` may only be applied to functions whereas `diff` makes only sense for 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 9

Sometimes you may need the n-th derivative of a function, where n is unknown. This can be achieved using the repeated composition operator. For example, let us write a function that computes the k-th Taylor polynomial of a function f at a point x0 and uses x as variable for that polynomial:

    >> nthtaylorpoly:=
       (f, k, x, x0) -> _plus(((D@@n)(f)(x0) * (x-x0)^n / n!) $n=0..k):
       nthtaylorpoly(sin, 7, x, 0)

                                     3    5      7
                                    x    x      x
                                x - -- + --- - ----
                                    6    120   5040

#### Example 10

Advanced users can extend `D` to their own special mathematical functions (see section ``Backgrounds'' below). To this end, embed your mathematical function into a function environment `f` and implement the behavior of `D` for this function as the `"D"` slot of the function environment. The slot must handle two cases: it may be either called with only one argument which equals `f`, or with two arguments where the second one equals `f`. In the latter case, the first argument is a list of arbitrary many indices; that is, the slot must be able to handle higher partial derivatives also.

Suppose, for example, that we are given a function f(t, x, y), and that we do not know anything about f except that it is differentiable infinitely often and satisfies the partial differential equation d^2 f/dx^2 + d^2 f/d y^2 = d f / d t. To make MuPAD eliminate derivatives with respect to `t`, we can do the following:

    >> f:= funcenv((t, x, y) -> procname(args())):
       f::D :=
       proc(indexlist, ff)
         local
           n        : DOM_INT,   // number of d/dt to replace
           list_2_3 : DOM_LIST;  // list of indices of 2's and 3's
                                 // these remain unchanged
       begin
         if args(0)<>2 then
           error("Wrong number of arguments")
         end_if;
         n        :=  nops(select(indexlist, _equal, 1));
         list_2_3 :=       select(indexlist, _unequal, 1);
         _plus(binomial(n, k) *
               hold(D)([2 $ 2*(n-k), 3 $ 2*k].list_2_3, hold(f))
         $k=0..n)
       end_proc:
       D([1, 2, 1], f)

          D([2, 2, 2, 2, 2], f) + 2 D([2, 2, 3, 3, 2], f) +

             D([3, 3, 3, 3, 2], f)

#### Background

- If `f` is a domain or a function environment with a `slot` `"D"`, then this slot is called to compute the derivative. The slot procedure has the same calling syntax as `D`. In particular--and in contrast to the `slot``"diff"`--the slot must be able to compute higher partial derivatives because the list of indices may have length greater than one. See example 10.

  The first operand of a function environment is used to compute the derivative if the slot `"D"` does not exist.

- If `f` is a procedure or a built-in kernel function (an ``executable object''), then `f` is called with auxiliary identifers as arguments. The result of the call is then differentiated using the function `diff`. If the result of `diff` yields an expression which can be regarded as function in the auxiliary identifers, then this function is returned, otherwise an unevaluated call of `D` is returned.

- Let us take the function environment `sin` as an example. It has no `"D"` slot, thus the procedure `op(sin, 1)`, which is responsible for evaluating the sine function, is used to compute `D(sin)`, as follows. This procedure is applied to an auxiliary identifier, say `x`, and differentiated with respect to this identifier via `diff`. The result is `diff(sin(x), x) = cos(x)`. Thus `cos` is returned as the derivative of `sin`.

#### Changes

- no changes

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