// File: /workspace/github_cpp_makefile_star2_O3/sebastienmeyer2[P]mst-clustering/src/kmeans.cpp
// Function: Cloud::init_plusplus()
void Cloud::init_plusplus()
{
    /*!
     * @brief Initializes the centers of this cloud using kmeans++
	 * which consists in drawing a distribution of points
     */

	// step of initialization for kmeans++
	int* chosenPoints = new int [this->k] ();
	int randomPoint = rand() % this->n;
	chosenPoints[0] = randomPoint;

	// loop 
	double* distances = new double [this->n] ();
	for (int i = 1; i < this->k; i ++){

		// we compute the nearest center for each data point
		double totalDist = 0.0;

		for (int j = 0; j < this->n; j ++){
			distances[j] = DBL_MAX;

			for (int l = 0; l < i; l ++){
				double dist = points[j].distance(&(points[chosenPoints[l]]));

				if (dist < distances[j]){
					distances[j] = dist;
				}

				totalDist += distances[j];
			}
		}

		for (int j = 0; j < this->n; j ++){
			distances[j] /= totalDist; 
			if (j > 0){
				distances[j] += distances[j-1]; // we create a cumulative sum
			}
		}

		// we find the next center from a uniform distribution
		double randomUnif = (double)rand() / RAND_MAX;

		for (int j = 0; j < this->n; j ++){
			if ( (j == 0 && distances[j] > randomUnif && randomUnif >= 0) \
					|| (j > 0 && distances[j] > randomUnif && randomUnif >= distances[j-1]) ){
				chosenPoints[i] = j;
			}
		}
	}

	// we just have to build our centers now!
	Point c;
	for (int i = 0; i < this->k; i ++){
		c.label = i;

		for (int j = 0; j < this->d; j ++){
			c.coords[j] = points[chosenPoints[i]].coords[j];
		}

		this->set_center(c, i);
	}		

	delete[] chosenPoints;
	chosenPoints = NULL;
	delete[] distances;
	distances = NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r15
movslq 0x8(%rdi), %rax
leaq (,%rax,4), %r14
testq %rax, %rax
movq $-0x1, %r13
cmovsq %r13, %r14
movq %r14, %rdi
callq 0x3030
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x3130
callq 0x30a0
movslq 0x4(%r15), %rbp
cltd
idivl %ebp
leaq (,%rbp,8), %r12
testq %rbp, %rbp
movq %rbx, (%rsp)
movl %edx, (%rbx)
cmovsq %r13, %r12
movq %r12, %rdi
callq 0x3030
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x3130
cmpl $0x2, 0x8(%r15)
jl 0xf28f
movl $0x1, %r12d
testl %ebp, %ebp
jle 0xf21f
xorps %xmm1, %xmm1
xorl %r13d, %r13d
movq %r14, %rbx
movabsq $0x7fefffffffffffff, %rax # imm = 0x7FEFFFFFFFFFFFFF
movq %rax, (%r14,%r13,8)
movq %r13, %rbp
shlq $0x4, %rbp
movsd 0x24ff(%rip), %xmm2     # 0x11688
xorl %r14d, %r14d
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, 0x10(%rsp)
movq 0x10(%r15), %rax
leaq (%rax,%rbp), %rdi
movq (%rsp), %rcx
movslq (%rcx,%r14,4), %rsi
shlq $0x4, %rsi
addq %rax, %rsi
callq 0x3b3a
movsd 0x8(%rsp), %xmm2
ucomisd %xmm0, %xmm2
jbe 0xf1ca
movsd %xmm0, (%rbx,%r13,8)
movapd %xmm0, %xmm2
movsd 0x10(%rsp), %xmm1
addsd %xmm2, %xmm1
incq %r14
cmpq %r14, %r12
jne 0xf18c
incq %r13
movslq 0x4(%r15), %rax
cmpq %rax, %r13
movq %rbx, %r14
jl 0xf169
testl %eax, %eax
jle 0xf21f
xorl %ecx, %ecx
movsd (%r14,%rcx,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rcx,8)
testq %rcx, %rcx
je 0xf217
addsd -0x8(%r14,%rcx,8), %xmm0
movsd %xmm0, (%r14,%rcx,8)
incq %rcx
cmpq %rcx, %rax
jne 0xf1f5
callq 0x30a0
xorpd %xmm2, %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x2749(%rip), %xmm0     # 0x11980
movslq 0x4(%r15), %rbp
testq %rbp, %rbp
jle 0xf27f
xorl %eax, %eax
testq %rax, %rax
je 0xf25e
movsd (%r14,%rax,8), %xmm1
ucomisd %xmm0, %xmm1
jbe 0xf277
ucomisd -0x8(%r14,%rax,8), %xmm0
jae 0xf26f
jmp 0xf277
ucomisd %xmm2, %xmm0
jb 0xf277
movsd (%r14), %xmm1
ucomisd %xmm0, %xmm1
jbe 0xf277
movq (%rsp), %rcx
movl %eax, (%rcx,%r12,4)
incq %rax
cmpq %rax, %rbp
jne 0xf242
incq %r12
movslq 0x8(%r15), %rax
cmpq %rax, %r12
jl 0xf15b
leaq 0x18(%rsp), %rdi
callq 0x3a20
movslq 0x8(%r15), %rax
testq %rax, %rax
jle 0xf317
movl (%r15), %ecx
movq 0x10(%r15), %rdx
movq 0x18(%rsp), %rsi
movq 0x18(%r15), %rdi
xorl %r9d, %r9d
movq %r9, %r8
testl %ecx, %ecx
jle 0xf309
movq (%rsp), %r9
movslq (%r9,%r8,4), %r9
shlq $0x4, %r9
movq (%rdx,%r9), %r9
xorl %r10d, %r10d
movsd (%r9,%r10,8), %xmm0
movsd %xmm0, (%rsi,%r10,8)
incq %r10
cmpq %r10, %rcx
jne 0xf2cf
testl %ecx, %ecx
jle 0xf309
movq %r8, %r9
shlq $0x4, %r9
movq (%rdi,%r9), %r9
xorl %r10d, %r10d
movsd (%rsi,%r10,8), %xmm0
movsd %xmm0, (%r9,%r10,8)
incq %r10
cmpq %r10, %rcx
jne 0xf2f5
leaq 0x1(%r8), %r9
cmpq %rax, %r9
jne 0xf2b5
movl %r8d, 0x20(%rsp)
movq (%rsp), %rdi
callq 0x3360
movq %r14, %rdi
callq 0x3360
leaq 0x18(%rsp), %rdi
callq 0x3a6e
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop