measuremancer

Search:
Group by:
Source   Edit  

Helper conversion to have the same API for Unchained types as well as regular numbers.Comparison operators. For two Measurements, only equal if that holds for value and uncertainty. TODO: should we use almostEqual here? Or is that too imprecise for the purpose?A "type safe" solution required for unchained could be achieved with something like this. However, it shows the problem of getting a squared type as the resder argumentDo we want the following? It forces any FloatLike to generate a Measurement[float]!propagation based plainly on operator overload?mutable assign/additionmutable assign/subtractionThe following two dirty (!) templates help us with the assignment of the result procedure calls, taking care of deducing the types and performing the conversions so that we don't need to manually convert them all the time. assign1 is used for the call to procRes with a single argument and assign2 for the procRes with two arguments.Overloads for literals that force same type as Measurement hasmutable assign/multiplicationOverloads for literals that force same type as Measurement hasNOTE: Using any of the following exponentiation functions is dangerous. The Nim parser might include an additional prefix into the argument to ^ instead of keeping it as a, well, prefix. So -(x - μ)^2 is parsed as (-(x - μ))^2!-> for static exponents-> for explicit float exponents

Now generate single argument (mostly trigonometric) functions They all follow the following structure

  proc exp*(m: Measurement): Measurement =
    result = procRes(exp(m.val), exp(m.val), m)
where the derivatives are taken from the 'lookup table' below.

NOTE: some of the following functions are not implemented in Nim atm, hence they are commented out. This is based on the same in astgrad, which itself took the map from somewhere else. Need to look up where that was, oops.

Types

FloatLike = concept xtypeof(T)typeof(U)
    x.toFloat is float
    let y = T(1.0)
    y.to(U) is U
Source   Edit  
FloatLikeCanBePowExp = concept xtypeof(T)typeof(U)
    x is FloatLike
    pow(1.0, x).toFloat is float
Source   Edit  
FloatLikeNotInt = concept xtypeof(T)typeof(U)
    x is FloatLike
    not (x is SomeInteger)
Source   Edit  
FloatLikeSupportsPow = concept xtypeof(T)typeof(U)
    x is FloatLike
    pow(x, 1.0).toFloat is float
Source   Edit  
FloatLikeUnchangedUnderPow = concept xtypeof(T)
    x is FloatLike
    (x ^ 2) is T
Note: this does not actually check for a runtime integer, but for reasons that elude me, it does the right thing. And doing the "correct" thing here does _not work. So uhh. Source   Edit  
Measurement[T] = object
  val*: T
  uncer*: T
Source   Edit  

Consts

mmErrPrec {.intdefine.} = 3
Source   Edit  

Procs

proc `$`[T: FloatLike](m: Measurement[T]): string
Source   Edit  
proc `*`[T: FloatLike; U: FloatLike](a: Measurement[T]; b: Measurement[U]): auto
Source   Edit  
proc `*`[T: FloatLike; U: FloatLike](m: Measurement[U]; x: T): auto
Source   Edit  
proc `*`[T: FloatLike; U: FloatLike](x: T; m: Measurement[U]): auto
Source   Edit  
proc `*`[T: FloatLike; U: FloatLike](x: T{lit}; m: Measurement[U]): Measurement[
    U]
Source   Edit  
proc `*`[U: FloatLike; T: FloatLike](m: Measurement[U]; x: T{lit}): Measurement[
    U]
Source   Edit  
proc `**`[T: FloatLike](m: Measurement[T]; p: static SomeInteger): auto
Source   Edit  
proc `**`[T: FloatLikeSupportsPow; U: FloatLikeCanBePowExp](a: Measurement[T];
    b: Measurement[U]): Measurement[T]

NOTE: Both types must be compatible FloatLike in such a way that T can be the base argument to pow and U the exponent argument. Note that the operation is destructive, i.e. the return type of pow(T, U) is forced to be T.

This is done so that we don't need to rely on returning auto. If the destructive nature is a problem for your use case, open an issue and we can adjust the logic.

Source   Edit  
proc `**`[T: FloatLikeUnchangedUnderPow](m: Measurement[T]; p: SomeInteger): Measurement[
    T]
Exponentiation for RT natural exponents, or technically for any type T for which calculating x ^ N does not change the type. Source   Edit  
proc `*=`[T: FloatLike](a: var Measurement[T]; b: Measurement[T])
Source   Edit  
proc `*=`[T: FloatLike](a: var Measurement[T]; b: T)
Source   Edit  
proc `+`[T: FloatLike; U: FloatLike](x`gensym7: `{}`(T, lit);
                                     m`gensym7: Measurement[U]): Measurement[U]
