360.0) { throw new InvalidArgumentException('Rotation must be' . " between 0 and 360, $rotation given."); } if ($noise < 0.0) { throw new InvalidArgumentException('Noise must be' . " greater than 0, $noise given."); } $this->center = Vector::quick([$x, $y]); $this->scale = $scale; $this->rotation = $rotation; $this->noise = $noise; } /** * Return the dimensionality of the data this generates. * * @internal * * @return int<0,max> */ public function dimensions() : int { return 2; } /** * Generate n data points. * * @param int<0,max> $n * @return Labeled */ public function generate(int $n) : Labeled { $r = Vector::rand($n)->multiply(M_PI) ->add(deg2rad($this->rotation)); $x = $r->cos()->asArray(); $y = $r->sin()->asArray(); $coordinates = array_transpose([$x, $y]); $noise = Matrix::gaussian($n, 2) ->multiply($this->noise); $samples = Matrix::quick($coordinates) ->multiply($this->scale) ->add($this->center) ->add($noise) ->asArray(); $labels = $r->rad2deg()->asArray(); return Labeled::quick($samples, $labels); } }