mirror of
				https://github.com/furyfire/trueskill.git
				synced 2025-11-04 02:02:29 +01:00 
			
		
		
		
	PHPMD reintroduced.
This commit is contained in:
		@@ -15,7 +15,7 @@ abstract class Factor
 | 
			
		||||
     */
 | 
			
		||||
    private array $messages = [];
 | 
			
		||||
 | 
			
		||||
    private readonly HashMap $messageToVariableBinding;
 | 
			
		||||
    private readonly HashMap $msgToVariableBinding;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Variable[] $variables
 | 
			
		||||
@@ -24,7 +24,7 @@ abstract class Factor
 | 
			
		||||
 | 
			
		||||
    protected function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->messageToVariableBinding = new HashMap();
 | 
			
		||||
        $this->msgToVariableBinding = new HashMap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -70,7 +70,7 @@ abstract class Factor
 | 
			
		||||
    {
 | 
			
		||||
        Guard::argumentIsValidIndex($messageIndex, count($this->messages), 'messageIndex');
 | 
			
		||||
        $message = $this->messages[$messageIndex];
 | 
			
		||||
        $variable = $this->messageToVariableBinding->getValue($message);
 | 
			
		||||
        $variable = $this->msgToVariableBinding->getValue($message);
 | 
			
		||||
 | 
			
		||||
        return $this->updateMessageVariable($message, $variable);
 | 
			
		||||
    }
 | 
			
		||||
@@ -85,7 +85,7 @@ abstract class Factor
 | 
			
		||||
     */
 | 
			
		||||
    public function resetMarginals(): void
 | 
			
		||||
    {
 | 
			
		||||
        $allValues = $this->messageToVariableBinding->getAllValues();
 | 
			
		||||
        $allValues = $this->msgToVariableBinding->getAllValues();
 | 
			
		||||
        foreach ($allValues as $currentVariable) {
 | 
			
		||||
            $currentVariable->resetToPrior();
 | 
			
		||||
        }
 | 
			
		||||
@@ -101,7 +101,7 @@ abstract class Factor
 | 
			
		||||
        Guard::argumentIsValidIndex($messageIndex, count($this->messages), 'messageIndex');
 | 
			
		||||
 | 
			
		||||
        $message = $this->messages[$messageIndex];
 | 
			
		||||
        $variable = $this->messageToVariableBinding->getValue($message);
 | 
			
		||||
        $variable = $this->msgToVariableBinding->getValue($message);
 | 
			
		||||
 | 
			
		||||
        return $this->sendMessageVariable($message, $variable);
 | 
			
		||||
    }
 | 
			
		||||
