Compare commits

..

No commits in common. "c18ccd38e2a674f9f60ce3ae700a8acae43bd8e6" and "23fc14af0a729087d998ac75fe2bf22f3f0fcd1a" have entirely different histories.

84 changed files with 177 additions and 605 deletions

2
.gitignore vendored

@ -1,6 +1,6 @@
.vscode
vendor
.*.cache/
.phpunit.cache
*.phar
.phpdoc/
output/

@ -1,53 +0,0 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd">
<description>Coding standard</description>
<file>src/</file>
<file>tests/</file>
<file>benchmark/</file>
<rule ref="PSR1">
<exclude name="Generic.Files.LineLength"/>
</rule>
<rule ref="PSR2"></rule>
<rule ref="PSR12"></rule>
<rule ref="Generic">
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed"/>
<exclude name="Generic.Files.LowercasedFilename.NotFound"/>
<exclude name="Generic.PHP.ClosingPHPTag.NotFound"/>
<exclude name="Generic.Files.EndFileNoNewline.Found"/>
<exclude name="Generic.Files.EndFileNoNewline.Found"/>
<exclude name="Generic.Arrays.DisallowShortArraySyntax.Found"/>
<exclude name="Generic.Functions.OpeningFunctionBraceKernighanRitchie.BraceOnNewLine"/>
<exclude name="Generic.Classes.OpeningBraceSameLine.BraceOnNewLine"/>
<exclude name="Generic.PHP.LowerCaseConstant.Found"/>
<exclude name="Generic.Formatting.SpaceAfterCast"/>
<exclude name="Generic.Formatting.MultipleStatementAlignment.NotSameWarning"/>
<exclude name="Generic.Commenting.DocComment.MissingShort"/>
<exclude name="Generic.NamingConventions.AbstractClassNamePrefix.Missing"/>
<exclude name="Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed"/>
<exclude name="Generic.NamingConventions.InterfaceNameSuffix.Missing"/>
<exclude name="Generic.Commenting.Todo.TaskFound"/>
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUse"/>
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed"/>
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed"/>
<exclude name="Generic.Formatting.SpaceBeforeCast.NoSpace"/>
<exclude name="Generic.CodeAnalysis.UselessOverridingMethod.Found"/>
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.NewlineBeforeOpenBrace"/>
</rule>
<!-- Ban some functions -->
<rule ref="Generic.PHP.ForbiddenFunctions">
<properties>
<property name="forbiddenFunctions" type="array">
<element key="sizeof" value="count"/>
<element key="delete" value="unset"/>
<element key="print" value="echo"/>
<element key="is_null" value="null"/>
<element key="create_function" value="null"/>
</property>
</properties>
</rule>
</ruleset>

@ -1,13 +0,0 @@
path:
- src/
- tests/
- benchmark/
jobs: 10
extensions:
- php
exclude:
- vendor
warning: true
memory-limit: -1
no-cache: true
log-junit: "output/lint.xml"

@ -12,4 +12,12 @@ pipeline:
image: composer
commands:
- composer install
- composer analyze
test:
image: php:cli-bookworm
commands:
- vendor/bin/phpunit tests
# document:
# image: phpdoc/phpdoc
# commands:
# - phpdoc

