Skip to content

Commit 5ac3b14

Browse files
committed
towards new factor jacobian
1 parent 71a8f37 commit 5ac3b14

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

src/services/FactorGradients.jl

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,79 @@
11
# utilities for calculating the gradient over factors
22

3+
struct FactorGradient{A <: AbstractMatrix}
4+
manifold::AbstractManifold
5+
JacF!::JacF_RLM!
6+
J::A
7+
end
8+
9+
function factorJacobian(
10+
fg,
11+
faclabel::Symbol,
12+
fro_p = first.(getVal.(fg, getVariableOrder(fg, faclabel), solveKey = :parametric))
13+
)
14+
faclabels = Symbol[faclabel;]
15+
frontals = ls(fg, faclabel)
16+
separators = Symbol[] # setdiff(ls(fg), frontals)
17+
18+
# get the subgraph formed by all frontals, separators and fully connected factors
19+
varlabels = union(frontals, separators)
20+
21+
filter!(faclabels) do fl
22+
return issubset(getVariableOrder(fg, fl), varlabels)
23+
end
24+
25+
facs = getFactor.(fg, faclabels)
26+
27+
# so the subgraph consists of varlabels(frontals + separators) and faclabels
28+
29+
varIntLabel = OrderedDict(zip(varlabels, collect(1:length(varlabels))))
30+
31+
# varIntLabel_frontals = filter(p->first(p) in frontals, varIntLabel)
32+
# varIntLabel_separators = filter(p->first(p) in separators, varIntLabel)
33+
34+
calcfacs = map(f->IIF.CalcFactorManopt(f, varIntLabel), facs)
35+
36+
# get the manifold and variable types
37+
frontal_vars = getVariable.(fg, frontals)
38+
vartypes, vartypecount, vartypeslist = IIF.getVariableTypesCount(frontal_vars)
39+
40+
PMs = map(vartypes) do vartype
41+
N = vartypecount[vartype]
42+
G = getManifold(vartype)
43+
return IIF.NPowerManifold(G, N)
44+
end
45+
M = ProductManifold(PMs...)
46+
47+
#
48+
#FIXME
49+
@assert length(M.manifolds) == 1 "#FIXME, this only works with 1 manifold type component"
50+
MM = M.manifolds[1]
51+
52+
# inital values and separators from fg
53+
# fro_p = first.(getVal.(frontal_vars, solveKey = :parametric))
54+
# sep_p::Vector{eltype(fro_p)} = first.(getVal.(fg, separators, solveKey = :parametric))
55+
sep_p = Vector{eltype(fro_p)}()
56+
57+
#cost and jacobian functions
58+
# cost function f: M->ℝᵈ for Riemannian Levenberg-Marquardt
59+
costF! = IIF.CostF_RLM!(calcfacs, fro_p, sep_p)
60+
# jacobian of function for Riemannian Levenberg-Marquardt
61+
jacF! = IIF.JacF_RLM!(MM, costF!)
62+
63+
num_components = length(jacF!.res)
64+
65+
p0 = deepcopy(fro_p)
66+
67+
# initial_residual_values = zeros(num_components)
68+
J = zeros(num_components, manifold_dimension(MM))
69+
70+
jacF!(MM, J, p0)
71+
72+
J
73+
end
74+
75+
76+
377
export getCoordSizes
478
export checkGradientsToleranceMask, calcPerturbationFromVariable
579

test/manifolds/factordiff.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
# dev test script for factor gradients using ForwardDiff and ManifoldDiff
3+
4+
# using ManifoldDiff
5+
# using Manifolds
6+
using IncrementalInference
7+
using StaticArrays
8+
# using DataStructures: OrderedDict
9+
10+
##
11+
12+
# M = SpecialEuclidean(2)
13+
# p = ArrayPartition(SA[0.0; 0.0], SMatrix{2,2}(1, 0, 0, 1.))
14+
15+
# # finitediff setup
16+
# r_backend = ManifoldDiff.TangentDiffBackend(
17+
# ManifoldDiff.FiniteDifferencesBackend()
18+
# )
19+
20+
# e0 = identity_element(M, p)
21+
22+
# cost(p_) = distance(M, e0, p_)
23+
24+
# cost(p)
25+
26+
# g = ManifoldDiff.jacobian(M, TranslationGroup(3), cost, p, r_backend)
27+
28+
29+
##
30+
31+
fg = LocalDFG(;
32+
solverParams = SolverParams(;
33+
graphinit=false
34+
)
35+
)
36+
37+
addVariable!.(fg, [:x0; :x1], Position2)
38+
f = addFactor!(fg, [:x0; :x1], EuclidDistance(Normal(10,1.0)))
39+
40+
p1 = [SA[0.0;0.0] for _ in 1:1]
41+
42+
setVal!(fg, :x1, p1, solveKey=:parametric)
43+
44+
45+
J = factorJacobian(fg, :x0x1f1)
46+
47+
##

0 commit comments

Comments
 (0)