Skip to content

Commit 9726c12

Browse files
authored
Merge pull request #508 from JuliaRobotics/feat/4Q19/fix499
add few tree tests (API)
2 parents 9abed88 + 679ea04 commit 9726c12

8 files changed

+216
-59
lines changed

src/CanonicalGraphExamples.jl

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
export loadCanonicalFG_Kaess, loadCanonicalFG_TestSymbolic, loadCanonicalFG_CaesarRing1D
3+
4+
5+
"""
6+
$SIGNATURES
7+
8+
Canonical example from literature, Kaess, et al.: ISAM2, IJRR, 2011.
9+
10+
Notes
11+
- Paper variable ordering: p = [:l1;:l2;:x1;:x2;:x3]
12+
"""
13+
function loadCanonicalFG_Kaess()
14+
fg = initfg()
15+
16+
addVariable!(fg,:x1, ContinuousScalar)
17+
addFactor!(fg, [:x1;], Prior(Normal()))
18+
19+
20+
addVariable!(fg,:x2, ContinuousScalar)
21+
addFactor!(fg,[:x1, :x2], LinearConditional(Normal()))
22+
23+
addVariable!(fg, :x3, ContinuousScalar)
24+
addFactor!(fg,[:x2,:x3],LinearConditional(Normal()))
25+
26+
addVariable!(fg, :l1, ContinuousScalar)
27+
addFactor!(fg, [:x1,:l1], LinearConditional(Normal()) )
28+
addFactor!(fg, [:x2,:l1], LinearConditional(Normal()) )
29+
30+
addVariable!(fg, :l2, ContinuousScalar)
31+
addFactor!(fg, [:x3,:l2], LinearConditional(Normal()))
32+
33+
return fg
34+
end
35+
36+
37+
"""
38+
$SIGNATURES
39+
40+
Canonical example introduced by Borglab.
41+
42+
Notes
43+
- Known variable ordering: p = [:x1; :l3; :l1; :x5; :x2; :l2; :x4; :x3]
44+
"""
45+
function loadCanonicalFG_TestSymbolic()
46+
fg = initfg()
47+
48+
addVariable!(fg, :x1, ContinuousScalar)
49+
addVariable!(fg, :x2, ContinuousScalar)
50+
addVariable!(fg, :x3, ContinuousScalar)
51+
addVariable!(fg, :x4, ContinuousScalar)
52+
addVariable!(fg, :x5, ContinuousScalar)
53+
addVariable!(fg, :l1, ContinuousScalar)
54+
addVariable!(fg, :l2, ContinuousScalar)
55+
addVariable!(fg, :l3, ContinuousScalar)
56+
57+
addFactor!(fg, [:x1;:l1], LinearConditional(Normal()))
58+
addFactor!(fg, [:x1;:x2], LinearConditional(Normal()))
59+
addFactor!(fg, [:x2;:l1], LinearConditional(Normal()))
60+
addFactor!(fg, [:x2;:x3], LinearConditional(Normal()))
61+
addFactor!(fg, [:x3;:x4], LinearConditional(Normal()))
62+
addFactor!(fg, [:x4;:l2], LinearConditional(Normal()))
63+
addFactor!(fg, [:x4;:x5], LinearConditional(Normal()))
64+
addFactor!(fg, [:l2;:x5], LinearConditional(Normal()))
65+
addFactor!(fg, [:x4;:l3], LinearConditional(Normal()))
66+
addFactor!(fg, [:x5;:l3], LinearConditional(Normal()))
67+
68+
return fg
69+
end
70+
71+
72+
73+
"""
74+
$SIGNATURES
75+
76+
Canonical example introduced originally as Caesar Hex Example.
77+
78+
Notes
79+
- Paper variable ordering: p = [:x0;:x2;:x4;:x6;:x1;:l1;:x5;:x3;]
80+
"""
81+
function loadCanonicalFG_CaesarRing1D()
82+
83+
fg = initfg()
84+
85+
addVariable!(fg, :x0, ContinuousScalar)
86+
addVariable!(fg, :x1, ContinuousScalar)
87+
addVariable!(fg, :x2, ContinuousScalar)
88+
addVariable!(fg, :x3, ContinuousScalar)
89+
addVariable!(fg, :x4, ContinuousScalar)
90+
addVariable!(fg, :x5, ContinuousScalar)
91+
addVariable!(fg, :x6, ContinuousScalar)
92+
93+
addFactor!(fg, [:x0], Prior(Normal()))
94+
addFactor!(fg, [:x0;:x1], LinearConditional(Normal()))
95+
addFactor!(fg, [:x1;:x2], LinearConditional(Normal()))
96+
addFactor!(fg, [:x2;:x3], LinearConditional(Normal()))
97+
addFactor!(fg, [:x3;:x4], LinearConditional(Normal()))
98+
addFactor!(fg, [:x4;:x5], LinearConditional(Normal()))
99+
addFactor!(fg, [:x5;:x6], LinearConditional(Normal()))
100+
101+
addVariable!(fg, :l1, ContinuousScalar)
102+
addFactor!(fg, [:x0;:l1], LinearConditional(Normal()))
103+
addFactor!(fg, [:x6;:l1], LinearConditional(Normal()))
104+
105+
return fg
106+
end

