// File: 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
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movslq 0x8(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x98(%rbp)
callq 0xa030
movq -0x98(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0x90(%rbp)
xorl %esi, %esi
callq 0xa3a0
movq -0x90(%rbp), %rax
movq %rax, -0x10(%rbp)
callq 0xa1c0
movq -0x88(%rbp), %rcx
cltd
idivl 0x4(%rcx)
movq -0x88(%rbp), %rax
movl %edx, -0x14(%rbp)
movl -0x14(%rbp), %edx
movq -0x10(%rbp), %rcx
movl %edx, (%rcx)
movslq 0x4(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x80(%rbp)
callq 0xa030
movq -0x80(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0x78(%rbp)
xorl %esi, %esi
callq 0xa3a0
movq -0x78(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x1, -0x24(%rbp)
movq -0x88(%rbp), %rcx
movl -0x24(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x338ba
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x88(%rbp), %rcx
movl -0x34(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x33799
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
movsd 0x40ad(%rip), %xmm0     # 0x37798
movsd %xmm0, (%rax,%rcx,8)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x33789
movq -0x88(%rbp), %rax
movq 0x10(%rax), %rdi
movslq -0x34(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rdi
movq 0x10(%rax), %rsi
movq -0x10(%rbp), %rax
movslq -0x38(%rbp), %rcx
movslq (%rax,%rcx,4), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xb660
movsd %xmm0, -0x40(%rbp)
movsd -0x40(%rbp), %xmm1
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x33764
movsd -0x40(%rbp), %xmm0
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x336f7
jmp 0x3378b
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x336c8
movl $0x0, -0x44(%rbp)
movq -0x88(%rbp), %rcx
movl -0x44(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x33801
movsd -0x30(%rbp), %xmm1
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
cmpl $0x0, -0x44(%rbp)
jle 0x337f4
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x337f6
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x337a0
callq 0xa1c0
cvtsi2sd %eax, %xmm0
movsd 0x4276(%rip), %xmm1     # 0x37a88
divsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movq -0x88(%rbp), %rcx
movl -0x54(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x338aa
cmpl $0x0, -0x54(%rbp)
jne 0x33859
movq -0x20(%rbp), %rax
movslq -0x54(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd -0x50(%rbp), %xmm0
jbe 0x33859
movsd -0x50(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jae 0x3388c
cmpl $0x0, -0x54(%rbp)
jle 0x3389a
movq -0x20(%rbp), %rax
movslq -0x54(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd -0x50(%rbp), %xmm0
jbe 0x3389a
movsd -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rax
movl -0x54(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
ucomisd (%rax,%rcx,8), %xmm0
jb 0x3389a
movl -0x54(%rbp), %edx
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x3389c
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x33822
jmp 0x338ac
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x336a6
leaq -0x68(%rbp), %rdi
callq 0xb520
movl $0x0, -0x6c(%rbp)
movq -0x88(%rbp), %rcx
movl -0x6c(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x33957
movl -0x6c(%rbp), %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x70(%rbp)
movq -0x88(%rbp), %rcx
movl -0x70(%rbp), %eax
cmpl (%rcx), %eax
jge 0x33936
movq -0x88(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
movslq -0x6c(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq -0x70(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x68(%rbp), %rax
movslq -0x70(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x338e6
movq -0x88(%rbp), %rdi
movl -0x6c(%rbp), %edx
leaq -0x68(%rbp), %rsi
callq 0x32a30
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x338ca
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, %rax
je 0x33974
movq -0xa0(%rbp), %rdi
callq 0xaa00
movq $0x0, -0x10(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x33999
movq -0xa8(%rbp), %rdi
callq 0xaa00
movq $0x0, -0x20(%rbp)
leaq -0x68(%rbp), %rdi
callq 0xb590
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)