mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 23:52:47 +08:00
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:
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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")
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user