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] }