Getting started

When taking measurements, one usually has to keep track of three things: The actual value of the measurement, the unit in which the quantity is measured and an uncertainty which quantifies how precise the measurement is. The package pyveu was created to simplify the work with real-life quantities.

The main class of the package is the pyveu.Quantity. This section is devoted to show typical ways in which the pyveu.Quantity objects are used.

Create quantities

There are several ways to create a pyveu.Quantity.

String expressions

The easiest is probably to class the constructor with a string expression. The expression can consist of three parts:

1. The first part specifies the value of the quantity. This part is mandatory. The value expression can be any int, float in regular or scientific notation.

2. The second part specifies the uncertainty. This part is optional. If it is specified, it must start with “+-” followed by a positive number.

3. The last portion specifies the unit. This part is optional. If it is omitted, the quantities is a pure scalar quantity without unit. The unit is specified by products and ratios of unit symbols (such as m for meter or s for seconds). Unit symbols can be raised to a power by suffixing it with ^n where n is the (positive or negative) exponent.

Parenthesis cannot be used.

Often, a unit is build by a ratio with a product in the denominator. To avoid cluttering the string with many / characters, it is possible to omit the * character in the product of the denominator. A space between two unit symbols multiplies the two units and has precedence of the ratio. This means the string 1 / m^2 s is equivalent to m^-2 * s^-1.

The following example creates quantities from valid expressions.

>>> from pyveu import Quantity
>>> Quantity("42")
<Quantity: 42>
>>> Quantity("137 +- 1")
<Quantity: 137 +- 1>
>>> Quantity("1.6 km")
<Quantity: 1600 m>
>>> Quantity("-8.22 +- 0.32 m / s")
<Quantity: (-8.22 +- 0.32) m s^(-1)>
>>> Quantity("3.2e-3 +- 34e-4 K / W")
<Quantity: (0.0032 +- 0.0034) m^(-2) kg^(-1) s^3 K>

Programmatically

When quantities are created programmatically, for example when reading a file, it looks quite painful to build a string with value, error, and unit. The constructor of the class pyveu.Quantity accepts all these arguments separately. The first three positional arguments are

  1. The value of the quantity as an int or float,
  2. The error of the quantities as an int or float; or None,
  3. The unit of the quantities as a unit vector; or None.

The first two arguments should be self-explanatory. The third argument, the unit vector, specifies the unit of the quantity. Unit vectors are how units are handled internally. When working with the default SI units, a unit vector is an 8-dimension vector, or simply a list with eight items. The items specify the exponents of the SI base units. It’s best to copy the unit vector from existing pyveu.Unit objects.

>>> import pyveu.si as si
>>> myunit = si.kelvin / si.watt
>>> myunit.unit_vector()
array([-2., -1.,  3.,  0.,  1.,  0.,  0.,  0.])

The following quantity is equivalent to the one created from the string 3.2e-3 +- 34e-4 K / W.

>>> Quantity(3.2e-3, 34e-4, myunit.unit_vector())
<Quantity: (0.0032 +- 0.0034) m^(-2) kg^(-1) s^3 K>

Named quantities

Quantities can be annotated with a label, symbol, and a latex alternative symbol. The names of the quantities are used when the quantity is printed. The information can also be used by a user program or a third-party library. For example, if a named quantity is passed to a plotting library, the label could be used as the axis label.

label
The label is a human-readable description of the quantity. Current, Fine structure constant, Heat conductivity are examples of good labels.
symbol
The symbol is the mathematical symbol used for the quantity. I, a or p are examples of good symbols.
latex alternative
Sometimes, the common mathematical symbol needs latex typesetting. In that case, you can specify the latex alternative, which is used instead of the symbol if the output medium is latex document. \\alpha or p_i are examples of good latex alternative symbols. If latex typesetting is not needed, this should be None.

We can name a quantity by passing the names via keyword arguments to the constructor. This work when using expression strings or when creating a unit programmatically.

>>> Quantity("42", label="The answer")
<Quantity The answer: 42>
>>> Quantity("0.00729", label="Fine structure constant",
... symbol="a", latex="\\alpha")
<Quantity Fine structure constant: a = 0.00729>
>>> Quantity("-8.22 +- 0.32 m / s", symbol="v")
<Quantity: v = (-8.22 +- 0.32) m s^(-1)>

