mirror of
https://github.com/furyfire/trueskill.git
synced 2025-01-16 01:47:39 +00:00
More type work
This commit is contained in:
@ -7,9 +7,12 @@ namespace DNW\Skills\FactorGraphs;
|
|||||||
*/
|
*/
|
||||||
class FactorList
|
class FactorList
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var Factor[] $list
|
||||||
|
*/
|
||||||
private array $list = [];
|
private array $list = [];
|
||||||
|
|
||||||
public function getLogNormalization()
|
public function getLogNormalization(): float
|
||||||
{
|
{
|
||||||
$list = $this->list;
|
$list = $this->list;
|
||||||
foreach ($list as &$currentFactor) {
|
foreach ($list as &$currentFactor) {
|
||||||
@ -39,12 +42,12 @@ class FactorList
|
|||||||
return $sumLogZ + $sumLogS;
|
return $sumLogZ + $sumLogS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function count()
|
public function count(): int
|
||||||
{
|
{
|
||||||
return count($this->list);
|
return count($this->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addFactor(Factor $factor)
|
public function addFactor(Factor $factor): Factor
|
||||||
{
|
{
|
||||||
$this->list[] = $factor;
|
$this->list[] = $factor;
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@ abstract class Schedule implements \Stringable
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function visit(int $depth = -1, int $maxDepth = 0);
|
abstract public function visit(int $depth = -1, int $maxDepth = 0): float;
|
||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return (string) $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ class ScheduleLoop extends Schedule
|
|||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function visit(int $depth = -1, int $maxDepth = 0)
|
public function visit(int $depth = -1, int $maxDepth = 0): float
|
||||||
{
|
{
|
||||||
$totalIterations = 1;
|
$totalIterations = 1;
|
||||||
$delta = $this->scheduleToLoop->visit($depth + 1, $maxDepth);
|
$delta = $this->scheduleToLoop->visit($depth + 1, $maxDepth);
|
||||||
|
@ -4,12 +4,12 @@ namespace DNW\Skills\FactorGraphs;
|
|||||||
|
|
||||||
class ScheduleSequence extends Schedule
|
class ScheduleSequence extends Schedule
|
||||||
{
|
{
|
||||||
public function __construct($name, private readonly array $schedules)
|
public function __construct(string $name, private readonly array $schedules)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function visit($depth = -1, $maxDepth = 0)
|
public function visit(int $depth = -1, int $maxDepth = 0): float
|
||||||
{
|
{
|
||||||
$maxDelta = 0;
|
$maxDelta = 0;
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ namespace DNW\Skills\FactorGraphs;
|
|||||||
|
|
||||||
class ScheduleStep extends Schedule
|
class ScheduleStep extends Schedule
|
||||||
{
|
{
|
||||||
public function __construct($name, private readonly Factor $factor, private $index)
|
public function __construct(string $name, private readonly Factor $factor, private $index)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function visit(int $depth = -1, int $maxDepth = 0)
|
public function visit(int $depth = -1, int $maxDepth = 0): float
|
||||||
{
|
{
|
||||||
$currentFactor = $this->factor;
|
$currentFactor = $this->factor;
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ class Matrix
|
|||||||
return new Matrix($this->rowCount - 1, $this->columnCount - 1, $result);
|
return new Matrix($this->rowCount - 1, $this->columnCount - 1, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCofactor($rowToRemove, $columnToRemove)
|
public function getCofactor(int $rowToRemove, int $columnToRemove): float
|
||||||
{
|
{
|
||||||
// See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for details
|
// See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for details
|
||||||
// REVIEW: should things be reversed since I'm 0 indexed?
|
// REVIEW: should things be reversed since I'm 0 indexed?
|
||||||
@ -312,7 +312,7 @@ class Matrix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function equals($otherMatrix)
|
public function equals(Matrix $otherMatrix): bool
|
||||||
{
|
{
|
||||||
// If one is null, but not both, return false.
|
// If one is null, but not both, return false.
|
||||||
if ($otherMatrix == null) {
|
if ($otherMatrix == null) {
|
||||||
|
@ -33,17 +33,17 @@ class Range
|
|||||||
|
|
||||||
// REVIEW: It's probably bad form to have access statics via a derived class, but the syntax looks better :-)
|
// REVIEW: It's probably bad form to have access statics via a derived class, but the syntax looks better :-)
|
||||||
|
|
||||||
public static function inclusive(int $min, int $max): self
|
public static function inclusive(int $min, int $max): static
|
||||||
{
|
{
|
||||||
return static::create($min, $max);
|
return static::create($min, $max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function exactly(int $value): self
|
public static function exactly(int $value): static
|
||||||
{
|
{
|
||||||
return static::create($value, $value);
|
return static::create($value, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function atLeast(int $minimumValue): self
|
public static function atLeast(int $minimumValue): static
|
||||||
{
|
{
|
||||||
return static::create($minimumValue, PHP_INT_MAX);
|
return static::create($minimumValue, PHP_INT_MAX);
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,10 @@ class Rating implements \Stringable
|
|||||||
return $this->mean - $this->conservativeStandardDeviationMultiplier * $this->standardDeviation;
|
return $this->mean - $this->conservativeStandardDeviationMultiplier * $this->standardDeviation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPartialUpdate(Rating $prior, Rating $fullPosterior, $updatePercentage): Rating
|
public function getPartialUpdate(Rating $prior, Rating $fullPosterior, float $updatePercentage): Rating
|
||||||
{
|
{
|
||||||
$priorGaussian = new GaussianDistribution($prior->getMean(), $prior->getStandardDeviation());
|
$priorGaussian = new GaussianDistribution($prior->getMean(), $prior->getStandardDeviation());
|
||||||
$posteriorGaussian = new GaussianDistribution($fullPosterior->getMean(), $fullPosterior . getStandardDeviation());
|
$posteriorGaussian = new GaussianDistribution($fullPosterior->getMean(), $fullPosterior->getStandardDeviation());
|
||||||
|
|
||||||
// From a clarification email from Ralf Herbrich:
|
// From a clarification email from Ralf Herbrich:
|
||||||
// "the idea is to compute a linear interpolation between the prior and posterior skills of each player
|
// "the idea is to compute a linear interpolation between the prior and posterior skills of each player
|
||||||
|
@ -15,9 +15,9 @@ use Exception;
|
|||||||
*/
|
*/
|
||||||
class GaussianLikelihoodFactor extends GaussianFactor
|
class GaussianLikelihoodFactor extends GaussianFactor
|
||||||
{
|
{
|
||||||
private $precision;
|
private float $precision;
|
||||||
|
|
||||||
public function __construct($betaSquared, Variable $variable1, Variable $variable2)
|
public function __construct(float $betaSquared, Variable $variable1, Variable $variable2)
|
||||||
{
|
{
|
||||||
parent::__construct(sprintf('Likelihood of %s going to %s', $variable2, $variable1));
|
parent::__construct(sprintf('Likelihood of %s going to %s', $variable2, $variable1));
|
||||||
$this->precision = 1.0 / $betaSquared;
|
$this->precision = 1.0 / $betaSquared;
|
||||||
@ -42,7 +42,7 @@ class GaussianLikelihoodFactor extends GaussianFactor
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateHelper(Message $message1, Message $message2, Variable $variable1, Variable $variable2)
|
private function updateHelper(Message $message1, Message $message2, Variable $variable1, Variable $variable2): float
|
||||||
{
|
{
|
||||||
$message1Value = clone $message1->getValue();
|
$message1Value = clone $message1->getValue();
|
||||||
$message2Value = clone $message2->getValue();
|
$message2Value = clone $message2->getValue();
|
||||||
@ -70,7 +70,7 @@ class GaussianLikelihoodFactor extends GaussianFactor
|
|||||||
return GaussianDistribution::subtract($newMarginal, $marginal1);
|
return GaussianDistribution::subtract($newMarginal, $marginal1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateMessageIndex($messageIndex)
|
public function updateMessageIndex($messageIndex): float
|
||||||
{
|
{
|
||||||
$messages = $this->getMessages();
|
$messages = $this->getMessages();
|
||||||
$vars = $this->getVariables();
|
$vars = $this->getVariables();
|
||||||
|
@ -14,16 +14,16 @@ use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
|
|||||||
*/
|
*/
|
||||||
class GaussianWithinFactor extends GaussianFactor
|
class GaussianWithinFactor extends GaussianFactor
|
||||||
{
|
{
|
||||||
private $epsilon;
|
private float $epsilon;
|
||||||
|
|
||||||
public function __construct($epsilon, Variable $variable)
|
public function __construct(float $epsilon, Variable $variable)
|
||||||
{
|
{
|
||||||
parent::__construct(sprintf('%s <= %.2f', $variable, $epsilon));
|
parent::__construct(sprintf('%s <= %.2f', $variable, $epsilon));
|
||||||
$this->epsilon = $epsilon;
|
$this->epsilon = $epsilon;
|
||||||
$this->createVariableToMessageBinding($variable);
|
$this->createVariableToMessageBinding($variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLogNormalization()
|
public function getLogNormalization(): float
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Variable[] $variables
|
* @var Variable[] $variables
|
||||||
@ -46,7 +46,7 @@ class GaussianWithinFactor extends GaussianFactor
|
|||||||
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message) + log($z);
|
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message) + log($z);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function updateMessageVariable(Message $message, Variable $variable)
|
protected function updateMessageVariable(Message $message, Variable $variable): float
|
||||||
{
|
{
|
||||||
$oldMarginal = clone $variable->getValue();
|
$oldMarginal = clone $variable->getValue();
|
||||||
$oldMessage = clone $message->getValue();
|
$oldMessage = clone $message->getValue();
|
||||||
|
@ -4,6 +4,7 @@ namespace DNW\Skills\TrueSkill\Layers;
|
|||||||
|
|
||||||
use DNW\Skills\FactorGraphs\ScheduleStep;
|
use DNW\Skills\FactorGraphs\ScheduleStep;
|
||||||
use DNW\Skills\FactorGraphs\Variable;
|
use DNW\Skills\FactorGraphs\Variable;
|
||||||
|
use DNW\Skills\FactorGraphs\KeyedVariable;
|
||||||
use DNW\Skills\Numerics\BasicMath;
|
use DNW\Skills\Numerics\BasicMath;
|
||||||
use DNW\Skills\Rating;
|
use DNW\Skills\Rating;
|
||||||
use DNW\Skills\TrueSkill\Factors\GaussianPriorFactor;
|
use DNW\Skills\TrueSkill\Factors\GaussianPriorFactor;
|
||||||
@ -63,7 +64,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createSkillOutputVariable($key)
|
private function createSkillOutputVariable(mixed $key) : KeyedVariable
|
||||||
{
|
{
|
||||||
$parentFactorGraph = $this->getParentFactorGraph();
|
$parentFactorGraph = $this->getParentFactorGraph();
|
||||||
$variableFactory = $parentFactorGraph->getVariableFactory();
|
$variableFactory = $parentFactorGraph->getVariableFactory();
|
||||||
|
@ -40,7 +40,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createOutputVariable($key): KeyedVariable
|
private function createOutputVariable(mixed $key): KeyedVariable
|
||||||
{
|
{
|
||||||
return $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance");
|
return $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance");
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,12 @@ use DNW\Skills\TrueSkill\Layers\TeamPerformancesToTeamPerformanceDifferencesLaye
|
|||||||
|
|
||||||
class TrueSkillFactorGraph extends FactorGraph
|
class TrueSkillFactorGraph extends FactorGraph
|
||||||
{
|
{
|
||||||
private $layers;
|
/**
|
||||||
|
* @var FactorGraphLayer[] $layers
|
||||||
|
*/
|
||||||
|
private array $layers;
|
||||||
|
|
||||||
private $priorLayer;
|
private PlayerPriorValuesToSkillsLayer $priorLayer;
|
||||||
|
|
||||||
public function __construct(private readonly GameInfo $gameInfo, array $teams, array $teamRanks)
|
public function __construct(private readonly GameInfo $gameInfo, array $teams, array $teamRanks)
|
||||||
{
|
{
|
||||||
@ -43,7 +46,7 @@ class TrueSkillFactorGraph extends FactorGraph
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGameInfo()
|
public function getGameInfo(): GameInfo
|
||||||
{
|
{
|
||||||
return $this->gameInfo;
|
return $this->gameInfo;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
|
|||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function calculateNewRating(GameInfo $gameInfo, Rating $selfRating, Rating $opponentRating, $comparison): Rating
|
private static function calculateNewRating(GameInfo $gameInfo, Rating $selfRating, Rating $opponentRating, PairwiseComparison $comparison): Rating
|
||||||
{
|
{
|
||||||
$drawMargin = DrawMargin::getDrawMarginFromDrawProbability(
|
$drawMargin = DrawMargin::getDrawMarginFromDrawProbability(
|
||||||
$gameInfo->getDrawProbability(),
|
$gameInfo->getDrawProbability(),
|
||||||
|
Reference in New Issue
Block a user