src/FactorGraph01.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,7 @@ function getEliminationOrder(dfg::G; ordering::Symbol=:qr, solvable::Int=1) wher
10951095
end
10961096

10971097
# Return the variable ordering that we should use for the Bayes map
1098+
# reverse order checked in #475 and #499
10981099
return permuteds[p] |> reverse
10991100
end
11001101

src/IncrementalInference.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ include("Factors/Sphere1D.jl")
548548
include("AdditionalUtils.jl")
549549
include("SolverAPI.jl")
550550

551+
include("CanonicalGraphExamples.jl")
551552
include("Deprecated.jl")
552553

553554
exportimg(pl) = error("Please do `using Gadfly` before IncrementalInference is used to allow image export.")

src/JunctionTree.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,16 @@ end
205205
206206
Build the whole tree in batch format.
207207
"""
208-
function buildTree!(tree::BayesTree, dfg::G, elimorder::Array{Symbol,1}) where G <: AbstractDFG
209-
revorder = reverse(elimorder,dims=1) # flipdim(p, 1)
208+
function buildTree!(tree::BayesTree, dfg::AbstractDFG, elimorder::Array{Symbol,1})
209+
revorder = reverse(elimorder,dims=1) # flipdim(p, 1), fixing #499
210210
# prevVar = 0
211211
for var in revorder
212212
@info "Adding $var to tree..."
213213
newPotential(tree, dfg, var, elimorder)
214214
prevVar = var
215215
end
216+
217+
return tree
216218
end
217219

218220
"""

test/runtests.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ end
4040

4141
include("testBasicForwardConvolve.jl")
4242

43-
4443
include("testFactorMetadata.jl")
4544

45+
include("testJunctionTreeConstruction.jl")
46+
4647
include("testBasicCSM.jl")
4748

4849
include("testCliqueFactors.jl")

test/testBasicGraphs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ tree, smt, hist = solveTree!(fg)
106106
# check mean and covariance -- should be zero
107107
@test abs((getKDE(fg, :x0) |> getKDEMean)[1] + 1000) < 0.6
108108
# should be sqrt(1/2) = 0.707 -- computation results nearer 0.7.
109-
@test 0.3 < Statistics.cov( getPoints(getKDE(fg, :x0))[1,:] ) < 1
109+
@test 0.2 < Statistics.cov( getPoints(getKDE(fg, :x0))[1,:] ) < 1
110110

111111
end
112112

test/testJunctionTree2.jl

Lines changed: 0 additions & 55 deletions
This file was deleted.

