fit($data); // Due to the fact that the sign of values can be flipped // during the calculation of eigenValues, we have to compare // absolute value of the values array_map(function ($val1, $val2) use ($epsilon): void { $this->assertEquals(abs($val1), abs($val2), '', $epsilon); }, $transformed, $reducedData); // Test fitted PCA object to transform an arbitrary sample of the // same dimensionality with the original dataset foreach ($data as $i => $row) { $newRow = [[$transformed[$i]]]; $newRow2 = $pca->transform($row); array_map(function ($val1, $val2) use ($epsilon): void { $this->assertEquals(abs($val1), abs($val2), '', $epsilon); }, $newRow, $newRow2); } } public function testPCAThrowWhenTotalVarianceOutOfRange(): void { $this->expectException(InvalidArgumentException::class); $pca = new PCA(0, null); } public function testPCAThrowWhenNumFeaturesOutOfRange(): void { $this->expectException(InvalidArgumentException::class); $pca = new PCA(null, 0); } public function testPCAThrowWhenParameterNotSpecified(): void { $this->expectException(InvalidArgumentException::class); $pca = new PCA(); } public function testPCAThrowWhenBothParameterSpecified(): void { $this->expectException(InvalidArgumentException::class); $pca = new PCA(0.9, 1); } public function testTransformThrowWhenNotFitted(): void { $samples = [ [1, 0], [1, 1], ]; $pca = new PCA(0.9); $this->expectException(InvalidOperationException::class); $pca->transform($samples); } }