mirror of
				https://github.com/furyfire/trueskill.git
				synced 2025-11-04 10:12:28 +01:00 
			
		
		
		
	Upgrade with rector
This commit is contained in:
		@@ -17,7 +17,7 @@ class DefaultVariable extends Variable
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setValue($value)
 | 
			
		||||
    public function setValue($value): never
 | 
			
		||||
    {
 | 
			
		||||
        throw new Exception();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,15 +6,15 @@ use DNW\Skills\Guard;
 | 
			
		||||
use DNW\Skills\HashMap;
 | 
			
		||||
use Exception;
 | 
			
		||||
 | 
			
		||||
abstract class Factor
 | 
			
		||||
abstract class Factor implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    private $_messages = [];
 | 
			
		||||
    private array $_messages = [];
 | 
			
		||||
 | 
			
		||||
    private $_messageToVariableBinding;
 | 
			
		||||
 | 
			
		||||
    private $_name;
 | 
			
		||||
 | 
			
		||||
    private $_variables = [];
 | 
			
		||||
    private array $_variables = [];
 | 
			
		||||
 | 
			
		||||
    protected function __construct($name)
 | 
			
		||||
    {
 | 
			
		||||
@@ -111,7 +111,7 @@ abstract class Factor
 | 
			
		||||
        return $message;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->_name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,17 +5,14 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
// edit this
 | 
			
		||||
abstract class FactorGraphLayer
 | 
			
		||||
{
 | 
			
		||||
    private $_localFactors = [];
 | 
			
		||||
    private array $_localFactors = [];
 | 
			
		||||
 | 
			
		||||
    private $_outputVariablesGroups = [];
 | 
			
		||||
    private array $_outputVariablesGroups = [];
 | 
			
		||||
 | 
			
		||||
    private $_inputVariablesGroups = [];
 | 
			
		||||
 | 
			
		||||
    private $_parentFactorGraph;
 | 
			
		||||
 | 
			
		||||
    protected function __construct(FactorGraph $parentGraph)
 | 
			
		||||
    protected function __construct(private readonly FactorGraph $_parentFactorGraph)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_parentFactorGraph = $parentGraph;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getInputVariablesGroups()
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 */
 | 
			
		||||
class FactorList
 | 
			
		||||
{
 | 
			
		||||
    private $_list = [];
 | 
			
		||||
    private array $_list = [];
 | 
			
		||||
 | 
			
		||||
    public function getLogNormalization()
 | 
			
		||||
    {
 | 
			
		||||
@@ -33,7 +33,7 @@ class FactorList
 | 
			
		||||
        $sumLogS = 0;
 | 
			
		||||
 | 
			
		||||
        foreach ($list as &$currentFactor) {
 | 
			
		||||
            $sumLogS = $sumLogS + $currentFactor->getLogNormalization();
 | 
			
		||||
            $sumLogS += $currentFactor->getLogNormalization();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $sumLogZ + $sumLogS;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,9 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class KeyedVariable extends Variable
 | 
			
		||||
{
 | 
			
		||||
    private $_key;
 | 
			
		||||
 | 
			
		||||
    public function __construct($key, $name, $prior)
 | 
			
		||||
    public function __construct(private $_key, $name, $prior)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($name, $prior);
 | 
			
		||||
        $this->_key = $key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKey()
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,10 @@
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class Message
 | 
			
		||||
class Message implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    private $_name;
 | 
			
		||||
 | 
			
		||||
    private $_value;
 | 
			
		||||
 | 
			
		||||
    public function __construct($value = null, $name = null)
 | 
			
		||||
    public function __construct(private $_value = null, private $_name = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_name = $name;
 | 
			
		||||
        $this->_value = $value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getValue()
 | 
			
		||||
@@ -24,7 +18,7 @@ class Message
 | 
			
		||||
        $this->_value = $value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return (string) $this->_name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,19 +2,16 @@
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
abstract class Schedule
 | 
			
		||||
abstract class Schedule implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    private $_name;
 | 
			
		||||
 | 
			
		||||
    protected function __construct($name)
 | 
			
		||||
    protected function __construct(private $_name)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract public function visit($depth = -1, $maxDepth = 0);
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->_name;
 | 
			
		||||
        return (string) $this->_name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,15 +4,9 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleLoop extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    private $_maxDelta;
 | 
			
		||||
 | 
			
		||||
    private $_scheduleToLoop;
 | 
			
		||||
 | 
			
		||||
    public function __construct($name, Schedule $scheduleToLoop, $maxDelta)
 | 
			
		||||
    public function __construct($name, private readonly Schedule $_scheduleToLoop, private $_maxDelta)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($name);
 | 
			
		||||
        $this->_scheduleToLoop = $scheduleToLoop;
 | 
			
		||||
        $this->_maxDelta = $maxDelta;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function visit($depth = -1, $maxDepth = 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,9 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleSequence extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    private $_schedules;
 | 
			
		||||
 | 
			
		||||
    public function __construct($name, array $schedules)
 | 
			
		||||
    public function __construct($name, private readonly array $_schedules)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($name);
 | 
			
		||||
        $this->_schedules = $schedules;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function visit($depth = -1, $maxDepth = 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,22 +4,15 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class ScheduleStep extends Schedule
 | 
			
		||||
{
 | 
			
		||||
    private $_factor;
 | 
			
		||||
 | 
			
		||||
    private $_index;
 | 
			
		||||
 | 
			
		||||
    public function __construct($name, Factor $factor, $index)
 | 
			
		||||
    public function __construct($name, private readonly Factor $_factor, private $_index)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($name);
 | 
			
		||||
        $this->_factor = $factor;
 | 
			
		||||
        $this->_index = $index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function visit($depth = -1, $maxDepth = 0)
 | 
			
		||||
    {
 | 
			
		||||
        $currentFactor = $this->_factor;
 | 
			
		||||
        $delta = $currentFactor->updateMessageIndex($this->_index);
 | 
			
		||||
 | 
			
		||||
        return $delta;
 | 
			
		||||
        return $currentFactor->updateMessageIndex($this->_index);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,18 +2,15 @@
 | 
			
		||||
 | 
			
		||||
namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class Variable
 | 
			
		||||
class Variable implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    private $_name;
 | 
			
		||||
 | 
			
		||||
    private $_prior;
 | 
			
		||||
 | 
			
		||||
    private $_value;
 | 
			
		||||
 | 
			
		||||
    public function __construct($name, $prior)
 | 
			
		||||
    public function __construct($name, private $_prior)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_name = 'Variable['.$name.']';
 | 
			
		||||
        $this->_prior = $prior;
 | 
			
		||||
        $this->resetToPrior();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +29,7 @@ class Variable
 | 
			
		||||
        $this->_value = $this->_prior;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->_name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,27 +4,21 @@ namespace DNW\Skills\FactorGraphs;
 | 
			
		||||
 | 
			
		||||
class VariableFactory
 | 
			
		||||
{
 | 
			
		||||
    // using a Func<TValue> to encourage fresh copies in case it's overwritten
 | 
			
		||||
    private $_variablePriorInitializer;
 | 
			
		||||
 | 
			
		||||
    public function __construct($variablePriorInitializer)
 | 
			
		||||
    public function __construct(private $_variablePriorInitializer)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_variablePriorInitializer = $variablePriorInitializer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createBasicVariable($name)
 | 
			
		||||
    {
 | 
			
		||||
        $initializer = $this->_variablePriorInitializer;
 | 
			
		||||
        $newVar = new Variable($name, $initializer());
 | 
			
		||||
 | 
			
		||||
        return $newVar;
 | 
			
		||||
        return new Variable($name, $initializer());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createKeyedVariable($key, $name)
 | 
			
		||||
    {
 | 
			
		||||
        $initializer = $this->_variablePriorInitializer;
 | 
			
		||||
        $newVar = new KeyedVariable($key, $name, $initializer());
 | 
			
		||||
 | 
			
		||||
        return $newVar;
 | 
			
		||||
        return new KeyedVariable($key, $name, $initializer());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,37 +7,18 @@ namespace DNW\Skills;
 | 
			
		||||
 */
 | 
			
		||||
class GameInfo
 | 
			
		||||
{
 | 
			
		||||
    const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6
 | 
			
		||||
    final const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6
 | 
			
		||||
 | 
			
		||||
    const DEFAULT_DRAW_PROBABILITY = 0.10;
 | 
			
		||||
    final const DEFAULT_DRAW_PROBABILITY = 0.10;
 | 
			
		||||
 | 
			
		||||
    const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300
 | 
			
		||||
    final const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300
 | 
			
		||||
 | 
			
		||||
    const DEFAULT_INITIAL_MEAN = 25.0;
 | 
			
		||||
    final const DEFAULT_INITIAL_MEAN = 25.0;
 | 
			
		||||
 | 
			
		||||
    const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333; // Default initial mean / 3
 | 
			
		||||
    final const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333;
 | 
			
		||||
 | 
			
		||||
    private $_initialMean;
 | 
			
		||||
 | 
			
		||||
    private $_initialStandardDeviation;
 | 
			
		||||
 | 
			
		||||
    private $_beta;
 | 
			
		||||
 | 
			
		||||
    private $_dynamicsFactor;
 | 
			
		||||
 | 
			
		||||
    private $_drawProbability;
 | 
			
		||||
 | 
			
		||||
    public function __construct($initialMean = self::DEFAULT_INITIAL_MEAN,
 | 
			
		||||
                                $initialStandardDeviation = self::DEFAULT_INITIAL_STANDARD_DEVIATION,
 | 
			
		||||
                                $beta = self::DEFAULT_BETA,
 | 
			
		||||
                                $dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR,
 | 
			
		||||
                                $drawProbability = self::DEFAULT_DRAW_PROBABILITY)
 | 
			
		||||
    public function __construct(private $_initialMean = self::DEFAULT_INITIAL_MEAN, private $_initialStandardDeviation = self::DEFAULT_INITIAL_STANDARD_DEVIATION, private $_beta = self::DEFAULT_BETA, private $_dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR, private $_drawProbability = self::DEFAULT_DRAW_PROBABILITY)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_initialMean = $initialMean;
 | 
			
		||||
        $this->_initialStandardDeviation = $initialStandardDeviation;
 | 
			
		||||
        $this->_beta = $beta;
 | 
			
		||||
        $this->_dynamicsFactor = $dynamicsFactor;
 | 
			
		||||
        $this->_drawProbability = $drawProbability;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getInitialMean()
 | 
			
		||||
 
 | 
			
		||||
@@ -7,16 +7,15 @@ namespace DNW\Skills;
 | 
			
		||||
 */
 | 
			
		||||
class HashMap
 | 
			
		||||
{
 | 
			
		||||
    private $_hashToValue = [];
 | 
			
		||||
    private array $_hashToValue = [];
 | 
			
		||||
 | 
			
		||||
    private $_hashToKey = [];
 | 
			
		||||
    private array $_hashToKey = [];
 | 
			
		||||
 | 
			
		||||
    public function getValue($key)
 | 
			
		||||
    {
 | 
			
		||||
        $hash = self::getHash($key);
 | 
			
		||||
        $hashValue = $this->_hashToValue[$hash];
 | 
			
		||||
 | 
			
		||||
        return $hashValue;
 | 
			
		||||
        return $this->_hashToValue[$hash];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setValue($key, $value)
 | 
			
		||||
@@ -30,16 +29,12 @@ class HashMap
 | 
			
		||||
 | 
			
		||||
    public function getAllKeys()
 | 
			
		||||
    {
 | 
			
		||||
        $keys = array_values($this->_hashToKey);
 | 
			
		||||
 | 
			
		||||
        return $keys;
 | 
			
		||||
        return array_values($this->_hashToKey);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAllValues()
 | 
			
		||||
    {
 | 
			
		||||
        $values = array_values($this->_hashToValue);
 | 
			
		||||
 | 
			
		||||
        return $values;
 | 
			
		||||
        return array_values($this->_hashToValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function count()
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ class DiagonalMatrix extends Matrix
 | 
			
		||||
 | 
			
		||||
        for ($currentRow = 0; $currentRow < $rowCount; $currentRow++) {
 | 
			
		||||
            for ($currentCol = 0; $currentCol < $colCount; $currentCol++) {
 | 
			
		||||
                if ($currentRow == $currentCol) {
 | 
			
		||||
                if ($currentRow === $currentCol) {
 | 
			
		||||
                    $this->setValue($currentRow, $currentCol, $diagonalValues[$currentRow]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    $this->setValue($currentRow, $currentCol, 0);
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,8 @@ namespace DNW\Skills\Numerics;
 | 
			
		||||
 * @author     Jeff Moser <jeff@moserware.com>
 | 
			
		||||
 * @copyright  2010 Jeff Moser
 | 
			
		||||
 */
 | 
			
		||||
class GaussianDistribution
 | 
			
		||||
class GaussianDistribution implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    private $_mean;
 | 
			
		||||
 | 
			
		||||
    private $_standardDeviation;
 | 
			
		||||
 | 
			
		||||
    // precision and precisionMean are used because they make multiplying and dividing simpler
 | 
			
		||||
    // (the the accompanying math paper for more details)
 | 
			
		||||
    private $_precision;
 | 
			
		||||
@@ -22,11 +18,9 @@ class GaussianDistribution
 | 
			
		||||
 | 
			
		||||
    private $_variance;
 | 
			
		||||
 | 
			
		||||
    public function __construct($mean = 0.0, $standardDeviation = 1.0)
 | 
			
		||||
    public function __construct(private $_mean = 0.0, private $_standardDeviation = 1.0)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_mean = $mean;
 | 
			
		||||
        $this->_standardDeviation = $standardDeviation;
 | 
			
		||||
        $this->_variance = BasicMath::square($standardDeviation);
 | 
			
		||||
        $this->_variance = BasicMath::square($_standardDeviation);
 | 
			
		||||
 | 
			
		||||
        if ($this->_variance != 0) {
 | 
			
		||||
            $this->_precision = 1.0 / $this->_variance;
 | 
			
		||||
@@ -34,11 +28,7 @@ class GaussianDistribution
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->_precision = \INF;
 | 
			
		||||
 | 
			
		||||
            if ($this->_mean == 0) {
 | 
			
		||||
                $this->_precisionMean = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->_precisionMean = \INF;
 | 
			
		||||
            }
 | 
			
		||||
            $this->_precisionMean = $this->_mean == 0 ? 0 : \INF;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -172,9 +162,8 @@ class GaussianDistribution
 | 
			
		||||
 | 
			
		||||
        $multiplier = 1.0 / ($standardDeviation * sqrt(2 * M_PI));
 | 
			
		||||
        $expPart = exp((-1.0 * BasicMath::square($x - $mean)) / (2 * BasicMath::square($standardDeviation)));
 | 
			
		||||
        $result = $multiplier * $expPart;
 | 
			
		||||
 | 
			
		||||
        return $result;
 | 
			
		||||
        return $multiplier * $expPart;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function cumulativeTo($x, $mean = 0.0, $standardDeviation = 1.0)
 | 
			
		||||
@@ -267,7 +256,7 @@ class GaussianDistribution
 | 
			
		||||
        return $mean - sqrt(2) * $standardDeviation * GaussianDistribution::inverseErrorFunctionCumulativeTo(2 * $x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return sprintf('mean=%.4f standardDeviation=%.4f', $this->_mean, $this->_standardDeviation);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,19 +6,10 @@ use Exception;
 | 
			
		||||
 | 
			
		||||
class Matrix
 | 
			
		||||
{
 | 
			
		||||
    const ERROR_TOLERANCE = 0.0000000001;
 | 
			
		||||
    public const ERROR_TOLERANCE = 0.0000000001;
 | 
			
		||||
 | 
			
		||||
    private $_matrixRowData;
 | 
			
		||||
 | 
			
		||||
    private $_rowCount;
 | 
			
		||||
 | 
			
		||||
    private $_columnCount;
 | 
			
		||||
 | 
			
		||||
    public function __construct($rows = 0, $columns = 0, $matrixData = null)
 | 
			
		||||
    public function __construct(private $_rowCount = 0, private $_columnCount = 0, private $_matrixRowData = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_rowCount = $rows;
 | 
			
		||||
        $this->_columnCount = $columns;
 | 
			
		||||
        $this->_matrixRowData = $matrixData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function fromColumnValues($rows, $columns, $columnValues)
 | 
			
		||||
@@ -37,9 +28,8 @@ class Matrix
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function fromRowsColumns()
 | 
			
		||||
    public static function fromRowsColumns(...$args)
 | 
			
		||||
    {
 | 
			
		||||
        $args = \func_get_args();
 | 
			
		||||
        $rows = $args[0];
 | 
			
		||||
        $cols = $args[1];
 | 
			
		||||
        $result = new Matrix($rows, $cols);
 | 
			
		||||
@@ -138,7 +128,7 @@ class Matrix
 | 
			
		||||
            $firstRowColValue = $this->_matrixRowData[0][$currentColumn];
 | 
			
		||||
            $cofactor = $this->getCofactor(0, $currentColumn);
 | 
			
		||||
            $itemToAdd = $firstRowColValue * $cofactor;
 | 
			
		||||
            $result = $result + $itemToAdd;
 | 
			
		||||
            $result += $itemToAdd;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $result;
 | 
			
		||||
@@ -258,7 +248,7 @@ class Matrix
 | 
			
		||||
                    $leftValue = $left->getValue($currentRow, $vectorIndex);
 | 
			
		||||
                    $rightValue = $right->getValue($vectorIndex, $currentColumn);
 | 
			
		||||
                    $vectorIndexProduct = $leftValue * $rightValue;
 | 
			
		||||
                    $productValue = $productValue + $vectorIndexProduct;
 | 
			
		||||
                    $productValue += $vectorIndexProduct;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $resultMatrix[$currentRow][$currentColumn] = $productValue;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,8 @@ namespace DNW\Skills\Numerics;
 | 
			
		||||
 | 
			
		||||
class SquareMatrix extends Matrix
 | 
			
		||||
{
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    public function __construct(...$allValues)
 | 
			
		||||
    {
 | 
			
		||||
        $allValues = func_get_args();
 | 
			
		||||
        $rows = (int) sqrt(count($allValues));
 | 
			
		||||
        $cols = $rows;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,21 +9,18 @@ namespace DNW\Skills;
 | 
			
		||||
 */
 | 
			
		||||
class PairwiseComparison
 | 
			
		||||
{
 | 
			
		||||
    const WIN = 1;
 | 
			
		||||
    final const WIN = 1;
 | 
			
		||||
 | 
			
		||||
    const DRAW = 0;
 | 
			
		||||
    final const DRAW = 0;
 | 
			
		||||
 | 
			
		||||
    const LOSE = -1;
 | 
			
		||||
    final const LOSE = -1;
 | 
			
		||||
 | 
			
		||||
    public static function getRankFromComparison($comparison)
 | 
			
		||||
    {
 | 
			
		||||
        switch ($comparison) {
 | 
			
		||||
            case PairwiseComparison::WIN:
 | 
			
		||||
                return [1, 2];
 | 
			
		||||
            case PairwiseComparison::LOSE:
 | 
			
		||||
                return [2, 1];
 | 
			
		||||
            default:
 | 
			
		||||
                return [1, 1];
 | 
			
		||||
        }
 | 
			
		||||
        return match ($comparison) {
 | 
			
		||||
            PairwiseComparison::WIN => [1, 2],
 | 
			
		||||
            PairwiseComparison::LOSE => [2, 1],
 | 
			
		||||
            default => [1, 1],
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,13 +5,11 @@ namespace DNW\Skills;
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a player who has a Rating.
 | 
			
		||||
 */
 | 
			
		||||
class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
class Player implements ISupportPartialPlay, ISupportPartialUpdate, \Stringable
 | 
			
		||||
{
 | 
			
		||||
    const DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time
 | 
			
		||||
    final const DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time
 | 
			
		||||
 | 
			
		||||
    const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0; // = receive 100% update
 | 
			
		||||
 | 
			
		||||
    private $_Id;
 | 
			
		||||
    final const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0;
 | 
			
		||||
 | 
			
		||||
    private $_PartialPlayPercentage;
 | 
			
		||||
 | 
			
		||||
@@ -20,18 +18,17 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a player.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  mixed  $id The identifier for the player, such as a name.
 | 
			
		||||
     * @param mixed $_Id The identifier for the player, such as a name.
 | 
			
		||||
     * @param  number  $partialPlayPercentage The weight percentage to give this player when calculating a new rank.
 | 
			
		||||
     * @param  number  $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.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($id,
 | 
			
		||||
    public function __construct(private $_Id,
 | 
			
		||||
                                $partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
 | 
			
		||||
                                $partialUpdatePercentage = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE)
 | 
			
		||||
    {
 | 
			
		||||
        // If they don't want to give a player an id, that's ok...
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, 'partialPlayPercentage');
 | 
			
		||||
        Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, 'partialUpdatePercentage');
 | 
			
		||||
        $this->_Id = $id;
 | 
			
		||||
        $this->_PartialPlayPercentage = $partialPlayPercentage;
 | 
			
		||||
        $this->_PartialUpdatePercentage = $partialUpdatePercentage;
 | 
			
		||||
    }
 | 
			
		||||
@@ -60,7 +57,7 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
 | 
			
		||||
        return $this->_PartialUpdatePercentage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return (string) $this->_Id;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,6 @@ use DNW\Skills\Numerics\Range;
 | 
			
		||||
 | 
			
		||||
class PlayersRange extends Range
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($min, $max)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($min, $max);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function create($min, $max)
 | 
			
		||||
    {
 | 
			
		||||
        return new PlayersRange($min, $max);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,28 +5,19 @@ namespace DNW\Skills;
 | 
			
		||||
// Container for a player's rating.
 | 
			
		||||
use DNW\Skills\Numerics\GaussianDistribution;
 | 
			
		||||
 | 
			
		||||
class Rating
 | 
			
		||||
class Rating implements \Stringable
 | 
			
		||||
{
 | 
			
		||||
    const CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3;
 | 
			
		||||
 | 
			
		||||
    private $_conservativeStandardDeviationMultiplier;
 | 
			
		||||
 | 
			
		||||
    private $_mean;
 | 
			
		||||
 | 
			
		||||
    private $_standardDeviation;
 | 
			
		||||
    final const CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a 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 $_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.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($mean, $standardDeviation, $conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER)
 | 
			
		||||
    public function __construct(private $_mean, private $_standardDeviation, private $_conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_mean = $mean;
 | 
			
		||||
        $this->_standardDeviation = $standardDeviation;
 | 
			
		||||
        $this->_conservativeStandardDeviationMultiplier = $conservativeStandardDeviationMultiplier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -76,7 +67,7 @@ class Rating
 | 
			
		||||
        return new Rating($partialPosteriorGaussion->getMean(), $partialPosteriorGaussion->getStandardDeviation(), $prior->_conservativeStandardDeviationMultiplier);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __toString()
 | 
			
		||||
    public function __toString(): string
 | 
			
		||||
    {
 | 
			
		||||
        return sprintf('mean=%.4f, standardDeviation=%.4f', $this->_mean, $this->_standardDeviation);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,17 +9,8 @@ use Exception;
 | 
			
		||||
 */
 | 
			
		||||
abstract class SkillCalculator
 | 
			
		||||
{
 | 
			
		||||
    private $_supportedOptions;
 | 
			
		||||
 | 
			
		||||
    private $_playersPerTeamAllowed;
 | 
			
		||||
 | 
			
		||||
    private $_totalTeamsAllowed;
 | 
			
		||||
 | 
			
		||||
    protected function __construct($supportedOptions, TeamsRange $totalTeamsAllowed, PlayersRange $playerPerTeamAllowed)
 | 
			
		||||
    protected function __construct(private $_supportedOptions, private readonly TeamsRange $_totalTeamsAllowed, private readonly PlayersRange $_playersPerTeamAllowed)
 | 
			
		||||
    {
 | 
			
		||||
        $this->_supportedOptions = $supportedOptions;
 | 
			
		||||
        $this->_totalTeamsAllowed = $totalTeamsAllowed;
 | 
			
		||||
        $this->_playersPerTeamAllowed = $playerPerTeamAllowed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -55,8 +46,6 @@ abstract class SkillCalculator
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param  array<\DNW\Skills\Team>  $teams
 | 
			
		||||
     * @param  \DNW\Skills\TeamsRange  $totalTeams
 | 
			
		||||
     * @param  \DNW\Skills\PlayersRange  $playersPerTeam
 | 
			
		||||
     * @return void
 | 
			
		||||
     * @throws \Exception
 | 
			
		||||
     */
 | 
			
		||||
@@ -79,9 +68,9 @@ abstract class SkillCalculator
 | 
			
		||||
 | 
			
		||||
class SkillCalculatorSupportedOptions
 | 
			
		||||
{
 | 
			
		||||
    const NONE = 0x00;
 | 
			
		||||
    final const NONE = 0x00;
 | 
			
		||||
 | 
			
		||||
    const PARTIAL_PLAY = 0x01;
 | 
			
		||||
    final const PARTIAL_PLAY = 0x01;
 | 
			
		||||
 | 
			
		||||
    const PARTIAL_UPDATE = 0x02;
 | 
			
		||||
    final const PARTIAL_UPDATE = 0x02;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,8 @@ namespace DNW\Skills;
 | 
			
		||||
 | 
			
		||||
class Teams
 | 
			
		||||
{
 | 
			
		||||
    public static function concat(/*variable arguments*/)
 | 
			
		||||
    public static function concat(...$args/*variable arguments*/)
 | 
			
		||||
    {
 | 
			
		||||
        $args = func_get_args();
 | 
			
		||||
        $result = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($args as $currentTeam) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,6 @@ use DNW\Skills\Numerics\Range;
 | 
			
		||||
 | 
			
		||||
class TeamsRange extends Range
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($min, $max)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($min, $max);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function create($min, $max)
 | 
			
		||||
    {
 | 
			
		||||
        return new TeamsRange($min, $max);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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(),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,5 +38,6 @@ class GaussianPriorFactor extends GaussianFactor
 | 
			
		||||
        $message->setValue($this->_newMessage);
 | 
			
		||||
 | 
			
		||||
        return GaussianDistribution::subtract($oldMarginal, $newMarginal);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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');
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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]);
 | 
			
		||||
 
 | 
			
		||||
@@ -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');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user