// File: sebastienmeyer2[P]mst-clustering/src/kmeans.cpp
// Function: Cloud::init_forgy()
void Cloud::init_forgy()
{
    /*!
     * @brief Initializes the centers of this cloud using Forgy method,
	 * that is it samples the centers uniformly from the data points
     */

	// we will pick points from our data 
	int* availablePoints = new int [this->n] ();
	for (int i = 0; i < this->n; i ++){
		availablePoints[i] = 1;
	}

	// we must know what we've chosen so far
	int* chosenPoints = new int [this->k] ();
	int leftCenters = this->k;

	while (leftCenters > 0){
		int randomPoint = rand() % this->n;

		if (availablePoints[randomPoint] > 0){
			availablePoints[randomPoint] = 0;
			chosenPoints[this->k - leftCenters] = randomPoint;
			leftCenters -= 1;
		}
	}

	// 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[] availablePoints;
	availablePoints = NULL;
	delete[] chosenPoints;
	chosenPoints = NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
movslq 0x4(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x50(%rbp)
callq 0xa030
movq -0x50(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0x48(%rbp)
xorl %esi, %esi
callq 0xa3a0
movq -0x48(%rbp), %rax
movq %rax, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x58(%rbp), %rcx
movl -0x14(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x33137
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movl $0x1, (%rax,%rcx,4)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x33111
movq -0x58(%rbp), %rax
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, -0x68(%rbp)
callq 0xa030
movq -0x68(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0x60(%rbp)
xorl %esi, %esi
callq 0xa3a0
movq -0x60(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0x20(%rbp)
movl 0x8(%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jle 0x331dd
callq 0xa1c0
movq -0x58(%rbp), %rcx
cltd
idivl 0x4(%rcx)
movl %edx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jle 0x331db
movq -0x58(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rdx
movl $0x0, (%rax,%rdx,4)
movl -0x28(%rbp), %edx
movq -0x20(%rbp), %rax
movl 0x8(%rcx), %ecx
subl -0x24(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x24(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x33188
leaq -0x38(%rbp), %rdi
callq 0xb520
movl $0x0, -0x3c(%rbp)
movq -0x58(%rbp), %rcx
movl -0x3c(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x3326b
movl -0x3c(%rbp), %eax
movl %eax, -0x30(%rbp)
movl $0x0, -0x40(%rbp)
movq -0x58(%rbp), %rcx
movl -0x40(%rbp), %eax
cmpl (%rcx), %eax
jge 0x33250
movq -0x58(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x20(%rbp), %rcx
movslq -0x3c(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq -0x40(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x38(%rbp), %rax
movslq -0x40(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x33206
movq -0x58(%rbp), %rdi
movl -0x3c(%rbp), %edx
leaq -0x38(%rbp), %rsi
callq 0x32a30
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x331ed
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, %rax
je 0x33282
movq -0x70(%rbp), %rdi
callq 0xaa00
movq $0x0, -0x10(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, %rax
je 0x332a1
movq -0x78(%rbp), %rdi
callq 0xaa00
movq $0x0, -0x20(%rbp)
leaq -0x38(%rbp), %rdi
callq 0xb590
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax,%rax)