In this short post, I express the Scmutils notation for partial derivatives of scalar functions with multiple parameters using JavaScript. As usual, you find the JavaScript program by following the Source Academy link, but this time, you need to change the language from Source §4 to “full JavaScript”.

The Single-parameter Case

An example of a scalar function with one parameter is the square function.

const square = x => x * x;

A naive numerical differentiation function follows the definition of derivatives, using Lagrange’s notation: f'(x) = (f(x + d) - f(x)) / d, where d approaches 0. Translating this definition to JavaScript yields differentiation function.

const differentiate = f => x => (f(x + delta) - f(x)) / delta;

I call it “naive” because rounding errors creep in very quickly, if delta is chosen to be very small. For precise methods of numerical differentiation, see an earlier post. To explore the notation for differentiation, I ignore these issues and stick to the naive version with a relatively large delta.

const delta = 1e-4;

Using this differentiate function, you can differentiate square as follows.

differentiate(square);    // returns a function square'
                          // approximately square'(x) = 2 * x

Applying the function that results from differentiating square to 1 gives approximately 2.

differentiate(square)(1);

The square function above only has one argument, so when you write square', it is clear what argument you are differentiating for.

Multiple Parameters

The problem with Lagrange’s notation is that it doesn’t spell out which parameter(s) you are differentiating for when there are multiple parameters.

For functions with multiple parameters, you would like to compute a partial derivative by changing one value and leave the other values unchanged.

For example, you would like to compute the partial derivative of f(x, y) = x² + x y + y² separately with respect to x, and with respect to y.

Euler’s notation uses the parameter name for this, regardless of its position in the list of arguments: (Dx f)(x, y) = (f(x + d, y) - f(x, y)) / d where d approaches 0

and (Dy f)(x, y) = (f(x, y + d) - f(x, y)) / d where d approaches 0

In the use cases of Scmutils, functions are often generated by other functions, and then the parameter names may not be obvious.

Scmutils Notation for Partial Derivatives

Scmutils solves the issue by defining a function partial that takes a subset of the parameter indices (rather than names) of the function to be differentiated, and returns a function transformer: A function that differentiates its argument function with repect to the parameters indicated by the indices.

Let’s start with the naive partial derivative with respect to a single parameter index:

const partial_single = 
    i => f => (...x) => (f(...add_to_index(x, i, delta))
                         - f(...x)) 
                        / delta;

where the helper function add_to_index adds a value delta to the ith component of the vector values.

const add_to_index = 
    (values, i, delta) => values.map((x, j) => i === j ? x + delta : x);

You can apply partial_single to 0 and f and get the partial derivative of f with respect to the first parameter x

partial_single(0)(f);         // returns Dx f
partial_single(0)(f)(1, 2);   // returns Dx f(1, 2), approximately 4

or with respect to parameter y

partial_single(1)(f);         // returns Dy f
partial_single(1)(f)(1, 2);   // returns Dy f(1, 2), approximately 5

You can use partial_single to differentiate the square function.

partial_single(0)(square);    // returns approximately Dx square: square'(x) = 2 * x
partial_single(0)(square)(1); // returns approximately square'(1) = 2

The partial function in Scmutils takes multiple parameter indices as arguments and returns a function transformer: A function that differentiates a given scalar function with repect to each of the indices. The corresponding JavaScript function partial is defined as follows, using a given partial_single function.

const partial = 
    (...ids) => ids.length === 0
                ? f => f // base case: no index given: keep f as it is
                // ids.slice(1) removes the first index from ids
                : f => partial_single(ids[0])(partial(...ids.slice(1))(f));

To illustrate partial, let’s define g(x, y, z) = x² + 2 y² + 3 z² + x y z.

const g = (x, y, z) => square(x) + 2 * square(y) + 3 * square(z) + x * y * z;

Now, you can play with partial and g:

partial(2)(g)(1, 2, 3);   // returns Dz g(1, 2, 3), approximately 20
partial(0,1)(g)(1, 2, 3);   // returns Dx Dy g(1, 2, 3), approximately 3
partial(0,2)(g)(1, 2, 3);   // returns Dx Dz g(1, 2, 3), approximately 2
partial(0,1,2)(g)(1, 2, 3);   // returns Dx Dy Dz g(1, 2, 3), approximately 1

The Nabla Function

The Nabla function (usually denoted by the symbol ∇) is a function transformer that takes a multi-parameter scalar function f as argument and returns a multi-parameter function that returns the gradient vector of f at the given position. In JavaScript, the Nabla function can be defined using partial_single as follows:

const Nabla = f => {
    // indices is vector [0, 1,...,n] where n is arity of f
    const indices = Array(f.length).fill().map( (ignore, i) => i);
    // partials is vector [Dx f, Dy f,...] if f has parameters x, y, ...
    const partials = indices.map(i => partial_single(i)(f));
    return (...x) => partials.map(p => p(...x));
};

For example, you can apply Nabla to the function f above as follows.

Nabla(f);          // the Nabla function of f

Nabla(f)(1, 2);    // the gradient vector of f at position (1,2),
                   // approximatately [4, 5]

For the function g you get:

Nabla(g)(1, 2, 3);    // the gradient vector of g at position (1,2,3):
                      // [Dx g(1,2,3), Dy g(1,2,3), Dz g(1,2,3)], approximately
		      // [8, 11, 20]

Functional Audio Processing     Unit Circle Art