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  }