14.5 Defining Multivariate Functions

Some common dimensional calculations such as wind chill or body mass index have more than one parameter. To support these calculations, units allows multivariate functions as unit definitions. Unlike the nonlinear units described above, multivariate functions provide only a forward evaluation and are not invertible: it is impossible to convert a wind chill output back to the temperature and wind speed that generated it.

A multivariate function definition is similar to that for other nonlinear units. For example, you could define ‘bmi’ like this, starting with the unit’s name followed immediately without white space by a comma-separated parameter list:

bmi(ht,wt) units=[m,kg] domain=(0,)(0,) (wt/kg)/(ht/m)^2

This defines a new unit, ‘bmi’, that has two parameters, ‘height’, and ‘weight’. You are allowed to use white space in the parameter list. The optional ‘units=’ specification (with no space before the ‘=’) provides a comma-separated list in square brackets of units that provide the dimensions of the parameters. If you list fewer units than the number of parameters, the remaining parameters will allow any unit. For univariate nonlinear units, a semicolon introduces the units of the inverse. The semicolon is not permitted in the ‘units=’ list for multivariate functions.

You specify the domain, if desired, using ‘domain=’, followed (without white space) by the intervals defining the domain of each parameter, either juxtaposed or separated by commas. The above example requires that both arguments be strictly positive. As usual, use square brackets to indicate closed intervals. The rules for domain intervals are the same as those described above for nonlinear units. If you need to indicate an unconstrained input give the interval ‘(,)’. The intervals in the domain specification must use numerical values; you cannot use units or calculations in the domain.

The final part of the definition is the expression that defines the unit. Since inverses are not well-defined for multivariate units, you cannot provide an inverse. Since you cannot provide an inverse, you also cannot provide a range, so the ‘range=’ specification is invalid for multivariate functions.

If you need to specify that a particular unit is of arbitrary dimension when units appearing after it in the parameter list are of specified dimension, you can do this using the special dimension specification, ‘*’. Here is a toy example:

func(a,b) units=[*,1] domain=(,),[-1,1] a asin(b)

In this example the first argument is permitted to be of any dimension, but the second argument must be dimensionless. The first argument has no domain bounds, but the second one must lie in the domain of the arcsine function.