gonum.org/v1/gonum@v0.14.0/graph/network/hits_test.go (about) 1 // Copyright ©2015 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 network 6 7 import ( 8 "fmt" 9 "math" 10 "sort" 11 "testing" 12 13 "gonum.org/v1/gonum/floats/scalar" 14 "gonum.org/v1/gonum/graph/simple" 15 ) 16 17 var hitsTests = []struct { 18 g []set 19 tol float64 20 21 wantTol float64 22 want map[int64]HubAuthority 23 }{ 24 { 25 // Example graph from http://www.cis.hut.fi/Opinnot/T-61.6020/2008/pagerank_hits.pdf page 8. 26 g: []set{ 27 A: linksTo(B, C, D), 28 B: linksTo(C, D), 29 C: linksTo(B), 30 D: nil, 31 }, 32 tol: 1e-4, 33 34 wantTol: 1e-4, 35 want: map[int64]HubAuthority{ 36 A: {Hub: 0.7887, Authority: 0}, 37 B: {Hub: 0.5774, Authority: 0.4597}, 38 C: {Hub: 0.2113, Authority: 0.6280}, 39 D: {Hub: 0, Authority: 0.6280}, 40 }, 41 }, 42 } 43 44 func TestHITS(t *testing.T) { 45 for i, test := range hitsTests { 46 g := simple.NewDirectedGraph() 47 for u, e := range test.g { 48 // Add nodes that are not defined by an edge. 49 if g.Node(int64(u)) == nil { 50 g.AddNode(simple.Node(u)) 51 } 52 for v := range e { 53 g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) 54 } 55 } 56 got := HITS(g, test.tol) 57 prec := 1 - int(math.Log10(test.wantTol)) 58 for n := range test.g { 59 if !scalar.EqualWithinAbsOrRel(got[int64(n)].Hub, test.want[int64(n)].Hub, test.wantTol, test.wantTol) { 60 t.Errorf("unexpected HITS result for test %d:\ngot: %v\nwant:%v", 61 i, orderedHubAuth(got, prec), orderedHubAuth(test.want, prec)) 62 break 63 } 64 if !scalar.EqualWithinAbsOrRel(got[int64(n)].Authority, test.want[int64(n)].Authority, test.wantTol, test.wantTol) { 65 t.Errorf("unexpected HITS result for test %d:\ngot: %v\nwant:%v", 66 i, orderedHubAuth(got, prec), orderedHubAuth(test.want, prec)) 67 break 68 } 69 } 70 } 71 } 72 73 func orderedHubAuth(w map[int64]HubAuthority, prec int) []keyHubAuthVal { 74 o := make(orderedHubAuthMap, 0, len(w)) 75 for k, v := range w { 76 o = append(o, keyHubAuthVal{prec: prec, key: k, val: v}) 77 } 78 sort.Sort(o) 79 return o 80 } 81 82 type keyHubAuthVal struct { 83 prec int 84 key int64 85 val HubAuthority 86 } 87 88 func (kv keyHubAuthVal) String() string { 89 return fmt.Sprintf("%d:{H:%.*f, A:%.*f}", 90 kv.key, kv.prec, kv.val.Hub, kv.prec, kv.val.Authority, 91 ) 92 } 93 94 type orderedHubAuthMap []keyHubAuthVal 95 96 func (o orderedHubAuthMap) Len() int { return len(o) } 97 func (o orderedHubAuthMap) Less(i, j int) bool { return o[i].key < o[j].key } 98 func (o orderedHubAuthMap) Swap(i, j int) { o[i], o[j] = o[j], o[i] }