Skip to content

SciNim/Measuremancer

Repository files navigation

Measuremancer - A library to handle your measurement uncertainties

This library is inspired by the excellent Measurements.jl and can, for all intents and purposes, be considered a port of it (even if it doesn’t yet support some of its features).

The basic gist is that one constructs Measurement objects for one’s measurement values, which include uncertainties. This is done via one of two ways:

import measuremancer
let x = 1.0 ± 0.1 # via unicode operator
let y = measurement(2.0, 0.5)

Printing either of these yields a string representation using the ± unicode operator:

1.0 ± 0.1

What makes this library actually useful however, is the ability to perform error propagation for the user.

import measuremancer
let x = 1.0 ± 0.1
let y = 2.0 ± 0.5

print x + y
print x * y
print x - y
print x / y

(print is a helper defined to print the expression in addition to the measurement. You may use echo as usual for regular printing). yields:

x + y: 3.0 ± 0.51
x * y: 2.0 ± 0.54
x - y: -1.0 ± 0.51
x / y: 0.50 ± 0.13

Error propagation is performed according to linear error propagation theory (or sometimes called “Gaussian error propagation”): https://en.wikipedia.org/wiki/Propagation_of_uncertainty

The library handles dependent variables correctly. This means things like:

import measuremancer
let x = 1.0 ± 0.1
print x - x
# and
print x / x

are handled correctly, resulting in:

x - x: 0.0 ± 0.0
x / x: 1.0 ± 0.0

meaning the resulting variable has no error associated to it.

We can also include more complicated expressions of course:

import measuremancer

proc gaus[T](x, μ, σ: T): T =
  result = 1.0 / sqrt(2 * PI) * exp(- ((x - μ)^2) / (2 *^2)))

let x = 1.0 ± 0.1
let μ = 0.5 ± 0.05
let σ = 1.2 ± 0.2

print gaus(x, μ, σ)

Note: Be very careful using ^ or ** for exponentiation. Notice the extra parenthesis around the (x - μ)^2 term (and σ^2). That is, because at least as of Nim devel 1.7 it otherwise includes the - in the square!

gaus(x, μ, σ): 0.366 ± 0.0177

Other distinct data types

Of course, we wouldn’t be Nim if we couldn’t also apply the whole logic to types other than float!

Feel free to perform error propagation on unchained types for example:

import unchained, meausuremancer

let m = 1.0.kg ± 0.1.kg
let a = 9.81.m•s⁻² ± 0.05.m•s⁻²

print m * a

which yields:

m * a: 9.81 ± 0.982 KiloGram•Meter•Second⁻²

NOTE: With units as complicated as unchained's types, there is still a chance of things breaking. Basic math (*, /, + and -) should work correctly now though.

Compilation flags & Nim version notes

As of Nim version 1.6 any code using this library has to be compiled with:

--experimental:unicodeOperators

Feel free to create a nim.cfg in the directory of your program to avoid having to set this setting manually every time.

NOTE: This flag was not available in Nim 1.4 yet. Unicode operators simply weren’t a thing. If you wish to use this library anyway, you can do so, simply by constructing Measurements using the measurement procedure. Further, in Nim >= 2.0, unicode operators are allowed by default. So, special compilation options are unneeded.

If compiled with `-d:useCligen`, uncertain number pair formatting is the default [`cligen/strUt`](https://github.com/c-blake/cligen/blob/master/cligen/strUt.nim).`fmtUncertain` That uses the uncertainty to limit precision of both value & uncertainty to the same decimal place (2 decimals of the uncertainty by default, as per one common convention).

About

A library to handle measurement uncertainties & error propagation

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages