Tenative pass at getting prior layer working. Found out about division by zero and closure differences.

This commit is contained in:
Jeff Moser 2010-09-25 18:25:56 -04:00
parent 086d94865f
commit fa10d276d6
11 changed files with 36 additions and 23 deletions

@ -9,7 +9,6 @@ require_once(dirname(__FILE__) . "/Variable.php");
use Moserware\Skills\Guard; use Moserware\Skills\Guard;
use Moserware\Skills\HashMap; use Moserware\Skills\HashMap;
abstract class Factor abstract class Factor
{ {
private $_messages = array(); private $_messages = array();
@ -21,7 +20,7 @@ abstract class Factor
protected function __construct($name) protected function __construct($name)
{ {
$this->_name = "Factor[" . $name . "]"; $this->_name = "Factor[" . $name . "]";
$this->_messagesToVariableBinding = new HashMap(); $this->_messageToVariableBinding = new HashMap();
} }
/// Returns the log-normalization constant of that factor /// Returns the log-normalization constant of that factor
@ -81,12 +80,12 @@ abstract class Factor
public abstract function createVariableToMessageBinding(Variable &$variable); public abstract function createVariableToMessageBinding(Variable &$variable);
protected function createVariableToMessageBindingWithMessage(Variable &$variable, Variable &$message) protected function createVariableToMessageBindingWithMessage(Variable &$variable, Message &$message)
{ {
$index = count($this->_messages); $index = count($this->_messages);
$this->_messages[] = $message; $this->_messages[] = $message;
$this->_messageToVariableBinding->setValue($message, $variable); $this->_messageToVariableBinding->setValue($message, $variable);
$this->_variables[] = $variable; $this->_variables[] = &$variable;
return $message; return $message;
} }

@ -38,7 +38,7 @@ abstract class FactorGraphLayer
return $this->_localFactors; return $this->_localFactors;
} }
public function &setInputVariablesGroups(&$value) public function setInputVariablesGroups(&$value)
{ {
$this->_inputVariablesGroups = $value; $this->_inputVariablesGroups = $value;
} }

@ -11,7 +11,7 @@ class VariableFactory
public function __construct($variablePriorInitializer) public function __construct($variablePriorInitializer)
{ {
$this->_variablePriorInitializer = $variablePriorInitializer; $this->_variablePriorInitializer = &$variablePriorInitializer;
} }
public function createBasicVariable() public function createBasicVariable()
@ -22,7 +22,8 @@ class VariableFactory
public function createKeyedVariable($key) public function createKeyedVariable($key)
{ {
$newVar = new KeyedVariable($key, $this->_variablePriorInitializer()); $initializer = $this->_variablePriorInitializer;
$newVar = new KeyedVariable($key, "key variable", $initializer());
return $newVar; return $newVar;
} }
} }

@ -1,5 +1,7 @@
<?php <?php
namespace Moserware\Skills;
class HashMap class HashMap
{ {
private $_hashToValue = array(); private $_hashToValue = array();

@ -81,9 +81,19 @@ class GaussianDistribution
$result = new GaussianDistribution(); $result = new GaussianDistribution();
$result->_precision = $precision; $result->_precision = $precision;
$result->_precisionMean = $precisionMean; $result->_precisionMean = $precisionMean;
if($precision != 0)
{
$result->_variance = 1.0/$precision; $result->_variance = 1.0/$precision;
$result->_standardDeviation = sqrt($result->_variance); $result->_standardDeviation = sqrt($result->_variance);
$result->_mean = $result->_precisionMean/$result->_precision; $result->_mean = $result->_precisionMean/$result->_precision;
}
else
{
$result->_variance = \INF;
$result->_standardDeviation = \INF;
$result->_mean = \NAN;
}
return $result; return $result;
} }

@ -9,7 +9,7 @@ class RatingContainer
public function __construct() public function __construct()
{ {
$this->_playerToRating = new \HashMap(); $this->_playerToRating = new HashMap();
} }
public function getRating($player) public function getRating($player)

