From c528e872d5062627f4000d1150333c0f49ac0965 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 13:03:31 +0300 Subject: [PATCH 01/14] Refactored ELU class --- src/NeuralNet/ActivationFunctions/ELU/ELU.php | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/NeuralNet/ActivationFunctions/ELU/ELU.php b/src/NeuralNet/ActivationFunctions/ELU/ELU.php index 4d5062574..fd852bce6 100644 --- a/src/NeuralNet/ActivationFunctions/ELU/ELU.php +++ b/src/NeuralNet/ActivationFunctions/ELU/ELU.php @@ -24,13 +24,16 @@ * @package Rubix/ML * @author Andrew DalPino * @author Aleksei Nechaev + * @author Samuel Akopyan */ class ELU implements ActivationFunction, SingleBufferDerivative { /** + * Class constructor. + * * @param float $alpha At which negative value the ELU will saturate. For example if alpha * equals 1, the leaked value will never be greater than -1.0. - * + * * @throws InvalidAplhaException */ public function __construct(protected float $alpha = 1.0) @@ -42,49 +45,54 @@ public function __construct(protected float $alpha = 1.0) } } + /** + * Apply the ELU activation function to the input. + * + * f(x) = x if x > 0 + * f(x) = α * (e^x - 1) if x ≤ 0 + * + * @param NDArray $input The input values + * @return NDArray The activated values + */ public function activate(NDArray $input) : NDArray { - $a = NumPower::multiply( - a: NumPower::expm1(NumPower::minimum( - a: $input, - b: 0 - )), + // Calculate positive part: x for x > 0 + $positiveActivation = NumPower::maximum(a: $input, b: 0); + + // Calculate negative part: alpha * (e^x - 1) for x <= 0 + $negativeMask = NumPower::minimum(a: $input, b: 0); + $negativeActivation = NumPower::multiply( + a: NumPower::expm1($negativeMask), b: $this->alpha ); - return NumPower::add( - a: NumPower::maximum( - a: $input, - b: 0 - ), - b: $a - ); + // Combine both parts + return NumPower::add(a: $positiveActivation, b: $negativeActivation); } /** - * Calculate the derivative of the activation output + * Calculate the derivative of the activation function. + * + * f'(x) = 1 if x > 0 + * f'(x) = α * e^x if x ≤ 0 * * @param NDArray $x Output matrix * @return NDArray Derivative matrix */ public function differentiate(NDArray $x) : NDArray { - $a = NumPower::multiply( - a: NumPower::lessEqual(a: $x, b: 0), - b: NumPower::exp($x) - ); - $b = NumPower::multiply( - a: $a, + // For x > 0: 1 + $positivePart = NumPower::greater(a: $x, b: 0); + + // For x <= 0: α * e^x + $negativeMask = NumPower::lessEqual(a: $x, b: 0); + $negativePart = NumPower::multiply( + a: NumPower::multiply(a: $negativeMask, b: NumPower::exp($x)), b: $this->alpha ); - return NumPower::add( - a: NumPower::greater( - a: $x, - b: 0 - ), - b: $b - ); + // Combine both parts + return NumPower::add(a: $positivePart, b: $negativePart); } /** From ac32b8729650268a5c642e11cdbf0c1f2007a756 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 13:15:37 +0300 Subject: [PATCH 02/14] Added docker related files --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 08239f13d..01178821b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,9 @@ pyvenv.cfg .idea .vscode .vs + +# Docker related files +Dockerfile +/docker/ +docker-compose.yml +Makefile From 04387472dea1781d6d1a0f96e19dbdd9ecc52cd2 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 13:50:24 +0300 Subject: [PATCH 03/14] Fixed error on implements base class --- src/NeuralNet/FeedForward.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/NeuralNet/FeedForward.php b/src/NeuralNet/FeedForward.php index 4849f1681..658691e5c 100644 --- a/src/NeuralNet/FeedForward.php +++ b/src/NeuralNet/FeedForward.php @@ -27,8 +27,7 @@ * @package Rubix/ML * @author Andrew DalPino */ -class FeedForward implements Network -{ +class FeedForward extends Network { /** * The input layer to the network. * From af4f89940221c5c673807a207db1fd62a6b3f1c5 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 14:09:30 +0300 Subject: [PATCH 04/14] Typo fix in class name --- src/NeuralNet/ActivationFunctions/ELU/ELU.php | 6 +++--- ...{InvalidAplhaException.php => InvalidAlphaException.php} | 4 ++-- tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/NeuralNet/ActivationFunctions/ELU/Exceptions/{InvalidAplhaException.php => InvalidAlphaException.php} (77%) diff --git a/src/NeuralNet/ActivationFunctions/ELU/ELU.php b/src/NeuralNet/ActivationFunctions/ELU/ELU.php index fd852bce6..2c97e81c2 100644 --- a/src/NeuralNet/ActivationFunctions/ELU/ELU.php +++ b/src/NeuralNet/ActivationFunctions/ELU/ELU.php @@ -8,7 +8,7 @@ use NDArray; use Rubix\ML\NeuralNet\ActivationFunctions\Base\Contracts\ActivationFunction; use Rubix\ML\NeuralNet\ActivationFunctions\Base\Contracts\SingleBufferDerivative; -use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidAplhaException; +use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidalphaException; /** * ELU @@ -34,12 +34,12 @@ class ELU implements ActivationFunction, SingleBufferDerivative * @param float $alpha At which negative value the ELU will saturate. For example if alpha * equals 1, the leaked value will never be greater than -1.0. * - * @throws InvalidAplhaException + * @throws InvalidalphaException */ public function __construct(protected float $alpha = 1.0) { if ($this->alpha < 0.0) { - throw new InvalidAplhaException( + throw new InvalidAlphaException( message: "Alpha must be greater than 0, $alpha given." ); } diff --git a/src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAplhaException.php b/src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAlphaException.php similarity index 77% rename from src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAplhaException.php rename to src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAlphaException.php index 71f5c8c3f..423c62596 100644 --- a/src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAplhaException.php +++ b/src/NeuralNet/ActivationFunctions/ELU/Exceptions/InvalidAlphaException.php @@ -9,6 +9,6 @@ /** * Invalid `alpha` parameter for ELU Activation function */ -class InvalidAplhaException extends InvalidArgumentException +class InvalidAlphaException extends InvalidArgumentException { -} \ No newline at end of file +} diff --git a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php index 7685fb16a..5fffca05c 100644 --- a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php @@ -12,7 +12,7 @@ use Rubix\ML\NeuralNet\ActivationFunctions\ELU\ELU; use PHPUnit\Framework\TestCase; use Generator; -use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidAplhaException; +use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidAlphaException; #[Group('ActivationFunctions')] #[CoversClass(ELU::class)] @@ -77,7 +77,7 @@ protected function setUp() : void public function testBadAlpha() : void { - $this->expectException(InvalidAplhaException::class); + $this->expectException(InvalidAlphaException::class); new ELU(-346); } From f44a59707ce3ab9a13f66309f5adb0a59aa0dd59 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 15:18:48 +0300 Subject: [PATCH 05/14] Refactored ELUTest --- .../ActivationFunctions/ELU/ELUTest.php | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php index 5fffca05c..2315a3187 100644 --- a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php @@ -14,12 +14,22 @@ use Generator; use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidAlphaException; +/** + * @group ActivationFunctions + * @covers \Rubix\ML\NeuralNet\ActivationFunctions\ELU\ELU + */ #[Group('ActivationFunctions')] #[CoversClass(ELU::class)] class ELUTest extends TestCase { + /** + * @var \Rubix\ML\NeuralNet\ActivationFunctions\ELU\ELU + */ protected ELU $activationFn; + /** + * @return \Generator> + */ public static function computeProvider() : Generator { yield [ @@ -45,6 +55,9 @@ public static function computeProvider() : Generator ]; } + /** + * @return \Generator> + */ public static function differentiateProvider() : Generator { yield [ @@ -70,21 +83,46 @@ public static function differentiateProvider() : Generator ]; } + /** + * Set up the test case. + */ protected function setUp() : void { $this->activationFn = new ELU(1.0); } - public function testBadAlpha() : void + /** + * @test + */ + public function testConstructorWithValidAlpha() : void + { + $activationFn = new ELU(2.0); + + $this->assertInstanceOf(ELU::class, $activationFn); + $this->assertEquals('ELU (alpha: 2)', (string) $activationFn); + } + + /** + * @test + */ + public function testConstructorWithInvalidAlpha() : void { $this->expectException(InvalidAlphaException::class); new ELU(-346); } + /** + * @test + */ + public function testToString() : void + { + $this->assertEquals('ELU (alpha: 1)', (string) $this->activationFn); + } + /** * @param NDArray $input - * @param list> $expected $expected + * @param list> $expected */ #[DataProvider('computeProvider')] public function testActivate(NDArray $input, array $expected) : void @@ -96,10 +134,10 @@ public function testActivate(NDArray $input, array $expected) : void /** * @param NDArray $input - * @param list> $expected $expected + * @param list> $expected */ #[DataProvider('differentiateProvider')] - public function testDifferentiate(NDArray $input, array $expected) : void + public function testDifferentiate1(NDArray $input, array $expected) : void { $derivatives = $this->activationFn->differentiate($input)->toArray(); From 7c7c9996847bb31e0b84c969473bca91955d8894 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 15:48:08 +0300 Subject: [PATCH 06/14] Style fixes for ELU and ELUTest --- src/NeuralNet/ActivationFunctions/ELU/ELU.php | 4 ++-- tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NeuralNet/ActivationFunctions/ELU/ELU.php b/src/NeuralNet/ActivationFunctions/ELU/ELU.php index 2c97e81c2..f94c5e7d5 100644 --- a/src/NeuralNet/ActivationFunctions/ELU/ELU.php +++ b/src/NeuralNet/ActivationFunctions/ELU/ELU.php @@ -32,9 +32,9 @@ class ELU implements ActivationFunction, SingleBufferDerivative * Class constructor. * * @param float $alpha At which negative value the ELU will saturate. For example if alpha - * equals 1, the leaked value will never be greater than -1.0. + * equals 1, the leaked value will never be greater than -1.0. * - * @throws InvalidalphaException + * @throws InvalidAlphaException */ public function __construct(protected float $alpha = 1.0) { diff --git a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php index 2315a3187..f1b4eab1d 100644 --- a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php @@ -23,12 +23,12 @@ class ELUTest extends TestCase { /** - * @var \Rubix\ML\NeuralNet\ActivationFunctions\ELU\ELU + * @var ELU */ protected ELU $activationFn; /** - * @return \Generator> + * @return Generator> */ public static function computeProvider() : Generator { @@ -56,7 +56,7 @@ public static function computeProvider() : Generator } /** - * @return \Generator> + * @return Generator> */ public static function differentiateProvider() : Generator { From d405dbded7813d053a634ee09801054627fc0e1a Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 15:51:06 +0300 Subject: [PATCH 07/14] Style fixes for ELU and ELUTest --- src/NeuralNet/ActivationFunctions/ELU/ELU.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NeuralNet/ActivationFunctions/ELU/ELU.php b/src/NeuralNet/ActivationFunctions/ELU/ELU.php index f94c5e7d5..ba890b1aa 100644 --- a/src/NeuralNet/ActivationFunctions/ELU/ELU.php +++ b/src/NeuralNet/ActivationFunctions/ELU/ELU.php @@ -8,7 +8,7 @@ use NDArray; use Rubix\ML\NeuralNet\ActivationFunctions\Base\Contracts\ActivationFunction; use Rubix\ML\NeuralNet\ActivationFunctions\Base\Contracts\SingleBufferDerivative; -use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidalphaException; +use Rubix\ML\NeuralNet\ActivationFunctions\ELU\Exceptions\InvalidAlphaException; /** * ELU From f3371febb2570c69a36dfd91e50cb1f6be69ae47 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 15:53:38 +0300 Subject: [PATCH 08/14] Syntax fixes for ELUTest --- .../ActivationFunctions/ELU/ELUTest.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php index f1b4eab1d..712854e96 100644 --- a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php @@ -28,7 +28,7 @@ class ELUTest extends TestCase protected ELU $activationFn; /** - * @return Generator> + * @return Generator */ public static function computeProvider() : Generator { @@ -56,7 +56,7 @@ public static function computeProvider() : Generator } /** - * @return Generator> + * @return Generator */ public static function differentiateProvider() : Generator { @@ -88,6 +88,8 @@ public static function differentiateProvider() : Generator */ protected function setUp() : void { + parent::setUp(); + $this->activationFn = new ELU(1.0); } @@ -98,8 +100,8 @@ public function testConstructorWithValidAlpha() : void { $activationFn = new ELU(2.0); - $this->assertInstanceOf(ELU::class, $activationFn); - $this->assertEquals('ELU (alpha: 2)', (string) $activationFn); + static::assertInstanceOf(ELU::class, $activationFn); + static::assertEquals('ELU (alpha: 2)', (string) $activationFn); } /** @@ -117,7 +119,7 @@ public function testConstructorWithInvalidAlpha() : void */ public function testToString() : void { - $this->assertEquals('ELU (alpha: 1)', (string) $this->activationFn); + static::assertEquals('ELU (alpha: 1)', (string) $this->activationFn); } /** @@ -129,7 +131,7 @@ public function testActivate(NDArray $input, array $expected) : void { $activations = $this->activationFn->activate($input)->toArray(); - $this->assertEquals($expected, $activations); + static::assertEquals($expected, $activations); } /** @@ -141,6 +143,6 @@ public function testDifferentiate1(NDArray $input, array $expected) : void { $derivatives = $this->activationFn->differentiate($input)->toArray(); - $this->assertEquals($expected, $derivatives); + static::assertEquals($expected, $derivatives); } } From fab36f4622696f97b119696e1d343277ca29555f Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 16:33:27 +0300 Subject: [PATCH 09/14] Syntax fixes for PHP8.4 --- .php-cs-fixer.dist.php | 1 + src/AnomalyDetectors/OneClassSVM.php | 2 +- src/Backends/Amp.php | 2 +- src/Classifiers/SVC.php | 2 +- src/Clusterers/MeanShift.php | 2 +- src/Helpers/Stats.php | 10 +++++----- .../ActivationFunctions/Base/Contracts/Derivative.php | 4 +++- .../Base/Contracts/IOBufferDerivative.php | 3 +-- .../Base/Contracts/OBufferDerivative.php | 3 +-- .../Base/Contracts/SingleBufferDerivative.php | 4 ++-- .../ActivationFunctions/HardSiLU/HardSiLU.php | 3 +-- .../ActivationFunctions/LeakyReLU/LeakyReLU.php | 2 +- src/NeuralNet/ActivationFunctions/SiLU/SiLU.php | 2 -- src/NeuralNet/ActivationFunctions/Softmax/Softmax.php | 4 +--- src/NeuralNet/FeedForward.php | 3 ++- src/PersistentModel.php | 2 +- src/Regressors/SVR.php | 2 +- src/Transformers/ImageRotator.php | 2 +- tests/AnomalyDetectors/RobustZScoreTest.php | 2 +- tests/Base/GridSearchTest.php | 2 +- tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php | 2 +- tests/NeuralNet/ActivationFunctions/ELUTest.php | 2 +- tests/NeuralNet/Initializers/He/HeUniformTest.php | 4 ++-- tests/NeuralNet/Initializers/LeCun/LeCunNormalTest.php | 4 ++-- .../NeuralNet/Initializers/LeCun/LeCunUniformTest.php | 4 ++-- tests/NeuralNet/Initializers/Normal/NormalTest.php | 10 +++++----- .../Initializers/Normal/TruncatedNormalTest.php | 10 +++++----- tests/NeuralNet/Initializers/Uniform/UniformTest.php | 6 +++--- .../NeuralNet/Initializers/Xavier/XavierNormalTest.php | 4 ++-- .../Initializers/Xavier/XavierUniformTest.php | 4 ++-- .../SamplesAreCompatibleWithTransformerTest.php | 2 +- tests/Tokenizers/SentenceTest.php | 4 ++-- tests/Transformers/MaxAbsoluteScalerTest.php | 2 +- tests/Transformers/MinMaxNormalizerTest.php | 2 +- 34 files changed, 57 insertions(+), 60 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 9a95a997e..94ede022b 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -10,6 +10,7 @@ return $config->setRules([ '@PSR2' => true, + '@PHP84Migration' => true, 'align_multiline_comment' => true, 'array_syntax' => ['syntax' => 'short'], 'backtick_to_shell_exec' => true, diff --git a/src/AnomalyDetectors/OneClassSVM.php b/src/AnomalyDetectors/OneClassSVM.php index bdd19775f..ab229ac6c 100644 --- a/src/AnomalyDetectors/OneClassSVM.php +++ b/src/AnomalyDetectors/OneClassSVM.php @@ -85,7 +85,7 @@ public function __construct( . "0 and 1, $nu given."); } - $kernel = $kernel ?? new RBF(); + $kernel ??= new RBF(); if ($tolerance < 0.0) { throw new InvalidArgumentException('Tolerance must be,' diff --git a/src/Backends/Amp.php b/src/Backends/Amp.php index 49299ad8a..02527123e 100644 --- a/src/Backends/Amp.php +++ b/src/Backends/Amp.php @@ -63,7 +63,7 @@ public function __construct(?int $workers = null) . " must be greater than 0, $workers given."); } - $workers = $workers ?? CPU::cores(); + $workers ??= CPU::cores(); $this->pool = new DefaultPool($workers); } diff --git a/src/Classifiers/SVC.php b/src/Classifiers/SVC.php index 509ed11f8..b063057cb 100644 --- a/src/Classifiers/SVC.php +++ b/src/Classifiers/SVC.php @@ -96,7 +96,7 @@ public function __construct( . " than 0, $c given."); } - $kernel = $kernel ?? new RBF(); + $kernel ??= new RBF(); if ($tolerance < 0.0) { throw new InvalidArgumentException('Tolerance must be' diff --git a/src/Clusterers/MeanShift.php b/src/Clusterers/MeanShift.php index e1adaa5b8..419d1f5d9 100644 --- a/src/Clusterers/MeanShift.php +++ b/src/Clusterers/MeanShift.php @@ -153,7 +153,7 @@ public static function estimateRadius( . " between 0 and 100, $percentile given."); } - $kernel = $kernel ?? new Euclidean(); + $kernel ??= new Euclidean(); $samples = $dataset->samples(); diff --git a/src/Helpers/Stats.php b/src/Helpers/Stats.php index c53052141..f090feab1 100644 --- a/src/Helpers/Stats.php +++ b/src/Helpers/Stats.php @@ -169,7 +169,7 @@ public static function variance(array $values, ?float $mean = null) : float throw new InvalidArgumentException('Variance is undefined for empty set.'); } - $mean = $mean ?? self::mean($values); + $mean ??= self::mean($values); $ssd = 0.0; @@ -195,7 +195,7 @@ public static function mad(array $values, ?float $median = null) : float . ' is undefined for empty set.'); } - $median = $median ?? self::median($values); + $median ??= self::median($values); $deviations = []; @@ -220,7 +220,7 @@ public static function skewness(array $values, ?float $mean = null) : float throw new InvalidArgumentException('Skewness is undefined for empty set.'); } - $mean = $mean ?? self::mean($values); + $mean ??= self::mean($values); $numerator = self::centralMoment($values, 3, $mean); $denominator = self::centralMoment($values, 2, $mean) ** 1.5; @@ -242,7 +242,7 @@ public static function kurtosis(array $values, ?float $mean = null) : float throw new InvalidArgumentException('Kurtosis is undefined for empty set.'); } - $mean = $mean ?? self::mean($values); + $mean ??= self::mean($values); $numerator = self::centralMoment($values, 4, $mean); $denominator = self::centralMoment($values, 2, $mean) ** 2; @@ -269,7 +269,7 @@ public static function centralMoment(array $values, int $moment, ?float $mean = throw new InvalidArgumentException('Moment cannot be less than 1.'); } - $mean = $mean ?? self::mean($values); + $mean ??= self::mean($values); $sigma = 0.0; diff --git a/src/NeuralNet/ActivationFunctions/Base/Contracts/Derivative.php b/src/NeuralNet/ActivationFunctions/Base/Contracts/Derivative.php index cba53bbd6..90dfcf40c 100644 --- a/src/NeuralNet/ActivationFunctions/Base/Contracts/Derivative.php +++ b/src/NeuralNet/ActivationFunctions/Base/Contracts/Derivative.php @@ -12,4 +12,6 @@ * @author Andrew DalPino * @author Aleksei Nechaev */ -interface Derivative {} \ No newline at end of file +interface Derivative +{ +} diff --git a/src/NeuralNet/ActivationFunctions/Base/Contracts/IOBufferDerivative.php b/src/NeuralNet/ActivationFunctions/Base/Contracts/IOBufferDerivative.php index 3081c70dd..c77ff3e04 100644 --- a/src/NeuralNet/ActivationFunctions/Base/Contracts/IOBufferDerivative.php +++ b/src/NeuralNet/ActivationFunctions/Base/Contracts/IOBufferDerivative.php @@ -4,5 +4,4 @@ interface IOBufferDerivative { - -} \ No newline at end of file +} diff --git a/src/NeuralNet/ActivationFunctions/Base/Contracts/OBufferDerivative.php b/src/NeuralNet/ActivationFunctions/Base/Contracts/OBufferDerivative.php index 21fd26cd9..0ae53eeb8 100644 --- a/src/NeuralNet/ActivationFunctions/Base/Contracts/OBufferDerivative.php +++ b/src/NeuralNet/ActivationFunctions/Base/Contracts/OBufferDerivative.php @@ -4,5 +4,4 @@ interface OBufferDerivative { - -} \ No newline at end of file +} diff --git a/src/NeuralNet/ActivationFunctions/Base/Contracts/SingleBufferDerivative.php b/src/NeuralNet/ActivationFunctions/Base/Contracts/SingleBufferDerivative.php index f5f505254..9fb98f894 100644 --- a/src/NeuralNet/ActivationFunctions/Base/Contracts/SingleBufferDerivative.php +++ b/src/NeuralNet/ActivationFunctions/Base/Contracts/SingleBufferDerivative.php @@ -22,5 +22,5 @@ interface SingleBufferDerivative extends Derivative * @param NDArray $x Input matrix * @return NDArray Derivative matrix */ - public function differentiate(NDArray $x): NDArray; -} \ No newline at end of file + public function differentiate(NDArray $x) : NDArray; +} diff --git a/src/NeuralNet/ActivationFunctions/HardSiLU/HardSiLU.php b/src/NeuralNet/ActivationFunctions/HardSiLU/HardSiLU.php index 2de11d15c..783d2fc48 100644 --- a/src/NeuralNet/ActivationFunctions/HardSiLU/HardSiLU.php +++ b/src/NeuralNet/ActivationFunctions/HardSiLU/HardSiLU.php @@ -4,8 +4,6 @@ use Tensor\Matrix; -use function exp; - /** * SiLU * @@ -33,6 +31,7 @@ class HardSiLU implements ActivationFunction public function activate(Matrix $input) : Matrix { $hardSigmoid = new HardSigmoid()->activate($input); + return $input * $hardSigmoid; } diff --git a/src/NeuralNet/ActivationFunctions/LeakyReLU/LeakyReLU.php b/src/NeuralNet/ActivationFunctions/LeakyReLU/LeakyReLU.php index 047e17d39..339e91c9a 100644 --- a/src/NeuralNet/ActivationFunctions/LeakyReLU/LeakyReLU.php +++ b/src/NeuralNet/ActivationFunctions/LeakyReLU/LeakyReLU.php @@ -74,7 +74,7 @@ public function differentiate(Matrix $input, Matrix $output) : Matrix { $positive = NumPower::greater($input, 0); $negative = NumPower::lessEqual($input, 0) * $this->leakage; - + return $positive + $negative; } diff --git a/src/NeuralNet/ActivationFunctions/SiLU/SiLU.php b/src/NeuralNet/ActivationFunctions/SiLU/SiLU.php index 4d58381eb..340e2b7be 100644 --- a/src/NeuralNet/ActivationFunctions/SiLU/SiLU.php +++ b/src/NeuralNet/ActivationFunctions/SiLU/SiLU.php @@ -4,8 +4,6 @@ use Tensor\Matrix; -use function exp; - /** * SiLU * diff --git a/src/NeuralNet/ActivationFunctions/Softmax/Softmax.php b/src/NeuralNet/ActivationFunctions/Softmax/Softmax.php index 468fcb5d8..62d1d077c 100644 --- a/src/NeuralNet/ActivationFunctions/Softmax/Softmax.php +++ b/src/NeuralNet/ActivationFunctions/Softmax/Softmax.php @@ -4,8 +4,6 @@ use Tensor\Matrix; -use const Rubix\ML\EPSILON; - /** * Softmax * @@ -34,7 +32,7 @@ public function activate(Matrix $input) : Matrix public function differentiate(Matrix $input, Matrix $output) : Matrix { $s = 1 / (1 + NumPower::exp(-$input)); - + return NumPower::diag($s) - NumPower::outer($s, $s); } diff --git a/src/NeuralNet/FeedForward.php b/src/NeuralNet/FeedForward.php index 658691e5c..5cffe79b1 100644 --- a/src/NeuralNet/FeedForward.php +++ b/src/NeuralNet/FeedForward.php @@ -27,7 +27,8 @@ * @package Rubix/ML * @author Andrew DalPino */ -class FeedForward extends Network { +class FeedForward extends Network +{ /** * The input layer to the network. * diff --git a/src/PersistentModel.php b/src/PersistentModel.php index 5e0129b04..1acf8b88d 100644 --- a/src/PersistentModel.php +++ b/src/PersistentModel.php @@ -54,7 +54,7 @@ class PersistentModel implements EstimatorWrapper, Learner, Probabilistic, Scori */ public static function load(Persister $persister, ?Serializer $serializer = null) : self { - $serializer = $serializer ?? new RBX(); + $serializer ??= new RBX(); $base = $serializer->deserialize($persister->load()); diff --git a/src/Regressors/SVR.php b/src/Regressors/SVR.php index 8e9f04a8c..702128bf2 100644 --- a/src/Regressors/SVR.php +++ b/src/Regressors/SVR.php @@ -98,7 +98,7 @@ public function __construct( . " greater than 0, $epsilon given."); } - $kernel = $kernel ?? new RBF(); + $kernel ??= new RBF(); if ($tolerance < 0.0) { throw new InvalidArgumentException('Tolerance must be' diff --git a/src/Transformers/ImageRotator.php b/src/Transformers/ImageRotator.php index 20afaaa8f..8969ad92c 100644 --- a/src/Transformers/ImageRotator.php +++ b/src/Transformers/ImageRotator.php @@ -116,7 +116,7 @@ protected function rotateAndCrop(array &$sample) : void 'x' => $newWidth / 2 - $originalWidth / 2, 'y' => $newHeight / 2 - $originalHeight / 2, 'width' => $originalWidth, - 'height' => $originalHeight + 'height' => $originalHeight, ]); } diff --git a/tests/AnomalyDetectors/RobustZScoreTest.php b/tests/AnomalyDetectors/RobustZScoreTest.php index cfc614b37..8e400cf3e 100644 --- a/tests/AnomalyDetectors/RobustZScoreTest.php +++ b/tests/AnomalyDetectors/RobustZScoreTest.php @@ -61,7 +61,7 @@ protected function setUp() : void y: 0.0, scale: 8.0, noise: 1.0 - ) + ), ], weights: [0.9, 0.1] ); diff --git a/tests/Base/GridSearchTest.php b/tests/Base/GridSearchTest.php index 22d2a05be..841a5306b 100644 --- a/tests/Base/GridSearchTest.php +++ b/tests/Base/GridSearchTest.php @@ -60,7 +60,7 @@ class: KNearestNeighbors::class, [true], [ new Euclidean(), - new Manhattan() + new Manhattan(), ], ], metric: new FBeta(), diff --git a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php index 712854e96..1a42ce5b2 100644 --- a/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELU/ELUTest.php @@ -34,7 +34,7 @@ public static function computeProvider() : Generator { yield [ NumPower::array([ - [1.0, -0.5, 0.0, 20.0, -10.0] + [1.0, -0.5, 0.0, 20.0, -10.0], ]), [ [1.0, -0.39346933364868164, 0.0, 20.0, -0.9999545812606812], diff --git a/tests/NeuralNet/ActivationFunctions/ELUTest.php b/tests/NeuralNet/ActivationFunctions/ELUTest.php index b848701fa..62db8b087 100644 --- a/tests/NeuralNet/ActivationFunctions/ELUTest.php +++ b/tests/NeuralNet/ActivationFunctions/ELUTest.php @@ -23,7 +23,7 @@ public static function computeProvider() : Generator { yield [ Matrix::quick([ - [1.0, -0.5, 0.0, 20.0, -10.0] + [1.0, -0.5, 0.0, 20.0, -10.0], ]), [ [1.0, -0.3934693402873666, 0.0, 20.0, -0.9999546000702375], diff --git a/tests/NeuralNet/Initializers/He/HeUniformTest.php b/tests/NeuralNet/Initializers/He/HeUniformTest.php index 0a2ffa4e5..0582dfffe 100644 --- a/tests/NeuralNet/Initializers/He/HeUniformTest.php +++ b/tests/NeuralNet/Initializers/He/HeUniformTest.php @@ -37,7 +37,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -60,7 +60,7 @@ public static function heUniformDistributionValidationProvider() : array 'big numbers' => [ 'fanIn' => 200, 'fanOut' => 300, - ] + ], ]; } diff --git a/tests/NeuralNet/Initializers/LeCun/LeCunNormalTest.php b/tests/NeuralNet/Initializers/LeCun/LeCunNormalTest.php index 202ef6a15..d9aefe12b 100644 --- a/tests/NeuralNet/Initializers/LeCun/LeCunNormalTest.php +++ b/tests/NeuralNet/Initializers/LeCun/LeCunNormalTest.php @@ -37,7 +37,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -60,7 +60,7 @@ public static function leCunNormalDistributionValidationProvider() : array 'big numbers' => [ 'fanIn' => 3000, 'fanOut' => 1000, - ] + ], ]; } diff --git a/tests/NeuralNet/Initializers/LeCun/LeCunUniformTest.php b/tests/NeuralNet/Initializers/LeCun/LeCunUniformTest.php index 515aa49f2..2064edda8 100644 --- a/tests/NeuralNet/Initializers/LeCun/LeCunUniformTest.php +++ b/tests/NeuralNet/Initializers/LeCun/LeCunUniformTest.php @@ -37,7 +37,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -60,7 +60,7 @@ public static function leCunUniformDistributionValidationProvider() : array 'big numbers' => [ 'fanIn' => 200, 'fanOut' => 300, - ] + ], ]; } diff --git a/tests/NeuralNet/Initializers/Normal/NormalTest.php b/tests/NeuralNet/Initializers/Normal/NormalTest.php index 7c676ec97..9d6641966 100644 --- a/tests/NeuralNet/Initializers/Normal/NormalTest.php +++ b/tests/NeuralNet/Initializers/Normal/NormalTest.php @@ -32,7 +32,7 @@ public static function invalidStandardDeviationProvider() : array ], 'zero stdDev' => [ 'stdDev' => 0, - ] + ], ]; } @@ -55,7 +55,7 @@ public static function validFanInFanOutCombinationsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -70,7 +70,7 @@ public static function normalDistributionInitializationProvider() : array 'small matrix' => [ 'fanIn' => 80, 'fanOut' => 50, - 'stdDev' => 0.25 + 'stdDev' => 0.25, ], 'medium matrix' => [ 'fanIn' => 300, @@ -80,8 +80,8 @@ public static function normalDistributionInitializationProvider() : array 'large matrix' => [ 'fanIn' => 3000, 'fanOut' => 1000, - 'stdDev' => 1.75 - ] + 'stdDev' => 1.75, + ], ]; } diff --git a/tests/NeuralNet/Initializers/Normal/TruncatedNormalTest.php b/tests/NeuralNet/Initializers/Normal/TruncatedNormalTest.php index 02ab90d72..82f4e88aa 100644 --- a/tests/NeuralNet/Initializers/Normal/TruncatedNormalTest.php +++ b/tests/NeuralNet/Initializers/Normal/TruncatedNormalTest.php @@ -32,7 +32,7 @@ public static function invalidStandardDeviationProvider() : array ], 'zero stdDev' => [ 'stdDev' => 0, - ] + ], ]; } @@ -55,7 +55,7 @@ public static function validFanInFanOutCombinationsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -70,7 +70,7 @@ public static function truncatedNormalDistributionInitializationProvider() : arr 'small numbers' => [ 'fanIn' => 30, 'fanOut' => 10, - 'stdDev' => 0.25 + 'stdDev' => 0.25, ], 'medium numbers' => [ 'fanIn' => 300, @@ -80,8 +80,8 @@ public static function truncatedNormalDistributionInitializationProvider() : arr 'big numbers' => [ 'fanIn' => 3000, 'fanOut' => 1000, - 'stdDev' => 1.75 - ] + 'stdDev' => 1.75, + ], ]; } diff --git a/tests/NeuralNet/Initializers/Uniform/UniformTest.php b/tests/NeuralNet/Initializers/Uniform/UniformTest.php index 966c0042a..a22d70a47 100644 --- a/tests/NeuralNet/Initializers/Uniform/UniformTest.php +++ b/tests/NeuralNet/Initializers/Uniform/UniformTest.php @@ -32,7 +32,7 @@ public static function betaProvider() : array ], 'zero beta' => [ 'beta' => 0, - ] + ], ]; } @@ -55,7 +55,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -81,7 +81,7 @@ public static function uniformDistributionValidationProvider() : array 'fanIn' => 200, 'fanOut' => 300, 'beta' => 0.3, - ] + ], ]; } diff --git a/tests/NeuralNet/Initializers/Xavier/XavierNormalTest.php b/tests/NeuralNet/Initializers/Xavier/XavierNormalTest.php index f2d3f20d7..95ed3e6f0 100644 --- a/tests/NeuralNet/Initializers/Xavier/XavierNormalTest.php +++ b/tests/NeuralNet/Initializers/Xavier/XavierNormalTest.php @@ -37,7 +37,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -60,7 +60,7 @@ public static function xavierNormalDistributionValidationProvider() : array 'big numbers' => [ 'fanIn' => 3000, 'fanOut' => 1000, - ] + ], ]; } diff --git a/tests/NeuralNet/Initializers/Xavier/XavierUniformTest.php b/tests/NeuralNet/Initializers/Xavier/XavierUniformTest.php index 22479df2a..236d69b80 100644 --- a/tests/NeuralNet/Initializers/Xavier/XavierUniformTest.php +++ b/tests/NeuralNet/Initializers/Xavier/XavierUniformTest.php @@ -37,7 +37,7 @@ public static function validShapeDimensionsProvider() : array 'fanIn less than fanOut' => [ 'fanIn' => 3, 'fanOut' => 4, - ] + ], ]; } @@ -60,7 +60,7 @@ public static function xavierUniformDistributionValidationProvider() : array 'big numbers' => [ 'fanIn' => 200, 'fanOut' => 300, - ] + ], ]; } diff --git a/tests/Specifications/SamplesAreCompatibleWithTransformerTest.php b/tests/Specifications/SamplesAreCompatibleWithTransformerTest.php index f89a2b50c..06ffcb300 100644 --- a/tests/Specifications/SamplesAreCompatibleWithTransformerTest.php +++ b/tests/Specifications/SamplesAreCompatibleWithTransformerTest.php @@ -37,7 +37,7 @@ public static function passesProvider() : Generator yield [ SamplesAreCompatibleWithTransformer::with( Unlabeled::quick([ - [1, 2, 3, 4, 5] + [1, 2, 3, 4, 5], ]), new L1Normalizer() ), diff --git a/tests/Tokenizers/SentenceTest.php b/tests/Tokenizers/SentenceTest.php index f086706df..16b85a1a4 100644 --- a/tests/Tokenizers/SentenceTest.php +++ b/tests/Tokenizers/SentenceTest.php @@ -61,7 +61,7 @@ public static function tokenizeProvider() : Generator 'Porque cambian las cosas.', 'Empujan a la raza humana hacia adelante.', 'Y mientras que algunos pueden verlos como los locos, nosotros vemos genio.', - 'Porque las personas que están lo suficientemente locas como para pensar que pueden cambiar el mundo, son las que lo hacen.' + 'Porque las personas que están lo suficientemente locas como para pensar que pueden cambiar el mundo, son las que lo hacen.', ], ]; @@ -166,7 +166,7 @@ public static function tokenizeProvider() : Generator 'آیا این برای من خوب خواهد بود؟', 'آیا توانستی به من کمک کنی؟', 'این کتاب بسیار جالب است!', - '"با توجه به شرایطی که الان داریم، آیا می‌توانیم به یک قرار ملاقات برسیم"؟' + '"با توجه به شرایطی که الان داریم، آیا می‌توانیم به یک قرار ملاقات برسیم"؟', ], ]; diff --git a/tests/Transformers/MaxAbsoluteScalerTest.php b/tests/Transformers/MaxAbsoluteScalerTest.php index 941d320de..08d9faf1a 100644 --- a/tests/Transformers/MaxAbsoluteScalerTest.php +++ b/tests/Transformers/MaxAbsoluteScalerTest.php @@ -83,7 +83,7 @@ public function testReverseTransformUnfitted() : void public function testSkipsNonFinite() : void { $samples = Unlabeled::build(samples: [ - [0.0, 3000.0, NAN, -6.0], [1.0, 30.0, NAN, 0.001] + [0.0, 3000.0, NAN, -6.0], [1.0, 30.0, NAN, 0.001], ]); $this->transformer->fit($samples); $this->assertNan($samples[0][2]); diff --git a/tests/Transformers/MinMaxNormalizerTest.php b/tests/Transformers/MinMaxNormalizerTest.php index d427a3485..4e52109f1 100644 --- a/tests/Transformers/MinMaxNormalizerTest.php +++ b/tests/Transformers/MinMaxNormalizerTest.php @@ -79,7 +79,7 @@ public function testTransformUnfitted() : void public function testSkipsNonFinite() : void { $samples = Unlabeled::build(samples: [ - [0.0, 3000.0, NAN, -6.0], [1.0, 30.0, NAN, 0.001] + [0.0, 3000.0, NAN, -6.0], [1.0, 30.0, NAN, 0.001], ]); $this->transformer->fit($samples); $this->assertNan($samples[0][2]); From 9cfdba6febc7200ea2d924672d751a3fd4bb9a25 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 16:57:08 +0300 Subject: [PATCH 10/14] Improved configuration for PHP-CS-Fixer --- .gitignore | 3 +++ .php-cs-fixer.dist.php | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 01178821b..bb704a7df 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ pyvenv.cfg .vscode .vs +# Cache files +/runtime/ + # Docker related files Dockerfile /docker/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 94ede022b..6be85b569 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -3,12 +3,20 @@ use PhpCsFixer\Finder; use PhpCsFixer\Config; -$finder = Finder::create()->in(__DIR__) - ->exclude('docs'); +$finder = Finder::create() + ->exclude([ + __DIR__ . '/docs/', + __DIR__ . '/vendor/', + ]) + ->in(__DIR__) + ->append([ + __FILE__, + ]); $config = new Config(); - -return $config->setRules([ +$config + ->setCacheFile(__DIR__ . '/runtime/.php-cs-fixer.cache') + ->setRules([ '@PSR2' => true, '@PHP84Migration' => true, 'align_multiline_comment' => true, @@ -116,3 +124,5 @@ 'unary_operator_spaces' => true, 'whitespace_after_comma_in_array' => true, ])->setFinder($finder); + +return $config; From 1e6b8571e9d8ab7cf199432c5bfee98524ad735b Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 16:57:25 +0300 Subject: [PATCH 11/14] Added PHP linter --- .phplint.yml | 8 ++++++++ composer.json | 2 ++ 2 files changed, 10 insertions(+) create mode 100644 .phplint.yml diff --git a/.phplint.yml b/.phplint.yml new file mode 100644 index 000000000..531cc831f --- /dev/null +++ b/.phplint.yml @@ -0,0 +1,8 @@ +path: ./ +jobs: 10 +cache-dir: runtime/.phplint.cache/ +extensions: + - php +exclude: + - vendor/ + - runtime/ diff --git a/composer.json b/composer.json index dad3b6843..2bdce584d 100644 --- a/composer.json +++ b/composer.json @@ -44,6 +44,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.73", "phpbench/phpbench": "^1.0", + "overtrue/phplint": "^9.6.2", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^2.0", "phpstan/phpstan-phpunit": "^2.0", @@ -89,6 +90,7 @@ "@putenv PHP_CS_FIXER_IGNORE_ENV=1", "php-cs-fixer fix --config=.php-cs-fixer.dist.php" ], + "phplint": "phplint", "test": "phpunit" }, "config": { From 797da3d485db0290189a69e807de388f388fa06f Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 17:00:43 +0300 Subject: [PATCH 12/14] Improved configuration for PHP-CS-Fixer --- .php-cs-fixer.dist.php | 211 +++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 105 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 6be85b569..868df1714 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -17,112 +17,113 @@ $config ->setCacheFile(__DIR__ . '/runtime/.php-cs-fixer.cache') ->setRules([ - '@PSR2' => true, - '@PHP84Migration' => true, - 'align_multiline_comment' => true, - 'array_syntax' => ['syntax' => 'short'], - 'backtick_to_shell_exec' => true, - 'binary_operator_spaces' => true, - 'blank_lines_before_namespace' => true, - 'blank_line_after_namespace' => true, - 'blank_line_after_opening_tag' => true, - 'blank_line_before_statement' => [ - 'statements' => [ - 'break', 'case', 'continue', 'declare', 'default', 'do', 'for', - 'if', 'foreach', 'return', 'switch', 'try', 'while', + '@PSR2' => true, + '@PHP84Migration' => true, + 'align_multiline_comment' => true, + 'array_syntax' => ['syntax' => 'short'], + 'backtick_to_shell_exec' => true, + 'binary_operator_spaces' => true, + 'blank_lines_before_namespace' => true, + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', 'case', 'continue', 'declare', 'default', 'do', 'for', + 'if', 'foreach', 'return', 'switch', 'try', 'while', + ], ], - ], - 'cast_spaces' => ['space' => 'single'], - 'class_attributes_separation' => true, - 'combine_consecutive_issets' => true, - 'combine_consecutive_unsets' => true, - 'compact_nullable_type_declaration' => true, - 'concat_space' => ['spacing' => 'one'], - 'fully_qualified_strict_types' => true, - 'increment_style' => ['style' => 'pre'], - 'linebreak_after_opening_tag' => true, - 'list_syntax' => ['syntax' => 'short'], - 'lowercase_cast' => true, - 'lowercase_static_reference' => true, - 'magic_constant_casing' => true, - 'magic_method_casing' => true, - 'multiline_comment_opening_closing' => true, - 'multiline_whitespace_before_semicolons' => [ - 'strategy' => 'no_multi_line', - ], - 'native_function_casing' => true, - 'native_type_declaration_casing' => true, - 'new_with_parentheses' => true, - 'no_alternative_syntax' => true, - 'no_blank_lines_after_class_opening' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_mixed_echo_print' => ['use' => 'echo'], - 'no_null_property_initialization' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_spaces_around_offset' => true, - 'no_superfluous_phpdoc_tags' => false, - 'no_superfluous_elseif' => true, - 'no_trailing_comma_in_singleline' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unneeded_braces' => true, - 'no_unset_cast' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'no_whitespace_before_comma_in_array' => true, - 'no_whitespace_in_blank_line' => true, - 'normalize_index_brace' => true, - 'nullable_type_declaration_for_default_null_value' => true, - 'object_operator_without_whitespace' => true, - 'ordered_class_elements' => [ - 'order' => [ - 'use_trait', 'constant_public', 'constant_protected', - 'constant_private', 'property_public_static', 'property_protected_static', - 'property_private_static', 'property_public', 'property_protected', - 'property_private', 'method_public_static', 'method_protected_static', - 'method_private_static', 'construct', 'destruct', 'phpunit', - 'method_public', 'method_protected', 'method_private', 'magic', + 'cast_spaces' => ['space' => 'single'], + 'class_attributes_separation' => true, + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'compact_nullable_type_declaration' => true, + 'concat_space' => ['spacing' => 'one'], + 'fully_qualified_strict_types' => true, + 'increment_style' => ['style' => 'pre'], + 'linebreak_after_opening_tag' => true, + 'list_syntax' => ['syntax' => 'short'], + 'lowercase_cast' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', ], - 'sort_algorithm' => 'none', - ], - 'php_unit_fqcn_annotation' => true, - 'php_unit_method_casing' => ['case' => 'camel_case'], - 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], - 'phpdoc_align' => ['align' => 'left'], - 'phpdoc_line_span' => [ - 'const' => 'multi', - 'method' => 'multi', - 'property' => 'multi', - ], - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_useless_inheritdoc' => true, - 'phpdoc_order' => true, - 'phpdoc_scalar' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_to_comment' => false, - 'phpdoc_trim' => true, - 'phpdoc_trim_consecutive_blank_line_separation' => true, - 'phpdoc_var_without_name' => true, - 'protected_to_private' => true, - 'return_assignment' => false, - 'return_type_declaration' => ['space_before' => 'one'], - 'semicolon_after_instruction' => true, - 'short_scalar_cast' => true, - 'simplified_null_return' => true, - 'single_quote' => true, - 'single_line_comment_style' => true, - 'ternary_operator_spaces' => true, - 'ternary_to_null_coalescing' => true, - 'type_declaration_spaces' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'whitespace_after_comma_in_array' => true, -])->setFinder($finder); + 'native_function_casing' => true, + 'native_type_declaration_casing' => true, + 'new_with_parentheses' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => ['use' => 'echo'], + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_around_offset' => true, + 'no_superfluous_phpdoc_tags' => false, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_braces' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'nullable_type_declaration_for_default_null_value' => true, + 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', 'constant_public', 'constant_protected', + 'constant_private', 'property_public_static', 'property_protected_static', + 'property_private_static', 'property_public', 'property_protected', + 'property_private', 'method_public_static', 'method_protected_static', + 'method_private_static', 'construct', 'destruct', 'phpunit', + 'method_public', 'method_protected', 'method_private', 'magic', + ], + 'sort_algorithm' => 'none', + ], + 'php_unit_fqcn_annotation' => true, + 'php_unit_method_casing' => ['case' => 'camel_case'], + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], + 'phpdoc_align' => ['align' => 'left'], + 'phpdoc_line_span' => [ + 'const' => 'multi', + 'method' => 'multi', + 'property' => 'multi', + ], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_to_comment' => false, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_var_without_name' => true, + 'protected_to_private' => true, + 'return_assignment' => false, + 'return_type_declaration' => ['space_before' => 'one'], + 'semicolon_after_instruction' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => true, + 'single_quote' => true, + 'single_line_comment_style' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_null_coalescing' => true, + 'type_declaration_spaces' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + ] +)->setFinder($finder); return $config; From 3bb51660a06bdb5953d65fe1d94149f8b1372820 Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 17:02:56 +0300 Subject: [PATCH 13/14] Improved configuration for PHP-CS-Fixer --- .php-cs-fixer.dist.php | 215 +++++++++++++++++++++-------------------- 1 file changed, 108 insertions(+), 107 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 868df1714..bf912673a 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -16,114 +16,115 @@ $config = new Config(); $config ->setCacheFile(__DIR__ . '/runtime/.php-cs-fixer.cache') - ->setRules([ - '@PSR2' => true, - '@PHP84Migration' => true, - 'align_multiline_comment' => true, - 'array_syntax' => ['syntax' => 'short'], - 'backtick_to_shell_exec' => true, - 'binary_operator_spaces' => true, - 'blank_lines_before_namespace' => true, - 'blank_line_after_namespace' => true, - 'blank_line_after_opening_tag' => true, - 'blank_line_before_statement' => [ - 'statements' => [ - 'break', 'case', 'continue', 'declare', 'default', 'do', 'for', - 'if', 'foreach', 'return', 'switch', 'try', 'while', + ->setRules( + [ + '@PSR2' => true, + '@PHP84Migration' => true, + 'align_multiline_comment' => true, + 'array_syntax' => ['syntax' => 'short'], + 'backtick_to_shell_exec' => true, + 'binary_operator_spaces' => true, + 'blank_lines_before_namespace' => true, + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', 'case', 'continue', 'declare', 'default', 'do', 'for', + 'if', 'foreach', 'return', 'switch', 'try', 'while', + ], ], - ], - 'cast_spaces' => ['space' => 'single'], - 'class_attributes_separation' => true, - 'combine_consecutive_issets' => true, - 'combine_consecutive_unsets' => true, - 'compact_nullable_type_declaration' => true, - 'concat_space' => ['spacing' => 'one'], - 'fully_qualified_strict_types' => true, - 'increment_style' => ['style' => 'pre'], - 'linebreak_after_opening_tag' => true, - 'list_syntax' => ['syntax' => 'short'], - 'lowercase_cast' => true, - 'lowercase_static_reference' => true, - 'magic_constant_casing' => true, - 'magic_method_casing' => true, - 'multiline_comment_opening_closing' => true, - 'multiline_whitespace_before_semicolons' => [ - 'strategy' => 'no_multi_line', - ], - 'native_function_casing' => true, - 'native_type_declaration_casing' => true, - 'new_with_parentheses' => true, - 'no_alternative_syntax' => true, - 'no_blank_lines_after_class_opening' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_mixed_echo_print' => ['use' => 'echo'], - 'no_null_property_initialization' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_spaces_around_offset' => true, - 'no_superfluous_phpdoc_tags' => false, - 'no_superfluous_elseif' => true, - 'no_trailing_comma_in_singleline' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unneeded_braces' => true, - 'no_unset_cast' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'no_whitespace_before_comma_in_array' => true, - 'no_whitespace_in_blank_line' => true, - 'normalize_index_brace' => true, - 'nullable_type_declaration_for_default_null_value' => true, - 'object_operator_without_whitespace' => true, - 'ordered_class_elements' => [ - 'order' => [ - 'use_trait', 'constant_public', 'constant_protected', - 'constant_private', 'property_public_static', 'property_protected_static', - 'property_private_static', 'property_public', 'property_protected', - 'property_private', 'method_public_static', 'method_protected_static', - 'method_private_static', 'construct', 'destruct', 'phpunit', - 'method_public', 'method_protected', 'method_private', 'magic', + 'cast_spaces' => ['space' => 'single'], + 'class_attributes_separation' => true, + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'compact_nullable_type_declaration' => true, + 'concat_space' => ['spacing' => 'one'], + 'fully_qualified_strict_types' => true, + 'increment_style' => ['style' => 'pre'], + 'linebreak_after_opening_tag' => true, + 'list_syntax' => ['syntax' => 'short'], + 'lowercase_cast' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', ], - 'sort_algorithm' => 'none', - ], - 'php_unit_fqcn_annotation' => true, - 'php_unit_method_casing' => ['case' => 'camel_case'], - 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], - 'phpdoc_align' => ['align' => 'left'], - 'phpdoc_line_span' => [ - 'const' => 'multi', - 'method' => 'multi', - 'property' => 'multi', - ], - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_useless_inheritdoc' => true, - 'phpdoc_order' => true, - 'phpdoc_scalar' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_to_comment' => false, - 'phpdoc_trim' => true, - 'phpdoc_trim_consecutive_blank_line_separation' => true, - 'phpdoc_var_without_name' => true, - 'protected_to_private' => true, - 'return_assignment' => false, - 'return_type_declaration' => ['space_before' => 'one'], - 'semicolon_after_instruction' => true, - 'short_scalar_cast' => true, - 'simplified_null_return' => true, - 'single_quote' => true, - 'single_line_comment_style' => true, - 'ternary_operator_spaces' => true, - 'ternary_to_null_coalescing' => true, - 'type_declaration_spaces' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'whitespace_after_comma_in_array' => true, - ] -)->setFinder($finder); + 'native_function_casing' => true, + 'native_type_declaration_casing' => true, + 'new_with_parentheses' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => ['use' => 'echo'], + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_around_offset' => true, + 'no_superfluous_phpdoc_tags' => false, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_braces' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'nullable_type_declaration_for_default_null_value' => true, + 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', 'constant_public', 'constant_protected', + 'constant_private', 'property_public_static', 'property_protected_static', + 'property_private_static', 'property_public', 'property_protected', + 'property_private', 'method_public_static', 'method_protected_static', + 'method_private_static', 'construct', 'destruct', 'phpunit', + 'method_public', 'method_protected', 'method_private', 'magic', + ], + 'sort_algorithm' => 'none', + ], + 'php_unit_fqcn_annotation' => true, + 'php_unit_method_casing' => ['case' => 'camel_case'], + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], + 'phpdoc_align' => ['align' => 'left'], + 'phpdoc_line_span' => [ + 'const' => 'multi', + 'method' => 'multi', + 'property' => 'multi', + ], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_to_comment' => false, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_var_without_name' => true, + 'protected_to_private' => true, + 'return_assignment' => false, + 'return_type_declaration' => ['space_before' => 'one'], + 'semicolon_after_instruction' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => true, + 'single_quote' => true, + 'single_line_comment_style' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_null_coalescing' => true, + 'type_declaration_spaces' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + ] + )->setFinder($finder); return $config; From cb4aa27c727af19067202ffd7804721b1314cf9a Mon Sep 17 00:00:00 2001 From: Samuel Akopyan Date: Tue, 17 Jun 2025 17:09:15 +0300 Subject: [PATCH 14/14] Improved configuration for phpstan --- phpstan.neon | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpstan.neon b/phpstan.neon index 991aa6d0b..bc464a8ea 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,10 @@ includes: - phpstan-baseline.neon parameters: level: 8 + phpVersion: 80400 + fileExtensions: + - php + tmpDir: ./runtime/.phpstan/ paths: - 'src' - 'benchmarks'