Source   Edit  
proc `+`[T: FloatLike](a, b: Measurement[T]): Measurement[T]
Source   Edit  
proc `+`[T: FloatLike](m`gensym7: Measurement[T]; x`gensym7: T): Measurement[T]
Source   Edit  
proc `+`[T: FloatLike](x`gensym7: T; m`gensym7: Measurement[T]): Measurement[T]
Source   Edit  
proc `+`[U: FloatLike; T: FloatLike](m`gensym7: Measurement[U];
                                     x`gensym7: `{}`(T, lit)): Measurement[U]
Source   Edit  
proc `+-`[T: FloatLike](val, uncer: T): Measurement[T]
noUnicode-mode makes output like this which users may want to re-use as input without edit. Nim 2/--experimental:unicodeOperators allows it. Source   Edit  
proc `+/`[F](x, y: Measurement[F]): Measurement[F]
en.wikipedia.org/wiki/Weighted_arithmetic_mean#Variance-defined_weights suggests inverse-variance weights via max.likelihood over normal distros theory which also makes sense from "variance linearity" perspective. This binary operator does this for a pair of measurements. Source   Edit  
proc `+=`[T: FloatLike](a: var Measurement[T]; b: Measurement[T])
Source   Edit  
proc `-`[T: FloatLike; U: FloatLike](x`gensym8: `{}`(T, lit);
                                     m`gensym8: Measurement[U]): Measurement[U]
Source   Edit  
proc `-`[T: FloatLike](a, b: Measurement[T]): Measurement[T]
Source   Edit  
proc `-`[T: FloatLike](m: Measurement[T]): Measurement[T]
Source   Edit  
proc `-`[T: FloatLike](m`gensym8: Measurement[T]; x`gensym8: T): Measurement[T]
Source   Edit  
proc `-`[T: FloatLike](x`gensym8: T; m`gensym8: Measurement[T]): Measurement[T]
Source   Edit  
proc `-`[U: FloatLike; T: FloatLike](m`gensym8: Measurement[U];
                                     x`gensym8: `{}`(T, lit)): Measurement[U]
Source   Edit  
proc `-=`[T: FloatLike](a: var Measurement[T]; b: Measurement[T])
Source   Edit  
proc `/`[T: FloatLike; U: FloatLike](a: Measurement[T]; b: Measurement[U]): auto
Source   Edit  
proc `/`[T: FloatLike; U: FloatLike](m: Measurement[T]; x: U): auto
Source   Edit  
proc `/`[T: FloatLike; U: FloatLike](x: T; m: Measurement[U]): auto
Source   Edit  
proc `/`[T: FloatLike; U: FloatLike](x: T{lit}; m: Measurement[U]): auto
Source   Edit  
proc `/`[U: FloatLike; T: FloatLike](m: Measurement[U]; x: T{lit}): Measurement[
    U]
Source   Edit  
proc `<`[T: FloatLike; U: FloatLike](a`gensym105: `{}`(U, lit);
                                     b`gensym105: Measurement[T]): bool
Source   Edit  
proc `<`[T: FloatLike; U: FloatLike](a`gensym105: Measurement[T];
                                     b`gensym105: `{}`(U, lit)): bool
Source   Edit  
proc `<`[T: FloatLike](a`gensym105, b`gensym105: Measurement[T]): bool
Source   Edit  
proc `<`[T: FloatLike](a`gensym105: Measurement[T]; b`gensym105: T): bool
Source   Edit  
proc `<`[T: FloatLike](a`gensym105: T; b`gensym105: Measurement[T]): bool
Source   Edit  
proc `<=`[T: FloatLike; U: FloatLike](a`gensym106: `{}`(U, lit);
                                      b`gensym106: Measurement[T]): bool
Source   Edit  
proc `<=`[T: FloatLike; U: FloatLike](a`gensym106: Measurement[T];
                                      b`gensym106: `{}`(U, lit)): bool
