mirror of
				https://github.com/furyfire/trueskill.git
				synced 2025-11-04 02:02:29 +01:00 
			
		
		
		
	Much stricter coding standards for phpstan, phpstan and psalm.
This commit is contained in:
		@@ -7,7 +7,7 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class for computing the factor graph's normalization constant.
 | 
			
		||||
 */
 | 
			
		||||
class FactorList
 | 
			
		||||
final class FactorList
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Factor[] $list
 | 
			
		||||
@@ -31,11 +31,11 @@ class FactorList
 | 
			
		||||
            $numberOfMessages = $factor->getNumberOfMessages();
 | 
			
		||||
 | 
			
		||||
            for ($j = 0; $j < $numberOfMessages; ++$j) {
 | 
			
		||||
                $sumLogZ += $factor->sendMessageIndex($j);
 | 
			
		||||
                $sumLogZ += (float)$factor->sendMessageIndex($j);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $sumLogS = 0;
 | 
			
		||||
        $sumLogS = 0.0;
 | 
			
		||||
 | 
			
		||||
        foreach ($list as &$currentFactor) {
 | 
			
		||||
            $sumLogS += $currentFactor->getLogNormalization();
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class KeyedVariable extends Variable
 | 
			
		||||
final class KeyedVariable extends Variable
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly mixed $key, mixed $prior)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
 | 
			
		||||
class Message
 | 
			
		||||
final class Message
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private GaussianDistribution $value)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleLoop extends Schedule
 | 
			
		||||
final class ScheduleLoop extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly Schedule $scheduleToLoop, private readonly float $maxDelta)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleSequence extends Schedule
 | 
			
		||||
final class ScheduleSequence extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Schedule[] $schedules
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleStep extends Schedule
 | 
			
		||||
final class ScheduleStep extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly Factor $factor, private readonly int $index)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,9 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class VariableFactory
 | 
			
		||||
final readonly class VariableFactory
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly \Closure $varPriorInitializer)
 | 
			
		||||
    public function __construct(private \Closure $varPriorInitializer)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace DNW\Skills;
 | 
			
		||||
/**
 | 
			
		||||
 * Parameters about the game for calculating the TrueSkill.
 | 
			
		||||
 */
 | 
			
		||||
class GameInfo
 | 
			
		||||
final readonly class GameInfo
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Default initial mean / 6
 | 
			
		||||
@@ -26,11 +26,11 @@ class GameInfo
 | 
			
		||||
    private const float DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly float $initialMean = self::DEFAULT_INITIAL_MEAN,
 | 
			
		||||
        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
 | 
			
		||||
        private float $initialMean = self::DEFAULT_INITIAL_MEAN,
 | 
			
		||||
        private float $initialStdDev = self::DEFAULT_INITIAL_STANDARD_DEVIATION,
 | 
			
		||||
        private float $beta = self::DEFAULT_BETA,
 | 
			
		||||
        private float $dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR,
 | 
			
		||||
        private float $drawProbability = self::DEFAULT_DRAW_PROBABILITY
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ use Exception;
 | 
			
		||||
 *
 | 
			
		||||
 * @see http://www.moserware.com/2008/01/borrowing-ideas-from-3-interesting.html
 | 
			
		||||
 */
 | 
			
		||||
class Guard
 | 
			
		||||
