// File: isaacbrodsky[P]K-means-plus-plus/k-means-multi.cpp
// Function: Cluster_set::Initialize_plus_plus_process(unsigned int, unsigned int, int, std::vector<float, std::allocator<float>>&, std::vector<bool, std::allocator<bool>> const&)
float Cluster_set::Initialize_plus_plus_process(unsigned uIndex, unsigned uLength, int iSelectedPoints, vector<float>& vfDistance, const vector<bool>& vbSkipPoints) {

	unsigned uLastIndex = uIndex + uLength;
	int iAttribute_index;
	int iK_index;
	float fSum_of_squares;
	float fDifference;
	float fTotalDistance = 0;

	// Compute distance to nearest cluster for all data instances.
	for (; uIndex < uLastIndex; uIndex++) {
		// Skip if already selected as a starting point
		if (!vbSkipPoints[uIndex]) {
			// Compute distance to nearest mean
			for (iK_index = 0; iK_index < iSelectedPoints; iK_index++) {
				fSum_of_squares = 0;

				for (iAttribute_index = 0; iAttribute_index < iAttribute_ct; iAttribute_index++) {
					fDifference = (vclInput_data[uIndex].vfAttribute[iAttribute_index] - vvfMeans[iK_index][iAttribute_index]);
					fSum_of_squares += (fDifference * fDifference);
				} // for

				// If this is the first evaluated distance, use it.
				// Otherwise only use the distance if it is better
				// than the previous best distance.
				if (iK_index == 0 || fSum_of_squares < vfDistance[uIndex]) {
					vfDistance[uIndex] = fSum_of_squares;
				}
			}

			// Sum the distance of all points to the closest
			// starting points as each one is calculated.
			fTotalDistance += vfDistance[uIndex];
		}
	}

	return fTotalDistance;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq %r8, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movl -0xc(%rbp), %eax
addl -0x10(%rbp), %eax
movl %eax, -0x2c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x40(%rbp)
movl -0xc(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x6b1d
movq -0x28(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0xa670
testb $0x1, %al
jne 0x6b0d
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x6af1
xorps %xmm0, %xmm0
movss %xmm0, -0x38(%rbp)
movl $0x0, -0x30(%rbp)
movq -0x48(%rbp), %rcx
movl -0x30(%rbp), %eax
cmpl 0x9c(%rcx), %eax
jge 0x6a94
movq -0x48(%rbp), %rdi
addq $0x80, %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0xa5f0
movq %rax, %rdi
movslq -0x30(%rbp), %rsi
callq 0xa3c0
movq -0x48(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0x4c(%rbp)
movslq -0x34(%rbp), %rsi
callq 0xa4e0
movq %rax, %rdi
movslq -0x30(%rbp), %rsi
callq 0xa3c0
movss -0x4c(%rbp), %xmm0
subss (%rax), %xmm0
movss %xmm0, -0x3c(%rbp)
movss -0x3c(%rbp), %xmm0
movss -0x3c(%rbp), %xmm2
movss -0x38(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x38(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x6a0a
cmpl $0x0, -0x34(%rbp)
je 0x6ac0
movss -0x38(%rbp), %xmm0
movss %xmm0, -0x50(%rbp)
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0xa3c0
movss -0x50(%rbp), %xmm1
movss (%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x6ae1
movss -0x38(%rbp), %xmm0
movss %xmm0, -0x54(%rbp)
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0xa3c0
movss -0x54(%rbp), %xmm0
movss %xmm0, (%rax)
jmp 0x6ae3
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x69ef
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0xa3c0
movss (%rax), %xmm0
addss -0x40(%rbp), %xmm0
movss %xmm0, -0x40(%rbp)
jmp 0x6b0f
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x69c6
movss -0x40(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)