Method Documentation

NeXLUncertainties.AllInputsType
AllInputs <: 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.

source
NeXLUncertainties.BasicLabelType

BasicLabel{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.

source
NeXLUncertainties.ComposedMeasurementModelType
ComposedMeasurementModel <: MeasurementModel

A ComposedMeasurementModel is used when the output from step-i will be used in a subsequent step. Favor ParallelMeasurementModel whenever a collection of MeasurementModels share the same inputs (or subsets of the same inputs) since the ParallelMeasurementModels can be run on multiple threads and the Jacobians can be concatenated rather than multiplied. ParallelMeasurementModels and ComposedMeasurementModels can be combined to produce efficient calculation models.

The final result of the ComposedMeasurementModel is the output of the final step.

source
NeXLUncertainties.LabelType

Label is the root abstract type used to provide unique identifiers for variables within UncertainValues and LabeledValues. See [BasicLabel]

source
NeXLUncertainties.LabeledValuesType
LabeledValues

A LabeledValues object represents an efficient way to deal with arrays of Labeled values (Float64). Each value is indexed via a Label so storing them in Vectors 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.

source
NeXLUncertainties.MMResultType
MMResult = Tuple{LabeledValues,Union{Missing,AbstractMatrix{Float64}}}

THe type of return values from the compute(...) function.

source
NeXLUncertainties.MaintainInputsType
MaintainInputs <: 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.

source
NeXLUncertainties.MeasurementModelType
MeasurementModel

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 MeasurementModels together to implement a multi-step calculation using the ∘ operator. If mm1 and mm2 are MeasurementModels 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 MeasurementModels 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.

source
NeXLUncertainties.ParallelMeasurementModelType
ParallelMeasurementModel <: MeasurementModel

A ParallelMeasurementModel is a collection of MeasurementModels that can be executed simultaneously since they share the same inputs (or a subset of the same inputs). ParallelMeasurementModels should be favored over ComposedMeasurementModels 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.

source
NeXLUncertainties.UncertainValuesType
UncertainValues

Represents a set of related variables with the covariance matrix that represents the uncertainty relationships between the variables.

source
Base.:|Method
(|)(mm1::MeasurementModel, mm2::MeasurementModel)
(^)(mm1::MeasurementModel, mm2::MeasurementModel)

Implements a mechanism to combine MeasurementModels 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))
source
Base.:∘Method
(∘)(mm1::MeasurementModel, mm2::MeasurementModel)

Implements composition of MeasurementModels.

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)
source
Base.catMethod
cat(uvss::AbstractArray{UncertainValues})::UncertainValues

Combines the disjoint UncertainValues in uvss into a single UncertainValues object.

source
Base.catMethod
cat(uvss::UncertainValues...)::UncertainValues

Combines the disjoint UncertainValues in uvss into a single UncertainValues object.

source
Base.filterMethod
filter(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.

source
Base.filterMethod
Base.filter(uvs::UncertainValues, labels::Vector{<:Label})::Matrix

Extract the covariance matrix associated with the variables specified in labels into a Matrix.

source
Base.indexinMethod
indexin(lv::LabeledValues, lbl::Label)::Int

Returns the index associated with the specified Label.

source
Base.maxMethod
max(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.

source
Base.minMethod
min(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.

source
Base.roundMethod
Base.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.

source
Base.valuesMethod
values(lv::LabeledValues)::Vector{Float64}

A copy Vector of the values in the same order as labels(lv).

source
Base.valuesMethod
values(uvs::UncertainValues)::Vector{Float64}

A Vector containing the Float64 value for each row in uvs. In the same order as labels(uvs).

source
LaTeXStrings.latexstringMethod
LaTeXStrings.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

source
LaTeXStrings.latexstringMethod
LaTeXStrings.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.

source
NeXLUncertainties.addMethod
add(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) )

source
NeXLUncertainties.asaMethod

asa(::Type{DataFrame}, lv::LabeledValues) extracts a LabeledValues object into a DataFrame in Label and Value columns.

source
NeXLUncertainties.checkcovariance!Function
checkcovariance!(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.

source
NeXLUncertainties.computeMethod
compute(mm::MeasurementModel, uvs::LabeledValues)::LabeledValues

Calculate the output values for the specified set of input LabeledValues.

source
NeXLUncertainties.covarianceMethod
covariance(uv1::UncertainValue, uv2::UncertainValue, correlation::Real)

Computes the covariance given the correlation coefficient between two UncertainValue.

source
NeXLUncertainties.divideFunction
divide(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) )

source
NeXLUncertainties.estimatedMethod
estimated(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.

source
NeXLUncertainties.labelsMethod
labels(uvs::UncertainValues)::Vector{<:Label}

Returns a Vector of Label in the order in which they appear in uvs.values and uvs.covariance.

source
NeXLUncertainties.labelsByTypeMethod
labelsByType(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 Labels. The second version extracts multiple different types in a single call.

source
NeXLUncertainties.mcpropagateMethod
mcpropagate(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.

source
NeXLUncertainties.multiplyFunction
multiply(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) )

source
NeXLUncertainties.parallelMethod
parallel(mm1::MeasurementModel, models::MeasurementModel...)

Implements a mechanism to combine MeasurementModels 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))
source
NeXLUncertainties.pearsonMethod
pearson(uv1::UncertainValue, uv2::UncertainValue, covar::Real)

Computes the Pearson correlation coefficient given the covariance between two UncertainValue.

source
NeXLUncertainties.propagateMethod
propagate(mm::MeasurementModel, uvs::UncertainValues)::UncertainValues

Propagate the input (measured values as UncertainValues) through the MeasurementModel to produce the output values (as UncertainValues).

source
NeXLUncertainties.sortedlabelsMethod
sortedlabels(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.

source
NeXLUncertainties.uncertaintyFunction
uncertainty(lbl::Label, uvs::UncertainValues, k::Float64=1.0)

The uncertainty associated with specified label (k σ where default k=1)

source
NeXLUncertainties.uvsMethod
uvs(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.

source
NeXLUncertainties.valueMethod
value(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

source
NeXLUncertainties.varianceMethod

variance(uvs::UncertainValues, lbl::Label) variance(uvs::UncertainValues, lbl::Label, default)

The variance associated with the specified Label.

source
NeXLUncertainties.σMethod
σ(lbl::Label, uvs::UncertainValues)

Returns the 1σ uncertainty associated with the specified label

source
Statistics.meanMethod
Statistics.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.

source
Statistics.stdMethod
Statistics.std(uvs::UncertainValue...)

The standard deviation of the value portion of the collection of UncertainValue items.

source