General cleanup and removal of all unnecessary references

This commit is contained in:
Alexander Liljengård
2016-05-24 16:31:21 +02:00
parent 519ad85fad
commit a65f2aa9f3
43 changed files with 366 additions and 386 deletions

View File

@ -43,8 +43,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
return $factorGraph->getUpdatedRatings();
}
public function calculateMatchQuality(GameInfo $gameInfo,
array &$teams)
public function calculateMatchQuality(GameInfo $gameInfo, array $teams)
{
// We need to create the A matrix which is the player team assigments.
$teamAssignmentsList = $teams;
@ -87,7 +86,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
return $result;
}
private static function getPlayerMeansVector(array &$teamAssignmentsList)
private static function getPlayerMeansVector(array $teamAssignmentsList)
{
// A simple vector of all the player means.
return new Vector(self::getPlayerRatingValues($teamAssignmentsList,
@ -96,7 +95,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
}));
}
private static function getPlayerCovarianceMatrix(array &$teamAssignmentsList)
private static function getPlayerCovarianceMatrix(array $teamAssignmentsList)
{
// This is a square matrix whose diagonal values represent the variance (square of standard deviation) of all
// players.
@ -108,8 +107,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
}
// Helper function that gets a list of values for all player ratings
private static function getPlayerRatingValues(array &$teamAssignmentsList,
$playerRatingFunction)
private static function getPlayerRatingValues(array $teamAssignmentsList, $playerRatingFunction)
{
$playerRatingValues = array();
@ -122,7 +120,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
return $playerRatingValues;
}
private static function createPlayerTeamAssignmentMatrix(&$teamAssignmentsList, $totalPlayers)
private static function createPlayerTeamAssignmentMatrix($teamAssignmentsList, $totalPlayers)
{
// The team assignment matrix is often referred to as the "A" matrix. It's a matrix whose rows represent the players
// and the columns represent teams. At Matrix[row, column] represents that player[row] is on team[col]

View File

@ -18,19 +18,19 @@ abstract class GaussianFactor extends Factor
* @param Variable $variable
* @return float|int
*/
protected function sendMessageVariable(Message &$message, Variable &$variable)
protected function sendMessageVariable(Message $message, Variable $variable)
{
$marginal = &$variable->getValue();
$messageValue = &$message->getValue();
$marginal = $variable->getValue();
$messageValue = $message->getValue();
$logZ = GaussianDistribution::logProductNormalization($marginal, $messageValue);
$variable->setValue(GaussianDistribution::multiply($marginal, $messageValue));
return $logZ;
}
public function &createVariableToMessageBinding(Variable &$variable)
public function createVariableToMessageBinding(Variable $variable)
{
$newDistribution = GaussianDistribution::fromPrecisionMean(0, 0);
$binding = &parent::createVariableToMessageBindingWithMessage($variable,
$binding = parent::createVariableToMessageBindingWithMessage($variable,
new Message(
$newDistribution,
sprintf("message from %s to %s", $this, $variable)));

View File

@ -14,7 +14,7 @@ class GaussianGreaterThanFactor extends GaussianFactor
{
private $_epsilon;
public function __construct($epsilon, Variable &$variable)
public function __construct($epsilon, Variable $variable)
{
parent::__construct(\sprintf("%s > %.2f", $variable, $epsilon));
$this->_epsilon = $epsilon;
@ -23,20 +23,26 @@ class GaussianGreaterThanFactor extends GaussianFactor
public function getLogNormalization()
{
$vars = &$this->getVariables();
$marginal = &$vars[0]->getValue();
$messages = &$this->getMessages();
$message = &$messages[0]->getValue();
/** @var Variable[] $vars */
$vars = $this->getVariables();
$marginal = $vars[0]->getValue();
/** @var Message[] $messages */
$messages = $this->getMessages();
$message = $messages[0]->getValue();
$messageFromVariable = GaussianDistribution::divide($marginal, $message);
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message)
+
log(
GaussianDistribution::cumulativeTo(($messageFromVariable->getMean() - $this->_epsilon) /
$messageFromVariable->getStandardDeviation()));
GaussianDistribution::cumulativeTo(
($messageFromVariable->getMean() - $this->_epsilon) /
$messageFromVariable->getStandardDeviation()
)
);
}
protected function updateMessageVariable(Message &$message, Variable &$variable)
protected function updateMessageVariable(Message $message, Variable $variable)
{
$oldMarginal = clone $variable->getValue();
$oldMessage = clone $message->getValue();
@ -55,16 +61,18 @@ class GaussianGreaterThanFactor extends GaussianFactor
$denom = 1.0 - TruncatedGaussianCorrectionFunctions::wExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC);
$newPrecision = $c / $denom;
$newPrecisionMean = ($d +
$newPrecisionMean = (
$d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC)) /
$denom;
TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC)
) / $denom;
$newMarginal = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
$newMessage = GaussianDistribution::divide(
GaussianDistribution::multiply($oldMessage, $newMarginal),
$oldMarginal);
$oldMarginal
);
// Update the message and marginal
$message->setValue($newMessage);

