php-ml/src/Clustering/KMeans/Point.php

126 lines
2.4 KiB
PHP
Raw Normal View History

2016-05-01 21:17:09 +00:00
<?php
2016-05-01 21:36:33 +00:00
2016-11-20 21:53:17 +00:00
declare(strict_types=1);
2016-05-01 21:17:09 +00:00
namespace Phpml\Clustering\KMeans;
2016-05-01 21:36:33 +00:00
use ArrayAccess;
2016-05-01 21:17:09 +00:00
2018-10-28 06:44:52 +00:00
class Point implements ArrayAccess, \Countable
2016-05-01 21:17:09 +00:00
{
2016-05-01 21:36:33 +00:00
/**
* @var int
*/
protected $dimension;
/**
* @var array
*/
protected $coordinates = [];
2016-05-01 21:36:33 +00:00
/**
* @var mixed
*/
protected $label;
2018-10-28 06:44:52 +00:00
/**
* @param mixed $label
*/
public function __construct(array $coordinates, $label = null)
2016-05-01 21:36:33 +00:00
{
$this->dimension = count($coordinates);
$this->coordinates = $coordinates;
$this->label = $label;
2016-05-01 21:36:33 +00:00
}
public function toArray(): array
2016-05-01 21:36:33 +00:00
{
return $this->coordinates;
}
/**
2018-10-28 06:44:52 +00:00
* @return float|int
2016-05-01 21:36:33 +00:00
*/
public function getDistanceWith(self $point, bool $precise = true)
2016-05-01 21:36:33 +00:00
{
$distance = 0;
for ($n = 0; $n < $this->dimension; ++$n) {
$difference = $this->coordinates[$n] - $point->coordinates[$n];
2016-11-20 21:53:17 +00:00
$distance += $difference * $difference;
2016-05-01 21:36:33 +00:00
}
return $precise ? $distance ** .5 : $distance;
2016-05-01 21:36:33 +00:00
}
/**
2018-10-28 06:44:52 +00:00
* @param Point[] $points
2016-05-01 21:36:33 +00:00
*/
2018-10-28 06:44:52 +00:00
public function getClosest(array $points): ?self
2016-05-01 21:36:33 +00:00
{
$minPoint = null;
2016-05-01 21:36:33 +00:00
foreach ($points as $point) {
$distance = $this->getDistanceWith($point, false);
if (!isset($minDistance)) {
$minDistance = $distance;
$minPoint = $point;
2016-05-01 21:36:33 +00:00
continue;
}
if ($distance < $minDistance) {
$minDistance = $distance;
$minPoint = $point;
}
}
return $minPoint;
}
public function getCoordinates(): array
2016-05-01 21:36:33 +00:00
{
return $this->coordinates;
}
/**
* @param mixed $offset
*/
public function offsetExists($offset): bool
2016-05-01 21:36:33 +00:00
{
return isset($this->coordinates[$offset]);
}
/**
* @param mixed $offset
*
* @return mixed
*/
public function offsetGet($offset)
{
return $this->coordinates[$offset];
}
/**
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet($offset, $value): void
2016-05-01 21:36:33 +00:00
{
$this->coordinates[$offset] = $value;
}
/**
* @param mixed $offset
*/
public function offsetUnset($offset): void
2016-05-01 21:36:33 +00:00
{
unset($this->coordinates[$offset]);
}
2018-10-28 06:44:52 +00:00
public function count(): int
{
return count($this->coordinates);
}
2016-05-01 21:17:09 +00:00
}