/**
* Compute the new position (coordinate vector) of a cluster center.
*/
@Override
public void reduce(Iterator<Record> dataPoints, Collector<Record> out) {
Record next = null;
// initialize coordinate vector sum and count
CoordVector coordinates = new CoordVector();
double[] coordinateSum = null;
int count = 0;
// compute coordinate vector sum and count
while (dataPoints.hasNext()) {
next = dataPoints.next();
// get the coordinates and the count from the record
double[] thisCoords = next.getField(1, CoordVector.class).getCoordinates();
int thisCount = next.getField(2, IntValue.class).getValue();
if (coordinateSum == null) {
if (coordinates.getCoordinates() != null) {
coordinateSum = coordinates.getCoordinates();
}
else {
coordinateSum = new double[thisCoords.length];
}
}
addToCoordVector(coordinateSum, thisCoords);
count += thisCount;
}
// compute new coordinate vector (position) of cluster center
for (int i = 0; i < coordinateSum.length; i++) {
coordinateSum[i] /= count;
}
coordinates.setCoordinates(coordinateSum);
next.setField(1, coordinates);
next.setNull(2);
// emit new position of cluster center
out.collect(next);
}