public double lloydPlusPlus(int k, int n, int d, Point points[]) {
        //System.out.println("starting kMeans++");
        //choose random centres
        this.tmpCentresStreamingCoreset = chooseRandomCentres(k, n, d, points);
        double cost = targetFunctionValue(k, n, this.tmpCentresStreamingCoreset, points);
        double newCost = cost;


        Point[] massCentres = new Point[k];
        double[] numberOfPoints = new double[k];

        do {
            cost = newCost;
            //reset centres of mass
            int i = 0;
            for (i = 0; i < k; i++) {
                massCentres[i] = new Point(d);
                numberOfPoints[i] = 0.0;
            }
            //compute centres of mass
            for (i = 0; i < n; i++) {
                int centre = points[i].determineClusterCentreKMeans(k, this.tmpCentresStreamingCoreset);
                for (int l = 0; l < massCentres[centre].dimension; l++) {
                    if (points[i].weight != 0.0)
                        massCentres[centre].coordinates[l] += points[i].coordinates[l];
                }
                numberOfPoints[centre] += points[i].weight;

            }

            //move centres
            for (i = 0; i < k; i++) {
                for (int l = 0; l < this.tmpCentresStreamingCoreset[i].dimension; l++) {
                    this.tmpCentresStreamingCoreset[i].coordinates[l] = massCentres[i].coordinates[l];
                    this.tmpCentresStreamingCoreset[i].weight = numberOfPoints[i];
                }
            }

            //calculate costs
            newCost = targetFunctionValue(k, n, this.tmpCentresStreamingCoreset, points);
            //System.out.println("old cost: "+cost+", new cost: "+newCost);
        } while (newCost < THRESHOLD * cost);


        //System.out.println("Centres: \n");
        int i = 0;
        for (i = 0; i < k; i++) {
            //System.out.print("(");
            int l = 0;
            for (l = 0; l < this.tmpCentresStreamingCoreset[i].dimension; l++) {
                //	System.out.print(this.tmpCentresStreamingCoreset[i].coordinates[l] / this.tmpCentresStreamingCoreset[i].weight);
                this.tmpCentresStreamingCoreset[i].coordinates[l] /= this.tmpCentresStreamingCoreset[i].weight;
                //	System.out.print(",");
            }
            //System.out.println(")");
        }
        //System.out.println("kMeans++ finished");
        //System.out.println(i+" "+newCost+" "+this.tmpCentresStreamingCoreset.length);*/
        return newCost;
    }