// File: jingdao[P]PointCloudApp/descriptor.cpp
// Function: Descriptor::kMeansClustering(std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>*)
void Descriptor::kMeansClustering(std::vector<std::vector<int>> *indices) {
	int k = 10;
//	int k = (int) sqrt(numPoints / 2);
	//initialize
	for (int i=0;i<k;i++) {
		std::vector<int> v;
		indices->push_back(v);
	}
	int* associations = new int[numPoints]();
	float* means = new float[k * dimension];
	int iterations = 0;

	//choose initial means
	for (int i=0;i<k;i++) {
		int index = rand() % numPoints;
		memcpy(means + i * dimension, data + index * dimension, dimension * sizeof(float));
	}

	bool update = true;
	while (update) {
		update = false;
		for (int i=0;i<k;i++)
			(*indices)[i].clear();

		//assignment step
		for (int i=0;i<numPoints;i++) {
			//find nearest mean
			int minIndex;
			float minDistance;
			for (int j=0;j<k;j++) {
				float distance = 0;
				for (int l=0;l<dimension;l++)
					distance += (data[i*dimension+l] - means[j*dimension+l]) * (data[i*dimension+l] - means[j*dimension+l]);
				if (j==0 || distance < minDistance) {
					minIndex = j;
					minDistance = distance;
				}
			}
			if (minIndex != associations[i])
				update = true;
			associations[i] = minIndex;
			(*indices)[minIndex].push_back(i);
		}

		//update step
		for (int i=0;i<k;i++) {
			for (int j=0;j<dimension;j++) {
				means[i * dimension + j] = 0;
				size_t clusterSize = (*indices)[i].size();
				for (size_t l=0;l<clusterSize;l++) {
					means[i * dimension + j] += data[(*indices)[i][l] * dimension + j];
				}
				means[i * dimension + j] /= clusterSize;
			}
		}
		iterations++;
	}

//	printf("K-Means: Found %lu clusters (%d iterations)\n",indices->size(),iterations);

	delete[] associations;
	delete[] means;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0xa, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x10684
leaq -0x30(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x3130
movq -0xa8(%rbp), %rsi
movq -0x10(%rbp), %rdi
callq 0xaef0
jmp 0x10656
leaq -0x30(%rbp), %rdi
callq 0x31d0
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1062c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x31d0
jmp 0x10b0e
movq -0xa0(%rbp), %rax
movslq (%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0xb8(%rbp)
callq 0x2040
movq -0xb8(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0xb0(%rbp)
xorl %esi, %esi
callq 0x2100
movq -0xb0(%rbp), %rax
movq -0xa0(%rbp), %rcx
movq %rax, -0x48(%rbp)
movl -0x14(%rbp), %eax
imull 0x4(%rcx), %eax
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x1077f
callq 0x2080
movq -0xa0(%rbp), %rcx
cltd
idivl (%rcx)
movq -0xa0(%rbp), %rax
movl %edx, -0x5c(%rbp)
movq -0x50(%rbp), %rdi
movl -0x58(%rbp), %ecx
imull 0x4(%rax), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rdi
movq 0x8(%rax), %rsi
movl -0x5c(%rbp), %ecx
imull 0x4(%rax), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rsi
movslq 0x4(%rax), %rdx
shlq $0x2, %rdx
callq 0x2180
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x1071c
movb $0x1, -0x5d(%rbp)
testb $0x1, -0x5d(%rbp)
je 0x10acb
movb $0x0, -0x5d(%rbp)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x107c0
movq -0x10(%rbp), %rdi
movslq -0x64(%rbp), %rsi
callq 0xaa00
movq %rax, %rdi
callq 0xaed0
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x10798
movl $0x0, -0x68(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x68(%rbp), %eax
cmpl (%rcx), %eax
jge 0x10907
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x108be
xorps %xmm0, %xmm0
movss %xmm0, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x7c(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x10889
movq -0xa0(%rbp), %rdx
movq 0x8(%rdx), %rax
movl -0x68(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x7c(%rbp), %ecx
movslq %ecx, %rcx
movss (%rax,%rcx,4), %xmm0
movq -0x50(%rbp), %rax
movl -0x74(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x7c(%rbp), %ecx
movslq %ecx, %rcx
subss (%rax,%rcx,4), %xmm0
movq 0x8(%rdx), %rax
movl -0x68(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x7c(%rbp), %ecx
movslq %ecx, %rcx
movss (%rax,%rcx,4), %xmm2
movq -0x50(%rbp), %rax
movl -0x74(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x7c(%rbp), %ecx
movslq %ecx, %rcx
subss (%rax,%rcx,4), %xmm2
movss -0x78(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x78(%rbp)
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x107fb
cmpl $0x0, -0x74(%rbp)
je 0x1089e
movss -0x78(%rbp), %xmm1
movss -0x70(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x108ae
movl -0x74(%rbp), %eax
movl %eax, -0x6c(%rbp)
movss -0x78(%rbp), %xmm0
movss %xmm0, -0x70(%rbp)
jmp 0x108b0
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x107e0
movl -0x6c(%rbp), %eax
movq -0x48(%rbp), %rcx
movslq -0x68(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
je 0x108d2
movb $0x1, -0x5d(%rbp)
movl -0x6c(%rbp), %edx
movq -0x48(%rbp), %rax
movslq -0x68(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x10(%rbp), %rdi
movslq -0x6c(%rbp), %rsi
callq 0xaa00
movq %rax, %rdi
leaq -0x68(%rbp), %rsi
callq 0xae30
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x107c7
movl $0x0, -0x80(%rbp)
movl -0x80(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x10abd
movl $0x0, -0x84(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x84(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x10aad
movq -0xa0(%rbp), %rdx
movq -0x50(%rbp), %rax
movl -0x80(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x84(%rbp), %ecx
movslq %ecx, %rcx
xorps %xmm0, %xmm0
movss %xmm0, (%rax,%rcx,4)
movq -0x10(%rbp), %rdi
movslq -0x80(%rbp), %rsi
callq 0xaa00
movq %rax, %rdi
callq 0xaca0
movq %rax, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
movq -0x98(%rbp), %rax
cmpq -0x90(%rbp), %rax
jae 0x10a20
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x80(%rbp), %rsi
callq 0xaa00
movq %rax, %rdi
movq -0x98(%rbp), %rsi
callq 0xacc0
movq -0xa0(%rbp), %rdx
movq %rax, %rcx
movq -0xc0(%rbp), %rax
movl (%rcx), %ecx
imull 0x4(%rdx), %ecx
addl -0x84(%rbp), %ecx
movslq %ecx, %rcx
movss (%rax,%rcx,4), %xmm0
movq -0x50(%rbp), %rax
movl -0x80(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x84(%rbp), %ecx
movslq %ecx, %rcx
addss (%rax,%rcx,4), %xmm0
movss %xmm0, (%rax,%rcx,4)
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x10984
movq -0x90(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0xc8(%rbp)
testq %rax, %rax
movss %xmm0, -0xc4(%rbp)
js 0x10a68
movss -0xc8(%rbp), %xmm0
movss %xmm0, -0xc4(%rbp)
movq -0xa0(%rbp), %rdx
movss -0xc4(%rbp), %xmm1
movq -0x50(%rbp), %rax
movl -0x80(%rbp), %ecx
imull 0x4(%rdx), %ecx
addl -0x84(%rbp), %ecx
movslq %ecx, %rcx
movss (%rax,%rcx,4), %xmm0
divss %xmm1, %xmm0
movss %xmm0, (%rax,%rcx,4)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x10924
jmp 0x10aaf
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x1090e
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x10783
movq -0x48(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpq $0x0, %rax
je 0x10ae8
movq -0xd0(%rbp), %rdi
callq 0x2250
movq -0x50(%rbp), %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, %rax
je 0x10b05
movq -0xd8(%rbp), %rdi
callq 0x2250
addq $0xe0, %rsp
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x2380
nopw (%rax,%rax)