File Coverage

blib/lib/Graph/Similarity/CoupledNodeEdgeScoring.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Graph::Similarity::CoupledNodeEdgeScoring;
2              
3 1     1   1832 use strict;
  1         2  
  1         41  
4 1     1   5 use warnings;
  1         3  
  1         36  
5              
6 1     1   392 use Moose;
  0            
  0            
7             use Graph;
8             use Math::Matrix;
9              
10             our $VERSION = '0.02';
11              
12             with 'Graph::Similarity::Method';
13              
14             has 'graph' => (is => 'rw', isa => 'ArrayRef[Graph]', required => 1);
15             #has 'num_of_iteration' => (is => 'rw', isa => 'Int', default => 10);
16              
17             __PACKAGE__->meta->make_immutable;
18             no Moose;
19              
20             sub calculate {
21             my $self = shift;
22              
23             # Store similarity matrix $sim{vertex1}{vertex2}
24             my %sim;
25             my $itr = $self->num_of_iteration;
26             my $g = $self->graph;
27             my $g1 = $$g[0];
28             my $g2 = $$g[1];
29              
30             # Create Matrix
31             # for graph1
32             my $adj1 = Graph::BitMatrix->new($g1);
33             my @v1 = $adj1->vertices; # the sequence order is importanct. Keep this.
34             my %v1;
35             my @a1;
36             my $c1=0;
37             for my $v (@v1){
38             $v1{$v}= $c1++;
39             my @tmp = $adj1->get_row($v, @v1);
40             push @a1, \@tmp;
41             }
42             my $m1 = new Math::Matrix(@a1);
43              
44             # for graph2
45             my $adj2 = Graph::BitMatrix->new($g2);
46             my @v2 = $adj2->vertices;
47             my %v2;
48             my @a2;
49             my $c2=0;
50             for my $v (@v2){
51             $v2{$v}= $c2++;
52             my @tmp = $adj2->get_row($v, @v2);
53             push @a2, \@tmp;
54             }
55             my $m2 = new Math::Matrix(@a2);
56              
57             # for initial z = 1
58             my @z;
59             for my $v2 (@v2){
60             my @tmp;
61             for my $v1 (@v1){
62             push @tmp, 1;
63             }
64             push @z, \@tmp;
65             }
66             my $z = new Math::Matrix(@z);
67              
68             # loop should be even count
69             $itr++ unless ($itr%2 == 0);
70              
71             for (my $i=0; $i<$itr;$i++){
72              
73             # B * Z * A^T
74             my $tmp1 = $m2->multiply($z)->multiply($m1->transpose);
75             # B^T * Z * A
76             my $tmp2 = $m2->transpose->multiply($z)->multiply($m1);
77            
78             my $numerator = $tmp1->add($tmp2);
79              
80             my ($m, $n) = $numerator->size;
81              
82             my $sum=0;
83             for my $row(0..($m-1)){
84             for my $col (0..($n-1)){
85             $sum += $numerator->[$row][$col] * $numerator->[$row][$col];
86             }
87             }
88             my $denominator = sqrt($sum);
89             $z = $numerator->multiply_scalar(1/$denominator);
90             }
91              
92             my $i=0;
93             for my $n2 (@v2){
94             my $j=0;
95             for my $n1 (@v1){
96             $sim{$n2}{$n1} = $z->[$i][$j];
97             $j++;
98             }
99             $i++;
100             }
101              
102             $self->_setSimilarity(\%sim);
103             return \%sim;
104             }
105              
106              
107              
108             =head1 NAME
109              
110             Graph::Similarity::CoupledNodeEdgeScoring - Coupled Node-Edge Scoring implementation
111              
112             =head1 VERSION
113              
114             Version 0.02
115              
116             =head1 SYNOPSIS
117              
118             Please see L<Graph::Similarity>
119              
120             =head1 DESCRIPTION
121              
122             This is the implementation of the below papers.
123              
124             B<Vincent D. Blondel "A Measure of Similarity between Graph Vertices: Applications to Synonym Extraction and Web Searching">
125              
126             and
127              
128             B<Laura Zager "Graph Similarity and Matching">
129              
130             =head1 METHODS
131              
132             =head2 calculate()
133              
134             This calculates Coupled Node-Edge Scoring. The algorithm is mentioned in Page.655 in Blondel's paper.
135             The convergence is not taken into account. Please set the number of iteration instead.
136              
137             =head1 AUTHOR
138              
139             Shohei Kameda, C<< <shoheik at cpan.org> >>
140              
141             =head1 LICENSE AND COPYRIGHT
142              
143             Copyright 2012 Shohei Kameda.
144              
145             This program is free software; you can redistribute it and/or modify it
146             under the terms of either: the GNU General Public License as published
147             by the Free Software Foundation; or the Artistic License.
148              
149             See http://dev.perl.org/licenses/ for more information.
150              
151              
152             =cut
153              
154             1; # End of Graph::Similarity::CoupledNodeEdgeScoring