UU: scientific units conversion package
UU (units-utility) is a JAL addon to convert quantities between different units of measurement. It is based on the International System of Units (Le Système International d'Unités), or SI.
But UU knows about other systems of units too, such as Imperial.
You can even define your own units by editing the constants library (see below).
UU serves the CAL-engine, as well as TABULA directly.
See TABULA for Release Notes for all 3 addons: math/cal, math/tabula, math/uu.
Initialize UU
UU is shipped as a conventional JAL addon. It provides a Lab entitled: "Scientific Units". To run the Lab, pick menu: Studio > Labs...
Initialize UU by simply loading it in the normal way, eg:
require 'math/uu'
Now exercise it like this:
uu '3 ft' NB. monadic uu: converts to SI units 0.914 m 'ft' uu '1 m' NB. dyadic uu: converts to given units: x 3.281 ft
The cover verb: uu
On loading UU the cover verb uu is defined like this, to be accessible from any locale:
uu_z_ =: uu_uu_
In your own app you may prefer to call uu_uu_ directly. The same goes for any of the externally-callable names in locale: 'uu'.
Two ways of calling verb: uu
Let's take (scientific) quantity to mean an entity having a numeric value and (known) units.
In the above example we've proffered the quantity: three feet as a single string: '3 ft'.
You can also call uu with separate numeric value and units:
value=: 3.28 units=: 'ft' uu value ; units ┌────────┬─┐ │0.999744│m│ └────────┴─┘
Notice that uu returns the converted quantity in the same form as the proffered quantity, either string or boxed duple.
The chief verb: convert
In your app you may prefer to sidestep verb uu altogether, as does TABULA.
The chief verb of the UU package is convert_uu_. It offers more generalized functionality in a more primitive form, eg:
convert_uu_ 'ft' ┌─┬─┬──────┐ │m│1│0.3048│ └─┴─┴──────┘
Verb: convert_uu_ takes a single string argument (y): the units to be converted and returns a boxed triple: siunits;passes;factor -where:
siunits (string) is the target units
passes (integer) is a count of conversion iterations
factor (floating) is the conversion factor from: siunits.
Integer passes is returned for diagnostic purposes and can usually be disregarded. A value of 1 usually indicates that the given units are directly specified in the constants library UUC and don't have to be inferred by repeated passes.
But passes=1 can also mean that UU cannot identify the units. Thus:
convert_uu_ 'elephant' ┌──┬─┬────┐ │kg│1│3400│ └──┴─┴────┘ convert_uu_ 'rhino' ┌──┬─┬─┐ │??│1│_│ └──┴─┴─┘
The convention for unknown units is '??', the corresponding conversion factor being: _ (infinity).
Use convert_uu_ in J code like this:
sourceunits=. 'ft'
z=. convert_uu_ sourceunits
f=. >{:z NB. (numeric) conversion factor
u=. >{.z NB. (string) target units
NB. or alternatively...
'u passes f'=. z NB. passes can be ignored
Using: convert_uu_ versus using: uu
Verb: uu is really just a cover for convert_uu_. Study its code to see how to handle calls to: convert_uu_ in realistic situations.
Unlike uu, verb: convert_uu_ is monadic-only. It converts only to SI-units. To convert feet [ft] to miles [mi], say, needs two calls of convert_uu_ and the quotient taken of the returned conversion factors.
Verb: convert_uu_ is more suitable for calling within application code. Verb: uu is handier for use in J "calculator mode" to convert given quantities.
The constants library: UUC
UU gets its data from the constants library, held in noun: UUC. This noun is defined by the script: uuc.ijs.
UUC is the only name defined by it.
When math/uu is loaded, UU is started by running the verb: start_uu_. This not only loads UUC from its script, but also saves the full pathname of the script as a noun: TPATH_UUC in locale 'z'. Thus you can edit the script uuc.ijs by either of these two equivalent sentences:
open TPATH_UUC uuc''
After editing uuc.ijs, run:
load TPATH_UUC start_uu''
for the changes to take effect.
The syntax of UUC
UUC is a literal 2D array, each line of which has the syntax:
<number> <unitsX> [<units>] <desc>
-where:
<number> evaluates to a number
<units> the units defined by this line
<unitsX> units which are defined elsewhere in UUC
<desc> text description of the units being defined.
The element: <number> is essentially a J-syntax phrase which yields the required (scalar) numeric value. However, for the sake of non-J users, more conventional expressions are allowed, such as:
-1.5E-10 1/16
Sample entries of UUC are:
1e4 m^2 [ha] hectare 0.0254 m [in] inch 36 in [yd] yard 4840 yd^2 [acre] acre
-from which we see that [acre] is defined in terms of [yd], which is itself defined in terms of [in], which is defined in terms of the fundamental units: [m].
It is better to structure UUC in this way, than to define every unit of length in terms of metres [m]. There is no advantage in the latter strategy (except to reduce the number of passes made by: convert_uu_) and the serious disadvantage of having 1 yd defined as approximately (but not exactly) 36 in.
The formulas library: UUF
In addition to the constants library UUC, UU also administers a formulas library UUF, having these counterparts:
UUC_uu_ UUF_uu_
TPATH_UUC_z_ TPATH_UUF_z_
uuc_z_'' uuf_z_''UUF provides services to TABULA in close analogy with UUC. But whilst UUF handling shares many features with UUC, UUF itself plays no part in the operation of UU when used as as a self-contained addon.
The use of unicode symbols by UU
UU offers the option to display units in either pure ASCII or ASCII-plus.
UNICODE_uu_ =: 0 NB. pure ASCII
UNICODE_uu_ =: 1 NB. ASCII-plusASCII-plus entails substituting unicode code-points in utf-8 encoding for these ASCII strings:
PI π
mu µ
Ang Å
Ohm Ω
^2 ²
^3 ³
deg °
amin '
asec "
eur €
cnt ¢
gbp £ The effect is to output units using their conventional SI characters, eg:
UNICODE_uu_ =: 0 'Ang/s^2' uu '1 m/s/s' 1.000E10 Ang/s^2 UNICODE_uu_ =: 1 'Ang/s^2' uu '1 m/s/s' 1.000E10 Å/s²
NOTE: m/s/s is equivalent to: m/s^2.
However, whichever setting of UNICODE_uu_ is used, arguments provided to verb: uu must always be in pure ASCII.
NOTE: departure from strict SI conventions: Å/s², not: Å s⁻².
