mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 23:26:52 +08:00

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.
190 lines
5.1 KiB
Go
190 lines
5.1 KiB
Go
// Copyright ©2019 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package layout_test
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"gonum.org/v1/gonum/graph"
|
|
"gonum.org/v1/gonum/graph/simple"
|
|
"gonum.org/v1/gonum/spatial/r2"
|
|
"gonum.org/v1/plot"
|
|
"gonum.org/v1/plot/vg"
|
|
|
|
. "gonum.org/v1/gonum/graph/layout"
|
|
)
|
|
|
|
var (
|
|
// tag is modified in isomap_noasm_test.go to "_noasm" when any
|
|
// build tag prevents use of the assembly numerical kernels.
|
|
tag string
|
|
|
|
// arch is modified in isomap_arm64_test.go to "_arm64" on arm64
|
|
// and "_386" on 386 to allow differences in numerical precision
|
|
// to be allowed for.
|
|
arch string
|
|
)
|
|
|
|
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 {
|
|
o := NewOptimizerR2(test.g, IsomapR2{}.Update)
|
|
var n int
|
|
for o.Update() {
|
|
n++
|
|
}
|
|
p := plot.New()
|
|
p.Add(render{o})
|
|
p.HideAxes()
|
|
path := filepath.Join("testdata", test.name+tag+arch+".png")
|
|
err := p.Save(10*vg.Centimeter, 10*vg.Centimeter, path)
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
continue
|
|
}
|
|
ok := checkRenderedLayout(t, path)
|
|
if !ok {
|
|
got := make(map[int64]r2.Vec)
|
|
nodes := test.g.Nodes()
|
|
for nodes.Next() {
|
|
id := nodes.Node().ID()
|
|
got[id] = o.Coord2(id)
|
|
}
|
|
t.Logf("got node positions: %#v", got)
|
|
}
|
|
}
|
|
}
|