@ -1,144 +0,0 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Benchmark;
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;
use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator;
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
use DNW\Skills\GameInfo;
use DNW\Skills\Player;
use DNW\Skills\Team;
use DNW\Skills\Teams;
class BasicBench
{
/**
* To benchmark performance when using TwoPlayerTrueSkillCalculator
*
* @Revs(20)
* @Iterations(20)
*/
public function benchBasic2PlayersUsingTwoPlayerTrueSkillCalculator(): void
{
$gameInfo = new GameInfo();
$p1 = new Player("Winner");
$p2 = new Player("Average");
$team1 = new Team($p1, $gameInfo->getDefaultRating());
$team2 = new Team($p2, $gameInfo->getDefaultRating());
for ($i = 0; $i < 10; $i++) {
$teams = Teams::concat($team1, $team2);
$calculator = new TwoPlayerTrueSkillCalculator();
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
$team1 = new Team($p1, $newRatings->getRating($p1));
$team2 = new Team($p2, $newRatings->getRating($p2));
$newRatings->getRating($p1)->getConservativeRating();
$newRatings->getRating($p2)->getConservativeRating();
}
}
/**
* To benchmark performance when using TwoTeamTrueSkillCalculator for just two players in two teams
*
* @Revs(20)
* @Iterations(20)
*/
public function benchBasic2PlayersUsingTwoTeamTrueSkillCalculator(): void
{
$gameInfo = new GameInfo();
$p1 = new Player("Winner");
$p2 = new Player("Average");
$team1 = new Team($p1, $gameInfo->getDefaultRating());
$team2 = new Team($p2, $gameInfo->getDefaultRating());
for ($i = 0; $i < 10; $i++) {
$teams = Teams::concat($team1, $team2);
$calculator = new TwoTeamTrueSkillCalculator();
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
$team1 = new Team($p1, $newRatings->getRating($p1));
$team2 = new Team($p2, $newRatings->getRating($p2));
$newRatings->getRating($p1)->getConservativeRating();
$newRatings->getRating($p2)->getConservativeRating();
}
}
/**
* To benchmark performance when using FactorGraphTrueSkillCalculator for just two players in two teams
*
* @Revs(20)
* @Iterations(20)
*/
public function benchBasic2PlayersUsingFactorGraphTrueSkillCalculator(): void
{
$gameInfo = new GameInfo();
$p1 = new Player("Winner");
$p2 = new Player("Average");
$team1 = new Team($p1, $gameInfo->getDefaultRating());
$team2 = new Team($p2, $gameInfo->getDefaultRating());
for ($i = 0; $i < 10; $i++) {
$teams = Teams::concat($team1, $team2);
$calculator = new FactorGraphTrueSkillCalculator();
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
$team1 = new Team($p1, $newRatings->getRating($p1));
$team2 = new Team($p2, $newRatings->getRating($p2));
$newRatings->getRating($p1)->getConservativeRating();
$newRatings->getRating($p2)->getConservativeRating();
}
}
/**
* To benchmark performance when using FactorGraphTrueSkillCalculator with 3 players in 3 teams
*
* @Revs(20)
* @Iterations(20)
*/
public function bench3Teams(): void
{
$gameInfo = new GameInfo();
$p1 = new Player("Winner");
$p2 = new Player("Average");
$p3 = new Player("Looser");
$team1 = new Team($p1, $gameInfo->getDefaultRating());
$team2 = new Team($p2, $gameInfo->getDefaultRating());
$team3 = new Team($p3, $gameInfo->getDefaultRating());
for ($i = 0; $i < 10; $i++) {
$teams = Teams::concat($team1, $team2, $team3);
$calculator = new FactorGraphTrueSkillCalculator();
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 3]);
$team1 = new Team($p1, $newRatings->getRating($p1));
$team2 = new Team($p2, $newRatings->getRating($p2));
$team3 = new Team($p3, $newRatings->getRating($p3));
$newRatings->getRating($p1)->getConservativeRating();
$newRatings->getRating($p2)->getConservativeRating();
$newRatings->getRating($p3)->getConservativeRating();
}
}
}

@ -6,10 +6,10 @@
"php": "^8.2"
},
"require-dev": {
"phpstan/phpstan": "^1.0",
"vimeo/psalm": "^5.21.1",
"phpmetrics/phpmetrics": "^3.0-dev",
"phpunit/phpunit": "^10.5"
"phpunit/phpunit": "^10",
"phpstan/phpstan": "^1",
"squizlabs/php_codesniffer": "*",
"vimeo/psalm": "^5.14"
},
"autoload": {
"psr-4": {
@ -22,26 +22,16 @@
}
},
"scripts": {
"test": "phpunit",
"document": "phpDocumentor",
"benchmark": "phpbench run --report=default --output=build-artifact",
"metrics": "vendor/bin/phpmetrics --config=phpmetrics.json",
"lint": [
"phplint",
"phpcs"
],
"static": [
"test": "vendor/bin/phpunit tests --display-warnings",
"test-coverage": "vendor/bin/phpunit tests --testdox --coverage-filter src --coverage-html output/coverage --coverage-text --testdox-html output/test.html --log-junit output/test.xml",
"document": "phpDocumentor --setting=graphs.enabled=true",
"analyze": [
"@analyze-phpstan",
"@analyze-psalm"
"@analyze-psalm",
"@analyze-phpcs"
],
"analyze-phpstan":"vendor/bin/phpstan analyze --error-format=raw",
"analyze-psalm": "vendor/bin/psalm --no-cache",
"all": [
"@test",
"@document",
"@benchmark",
"@lint",
"@static"
]
"analyze-phpcs": "vendor/bin/phpcs --report=emacs --standard=PSR1,PSR2,PSR12 --exclude=Generic.Files.LineLength src tests"
}
}

162
composer.lock generated

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "129eec96c91a9ee234640b9d6bcd0f43",
"content-hash": "667bb75c25a72b3d35f64ada9d9d9e0d",
"packages": [],
"packages-dev": [
{
@ -1082,82 +1082,6 @@
},
"time": "2024-01-11T11:49:22+00:00"
},
{
"name": "phpmetrics/phpmetrics",
"version": "v3.0.0rc5",
"source": {
"type": "git",
"url": "https://github.com/phpmetrics/PhpMetrics.git",
"reference": "7a4ee5d6a8233f449fb9125ad586d3880c8a1b2f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/7a4ee5d6a8233f449fb9125ad586d3880c8a1b2f",
"reference": "7a4ee5d6a8233f449fb9125ad586d3880c8a1b2f",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"nikic/php-parser": "^4",
"php": ">=8.1"
},
"replace": {
"halleck45/php-metrics": "*",
"halleck45/phpmetrics": "*"
},
"require-dev": {
"phake/phake": "^4.4.0",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan-strict-rules": "^1.5",
"phpunit/phpunit": "^10.3",
"roave/security-advisories": "dev-latest",
"sebastian/comparator": ">=5.0.0",
"squizlabs/php_codesniffer": "^3.7",
"symfony/dom-crawler": "^6.3",
"vimeo/psalm": "^5.15"
},
"suggest": {
"ext-dom": "To allow XML parsing and report results.",
"ext-yaml": "To allow yaml parsing of configuration files."
},
"bin": [
"bin/phpmetrics"
],
"type": "library",
"autoload": {
"psr-4": {
"Hal\\": "src/Hal"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jean-François Lépine",
"email": "lepinejeanfrancois@yahoo.fr",
"homepage": "http://www.lepine.pro",
"role": "Copyright Holder"
}
],
"description": "Static analyzer tool for PHP : Coupling, Cyclomatic complexity, Maintainability Index, Halstead's metrics... and more !",
"homepage": "http://www.phpmetrics.org",
"keywords": [
"analysis",
"qa",
"quality",
"testing"
],
"support": {
"issues": "https://github.com/PhpMetrics/PhpMetrics/issues",
"source": "https://github.com/phpmetrics/PhpMetrics/tree/v3.0.0rc5"
},
"time": "2024-01-17T10:59:12+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.25.0",
@ -2770,6 +2694,86 @@
],
"time": "2023-11-14T14:08:51+00:00"
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.8.1",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7",
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
},
"bin": [
"bin/phpcbf",
"bin/phpcs"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "Former lead"
},
{
"name": "Juliette Reinders Folmer",
"role": "Current lead"
},
{
"name": "Contributors",
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards",
"static analysis"
],
"support": {
"issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
"security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
"source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
},
"funding": [
{
"url": "https://github.com/PHPCSStandards",
"type": "github"
},
{
"url": "https://github.com/jrfnl",
"type": "github"
},
{
"url": "https://opencollective.com/php_codesniffer",
"type": "open_collective"
}
],
"time": "2024-01-11T20:47:48+00:00"
},
{
"name": "symfony/console",
"version": "v7.0.3",
@ -3645,9 +3649,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"phpmetrics/phpmetrics": 20
},
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