Source   Edit  
proc `<=`[T: FloatLike](a`gensym106, b`gensym106: Measurement[T]): bool
Source   Edit  
proc `<=`[T: FloatLike](a`gensym106: Measurement[T]; b`gensym106: T): bool
Source   Edit  
proc `<=`[T: FloatLike](a`gensym106: T; b`gensym106: Measurement[T]): bool
Source   Edit  
proc `==`[T: FloatLike; U: FloatLike](m1: Measurement[T]; m2: Measurement[U]): bool
NOTE: This is a bit hacky, but it checks if two types are simply aliases based on their names being equal. In unchained this can happen if a local type is redefined and the two measurements have different "type instances". Source   Edit  
proc `==`[T: FloatLike](k1, k2: DerivKey[T]): bool
Source   Edit  
proc `==`[T: FloatLike](m1, m2: Measurement[T]): bool
comparison of two measurements does not need to take into account the type, as we require same type anyway. Hence use toFloat to compare as float Source   Edit  
proc `==`[T: FloatLike](m: Measurement[T]; x: T): bool
Source   Edit  
proc `==`[T: FloatLike](x: T; m: Measurement[T]): bool
Source   Edit  
proc `^`[T: FloatLike](m: Measurement[T]; p: static SomeInteger): auto
NOTE: If you import unchained, this version is not actually used, as unchained defines a macro ^ for static integer exponents, which simply rewrites the AST to an infix (or trivial) node! Source   Edit  
proc `^`[T: FloatLikeSupportsPow; U: FloatLikeNotInt](m: Measurement[T]; p: U): Measurement[
    T]
Source   Edit  
proc `^`[T: FloatLikeUnchangedUnderPow](m: Measurement[T]; p: SomeInteger): Measurement[
    T]
Source   Edit  
proc abs[T: FloatLike](m: Measurement[T]): Measurement[T]
Source   Edit  
proc abs2[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccos[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccosh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccot[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccoth[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccsc[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arccsch[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arcsec[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arcsech[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arcsin[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arcsinh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arctan[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc arctanh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc cbrt[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc copysign[T: FloatLike; U: FloatLike](a: Measurement[T]; b: U): Measurement[
    T]
Source   Edit  
proc copysign[T: FloatLike; U: FloatLike](a: U; b: Measurement[T]): U
Source   Edit  
proc copysign[T: FloatLike](a, b: Measurement[T]): Measurement[T]
Source   Edit  
proc cos[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc cosh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc cot[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc coth[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc csc[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc csch[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc deg2rad[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc erf[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc erfc[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc erfcinv[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc erfi[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc erfinv[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
func error[T: FloatLike](m: Measurement[T]): T {.inline.}
Source   Edit  
proc exp[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc exp2[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc expm1[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc hash[T: FloatLike](key: DerivKey[T]): Hash
Source   Edit  
proc inv[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc isInf[T: FloatLike](m: Measurement[T]): bool
Source   Edit  
proc isNegInf[T: FloatLike](m: Measurement[T]): bool
Source   Edit  
proc ln[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc log[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc log1p[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc log2[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc log10[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc mean[F](x: varargs[Measurement[F]]): Measurement[F]
Average however many uncertain values in x into an overall estimate using the binary +/ operator. x can also be any openArray[Measurement[F]]. Source   Edit  
proc measurement[T: FloatLike](val, uncer: T{lit}): Measurement[float]
Source   Edit  
proc measurement[T: FloatLike](value, uncertainty: T): Measurement[T]
Source   Edit  
proc pretty[T: FloatLike](m: Measurement[T]; precision: int; merge = false): string
On the regular printing backend merge is ignored. Source   Edit  
proc rad2deg[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc sec[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc sech[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
func signbit[T: FloatLike](m: Measurement[T]): bool
Source   Edit  
proc sin[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc sinh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc sqrt[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc tan[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc tanh[T](m: Measurement[T]): auto
letStmt contains the definition of x, let x = m.val Source   Edit  
proc to[T: FloatLike; U](m: Measurement[T]; dtype: typedesc[U]): Measurement[U]
Source   Edit  
proc to[T: SomeNumber; U](x: T; _: typedesc[U]): U
Source   Edit  
proc toFloat[T: SomeFloat](x: T): float
Source   Edit  
proc toFloat[T: SomeInteger](x: T): float
Source   Edit  
func uncertainty[T: FloatLike](m: Measurement[T]): T {.inline.}
Source   Edit  
func value[T: FloatLike](m: Measurement[T]): T {.inline.}
Source   Edit  
proc ±[T: FloatLike](val, uncer: T): Measurement[T]
Source   Edit  
proc ±[T: FloatLike](val, uncer: T{lit}): Measurement[float]
Source   Edit  

Templates