sub srs_full_matrix { my $mov = shift; my $played = shift; my $opt = shift || (); my $epsilon = 0.001; my $maxiter = 1000000; my $debug = 0; $epsilon = $opt->{epsilon} if ( $opt->{epsilon} ); $maxiter = $opt->{maxiter} if ( $opt->{maxiter} ); $debug = $opt->{debug} if ( $opt->{debug} ); my $srs = $mov->copy(); my $oldsrs = $srs->copy(); my $delta = 10.0; my $iter = 0; while ( $delta > $epsilon and $iter < $maxiter ) { my $wt = 1.0 / sumover $played; my $prod = $srs x $played; my $sos = $wt * $prod; $srs = $mov + $sos; $delta = max abs ( $srs - $oldsrs ); $oldsrs = $srs->copy(); $iter++; } print "iter = $iter\n" if $debug; print "epsilon = $epsilon\n" if $debug; printf "delta = %7.4f\n", $delta if $debug; my $offset = sum $srs; $srs -= ( $offset / $mov->nelem ); return $srs->slice(":,(0)"); } #### sub load_srs_data { my $games = shift; my %team; for ( @$games ) { my ( $visitor, $visit_score, $home_team, $home_score ) = split "\,", $_; my $diff = $home_score - $visit_score; $team{$visitor}{games_played}++; $team{$home_team}{games_played}++; $team{$visitor}{points} -= $diff; $team{$home_team}{points} += $diff; push @{$team{$visitor}{played}}, $home_team; push @{$team{$home_team}{played}}, $visitor; } my $total_team = scalar keys %team; my $played = zeroes $total_team, $total_team; my $mov = zeroes $total_team; my %team_map; my $ii = 0; for ( sort keys %team ) { my $team_diff = $team{$_}{points} / $team{$_}{games_played}; $team_map{$_} = $ii; $mov->set( $ii, $team_diff ); $ii++; } for ( keys %team ) { my $i = $team_map{$_}; for my $opp (@{$team{$_}{played}}) { my $j = $team_map{$opp}; my $a = $played->at ( $i, $j ); $a++; $played->set( $i, $j, $a ); } } return \%team, \%team_map, $mov, $played; }