@ -1,11 +0,0 @@
{
"runner.bootstrap": "vendor/autoload.php",
"runner.path": "benchmark/",
"report.outputs": {
"build-artifact": {
"renderer": "html",
"path": "output/benchmark.html",
"title": "Benchmarking"
}
}
}

@ -1,20 +0,0 @@
{
"composer": true,
"includes": [
"src"
],
"excludes": [
"tests"
],
"report": {
"html": "output/metrics/"
},
"plugins": {
"git": {
"binary": "git"
},
"junit": {
"file": "output/test.xml"
}
}
}

@ -3,4 +3,3 @@ parameters:
paths:
- src
- tests
- benchmark

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false" displayDetailsOnTestsThatTriggerWarnings="true">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage/>
<testsuites>
<testsuite name="PHPSkills Test Suite">
<directory>./tests/</directory>
@ -10,14 +11,4 @@
<directory suffix=".php">src/</directory>
</include>
</source>
<logging>
<junit outputFile="output/test/junit.xml"/>
<testdoxHtml outputFile="output/test/index.html"/>
</logging>
<coverage>
<report>
<html outputDirectory="output/coverage" />
</report>
</coverage>
</phpunit>

@ -11,7 +11,6 @@
<projectFiles>
<directory name="src" />
<directory name="tests" />
<directory name="benchmark" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
use DNW\Skills\Guard;
@ -96,7 +94,6 @@ abstract class Factor implements \Stringable
/**
* Sends the ith message to the marginal and returns the log-normalization constant
*
* @throws Exception
*/
public function sendMessageIndex(int $messageIndex): float|int

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class FactorGraph

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
use DNW\Skills\FactorGraphs\ScheduleSequence;
@ -44,7 +42,6 @@ abstract class FactorGraphLayer
/**
* This reference is still needed
*
* @return array<int,array<int,object>>
*/
public function &getOutputVariablesGroups(): array
@ -85,11 +82,11 @@ abstract class FactorGraphLayer
public function createPriorSchedule(): ?ScheduleSequence
{
return NULL;
return null;
}
public function createPosteriorSchedule(): ?ScheduleSequence
{
return NULL;
return null;
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
/**

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class KeyedVariable extends Variable

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
use DNW\Skills\Numerics\GaussianDistribution;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
abstract class Schedule implements \Stringable

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class ScheduleLoop extends Schedule

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class ScheduleSequence extends Schedule

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class ScheduleStep extends Schedule

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
use DNW\Skills\Numerics\GaussianDistribution;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\FactorGraphs;
class VariableFactory

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**
@ -25,8 +23,7 @@ class GameInfo
private float $beta = self::DEFAULT_BETA,
private float $dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR,
private float $drawProbability = self::DEFAULT_DRAW_PROBABILITY
)
{
) {
}
public function getInitialMean(): float

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
use Exception;
@ -15,7 +13,7 @@ class Guard
{
public static function argumentNotNull(mixed $value, string $parameterName): void
{
if ($value == NULL) {
if ($value == null) {
throw new Exception($parameterName . ' can not be null');
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
interface ISupportPartialUpdate

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
/**
@ -16,7 +14,6 @@ class BasicMath
* Squares the input (x^2 = x * x)
*
* @param float $x Value to square (x)
*
* @return float The squared value (x^2)
*/
public static function square($x): float
@ -29,7 +26,6 @@ class BasicMath
*
* @param mixed[] $itemsToSum The items to sum,
* @param \Closure $callback The function to apply to each array element before summing.
*
* @return float The sum.
*/
public static function sum(array $itemsToSum, \Closure $callback): float

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
class DiagonalMatrix extends Matrix

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
/**
@ -200,8 +198,7 @@ class GaussianDistribution implements \Stringable
-1.523e-15,
-9.4e-17,
1.21e-16,
-2.8e-17,
];
-2.8e-17, ];
$ncof = count($coefficients);
$d = 0.0;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
class IdentityMatrix extends DiagonalMatrix

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
use Exception;
@ -13,7 +11,7 @@ class Matrix
/**
* @param array<int,array<int,float>> $matrixRowData
*/
public function __construct(private int $rowCount = 0, private int $columnCount = 0, private array $matrixRowData = [])
public function __construct(private int $rowCount = 0, private int $columnCount = 0, private array $matrixRowData = array())
{
}
@ -309,7 +307,7 @@ class Matrix
public function equals(Matrix $otherMatrix): bool
{
if (($this->rowCount != $otherMatrix->getRowCount()) || ($this->columnCount != $otherMatrix->getColumnCount())) {
return FALSE;
return false;
}
for ($currentRow = 0; $currentRow < $this->rowCount; $currentRow++) {
@ -321,11 +319,11 @@ class Matrix
);
if ($delta > self::ERROR_TOLERANCE) {
return FALSE;
return false;
}
}
}
return TRUE;
return true;
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
// The whole purpose of this class is to make the code for the SkillCalculator(s)

