Method Documentation
NeXLUncertainties.AllInputs
— TypeAllInputs <: MeasurementModel
Carry over all of the input variables to the next step in a calculation. Typically used in consort with a ParallelMeasurementModel
when inputs to this step will also be required in subsequent steps.
NeXLUncertainties.BasicLabel
— TypeBasicLabel{T}
is a mechanism for creating Label
around other objects. For example, BasicLabel{String} would create a Label
using a String
to provide a unique identifier.
NeXLUncertainties.ComposedMeasurementModel
— TypeComposedMeasurementModel <: MeasurementModel
A ComposedMeasurementModel
is used when the output from step-i will be used in a subsequent step. Favor ParallelMeasurementModel
whenever a collection of MeasurementModel
s share the same inputs (or subsets of the same inputs) since the ParallelMeasurementModel
s can be run on multiple threads and the Jacobians can be concatenated rather than multiplied. ParallelMeasurementModel
s and ComposedMeasurementModel
s can be combined to produce efficient calculation models.
The final result of the ComposedMeasurementModel is the output of the final step.
NeXLUncertainties.Label
— TypeLabel
is the root abstract type used to provide unique identifiers for variables within UncertainValues
and LabeledValues
. See [BasicLabel]
NeXLUncertainties.LabeledValues
— TypeLabeledValues
A LabeledValues
object represents an efficient way to deal with arrays of Label
ed values (Float64
). Each value is indexed via a Label
so storing them in Vector
s with be O(N) whereas storing the Label
and value in a Dict
is O(1). However, storing them in a Dict
loses the ordering which we would also like to retain. LabeledValues
are O(1) while retaining the order of the labels.
NeXLUncertainties.MMResult
— TypeMMResult = Tuple{LabeledValues,Union{Missing,AbstractMatrix{Float64}}}
THe type of return values from the compute(...)
function.
NeXLUncertainties.MaintainInputs
— TypeMaintainInputs <: MeasurementModel
Carry over a subset of the input variables to the next step in a calculation. Typically used in consort with a ParallelMeasurementModel
when inputs to this step will also be required in subsequent steps.
NeXLUncertainties.MeasurementModel
— TypeMeasurementModel
MeasurementModel
is an abstract type representing a vector function of a vector input with correlated uncertainties. A MeasurementModel
is responsible for calculating vector function outputs and the associated Jacobian matrix both evaluated at the input values.
To emphasize that a MeasurementModel represents a vector function that takes an UncertainValues object representing the input values into an UncertainValues object representing the output values, the function operator has been overloaded:
(mm::MeasurementModel)(uvs::UncertainValues)::UncertainValues
or
(mm::MeasurementModel)(uvs::Dict{<:Label, UncertainValue})::UncertainValues
This helps you to think of a MeasurementModel as the equivalent of a function for UncertainValues.
Furthermore, you can compose / pipe / chain MeasurementModel
s together to implement a multi-step calculation using the ∘ operator. If mm1
and mm2
are MeasurementModel
s such that the inputs for mm2
come from mm1
(and the original inputs) then:
(mm2 ∘ mm1)(inputs) = mm2(mm1(inputs))
Equivalently, if mm3
and mm4
both take the same inputs they may be computed in parallel using:
(mm3 | mm4)(inputs) = cat(mm3(inputs), mm4(inputs))
You can combine ∘
and |
together like this:
(mm2 ∘ (mm3 | mm4) ∘ mm1)(inputs) = mm2(cat(mm3(mm1(inputs)),mm4(mm1(inputs))))
which first computes o1=mm1(inputs)
then computes o3=mm3(inputs+o1)
and o4=mm4(inputs+o1)
finally computes mm2(inputs+o1+o3+o4)
.
Composing MeasurementModel
s is where the magic occurs. For a complex measurement model, it may not be feasible/possible to calculate an analytical form of the partial derivative. However, if the model can be broken into a series of smaller composable steps for which the analytical partial derivative can be calculated, the steps can be combined to build the full model. Of course this isn't magic, it results from this property of Jacobians:
$\mathbf{J}_{g(f(x))} |_x = \mathbf{J}_g(y) |_{f(x)} \mathbf{J}_{f(x)} |_x$
To use this framework on your measurement model, you must implement the function compute(...)
for YourMeasurementModel
.
compute(mm::YourMeasurementModel, inputs::LabeledValues, withJac::Boolean)::MMResult
where
MMResult = Tuple{LabeledValues, Union{Missing,AbstractMatrix{Float64}}}
The function compute(...)
is responsible for computing the models output values and the Jacobian of the output values with respect to the input values. The Jacobian is a matrix with one row per output value and one column per input value. The contents of the r,c-th element is the partial derivative of the r-th output value with respect to the c-th input value.
MMResult
represents the function output values (LabeledValues
) and the Jacobian as an AbstractMatrix{Float64}
. To optimize the compute(...)
function when used to simply compute the vector valued function, the Jacobian must calculated only when withJac=true
. If withJac=false
then returning 'missing' for the Jacobian is encouraged. This facilates efficiency when using 'compute(...)' in situations like Monte Carlo propagation (using mcpropagate(...)
) where it is wasteful to compute the Jacobian but you'd otherwise like to use identical code to compute the function values.
NeXLUncertainties.ParallelMeasurementModel
— TypeParallelMeasurementModel <: MeasurementModel
A ParallelMeasurementModel
is a collection of MeasurementModel
s that can be executed simultaneously since they share the same inputs (or a subset of the same inputs). ParallelMeasurementModel
s should be favored over ComposedMeasurementModel
s since they can be threaded and combining Jacobians is more computationally efficient.
ParallelMeasurementModel(models::AbstractVector{MeasurementModel}, multithread=false)
While ParallelMeasurementModel
supports multi-threading, multi-threading should be used only when the cost of the calculation is going to exceed the overhead necessary to create and manage the thread. Usually this means, only use multithread=true
on one of the outer-most steps of a large calculation where splitting the calculation can keep the Jacobians as small as possible until the last possible moment.
The result of the ParallelMeasurementModel is the union of the outputs from each model.
NeXLUncertainties.UncertainValue
— TypeUncertainValue
Represents a floating point numerical value and an associated uncertainty (1σ).
NeXLUncertainties.UncertainValues
— TypeUncertainValues
Represents a set of related variables with the covariance matrix that represents the uncertainty relationships between the variables.
Base.:|
— Method(|)(mm1::MeasurementModel, mm2::MeasurementModel)
(^)(mm1::MeasurementModel, mm2::MeasurementModel)
Implements a mechanism to combine MeasurementModel
s that work on the same input to produce output that is the combination of the outputs of all the measurement models. This is useful when a calculation forks into 2 or more distinct calculations which are later composed as is shown in the examples.
Examples:
j = f | g # Creates a ParallelMeasurementModel([f,g], false)
jp = f ^ g # Creates a ParallelMeasurementModel([f,g], true)
y = j(x) # where y combines the outputs of f(x) and h(x)
z = (f | g | h)(x) # Conceptually like combine(f(x), g(x), h(x)) into a single output
zp = (f ^ g ^ h)(x) # ParallelMeasurementModel([f,g,h], true) Conceptually like combine(f(x), g(x), h(x)) into a single output
(k ∘ (f | g | h))(x) == k(z) # Conceptually like k(f(x),g(x),h(x))
Base.:∘
— Method(∘)(mm1::MeasurementModel, mm2::MeasurementModel)
Implements composition of MeasurementModel
s.
Examples:
(g ∘ f)(x) == propagate(ComposedMeasurementModel([f, g]), x)
(g ∘ f)(x) == g(f(x))
(h ∘ g ∘ f)(x) == propagate(ComposedMeasurementModel([f, g, h]), x)
(h ∘ g ∘ f)(x) == h(g(f(x)))
Note:
(h ∘ (g ∘ f))(x) == ((h ∘ g) ∘ f)(x) == (h ∘ g ∘ f)(x)
Base.cat
— Methodcat(uvss::AbstractArray{UncertainValues})::UncertainValues
Combines the disjoint UncertainValues in uvss into a single UncertainValues object.
Base.cat
— Methodcat(uvss::UncertainValues...)::UncertainValues
Combines the disjoint UncertainValues in uvss into a single UncertainValues object.
Base.filter
— Methodfilter(labels::AbstractVector{<:Label}, mmr::MMResult)::MMResult
Trims an MMResult down to only those labels in labels
. This can optimize calculations which are carrying a lot of intermediary results that are no longer needed. All Jacobian input columns are maintained but only those output rows associated with a label in labels
will be retained. This method reorders the output values to match the order in labels
.
If the input 'mmr' is N functions of M variables and length(labels)=P
then the result will be P functions of M variables.
Base.filter
— MethodBase.filter(uvs::UncertainValues, labels::Vector{<:Label})::Matrix
Extract the covariance matrix associated with the variables specified in labels into a Matrix.
Base.indexin
— Methodindexin(lv::LabeledValues, lbl::Label)::Int
Returns the index associated with the specified Label
.
Base.max
— Methodmax(uv1::UncertainValue, uv2::UncertainValue)
Determines the maximum of two values by comparing first the value and second the uncertainty. (Equal value defer to the larger uncertainty being considered the 'max'.)
If value(uv1)==value(uv2)
then it is undefined which is larger but to ensure a constant ordering I define the one with a larger uncertainty to be larger since it is more probable that it could be larger.
Base.min
— Methodmin(uv1::UncertainValue, uv2::UncertainValue)
Determines the maximum of two values by comparing first the value and second the uncertainty. (Equal value defer to the larger uncertainty being considered the 'min'.)
If value(uv1)==value(uv2)
then it is undefined which is smaller but to ensure a constant ordering I define the one with a larger uncertainty to be smaller since it is more probable that it could be smaller.
Base.round
— MethodBase.round(uva::UncertainValue; defdigits=4)
Provides a (somewhat) intelligent formatter for UncertainValue
objects that uses the uncertainty to suggest the number of digits to display.
Base.values
— Methodvalues(lv::LabeledValues)::Vector{Float64}
A copy Vector
of the values in the same order as labels(lv)
.
Base.values
— Methodvalues(uvs::UncertainValues)::Vector{Float64}
A Vector containing the Float64 value for each row in uvs. In the same order as labels(uvs).
LaTeXStrings.latexstring
— MethodLaTeXStrings.latexstring(uvs::UncertainValues; fmt="%0.3f", mode=:normal[|:siunutx])::LaTeXString
Formats a UncertainValues
as a LaTeXString (mode=:siunitx
uses \num{}
from the siunitx package.) Also requires the amsmath package for vmatrix
LaTeXStrings.latexstring
— MethodLaTeXStrings.latexstring(uv::UncertainValue; fmt=nothing, mode=:normal[|:siunitx])::LaTeXString
Converts an UncertainValue
to a LaTeXString
in a reasonable manner. mode=:siunitx" requires
\usepackage{siunitx}which defines
\num{}.
fmt` is a C-style format string like "%0.2f" or nothing for an "intelligent" default.
NeXLUncertainties.add
— Methodadd(ka::Real, a::UncertainValue, kb::Real, b::UncertainValue, cc::AbstractFloat)
Computes ka*a + kb*b
where a
and b
are UncertainValue and cc
is the correlation coefficient defined as cc = covar(a,b)/( σ(a), σ(b) )
NeXLUncertainties.asa
— Methodasa(::Type{DataFrame}, lv::LabeledValues)
extracts a LabeledValues
object into a DataFrame
in Label and Value columns.
NeXLUncertainties.checkcovariance!
— Functioncheckcovariance!(cov::AbstractMatrix)
Checks whether the matrix meets the criteria for a covariance matrix. (Square, non-negative diagonal elements, symmetric cov[r,c]==cov[c,r], and the correlation coefficient between -1.0 and 1.0). The tests are approximate to handle rounding errors but when a symmetric pair of values are not precisely equal they are set equal and when the correlation coefficient is slightly outside [-1,1], it is restricted to within these bounds. Thus the input matrix can be modified, in ways that are probably benign, by this "check" function.
NeXLUncertainties.compute
— Methodcompute(mm::MeasurementModel, uvs::LabeledValues)::LabeledValues
Calculate the output values for the specified set of input LabeledValues.
NeXLUncertainties.correlation
— Methodcorrelation(uvs::UncertainValues, a::Label, b::Label)
Returns the Pearson correlation coefficient between variables a
and b
.
NeXLUncertainties.covariance
— Methodcovariance(uv1::UncertainValue, uv2::UncertainValue, correlation::Real)
Computes the covariance given the correlation coefficient between two UncertainValue.
NeXLUncertainties.covariance
— Methodcovariance(uvs::UncertainValues, lbl1::Label, lbl2::Label)
The covariance between the two variables.
NeXLUncertainties.divide
— Functiondivide(n::UncertainValue, d::UncertainValue, cc::AbstractFloat)
Computes n/d
where n
and d
are UncertainValue and cc
is the correlation coefficient defined as cc = covar(n,d)/( σ(n), σ(d) )
NeXLUncertainties.equivalent
— Functionequivalent(A::UncertainValue, B::UncertainValue, k=1.0)
A and B are equivalent if |A-B| <= k σ(A-B)
NeXLUncertainties.estimated
— Methodestimated(labels::Vector{<:Label}, samples::Matrix{Float64})
Estimate an UncertainValues based on a set of samples ('measurements'). Computes the mean values and the covariance matrix from the expectation values. Each row r
in samples represents a measured quantity as identified by labels[r]
. Each column represents a single set of measurements of all the labeled quantities.
NeXLUncertainties.fractional
— Methodfractional(f::Real)
Returns 0
NeXLUncertainties.fractional
— Methodfractional(uv::UncertainValue)
Computes the fractional uncertainty.
NeXLUncertainties.labeledvalues
— Methodlabeledvalues(uvs::UncertainValues)
Converts the values of an UncertainValues object into a LabeledValues object.
NeXLUncertainties.labels
— Methodlabels(lv::LabeledValues)::Vector{Label}
A Vector
of the Label
s in order.
NeXLUncertainties.labels
— Methodlabels(uvs::UncertainValues)::Vector{<:Label}
Returns a Vector of Label in the order in which they appear in uvs.values
and uvs.covariance
.
NeXLUncertainties.labelsByType
— MethodlabelsByType(ty::Type{<:Label}, labels::AbstractVector{<:Label})
labelsByType(types::AbstractVector{DataType}, labels::AbstractVector{<:Label})
Extracts all of a specific type of Label
from a list of Label
s. The second version extracts multiple different types in a single call.
NeXLUncertainties.mcpropagate
— Methodmcpropagate(mm::MeasurementModel, inputs::UncertainValues, n::Int, parallel::Bool=true, rng::AbstractRNG = Random.GLOBAL_RNG)::UncertainValues
Propagate the inputs
through the MeasurementModel
using a MonteCarlo algorithm in which the inputs are assumed to be represented by a MvNormal
distribution with covariance from inputs
. Performs 'n' iterations and multi-thread if parallel=true
.
NeXLUncertainties.multiply
— Functionmultiply(a::UncertainValue, b::UncertainValue, cc::AbstractFloat)
Computes a*b
where a
and b
are UncertainValue and cc
is the correlation coefficient defined as cc = covar(a,b)/( σ(a), σ(b) )
NeXLUncertainties.parallel
— Methodparallel(mm1::MeasurementModel, models::MeasurementModel...)
Implements a mechanism to combine MeasurementModel
s that work on the same input to produce output that is the combination of the outputs of all the measurement models. This is useful when a calculation forks into 2 or more distinct calculations which are later composed as is shown in the examples.
Examples:
j = parallel(f,g) # Creates a ParallelMeasurementModel([f,g], true)
y = j(x) # where y combines the outputs of f(x) and h(x)
z = parallel(f, g, h)(x) # Conceptually like combine(f(x), g(x), h(x)) into a single output
(k ∘ parallel(f, g, h))(x) == k(z) # Conceptually like k(f(x),g(x),h(x))
NeXLUncertainties.pearson
— Methodpearson(uv1::UncertainValue, uv2::UncertainValue, covar::Real)
Computes the Pearson correlation coefficient given the covariance between two UncertainValue.
NeXLUncertainties.poisson
— Methodpoisson(val::Int)
Creates an UncertainValue from an integer which is assumed to have σ = sqrt(val).
NeXLUncertainties.propagate
— Methodpropagate(mm::MeasurementModel, uvs::UncertainValues)::UncertainValues
Propagate the input (measured values as UncertainValues) through the MeasurementModel to produce the output values (as UncertainValues).
NeXLUncertainties.sortedlabels
— Methodsortedlabels(uvs::UncertainValues)
A alphabetically sorted list of the labels. Warning this can be slow. Use keys(...) if you want just a unordered set of labels.
NeXLUncertainties.uncertainty
— Functionuncertainty(uv::UncertainValue, k::Real=1.0)
Returns the k-σ uncertainty (defaults to k=1.0)
NeXLUncertainties.uncertainty
— Functionuncertainty(lbl::Label, uvs::UncertainValues, k::Float64=1.0)
The uncertainty associated with specified label (k σ where default k=1)
NeXLUncertainties.uncertainty
— Methoduncertainty(f::Real, k::Real=1.0)
Returns 0.0.
NeXLUncertainties.uv
— Functionuv(val::Real, σ::Real)
Create an UncertainValue from a real value and 1σ uncertainty.
NeXLUncertainties.uvs
— Methoduvs(labels::AbstractVector{<:Label}, values::AbstractVector{Float64}, covar::AbstractMatrix{Float64})
uvs(labels::AbstractVector{<:Label}, values::AbstractVector{Float64}, vars::AbstractVector{Float64})
uvs(values::Pair{<:Label,UncertainValue}...)
uvs(value::Pair{<:Label,UncertainValue})
uvs(values::Dict{<:Label,UncertainValue})
Various methods for constructing UncertainValues
structures from varying types of inputs.
NeXLUncertainties.value
— Methodvalue(lv::LabeledValues, lbl::Label)::Float64
Returns the value associated with the specified Label
.
NeXLUncertainties.value
— Methodvalue(f::Real)
Returns f
NeXLUncertainties.value
— Methodvalue(uvs::UncertainValues, lbl::Label)
value(uvs::UncertainValues, lbl::Label, defValue)
The value associate with the Label. The first implementation throws an exception if lbl
is not present while the second implementation returns defValue
NeXLUncertainties.value
— Methodvalue(uv::UncertainValue)
Returns the value portion. (uv.value)
NeXLUncertainties.variance
— Methodvariance(f::Real)
Returns 0.
NeXLUncertainties.variance
— Methodvariance(uvs::UncertainValues, lbl::Label) variance(uvs::UncertainValues, lbl::Label, default)
The variance associated with the specified Label.
NeXLUncertainties.variance
— Methodvariance(uv::UncertainValue)
Returns σ².
NeXLUncertainties.σ
— Methodσ(r::Real)
Returns 0.
NeXLUncertainties.σ
— Methodσ(lbl::Label, uvs::UncertainValues)
Returns the 1σ uncertainty associated with the specified label
NeXLUncertainties.σ
— Methodσ(uv::UncertainValue)
Returns the 1-σ uncertainty)
Statistics.mean
— MethodStatistics.mean(uvs::AbstractVector{UncertainValue}, minvar=0.0e-10)
The variance weighted mean of a collection of UncertainValue items. (see https://en.wikipedia.org/wiki/Weightedarithmeticmean#Variance_weights). Be careful! Adding a single value with value!=0 and σ=0.0 will cause NaN.
Statistics.std
— MethodStatistics.std(uvs::UncertainValue...)
The standard deviation of the value portion of the collection of UncertainValue items.