|
1 | 1 | # utilities for calculating the gradient over factors
|
2 | 2 |
|
| 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 | + |
3 | 77 | export getCoordSizes
|
4 | 78 | export checkGradientsToleranceMask, calcPerturbationFromVariable
|
5 | 79 |
|
|
0 commit comments