Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -797,4 +797,5 @@ refWeights(state::State) = state.belief.weights
refPoints(state::State) = state.belief.points
refBandwidth(state::State) = state.belief.trailing_forms[1]
refBandwidths(state::State) = SparseArrays.nonzeros(state.belief.trailing_forms)
refObservability(state::State) = state.belief.observability
getTopologyKind(state::State) = state.belief.topologykind
9 changes: 5 additions & 4 deletions src/Serialization/StateSerialization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,24 @@ function unpackOldState(d)
#
label = Symbol(d.solveKey)
!isempty(d.covar) && error("covar field is not supported")
if label == :parametric
belief = HomotopyDensityDFG{T, getPointType(T)}(;
belief = if label == :parametric
HomotopyDensityDFG{T, getPointType(T)}(;
principal_elements = vals,
principal_forms = [BW],
observability = d.infoPerCoord,
)
else
belief = HomotopyDensityDFG{T, getPointType(T)}(;
HomotopyDensityDFG{T, getPointType(T)}(;
points = vals,
trailing_forms = sparsevec(Dict(1 => BW)),
observability = d.infoPerCoord,
)
end
return State{T, getPointType(T)}(;
label,
belief,
separator = Symbol.(d.separator),
initialized = d.initialized,
observability = d.infoPerCoord,
marginalized = d.ismargin,
solves = d.solvedCount,
)
Expand Down
37 changes: 24 additions & 13 deletions src/entities/HomotopyDensity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@ end
"""
HomotopyDensityDFG{T <: StateType, P}

Hybrid belief representation with natural transition between (non)parametric representations.
Hybrid belief representation with natural transition between hybrid-(non)parametric representations.
This type better allows apples to apples comparisons between divergent beliefs, by means of
a powerful enough density representation.

**THIS IS IMPORTANT**: Fundamentally related to `HomotopyDensity` definition in AMP.jl.

!!! warning "Raw Data Container"
`HomotopyDensityDFG` is the raw data schema used for database storage and serialization.
Mutating this structure in-place is discouraged. Rather, construct a new `State` object
and call `addState!` or `mergeState!`.
and call `addState!` or `mergeState!`. Interaction should use API from HomotopyDensity provider
rather than raw reference access.

Notes:
- These are the internal raw beliefs and need to be viewed through a lens such as
Expand All @@ -73,30 +76,37 @@ provided by AMP for features like pdf evaluation.
- a.k.a. model order reduction given a topology selection
"""
@kwdef struct HomotopyDensityDFG{T <: StateType, P}
"""To make apples vs apples comparison of one belief to another, only the reprkind between densities are needed for understanding
how to interpret this object. By analogy, and image is an image, but might be stored bitmap, jpeg, png, and use RGB24, YCbCr, etc."""
reprkind::HomotopyReprDFG{T} =
HomotopyReprDFG(DefaultTopologyKind(), DefaultFormKind(), T(), nothing)
"""A hint for downstream solvers on how to interpret this data (The 'How')"""
topologykind::AbstractHomotopyTopology = DefaultTopologyKind()

points::Vector{P} = P[] # previously `val`
weights::Vector{Float64} = Float64[]
"""Stores the amount of information captured in each coordinate dimension."""
observability::Vector{Float64} = Float64[] #zeros(getDimension(T)) #TODO renamed from infoPerCoord in v0.29
"""
In model order reduction, PCA, and modal analysis, the terms for the eigenvectors associated with the largest and smallest eigenvalues are commonly:
Major eigenvectors are often called "dominant eigenvectors," or simply "leading modes." In Principal Component Analysis (PCA), these are the "principal components."
Minor eigenvectors are sometimes called "trailing eigenvectors," or "residual modes." In PCA, these correspond to the components with the smallest variance.
Principal/major/dominant/leading recon-basis/eigen vectors. In Principal Component Analysis (PCA), these are the "principal components."
Trailing/minor/residual recon-basis/eigen vectors. In PCA, these correspond to the components with the smallest variance.
"""
principal_coeffs::Vector{Float64} = Vector{Float64}() # FIXME getMajorsLength(reprkind))
principal_elements::Vector{P} = P[] # previously `val[1]` for Gaussian
principal_forms::Vector{Matrix{Float64}} = Matrix{Float64}[] # previously `covar` existed but was stored in `bw` (hacky)
principal_elements::Vector{P} = P[] # FIXME, use ArrayPartion instead. previously `val[1]` for Gaussian
principal_forms::Vector{Matrix{Float64}} = Matrix{Float64}[] # FIXME, use ArrayPartition instead # previously `covar` existed but was stored in `bw` (hacky)
"""Input points may be weighted, and/or reused as part of reconstruction in the trailing forms."""
weights::Vector{Float64} = Float64[]
"""Hard decision that input data are sample points from some manifold, but note the reconstruction might not use points at all."""
points::Vector{P} = P[] # previously `val`
"""
Store minor eigenvalue details such as leaf bandwidth or reconstruction vectors.
- When lifted for compute efficiency, this field is likely to hold something like PDMats.
- When lowered or for serde, this field is likely to hold Dict{Int, Vector{Float64}}.
- Live compute version may hold something like PDMats/Cholesky.
- Stored version might be similar to a Gaussian splat
"""
trailing_forms::SparseVector{Matrix{Float64}, Int} = spzeros(Matrix{Float64}, 1) #previously `bw`
trailing_forms::SparseVector{Matrix{Float64}, Int} = spzeros(Matrix{Float64}, 1) # FIXME use ArrayPartion instead # previously `bw`

"""
Geometric points permute field, allows fast binary tree operations and geometric points splits for manellic (ball) trees.
- Geometric split reqs at least 2*(N+1)-1 points -- e.g. when nodes have only right children, points=[1,2,-3].
- Balanced split reqs at least 2*(N+1)-1 points, incl. right-only case -- e.g. when nodes have only right children, points=[1,2,-3].
- Unclear at time of writing whether DFG v1.X will exceed binary tree representations, but at least `.structure` allows for e.g. n-many child topologies.
"""
structure::SparseVector{Vector{Int}, Int} = spzeros(Vector{Int}, 1)
end
Expand All @@ -113,6 +123,7 @@ function StructUtils.fielddefaults(
) where {T, P}
return (
topologykind = DefaultTopologyKind(),
observability = Float64[],
principal_coeffs = Float64[],
principal_elements = P[],
principal_forms = Matrix{Float64}[],
Expand Down
3 changes: 0 additions & 3 deletions src/entities/State.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ $(TYPEDFIELDS)
separator::Vector{Symbol} = Symbol[]
"""False if initial numerical values are not yet available or stored values are not ready for further processing yet."""
initialized::Bool = false
"""Stores the amount of information captured in each coordinate dimension."""
observability::Vector{Float64} = Float64[]#zeros(getDimension(T)) #TODO renamed from infoPerCoord in v0.29
"""Should this state be treated as marginalized in inference computations."""
marginalized::Bool = false #TODO renamed from ismargin v0.29
"""How many times has a solver updated this state estimate."""
Expand Down Expand Up @@ -88,7 +86,6 @@ function StructUtils.fielddefaults(
belief = HomotopyDensityDFG{T, P}(),
separator = Symbol[],
initialized = false,
observability = Float64[],
marginalized = false,
solves = 0,
statekind = T(),
Expand Down
6 changes: 3 additions & 3 deletions src/services/compare.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ function compare(a::State, b::State)
a.initialized != b.initialized &&
@debug("initialized is not equal") === nothing &&
return false
!isapprox(a.observability, b.observability; atol = 1e-13) &&
@debug("infoPerCoord is not equal") === nothing &&
return false
# !isapprox(a.observability, b.observability; atol = 1e-13) &&
# @debug("infoPerCoord is not equal") === nothing &&
# return false
a.marginalized != b.marginalized &&
@debug("ismargin is not equal") === nothing &&
return false
Expand Down
2 changes: 1 addition & 1 deletion test/testBlocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@ function FileDFGTestBlock(testDFGAPI; VARTYPE = VariableDFG, FACTYPE = FactorDFG
# vnd.bw[1] = [1.0;]
# vnd.dontmargin = true
# vnd.eliminated = true
vnd.observability .= Float64[1.5;]
# vnd.observability .= Float64[1.5;]
vnd.initialized = true
vnd.marginalized = true
push!(vnd.separator, :sep)
Expand Down
Loading