# (units.info)Nonlinear units

Next: Localization Prev: Defining new units Up: Top
Enter node , (file) or (file)node
```
8 Defining nonlinear units
**************************

Some units conversions of interest are nonlinear; for example,
temperature conversions between the Fahrenheit and Celsius scales
cannot be done by simply multiplying by conversions factors.

When you give a linear unit definition such as `inch 2.54 cm' you
are providing information that `units' uses to convert values in inches
into primitive units of meters.  For nonlinear units, you give a
functional definition that provides the same information.

Nonlinear units are represented using a functional notation.  It is
best to regard this notation not as a function call but as a way of
adding units to a number, much the same way that writing a linear unit
name after a number adds units to that number.  Internally, nonlinear
units are defined by a pair of functions which convert to and from
linear units in the data file, so that an eventual conversion to
primitive units is possible.

Here is an example nonlinear unit definition:

tempF(x) [1;K] (x+(-32)) degF + stdtemp ; (tempF+(-stdtemp))/degF + 32

A nonlinear unit definition comprises a unit name, a dummy parameter
name, two functions, and two corresponding units.  The functions tell
`units' how to convert to and from the new unit.  In order to produce
valid results, the arguments of these functions need to have the
correct dimensions.  To facilitate error checking, you may specify the
dimensions.

The definition begins with the unit name followed immediately (with
no spaces) by a `(' character.  In parentheses is the name of the
parameter.  Next is an optional specification of the units required by
the functions in this definition.  In the example above, the `tempF'
function requires an input argument conformable with `1'.  For normal
nonlinear units definitions the forward function will always take a
dimensionless argument.  The inverse function requires an input
argument conformable with `K'.  In general the inverse function will
need units that match the quantity measured by your nonlinear unit.
The sole purpose of the expression in brackets to enable `units' to
perform error checking on function arguments.

Next the function definitions appear.  In the example above, the
`tempF' function is defined by

tempF(x) = (x+(-32)) degF + stdtemp

This gives a rule for converting `x' in the units `tempF' to linear
units of absolute temperature, which makes it possible to convert from
tempF to other units.

In order to make conversions to Fahrenheit possible, you must give a
rule for the inverse conversions. The inverse will be `x(tempF)' and
its definition appears after a `;' character.  In our example, the
inverse is

x(tempF) = (tempF+(-stdtemp))/degF + 32

This inverse definition takes an absolute temperature as its argument
and converts it to the Fahrenheit temperature.  The inverse can be
omitted by leaving out the `;' character, but then conversions to the
unit will be impossible.  If the inverse is omitted then the `--check'
option will display a warning.  It is up to you to calculate and enter
the correct inverse function to obtain proper conversions.  The
`--check' option tests the inverse at one point and print an error if
it is not valid there, but this is not a guarantee that your inverse is
correct.

If you wish to make synonyms for nonlinear units, you still need to
define both the forward and inverse functions.  Inverse functions can be
obtained using the `~' operator.  So to create a synonym for `tempF'
you could write

fahrenheit(x) [1;K] tempF(x); ~tempF(fahrenheit)

You may occasionally wish to define a function that operates on
units.  This can be done using a nonlinear unit definition.  For
example, the definition below provides conversion between radius and
the area of a circle.  Note that this definition requires a length as
input and produces an area as output, as indicated by the specification
in brackets.

circlearea(r) [m;m^2] pi r^2 ; sqrt(circlearea/pi)

Sometimes you may be interested in a piecewise linear unit such as
many wire gauges.  Piecewise linear units can be defined by specifying
conversions to linear units on a list of points.  Conversion at other
points will be done by linear interpolation.  A partial definition of
zinc gauge is

zincgauge[in] 1 0.002, 10 0.02, 15 0.04, 19 0.06, 23 0.1

In this example, `zincgauge' is the name of the piecewise linear unit.
The definition of such a unit is indicated by the embedded `['
character.  After the bracket, you should indicate the units to be
attached to the numbers in the table.  No spaces can appear before the
`]' character, so a definition like `foo[kg meters]' is illegal;
instead write `foo[kg*meters]'.  The definition of the unit consists of
a list of pairs optionally separated by commas.  This list defines a
function for converting from the piecewise linear unit to linear units.
The first item in each pair is the function argument; the second item
is the value of the function at that argument (in the units specified
in brackets).  In this example, we define `zincgauge' at five points.
For example, we set `zincgauge(1)' equal to `0.002 in'.  Definitions
like this may be  more readable  if written using  continuation
characters as

zincgauge[in] \
1 0.002  \
10 0.02   \
15 0.04   \
19 0.06   \
23 0.1

With the preceeding definition, the following conversion can be
performed:

You have: zincgauge(10)
You want: in
* 0.02
/ 50
You have: .01 inch
You want: zincgauge
5

If you define a piecewise linear unit that is not strictly
monotonic, then the inverse will not be well defined.  If the inverse is
requested for such a unit, `units' will return the smallest inverse.
The `--check' option will print a warning if a non-monotonic piecewise
linear unit is encountered.

```

automatically generated by info2www version 1.2.2.9