@@ -112,7 +112,7 @@ abstract class Factor
 | 
			
		||||
 | 
			
		||||
    protected function createVariableToMessageBindingWithMessage(Variable $variable, Message $message): Message
 | 
			
		||||
    {
 | 
			
		||||
        $this->messageToVariableBinding->setValue($message, $variable);
 | 
			
		||||
        $this->msgToVariableBinding->setValue($message, $variable);
 | 
			
		||||
        $this->messages[] = $message;
 | 
			
		||||
        $this->variables[] = $variable;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ abstract class FactorGraphLayer
 | 
			
		||||
    /**
 | 
			
		||||
     * @var array<int,array<int,Variable>>
 | 
			
		||||
     */
 | 
			
		||||
    private array $outputVariablesGroups = [];
 | 
			
		||||
    private array $outputVarGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var array<int,array<int,Variable>>
 | 
			
		||||
@@ -48,7 +48,7 @@ abstract class FactorGraphLayer
 | 
			
		||||
     */
 | 
			
		||||
    public function &getOutputVariablesGroups(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->outputVariablesGroups;
 | 
			
		||||
        return $this->outputVarGroups;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -26,12 +26,12 @@ class FactorList
 | 
			
		||||
        $listCount = count($this->list);
 | 
			
		||||
 | 
			
		||||
        for ($i = 0; $i < $listCount; ++$i) {
 | 
			
		||||
            $f = $this->list[$i];
 | 
			
		||||
            $factor = $this->list[$i];
 | 
			
		||||
 | 
			
		||||
            $numberOfMessages = $f->getNumberOfMessages();
 | 
			
		||||
            $numberOfMessages = $factor->getNumberOfMessages();
 | 
			
		||||
 | 
			
		||||
            for ($j = 0; $j < $numberOfMessages; ++$j) {
 | 
			
		||||
                $sumLogZ += $f->sendMessageIndex($j);
 | 
			
		||||
                $sumLogZ += $factor->sendMessageIndex($j);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,20 +6,20 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class VariableFactory
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private \Closure $variablePriorInitializer)
 | 
			
		||||
    public function __construct(private \Closure $varPriorInitializer)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createBasicVariable(): Variable
 | 
			
		||||
    {
 | 
			
		||||
        $initializer = $this->variablePriorInitializer;
 | 
			
		||||
        $initializer = $this->varPriorInitializer;
 | 
			
		||||
 | 
			
		||||
        return new Variable($initializer());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createKeyedVariable(mixed $key): KeyedVariable
 | 
			
		||||
    {
 | 
			
		||||
        $initializer = $this->variablePriorInitializer;
 | 
			
		||||
        $initializer = $this->varPriorInitializer;
 | 
			
		||||
 | 
			
		||||
        return new KeyedVariable($key, $initializer());
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ class GameInfo
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly float $initialMean = self::DEFAULT_INITIAL_MEAN,
 | 
			
		||||
        private readonly float $initialStandardDeviation = self::DEFAULT_INITIAL_STANDARD_DEVIATION,
 | 
			
		||||
        private readonly float $initialStdDev = self::DEFAULT_INITIAL_STANDARD_DEVIATION,
 | 
			
		||||
        private readonly float $beta = self::DEFAULT_BETA,
 | 
			
		||||
        private readonly float $dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR,
 | 
			
		||||
        private readonly float $drawProbability = self::DEFAULT_DRAW_PROBABILITY
 | 
			
		||||
@@ -42,7 +42,7 @@ class GameInfo
 | 
			
		||||
 | 
			
		||||
    public function getInitialStandardDeviation(): float
 | 
			
		||||
    {
 | 
			
		||||
        return $this->initialStandardDeviation;
 | 
			
		||||
        return $this->initialStdDev;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getBeta(): float
 | 
			
		||||
@@ -62,6 +62,6 @@ class GameInfo
 | 
			
		||||
 | 
			
		||||
    public function getDefaultRating(): Rating
 | 
			
		||||
    {
 | 
			
		||||
        return new Rating($this->initialMean, $this->initialStandardDeviation);
 | 
			
		||||
        return new Rating($this->initialMean, $this->initialStdDev);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,15 +13,15 @@ namespace DNW\Skills\Numerics;
 | 
			
		||||
class BasicMath
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Squares the input (x^2 = x * x)
 | 
			
		||||
     * Squares the input (input^2 = input * input)
 | 
			
		||||
     *
 | 
			
		||||
     * @param $x Value to square (x)
 | 
			
		||||
     * @param $input Value to square (input)
 | 
			
		||||
     *
 | 
			
		||||
     * @return float The squared value (x^2)
 | 
			
		||||
     * @return float The squared value (input^2)
 | 
			
		||||
     */
 | 
			
		||||
    public static function square(float $x): float
 | 
			
		||||
    public static function square(float $input): float
 | 
			
		||||
    {
 | 
			
		||||
        return $x * $x;
 | 
			
		||||
        return $input * $input;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,6 @@ class GaussianDistribution
 | 
			
		||||
            $this->precisionMean = $this->precision * $this->mean;
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->precision = \INF;
 | 
			
		||||
 | 
			
		||||
            $this->precisionMean = $this->mean == 0 ? 0 : \INF;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -175,7 +174,7 @@ class GaussianDistribution
 | 
			
		||||
        BasicMath::square($meanDifference) / (2 * $varianceDifference);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function at(float $x, float $mean = 0.0, float $standardDeviation = 1.0): float
 | 
			
		||||
    public static function at(float $var, float $mean = 0.0, float $standardDeviation = 1.0): float
 | 
			
		||||
    {
 | 
			
		||||
        // See http://mathworld.wolfram.com/NormalDistribution.html
 | 
			
		||||
        //                1              -(x-mean)^2 / (2*stdDev^2)
 | 
			
		||||
@@ -183,22 +182,22 @@ class GaussianDistribution
 | 
			
		||||
        //        stdDev * sqrt(2*pi)
 | 
			
		||||
 | 
			
		||||
        $multiplier = 1.0 / ($standardDeviation * self::M_SQRT_2_PI);
 | 
			
		||||
        $expPart = exp((-1.0 * BasicMath::square($x - $mean)) / (2 * BasicMath::square($standardDeviation)));
 | 
			
		||||
        $expPart = exp((-1.0 * BasicMath::square($var - $mean)) / (2 * BasicMath::square($standardDeviation)));
 | 
			
		||||
 | 
			
		||||
        return $multiplier * $expPart;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function cumulativeTo(float $x): float
 | 
			
		||||
    public static function cumulativeTo(float $var): float
 | 
			
		||||
    {
 | 
			
		||||
        $result = GaussianDistribution::errorFunctionCumulativeTo(-M_SQRT1_2 * $x);
 | 
			
		||||
        $result = GaussianDistribution::errorFunctionCumulativeTo(-M_SQRT1_2 * $var);
 | 
			
		||||
 | 
			
		||||
        return 0.5 * $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static function errorFunctionCumulativeTo(float $x): float
 | 
			
		||||
    private static function errorFunctionCumulativeTo(float $var): float
 | 
			
		||||
    {
 | 
			
		||||
        // Derived from page 265 of Numerical Recipes 3rd Edition
 | 
			
		||||
        $z = abs($x);
 | 
			
		||||
        $z = abs($var);
 | 
			
		||||
 | 
			
		||||
        $t = 2.0 / (2.0 + $z);
 | 
			
		||||
        $ty = 4 * $t - 2;
 | 
			
		||||
@@ -246,7 +245,7 @@ class GaussianDistribution
 | 
			
		||||
 | 
			
		||||
        $ans = $t * exp(-$z * $z + 0.5 * ($coefficients[0] + $ty * $d) - $dd);
 | 
			
		||||
 | 
			
		||||
        return ($x >= 0.0) ? $ans : (2.0 - $ans);
 | 
			
		||||
        return ($var >= 0.0) ? $ans : (2.0 - $ans);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static function inverseErrorFunctionCumulativeTo(float $p): float
 | 
			
		||||
@@ -272,9 +271,9 @@ class GaussianDistribution
 | 
			
		||||
        return ($p < 1.0) ? $x : -$x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function inverseCumulativeTo(float $x, float $mean = 0.0, float $standardDeviation = 1.0): float
 | 
			
		||||
    public static function inverseCumulativeTo(float $var, float $mean = 0.0, float $standardDeviation = 1.0): float
 | 
			
		||||
    {
 | 
			
		||||
        // From numerical recipes, page 320
 | 
			
		||||
        return $mean - M_SQRT2 * $standardDeviation * GaussianDistribution::inverseErrorFunctionCumulativeTo(2 * $x);
 | 
			
		||||
        return $mean - M_SQRT2 * $standardDeviation * GaussianDistribution::inverseErrorFunctionCumulativeTo(2 * $var);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -76,10 +76,10 @@ class Matrix
 | 
			
		||||
        $transposeMatrix = [];
 | 
			
		||||
 | 
			
		||||
        $rowMatrixData = $this->matrixRowData;
 | 
			
		||||
        for ($currentRowTransposeMatrix = 0; $currentRowTransposeMatrix < $this->columnCount; ++$currentRowTransposeMatrix) {
 | 
			
		||||
            for ($currentColumnTransposeMatrix = 0; $currentColumnTransposeMatrix < $this->rowCount; ++$currentColumnTransposeMatrix) {
 | 
			
		||||
                $transposeMatrix[$currentRowTransposeMatrix][$currentColumnTransposeMatrix] =
 | 
			
		||||
                    $rowMatrixData[$currentColumnTransposeMatrix][$currentRowTransposeMatrix];
 | 
			
		||||
        for ($curRowTransposeMx = 0; $curRowTransposeMx < $this->columnCount; ++$curRowTransposeMx) {
 | 
			
		||||
            for ($curColTransposeMx = 0; $curColTransposeMx < $this->rowCount; ++$curColTransposeMx) {
 | 
			
		||||
                $transposeMatrix[$curRowTransposeMx][$curColTransposeMx] =
 | 
			
		||||
                    $rowMatrixData[$curColTransposeMx][$curRowTransposeMx];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,14 +8,14 @@ class PartialPlay
 | 
			
		||||
{
 | 
			
		||||
    public static function getPartialPlayPercentage(Player $player): float
 | 
			
		||||
    {
 | 
			
		||||
        $partialPlayPercentage = $player->getPartialPlayPercentage();
 | 
			
		||||
        $partialPlayPct = $player->getPartialPlayPercentage();
 | 
			
		||||
 | 
			
		||||
        // HACK to get around bug near 0
 | 
			
		||||
        $smallestPercentage = 0.0001;
 | 
			
		||||
        if ($partialPlayPercentage < $smallestPercentage) {
 | 
			
		||||
            return $smallestPercentage;
 | 
			
		||||
        $smallestPct = 0.0001;
 | 
			
		||||
        if ($partialPlayPct < $smallestPct) {
 | 
			
		||||
            return $smallestPct;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $partialPlayPercentage;
 | 
			
		||||
        return $partialPlayPct;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,27 +13,27 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
 | 
			
		||||
    private const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0;
 | 
			
		||||
 | 
			
		||||
    private readonly float $PartialPlayPercentage;
 | 
			
		||||
    private readonly float $PartialPlayPct;
 | 
			
		||||
 | 
			
		||||
    private readonly float $PartialUpdatePercentage;
 | 
			
		||||
    private readonly float $PartialUpdatePct;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a player.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|int $Id                      The identifier for the player, such as a name.
 | 
			
		||||
     * @param float $partialPlayPercentage   The weight percentage to give this player when calculating a new rank.
 | 
			
		||||
     * @param float $partialUpdatePercentage Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update.
 | 
			
		||||
     * @param float $partialPlayPct   The weight percentage to give this player when calculating a new rank.
 | 
			
		||||
     * @param float $partialUpdatePct Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly mixed $Id,
 | 
			
		||||
        float $partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
 | 
			
		||||
        float $partialUpdatePercentage = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE
 | 
			
		||||
        float $partialPlayPct = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
 | 
			
		||||
        float $partialUpdatePct = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, 'partialPlayPercentage');
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, 'partialUpdatePercentage');
 | 
			
		||||
        $this->PartialPlayPercentage = $partialPlayPercentage;
 | 
			
		||||
        $this->PartialUpdatePercentage = $partialUpdatePercentage;
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialPlayPct, 0.0, 1.0, 'partialPlayPercentage');
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialUpdatePct, 0, 1.0, 'partialUpdatePercentage');
 | 
			
		||||
        $this->PartialPlayPct = $partialPlayPct;
 | 
			
		||||
        $this->PartialUpdatePct = $partialUpdatePct;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -49,7 +49,7 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
     */
 | 
			
		||||
    public function getPartialPlayPercentage(): float
 | 
			
		||||
    {
 | 
			
		||||
        return $this->PartialPlayPercentage;
 | 
			
		||||
        return $this->PartialPlayPct;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -57,6 +57,6 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
     */
 | 
			
		||||
    public function getPartialUpdatePercentage(): float
 | 
			
		||||
    {
 | 
			
		||||
        return $this->PartialUpdatePercentage;
 | 
			
		||||
        return $this->PartialUpdatePct;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -171,7 +171,8 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
 | 
			
		||||
        $currentColumn = 0;
 | 
			
		||||
 | 
			
		||||
        for ($i = 0; $i < count($teamAssignmentsList) - 1; ++$i) {
 | 
			
		||||
        $teamCnt = count($teamAssignmentsList);
 | 
			
		||||
        for ($i = 0; $i < $teamCnt - 1; ++$i) {
 | 
			
		||||
            $currentTeam = $teamAssignmentsList[$i];
 | 
			
		||||
 | 
			
		||||
            // Need to add in 0's for all the previous players, since they're not
 | 
			
		||||
 
 | 
			
		||||
@@ -60,9 +60,9 @@ class GaussianLikelihoodFactor extends GaussianFactor
 | 
			
		||||
            $a * ($marginal2->getPrecision() - $message2Value->getPrecision())
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $oldMarginalWithoutMessage = GaussianDistribution::divide($marginal1, $message1Value);
 | 
			
		||||
        $oldMarginalWithoutMsg = GaussianDistribution::divide($marginal1, $message1Value);
 | 
			
		||||
 | 
			
		||||
        $newMarginal = GaussianDistribution::multiply($oldMarginalWithoutMessage, $newMessage);
 | 
			
		||||
        $newMarginal = GaussianDistribution::multiply($oldMarginalWithoutMsg, $newMessage);
 | 
			
		||||
 | 
			
		||||
        // Update the message and marginal
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,9 @@ use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var array<int[]> $variableIndexOrdersForWeights
 | 
			
		||||
     * @var array<int[]> $varIndexOrdersForWeights
 | 
			
		||||
     */
 | 
			
		||||
    private array $variableIndexOrdersForWeights = [];
 | 
			
		||||
    private array $varIndexOrdersForWeights = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This following is used for convenience, for example, the first entry is [0, 1, 2]
 | 
			
		||||
@@ -58,9 +58,9 @@ class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
        $variablesToSumLength = count($variablesToSum);
 | 
			
		||||
 | 
			
		||||
        // 0..n-1
 | 
			
		||||
        $this->variableIndexOrdersForWeights[0] = [];
 | 
			
		||||
        $this->varIndexOrdersForWeights[0] = [];
 | 
			
		||||
        for ($i = 0; $i < ($variablesToSumLength + 1); ++$i) {
 | 
			
		||||
            $this->variableIndexOrdersForWeights[0][] = $i;
 | 
			
		||||
            $this->varIndexOrdersForWeights[0][] = $i;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $variableWeightsLength = count($variableWeights);
 | 
			
		||||
@@ -113,7 +113,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
            $currentWeights[$currentDestinationWeightIndex] = $finalWeight;
 | 
			
		||||
            $currentWeightsSquared[$currentDestinationWeightIndex] = BasicMath::square($finalWeight);
 | 
			
		||||
            $variableIndices[count($variableWeights)] = 0;
 | 
			
		||||
            $this->variableIndexOrdersForWeights[] = $variableIndices;
 | 
			
		||||
            $this->varIndexOrdersForWeights[] = $variableIndices;
 | 
			
		||||
 | 
			
		||||
            $this->weights[$weightsIndex] = $currentWeights;
 | 
			
		||||
            $this->weightsSquared[$weightsIndex] = $currentWeightsSquared;
 | 
			
		||||
@@ -160,9 +160,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
 | 
			
		||||
        // The math works out so that 1/newPrecision = sum of a_i^2 /marginalsWithoutMessages[i]
 | 
			
		||||
        $inverseOfNewPrecisionSum = 0.0;
 | 
			
		||||
        $anotherInverseOfNewPrecisionSum = 0.0;
 | 
			
		||||
        $weightedMeanSum = 0.0;
 | 
			
		||||
        $anotherWeightedMeanSum = 0.0;
 | 
			
		||||
 | 
			
		||||
        $weightsSquaredLength = count($weightsSquared);
 | 
			
		||||
 | 
			
		||||
@@ -172,16 +170,11 @@ class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
            $inverseOfNewPrecisionSum += $weightsSquared[$i] /
 | 
			
		||||
                ($variables[$i + 1]->getValue()->getPrecision() - $messages[$i + 1]->getValue()->getPrecision());
 | 
			
		||||
 | 
			
		||||
            $diff = GaussianDistribution::divide($variables[$i + 1]->getValue(), $messages[$i + 1]->getValue());
 | 
			
		||||
            $anotherInverseOfNewPrecisionSum += $weightsSquared[$i] / $diff->getPrecision();
 | 
			
		||||
 | 
			
		||||
            $weightedMeanSum += $weights[$i]
 | 
			
		||||
                *
 | 
			
		||||
                ($variables[$i + 1]->getValue()->getPrecisionMean() - $messages[$i + 1]->getValue()->getPrecisionMean())
 | 
			
		||||
                /
 | 
			
		||||
                ($variables[$i + 1]->getValue()->getPrecision() - $messages[$i + 1]->getValue()->getPrecision());
 | 
			
		||||
 | 
			
		||||
            $anotherWeightedMeanSum += $weights[$i] * $diff->getPrecisionMean() / $diff->getPrecision();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $newPrecision = 1.0 / $inverseOfNewPrecisionSum;
 | 
			
		||||
@@ -214,7 +207,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
        $updatedMessages = [];
 | 
			
		||||
        $updatedVariables = [];
 | 
			
		||||
 | 
			
		||||
        $indicesToUse = $this->variableIndexOrdersForWeights[$messageIndex];
 | 
			
		||||
        $indicesToUse = $this->varIndexOrdersForWeights[$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
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,8 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        TrueSkillFactorGraph $parentGraph,
 | 
			
		||||
        private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $TeamPerformancesToTeamPerformanceDifferencesLayer,
 | 
			
		||||
        private readonly TeamDifferencesComparisonLayer $TeamDifferencesComparisonLayer
 | 
			
		||||
        private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $teamPerformancesToTeamPerformanceDifferencesLayer,
 | 
			
		||||
        private readonly TeamDifferencesComparisonLayer $teamDifferencesComparisonLayer
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($parentGraph);
 | 
			
		||||
@@ -25,20 +25,20 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
    public function getLocalFactors(): array
 | 
			
		||||
    {
 | 
			
		||||
        return array_merge(
 | 
			
		||||
            $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
 | 
			
		||||
            $this->TeamDifferencesComparisonLayer->getLocalFactors()
 | 
			
		||||
            $this->teamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
 | 
			
		||||
            $this->teamDifferencesComparisonLayer->getLocalFactors()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildLayer(): void
 | 
			
		||||
    {
 | 
			
		||||
        $inputVariablesGroups = $this->getInputVariablesGroups();
 | 
			
		||||
        $this->TeamPerformancesToTeamPerformanceDifferencesLayer->setInputVariablesGroups($inputVariablesGroups);
 | 
			
		||||
        $this->TeamPerformancesToTeamPerformanceDifferencesLayer->buildLayer();
 | 
			
		||||
        $this->teamPerformancesToTeamPerformanceDifferencesLayer->setInputVariablesGroups($inputVariablesGroups);
 | 
			
		||||
        $this->teamPerformancesToTeamPerformanceDifferencesLayer->buildLayer();
 | 
			
		||||
 | 
			
		||||
        $teamDifferencesOutputVariablesGroups = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
 | 
			
		||||
        $this->TeamDifferencesComparisonLayer->setInputVariablesGroups($teamDifferencesOutputVariablesGroups);
 | 
			
		||||
        $this->TeamDifferencesComparisonLayer->buildLayer();
 | 
			
		||||
        $teamDifferencesOutputVariablesGroups = $this->teamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
 | 
			
		||||
        $this->teamDifferencesComparisonLayer->setInputVariablesGroups($teamDifferencesOutputVariablesGroups);
 | 
			
		||||
        $this->teamDifferencesComparisonLayer->buildLayer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createPriorSchedule(): ?ScheduleSequence
 | 
			
		||||
@@ -56,9 +56,9 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // When dealing with differences, there are always (n-1) differences, so add in the 1
 | 
			
		||||
        $totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
 | 
			
		||||
        $totalTeamDifferences = count($this->teamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
 | 
			
		||||
 | 
			
		||||
        $localFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
 | 
			
		||||
        $localFactors = $this->teamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
 | 
			
		||||
 | 
			
		||||
        $firstDifferencesFactor = $localFactors[0];
 | 
			
		||||
        $lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
 | 
			
		||||
@@ -83,8 +83,8 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
 | 
			
		||||
    private function createTwoTeamInnerPriorLoopSchedule(): ScheduleSequence
 | 
			
		||||
    {
 | 
			
		||||
        $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
 | 
			
		||||
        $teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
 | 
			
		||||
        $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->teamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
 | 
			
		||||
        $teamDifferencesComparisonLayerLocalFactors = $this->teamDifferencesComparisonLayer->getLocalFactors();
 | 
			
		||||
 | 
			
		||||
        $firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
 | 
			
		||||
        $firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0];
 | 
			
		||||
@@ -109,13 +109,13 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
 | 
			
		||||
    private function createMultipleTeamInnerPriorLoopSchedule(): ScheduleLoop
 | 
			
		||||
    {
 | 
			
		||||
        $totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
 | 
			
		||||
        $totalTeamDifferences = count($this->teamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
 | 
			
		||||
 | 
			
		||||
        $forwardScheduleList = [];
 | 
			
		||||
 | 
			
		||||
        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];
 | 
			
		||||
@@ -151,8 +151,8 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
        $backwardScheduleList = [];
 | 
			
		||||
 | 
			
		||||
        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];
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,8 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
 | 
			
		||||
            $this->addLayerFactor($newSumFactor);
 | 
			
		||||
 | 
			
		||||
            // REVIEW: Does it make sense to have groups of one?
 | 
			
		||||
            $outputVariablesGroups = &$this->getOutputVariablesGroups();
 | 
			
		||||
            $outputVariablesGroups[] = [$teamPerformance];
 | 
			
		||||
            $outputVarGroups = &$this->getOutputVariablesGroups();
 | 
			
		||||
            $outputVarGroups[] = [$teamPerformance];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,12 +34,12 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
            $localCurrentTeam = $currentTeam;
 | 
			
		||||
            $currentTeamSkills = [];
 | 
			
		||||
 | 
			
		||||
            $currentTeamAllPlayers = $localCurrentTeam->getAllPlayers();
 | 
			
		||||
            foreach ($currentTeamAllPlayers as $currentTeamPlayer) {
 | 
			
		||||
                $localCurrentTeamPlayer = $currentTeamPlayer;
 | 
			
		||||
                $currentTeamPlayerRating = $currentTeam->getRating($localCurrentTeamPlayer);
 | 
			
		||||
                $playerSkill = $this->createSkillOutputVariable($localCurrentTeamPlayer);
 | 
			
		||||
                $priorFactor = $this->createPriorFactor($currentTeamPlayerRating, $playerSkill);
 | 
			
		||||
            $curTeamAllPlayers = $localCurrentTeam->getAllPlayers();
 | 
			
		||||
            foreach ($curTeamAllPlayers as $curTeamPlayer) {
 | 
			
		||||
                $localCurTeamPlayer = $curTeamPlayer;
 | 
			
		||||
                $curTeamPlayerRating = $currentTeam->getRating($localCurTeamPlayer);
 | 
			
		||||
                $playerSkill = $this->createSkillOutputVariable($localCurTeamPlayer);
 | 
			
		||||
                $priorFactor = $this->createPriorFactor($curTeamPlayerRating, $playerSkill);
 | 
			
		||||
                $this->addLayerFactor($priorFactor);
 | 
			
		||||
                $currentTeamSkills[] = $playerSkill;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,25 +15,25 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    public function buildLayer(): void
 | 
			
		||||
    {
 | 
			
		||||
        $inputVariablesGroups = $this->getInputVariablesGroups();
 | 
			
		||||
        $outputVariablesGroups = &$this->getOutputVariablesGroups();
 | 
			
		||||
        $inputVarGroups = $this->getInputVariablesGroups();
 | 
			
		||||
        $outputVarGroups = &$this->getOutputVariablesGroups();
 | 
			
		||||
 | 
			
		||||
        foreach ($inputVariablesGroups as $currentTeam) {
 | 
			
		||||
        foreach ($inputVarGroups as $currentTeam) {
 | 
			
		||||
            $currentTeamPlayerPerformances = [];
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * @var Variable $playerSkillVariable
 | 
			
		||||
             * @var Variable $playerSkillVar
 | 
			
		||||
             */
 | 
			
		||||
            foreach ($currentTeam as $playerSkillVariable) {
 | 
			
		||||
                $localPlayerSkillVariable = $playerSkillVariable;
 | 
			
		||||
                $currentPlayer = ($localPlayerSkillVariable instanceof KeyedVariable) ? $localPlayerSkillVariable->getKey() : "";
 | 
			
		||||
            foreach ($currentTeam as $playerSkillVar) {
 | 
			
		||||
                $localPlayerSkillVar = $playerSkillVar;
 | 
			
		||||
                $currentPlayer = ($localPlayerSkillVar instanceof KeyedVariable) ? $localPlayerSkillVar->getKey() : "";
 | 
			
		||||
                $playerPerformance = $this->createOutputVariable($currentPlayer);
 | 
			
		||||
                $newLikelihoodFactor = $this->createLikelihood($localPlayerSkillVariable, $playerPerformance);
 | 
			
		||||
                $newLikelihoodFactor = $this->createLikelihood($localPlayerSkillVar, $playerPerformance);
 | 
			
		||||
                $this->addLayerFactor($newLikelihoodFactor);
 | 
			
		||||
                $currentTeamPlayerPerformances[] = $playerPerformance;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $outputVariablesGroups[] = $currentTeamPlayerPerformances;
 | 
			
		||||
            $outputVarGroups[] = $currentTeamPlayerPerformances;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -118,9 +118,9 @@ class TrueSkillFactorGraph extends FactorGraph
 | 
			
		||||
        $allLayersReverse = array_reverse($this->layers);
 | 
			
		||||
 | 
			
		||||
        foreach ($allLayersReverse as $currentLayer) {
 | 
			
		||||
            $currentPosteriorSchedule = $currentLayer->createPosteriorSchedule();
 | 
			
		||||
            if ($currentPosteriorSchedule != NULL) {
 | 
			
		||||
                $fullSchedule[] = $currentPosteriorSchedule;
 | 
			
		||||
            $curPosteriorSchedule = $currentLayer->createPosteriorSchedule();
 | 
			
		||||
            if ($curPosteriorSchedule != NULL) {
 | 
			
		||||
                $fullSchedule[] = $curPosteriorSchedule;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -102,33 +102,33 @@ class TruncatedGaussianCorrectionFunctions
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // the multiplicative correction of a double-sided truncated Gaussian with unit variance
 | 
			
		||||
    public static function wWithinMarginScaled(float $teamPerformanceDifference, float $drawMargin, float $c): float
 | 
			
		||||
    public static function wWithinMarginScaled(float $teamPerformanceDiff, float $drawMargin, float $c): float
 | 
			
		||||
    {
 | 
			
		||||
        return self::wWithinMargin($teamPerformanceDifference / $c, $drawMargin / $c);
 | 
			
		||||
        return self::wWithinMargin($teamPerformanceDiff / $c, $drawMargin / $c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // From F#:
 | 
			
		||||
    public static function wWithinMargin(float $teamPerformanceDifference, float $drawMargin): float
 | 
			
		||||
    public static function wWithinMargin(float $teamPerformanceDiff, float $drawMargin): float
 | 
			
		||||
    {
 | 
			
		||||
        $teamPerformanceDifferenceAbsoluteValue = abs($teamPerformanceDifference);
 | 
			
		||||
        $denominator = GaussianDistribution::cumulativeTo($drawMargin - $teamPerformanceDifferenceAbsoluteValue)
 | 
			
		||||
        $teamPerformanceDiffAbsValue = abs($teamPerformanceDiff);
 | 
			
		||||
        $denominator = GaussianDistribution::cumulativeTo($drawMargin - $teamPerformanceDiffAbsValue)
 | 
			
		||||
            -
 | 
			
		||||
            GaussianDistribution::cumulativeTo(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue);
 | 
			
		||||
            GaussianDistribution::cumulativeTo(-$drawMargin - $teamPerformanceDiffAbsValue);
 | 
			
		||||
 | 
			
		||||
        if ($denominator < 2.222758749e-162) {
 | 
			
		||||
            return 1.0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $vt = self::vWithinMargin($teamPerformanceDifferenceAbsoluteValue, $drawMargin);
 | 
			
		||||
        $vt = self::vWithinMargin($teamPerformanceDiffAbsValue, $drawMargin);
 | 
			
		||||
 | 
			
		||||
        return $vt * $vt +
 | 
			
		||||
        (($drawMargin - $teamPerformanceDifferenceAbsoluteValue)
 | 
			
		||||
        (($drawMargin - $teamPerformanceDiffAbsValue)
 | 
			
		||||
            *
 | 
			
		||||
            GaussianDistribution::at(
 | 
			
		||||
                $drawMargin - $teamPerformanceDifferenceAbsoluteValue
 | 
			
		||||
                $drawMargin - $teamPerformanceDiffAbsValue
 | 
			
		||||
            )
 | 
			
		||||
            - (-$drawMargin - $teamPerformanceDifferenceAbsoluteValue)
 | 
			
		||||
            - (-$drawMargin - $teamPerformanceDiffAbsValue)
 | 
			
		||||
            *
 | 
			
		||||
            GaussianDistribution::at(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue)) / $denominator;
 | 
			
		||||
            GaussianDistribution::at(-$drawMargin - $teamPerformanceDiffAbsValue)) / $denominator;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -125,9 +125,9 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $selfTeamAllPlayers = $selfTeam->getAllPlayers();
 | 
			
		||||
        foreach ($selfTeamAllPlayers as $selfTeamCurrentPlayer) {
 | 
			
		||||
            $localSelfTeamCurrentPlayer = $selfTeamCurrentPlayer;
 | 
			
		||||
            $previousPlayerRating = $selfTeam->getRating($localSelfTeamCurrentPlayer);
 | 
			
		||||
        foreach ($selfTeamAllPlayers as $selfTeamCurPlayer) {
 | 
			
		||||
            $localSelfTeamCurPlayer = $selfTeamCurPlayer;
 | 
			
		||||
            $previousPlayerRating = $selfTeam->getRating($localSelfTeamCurPlayer);
 | 
			
		||||
 | 
			
		||||
            $meanMultiplier = (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / $c;
 | 
			
		||||
            $stdDevMultiplier = (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / BasicMath::square($c);
 | 
			
		||||
@@ -139,7 +139,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
                (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1 - $w * $stdDevMultiplier)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            $newPlayerRatings->setRating($localSelfTeamCurrentPlayer, new Rating($newMean, $newStdDev));
 | 
			
		||||
            $newPlayerRatings->setRating($localSelfTeamCurPlayer, new Rating($newMean, $newStdDev));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user