center = Vector::quick([$x, $y, $z]); $this->scale = $scale; $this->depth = $depth; $this->noise = $noise; } /** * Return the dimensionality of the data this generates. * * @internal * * @return int<0,max> */ public function dimensions() : int { return 3; } /** * Generate n data points. * * @param int<0,max> $n * @return Labeled */ public function generate(int $n) : Labeled { $t = Vector::rand($n) ->multiply(2) ->add(1) ->multiply(M_PI + HALF_PI); $x = $t->multiply($t->cos())->asArray(); $y = Vector::rand($n)->multiply($this->depth)->asArray(); $z = $t->multiply($t->sin())->asArray(); $coordinates = array_transpose([$x, $y, $z]); $noise = Matrix::gaussian($n, 3) ->multiply($this->noise); $samples = Matrix::quick($coordinates) ->multiply($this->scale) ->add($this->center) ->add($noise) ->asArray(); $labels = $t->asArray(); return Labeled::quick($samples, $labels); } }