Passed
Push — master ( 47cdff...ed5fc8 )
by Arkadiusz
03:38
created

src/Phpml/Clustering/KMeans/Cluster.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Phpml\Clustering\KMeans;
6
7
use IteratorAggregate;
8
use Countable;
9
use SplObjectStorage;
10
use LogicException;
11
12
class Cluster extends Point implements IteratorAggregate, Countable
13
{
14
    /**
15
     * @var Space
16
     */
17
    protected $space;
18
19
    /**
20
     * @var SplObjectStorage|Point[]
21
     */
22
    protected $points;
23
24
    /**
25
     * @param Space $space
26
     * @param array $coordinates
27
     */
28
    public function __construct(Space $space, array $coordinates)
29
    {
30
        parent::__construct($coordinates);
31
        $this->space = $space;
32
        $this->points = new SplObjectStorage();
33
    }
34
35
    /**
36
     * @return array
37
     */
38
    public function getPoints()
39
    {
40
        $points = [];
41
        foreach ($this->points as $point) {
42
            $points[] = $point->toArray();
43
        }
44
45
        return $points;
46
    }
47
48
    /**
49
     * @return array
50
     */
51
    public function toArray()
52
    {
53
        return [
54
            'centroid' => parent::toArray(),
55
            'points' => $this->getPoints(),
56
        ];
57
    }
58
59
    /**
60
     * @param Point $point
61
     *
62
     * @return Point
63
     *
64
     * @throws \LogicException
65
     */
66
    public function attach(Point $point)
67
    {
68
        if ($point instanceof self) {
69
            throw new LogicException('cannot attach a cluster to another');
70
        }
71
72
        $this->points->attach($point);
73
74
        return $point;
75
    }
76
77
    /**
78
     * @param Point $point
79
     *
80
     * @return Point
81
     */
82
    public function detach(Point $point)
83
    {
84
        $this->points->detach($point);
85
86
        return $point;
87
    }
88
89
    /**
90
     * @param SplObjectStorage $points
91
     */
92
    public function attachAll(SplObjectStorage $points)
93
    {
94
        $this->points->addAll($points);
95
    }
96
97
    /**
98
     * @param SplObjectStorage $points
99
     */
100
    public function detachAll(SplObjectStorage $points)
101
    {
102
        $this->points->removeAll($points);
103
    }
104
105
    public function updateCentroid()
106
    {
107
        if (!$count = count($this->points)) {
108
            return;
109
        }
110
111
        $centroid = $this->space->newPoint(array_fill(0, $this->dimension, 0));
112
113
        foreach ($this->points as $point) {
114 View Code Duplication
            for ($n = 0; $n < $this->dimension; ++$n) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
                $centroid->coordinates[$n] += $point->coordinates[$n];
116
            }
117
        }
118
119 View Code Duplication
        for ($n = 0; $n < $this->dimension; ++$n) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
            $this->coordinates[$n] = $centroid->coordinates[$n] / $count;
121
        }
122
    }
123
124
    /**
125
     * @return Point[]|SplObjectStorage
126
     */
127
    public function getIterator()
128
    {
129
        return $this->points;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->points; of type SplObjectStorage|Phpml\Clustering\KMeans\Point[] adds the type Phpml\Clustering\KMeans\Point[] to the return on line 129 which is incompatible with the return type declared by the interface IteratorAggregate::getIterator of type Traversable.
Loading history...
130
    }
131
132
    /**
133
     * @return mixed
134
     */
135
    public function count()
136
    {
137
        return count($this->points);
138
    }
139
    
140
    /**
141
    * @param array $newCoordinates
142
    */
143
    public function setCoordinates(array $newCoordinates)
144
    {
145
        $this->coordinates = $newCoordinates;
146
    }
147
}
148