package Statistics::SocialNetworks; use 5.008008; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use Graph::Statistics ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( constraint c p CTdi flushCache ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.02'; # Preloaded methods go here. my %p = (); # cache for p() results sub m { my $g = shift; my $i = shift; my $j = shift; my %g = %{$g}; return $g{$i}{$j} if defined $g{$i}{$j}; return 0; } sub flushCache { %p = (); } sub CTdi { #Coleman-Theil disorder index #a measure of diversity of contacts #0 = same for all contacts #1 = all constraint is measured in a single relationship my $g = shift; my $i = shift; my %g = %{$g}; my @N = keys %{$g{$i}}; my $N = $#N + 1; return 1 if ( $N == 1 ); my $sum = 0; my $C = constraint($g,$i); if ( $C ) { foreach my $j ( @N ) { next if ($j eq $i); my $factor = c($g, $i, $j)/($C/$N); $sum += $factor * log($factor) if ( $factor ); } $sum /= ($N * log($N)); } return $sum; } sub p { my $g = shift; # graph my $i = shift; my $j = shift; my %g = %{$g}; return $p{$i}{$j} if (defined $p{$i}{$j}); my @v = keys %{$g{$i}}; my $z = 0; my $total_w = 0; my $n; my $w = undef; foreach $n ( @v ) { $w = $g{$i}{$n} || 1; $total_w += $w; next unless ( $n eq $j ); $z += $w; } return $p{$i}{$j} = 0 unless ($z > 0); $p{$i}{$j} = ($z/($total_w)); return $p{$i}{$j}; } sub c { my $g = shift; # graph my $i = shift; my $j = shift; my %g = %{$g}; my $sum = p($g,$i,$j); my @v = keys %{$g{$i}}; my $key; foreach $key ( @v ) { next if $key eq $i; next if $key eq $j; $sum += p($g, $i, $key) * p($g, $key, $j); } return $sum * $sum; } sub constraint { my $g = shift; # graph my $i = shift; my %g = %{$g}; my $sum = 0; my @v = keys %{$g{$i}}; return 1 if ($#v == 0); my $node; foreach $node ( @v ) { next if ( $node eq $i ); $sum += c($g, $i, $node); } return $sum; } 1; __END__ # Below is stub documentation for your module. You'd better edit it! =head1 NAME Graph::Statistics - Perl extension for calculating network constraint and other network statistics. =head1 SYNOPSIS use Graph::Statistics ':all'; # create hash representing graph my %g; foreach $f ( qw( a b c ) ) { foreach $t ( qw( a b c ) ) { next if $f eq $t; $g{$f}{$t} = rand(); } } # every time the network changes and before calculations # not needed if you are only creating the graph once flushCache(); # print out Burt network constraint value for each node foreach $f ( keys %g ) { print "$f,", constraint(\%g,$f), "\n"; } # print out Coleman-Theil disorder index for each node foreach $f ( keys %g ) { print "$f,", CTdi(\%g,$f), "\n"; } =head1 DESCRIPTION Calculates Burt's network constraint value on nodes within a hash based network representation. An earlier version (not public) was based on Graph, but that was too slow for networks of size. =head2 Methods =over 4 =item * constraint(hashreference, nodeidentifier) returns the network constraint =item * c(hash reference, node identifier a, node identifier b) the portion of the network constraint on a by b. =item * p(hash reference, node identifier a, node identifier b) the portion of the value ab of the total weights of edges from a. =item * flushCache() clears an internal cache used to speed everything up. =item * CTdi(hash reference, node identifier) Coleman-Theil disorder index. A measure of diversity of neighbor nodes. =head1 AUTHOR Erich S. Morisse, Eemorisse@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by Erich Morisse This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut