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 )