Units¶
YggdrasilRapidJSON added support for attaching units to scalars and arrays that can be tracked during arithmetic operations. The yggdrasil_rapidjson.units submodule wraps the YggdrasilRapidJSON units classes. Unit expressions are parsed from provided strings. Available units and expression can be found in the YggdrasilRapidJSON documentation. Both the scalar (yggdrasil_rapidjson.units.Quantity) and array classes (yggdrasil_rapidjson.units.QuantityArray) are built on Numpy arrays and can be used with Numpy methods in the ways that Numpy arrays can including Numpy ufuncs.
Scalars¶
Scalar unit quantities can be created from built-in number classes
>>> from yggdrasil_rapidjson import units
>>> x = units.Quantity(5, 'cm')
or numpy scalars
>>> import numpy as np
>>> y = units.Quantity(np.int8(3), 's')
Arrays¶
Array unit quantities can be created from lists or numpy arrays
>>> xarr = units.QuantityArray([1, 2, 3, 4], 'cm')
or numpy arrays
>>> import numpy as np
>>> yarr = units.QuantityArray(np.ones((3, 3), dtype='int8'), 's')
Operations¶
Arithmetic operations can be performed between quantities and scalars,
>>> 3 * x
Quantity(15, 'cm')
>>> x / 3
Quantity(1.66666667, 'cm')
>>> x % 2
Quantity(1, 'cm')
>>> y**2
Quantity(9, dtype=int8, units='s**2')
between quantities and other quantities,
>>> x * y
Quantity(15, 'cm*s')
>>> x / y
Quantity(1.66666667, 'cm*(s**-1)')
>>> x / units.Quantity(4, 'm')
Quantity(0.0125, '')
>>> x + units.Quantity(4, 'mm')
Quantity(5.4, 'cm')
between quantity arrays and scalars or arrays with the same shape,
>>> 3 * xarr
QuantityArray([ 3, 6, 9, 12], 'cm')
>>> xarr % 2
QuantityArray([1, 0, 1, 0], 'cm')
>>> yarr**2
QuantityArray([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]], dtype=int8, units='s**2')
>>> xarr * np.array([0.1, 0.4, 2.0, 0.0])
QuantityArray([0.1, 0.8, 6. , 0. ], 'cm')
between quantity arrays and quantity scalars
>>> xarr * x
Quantity([ 5, 10, 15, 20], 'cm**2')
>>> xarr / y
Quantity([0.33333333, 0.66666667, 1. , 1.33333333], 'cm*(s**-1)')
>>> xarr % x
Quantity([1, 2, 3, 4], 'cm')
and between quantity arrays of the same shape
>>> xarr / yarr
Traceback (most recent call last):
ValueError: operands could not be broadcast together with shapes (4,) (3,3)
>>> xarr / (0.3 * np.ones((4, )))
QuantityArray([ 3.33333333, 6.66666667, 10. , 13.33333333], 'cm')
>>> xarr / units.QuantityArray(np.ones((4, )), 'kg')
QuantityArray([1., 2., 3., 4.], 'cm*(kg**-1)')
Some operations are only valid between quantities with compatible units. If the units are not compatible, a yggdrasil_rapidjson.units.UnitsError will be raised.
>>> x + 2
Traceback (most recent call last):
UnitsError: Incompatible units: '' and 'cm'
>>> x + units.Quantity(2, 'mm')
Quantity(5.2, 'cm')
>>> x + y
Traceback (most recent call last):
UnitsError: Incompatible units: 's' and 'cm'
>>> x % y
Traceback (most recent call last):
UnitsError: Incompatible units: 's' and 'cm'
Numpy ufuncs can also be used on both scalar and array quantities
>>> np.sqrt(x)
Quantity(2.23606798, 'cm**0.5')
>>> np.sqrt(xarr)
QuantityArray([1. , 1.41421356, 1.73205081, 2. ], 'cm**0.5')
>>> np.power(x, 1.5)
Quantity(11.18033989, 'cm**1.5')
>>> np.abs(x)
Quantity(5, 'cm')
>>> np.sign(x)
1
>>> np.reciprocal(x)
Quantity(0, 'cm**-1')
Trigonometric functions are only valid on quantities that have angular units. Inverse trigonometric functions are only valid on quantities that are dimensionless.
>>> np.sin(x)
Traceback (most recent call last):
UnitsError: Incompatible units: 'cm' and 'rad'
>>> np.sin(units.Quantity(np.pi / 2, 'radians'))
Quantity(1., '')
>>> np.cos(units.Quantity(180, 'degrees'))
Quantity(-1., '')
>>> np.arccos(x)
Traceback (most recent call last):
UnitsError: Incompatible units: 'cm' and ''
>>> np.arccos(units.Quantity(-1., ''))
Quantity(3.14159265, 'rad')