public List<Double[]> run() throws IOException {
		setKRandomPoints();
		
		// until objective function does not converge... do
		clusterMapping();
		
		// loop while convergence of objective function not satisfied
		// calculate the new centroid points
		Double[] newCentroid = new Double[dimension];
		int pointsCounter = 0;
		double sum = 0.0;
		boolean isStopCondition = false;
		while (!isStopCondition) {
			for (int clusterID = 0; clusterID < clustersMapping.length; clusterID++) {
				List<Integer> indexList = clustersMapping[clusterID];
				for (int d = 0; d < dimension; d++) {
					for (Integer clusterPoint : indexList) {
						sum += points.get(clusterPoint)[d];
						pointsCounter++;
					}
					newCentroid[d] = sum / pointsCounter;
					sum = 0;
					pointsCounter = 0;
				}
				if (!compare(clustersCentroids.get(clusterID), newCentroid)) {
					clustersCentroids.set(clusterID, newCentroid);
					isStopCondition = false;
				} else {
					isStopCondition = true;
				}
				newCentroid = new Double[dimension];
			}
			clusterMapping();
		}
		BufferedWriter writer = null;
        try {
    	    writer = new BufferedWriter(new FileWriter("/Users/xwang/Documents/workspace/SLDA/dictionary.txt"));
    	    for(int i = 0; i < clustersCentroids.size(); i++) {
    	    	for(int j = 0; j < clustersCentroids.get(i).length; j++)
    		        writer.write(clustersCentroids.get(i)[j] + "\t");
    	    	writer.write("\n");
    	    }
        } catch(IOException e) {
    	    e.printStackTrace();
        } finally {
            writer.close();
        }
		return clustersCentroids;
	}