@ -1,14 +1,12 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
class SquareMatrix extends Matrix
{
public function __construct(float|int ...$allValues)
{
$rows = (int)sqrt(count($allValues));
$rows = (int) sqrt(count($allValues));
$cols = $rows;
$matrixData = [];

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Numerics;
class Vector extends Matrix

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
class PartialPlay

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**
@ -28,8 +26,7 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate, \Stringable
private mixed $Id,
float $partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
float $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');
@ -63,6 +60,6 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate, \Stringable
public function __toString(): string
{
return (string)$this->Id;
return (string) $this->Id;
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
use DNW\Skills\Numerics\Range;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
/**
@ -14,7 +12,6 @@ class RankSorter
*
* @param array<mixed> $teams The items to sort according to the order specified by ranks.
* @param array<int> $teamRanks The ranks for each item where 1 is first place.
*
* @return array<int>
*/
public static function sort(array &$teams, array &$teamRanks): array

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
// Container for a player's rating.

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
class RatingContainer

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
use Exception;
@ -15,8 +13,7 @@ abstract class SkillCalculator
private int $supportedOptions,
private readonly TeamsRange $totalTeamsAllowed,
private readonly PlayersRange $playersPerTeamAllowed
)
{
) {
}
/**
@ -25,7 +22,6 @@ abstract class SkillCalculator
* @param GameInfo $gameInfo Parameters for the game.
* @param Team[] $teams A mapping of team players and their ratings.
* @param int[] $teamRanks The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2).
*
* @return RatingContainer All the players and their new ratings.
*/
abstract public function calculateNewRatings(
@ -39,7 +35,6 @@ abstract class SkillCalculator
*
* @param GameInfo $gameInfo Parameters for the game.
* @param Team[] $teams A mapping of team players and their ratings.
*
* @return float The quality of the match between the teams as a percentage (0% = bad, 100% = well matched).
*/
abstract public function calculateMatchQuality(GameInfo $gameInfo, array $teams): float;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
class SkillCalculatorSupportedOptions

@ -1,16 +1,14 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
class Team extends RatingContainer
{
public function __construct(Player $player = NULL, Rating $rating = NULL)
public function __construct(Player $player = null, Rating $rating = null)
{
parent::__construct();
if ($player && $rating) {
if (! is_null($player) && ! is_null($rating)) {
$this->addPlayer($player, $rating);
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
class Teams

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills;
use DNW\Skills\Numerics\Range;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo;
@ -36,8 +34,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
GameInfo $gameInfo,
array $teams,
array $teamRanks
): RatingContainer
{
): RatingContainer {
Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams);
@ -127,9 +124,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
/**
* Helper function that gets a list of values for all player ratings
*
* @param Team[] $teamAssignmentsList
*
* @return int[]
*/
private static function getPlayerRatingValues(array $teamAssignmentsList, \Closure $playerRatingFunction): array

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Factor;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Message;
@ -64,9 +62,11 @@ class GaussianGreaterThanFactor extends GaussianFactor
$denom = 1.0 - TruncatedGaussianCorrectionFunctions::wExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC);
$newPrecision = $c / $denom;
$newPrecisionMean = ($d +
$newPrecisionMean = (
$d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC)) / $denom;
TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC)
) / $denom;
$newMarginal = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\KeyedVariable;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Message;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Message;
@ -26,7 +24,6 @@ class GaussianWeightedSumFactor extends GaussianFactor
/**
* 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]
*
* @var array<float[]> $weights
*/
private array $weights = [];
@ -250,7 +247,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$absValue = sprintf('%.2f', \abs($weights[$i])); // 0.00?
$result .= $absValue;
$result .= '*[';
$result .= (string)$variablesToSum[$i];
$result .= (string) $variablesToSum[$i];
$result .= ']';
$isLast = ($i === $totalVars - 1);

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Message;
@ -67,7 +65,8 @@ class GaussianWithinFactor extends GaussianFactor
$newPrecision = $c / $denominator;
$newPrecisionMean = ($d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)) / $denominator;
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)
) / $denominator;
$newMarginal = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
$newMessage = GaussianDistribution::divide(

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\ScheduleLoop;
@ -17,8 +15,7 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
TrueSkillFactorGraph $parentGraph,
private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $TeamPerformancesToTeamPerformanceDifferencesLayer,
private readonly TeamDifferencesComparisonLayer $TeamDifferencesComparisonLayer
)
{
) {
parent::__construct($parentGraph);
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\ScheduleStep;
@ -89,7 +87,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
*/
private function createOutputVariable(array $team): Variable
{
$memberNames = array_map(fn ($currentPlayer) => (string)($currentPlayer->getKey()), $team);
$memberNames = array_map(fn ($currentPlayer) => (string) ($currentPlayer->getKey()), $team);
$teamMemberNames = \implode(', ', $memberNames);

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\ScheduleStep;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\KeyedVariable;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\TrueSkill\DrawMargin;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\Variable;
@ -32,8 +30,7 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
Variable $strongerTeam,
Variable $weakerTeam,
Variable $output
): GaussianWeightedSumFactor
{
): GaussianWeightedSumFactor {
$teams = [$strongerTeam, $weakerTeam];
$weights = [1.0, -1.0];

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\FactorGraphLayer;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\FactorGraphs\FactorGraph;
@ -62,11 +60,11 @@ class TrueSkillFactorGraph extends FactorGraph
public function buildGraph(): void
{
$lastOutput = NULL;
$lastOutput = null;
$layers = $this->layers;
foreach ($layers as $currentLayer) {
if ($lastOutput != NULL) {
if ($lastOutput != null) {
$currentLayer->setInputVariablesGroups($lastOutput);
}
@ -107,7 +105,7 @@ class TrueSkillFactorGraph extends FactorGraph
$layers = $this->layers;
foreach ($layers as $currentLayer) {
$currentPriorSchedule = $currentLayer->createPriorSchedule();
if ($currentPriorSchedule != NULL) {
if ($currentPriorSchedule != null) {
$fullSchedule[] = $currentPriorSchedule;
}
}
@ -116,7 +114,7 @@ class TrueSkillFactorGraph extends FactorGraph
foreach ($allLayersReverse as $currentLayer) {
$currentPosteriorSchedule = $currentLayer->createPosteriorSchedule();
if ($currentPosteriorSchedule != NULL) {
if ($currentPosteriorSchedule != null) {
$fullSchedule[] = $currentPosteriorSchedule;
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution;
@ -122,7 +120,8 @@ class TruncatedGaussianCorrectionFunctions
$vt = self::vWithinMargin($teamPerformanceDifferenceAbsoluteValue, $drawMargin);
return $vt * $vt +
(($drawMargin - $teamPerformanceDifferenceAbsoluteValue)
(
($drawMargin - $teamPerformanceDifferenceAbsoluteValue)
*
GaussianDistribution::at(
$drawMargin - $teamPerformanceDifferenceAbsoluteValue

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo;
@ -37,8 +35,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
GameInfo $gameInfo,
array $teams,
array $teamRanks
): RatingContainer
{
): RatingContainer {
// Basic argument checking
Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams);

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo;
@ -70,8 +68,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
Team $selfTeam,
Team $otherTeam,
PairwiseComparison $selfToOtherTeamComparison
): void
{
): void {
$drawMargin = DrawMargin::getDrawMarginFromDrawProbability(
$gameInfo->getDrawProbability(),
$gameInfo->getBeta()

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\FactorGraphs;
use DNW\Skills\FactorGraphs\ScheduleStep;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\FactorGraphs;
use DNW\Skills\FactorGraphs\Variable;
@ -15,7 +13,6 @@ class VariableTest extends TestCase
$gd_prior = new GaussianDistribution();
$var = new Variable('dummy', $gd_prior);
$this->assertEquals($gd_prior, $var->getValue());
$gd_new = new GaussianDistribution();
$this->assertEquals($gd_new, $var->getValue());
$var->resetToPrior();

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests;
use DNW\Skills\Guard;
@ -14,7 +12,7 @@ class GuardTest extends TestCase
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('dummy can not be null');
Guard::argumentNotNull(NULL, "dummy");
Guard::argumentNotNull(null, "dummy");
}
public function testargumentIsValidIndex(): void

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\BasicMath;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\BasicMath;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\IdentityMatrix;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\Range;

@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests;
use DNW\Skills\Player;
use PHPUnit\Framework\TestCase;
class PlayerTest extends TestCase
{
public function test(): void
{
$p = new Player('dummy', 0.1, 0.2);
$this->assertEquals('dummy', (string)$p);
$this->assertEquals(0.1, $p->getPartialPlayPercentage());
$this->assertEquals(0.2, $p->getPartialUpdatePercentage());
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests;
use DNW\Skills\RankSorter;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests;
use DNW\Skills\Rating;
@ -21,10 +19,10 @@ class RatingTest extends TestCase
public function testPartialUpdate(): void
{
$rating = new Rating(100, 10, 5);
$ratingOld = new Rating(100, 10, 5);
$ratingNew = new Rating(200, 10, 5);
$rating_prior = new Rating(100, 10, 5);
$rating_new = new Rating(200, 10, 5);
$rating_partial = $rating->getPartialUpdate($ratingOld, $ratingNew, 0.5);
$rating_partial = $rating ->getPartialUpdate($rating_prior, $rating_new, 0.5);
$this->assertEquals(150, $rating_partial->getMean());

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\TrueSkill\DrawMargin;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
@ -23,6 +21,6 @@ class FactorGraphTeamTrueSkillCalculatorTest extends TestCase
public function testMethodisSupported(): void
{
$calculator = new FactorGraphTrueSkillCalculator();
$this->assertEquals(TRUE, $calculator->isSupported(SkillCalculatorSupportedOptions::PARTIAL_PLAY));
$this->assertEquals(true, $calculator->isSupported(SkillCalculatorSupportedOptions::PARTIAL_PLAY));
}
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\GameInfo;
@ -27,7 +25,7 @@ class FactorGraphTrueSkillCalculatorTest extends TestCase
new Player("hillary"),
];
$teams = [];
$teams = array();
foreach ($players as $player) {
$teams[] = new Team($player, $gameInfo->getDefaultRating());
}

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\GameInfo;
@ -110,7 +108,6 @@ class TrueSkillCalculatorTests
$team2 = new Team($player2, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
$player1NewRating = $newRatings->getRating($player1);
@ -173,7 +170,9 @@ class TrueSkillCalculatorTests
private static function oneOnTwoSimpleTest(TestCase $testClass, SkillCalculator $calculator): void
{
$player1 = new Player(1);
$gameInfo = new GameInfo();
$team1 = new Team();
$team1->addPlayer($player1, $gameInfo->getDefaultRating());

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;

@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator;