The Miscellaneous`Units2` Package
By Ted Ersek    ersektr@navair.navy.mil

This notebook demonstrates features in the package  Miscellaneous`Units2` which is an improvement on the standard package Miscellaneous`Units`.  You can download still another units package posted at  http://home.earthlink.net/~djmp/Mathematica.html  which was written by David Park. You will notice David's package has a lot of features not included in either  Miscellaneous`Units`  or  Miscellaneous`Units2`.  I might be willing to add features found in David's package to Miscellaneous`Units2` if someone would like me to.  If that is the case send me an email explaining what features you would like to have added.

Version History

Version 1.0 was posted on MathSource in May 2002. 

Version 1.1 was posted on MathSource in Dec 2002. 
After loading Version 1.0 of Miscellaneous`Units2` one would get error messages after evaluating something like the input in the next cell.  This was due to a bug that is fixed in Version 1.1.

foo[expr_, n_Integer] := Part[expr, n]

Where to store the package and how to load it

The package source code file (Units2.m) should be copied to the directory returned after evaluating the next cell.

\(ToFileName[{$TopDirectory, "AddOns", "StandardPackages", "Miscellaneous"}]\)

Once (Units2.m) is copied to the right folder the package can be loaded by evaluating the Needs statement in the next cell.

Needs["Miscellaneous`Units2`"]

Examples Where  Miscellaneous`Units2`  Excels

When using the standard package  Miscellaneous`Units`  the output of evaluating ((Sqrt[20 + 5 + 16*25 (π^2)]) Ohm)  is formatted as  (Ohm (Sqrt[25 + 400  (π^2)])) which doesn't comply with the normal convention of putting units at the end.  Miscellaneous`Units2` doesn't have this problem.

(Sqrt[20 + 5 + 16*25 (π^2)]) Ohm

If your not using Miscellaneous`Units2` the following simply evaluates to zero.

t1 = 5 Second;
t2 = 2 Second;
t3 = 3 Second;
t1 - t2 - t3

Under Miscellaneous`Units2`  Convert seems to work the same as it does when using the standard package Miscellaneous`Units.  Actually Miscellaneous`Units2`  gives Convert additional definitions to ensure it knows how to deal with the UnitsWrapper head which I discuss below.  The next cell gives an example where Convert seems to do the same thing it does under the standard package.

Convert[45.3 (( Kilo Meter)/Hour), (Feet/Second)]

The standard package Miscellaneous`Units` can't handle the next examples but Miscellaneous`Units2` can.

Convert[0.36  Radian, °]

Convert[0.0024  (Radian/Second), (°/Minute)]

Under Miscellaneous`Units2`  the following examples are simplified automatically.

z = (3 + 5  I) Ohm;
Abs[z]

Round[3.7 ((Foot*Pound)/(Second^2))]

You will also find that after loading the Miscellaneous`Units2` package Sign, Ceiling, Floor, Round, Conjugate, Im, Re, IntegerPart, FractionalPart and trigonometric functions handle units gracefully just as Abs and Round do above.  

Furthermore, the following automatically uses PowerExpand.

(Sqrt[(((2  Second))^2) - (((1.99 Second))^2)])

A Shadowed Symbol

If you use the  Miscellaneous`Units2` and  Graphics`Colors` packages you will get an error message complaining that the symbol Gray is used in two contexts.  The Miscellaneous`Units2` package automatically loads the standard package  Miscellaneous`Units` which uses Gray as the derived SI unit of absorbed dose of radiation.  The  Graphics`Colors` package uses Gray as an RGBColor.

Solutions

If you think you might use the color Gray and almost never use the unit Gray you can load  Miscellaneous`Units2` before Graphics`Colors` and ignore the warning message.  You can then use Gray for the color Gray, and  Miscellaneous`SIUnits`Gray for the unit of radiation.

On the other had if you are more likely to use Gray as a unit of radiation you should load  Graphics`Color` first.  That way Gray will refer to the unit of radiation and you will need to use  Graphics`Colors`Gray for the color Gray.

Then if you are sure you will NEVER use one of the versions of Gray you can eliminate one of them.  To do that open the code for the package whose version of Gray you will never use  (Miscellaneous`Units` or Graphics`Colors`),  and comment out all code involving the symbol Gray.

The Head  'UnitsWrapper'  is key

Miscellaneous`Units2` uses the system symbol  $Pre to automatically separate the units of an expression from things that aren't units.  Expression with units are wrapped in the head UnitsWrapper which is invisible in StandardForm and TraditionalForm output.  So for example nothing looks unusual about the output of the following.

expr = 3 x1 x2 Meter (Kilogram/(Second^2))

However, the InputForm of expr has the head 'UnitsWrapper' as shown in the next output.

InputForm[expr]

The list of symbols that are considered units is stored in UnitList and you can see this list by evaluating the next cell.  This list includes all the units supported by the standard package  Miscellaneous`Units`  with the addition of the unit dB.

UnitList

The Miscellaneous`Units2`  package makes a new unit dB with the usage message below.

?dB

Gamma and a few other symbols can be used as a function and also as a unit of measure.  An impressive feature of the Miscellaneous`Units2`  package is that it can automatically tell one from the other.  This is demonstrated below where Gamma is parsed correctly as a unit in one case and a function in another case!

expr1 = (b1 + b2) Gamma;
InputForm[expr1]

expr2 = 3  Gamma[x] Second;
InputForm[expr2]

Using Symbols from  Miscellaneous`PhysicalConstants`

If you try using constants from the standard package  Miscellaneous`PhysicalConstants`  you will see the  
Miscellaneous`Units2`  package doesn't automatically put the physical constants in the UnitsWrapper form.  This is demonstrated in the next cell.

Needs["Miscellaneous`PhysicalConstants`"];
InputForm[AccelerationDueToGravity ]

After loading the Miscellaneous`Units2` package Convert can work with the symbols in the standard package  Miscellaneous`PhysicalConstants`  even though the constants aren't in the UnitsWrapper form.  This capability is demonstrated in the next cell.

Convert[AccelerationDueToGravity, (Foot/(Second^2))]

Sometimes you might want to convert an expression to the UnitsWrapper form.  The head UnitsWrapper will do this as demonstrated in the next cell.

g = 
        UnitsWrapper[AccelerationDueToGravity];
InputForm[g]

You might also make an assignment such as (t = 5.2 Second) before loading the Miscellaneous`Units2` package and if you do the definition of (t) will not be in the UnitsWrapper form even after the package is loaded.  However, you can easily convert such an expression to UnitsWrapper form just as I did above with AccelerationDueToGravity.

Working with Degrees

Evaluating the following gives the same result it normally does.  I arranged it that way since some people probably rely on this behavior.

44.6 °

So if you want say some symbol is  (44.6 degrees)  you need to explicitly use UnitsWrapper as I do below.

angle1 = UnitsWrapper[44.6, °]

The calculation in the next cell is performed automatically.

2  angle1

The angle in the next cell isn't parsed into  UnitsWrapper[30, Degree].

angle2 = 30  °;
FullForm[angle2]

The calculation in the next cell isn't computed because angle1 has the head UnitsWrapper, but  (30 °) has the head Times.

angle1 + 30 °

The next input also doesn't compute because angle1 has the head UnitsWrapper, but 30.5 has the head Real.

angle1 + 30.5

If you want to add something to angle1 defined above the other term must have the form  UnitsWrapper[_, °]  as in the next cell.

angle2 = UnitsWrapper[30, °];
angle1 + angle2

UnitsWrapper has the attribute NHoldRest, and this allows us to numerically approximate the angle in the next cell and N[_] doesn't convert  °  to  its numeric value.

UnitsWrapper[153/20, °]
N[%]

Trigonometric functions return the expected result when given an argument with the form  UnitsWrapper[_, Degree].  Here we get the Sin of 44.6 degrees.

{angle1, Sin[angle1]}

Trigonometric functions also return the expected result when given an argument with the form 
UnitsWrapper[_, Radian]  as in the next cell.

{Sin[(π/4) Radian], Sin[2.3 Radian]}

Nothing happens to the next input and this seems natural because Mathematica normally does nothing with Sin[π/9].

Sin[π/9 Radian]

If it were not for the use Radian inside the trigonometric functions the following would automatically get converted to radicals.  I could have designed the package to ensure this is done automatically, but instead I will explain how you can get the desired result with a little Mathematica programming.

expr1 = 
        Cos[(π/9) Radian] + 
          Sin[(π/9) Radian];
FunctionExpand[expr1]

In the next cell I convert expr1 above to a expression that doesn't use the unit Radian or the UnitsWrapper head.  FunctionExpand can then be used on the resulting expression.

expr2 = 
      expr1 /. UnitsWrapper[x_, Radian] :> 
          x
FunctionExpand[expr2]

ConvertTemperature, SI, MKS, CGS

You should find that after loading the  Miscellaneous`Units2` package the functions ConvertTemperature, SI, MKS, CGS  appear to work exactly as they do when using the standard package  Miscellaneous`Units`.