test/testJunctionTreeConstruction.jl

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# another tree test
2+
3+
using IncrementalInference
4+
using Test
5+
6+
7+
@testset "Variable ordering Bayes tree member check." begin
8+
9+
fg = loadCanonicalFG_Kaess()
10+
# Choose specific variable ordering and perform check.
11+
vo = [:l1, :l2, :x1, :x2, :x3]
12+
tree = buildTreeFromOrdering!(fg, vo)
13+
@test vo == tree.variableOrder
14+
@test vo == getVariableOrder(tree)
15+
@test vo == getEliminationOrder(tree)
16+
17+
end
18+
19+
@testset "Test Caesar Ring 1D symbolic tree construction" begin
20+
21+
fg = loadCanonicalFG_CaesarRing1D()
22+
# drawGraph(fg, show=true)
23+
24+
eo = [:x0;:x2;:x4;:x6;:x1;:l1;:x5;:x3;]
25+
26+
tree = buildTreeFromOrdering!(fg,eo)
27+
drawTree(tree, show=true)
28+
29+
@test length(tree.cliques) == 6
30+
31+
C0 = getCliq(tree, :x3)
32+
@test intersect( C0 |> getFrontals, [:x3; :x5; :l1]) |> length == 3
33+
@test C0 |> getCliqSeparatorVarIds |> length == 0
34+
35+
cC0 = getChildren(tree, C0)
36+
@test cC0 |> length == 3
37+
38+
C1 = getCliq(tree, :x1)
39+
@test C1 in cC0
40+
@test C1 |> getFrontals == [:x1;]
41+
@test intersect(C1 |> getCliqSeparatorVarIds, [:x3;:l1]) |> length == 2
42+
43+
cC1 = getChildren(tree, C1)
44+
@test cC1 |> length == 2
45+
46+
C4 = getCliq(tree, :x2)
47+
@test C4 in cC1
48+
@test C4 |> getFrontals == [:x2;]
49+
@test intersect(C4 |> getCliqSeparatorVarIds, [:x3;:x1]) |> length == 2
50+
51+
C5 = getCliq(tree, :x0)
52+
@test C5 in cC1
53+
@test C5 |> getFrontals == [:x0;]
54+
@test intersect(C5 |> getCliqSeparatorVarIds, [:l1;:x1]) |> length == 2
55+
56+
C2 = getCliq(tree, :x6)
57+
@test C2 in cC0
58+
@test C2 |> getFrontals == [:x6;]
59+
@test intersect(C2 |> getCliqSeparatorVarIds, [:l1;:x5]) |> length == 2
60+
61+
C3 = getCliq(tree, :x4)
62+
@test C3 in cC0
63+
@test C3 |> getFrontals == [:x4;]
64+
@test intersect(C3 |> getCliqSeparatorVarIds, [:x3;:x5]) |> length == 2
65+
66+
end
67+
68+
69+
@testset "Test tree formation and consistent APIs" begin
70+
71+
fg = loadCanonicalFG_TestSymbolic()
72+
73+
#writeGraphPdf(fg, show=true)
74+
75+
eo = [:x1; :l3; :l1; :x5; :x2; :l2; :x4; :x3]
76+
77+
tree = buildTreeFromOrdering!(fg,eo)
78+
# drawTree(tree, show=true)
79+
80+
@warn "TODO, complete further testing on tree formation"
81+
82+
83+
## test variable order APIs consistent, see issue 499
84+
85+
vo = getEliminationOrder(fg)
86+
tree1 = resetBuildTreeFromOrder!(fg, vo)
87+
# drawTree(tree1, show=true)
88+
89+
tree2 = wipeBuildNewTree!(fg)
90+
# drawTree(tree2, show=true)
91+
92+
@test getVariableOrder(tree1) == getVariableOrder(tree1)
93+
94+
end
95+
96+
97+
98+
99+
100+
101+
#

0 commit comments

Comments
 (0)