-
Notifications
You must be signed in to change notification settings - Fork 4
Manellic code shuffle towards DFG v1 compliance #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| # end | ||
| # end | ||
|
|
||
| # number of data points (aka particles) in tree, i.e. N | ||
| Base.length(::ManellicTree{M, D, N}) where {M, D, N} = N | ||
|
|
||
| getPoints(mt::ManellicTree) = view(mt.data, mt.permute) | ||
|
|
@@ -16,7 +17,7 @@ getWeights(mt::ManellicTree) = view(mt.weights, mt.permute) | |
| # _getleft(i::Integer, N) = 2*i + (2*i < N ? 0 : 1) | ||
| # _getright(i::Integer, N) = _getleft(i,N) + 1 | ||
|
|
||
| # either leaf or tree kernel, if larger than N | ||
| # either tree or leaf kernel, if larger than N | ||
| function leftIndex(mt::ManellicTree, krnIdx::Int = 1) | ||
| return 2 * krnIdx + (2 * krnIdx < length(mt) ? 0 : 1) | ||
| end | ||
|
|
@@ -51,6 +52,9 @@ getKernelLeafAsTreeKer( | |
|
|
||
| Return kernel from tree by binary tree index, and convert leaf kernels to tree kernel types if necessary. | ||
|
|
||
| Notes: | ||
| - BinaryTree (BT) index goes from root=1 to largest leaf 2*N | ||
|
|
||
| See also: [`getKernelLeafAsTreeKer`](@ref) | ||
| """ | ||
| function getKernelTree( | ||
|
|
@@ -92,8 +96,9 @@ function getKernelTree( | |
| end | ||
| end | ||
|
|
||
|
|
||
| # check for existence in tree or leaves | ||
| function exists_BTLabel(mt::ManellicTree{M, D, N}, idx::Int) where {M, D, N} | ||
| # check for existence in tree or leaves | ||
| eset = if idx < N | ||
| mt._workaround_isdef_treekernel | ||
| else | ||
|
|
@@ -115,8 +120,11 @@ function isLeaf_BTLabel(mt::ManellicTree{M, D, N}, idx::Int) where {M, D, N} | |
| end | ||
| end | ||
|
|
||
| # check for uniform weights | ||
| uniWT(mt::ManellicTree) = 1 === length(union(diff(getWeights(mt)))) | ||
|
|
||
|
|
||
| # check for uniform bandwidths in kernels | ||
| function uniBW(mt::ManellicTree{M, D, N}) where {M, D, N} | ||
| if 1 < length(mt.leaf_kernels) | ||
| bw = cov(mt.leaf_kernels[1]) | ||
|
|
@@ -219,6 +227,7 @@ function Base.convert( | |
| return src | ||
| end | ||
|
|
||
| # case for different types requiring conversion | ||
| function Base.convert( | ||
| ::Type{MvNormalKernel{P, T, M, iM}}, | ||
| src::MvNormalKernel, | ||
|
|
@@ -231,7 +240,7 @@ function Base.convert( | |
| return MvNormalKernel{P, T, M, iM}(μ, p, sqrt_iΣ, src.weight) | ||
| end | ||
|
|
||
| # covariance | ||
| # covariance eigen decomposition and sort ascending | ||
| function eigenCoords(f_CVp::AbstractMatrix) | ||
| function _decomp(evc::AbstractMatrix, evl::AbstractVector, _toflip::Bool = det(evc) < 0) | ||
| pidx = _toflip ? sortperm(evl; rev = true) : 1:length(evl) | ||
|
|
@@ -253,10 +262,10 @@ end | |
|
|
||
| Give vector of manifold points and split along largest covariance (i.e. major direction) | ||
|
|
||
| DeVNotes: | ||
| DevNotes: | ||
| - FIXME: upgrade to Manopt version | ||
| - https://github.com/JuliaRobotics/ApproxManifoldProducts.jl/issues/277 | ||
| - FIXME use manifold mean and cov calculation instead | ||
| - TODO, instead use Krylov methods (e.g. recursive power series) for next largest eigen vector down depth of tree for efficiency | ||
| """ | ||
| function splitPointsEigen( | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note, I already did some previous effort towards the homotopy concept by using eigen for finding the next largest variance down the tree. Just adding the note here that a much more efficient approach would be to only extract the largest eigen vector via Krylov methods instead of recalculating the whole eigen decomp each time. |
||
| M::AbstractLieGroup, | ||
|
|
@@ -437,7 +446,7 @@ Notes: | |
| DevNotes: | ||
| - Design Decision 24Q1, Manellic.MvNormalKernel bandwidth defs should ALWAYS ONLY BE covariances, because | ||
| - Vision state is multiple bandwidth kernels including off diagonals in both tree or leaf kernels | ||
| - Hybrid parametric to leafs convariance continuity | ||
| - Hybrid parametric to leafs covariance continuity | ||
| - https://github.com/JuliaStats/Distributions.jl/blob/a9b0e3c99c8dda367f69b2dbbdfa4530c810e3d7/src/multivariate/mvnormal.jl#L220-L224 | ||
| """ | ||
| function buildTree_Manellic!( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Affie , I've been working through ManellicTree as prototype for HomotopyBelief. I'm calling here to check for discussion points on:
meanandcov? TheseStatistics.overloads would be the interface for all things "hybrid-parametric" (separately we need to know depth in tree for getting the number of modes).ManellicTreeBelief_likely to be renamed toHomotopyBeliefas part of stabilizing DFG v1.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For factors, the common entry point is
getMeasurementParametric, callingmeanandinvcov.For variables
.valand.bwis used directly.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a good example (recently) of using
.valperhaps please? I'm trying to figure out if that should be renamed togetPointsorgetModesetc...I'm looking for a not dehann usage example if you have one pls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the last idea was to go through calls like these:
There are still a few direct field access methods in the same files.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay thanks -- so I think the way to go here is something like
modes = getMixture(_, nmodes=1)which returns aVector{ConcentratedGaussian{M}}(legacy name isMvNormalKernel). From theremanipoint := getMean(modes[1])andsqrt(1/Σ^2) := getInformationmat(modes[1]); also1/Σ^2 := getPrecisionmat(modes[1]).There is some nuance on how
getMixtureworks. I think just return the kernels (i.e. mixture) atdepth = ceil(log2(nmodes))in the belief tree.This also means that convenience wrappers can exist (but we miss the opportunity to promote the new solver)
getMean(getBelief(getVariable(dfg,:w_X1))).My sense at the moment is that we should promote
getBeliefandgetMixtureas the front facing API. We can then find a way to documentgetPoints(belief)orcov(getMixture(_, 1)). This would also mean happenstance equivalents such asgetPoints(getMixture(fg, lb, nmodes=1))[1] == getMean(getBelief(fg, lb)), where the second is the least desirable signature in terms of overall UX.