all: make tests pass when -count is greater than 1

Tests run repeatedly do not reinitialise state, meaning that a second run
of the tests will have leftover state from the previous run. This ensures
that repeated runs are identical with the exception of map iteration order.
This commit is contained in:
Dan Kortschak
2022-08-06 10:16:11 +09:30
parent aedb59a6f6
commit a4dda6a99c
6 changed files with 769 additions and 766 deletions

View File

@@ -17,113 +17,113 @@ type graphBuilder interface {
graph.Builder graph.Builder
} }
var copyTests = []struct {
desc string
src graph.Graph
dst graphBuilder
// If want is nil, compare to src.
want graph.Graph
}{
{
desc: "undirected to undirected",
src: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewUndirectedGraph(),
},
{
desc: "undirected to directed",
src: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewDirectedGraph(),
want: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
// want is a directed graph copied from
// an undirected graph so we need to have
// all edges in both directions.
g.SetEdge(e)
e.T, e.F = e.F, e.T
g.SetEdge(e)
}
return g
}(),
},
{
desc: "directed to undirected",
src: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewUndirectedGraph(),
want: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
},
{
desc: "directed to directed",
src: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewDirectedGraph(),
},
}
func TestCopy(t *testing.T) { func TestCopy(t *testing.T) {
copyTests := []struct {
desc string
src graph.Graph
dst graphBuilder
// If want is nil, compare to src.
want graph.Graph
}{
{
desc: "undirected to undirected",
src: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewUndirectedGraph(),
},
{
desc: "undirected to directed",
src: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewDirectedGraph(),
want: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
// want is a directed graph copied from
// an undirected graph so we need to have
// all edges in both directions.
g.SetEdge(e)
e.T, e.F = e.F, e.T
g.SetEdge(e)
}
return g
}(),
},
{
desc: "directed to undirected",
src: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewUndirectedGraph(),
want: func() graph.Graph {
g := simple.NewUndirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
},
{
desc: "directed to directed",
src: func() graph.Graph {
g := simple.NewDirectedGraph()
g.AddNode(simple.Node(-1))
for _, e := range []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
} {
g.SetEdge(e)
}
return g
}(),
dst: simple.NewDirectedGraph(),
},
}
for _, test := range copyTests { for _, test := range copyTests {
graph.Copy(test.dst, test.src) graph.Copy(test.dst, test.src)
want := test.want want := test.want
@@ -141,113 +141,113 @@ type graphWeightedBuilder interface {
graph.WeightedBuilder graph.WeightedBuilder
} }
var copyWeightedTests = []struct {
desc string
src graph.Weighted
dst graphWeightedBuilder
// If want is nil, compare to src.
want graph.Graph
}{
{
desc: "undirected to undirected",
src: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedUndirectedGraph(0, 0),
},
{
desc: "undirected to directed",
src: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedDirectedGraph(0, 0),
want: func() graph.Graph {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
// want is a directed graph copied from
// an undirected graph so we need to have
// all edges in both directions.
g.SetWeightedEdge(e)
e.T, e.F = e.F, e.T
g.SetWeightedEdge(e)
}
return g
}(),
},
{
desc: "directed to undirected",
src: func() graph.Weighted {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedUndirectedGraph(0, 0),
want: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
},
{
desc: "directed to directed",
src: func() graph.Weighted {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedDirectedGraph(0, 0),
},
}
func TestCopyWeighted(t *testing.T) { func TestCopyWeighted(t *testing.T) {
copyWeightedTests := []struct {
desc string
src graph.Weighted
dst graphWeightedBuilder
// If want is nil, compare to src.
want graph.Graph
}{
{
desc: "undirected to undirected",
src: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedUndirectedGraph(0, 0),
},
{
desc: "undirected to directed",
src: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedDirectedGraph(0, 0),
want: func() graph.Graph {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
// want is a directed graph copied from
// an undirected graph so we need to have
// all edges in both directions.
g.SetWeightedEdge(e)
e.T, e.F = e.F, e.T
g.SetWeightedEdge(e)
}
return g
}(),
},
{
desc: "directed to undirected",
src: func() graph.Weighted {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedUndirectedGraph(0, 0),
want: func() graph.Weighted {
g := simple.NewWeightedUndirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
},
{
desc: "directed to directed",
src: func() graph.Weighted {
g := simple.NewWeightedDirectedGraph(0, 0)
g.AddNode(simple.Node(-1))
for _, e := range []simple.WeightedEdge{
{F: simple.Node(0), T: simple.Node(1), W: 1},
{F: simple.Node(0), T: simple.Node(3), W: 1},
{F: simple.Node(1), T: simple.Node(2), W: 1},
} {
g.SetWeightedEdge(e)
}
return g
}(),
dst: simple.NewWeightedDirectedGraph(0, 0),
},
}
for _, test := range copyWeightedTests { for _, test := range copyWeightedTests {
graph.CopyWeighted(test.dst, test.src) graph.CopyWeighted(test.dst, test.src)
want := test.want want := test.want

View File

@@ -19,184 +19,184 @@ import (
. "gonum.org/v1/gonum/graph/layout" . "gonum.org/v1/gonum/graph/layout"
) )
var eadesR2Tests = []struct {
name string
g graph.Graph
param EadesR2
wantIters int
}{
{
name: "line",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "square",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "tetrahedron",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "sheet",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "tube",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
// This test does not produce a good layout, but is here to
// ensure that Update does not panic with steep decent rates.
name: "tube-steep",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 99,
},
{
name: "wp_page", // https://en.wikipedia.org/wiki/PageRank#/media/File:PageRanks-Example.jpg
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(1), T: simple.Node(5)},
{F: simple.Node(1), T: simple.Node(6)},
{F: simple.Node(1), T: simple.Node(7)},
{F: simple.Node(1), T: simple.Node(8)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(4), T: simple.Node(8)},
{F: simple.Node(4), T: simple.Node(9)},
{F: simple.Node(4), T: simple.Node(10)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
}
func TestEadesR2(t *testing.T) { func TestEadesR2(t *testing.T) {
eadesR2Tests := []struct {
name string
g graph.Graph
param EadesR2
wantIters int
}{
{
name: "line",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "square",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "tetrahedron",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "sheet",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
name: "tube",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
{
// This test does not produce a good layout, but is here to
// ensure that Update does not panic with steep decent rates.
name: "tube-steep",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 99,
},
{
name: "wp_page", // https://en.wikipedia.org/wiki/PageRank#/media/File:PageRanks-Example.jpg
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(1), T: simple.Node(5)},
{F: simple.Node(1), T: simple.Node(6)},
{F: simple.Node(1), T: simple.Node(7)},
{F: simple.Node(1), T: simple.Node(8)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(4), T: simple.Node(8)},
{F: simple.Node(4), T: simple.Node(9)},
{F: simple.Node(4), T: simple.Node(10)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
param: EadesR2{Repulsion: 1, Rate: 0.1, Updates: 100, Theta: 0.1, Src: rand.NewSource(1)},
wantIters: 100,
},
}
for _, test := range eadesR2Tests { for _, test := range eadesR2Tests {
eades := test.param eades := test.param
o := NewOptimizerR2(test.g, eades.Update) o := NewOptimizerR2(test.g, eades.Update)

View File

@@ -28,138 +28,138 @@ var (
arch string arch string
) )
var isomapR2Tests = []struct {
name string
g graph.Graph
}{
{
name: "line_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "square_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "tetrahedron_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "sheet_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "tube_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "wp_page_isomap", // https://en.wikipedia.org/wiki/PageRank#/media/File:PageRanks-Example.jpg
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(1), T: simple.Node(5)},
{F: simple.Node(1), T: simple.Node(6)},
{F: simple.Node(1), T: simple.Node(7)},
{F: simple.Node(1), T: simple.Node(8)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(4), T: simple.Node(8)},
{F: simple.Node(4), T: simple.Node(9)},
{F: simple.Node(4), T: simple.Node(10)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
}
func TestIsomapR2(t *testing.T) { func TestIsomapR2(t *testing.T) {
isomapR2Tests := []struct {
name string
g graph.Graph
}{
{
name: "line_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "square_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "tetrahedron_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(2), T: simple.Node(3)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "sheet_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "tube_isomap",
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(1)},
{F: simple.Node(0), T: simple.Node(2)},
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(2), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(3), T: simple.Node(5)},
{F: simple.Node(3), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(5), T: simple.Node(8)},
{F: simple.Node(6), T: simple.Node(7)},
{F: simple.Node(6), T: simple.Node(8)},
{F: simple.Node(7), T: simple.Node(8)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
{
name: "wp_page_isomap", // https://en.wikipedia.org/wiki/PageRank#/media/File:PageRanks-Example.jpg
g: func() graph.Graph {
edges := []simple.Edge{
{F: simple.Node(0), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(2)},
{F: simple.Node(1), T: simple.Node(3)},
{F: simple.Node(1), T: simple.Node(4)},
{F: simple.Node(1), T: simple.Node(5)},
{F: simple.Node(1), T: simple.Node(6)},
{F: simple.Node(1), T: simple.Node(7)},
{F: simple.Node(1), T: simple.Node(8)},
{F: simple.Node(3), T: simple.Node(4)},
{F: simple.Node(4), T: simple.Node(5)},
{F: simple.Node(4), T: simple.Node(6)},
{F: simple.Node(4), T: simple.Node(7)},
{F: simple.Node(4), T: simple.Node(8)},
{F: simple.Node(4), T: simple.Node(9)},
{F: simple.Node(4), T: simple.Node(10)},
}
g := simple.NewUndirectedGraph()
for _, e := range edges {
g.SetEdge(e)
}
return orderedGraph{g}
}(),
},
}
for _, test := range isomapR2Tests { for _, test := range isomapR2Tests {
o := NewOptimizerR2(test.g, IsomapR2{}.Update) o := NewOptimizerR2(test.g, IsomapR2{}.Update)
var n int var n int

View File

@@ -21,48 +21,48 @@ import (
// weightedlines // weightedlines
// empty // empty
var nodesOfTests = []struct {
name string
nodes graph.Nodes
want []graph.Node
}{
{
name: "nil",
nodes: nil,
want: nil,
},
{
name: "empty",
nodes: graph.Empty,
want: nil,
},
{
name: "no nodes",
nodes: iterator.NewOrderedNodes(nil),
want: nil,
},
{
name: "implicit nodes",
nodes: iterator.NewImplicitNodes(-1, 4, func(id int) graph.Node { return simple.Node(id) }),
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
{
name: "no slice method",
nodes: basicNodes{iterator.NewOrderedNodes([]graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)})},
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
{
name: "explicit nodes",
nodes: iterator.NewOrderedNodes([]graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)}),
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
}
type basicNodes struct { type basicNodes struct {
graph.Nodes graph.Nodes
} }
func TestNodesOf(t *testing.T) { func TestNodesOf(t *testing.T) {
nodesOfTests := []struct {
name string
nodes graph.Nodes
want []graph.Node
}{
{
name: "nil",
nodes: nil,
want: nil,
},
{
name: "empty",
nodes: graph.Empty,
want: nil,
},
{
name: "no nodes",
nodes: iterator.NewOrderedNodes(nil),
want: nil,
},
{
name: "implicit nodes",
nodes: iterator.NewImplicitNodes(-1, 4, func(id int) graph.Node { return simple.Node(id) }),
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
{
name: "no slice method",
nodes: basicNodes{iterator.NewOrderedNodes([]graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)})},
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
{
name: "explicit nodes",
nodes: iterator.NewOrderedNodes([]graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)}),
want: []graph.Node{simple.Node(-1), simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3)},
},
}
for _, test := range nodesOfTests { for _, test := range nodesOfTests {
got := graph.NodesOf(test.nodes) got := graph.NodesOf(test.nodes)
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {
@@ -71,59 +71,59 @@ func TestNodesOf(t *testing.T) {
} }
} }
var edgesOfTests = []struct {
name string
edges graph.Edges
want []graph.Edge
}{
{
name: "nil",
edges: nil,
want: nil,
},
{
name: "empty",
edges: graph.Empty,
want: nil,
},
{
name: "no edges",
edges: iterator.NewOrderedEdges(nil),
want: nil,
},
{
name: "no slice method",
edges: basicEdges{iterator.NewOrderedEdges([]graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
})},
want: []graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
},
},
{
name: "explicit edges",
edges: iterator.NewOrderedEdges([]graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
}),
want: []graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
},
},
}
type basicEdges struct { type basicEdges struct {
graph.Edges graph.Edges
} }
func TestEdgesOf(t *testing.T) { func TestEdgesOf(t *testing.T) {
edgesOfTests := []struct {
name string
edges graph.Edges
want []graph.Edge
}{
{
name: "nil",
edges: nil,
want: nil,
},
{
name: "empty",
edges: graph.Empty,
want: nil,
},
{
name: "no edges",
edges: iterator.NewOrderedEdges(nil),
want: nil,
},
{
name: "no slice method",
edges: basicEdges{iterator.NewOrderedEdges([]graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
})},
want: []graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
},
},
{
name: "explicit edges",
edges: iterator.NewOrderedEdges([]graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
}),
want: []graph.Edge{
simple.Edge{F: simple.Node(-1), T: simple.Node(0)},
simple.Edge{F: simple.Node(1), T: simple.Node(2)},
simple.Edge{F: simple.Node(3), T: simple.Node(4)},
},
},
}
for _, test := range edgesOfTests { for _, test := range edgesOfTests {
got := graph.EdgesOf(test.edges) got := graph.EdgesOf(test.edges)
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {
@@ -132,59 +132,59 @@ func TestEdgesOf(t *testing.T) {
} }
} }
var weightedEdgesOfTests = []struct {
name string
edges graph.WeightedEdges
want []graph.WeightedEdge
}{
{
name: "nil",
edges: nil,
want: nil,
},
{
name: "empty",
edges: graph.Empty,
want: nil,
},
{
name: "no edges",
edges: iterator.NewOrderedWeightedEdges(nil),
want: nil,
},
{
name: "no slice method",
edges: basicWeightedEdges{iterator.NewOrderedWeightedEdges([]graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
})},
want: []graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
},
},
{
name: "explicit edges",
edges: iterator.NewOrderedWeightedEdges([]graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
}),
want: []graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
},
},
}
type basicWeightedEdges struct { type basicWeightedEdges struct {
graph.WeightedEdges graph.WeightedEdges
} }
func TestWeightedEdgesOf(t *testing.T) { func TestWeightedEdgesOf(t *testing.T) {
weightedEdgesOfTests := []struct {
name string
edges graph.WeightedEdges
want []graph.WeightedEdge
}{
{
name: "nil",
edges: nil,
want: nil,
},
{
name: "empty",
edges: graph.Empty,
want: nil,
},
{
name: "no edges",
edges: iterator.NewOrderedWeightedEdges(nil),
want: nil,
},
{
name: "no slice method",
edges: basicWeightedEdges{iterator.NewOrderedWeightedEdges([]graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
})},
want: []graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
},
},
{
name: "explicit edges",
edges: iterator.NewOrderedWeightedEdges([]graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
}),
want: []graph.WeightedEdge{
simple.WeightedEdge{F: simple.Node(-1), T: simple.Node(0), W: 1},
simple.WeightedEdge{F: simple.Node(1), T: simple.Node(2), W: 2},
simple.WeightedEdge{F: simple.Node(3), T: simple.Node(4), W: 3},
},
},
}
for _, test := range weightedEdgesOfTests { for _, test := range weightedEdgesOfTests {
got := graph.WeightedEdgesOf(test.edges) got := graph.WeightedEdgesOf(test.edges)
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {
@@ -193,59 +193,59 @@ func TestWeightedEdgesOf(t *testing.T) {
} }
} }
var linesOfTests = []struct {
name string
lines graph.Lines
want []graph.Line
}{
{
name: "nil",
lines: nil,
want: nil,
},
{
name: "empty",
lines: graph.Empty,
want: nil,
},
{
name: "no edges",
lines: iterator.NewOrderedLines(nil),
want: nil,
},
{
name: "no slice method",
lines: basicLines{iterator.NewOrderedLines([]graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
})},
want: []graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
},
},
{
name: "explicit edges",
lines: iterator.NewOrderedLines([]graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
}),
want: []graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
},
},
}
type basicLines struct { type basicLines struct {
graph.Lines graph.Lines
} }
func TestLinesOf(t *testing.T) { func TestLinesOf(t *testing.T) {
linesOfTests := []struct {
name string
lines graph.Lines
want []graph.Line
}{
{
name: "nil",
lines: nil,
want: nil,
},
{
name: "empty",
lines: graph.Empty,
want: nil,
},
{
name: "no edges",
lines: iterator.NewOrderedLines(nil),
want: nil,
},
{
name: "no slice method",
lines: basicLines{iterator.NewOrderedLines([]graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
})},
want: []graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
},
},
{
name: "explicit edges",
lines: iterator.NewOrderedLines([]graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
}),
want: []graph.Line{
multi.Line{F: multi.Node(-1), T: multi.Node(0), UID: -1},
multi.Line{F: multi.Node(1), T: multi.Node(2), UID: 0},
multi.Line{F: multi.Node(3), T: multi.Node(4), UID: 1},
},
},
}
for _, test := range linesOfTests { for _, test := range linesOfTests {
got := graph.LinesOf(test.lines) got := graph.LinesOf(test.lines)
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {
@@ -254,59 +254,59 @@ func TestLinesOf(t *testing.T) {
} }
} }
var weightedLinesOfTests = []struct {
name string
lines graph.WeightedLines
want []graph.WeightedLine
}{
{
name: "nil",
lines: nil,
want: nil,
},
{
name: "empty",
lines: graph.Empty,
want: nil,
},
{
name: "no edges",
lines: iterator.NewOrderedWeightedLines(nil),
want: nil,
},
{
name: "no slice method",
lines: basicWeightedLines{iterator.NewOrderedWeightedLines([]graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
})},
want: []graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
},
},
{
name: "explicit edges",
lines: iterator.NewOrderedWeightedLines([]graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
}),
want: []graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
},
},
}
type basicWeightedLines struct { type basicWeightedLines struct {
graph.WeightedLines graph.WeightedLines
} }
func TestWeightedLinesOf(t *testing.T) { func TestWeightedLinesOf(t *testing.T) {
weightedLinesOfTests := []struct {
name string
lines graph.WeightedLines
want []graph.WeightedLine
}{
{
name: "nil",
lines: nil,
want: nil,
},
{
name: "empty",
lines: graph.Empty,
want: nil,
},
{
name: "no edges",
lines: iterator.NewOrderedWeightedLines(nil),
want: nil,
},
{
name: "no slice method",
lines: basicWeightedLines{iterator.NewOrderedWeightedLines([]graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
})},
want: []graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
},
},
{
name: "explicit edges",
lines: iterator.NewOrderedWeightedLines([]graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
}),
want: []graph.WeightedLine{
multi.WeightedLine{F: multi.Node(-1), T: multi.Node(0), W: 1, UID: -1},
multi.WeightedLine{F: multi.Node(1), T: multi.Node(2), W: 2, UID: 0},
multi.WeightedLine{F: multi.Node(3), T: multi.Node(4), W: 3, UID: 1},
},
},
}
for _, test := range weightedLinesOfTests { for _, test := range weightedLinesOfTests {
got := graph.WeightedLinesOf(test.lines) got := graph.WeightedLinesOf(test.lines)
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {

View File

@@ -163,11 +163,12 @@ func TestMetropolisHastings(t *testing.T) {
compareNormal(t, target, batch, nil, 5e-1, 5e-1) compareNormal(t, target, batch, nil, 5e-1, 5e-1)
} }
// randomNormal constructs a random Normal distribution. // randomNormal constructs a random Normal distribution using the provided
// random source.
func randomNormal(dim int, src *rand.Rand) (*distmv.Normal, bool) { func randomNormal(dim int, src *rand.Rand) (*distmv.Normal, bool) {
data := make([]float64, dim*dim) data := make([]float64, dim*dim)
for i := range data { for i := range data {
data[i] = rand.Float64() data[i] = src.Float64()
} }
a := mat.NewDense(dim, dim, data) a := mat.NewDense(dim, dim, data)
var sigma mat.SymDense var sigma mat.SymDense
@@ -180,6 +181,8 @@ func randomNormal(dim int, src *rand.Rand) (*distmv.Normal, bool) {
} }
func compareNormal(t *testing.T, want *distmv.Normal, batch *mat.Dense, weights []float64, meanTol, covTol float64) { func compareNormal(t *testing.T, want *distmv.Normal, batch *mat.Dense, weights []float64, meanTol, covTol float64) {
t.Helper()
dim := want.Dim() dim := want.Dim()
mu := want.Mean(nil) mu := want.Mean(nil)
var sigma mat.SymDense var sigma mat.SymDense
@@ -224,10 +227,11 @@ func TestMetropolisHastingser(t *testing.T) {
{3, 103, 11, 51}, {3, 103, 11, 51},
{3, 103, 51, 11}, {3, 103, 51, 11},
} { } {
src := rand.New(rand.NewSource(1))
dim := test.dim dim := test.dim
initial := make([]float64, dim) initial := make([]float64, dim)
target, ok := randomNormal(dim, nil) target, ok := randomNormal(dim, src)
if !ok { if !ok {
t.Fatal("bad test, sigma not pos def") t.Fatal("bad test, sigma not pos def")
} }
@@ -239,7 +243,7 @@ func TestMetropolisHastingser(t *testing.T) {
// Test the Metropolis Hastingser by generating all the samples, then generating // Test the Metropolis Hastingser by generating all the samples, then generating
// the same samples with a burnin and rate. // the same samples with a burnin and rate.
src := rand.New(rand.NewSource(1)) src = rand.New(rand.NewSource(1))
proposal, ok := NewProposalNormal(sigmaImp, src) proposal, ok := NewProposalNormal(sigmaImp, src)
if !ok { if !ok {
t.Fatal("bad test, sigma not pos def") t.Fatal("bad test, sigma not pos def")

View File

@@ -185,20 +185,19 @@ func TestDimensionEquality(t *testing.T) {
} }
} }
var operationTests = []struct {
recvOp func(Uniter) *Unit
param Uniter
want Uniter
}{
{Dimless(1).Unit().Add, Dimless(2), Dimless(3)},
{Dimless(1).Unit().Mul, Dimless(2), Dimless(2)},
{Dimless(1).Unit().Mul, Length(2), Length(2)},
{Length(1).Unit().Mul, Dimless(2), Length(2)},
{Dimless(1).Unit().Div, Length(2), New(0.5, Dimensions{LengthDim: -1})},
{Length(1).Unit().Div, Dimless(2), Length(0.5)},
}
func TestOperations(t *testing.T) { func TestOperations(t *testing.T) {
operationTests := []struct {
recvOp func(Uniter) *Unit
param Uniter
want Uniter
}{
{Dimless(1).Unit().Add, Dimless(2), Dimless(3)},
{Dimless(1).Unit().Mul, Dimless(2), Dimless(2)},
{Dimless(1).Unit().Mul, Length(2), Length(2)},
{Length(1).Unit().Mul, Dimless(2), Length(2)},
{Dimless(1).Unit().Div, Length(2), New(0.5, Dimensions{LengthDim: -1})},
{Length(1).Unit().Div, Dimless(2), Length(0.5)},
}
t.Parallel() t.Parallel()
for i, test := range operationTests { for i, test := range operationTests {
var got Uniter var got Uniter