1.0) { throw new InvalidArgumentException('Sparsity must be' . " between 0 and 1, $sparsity given."); } parent::__construct($dimensions); $this->sparsity = $sparsity; } /** * Fit the transformer to a dataset. * * @param Dataset $dataset * @throws InvalidArgumentException */ public function fit(Dataset $dataset) : void { SamplesAreCompatibleWithTransformer::with($dataset, $this)->check(); $n = $dataset->numFeatures(); if (is_null($this->sparsity)) { $density = 1.0 / (1.0 + sqrt($n)); } else { $density = 1.0 - $this->sparsity; } $dHat = sqrt(1.0 / $density); $distribution = [ [-$dHat, 0.5 * $density], [0.0, 1.0 - $density], [$dHat, 0.5 * $density], ]; $max = getrandmax(); $r = []; while (count($r) < $n) { $row = []; while (count($row) < $this->dimensions) { $delta = rand() / $max; foreach ($distribution as [$value, $probability]) { $delta -= $probability; if ($delta <= 0.0) { $row[] = $value; break; } } } $r[] = $row; } $this->r = Matrix::quick($r); } /** * Return the string representation of the object. * * @internal * * @return string */ public function __toString() : string { return "Sparse Random Projector (dimensions: {$this->dimensions}, sparsity: {$this->sparsity})"; } }