@ -31,7 +31,7 @@ abstract class GaussianFactor extends Factor
public function createVariableToMessageBinding(Variable &$variable) public function createVariableToMessageBinding(Variable &$variable)
{ {
return parent::createVariableToMessageBinding($variable, return parent::createVariableToMessageBindingWithMessage($variable,
new Message( new Message(
GaussianDistribution::fromPrecisionMean(0, 0), GaussianDistribution::fromPrecisionMean(0, 0),
"message from {0} to {1}", $this)); "message from {0} to {1}", $this));

@ -23,11 +23,11 @@ class GaussianPriorFactor extends GaussianFactor
{ {
parent::__construct("Prior value going to {0}"); parent::__construct("Prior value going to {0}");
$this->_newMessage = new GaussianDistribution($mean, sqrt($variance)); $this->_newMessage = new GaussianDistribution($mean, sqrt($variance));
$this->createVariableToMessageBinding($variable, $newMessage = new Message(GaussianDistribution::fromPrecisionMean(0, 0),
new Message(
GaussianDistribution::fromPrecisionMean(0, 0),
"message from {0} to {1}", "message from {0} to {1}",
$this, variable)); $this, $variable);
$this->createVariableToMessageBindingWithMessage($variable, $newMessage);
} }
protected function updateMessageVariable(Message &$message, Variable &$variable) protected function updateMessageVariable(Message &$message, Variable &$variable)

@ -35,11 +35,12 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{ {
$currentTeamPlayerRating = $currentTeam->getRating($currentTeamPlayer); $currentTeamPlayerRating = $currentTeam->getRating($currentTeamPlayer);
$playerSkill = $this->createSkillOutputVariable($currentTeamPlayer); $playerSkill = $this->createSkillOutputVariable($currentTeamPlayer);
$this->addLayerFactor($this->createPriorFactor($currentTeamPlayer, $currentTeamPlayerRating, $playerSkill)); $priorFactor = $this->createPriorFactor($currentTeamPlayer, $currentTeamPlayerRating, $playerSkill);
$this->addLayerFactor($priorFactor);
$currentTeamSkills[] = $playerSkill; $currentTeamSkills[] = $playerSkill;
} }
$outputVariablesGroups = $this->getOutputVariablesGroups(); $outputVariablesGroups = &$this->getOutputVariablesGroups();
$outputVariablesGroups[] = $currentTeamSkills; $outputVariablesGroups[] = $currentTeamSkills;
} }
} }

@ -52,7 +52,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
array_map( array_map(
function($likelihood) function($likelihood)
{ {
return $this->scheduleStep("Skill to Perf step", $likelihood, 0); return new ScheduleStep("Skill to Perf step", $likelihood, 0);
}, },
$this->getLocalFactors()), $this->getLocalFactors()),
"All skill to performance sending"); "All skill to performance sending");

@ -15,6 +15,7 @@ require_once(dirname(__FILE__) . '/Layers/PlayerSkillsToPerformancesLayer.php');
require_once(dirname(__FILE__) . '/Layers/TeamDifferencesComparisonLayer.php'); require_once(dirname(__FILE__) . '/Layers/TeamDifferencesComparisonLayer.php');
require_once(dirname(__FILE__) . '/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.php'); require_once(dirname(__FILE__) . '/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.php');
use Moserware\Numerics\GaussianDistribution;
use Moserware\Skills\GameInfo; use Moserware\Skills\GameInfo;
use Moserware\Skills\Rating; use Moserware\Skills\Rating;
use Moserware\Skills\FactorGraphs\FactorGraph; use Moserware\Skills\FactorGraphs\FactorGraph;
@ -33,7 +34,6 @@ class TrueSkillFactorGraph extends FactorGraph
private $_gameInfo; private $_gameInfo;
private $_layers; private $_layers;
private $_priorLayer; private $_priorLayer;
private $_variableFactory;
public function __construct(GameInfo &$gameInfo, &$teams, array $teamRanks) public function __construct(GameInfo &$gameInfo, &$teams, array $teamRanks)
{ {
@ -44,8 +44,8 @@ class TrueSkillFactorGraph extends FactorGraph
{ {
return GaussianDistribution::fromPrecisionMean(0, 0); return GaussianDistribution::fromPrecisionMean(0, 0);
}); });
$this->setVariableFactory($newFactory);
$this->setVariableFactory($newFactory);
$this->_layers = array( $this->_layers = array(
$this->_priorLayer, $this->_priorLayer,
new PlayerSkillsToPerformancesLayer($this), new PlayerSkillsToPerformancesLayer($this),