Algorithm-HITS-Lite
view release on metacpan or search on metacpan
lib/Algorithm/HITS/Lite.pm view on Meta::CPAN
package Algorithm::HITS::Lite;
use Spiffy -Base;
our $VERSION = '0.04';
=head1 NAME
Algorithm::HITS::Lite - HITS algorithm implementation not requiring PDL
=head1 SYNOPSIS
my $ah = Algorithm::HITS::Lite->new(network => $adjm);
my ($hub,$auth) = $ah->iterate(10);
=cut
field 'network';
field nodes => -init => '$self->_collect_nodes';
=head1 APIs
=head2 new(network => $adjm)
The required parameter $adjm is the 'Adjency Matrix' presentation of
network, must be a hashref of hashref.
=head2 iterate($k)
Iterate the process for $k timesm, default to 10 if it's not given.
Return a ($hub,$auth) weight pair. Each is a hashref with
keys are the same as keys in $adjm.
=cut
sub iterate {
my $k = shift || 10; # iter k times
my $nodes = $self->nodes;
my $xi = $self->_build_z(@$nodes);
my $yi = $self->_build_z(@$nodes);
my ($xj,$yj) = ($xi,$yi);
for(1..$k) {
$xj = $self->_op_T($xi,$yi);
$yj = $self->_op_O($xj,$yi);
$xi = $self->_normalize_xy($xj);
$yi = $self->_normalize_xy($yj);
}
return($xi,$yi);
}
# Collect adjency matrix nodes.
# (All hash keys)
sub _collect_nodes {
my $adjm = $self->network;
my %nodes;
for my $k1 (keys %$adjm) {
$nodes{$k1} = 1;
for my $k2 (keys %{$adjm->{$k1}}) {
$nodes{$k2} = 1;
}
}
my @n = keys %nodes;
$self->nodes(\@n);
return [@n];
}
sub _build_z {
my $z = {};
$z->{$_} = 1 for(@_);
return $z;
}
sub _normalize_xy {
my $x = shift;
my @vs = values %$x;
my $sq = sqrt($self->sqsum(@vs));
if($sq == 0) {
for(keys %$x) {
$x->{$_} = 0;
}
} else {
for(keys %$x) {
$x->{$_} /= $sq;
}
}
return $x;
}
sub _op_T {
( run in 1.895 second using v1.01-cache-2.11-cpan-df04353d9ac )