gonum.org/v1/gonum@v0.14.0/graph/layout/isomap_test.go (about) 1 // Copyright ©2019 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package layout_test 6 7 import ( 8 "path/filepath" 9 "testing" 10 11 "gonum.org/v1/gonum/graph" 12 "gonum.org/v1/gonum/graph/simple" 13 "gonum.org/v1/gonum/spatial/r2" 14 "gonum.org/v1/plot" 15 "gonum.org/v1/plot/vg" 16 17 . "gonum.org/v1/gonum/graph/layout" 18 ) 19 20 var ( 21 // tag is modified in isomap_noasm_test.go to "_noasm" when any 22 // build tag prevents use of the assembly numerical kernels. 23 tag string 24 25 // arch is modified in isomap_arm64_test.go to "_arm64" on arm64 26 // and "_386" on 386 to allow differences in numerical precision 27 // to be allowed for. 28 arch string 29 ) 30 31 func TestIsomapR2(t *testing.T) { 32 isomapR2Tests := []struct { 33 name string 34 g graph.Graph 35 }{ 36 { 37 name: "line_isomap", 38 g: func() graph.Graph { 39 edges := []simple.Edge{ 40 {F: simple.Node(0), T: simple.Node(1)}, 41 } 42 g := simple.NewUndirectedGraph() 43 for _, e := range edges { 44 g.SetEdge(e) 45 } 46 return orderedGraph{g} 47 }(), 48 }, 49 { 50 name: "square_isomap", 51 g: func() graph.Graph { 52 edges := []simple.Edge{ 53 {F: simple.Node(0), T: simple.Node(1)}, 54 {F: simple.Node(0), T: simple.Node(2)}, 55 {F: simple.Node(1), T: simple.Node(3)}, 56 {F: simple.Node(2), T: simple.Node(3)}, 57 } 58 g := simple.NewUndirectedGraph() 59 for _, e := range edges { 60 g.SetEdge(e) 61 } 62 return orderedGraph{g} 63 }(), 64 }, 65 { 66 name: "tetrahedron_isomap", 67 g: func() graph.Graph { 68 edges := []simple.Edge{ 69 {F: simple.Node(0), T: simple.Node(1)}, 70 {F: simple.Node(0), T: simple.Node(2)}, 71 {F: simple.Node(0), T: simple.Node(3)}, 72 {F: simple.Node(1), T: simple.Node(2)}, 73 {F: simple.Node(1), T: simple.Node(3)}, 74 {F: simple.Node(2), T: simple.Node(3)}, 75 } 76 g := simple.NewUndirectedGraph() 77 for _, e := range edges { 78 g.SetEdge(e) 79 } 80 return orderedGraph{g} 81 }(), 82 }, 83 { 84 name: "sheet_isomap", 85 g: func() graph.Graph { 86 edges := []simple.Edge{ 87 {F: simple.Node(0), T: simple.Node(1)}, 88 {F: simple.Node(0), T: simple.Node(3)}, 89 {F: simple.Node(1), T: simple.Node(2)}, 90 {F: simple.Node(1), T: simple.Node(4)}, 91 {F: simple.Node(2), T: simple.Node(5)}, 92 {F: simple.Node(3), T: simple.Node(4)}, 93 {F: simple.Node(3), T: simple.Node(6)}, 94 {F: simple.Node(4), T: simple.Node(5)}, 95 {F: simple.Node(4), T: simple.Node(7)}, 96 {F: simple.Node(5), T: simple.Node(8)}, 97 {F: simple.Node(6), T: simple.Node(7)}, 98 {F: simple.Node(7), T: simple.Node(8)}, 99 } 100 g := simple.NewUndirectedGraph() 101 for _, e := range edges { 102 g.SetEdge(e) 103 } 104 return orderedGraph{g} 105 }(), 106 }, 107 { 108 name: "tube_isomap", 109 g: func() graph.Graph { 110 edges := []simple.Edge{ 111 {F: simple.Node(0), T: simple.Node(1)}, 112 {F: simple.Node(0), T: simple.Node(2)}, 113 {F: simple.Node(0), T: simple.Node(3)}, 114 {F: simple.Node(1), T: simple.Node(2)}, 115 {F: simple.Node(1), T: simple.Node(4)}, 116 {F: simple.Node(2), T: simple.Node(5)}, 117 {F: simple.Node(3), T: simple.Node(4)}, 118 {F: simple.Node(3), T: simple.Node(5)}, 119 {F: simple.Node(3), T: simple.Node(6)}, 120 {F: simple.Node(4), T: simple.Node(5)}, 121 {F: simple.Node(4), T: simple.Node(7)}, 122 {F: simple.Node(5), T: simple.Node(8)}, 123 {F: simple.Node(6), T: simple.Node(7)}, 124 {F: simple.Node(6), T: simple.Node(8)}, 125 {F: simple.Node(7), T: simple.Node(8)}, 126 } 127 g := simple.NewUndirectedGraph() 128 for _, e := range edges { 129 g.SetEdge(e) 130 } 131 return orderedGraph{g} 132 }(), 133 }, 134 { 135 name: "wp_page_isomap", // https://en.wikipedia.org/wiki/PageRank#/media/File:PageRanks-Example.jpg 136 g: func() graph.Graph { 137 edges := []simple.Edge{ 138 {F: simple.Node(0), T: simple.Node(3)}, 139 {F: simple.Node(1), T: simple.Node(2)}, 140 {F: simple.Node(1), T: simple.Node(3)}, 141 {F: simple.Node(1), T: simple.Node(4)}, 142 {F: simple.Node(1), T: simple.Node(5)}, 143 {F: simple.Node(1), T: simple.Node(6)}, 144 {F: simple.Node(1), T: simple.Node(7)}, 145 {F: simple.Node(1), T: simple.Node(8)}, 146 {F: simple.Node(3), T: simple.Node(4)}, 147 {F: simple.Node(4), T: simple.Node(5)}, 148 {F: simple.Node(4), T: simple.Node(6)}, 149 {F: simple.Node(4), T: simple.Node(7)}, 150 {F: simple.Node(4), T: simple.Node(8)}, 151 {F: simple.Node(4), T: simple.Node(9)}, 152 {F: simple.Node(4), T: simple.Node(10)}, 153 } 154 g := simple.NewUndirectedGraph() 155 for _, e := range edges { 156 g.SetEdge(e) 157 } 158 return orderedGraph{g} 159 }(), 160 }, 161 } 162 163 for _, test := range isomapR2Tests { 164 o := NewOptimizerR2(test.g, IsomapR2{}.Update) 165 var n int 166 for o.Update() { 167 n++ 168 } 169 p := plot.New() 170 p.Add(render{o}) 171 p.HideAxes() 172 path := filepath.Join("testdata", test.name+tag+arch+".png") 173 err := p.Save(10*vg.Centimeter, 10*vg.Centimeter, path) 174 if err != nil { 175 t.Errorf("unexpected error: %v", err) 176 continue 177 } 178 ok := checkRenderedLayout(t, path) 179 if !ok { 180 got := make(map[int64]r2.Vec) 181 nodes := test.g.Nodes() 182 for nodes.Next() { 183 id := nodes.Node().ID() 184 got[id] = o.Coord2(id) 185 } 186 t.Logf("got node positions: %#v", got) 187 } 188 } 189 }