View File

@ -1,6 +1,7 @@
<?php namespace Moserware\Skills\TrueSkill\Factors;
use Exception;
use Moserware\Skills\FactorGraphs\KeyedVariable;
use Moserware\Skills\FactorGraphs\Message;
use Moserware\Skills\FactorGraphs\Variable;
use Moserware\Skills\Numerics\GaussianDistribution;
@ -14,7 +15,7 @@ class GaussianLikelihoodFactor extends GaussianFactor
{
private $_precision;
public function __construct($betaSquared, Variable &$variable1, Variable &$variable2)
public function __construct($betaSquared, Variable $variable1, Variable $variable2)
{
parent::__construct(sprintf("Likelihood of %s going to %s", $variable2, $variable1));
$this->_precision = 1.0 / $betaSquared;
@ -24,16 +25,18 @@ class GaussianLikelihoodFactor extends GaussianFactor
public function getLogNormalization()
{
$vars = &$this->getVariables();
$messages = &$this->getMessages();
/** @var KeyedVariable[]|mixed $vars */
$vars = $this->getVariables();
/** @var Message[] $messages */
$messages = $this->getMessages();
return GaussianDistribution::logRatioNormalization(
$vars[0]->getValue(),
$messages[0]->getValue());
$messages[0]->getValue()
);
}
private function updateHelper(Message &$message1, Message &$message2,
Variable &$variable1, Variable &$variable2)
private function updateHelper(Message $message1, Message $message2, Variable $variable1, Variable $variable2)
{
$message1Value = clone $message1->getValue();
$message2Value = clone $message2->getValue();
@ -45,7 +48,8 @@ class GaussianLikelihoodFactor extends GaussianFactor
$newMessage = GaussianDistribution::fromPrecisionMean(
$a * ($marginal2->getPrecisionMean() - $message2Value->getPrecisionMean()),
$a * ($marginal2->getPrecision() - $message2Value->getPrecision()));
$a * ($marginal2->getPrecision() - $message2Value->getPrecision())
);
$oldMarginalWithoutMessage = GaussianDistribution::divide($marginal1, $message1Value);
@ -62,8 +66,8 @@ class GaussianLikelihoodFactor extends GaussianFactor
public function updateMessageIndex($messageIndex)
{
$messages = &$this->getMessages();
$vars = &$this->getVariables();
$messages = $this->getMessages();
$vars = $this->getVariables();
switch ($messageIndex) {
case 0:

View File

@ -13,7 +13,7 @@ class GaussianPriorFactor extends GaussianFactor
{
private $_newMessage;
public function __construct($mean, $variance, Variable &$variable)
public function __construct($mean, $variance, Variable $variable)
{
parent::__construct(sprintf("Prior value going to %s", $variable));
$this->_newMessage = new GaussianDistribution($mean, sqrt($variance));
@ -23,18 +23,17 @@ class GaussianPriorFactor extends GaussianFactor
$this->createVariableToMessageBindingWithMessage($variable, $newMessage);
}
protected function updateMessageVariable(Message &$message, Variable &$variable)
protected function updateMessageVariable(Message $message, Variable $variable)
{
$oldMarginal = clone $variable->getValue();
$oldMessage = $message;
$newMarginal =
GaussianDistribution::fromPrecisionMean(
$oldMarginal->getPrecisionMean() + $this->_newMessage->getPrecisionMean() - $oldMessage->getValue()->getPrecisionMean(),
$oldMarginal->getPrecision() + $this->_newMessage->getPrecision() - $oldMessage->getValue()->getPrecision());
$newMarginal = GaussianDistribution::fromPrecisionMean(
$oldMarginal->getPrecisionMean() + $this->_newMessage->getPrecisionMean() - $oldMessage->getValue()->getPrecisionMean(),
$oldMarginal->getPrecision() + $this->_newMessage->getPrecision() - $oldMessage->getValue()->getPrecision()
);
$variable->setValue($newMarginal);
$newMessage = &$this->_newMessage;
$message->setValue($newMessage);
$message->setValue($this->_newMessage);
return GaussianDistribution::subtract($oldMarginal, $newMarginal);
}
}

View File

@ -20,7 +20,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
private $_weights;
private $_weightsSquared;
public function __construct(Variable &$sumVariable, array &$variablesToSum, array &$variableWeights = null)
public function __construct(Variable $sumVariable, array $variablesToSum, array $variableWeights = null)
{
parent::__construct(self::createName($sumVariable, $variablesToSum, $variableWeights));
$this->_weights = array();
@ -29,7 +29,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
// The first weights are a straightforward copy
// v_0 = a_1*v_1 + a_2*v_2 + ... + a_n * v_n
$variableWeightsLength = count($variableWeights);
$this->_weights[0] = \array_fill(0, count($variableWeights), 0);
$this->_weights[0] = array_fill(0, count($variableWeights), 0);
for ($i = 0; $i < $variableWeightsLength; $i++) {
$weight = &$variableWeights[$i];
@ -104,16 +104,16 @@ class GaussianWeightedSumFactor extends GaussianFactor
$this->createVariableToMessageBinding($sumVariable);
foreach ($variablesToSum as &$currentVariable) {
$localCurrentVariable = &$currentVariable;
foreach ($variablesToSum as $currentVariable) {
$localCurrentVariable = $currentVariable;
$this->createVariableToMessageBinding($localCurrentVariable);
}
}
public function getLogNormalization()
{
$vars = &$this->getVariables();
$messages = &$this->getMessages();
$vars = $this->getVariables();
$messages = $this->getMessages();
$result = 0.0;
@ -126,9 +126,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
return $result;
}
private function updateHelper(array &$weights, array &$weightsSquared,
array &$messages,
array &$variables)
private function updateHelper(array $weights, array $weightsSquared, array $messages, array $variables)
{
// Potentially look at http://mathworld.wolfram.com/NormalSumDistribution.html for clues as
// to what it's doing
@ -185,23 +183,23 @@ class GaussianWeightedSumFactor extends GaussianFactor
public function updateMessageIndex($messageIndex)
{
$allMessages = &$this->getMessages();
$allVariables = &$this->getVariables();
$allMessages = $this->getMessages();
$allVariables = $this->getVariables();
Guard::argumentIsValidIndex($messageIndex, count($allMessages), "messageIndex");
$updatedMessages = array();
$updatedVariables = array();
$indicesToUse = &$this->_variableIndexOrdersForWeights[$messageIndex];
$indicesToUse = $this->_variableIndexOrdersForWeights[$messageIndex];
// The tricky part here is that we have to put the messages and variables in the same
// order as the weights. Thankfully, the weights and messages share the same index numbers,
// so we just need to make sure they're consistent
$allMessagesCount = count($allMessages);
for ($i = 0; $i < $allMessagesCount; $i++) {
$updatedMessages[] = &$allMessages[$indicesToUse[$i]];
$updatedVariables[] = &$allVariables[$indicesToUse[$i]];
$updatedMessages[] = $allMessages[$indicesToUse[$i]];
$updatedVariables[] = $allVariables[$indicesToUse[$i]];
}
return $this->updateHelper($this->_weights[$messageIndex],

View File

@ -14,7 +14,7 @@ class GaussianWithinFactor extends GaussianFactor
{
private $_epsilon;
public function __construct($epsilon, Variable &$variable)
public function __construct($epsilon, Variable $variable)
{
parent::__construct(sprintf("%s <= %.2f", $variable, $epsilon));
$this->_epsilon = $epsilon;
@ -23,11 +23,13 @@ class GaussianWithinFactor extends GaussianFactor
public function getLogNormalization()
{
$variables = &$this->getVariables();
$marginal = &$variables[0]->getValue();
/** @var Variable[] $variables */
$variables = $this->getVariables();
$marginal = $variables[0]->getValue();
$messages = &$this->getMessages();
$message = &$messages[0]->getValue();
/** @var Message[] $messages */
$messages = $this->getMessages();
$message = $messages[0]->getValue();
$messageFromVariable = GaussianDistribution::divide($marginal, $message);
$mean = $messageFromVariable->getMean();
$std = $messageFromVariable->getStandardDeviation();
@ -38,7 +40,7 @@ class GaussianWithinFactor extends GaussianFactor
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message) + log($z);
}
protected function updateMessageVariable(Message &$message, Variable &$variable)
protected function updateMessageVariable(Message $message, Variable $variable)
{
$oldMarginal = clone $variable->getValue();
$oldMessage = clone $message->getValue();
@ -55,15 +57,16 @@ class GaussianWithinFactor extends GaussianFactor
$denominator = 1.0 - TruncatedGaussianCorrectionFunctions::wWithinMargin($dOnSqrtC, $epsilonTimesSqrtC);
$newPrecision = $c / $denominator;
$newPrecisionMean = ($d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)) /
$denominator;
$newPrecisionMean = ( $d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)
) / $denominator;
$newMarginal = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
$newMessage = GaussianDistribution::divide(
GaussianDistribution::multiply($oldMessage, $newMarginal),
$oldMarginal);
$oldMarginal
);
// Update the message and marginal
$message->setValue($newMessage);

View File

@ -1,5 +1,6 @@
<?php namespace Moserware\Skills\TrueSkill\Layers;
use Exception;
use Moserware\Skills\FactorGraphs\ScheduleLoop;
use Moserware\Skills\FactorGraphs\ScheduleSequence;
use Moserware\Skills\FactorGraphs\ScheduleStep;
@ -11,30 +12,31 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
private $_TeamDifferencesComparisonLayer;
private $_TeamPerformancesToTeamPerformanceDifferencesLayer;
public function __construct(TrueSkillFactorGraph &$parentGraph,
TeamPerformancesToTeamPerformanceDifferencesLayer &$teamPerformancesToPerformanceDifferences,
TeamDifferencesComparisonLayer &$teamDifferencesComparisonLayer)
public function __construct(TrueSkillFactorGraph $parentGraph,
TeamPerformancesToTeamPerformanceDifferencesLayer $teamPerformancesToPerformanceDifferences,
TeamDifferencesComparisonLayer $teamDifferencesComparisonLayer)
{
parent::__construct($parentGraph);
$this->_TeamPerformancesToTeamPerformanceDifferencesLayer = $teamPerformancesToPerformanceDifferences;
$this->_TeamDifferencesComparisonLayer = $teamDifferencesComparisonLayer;
}
public function &getLocalFactors()
public function getLocalFactors()
{
$localFactors =
array_merge($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
$this->_TeamDifferencesComparisonLayer->getLocalFactors());
$localFactors = array_merge($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
$this->_TeamDifferencesComparisonLayer->getLocalFactors()
);
return $localFactors;
}
public function buildLayer()
{
$inputVariablesGroups = &$this->getInputVariablesGroups();
$inputVariablesGroups = $this->getInputVariablesGroups();
$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->setInputVariablesGroups($inputVariablesGroups);
$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->buildLayer();
$teamDifferencesOutputVariablesGroups = &$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
$teamDifferencesOutputVariablesGroups = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
$this->_TeamDifferencesComparisonLayer->setInputVariablesGroups($teamDifferencesOutputVariablesGroups);
$this->_TeamDifferencesComparisonLayer->buildLayer();
}
@ -44,7 +46,7 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
switch (count($this->getInputVariablesGroups())) {
case 0:
case 1:
throw new InvalidOperationException();
throw new Exception('InvalidOperation');
case 2:
$loop = $this->createTwoTeamInnerPriorLoopSchedule();
break;
@ -57,10 +59,11 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$totalTeamDifferences = count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$totalTeams = $totalTeamDifferences + 1;
$localFactors = &$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$localFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$firstDifferencesFactor = $localFactors[0];
$lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
$firstDifferencesFactor = &$localFactors[0];
$lastDifferencesFactor = &$localFactors[$totalTeamDifferences - 1];
$innerSchedule = new ScheduleSequence(
"inner schedule",
array(
@ -79,11 +82,11 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
private function createTwoTeamInnerPriorLoopSchedule()
{
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = &$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = &$this->_TeamDifferencesComparisonLayer->getLocalFactors();
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->_TeamDifferencesComparisonLayer->getLocalFactors();
$firstPerfToTeamDiff = &$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
$firstTeamDiffComparison = &$teamDifferencesComparisonLayerLocalFactors[0];
$firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
$firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0];
$itemsToSequence = array(
new ScheduleStep(
"send team perf to perf differences",
@ -107,11 +110,11 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$forwardScheduleList = array();
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = &$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = &$this->_TeamDifferencesComparisonLayer->getLocalFactors();
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->_TeamDifferencesComparisonLayer->getLocalFactors();
$currentTeamPerfToTeamPerfDiff = &$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$i];
$currentTeamDiffComparison = &$teamDifferencesComparisonLayerLocalFactors[$i];
$currentTeamPerfToTeamPerfDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$i];
$currentTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[$i];
$currentForwardSchedulePiece =
$this->scheduleSequence(
@ -135,12 +138,12 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$backwardScheduleList = array();
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = &$this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = &$this->_TeamDifferencesComparisonLayer->getLocalFactors();
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->_TeamDifferencesComparisonLayer->getLocalFactors();
$differencesFactor = &$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$comparisonFactor = &$teamDifferencesComparisonLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$performancesToDifferencesFactor = &$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$differencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$comparisonFactor = $teamDifferencesComparisonLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$performancesToDifferencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$currentBackwardSchedulePiece = new ScheduleSequence(
"current backward schedule piece",

View File

@ -9,17 +9,17 @@ use Moserware\Skills\TrueSkill\TrueSkillFactorGraph;
class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph &$parentGraph)
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = &$this->getInputVariablesGroups();
foreach ($inputVariablesGroups as &$currentTeam) {
$localCurrentTeam = &$currentTeam;
$teamPerformance = &$this->createOutputVariable($localCurrentTeam);
$inputVariablesGroups = $this->getInputVariablesGroups();
foreach ($inputVariablesGroups as $currentTeam) {
$localCurrentTeam = $currentTeam;
$teamPerformance = $this->createOutputVariable($localCurrentTeam);
$newSumFactor = $this->createPlayerToTeamSumFactor($localCurrentTeam, $teamPerformance);
$this->addLayerFactor($newSumFactor);
@ -32,9 +32,9 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
public function createPriorSchedule()
{
$localFactors = &$this->getLocalFactors();
$localFactors = $this->getLocalFactors();
$sequence = &$this->scheduleSequence(
$sequence = $this->scheduleSequence(
array_map(
function ($weightedSumFactor) {
return new ScheduleStep("Perf to Team Perf Step", $weightedSumFactor, 0);
@ -44,11 +44,11 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
return $sequence;
}
protected function createPlayerToTeamSumFactor(&$teamMembers, &$sumVariable)
protected function createPlayerToTeamSumFactor($teamMembers, $sumVariable)
{
$weights = array_map(
function ($v) {
$player = &$v->getKey();
$player = $v->getKey();
return PartialPlay::getPartialPlayPercentage($player);
},
$teamMembers);
@ -63,9 +63,9 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
public function createPosteriorSchedule()
{
$allFactors = array();
$localFactors = &$this->getLocalFactors();
foreach ($localFactors as &$currentFactor) {
$localCurrentFactor = &$currentFactor;
$localFactors = $this->getLocalFactors();
foreach ($localFactors as $currentFactor) {
$localCurrentFactor = $currentFactor;
$numberOfMessages = $localCurrentFactor->getNumberOfMessages();
for ($currentIteration = 1; $currentIteration < $numberOfMessages; $currentIteration++) {
$allFactors[] = new ScheduleStep("team sum perf @" . $currentIteration,
@ -75,15 +75,14 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
return $this->scheduleSequence($allFactors, "all of the team's sum iterations");
}
private function &createOutputVariable(&$team)
private function createOutputVariable($team)
{
$memberNames = \array_map(function ($currentPlayer) {
$memberNames = array_map(function ($currentPlayer) {
return (string)($currentPlayer->getKey());
},
$team);
}, $team);
$teamMemberNames = \join(", ", $memberNames);
$outputVariable = &$this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team[" . $teamMemberNames . "]'s performance");
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team[" . $teamMemberNames . "]'s performance");
return $outputVariable;
}
}

View File

@ -13,7 +13,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{
private $_teams;
public function __construct(TrueSkillFactorGraph &$parentGraph, array &$teams)
public function __construct(TrueSkillFactorGraph $parentGraph, array $teams)
{
parent::__construct($parentGraph);
$this->_teams = $teams;
@ -21,17 +21,17 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
public function buildLayer()
{
$teams = &$this->_teams;
foreach ($teams as &$currentTeam) {
$localCurrentTeam = &$currentTeam;
$teams = $this->_teams;
foreach ($teams as $currentTeam) {
$localCurrentTeam = $currentTeam;
$currentTeamSkills = array();
$currentTeamAllPlayers = $localCurrentTeam->getAllPlayers();
foreach ($currentTeamAllPlayers as &$currentTeamPlayer) {
$localCurrentTeamPlayer = &$currentTeamPlayer;
foreach ($currentTeamAllPlayers as $currentTeamPlayer) {
$localCurrentTeamPlayer = $currentTeamPlayer;
$currentTeamPlayerRating = $currentTeam->getRating($localCurrentTeamPlayer);
$playerSkill = &$this->createSkillOutputVariable($localCurrentTeamPlayer);
$priorFactor = &$this->createPriorFactor($localCurrentTeamPlayer, $currentTeamPlayerRating, $playerSkill);
$playerSkill = $this->createSkillOutputVariable($localCurrentTeamPlayer);
$priorFactor = $this->createPriorFactor($localCurrentTeamPlayer, $currentTeamPlayerRating, $playerSkill);
$this->addLayerFactor($priorFactor);
$currentTeamSkills[] = $playerSkill;
}
@ -43,17 +43,17 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
public function createPriorSchedule()
{
$localFactors = &$this->getLocalFactors();
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function (&$prior) {
function ($prior) {
return new ScheduleStep("Prior to Skill Step", $prior, 0);
},
$localFactors),
"All priors");
}
private function createPriorFactor(&$player, Rating &$priorRating, Variable &$skillsVariable)
private function createPriorFactor($player, Rating $priorRating, Variable $skillsVariable)
{
return new GaussianPriorFactor(
$priorRating->getMean(),
@ -63,11 +63,11 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
);
}
private function &createSkillOutputVariable(&$key)
private function createSkillOutputVariable($key)
{
$parentFactorGraph = &$this->getParentFactorGraph();
$variableFactory = &$parentFactorGraph->getVariableFactory();
$skillOutputVariable = &$variableFactory->createKeyedVariable($key, $key . "'s skill");
$parentFactorGraph = $this->getParentFactorGraph();
$variableFactory = $parentFactorGraph->getVariableFactory();
$skillOutputVariable = $variableFactory->createKeyedVariable($key, $key . "'s skill");
return $skillOutputVariable;
}
}

View File

@ -8,23 +8,23 @@ use Moserware\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph &$parentGraph)
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = &$this->getInputVariablesGroups();
$inputVariablesGroups = $this->getInputVariablesGroups();
$outputVariablesGroups = &$this->getOutputVariablesGroups();
foreach ($inputVariablesGroups as &$currentTeam) {
foreach ($inputVariablesGroups as $currentTeam) {
$currentTeamPlayerPerformances = array();
foreach ($currentTeam as &$playerSkillVariable) {
$localPlayerSkillVariable = &$playerSkillVariable;
$currentPlayer = &$localPlayerSkillVariable->getKey();
$playerPerformance = &$this->createOutputVariable($currentPlayer);
foreach ($currentTeam as $playerSkillVariable) {
$localPlayerSkillVariable = $playerSkillVariable;
$currentPlayer = $localPlayerSkillVariable->getKey();
$playerPerformance = $this->createOutputVariable($currentPlayer);
$newLikelihoodFactor = $this->createLikelihood($localPlayerSkillVariable, $playerPerformance);
$this->addLayerFactor($newLikelihoodFactor);
$currentTeamPlayerPerformances[] = $playerPerformance;
@ -34,7 +34,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
}
}
private function createLikelihood(KeyedVariable &$playerSkill, KeyedVariable &$playerPerformance)
private function createLikelihood(KeyedVariable $playerSkill, KeyedVariable $playerPerformance)
{
return new GaussianLikelihoodFactor(
BasicMath::square($this->getParentFactorGraph()->getGameInfo()->getBeta()),
@ -43,15 +43,15 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
);
}
private function &createOutputVariable(&$key)
private function createOutputVariable($key)
{
$outputVariable = &$this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance");
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance");
return $outputVariable;
}
public function createPriorSchedule()
{
$localFactors = &$this->getLocalFactors();
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function ($likelihood) {
@ -63,7 +63,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
public function createPosteriorSchedule()
{
$localFactors = &$this->getLocalFactors();
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function ($likelihood) {

View File

@ -10,22 +10,22 @@ class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
private $_epsilon;
private $_teamRanks;
public function __construct(TrueSkillFactorGraph &$parentGraph, array &$teamRanks)
public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks)
{
parent::__construct($parentGraph);
$this->_teamRanks = $teamRanks;
$gameInfo = &$this->getParentFactorGraph()->getGameInfo();
$gameInfo = $this->getParentFactorGraph()->getGameInfo();
$this->_epsilon = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta());
}
public function buildLayer()
{
$inputVarGroups = &$this->getInputVariablesGroups();
$inputVarGroups = $this->getInputVariablesGroups();
$inputVarGroupsCount = count($inputVarGroups);
for ($i = 0; $i < $inputVarGroupsCount; $i++) {
$isDraw = ($this->_teamRanks[$i] == $this->_teamRanks[$i + 1]);
$teamDifference = &$inputVarGroups[$i][0];
$teamDifference = $inputVarGroups[$i][0];
$factor =
$isDraw

View File

@ -6,23 +6,23 @@ use Moserware\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph &$parentGraph)
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = &$this->getInputVariablesGroups();
$inputVariablesGroups = $this->getInputVariablesGroups();
$inputVariablesGroupsCount = count($inputVariablesGroups);
$outputVariablesGroup = &$this->getOutputVariablesGroups();
for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++)
{
$strongerTeam = &$inputVariablesGroups[$i][0];
$weakerTeam = &$inputVariablesGroups[$i + 1][0];
$strongerTeam = $inputVariablesGroups[$i][0];
$weakerTeam = $inputVariablesGroups[$i + 1][0];
$currentDifference = &$this->createOutputVariable();
$currentDifference = $this->createOutputVariable();
$newDifferencesFactor = $this->createTeamPerformanceToDifferenceFactor($strongerTeam, $weakerTeam, $currentDifference);
$this->addLayerFactor($newDifferencesFactor);
@ -31,17 +31,18 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
}
}
private function createTeamPerformanceToDifferenceFactor(
Variable &$strongerTeam, Variable &$weakerTeam, Variable &$output)
private function createTeamPerformanceToDifferenceFactor(Variable $strongerTeam,
Variable $weakerTeam,
Variable $output)
{
$teams = array($strongerTeam, $weakerTeam);
$weights = array(1.0, -1.0);
return new GaussianWeightedSumFactor($output, $teams, $weights);
}
private function &createOutputVariable()
private function createOutputVariable()
{
$outputVariable = &$this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team performance difference");
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team performance difference");
return $outputVariable;
}
}

View File

@ -5,7 +5,7 @@ use Moserware\Skills\TrueSkill\TrueSkillFactorGraph;
abstract class TrueSkillFactorGraphLayer extends FactorGraphLayer
{
public function __construct(TrueSkillFactorGraph &$parentGraph)
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}

View File

@ -1,6 +1,7 @@
<?php namespace Moserware\Skills\TrueSkill;
use Moserware\Skills\GameInfo;
use Moserware\Skills\Numerics\GaussianDistribution;
use Moserware\Skills\Rating;
use Moserware\Skills\RatingContainer;
use Moserware\Skills\FactorGraphs\FactorGraph;
@ -20,7 +21,7 @@ class TrueSkillFactorGraph extends FactorGraph
private $_layers;
private $_priorLayer;
public function __construct(GameInfo &$gameInfo, array &$teams, array $teamRanks)
public function __construct(GameInfo $gameInfo, array $teams, array $teamRanks)
{
$this->_priorLayer = new PlayerPriorValuesToSkillsLayer($this, $teams);
$this->_gameInfo = $gameInfo;
@ -50,15 +51,15 @@ class TrueSkillFactorGraph extends FactorGraph
{
$lastOutput = null;
$layers = &$this->_layers;
foreach ($layers as &$currentLayer) {
$layers = $this->_layers;
foreach ($layers as $currentLayer) {
if ($lastOutput != null) {
$currentLayer->setInputVariablesGroups($lastOutput);
}
$currentLayer->buildLayer();
$lastOutput = &$currentLayer->getOutputVariablesGroups();
$lastOutput = $currentLayer->getOutputVariablesGroups();
}
}
@ -72,11 +73,11 @@ class TrueSkillFactorGraph extends FactorGraph
{
$factorList = new FactorList();
$layers = &$this->_layers;
foreach ($layers as &$currentLayer) {
$localFactors = &$currentLayer->getLocalFactors();
foreach ($localFactors as &$currentFactor) {
$localCurrentFactor = &$currentFactor;
$layers = $this->_layers;
foreach ($layers as $currentLayer) {
$localFactors = $currentLayer->getLocalFactors();
foreach ($localFactors as $currentFactor) {
$localCurrentFactor = $currentFactor;
$factorList->addFactor($localCurrentFactor);
}
}
@ -89,17 +90,17 @@ class TrueSkillFactorGraph extends FactorGraph
{
$fullSchedule = array();
$layers = &$this->_layers;
foreach ($layers as &$currentLayer) {
$layers = $this->_layers;
foreach ($layers as $currentLayer) {
$currentPriorSchedule = $currentLayer->createPriorSchedule();
if ($currentPriorSchedule != null) {
$fullSchedule[] = $currentPriorSchedule;
}
}
$allLayersReverse = \array_reverse($this->_layers);
$allLayersReverse = array_reverse($this->_layers);
foreach ($allLayersReverse as &$currentLayer) {
foreach ($allLayersReverse as $currentLayer) {
$currentPosteriorSchedule = $currentLayer->createPosteriorSchedule();
if ($currentPosteriorSchedule != null) {
$fullSchedule[] = $currentPosteriorSchedule;
@ -113,10 +114,10 @@ class TrueSkillFactorGraph extends FactorGraph
{
$result = new RatingContainer();
$priorLayerOutputVariablesGroups = &$this->_priorLayer->getOutputVariablesGroups();
foreach ($priorLayerOutputVariablesGroups as &$currentTeam) {
foreach ($currentTeam as &$currentPlayer) {
$localCurrentPlayer = &$currentPlayer->getKey();
$priorLayerOutputVariablesGroups = $this->_priorLayer->getOutputVariablesGroups();
foreach ($priorLayerOutputVariablesGroups as $currentTeam) {
foreach ($currentTeam as $currentPlayer) {
$localCurrentPlayer = $currentPlayer->getKey();
$newRating = new Rating($currentPlayer->getValue()->getMean(),
$currentPlayer->getValue()->getStandardDeviation());

View File

@ -38,8 +38,12 @@ class TruncatedGaussianCorrectionFunctions
*
* In the reference F# implementation, this is referred to as "the multiplicative
* correction of a single-sided truncated Gaussian with unit variance."
*
* @param $teamPerformanceDifference
* @param $drawMargin
* @param $c
* @return float
*/
public static function wExceedsMarginScaled($teamPerformanceDifference, $drawMargin, $c)
{
return self::wExceedsMargin($teamPerformanceDifference / $c, $drawMargin / $c);

View File

@ -9,7 +9,6 @@ use Moserware\Skills\Rating;
use Moserware\Skills\RatingContainer;
use Moserware\Skills\SkillCalculator;
use Moserware\Skills\SkillCalculatorSupportedOptions;
use Moserware\Skills\PlayersRange;
use Moserware\Skills\TeamsRange;
@ -126,7 +125,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
/**
* {@inheritdoc }
*/
public function calculateMatchQuality(GameInfo $gameInfo, array &$teams)
public function calculateMatchQuality(GameInfo $gameInfo, array $teams)
{
Guard::argumentNotNull($gameInfo, "gameInfo");
$this->validateTeamCountAndPlayersCountPerTeam($teams);
@ -146,18 +145,18 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
$player2SigmaSquared = BasicMath::square($player2Rating->getStandardDeviation());
// This is the square root part of the equation:
$sqrtPart =
sqrt(
(2*$betaSquared)
/
(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared));
$sqrtPart = sqrt(
(2*$betaSquared)
/
(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared)
);
// This is the exponent part of the equation:
$expPart =
exp(
(-1*BasicMath::square($player1Rating->getMean() - $player2Rating->getMean()))
/
(2*(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared)));
$expPart = exp(
(-1*BasicMath::square($player1Rating->getMean() - $player2Rating->getMean()))
/
(2*(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared))
);
return $sqrtPart*$expPart;
}

View File

@ -57,7 +57,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
}
private static function updatePlayerRatings(GameInfo $gameInfo,
RatingContainer &$newPlayerRatings,
RatingContainer $newPlayerRatings,
Team $selfTeam,
Team $otherTeam,
$selfToOtherTeamComparison)
@ -119,9 +119,9 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
$rankMultiplier = 1;
}
$selfTeamAllPlayers = &$selfTeam->getAllPlayers();
foreach ($selfTeamAllPlayers as &$selfTeamCurrentPlayer) {
$localSelfTeamCurrentPlayer = &$selfTeamCurrentPlayer;
$selfTeamAllPlayers = $selfTeam->getAllPlayers();
foreach ($selfTeamAllPlayers as $selfTeamCurrentPlayer) {
$localSelfTeamCurrentPlayer = $selfTeamCurrentPlayer;
$previousPlayerRating = $selfTeam->getRating($localSelfTeamCurrentPlayer);
$meanMultiplier = (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / $c;
@ -141,7 +141,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
/**
* {@inheritdoc}
*/
public function calculateMatchQuality(GameInfo $gameInfo, array &$teams)
public function calculateMatchQuality(GameInfo $gameInfo, array $teams)
{
Guard::argumentNotNull($gameInfo, "gameInfo");
$this->validateTeamCountAndPlayersCountPerTeam($teams);