Upgrade with rector

This commit is contained in:
Alex Wulf
2022-07-05 16:21:06 +02:00
parent fd5d276359
commit 689e3b75fe
38 changed files with 144 additions and 355 deletions

View File

@ -38,7 +38,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
$factorGraph->buildGraph();
$factorGraph->runSchedule();
$probabilityOfOutcome = $factorGraph->getProbabilityOfRanking();
$factorGraph->getProbabilityOfRanking();
return $factorGraph->getUpdatedRatings();
}
@ -47,11 +47,11 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
{
// We need to create the A matrix which is the player team assigments.
$teamAssignmentsList = $teams;
$skillsMatrix = $this->getPlayerCovarianceMatrix($teamAssignmentsList);
$meanVector = $this->getPlayerMeansVector($teamAssignmentsList);
$skillsMatrix = self::getPlayerCovarianceMatrix($teamAssignmentsList);
$meanVector = self::getPlayerMeansVector($teamAssignmentsList);
$meanVectorTranspose = $meanVector->getTranspose();
$playerTeamAssignmentsMatrix = $this->createPlayerTeamAssignmentMatrix($teamAssignmentsList, $meanVector->getRowCount());
$playerTeamAssignmentsMatrix = self::createPlayerTeamAssignmentMatrix($teamAssignmentsList, $meanVector->getRowCount());
$playerTeamAssignmentsMatrixTranspose = $playerTeamAssignmentsMatrix->getTranspose();
$betaSquared = BasicMath::square($gameInfo->getBeta());
@ -81,18 +81,14 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
$sqrtPartDenominator = $middle->getDeterminant();
$sqrtPart = $sqrtPartNumerator / $sqrtPartDenominator;
$result = exp($expPart) * sqrt($sqrtPart);
return $result;
return exp($expPart) * sqrt($sqrtPart);
}
private static function getPlayerMeansVector(array $teamAssignmentsList)
{
// A simple vector of all the player means.
return new Vector(self::getPlayerRatingValues($teamAssignmentsList,
function ($rating) {
return $rating->getMean();
}));
fn($rating) => $rating->getMean()));
}
private static function getPlayerCovarianceMatrix(array $teamAssignmentsList)
@ -101,9 +97,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// players.
return new DiagonalMatrix(
self::getPlayerRatingValues($teamAssignmentsList,
function ($rating) {
return BasicMath::square($rating->getStandardDeviation());
}));
fn($rating) => BasicMath::square($rating->getStandardDeviation())));
}
// Helper function that gets a list of values for all player ratings
@ -141,7 +135,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
$playerAssignments = [];
$totalPreviousPlayers = 0;
$teamAssignmentsListCount = count($teamAssignmentsList);
$teamAssignmentsListCount = is_countable($teamAssignmentsList) ? count($teamAssignmentsList) : 0;
$currentColumn = 0;
@ -175,8 +169,6 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
$currentColumn++;
}
$playerTeamAssignmentsMatrix = Matrix::fromColumnValues($totalPlayers, $teamAssignmentsListCount - 1, $playerAssignments);
return $playerTeamAssignmentsMatrix;
return Matrix::fromColumnValues($totalPlayers, $teamAssignmentsListCount - 1, $playerAssignments);
}
}

View File

@ -9,19 +9,10 @@ use DNW\Skills\Numerics\GaussianDistribution;
abstract class GaussianFactor extends Factor
{
protected function __construct($name)
{
parent::__construct($name);
}
/**
* Sends the factor-graph message with and returns the log-normalization constant.
*
* @param Message $message
* @param Variable $variable
* @return float|int
*/
protected function sendMessageVariable(Message $message, Variable $variable)
protected function sendMessageVariable(Message $message, Variable $variable): float|int
{
$marginal = $variable->getValue();
$messageValue = $message->getValue();
@ -34,11 +25,10 @@ abstract class GaussianFactor extends Factor
public function createVariableToMessageBinding(Variable $variable)
{
$newDistribution = GaussianDistribution::fromPrecisionMean(0, 0);
$binding = parent::createVariableToMessageBindingWithMessage($variable,
return parent::createVariableToMessageBindingWithMessage($variable,
new Message(
$newDistribution,
sprintf('message from %s to %s', $this, $variable)));
return $binding;
}
}

View File

@ -71,15 +71,12 @@ class GaussianLikelihoodFactor extends GaussianFactor
$messages = $this->getMessages();
$vars = $this->getVariables();
switch ($messageIndex) {
case 0:
return $this->updateHelper($messages[0], $messages[1],
$vars[0], $vars[1]);
case 1:
return $this->updateHelper($messages[1], $messages[0],
$vars[1], $vars[0]);
default:
throw new Exception();
}
return match ($messageIndex) {
0 => $this->updateHelper($messages[0], $messages[1],
$vars[0], $vars[1]),
1 => $this->updateHelper($messages[1], $messages[0],
$vars[1], $vars[0]),
default => throw new Exception(),
};
}
}