Arithmetics with quantities

Calculating with quantities is as easy as doing it with simple numbers in Python. The pyveu.Quantity overload the operators +, -, *, / and **. Arithmetic operations are carried out for the value of the quantity, for the unit. The uncertainties of the quantities are propagated to the result.

>>> duration = Quantity("28 +- 1 min")
>>> distance = Quantity("1000 +- 50 m")
>>> speed = distance / duration
>>> speed
<Quantity: (0.595238 +- 0.0365745) m s^(-1) | depends=[9, 10]>

The package also brings common mathematical methods, such as pyveu.exp() and pyveu.log(). Calling these methods will also propagate the uncertainty.

>>> from pyveu import log
>>> log(Quantity("431 +- 13"))
<Quantity: 6.06611 +- 0.0301624 | depends=[12]>

The depnds part of the printout indicates that the quantity depends on another quantity (here the quantity with id 12). This information is required to keep track of the correlations between quantities. What are correlations between quantities? When you call Quantity(), you create a new, statistically independent quantity. The difference between independent and correlated quantities will become apparent with an example.

Assume you have two statically independent measurements of a physical quantity, you should call Quantity() twice. The quantity object a and b are independent.

>>> a = Quantity("1 +- 0.1")
>>> b = Quantity("1 +- 0.1")

When we add them, we see that the relative uncertainty gets reduced because the up and down fluctuations of both quantities cancel on average.

>>> a + b
<Quantity: 2 +- 0.141421 | depends=[14, 15]>

On the other hand, we can also create two quantities c and d whose uncertainties are correlated.

>>> parent = Quantity("1 +- 0.1")
>>> c = 1 * parent
>>> d = 1 * parent

Adding c and d is identical to 2 * parent, so the result should be the same.

>>> c + d
<Quantity: 2 +- 0.2 | depends=[17]>
>>> 2 * parent
<Quantity: 2 +- 0.2 | depends=[17]>

Notice that when adding the quantities, the error is simply scaled by the factor two. The up and down fluctuations cannot cancel, because they are always in the same direction.

Internally, correlations are stored as dependencies along with the derivates. The derivative tells the system to what extend an uncertainty propagates to a derived quantity. Using the chain rule it is easy to compute the derivative of a new derived quantity. This technique is known as [automatic differentiation](https://en.wikipedia.org/wiki/Automatic_differentiation) or auto-diff.

Retrieve the result

The properties of a quantity can be access programmatically with the pyveu.Quantity.value(), pyveu.Quantity.error() and pyveu.Quantity.unit_vector() methods.

>>> height = Quantity("178 +- 2 cm")
>>> height.value()
1.78
>>> height.error()
0.02
>>> height.unit_vector()
array([1., 0., 0., 0., 0., 0., 0., 0.])

By default, these methods return the value in multiples of the base units, here meter and not centimeter. To get the values in a different unit, pass a unit object or a unit expression to the pyveu.Quantity.value() and pyveu.Quantity.error() methods.

>>> height = Quantity("178 +- 2 cm")
>>> height.value("mm")
1780.0
>>> height.error("mm")
20.0

Quantities come with the pyveu.Quantity.str() method, which generates a string representation with sensible rounding.

>>> height = Quantity("178.12345 +- 2.12345 cm")
>>> height.str()
'(1.78 +- 0.02) m'

As with pyveu.Quantity.value() and pyveu.Quantity.error(), pyveu.Quantity.str() accepts an argument to print the quantity in another unit. Unlike the other two methods, the unit passed to pyveu.Quantity.str() does not need to be a scalar multiple of the quantity. The print out will automatically append any missing arguments.

>>> speed = Quantity("10 +- 0.1 m / s")
>>> speed.str("km / hr")
'(36.0 +- 0.4) km / hr'
>>> speed.str("km")  # missing 1/second added automatically
'(0.01000 +- 0.00010) km * 1 / s'

The default set of units contains the speed of light, Planck’s constant and electron volts. This makes it easy to convert between natural and SI units.

>>> electron_mass = Quantity("0.5 MeV / c^2")
>>> electron_mass
<Quantity: 8.91331e-31 kg>
>>> red_h_c = Quantity("1 h c") / (2 * math.pi)  # Note: hbar = 100 * bar
>>> red_h_c.str("MeV fm")
'197.32698045930246 MeV * fm'