final class Guard
 | 
			
		||||
{
 | 
			
		||||
    public static function argumentIsValidIndex(int $index, int $count, string $parameterName): void
 | 
			
		||||
    {
 | 
			
		||||
@@ -23,7 +23,7 @@ class Guard
 | 
			
		||||
    public static function argumentInRangeInclusive(float $value, float $min, float $max, string $parameterName): void
 | 
			
		||||
    {
 | 
			
		||||
        if (($value < $min) || ($value > $max)) {
 | 
			
		||||
            throw new Exception($parameterName . ' is not in the valid range [' . $min . ', ' . $max . ']');
 | 
			
		||||
            throw new Exception($parameterName . ' is not in the valid range [' . (int)$min . ', ' . (int)$max . ']');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace DNW\Skills;
 | 
			
		||||
/**
 | 
			
		||||
 * Basic hashmap that supports object keys.
 | 
			
		||||
 */
 | 
			
		||||
class HashMap
 | 
			
		||||
final class HashMap
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var mixed[] $hashToValue
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ namespace DNW\Skills\Numerics;
 | 
			
		||||
 * @author    Jeff Moser <jeff@moserware.com>
 | 
			
		||||
 * @copyright 2010 Jeff Moser
 | 
			
		||||
 */
 | 
			
		||||
class BasicMath
 | 
			
		||||
final class BasicMath
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Squares the input (input^2 = input * input)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ namespace DNW\Skills\Numerics;
 | 
			
		||||
 * @author    Jeff Moser <jeff@moserware.com>
 | 
			
		||||
 * @copyright 2010 Jeff Moser
 | 
			
		||||
 */
 | 
			
		||||
class GaussianDistribution
 | 
			
		||||
final class GaussianDistribution
 | 
			
		||||
{
 | 
			
		||||
    private const float DEFAULT_STANDARD_DEVIATION = 1.0;
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +171,7 @@ class GaussianDistribution
 | 
			
		||||
        $meanDifference = $numerator->mean - $denominator->mean;
 | 
			
		||||
 | 
			
		||||
        return log($denominator->variance) + self::M_LOG_SQRT_2_PI - log($varianceDifference) / 2.0 +
 | 
			
		||||
        BasicMath::square($meanDifference) / (2 * $varianceDifference);
 | 
			
		||||
        BasicMath::square($meanDifference) / (2.0 * $varianceDifference);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function at(float $var, float $mean = 0.0, float $standardDeviation = 1.0): float
 | 
			
		||||
@@ -182,7 +182,7 @@ class GaussianDistribution
 | 
			
		||||
        //        stdDev * sqrt(2*pi)
 | 
			
		||||
 | 
			
		||||
        $multiplier = 1.0 / ($standardDeviation * self::M_SQRT_2_PI);
 | 
			
		||||
        $expPart = exp((-1.0 * BasicMath::square($var - $mean)) / (2 * BasicMath::square($standardDeviation)));
 | 
			
		||||
        $expPart = exp((-1.0 * BasicMath::square($var - $mean)) / (2.0 * BasicMath::square($standardDeviation)));
 | 
			
		||||
 | 
			
		||||
        return $multiplier * $expPart;
 | 
			
		||||
    }
 | 
			
		||||
@@ -200,7 +200,7 @@ class GaussianDistribution
 | 
			
		||||
        $z = abs($var);
 | 
			
		||||
 | 
			
		||||
        $t = 2.0 / (2.0 + $z);
 | 
			
		||||
        $ty = 4 * $t - 2;
 | 
			
		||||
        $ty = 4.0 * $t - 2.0;
 | 
			
		||||
 | 
			
		||||
        $coefficients = [
 | 
			
		||||
            -1.3026537197817094,
 | 
			
		||||
@@ -259,8 +259,8 @@ class GaussianDistribution
 | 
			
		||||
            return 100;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $pp = ($p < 1.0) ? $p : 2 - $p;
 | 
			
		||||
        $t = sqrt(-2 * log($pp / 2.0)); // Initial guess
 | 
			
		||||
        $pp = ($p < 1.0) ? $p : 2.0 - $p;
 | 
			
		||||
        $t = sqrt(-2.0 * log($pp / 2.0)); // Initial guess
 | 
			
		||||
        $x = -M_SQRT1_2 * ((2.30753 + $t * 0.27061) / (1.0 + $t * (0.99229 + $t * 0.04481)) - $t);
 | 
			
		||||
 | 
			
		||||
        for ($j = 0; $j < 2; ++$j) {
 | 
			
		||||
@@ -274,6 +274,6 @@ class GaussianDistribution
 | 
			
		||||
    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 * $var);
 | 
			
		||||
        return $mean - M_SQRT2 * $standardDeviation * GaussianDistribution::inverseErrorFunctionCumulativeTo(2.0 * $var);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\Numerics;
 | 
			
		||||
 | 
			
		||||
class IdentityMatrix extends DiagonalMatrix
 | 
			
		||||
final class IdentityMatrix extends DiagonalMatrix
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(int $rows)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -130,10 +130,10 @@ class Matrix
 | 
			
		||||
            // | a b |
 | 
			
		||||
            // | c d |
 | 
			
		||||
            // The determinant is ad - bc
 | 
			
		||||
            $a = $this->getValue(0, 0);
 | 
			
		||||
            $b = $this->getValue(0, 1);
 | 
			
		||||
            $c = $this->getValue(1, 0);
 | 
			
		||||
            $d = $this->getValue(1, 1);
 | 
			
		||||
            $a = (float)$this->getValue(0, 0);
 | 
			
		||||
            $b = (float)$this->getValue(0, 1);
 | 
			
		||||
            $c = (float)$this->getValue(1, 0);
 | 
			
		||||
            $d = (float)$this->getValue(1, 1);
 | 
			
		||||
 | 
			
		||||
            return $a * $d - $b * $c;
 | 
			
		||||
        }
 | 
			
		||||
@@ -148,7 +148,7 @@ class Matrix
 | 
			
		||||
 | 
			
		||||
        // I expand along the first row
 | 
			
		||||
        for ($currentColumn = 0; $currentColumn < $this->columnCount; ++$currentColumn) {
 | 
			
		||||
            $firstRowColValue = $this->getValue(0, $currentColumn);
 | 
			
		||||
            $firstRowColValue = (float)$this->getValue(0, $currentColumn);
 | 
			
		||||
            $cofactor = $this->getCofactor(0, $currentColumn);
 | 
			
		||||
            $itemToAdd = $firstRowColValue * $cofactor;
 | 
			
		||||
            $result += $itemToAdd;
 | 
			
		||||
@@ -201,7 +201,7 @@ class Matrix
 | 
			
		||||
    public function getInverse(): Matrix|SquareMatrix
 | 
			
		||||
    {
 | 
			
		||||
        if (($this->rowCount == 1) && ($this->columnCount == 1)) {
 | 
			
		||||
            return new SquareMatrix(1.0 / $this->getValue(0, 0));
 | 
			
		||||
            return new SquareMatrix(1.0 / (float)$this->getValue(0, 0));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Take the simple approach:
 | 
			
		||||
@@ -240,9 +240,9 @@ class Matrix
 | 
			
		||||
        for ($currentRow = 0; $currentRow < $left->getRowCount(); ++$currentRow) {
 | 
			
		||||
            for ($currentColumn = 0; $currentColumn < $right->getColumnCount(); ++$currentColumn) {
 | 
			
		||||
                $resultMatrix[$currentRow][$currentColumn] =
 | 
			
		||||
                    $left->getValue($currentRow, $currentColumn)
 | 
			
		||||
                    (float)$left->getValue($currentRow, $currentColumn)
 | 
			
		||||
                    +
 | 
			
		||||
                    $right->getValue($currentRow, $currentColumn);
 | 
			
		||||
                    (float)$right->getValue($currentRow, $currentColumn);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -268,8 +268,8 @@ class Matrix
 | 
			
		||||
                $productValue = 0;
 | 
			
		||||
 | 
			
		||||
                for ($vectorIndex = 0; $vectorIndex < $left->getColumnCount(); ++$vectorIndex) {
 | 
			
		||||
                    $leftValue = $left->getValue($currentRow, $vectorIndex);
 | 
			
		||||
                    $rightValue = $right->getValue($vectorIndex, $currentColumn);
 | 
			
		||||
                    $leftValue = (float)$left->getValue($currentRow, $vectorIndex);
 | 
			
		||||
                    $rightValue = (float)$right->getValue($vectorIndex, $currentColumn);
 | 
			
		||||
                    $vectorIndexProduct = $leftValue * $rightValue;
 | 
			
		||||
                    $productValue += $vectorIndexProduct;
 | 
			
		||||
                }
 | 
			
		||||
@@ -339,8 +339,8 @@ class Matrix
 | 
			
		||||
            for ($currentColumn = 0; $currentColumn < $this->columnCount; ++$currentColumn) {
 | 
			
		||||
                $delta =
 | 
			
		||||
                    abs(
 | 
			
		||||
                        $this->getValue($currentRow, $currentColumn) -
 | 
			
		||||
                        $otherMatrix->getValue($currentRow, $currentColumn)
 | 
			
		||||
                        (float)$this->getValue($currentRow, $currentColumn) -
 | 
			
		||||
                        (float)$otherMatrix->getValue($currentRow, $currentColumn)
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                if ($delta > self::ERROR_TOLERANCE) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\Numerics;
 | 
			
		||||
 | 
			
		||||
class SquareMatrix extends Matrix
 | 
			
		||||
final class SquareMatrix extends Matrix
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(float|int ...$allValues)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\Numerics;
 | 
			
		||||
 | 
			
		||||
class Vector extends Matrix
 | 
			
		||||
final class Vector extends Matrix
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @param float[] $vectorValues
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills;
 | 
			
		||||
 | 
			
		||||
class PartialPlay
 | 
			
		||||
final class PartialPlay
 | 
			
		||||
{
 | 
			
		||||
    public static function getPartialPlayPercentage(Player $player): float
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,15 +7,15 @@ namespace DNW\Skills;
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a player who has a Rating.
 | 
			
		||||
 */
 | 
			
		||||
class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
final readonly class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
{
 | 
			
		||||
    private const float DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time
 | 
			
		||||
 | 
			
		||||
    private const float DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0;
 | 
			
		||||
 | 
			
		||||
    private readonly float $PartialPlayPct;
 | 
			
		||||
    private float $PartialPlayPct;
 | 
			
		||||
 | 
			
		||||
    private readonly float $PartialUpdatePct;
 | 
			
		||||
    private float $PartialUpdatePct;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a player.
 | 
			
		||||
@@ -25,7 +25,7 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
     * @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,
 | 
			
		||||
        private mixed $Id,
 | 
			
		||||
        float $partialPlayPct = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
 | 
			
		||||
        float $partialUpdatePct = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@ namespace DNW\Skills;
 | 
			
		||||
 | 
			
		||||
use DNW\Skills\Numerics\Range;
 | 
			
		||||
 | 
			
		||||
class PlayersRange extends Range
 | 
			
		||||
final class PlayersRange extends Range
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace DNW\Skills;
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class to sort ranks in non-decreasing order.
 | 
			
		||||
 */
 | 
			
		||||
class RankSorter
 | 
			
		||||
final class RankSorter
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Performs an in-place sort of the items in according to the ranks in non-decreasing order.
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
/**
 | 
			
		||||
 * Container for a player's rating.
 | 
			
		||||
 */
 | 
			
		||||
class Rating
 | 
			
		||||
final readonly class Rating
 | 
			
		||||
{
 | 
			
		||||
    private const float CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3;
 | 
			
		||||
 | 
			
		||||
@@ -18,9 +18,9 @@ class Rating
 | 
			
		||||
     *
 | 
			
		||||
     * @param float     $mean                                    The statistical mean value of the rating (also known as mu).
 | 
			
		||||
     * @param float     $standardDeviation                       The standard deviation of the rating (also known as s).
 | 
			
		||||
     * @param float|int $conservativeStandardDeviationMultiplier optional The number of standardDeviations to subtract from the mean to achieve a conservative rating.
 | 
			
		||||
     * @param float     $conservativeStandardDeviationMultiplier optional The number of standardDeviations to subtract from the mean to achieve a conservative rating.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(private readonly float $mean, private readonly float $standardDeviation, private readonly float|int $conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER)
 | 
			
		||||
    public function __construct(private float $mean, private float $standardDeviation, private float $conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills;
 | 
			
		||||
 | 
			
		||||
class Team extends RatingContainer
 | 
			
		||||
final class Team extends RatingContainer
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(?Player $player = NULL, ?Rating $rating = NULL)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@ namespace DNW\Skills;
 | 
			
		||||
 | 
			
		||||
use DNW\Skills\Numerics\Range;
 | 
			
		||||
 | 
			
		||||
class TeamsRange extends Range
 | 
			
		||||
final class TeamsRange extends Range
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,6 @@ final class DrawMargin
 | 
			
		||||
        //
 | 
			
		||||
        // margin = inversecdf((draw probability + 1)/2) * sqrt(n1+n2) * beta
 | 
			
		||||
        // n1 and n2 are the number of players on each team
 | 
			
		||||
        return GaussianDistribution::inverseCumulativeTo(.5 * ($drawProbability + 1), 0, 1) * M_SQRT2 * $beta;
 | 
			
		||||
        return GaussianDistribution::inverseCumulativeTo(0.5 * ($drawProbability + 1.0), 0.0, 1.0) * M_SQRT2 * $beta;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ use DNW\Skills\Rating;
 | 
			
		||||
/**
 | 
			
		||||
 * Calculates TrueSkill using a full factor graph.
 | 
			
		||||
 */
 | 
			
		||||
class FactorGraphTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
final class FactorGraphTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
{
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
 | 
			
		||||
 *
 | 
			
		||||
 * See the accompanying math paper for more details.
 | 
			
		||||
 */
 | 
			
		||||
class GaussianGreaterThanFactor extends GaussianFactor
 | 
			
		||||
final class GaussianGreaterThanFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly float $epsilon, Variable $variable)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ use Exception;
 | 
			
		||||
 *
 | 
			
		||||
 * See the accompanying math paper for more details.
 | 
			
		||||
 */
 | 
			
		||||
class GaussianLikelihoodFactor extends GaussianFactor
 | 
			
		||||
final class GaussianLikelihoodFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    private readonly float $precision;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
 *
 | 
			
		||||
 * See the accompanying math paper for more details.
 | 
			
		||||
 */
 | 
			
		||||
class GaussianPriorFactor extends GaussianFactor
 | 
			
		||||
final class GaussianPriorFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    private readonly GaussianDistribution $newMessage;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
 *
 | 
			
		||||
 * See the accompanying math paper for more details.
 | 
			
		||||
 */
 | 
			
		||||
class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
final class GaussianWeightedSumFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var array<int[]> $varIndexOrdersForWeights
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
 | 
			
		||||
 *
 | 
			
		||||
 * See the accompanying math paper for more details.
 | 
			
		||||
 */
 | 
			
		||||
class GaussianWithinFactor extends GaussianFactor
 | 
			
		||||
final class GaussianWithinFactor extends GaussianFactor
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly float $epsilon, Variable $variable)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
// The whole purpose of this is to do a loop on the bottom
 | 
			
		||||
class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        TrueSkillFactorGraph $parentGraph,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
 | 
			
		||||
use DNW\Skills\FactorGraphs\Variable;
 | 
			
		||||
use DNW\Skills\FactorGraphs\KeyedVariable;
 | 
			
		||||
 | 
			
		||||
class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    #[\Override]
 | 
			
		||||
    public function buildLayer(): void
 | 
			
		||||
@@ -51,7 +51,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
 | 
			
		||||
    /**
 | 
			
		||||
     * @param KeyedVariable[] $teamMembers
 | 
			
		||||
     */
 | 
			
		||||
    protected function createPlayerToTeamSumFactor(array $teamMembers, Variable $sumVariable): GaussianWeightedSumFactor
 | 
			
		||||
    private function createPlayerToTeamSumFactor(array $teamMembers, Variable $sumVariable): GaussianWeightedSumFactor
 | 
			
		||||
    {
 | 
			
		||||
        $weights = array_map(
 | 
			
		||||
            static function ($v): float {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ use DNW\Skills\FactorGraphs\ScheduleSequence;
 | 
			
		||||
 | 
			
		||||
// We intentionally have no Posterior schedule since the only purpose here is to
 | 
			
		||||
// start the process.
 | 
			
		||||
class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Team[] $teams
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ use DNW\Skills\Numerics\BasicMath;
 | 
			
		||||
use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
 | 
			
		||||
use DNW\Skills\FactorGraphs\ScheduleSequence;
 | 
			
		||||
 | 
			
		||||
class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    #[\Override]
 | 
			
		||||
    public function buildLayer(): void
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ use DNW\Skills\TrueSkill\Factors\GaussianGreaterThanFactor;
 | 
			
		||||
use DNW\Skills\TrueSkill\Factors\GaussianWithinFactor;
 | 
			
		||||
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
 | 
			
		||||
 | 
			
		||||
class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    private readonly float $epsilon;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace DNW\Skills\TrueSkill\Layers;
 | 
			
		||||
use DNW\Skills\FactorGraphs\Variable;
 | 
			
		||||
use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
 | 
			
		||||
 | 
			
		||||
class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
final class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    #[\Override]
 | 
			
		||||
    public function buildLayer(): void
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ use DNW\Skills\TrueSkill\Layers\PlayerSkillsToPerformancesLayer;
 | 
			
		||||
use DNW\Skills\TrueSkill\Layers\TeamDifferencesComparisonLayer;
 | 
			
		||||
use DNW\Skills\TrueSkill\Layers\TeamPerformancesToTeamPerformanceDifferencesLayer;
 | 
			
		||||
 | 
			
		||||
class TrueSkillFactorGraph extends FactorGraph
 | 
			
		||||
final class TrueSkillFactorGraph extends FactorGraph
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var FactorGraphLayer[] $layers
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ namespace DNW\Skills\TrueSkill;
 | 
			
		||||
 | 
			
		||||
use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
 | 
			
		||||
class TruncatedGaussianCorrectionFunctions
 | 
			
		||||
final class TruncatedGaussianCorrectionFunctions
 | 
			
		||||
{
 | 
			
		||||
    // These functions from the bottom of page 4 of the TrueSkill paper.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ use DNW\Skills\TeamsRange;
 | 
			
		||||
 * When you only have two players, a lot of the math simplifies. The main purpose of this class
 | 
			
		||||
 * is to show the bare minimum of what a TrueSkill implementation should have.
 | 
			
		||||
 */
 | 
			
		||||
class TwoPlayerTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
final class TwoPlayerTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
{
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
@@ -95,7 +95,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
            +
 | 
			
		||||
            BasicMath::square($opponentRating->getStandardDeviation())
 | 
			
		||||
            +
 | 
			
		||||
            2 * BasicMath::square($gameInfo->getBeta())
 | 
			
		||||
            2.0 * BasicMath::square($gameInfo->getBeta())
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $winningMean = $selfRating->getMean();
 | 
			
		||||
@@ -131,7 +131,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
        $stdDevMultiplier = $varianceWithDynamics / BasicMath::square($c);
 | 
			
		||||
 | 
			
		||||
        $newMean = $selfRating->getMean() + ($rankMultiplier * $meanMultiplier * $v);
 | 
			
		||||
        $newStdDev = sqrt($varianceWithDynamics * (1 - $w * $stdDevMultiplier));
 | 
			
		||||
        $newStdDev = sqrt($varianceWithDynamics * (1.0 - $w * $stdDevMultiplier));
 | 
			
		||||
 | 
			
		||||
        return new Rating($newMean, $newStdDev);
 | 
			
		||||
    }
 | 
			
		||||
@@ -160,16 +160,16 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
 | 
			
		||||
        // This is the square root part of the equation:
 | 
			
		||||
        $sqrtPart = sqrt(
 | 
			
		||||
            (2 * $betaSquared)
 | 
			
		||||
            (2.0 * $betaSquared)
 | 
			
		||||
            /
 | 
			
		||||
            (2 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared)
 | 
			
		||||
            (2.0 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // This is the exponent part of the equation:
 | 
			
		||||
        $expPart = exp(
 | 
			
		||||
            (-1 * BasicMath::square($player1Rating->getMean() - $player2Rating->getMean()))
 | 
			
		||||
            (-1.0 * BasicMath::square($player1Rating->getMean() - $player2Rating->getMean()))
 | 
			
		||||
            /
 | 
			
		||||
            (2 * (2 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared))
 | 
			
		||||
            (2.0 * (2.0 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared))
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return $sqrtPart * $expPart;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ use DNW\Skills\TeamsRange;
 | 
			
		||||
 *
 | 
			
		||||
 * When you only have two teams, the math is still simple: no factor graphs are used yet.
 | 
			
		||||
 */
 | 
			
		||||
class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
final class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
{
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
@@ -122,7 +122,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
            // assume draw
 | 
			
		||||
            $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c);
 | 
			
		||||
            $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c);
 | 
			
		||||
            $rankMultiplier = 1;
 | 
			
		||||
            $rankMultiplier = 1.0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $selfTeamAllPlayers = $selfTeam->getAllPlayers();
 | 
			
		||||
@@ -137,7 +137,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
            $newMean = $previousPlayerRating->getMean() + $playerMeanDelta;
 | 
			
		||||
 | 
			
		||||
            $newStdDev = sqrt(
 | 
			
		||||
                (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1 - $w * $stdDevMultiplier)
 | 
			
		||||
                (BasicMath::square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1.0 - $w * $stdDevMultiplier)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            $newPlayerRatings->setRating($localSelfTeamCurPlayer, new Rating($newMean, $newStdDev));
 | 
			
		||||
@@ -184,9 +184,9 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $expPart = exp(
 | 
			
		||||
            (-1 * BasicMath::square($team1MeanSum - $team2MeanSum))
 | 
			
		||||
            (-1.0 * BasicMath::square($team1MeanSum - $team2MeanSum))
 | 
			
		||||
            /
 | 
			
		||||
            (2 * ($totalPlayers * $betaSquared + $team1StdDevSquared + $team2StdDevSquared))
 | 
			
		||||
            (2.0 * ($totalPlayers * $betaSquared + $team1StdDevSquared + $team2StdDevSquared))
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return $expPart * $sqrtPart;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user