// File: /workspace/github_cpp_makefile_star2_O1/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, %rbx
cmovsq %rbx, %r14
movq %r14, %rdi
callq 0x3030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x3130
callq 0x30a0
movslq 0x4(%r15), %rcx
cltd
idivl %ecx
leaq (,%rcx,8), %r12
testq %rcx, %rcx
movq %r13, 0x8(%rsp)
movl %edx, (%r13)
cmovsq %rbx, %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 0xee15
movl $0x1, %r12d
movl 0x4(%r15), %eax
xorpd %xmm1, %xmm1
testl %eax, %eax
jle 0xed72
xorl %ebp, %ebp
movabsq $0x7fefffffffffffff, %rax # imm = 0x7FEFFFFFFFFFFFFF
movq %rax, (%r14,%rbp,8)
movq %rbp, %r13
shlq $0x4, %r13
xorl %ebx, %ebx
movsd %xmm1, 0x10(%rsp)
movq 0x10(%r15), %rax
leaq (%rax,%r13), %rdi
movq 0x8(%rsp), %rcx
movslq (%rcx,%rbx,4), %rsi
shlq $0x4, %rsi
addq %rax, %rsi
callq 0x3b3a
movsd (%r14,%rbp,8), %xmm1
ucomisd %xmm0, %xmm1
jbe 0xed52
movsd %xmm0, (%r14,%rbp,8)
movsd 0x10(%rsp), %xmm1
addsd (%r14,%rbp,8), %xmm1
incq %rbx
cmpq %rbx, %r12
jne 0xed1d
incq %rbp
movslq 0x4(%r15), %rax
cmpq %rax, %rbp
jl 0xed06
testl %eax, %eax
jle 0xeda4
movl %eax, %eax
xorl %ecx, %ecx
movsd (%r14,%rcx,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rcx,8)
testq %rcx, %rcx
je 0xed9c
addsd -0x8(%r14,%rcx,8), %xmm0
movsd %xmm0, (%r14,%rcx,8)
incq %rcx
cmpq %rcx, %rax
jne 0xed7a
callq 0x30a0
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x2b48(%rip), %xmm0     # 0x11900
movslq 0x4(%r15), %rax
testq %rax, %rax
xorpd %xmm2, %xmm2
jle 0xee05
xorl %ecx, %ecx
testq %rcx, %rcx
je 0xede3
movsd (%r14,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
jbe 0xedfd
ucomisd -0x8(%r14,%rcx,8), %xmm0
jae 0xedf4
jmp 0xedfd
ucomisd %xmm2, %xmm0
jb 0xedfd
movsd (%r14), %xmm1
ucomisd %xmm0, %xmm1
jbe 0xedfd
movq 0x8(%rsp), %rdx
movl %ecx, (%rdx,%r12,4)
incq %rcx
cmpq %rcx, %rax
jne 0xedc7
incq %r12
movslq 0x8(%r15), %rax
cmpq %rax, %r12
jl 0xecf8
leaq 0x18(%rsp), %rdi
callq 0x3a20
movslq 0x8(%r15), %rax
testq %rax, %rax
jle 0xee9e
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 0xee6a
movq 0x8(%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 0xee56
testl %ecx, %ecx
jle 0xee90
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 0xee7c
leaq 0x1(%r8), %r9
cmpq %rax, %r9
jne 0xee3b
movl %r8d, 0x20(%rsp)
movq 0x8(%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