View File

@ -38,5 +38,6 @@ class GaussianPriorFactor extends GaussianFactor
$message->setValue($this->_newMessage);
return GaussianDistribution::subtract($oldMarginal, $newMarginal);
}
}

View File

@ -15,24 +15,22 @@ use DNW\Skills\Numerics\GaussianDistribution;
*/
class GaussianWeightedSumFactor extends GaussianFactor
{
private $_variableIndexOrdersForWeights = [];
private array $_variableIndexOrdersForWeights = [];
// This following is used for convenience, for example, the first entry is [0, 1, 2]
// corresponding to v[0] = a1*v[1] + a2*v[2]
private $_weights;
private array $_weights = [];
private $_weightsSquared;
private array $_weightsSquared = [];
public function __construct(Variable $sumVariable, array $variablesToSum, array $variableWeights = null)
{
parent::__construct(self::createName($sumVariable, $variablesToSum, $variableWeights));
$this->_weights = [];
$this->_weightsSquared = [];
// 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);
$variableWeightsLength = count((array) $variableWeights);
$this->_weights[0] = array_fill(0, count((array) $variableWeights), 0);
for ($i = 0; $i < $variableWeightsLength; $i++) {
$weight = &$variableWeights[$i];
@ -48,7 +46,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$this->_variableIndexOrdersForWeights[0][] = $i;
}
$variableWeightsLength = count($variableWeights);
$variableWeightsLength = count((array) $variableWeights);
// The rest move the variables around and divide out the constant.
// For example:
@ -71,7 +69,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
for ($currentWeightSourceIndex = 0;
$currentWeightSourceIndex < $variableWeightsLength;
$currentWeightSourceIndex++) {
if ($currentWeightSourceIndex == ($weightsIndex - 1)) {
if ($currentWeightSourceIndex === $weightsIndex - 1) {
continue;
}
@ -98,7 +96,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
}
$currentWeights[$currentDestinationWeightIndex] = $finalWeight;
$currentWeightsSquared[$currentDestinationWeightIndex] = BasicMath::square($finalWeight);
$variableIndices[count($variableWeights)] = 0;
$variableIndices[count((array) $variableWeights)] = 0;
$this->_variableIndexOrdersForWeights[] = $variableIndices;
$this->_weights[$weightsIndex] = $currentWeights;
@ -121,7 +119,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$result = 0.0;
// We start at 1 since offset 0 has the sum
$varCount = count($vars);
$varCount = is_countable($vars) ? count($vars) : 0;
for ($i = 1; $i < $varCount; $i++) {
$result += GaussianDistribution::logRatioNormalization($vars[$i]->getValue(), $messages[$i]->getValue());
}
@ -167,7 +165,6 @@ class GaussianWeightedSumFactor extends GaussianFactor
$anotherNewPrecision = 1.0 / $anotherInverseOfNewPrecisionSum;
$newPrecisionMean = $newPrecision * $weightedMeanSum;
$anotherNewPrecisionMean = $anotherNewPrecision * $anotherWeightedMeanSum;
$newMessage = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
$oldMarginalWithoutMessage = GaussianDistribution::divide($marginal0, $message0);
@ -190,7 +187,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$allMessages = $this->getMessages();
$allVariables = $this->getVariables();
Guard::argumentIsValidIndex($messageIndex, count($allMessages), 'messageIndex');
Guard::argumentIsValidIndex($messageIndex, is_countable($allMessages) ? count($allMessages) : 0, 'messageIndex');
$updatedMessages = [];
$updatedVariables = [];
@ -200,7 +197,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
// 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);
$allMessagesCount = is_countable($allMessages) ? count($allMessages) : 0;
for ($i = 0; $i < $allMessagesCount; $i++) {
$updatedMessages[] = $allMessages[$indicesToUse[$i]];
$updatedVariables[] = $allVariables[$indicesToUse[$i]];
@ -218,7 +215,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$result = (string) $sumVariable;
$result .= ' = ';
$totalVars = count($variablesToSum);
$totalVars = is_countable($variablesToSum) ? count($variablesToSum) : 0;
for ($i = 0; $i < $totalVars; $i++) {
$isFirst = ($i == 0);
@ -232,7 +229,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$result .= (string) $variablesToSum[$i];
$result .= ']';
$isLast = ($i == ($totalVars - 1));
$isLast = ($i === $totalVars - 1);
if (! $isLast) {
if ($weights[$i + 1] >= 0) {

View File

@ -11,26 +11,18 @@ use Exception;
// The whole purpose of this is to do a loop on the bottom
class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
{
private $_TeamDifferencesComparisonLayer;
private $_TeamPerformancesToTeamPerformanceDifferencesLayer;
public function __construct(TrueSkillFactorGraph $parentGraph,
TeamPerformancesToTeamPerformanceDifferencesLayer $teamPerformancesToPerformanceDifferences,
TeamDifferencesComparisonLayer $teamDifferencesComparisonLayer)
private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $_TeamPerformancesToTeamPerformanceDifferencesLayer,
private readonly TeamDifferencesComparisonLayer $_TeamDifferencesComparisonLayer)
{
parent::__construct($parentGraph);
$this->_TeamPerformancesToTeamPerformanceDifferencesLayer = $teamPerformancesToPerformanceDifferences;
$this->_TeamDifferencesComparisonLayer = $teamDifferencesComparisonLayer;
}
public function getLocalFactors()
{
$localFactors = array_merge($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
return array_merge($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
$this->_TeamDifferencesComparisonLayer->getLocalFactors()
);
return $localFactors;
}
public function buildLayer()
@ -46,7 +38,7 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
public function createPriorSchedule()
{
switch (count($this->getInputVariablesGroups())) {
switch (is_countable($this->getInputVariablesGroups()) ? count($this->getInputVariablesGroups()) : 0) {
case 0:
case 1:
throw new Exception('InvalidOperation');
@ -59,15 +51,14 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
}
// When dealing with differences, there are always (n-1) differences, so add in the 1
$totalTeamDifferences = count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$totalTeams = $totalTeamDifferences + 1;
$totalTeamDifferences = is_countable($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors()) ? count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors()) : 0;
$localFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$firstDifferencesFactor = $localFactors[0];
$lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
$innerSchedule = new ScheduleSequence(
return new ScheduleSequence(
'inner schedule',
[
$loop,
@ -79,8 +70,6 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$lastDifferencesFactor, 2),
]
);
return $innerSchedule;
}
private function createTwoTeamInnerPriorLoopSchedule()
@ -108,7 +97,7 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
private function createMultipleTeamInnerPriorLoopSchedule()
{
$totalTeamDifferences = count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$totalTeamDifferences = is_countable($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors()) ? count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors()) : 0;
$forwardScheduleList = [];
@ -173,11 +162,9 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$initialMaxDelta = 0.0001;
$loop = new ScheduleLoop(
return new ScheduleLoop(
sprintf('loop with max delta of %f', $initialMaxDelta),
$forwardBackwardScheduleToLoop,
$initialMaxDelta);
return $loop;
}
}

View File

@ -9,11 +9,6 @@ use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = $this->getInputVariablesGroups();
@ -34,15 +29,11 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
{
$localFactors = $this->getLocalFactors();
$sequence = $this->scheduleSequence(
return $this->scheduleSequence(
array_map(
function ($weightedSumFactor) {
return new ScheduleStep('Perf to Team Perf Step', $weightedSumFactor, 0);
},
fn($weightedSumFactor) => new ScheduleStep('Perf to Team Perf Step', $weightedSumFactor, 0),
$localFactors),
'all player perf to team perf schedule');
return $sequence;
}
protected function createPlayerToTeamSumFactor($teamMembers, $sumVariable)
@ -79,13 +70,10 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
private function createOutputVariable($team)
{
$memberNames = array_map(function ($currentPlayer) {
return (string) ($currentPlayer->getKey());
}, $team);
$memberNames = array_map(fn($currentPlayer) => (string) ($currentPlayer->getKey()), $team);
$teamMemberNames = \implode(', ', $memberNames);
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team['.$teamMemberNames."]'s performance");
return $outputVariable;
return $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team['.$teamMemberNames."]'s performance");
}
}

View File

@ -13,12 +13,9 @@ use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
// start the process.
class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{
private $_teams;
public function __construct(TrueSkillFactorGraph $parentGraph, array $teams)
public function __construct(TrueSkillFactorGraph $parentGraph, private readonly array $_teams)
{
parent::__construct($parentGraph);
$this->_teams = $teams;
}
public function buildLayer()
@ -33,7 +30,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
$localCurrentTeamPlayer = $currentTeamPlayer;
$currentTeamPlayerRating = $currentTeam->getRating($localCurrentTeamPlayer);
$playerSkill = $this->createSkillOutputVariable($localCurrentTeamPlayer);
$priorFactor = $this->createPriorFactor($localCurrentTeamPlayer, $currentTeamPlayerRating, $playerSkill);
$priorFactor = $this->createPriorFactor($currentTeamPlayerRating, $playerSkill);
$this->addLayerFactor($priorFactor);
$currentTeamSkills[] = $playerSkill;
}
@ -49,14 +46,12 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
return $this->scheduleSequence(
array_map(
function ($prior) {
return new ScheduleStep('Prior to Skill Step', $prior, 0);
},
fn($prior) => new ScheduleStep('Prior to Skill Step', $prior, 0),
$localFactors),
'All priors');
}
private function createPriorFactor($player, Rating $priorRating, Variable $skillsVariable)
private function createPriorFactor(Rating $priorRating, Variable $skillsVariable)
{
return new GaussianPriorFactor(
$priorRating->getMean(),
@ -70,8 +65,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{
$parentFactorGraph = $this->getParentFactorGraph();
$variableFactory = $parentFactorGraph->getVariableFactory();
$skillOutputVariable = $variableFactory->createKeyedVariable($key, $key."'s skill");
return $skillOutputVariable;
return $variableFactory->createKeyedVariable($key, $key."'s skill");
}
}

View File

@ -10,11 +10,6 @@ use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = $this->getInputVariablesGroups();
@ -47,9 +42,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
private function createOutputVariable($key)
{
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key."'s performance");
return $outputVariable;
return $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key."'s performance");
}
public function createPriorSchedule()
@ -58,9 +51,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
return $this->scheduleSequence(
array_map(
function ($likelihood) {
return new ScheduleStep('Skill to Perf step', $likelihood, 0);
},
fn($likelihood) => new ScheduleStep('Skill to Perf step', $likelihood, 0),
$localFactors),
'All skill to performance sending');
}
@ -71,9 +62,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
return $this->scheduleSequence(
array_map(
function ($likelihood) {
return new ScheduleStep('name', $likelihood, 1);
},
fn($likelihood) => new ScheduleStep('name', $likelihood, 1),
$localFactors),
'All skill to performance sending');
}

View File

@ -11,12 +11,9 @@ class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
{
private $_epsilon;
private $_teamRanks;
public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks)
public function __construct(TrueSkillFactorGraph $parentGraph, private readonly array $_teamRanks)
{
parent::__construct($parentGraph);
$this->_teamRanks = $teamRanks;
$gameInfo = $this->getParentFactorGraph()->getGameInfo();
$this->_epsilon = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta());
}
@ -24,7 +21,7 @@ class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
public function buildLayer()
{
$inputVarGroups = $this->getInputVariablesGroups();
$inputVarGroupsCount = count($inputVarGroups);
$inputVarGroupsCount = is_countable($inputVarGroups) ? count($inputVarGroups) : 0;
for ($i = 0; $i < $inputVarGroupsCount; $i++) {
$isDraw = ($this->_teamRanks[$i] == $this->_teamRanks[$i + 1]);

View File

@ -8,15 +8,10 @@ use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
{
public function __construct(TrueSkillFactorGraph $parentGraph)
{
parent::__construct($parentGraph);
}
public function buildLayer()
{
$inputVariablesGroups = $this->getInputVariablesGroups();
$inputVariablesGroupsCount = count($inputVariablesGroups);
$inputVariablesGroupsCount = is_countable($inputVariablesGroups) ? count($inputVariablesGroups) : 0;
$outputVariablesGroup = &$this->getOutputVariablesGroups();
for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++) {
@ -44,8 +39,6 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
private function createOutputVariable()
{
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team performance difference');
return $outputVariable;
return $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team performance difference');
}
}

View File

@ -19,20 +19,15 @@ use DNW\Skills\TrueSkill\Layers\TeamPerformancesToTeamPerformanceDifferencesLaye
class TrueSkillFactorGraph extends FactorGraph
{
private $_gameInfo;
private $_layers;
private $_priorLayer;
public function __construct(GameInfo $gameInfo, array $teams, array $teamRanks)
public function __construct(private readonly GameInfo $_gameInfo, array $teams, array $teamRanks)
{
$this->_priorLayer = new PlayerPriorValuesToSkillsLayer($this, $teams);
$this->_gameInfo = $gameInfo;
$newFactory = new VariableFactory(
function () {
return GaussianDistribution::fromPrecisionMean(0, 0);
});
fn() => GaussianDistribution::fromPrecisionMean(0, 0));
$this->setVariableFactory($newFactory);
$this->_layers = [
@ -70,7 +65,7 @@ class TrueSkillFactorGraph extends FactorGraph
public function runSchedule()
{
$fullSchedule = $this->createFullSchedule();
$fullScheduleDelta = $fullSchedule->visit();
$fullSchedule->visit();
}
public function getProbabilityOfRanking()

View File

@ -72,16 +72,12 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
$totalPlayers = $selfTeam->count() + $otherTeam->count();
$meanGetter = function ($currentRating) {
return $currentRating->getMean();
};
$meanGetter = fn($currentRating) => $currentRating->getMean();
$selfMeanSum = BasicMath::sum($selfTeam->getAllRatings(), $meanGetter);
$otherTeamMeanSum = BasicMath::sum($otherTeam->getAllRatings(), $meanGetter);
$varianceGetter = function ($currentRating) {
return BasicMath::square($currentRating->getStandardDeviation());
};
$varianceGetter = fn($currentRating) => BasicMath::square($currentRating->getStandardDeviation());
$c = sqrt(
BasicMath::sum($selfTeam->getAllRatings(), $varianceGetter)
@ -148,22 +144,18 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
// We've verified that there's just two teams
$team1Ratings = $teams[0]->getAllRatings();
$team1Count = count($team1Ratings);
$team1Count = is_countable($team1Ratings) ? count($team1Ratings) : 0;
$team2Ratings = $teams[1]->getAllRatings();
$team2Count = count($team2Ratings);
$team2Count = is_countable($team2Ratings) ? count($team2Ratings) : 0;
$totalPlayers = $team1Count + $team2Count;
$betaSquared = BasicMath::square($gameInfo->getBeta());
$meanGetter = function ($currentRating) {
return $currentRating->getMean();
};
$meanGetter = fn($currentRating) => $currentRating->getMean();
$varianceGetter = function ($currentRating) {
return BasicMath::square($currentRating->getStandardDeviation());
};
$varianceGetter = fn($currentRating) => BasicMath::square($currentRating->getStandardDeviation());
$team1MeanSum = BasicMath::sum($team1Ratings, $meanGetter);
$team1StdDevSquared = BasicMath::sum($team1Ratings, $varianceGetter);