private int ClosestCentroidToCentroid(Centroid c) { double lowestDist = Double.MaxValue; int lowestIndex = 0; for (int i = 0; i < _centroids.Length; i++) { var tmpDist = GetDistance(c, _centroids[i]); if (tmpDist < lowestDist && _centroids[i].Length > 1) { lowestDist = tmpDist; lowestIndex = i; } } return lowestIndex; }
private int ClosestPoint(Centroid c1, Centroid c2) { double lowestDist = GetDistance(c2.GetPoint(0), c1); int lowestIndex = 0; for (int i = 1; i < c2.Length; i++) { var tmpDist = GetDistance(c2.GetPoint(i), c1); if (tmpDist < lowestDist) { lowestDist = tmpDist; lowestIndex = i; } } return lowestIndex; }
void Initialize() { double distortionBeforeUpdate = 0; // distortion measure before // updating centroids double distortionAfterUpdate = 0; // distortion measure after update // centroids // design a 1-vector Codebook _centroids = new Centroid[1]; // then initialize it with (0, 0) coordinates double[] origin = new double[_dimension]; _centroids[0] = new Centroid(origin); // initially, all training points will belong to 1 single cell for (int i = 0; i < _points.Length; i++) { _centroids[0].Add(_points[i], 0); } // calls update to set the initial codevector as the average of all // points _centroids[0].Update(); // Iteration 1: repeat splitting step and K-means until required number // of codewords is reached while (_centroids.Length < _codebookSize) { // split codevectors by a binary splitting method Split(); // group training points to centroids closest to them GroupPtoC(); // Iteration 2: perform K-means algorithm do { for (int i = 0; i < _centroids.Length; i++) { distortionBeforeUpdate += _centroids[i].Distortion; _centroids[i].Update(); } // regroup GroupPtoC(); for (int i = 0; i < _centroids.Length; i++) { distortionAfterUpdate += _centroids[i].Distortion; } } while (Math.Abs(distortionAfterUpdate - distortionBeforeUpdate) < MinDistortion); } }
private void Split() { // "Centroids length now becomes " + centroids.length + 2 Centroid[] temp = new Centroid[_centroids.Length * 2]; double[][] tCo = new double[2][]; for (int i = 0; i < temp.Length; i += 2) { tCo[0] = new double[_dimension]; tCo[1] = new double[_dimension]; for (int j = 0; j < _dimension; j++) { tCo[0][j] = _centroids[i / 2][j] * (1 + SplitValue); tCo[1][j] = _centroids[i / 2][j] * (1 - SplitValue); } temp[i] = new Centroid(tCo[0]); temp[i + 1] = new Centroid(tCo[1]); } // replace old centroids array with new one _centroids = temp; }
private double GetDistance(Point point, Centroid tC) { double distance = 0; for (int i = 0; i < _dimension; i++) { var temp = point[i] - tC[i]; distance += temp * temp; } distance = Math.Sqrt(distance); return distance; }