Completed
Push — develop ( 01a249...bb9e1a )
by Arkadiusz
02:44
created

Cluster::getIterator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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 array(
54
            'centroid' => parent::toArray(),
55
            'points' => $this->getPoints(),
56
        );
57
    }
58
59
    /**
60
     * @param Point $point
61
     *
62
     * @return Point
63
     */
64
    public function attach(Point $point)
65
    {
66
        if ($point instanceof self) {
67
            throw new LogicException('cannot attach a cluster to another');
68
        }
69
70
        $this->points->attach($point);
71
72
        return $point;
73
    }
74
75
    /**
76
     * @param Point $point
77
     *
78
     * @return Point
79
     */
80
    public function detach(Point $point)
81
    {
82
        $this->points->detach($point);
83
84
        return $point;
85
    }
86
87
    /**
88
     * @param SplObjectStorage $points
89
     */
90
    public function attachAll(SplObjectStorage $points)
91
    {
92
        $this->points->addAll($points);
93
    }
94
95
    /**
96
     * @param SplObjectStorage $points
97
     */
98
    public function detachAll(SplObjectStorage $points)
99
    {
100
        $this->points->removeAll($points);
101
    }
102
103
    public function updateCentroid()
104
    {
105
        if (!$count = count($this->points)) {
106
            return;
107
        }
108
109
        $centroid = $this->space->newPoint(array_fill(0, $this->dimension, 0));
110
111
        foreach ($this->points as $point) {
112 View Code Duplication
            for ($n = 0; $n < $this->dimension; ++$n) {
0 ignored issues
show
Duplication introduced by
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...
113
                $centroid->coordinates[$n] += $point->coordinates[$n];
114
            }
115
        }
116
117 View Code Duplication
        for ($n = 0; $n < $this->dimension; ++$n) {
0 ignored issues
show
Duplication introduced by
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...
118
            $this->coordinates[$n] = $centroid->coordinates[$n] / $count;
119
        }
120
    }
121
122
    /**
123
     * @return Point[]|SplObjectStorage
124
     */
125
    public function getIterator()
126
    {
127
        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 127 which is incompatible with the return type declared by the interface IteratorAggregate::getIterator of type Traversable.
Loading history...
128
    }
129
130
    /**
131
     * @return mixed
132
     */
133
    public function count()
134
    {
135
        return count($this->points);
136
    }
137
}
138