Skip to content

Commit 23dbcd0

Browse files
authored
Merge pull request #243 from JuliaRobotics/4Q19/feature/needsahome
buildSubgraphFromLabels! function in needsahome.jl
2 parents 30de896 + dd672a3 commit 23dbcd0

File tree

5 files changed

+171
-0
lines changed

5 files changed

+171
-0
lines changed

src/DistributedFactorGraphs.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ include("CloudGraphsDFG/CloudGraphsDFG.jl")
100100
const InMemoryDFGTypes = Union{GraphsDFG, LightDFG}
101101
export InMemoryDFGTypes
102102

103+
# Needs a home.
104+
include("needsahome.jl")
105+
103106
function __init__()
104107
@require GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231" begin
105108
@info "Including Plots"

src/GraphsDFG/entities/GraphsDFG.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@ mutable struct GraphsDFG{T <: AbstractParams} <: AbstractDFG
2121
labelDict::Dict{Symbol, Int64}
2222
addHistory::Vector{Symbol} #TODO: Discuss more - is this an audit trail?
2323
solverParams::T # Solver parameters
24+
# GraphsDFG{T}(x...) where T <: AbstractParams = new{T}(x...)
2425
end
2526

27+
28+
GraphsDFG( g::FGType=Graphs.incdict(GraphsNode,is_directed=false),
29+
d::String="Graphs.jl implementation",
30+
n::Int64=0,
31+
l::Dict{Symbol, Int64}=Dict{Symbol, Int64}(),
32+
a::Vector{Symbol}=Symbol[];
33+
userId::String = "UserID",
34+
robotId::String = "robotID",
35+
sessionId::String = "sessionID",
36+
userData::Dict{Symbol, String} = Dict{Symbol, String}(),
37+
robotData::Dict{Symbol, String} = Dict{Symbol, String}(),
38+
sessionData::Dict{Symbol, String} = Dict{Symbol, String}(),
39+
params::T=NoSolverParams()) where T <: AbstractParams = GraphsDFG{T}(g, d, userId, robotId, sessionId, userData, robotData, sessionData, n, l, a, params)
40+
2641
GraphsDFG{T}( g::FGType=Graphs.incdict(GraphsNode,is_directed=false),
2742
d::String="Graphs.jl implementation",
2843
n::Int64=0,

src/needsahome.jl

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
export buildSubgraphFromLabels!, buildSubgraphFromLabels!_SPECIAL
2+
export buildSubgraphFromLabels
3+
4+
5+
"""
6+
$SIGNATURES
7+
Construct a new factor graph object as a subgraph of `dfg <: AbstractDFG` based on the
8+
variable labels `syms::Vector{Symbols}`.
9+
10+
SamC: Can we not just use _copyIntoGraph! for this? Looks like a small refactor to make it work.
11+
Will paste in as-is for now and we can figure it out as we go.
12+
13+
Notes
14+
- Slighly messy internals, but gets the job done -- some room for performance improvement.
15+
- Defaults to GraphDFG, but likely to change to LightDFG in future.
16+
17+
Related
18+
19+
getVariableIds, _copyIntoGraph!
20+
"""
21+
function buildSubgraphFromLabels!(dfg::G,
22+
syms::Vector{Symbol};
23+
subfg::AbstractDFG=(G <: InMemoryDFGTypes ? G : GraphsDFG)(params=getSolverParams(dfg)),
24+
solvable::Int=0,
25+
allowedFactors::Union{Nothing, Vector{Symbol}}=nothing )::G where G <: AbstractDFG
26+
#
27+
28+
# add a little too many variables (since we need the factors)
29+
for sym in syms
30+
if solvable <= getSolvable(dfg, sym)
31+
getSubgraphAroundNode(dfg, getVariable(dfg, sym), 2, false, subfg, solvable=solvable)
32+
end
33+
end
34+
35+
# remove excessive variables that were copied by neighbors distance 2
36+
currVars = getVariableIds(subfg)
37+
toDelVars = setdiff(currVars, syms)
38+
for dv in toDelVars
39+
# delete any neighboring factors first
40+
for fc in lsf(subfg, dv)
41+
deleteFactor!(subfg, fc)
42+
end
43+
44+
# and the variable itself
45+
deleteVariable!(subfg, dv)
46+
end
47+
48+
return subfg
49+
end
50+
51+
function buildSubgraphFromLabels(dfg::G,
52+
syms::Vector{Symbol};
53+
subfg::AbstractDFG=(G <: InMemoryDFGTypes ? G : GraphsDFG)(params=getSolverParams(dfg)),
54+
solvable::Int=0,
55+
allowedFactors::Union{Nothing, Vector{Symbol}}=nothing )::G where G <: AbstractDFG
56+
#
57+
@warn "Deprecated buildSubgraphFromLabels, use buildSubgraphFromLabels! instead."
58+
buildSubgraphFromLabels!(dfg, syms, subfg=subfg, solvable=solvable, allowedFactors=allowedFactors )
59+
end
60+
61+
62+
"""
63+
$SIGNATURES
64+
65+
IIF clique specific version of building subgraphs. This is was an unfortunate rewrite of the existing `buildSubgraphFromLabels!` function above. Currently halfway consolidated. Tests required to ensure these two functions can be reduced to and will perform the same in both.
66+
67+
DevNotes
68+
- DF: Could we somehow better consolidate the functionality of this method into `buildSubgraphFromLabels!` above, which in turn should be consolidated as SamC suggests.
69+
- Since this function has happened more than once, it seems the name `buildSubgraphFromLabels!` might stick around, even if it just becomes a wrapper.
70+
71+
Related
72+
73+
buildSubgraphFromLabels!, _copyIntoGraph!, getVariableIds
74+
"""
75+
function buildSubgraphFromLabels!_SPECIAL(dfg::G,
76+
# frontals::Vector{Symbol},
77+
syms::Vector{Symbol};
78+
subfg::AbstractDFG=(G <: InMemoryDFGTypes ? G : GraphsDFG)(params=getSolverParams(dfg)),
79+
solvable::Int=0,
80+
allowedFactors::Union{Nothing, Vector{Symbol}}=nothing )::G where G <: AbstractDFG
81+
#
82+
# for sym in separators
83+
# (solvable <= getSolvable(dfg, sym)) && DFG.addVariable!(subfg, deepcopy(DFG.getVariable(dfg, sym)))
84+
# end
85+
86+
addfac = Symbol[]
87+
for sym in syms # frontals
88+
if solvable <= getSolvable(dfg, sym)
89+
DFG.addVariable!(subfg, deepcopy(DFG.getVariable(dfg, sym)))
90+
append!(addfac, getNeighbors(dfg, sym, solvable=solvable))
91+
end
92+
end
93+
94+
# allowable factors as intersect between connected an user list
95+
usefac = allowedFactors == nothing ? addfac : intersect(allowedFactors, addfac)
96+
97+
allvars = ls(subfg)
98+
for sym in usefac
99+
fac = DFG.getFactor(dfg, sym)
100+
vos = fac._variableOrderSymbols
101+
#TODO don't add duplicates to start with
102+
if !exists(subfg,fac) && (vos allvars) && (solvable <= getSolvable(dfg, sym))
103+
DFG.addFactor!(subfg, fac._variableOrderSymbols, deepcopy(fac))
104+
end
105+
end
106+
107+
# remove orphans
108+
for fct in DFG.getFactors(subfg)
109+
# delete any neighboring factors first
110+
if length(getNeighbors(subfg, fct)) != length(fct._variableOrderSymbols)
111+
DFG.deleteFactor!(subfg, fc)
112+
@error "deleteFactor! this should not happen"
113+
end
114+
end
115+
116+
return subfg
117+
end

test/needsahomeTests.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using DistributedFactorGraphs
2+
using Test
3+
4+
struct TestInferenceVariable1 <: InferenceVariable end
5+
struct TestInferenceVariable2 <: InferenceVariable end
6+
7+
@testset "Needs-a-home tests" begin
8+
dfg = GraphsDFG{NoSolverParams}(params=NoSolverParams())
9+
10+
# Build a graph
11+
v1 = DFGVariable(:a, TestInferenceVariable1())
12+
v2 = DFGVariable(:b, TestInferenceVariable1())
13+
f1 = DFGFactor{Int, :Symbol}(:f1)
14+
addVariable!(dfg, v1)
15+
addVariable!(dfg, v2)
16+
addFactor!(dfg, [v1, v2], f1)
17+
18+
# Standard tests
19+
newdfg = buildSubgraphFromLabels!(dfg, [:b])
20+
@test ls(newdfg) == [:b]
21+
# Okay it looks like this function only accepts variables, is that right?
22+
@test_throws Exception newdfg = buildSubgraphFromLabels!(dfg, [:b, :f1])
23+
newdfg = buildSubgraphFromLabels!(dfg, [:b, :a])
24+
@test symdiff(ls(newdfg), [:b, :a]) == []
25+
@test lsf(newdfg) == [:f1]
26+
27+
# Check solvable filter
28+
@test setSolvable!(getVariable(dfg, :a), 1) == 1
29+
@test setSolvable!(getVariable(dfg, :b), 0) == 0
30+
@test setSolvable!(getFactor(dfg, :f1), 1) == 1
31+
newdfg = buildSubgraphFromLabels!(dfg, [:b, :a]; solvable = 1)
32+
@test ls(newdfg) == [:a]
33+
end

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ end
4444
include("DataStoreTests.jl")
4545
end
4646

47+
@testset "Needs-a-Home Tests" begin
48+
include("needsahomeTests.jl")
49+
end
4750

4851
@testset "LightDFG subtype tests" begin
4952
for type in [(var=DFGVariableSummary, fac=DFGFactorSummary), (var=SkeletonDFGVariable,fac=SkeletonDFGFactor)]

0 commit comments

Comments
 (0)