// File: nikosgalanis[P]Vectors-Similarity-Search-and-Clustering/programs/Clustering/../../algorithms/Clustering/clustering.h
// Function: Clustering<double>::initialization()
void initialization(void) {
		// chose a first index randomly
		std::random_device mch;
		std::default_random_engine generator(mch());
		std::uniform_int_distribution<int> distribution_int(0,n_points - 1);
		int index = distribution_int(generator);
		// this is our first centroid
		centroids.push_back(feature_vectors.at(index));
			// find the other centroids with the algorithm init++
			for (int t = 1; t < k; t++) {
				// define a distance vector
				vector<T> D(n_points, INT_MAX);
				// define a vector of the partial sums
				vector<T> P(n_points, 0);
				// for every point
				for (int i = 0; i < n_points; i++) {
					// check if it is centroid
					vector<T> curr = feature_vectors.at(i);
					if (std::find(centroids.begin(), centroids.end(), curr) == centroids.end()) {
						//compute D(i)
						for (int j = 0; j < t; j++) {
							T dist = metrics::ManhatanDistance(feature_vectors.at(i), centroids.at(j), space_dim);
							if (dist < D.at(i))
								D.at(i) = dist;
						}
					} else {
						// if it is a centroid, set its D value to 0
						D.at(i) = 0;
					}
					// compute the partial sums effectively
					if (i == 0)
						P.at(i) = pow(D.at(0), 2);
					else 
						P.at(i) = P.at(i - 1) + pow(D.at(i), 2);
				}
				//pick a uniformly distributed x
				std::uniform_real_distribution<double> distribution_real(0, P.at(n_points -1));
				double x = distribution_real(generator);

				// find its correct position
				int r_index = -1;
				int i = 0;
				for (i = 0; i < n_points; i++) {
					if (P.at(i) > (T)x) {
						r_index = i;
						break;
					}
				}
				// ensure that the point is not a csntroid
				while ((i - 1 > 0) && P.at(i) == P.at(i - 1)) {
					r_index--;
				}
				assert(r_index > 0);
				// now the r_index has a correct value, so its our new centroid
				centroids.push_back(feature_vectors.at(r_index));
			}
		}

// Assembly:
subq $0x15d8, %rsp           # imm = 0x15D8
movq %rdi, 0x15d0(%rsp)
movq 0x15d0(%rsp), %rax
movq %rax, 0x120(%rsp)
leaq 0x248(%rsp), %rdi
movq %rdi, 0x128(%rsp)
callq 0xaec0
movq 0x128(%rsp), %rdi
callq 0xaf60
movl %eax, 0x134(%rsp)
jmp 0x143fa
movl 0x134(%rsp), %eax
movl %eax, %eax
movl %eax, %esi
leaq 0x240(%rsp), %rdi
callq 0xaf70
jmp 0x14414
movq 0x120(%rsp), %rax
movl 0x4(%rax), %edx
decl %edx
leaq 0x22c(%rsp), %rdi
xorl %esi, %esi
callq 0xfc80
jmp 0x14432
leaq 0x22c(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0xfcc0
movl %eax, 0x11c(%rsp)
jmp 0x14450
movq 0x120(%rsp), %rdi
movl 0x11c(%rsp), %eax
movl %eax, 0x228(%rsp)
movq %rdi, %rax
addq $0x30, %rax
movq %rax, 0x108(%rsp)
addq $0x48, %rdi
movslq 0x228(%rsp), %rsi
callq 0x6f30
movq %rax, 0x110(%rsp)
jmp 0x14490
movq 0x110(%rsp), %rsi
movq 0x108(%rsp), %rdi
callq 0x34e0
jmp 0x144a7
movl $0x1, 0x224(%rsp)
movq 0x120(%rsp), %rcx
movl 0x224(%rsp), %eax
cmpl (%rcx), %eax
jge 0x14ce8
movq 0x120(%rsp), %rax
movslq 0x4(%rax), %rax
movq %rax, 0xf8(%rsp)
movabsq $0x41dfffffffc00000, %rax # imm = 0x41DFFFFFFFC00000
movq %rax, 0x200(%rsp)
leaq 0x1ff(%rsp), %rdi
movq %rdi, 0x100(%rsp)
callq 0x3730
movq 0xf8(%rsp), %rsi
movq 0x100(%rsp), %rcx
leaq 0x208(%rsp), %rdi
leaq 0x200(%rsp), %rdx
callq 0xadc0
jmp 0x1452b
leaq 0x1ff(%rsp), %rdi
callq 0x4730
movq 0x120(%rsp), %rax
movslq 0x4(%rax), %rax
movq %rax, 0xe8(%rsp)
movq $0x0, 0x1d8(%rsp)
leaq 0x1d7(%rsp), %rdi
movq %rdi, 0xf0(%rsp)
callq 0x3730
movq 0xe8(%rsp), %rsi
movq 0xf0(%rsp), %rcx
leaq 0x1e0(%rsp), %rdi
leaq 0x1d8(%rsp), %rdx
callq 0xadc0
jmp 0x14594
leaq 0x1d7(%rsp), %rdi
callq 0x4730
movl $0x0, 0x1d0(%rsp)
movq 0x120(%rsp), %rcx
movl 0x1d0(%rsp), %eax
cmpl 0x4(%rcx), %eax
jge 0x14aa4
movq 0x120(%rsp), %rdi
addq $0x48, %rdi
movslq 0x1d0(%rsp), %rsi
callq 0x6f30
movq %rax, 0xe0(%rsp)
jmp 0x145e7
movq 0xe0(%rsp), %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x45a0
jmp 0x145fe
movq 0x120(%rsp), %rdi
addq $0x30, %rdi
movq %rdi, 0xd0(%rsp)
callq 0x4cd0
movq 0xd0(%rsp), %rdi
movq %rax, 0x1a8(%rsp)
callq 0x4540
movq %rax, 0x1a0(%rsp)
movq 0x1a8(%rsp), %rdi
movq 0x1a0(%rsp), %rsi
leaq 0x1b8(%rsp), %rdx
callq 0x15a90
movq %rax, 0xd8(%rsp)
jmp 0x1465b
movq 0x120(%rsp), %rdi
movq 0xd8(%rsp), %rax
movq %rax, 0x1b0(%rsp)
addq $0x30, %rdi
callq 0x4540
movq %rax, 0x198(%rsp)
leaq 0x1b0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x15a50
testb $0x1, %al
jne 0x146a2
jmp 0x14921
movl $0x0, 0x194(%rsp)
movl 0x194(%rsp), %eax
cmpl 0x224(%rsp), %eax
jge 0x1491f
movq 0x120(%rsp), %rdi
addq $0x48, %rdi
movslq 0x1d0(%rsp), %rsi
callq 0x6f30
movq %rax, 0xc8(%rsp)
jmp 0x146e4
movq 0xc8(%rsp), %rsi
leaq 0x170(%rsp), %rdi
callq 0x45a0
jmp 0x146fb
movq 0x120(%rsp), %rdi
addq $0x30, %rdi
movslq 0x194(%rsp), %rsi
callq 0x6f30
movq %rax, 0xc0(%rsp)
jmp 0x1471e
movq 0xc0(%rsp), %rsi
leaq 0x158(%rsp), %rdi
callq 0x45a0
jmp 0x14735
movq 0x120(%rsp), %rax
movl 0x8(%rax), %edx
leaq 0x170(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x15af0
movsd %xmm0, 0xb8(%rsp)
jmp 0x14760
leaq 0x158(%rsp), %rdi
callq 0x3550
leaq 0x170(%rsp), %rdi
callq 0x3550
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x188(%rsp)
movsd 0x188(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movslq 0x1d0(%rsp), %rsi
leaq 0x208(%rsp), %rdi
callq 0xb000
movq %rax, 0xb0(%rsp)
jmp 0x147bd
movsd 0xa8(%rsp), %xmm1
movq 0xb0(%rsp), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x14907
movsd 0x188(%rsp), %xmm0
movsd %xmm0, 0x98(%rsp)
movslq 0x1d0(%rsp), %rsi
leaq 0x208(%rsp), %rdi
callq 0xb000
movq %rax, 0xa0(%rsp)
jmp 0x1480d
movq 0xa0(%rsp), %rax
movsd 0x98(%rsp), %xmm0
movsd %xmm0, (%rax)
jmp 0x14907
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x14cfd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x1ff(%rsp), %rdi
callq 0x4730
jmp 0x14cfd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x1d7(%rsp), %rdi
callq 0x4730
jmp 0x14cd9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x14ccc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x14a92
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x148f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x3550
leaq 0x170(%rsp), %rdi
callq 0x3550
jmp 0x14a92
jmp 0x14909
movl 0x194(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x194(%rsp)
jmp 0x146ad
jmp 0x1494f
movslq 0x1d0(%rsp), %rsi
leaq 0x208(%rsp), %rdi
callq 0xb000
movq %rax, 0x90(%rsp)
jmp 0x14940
movq 0x90(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
cmpl $0x0, 0x1d0(%rsp)
jne 0x149c8
xorl %eax, %eax
movl %eax, %esi
leaq 0x208(%rsp), %rdi
callq 0xb000
movq %rax, 0x88(%rsp)
jmp 0x14974
movq 0x88(%rsp), %rax
movsd (%rax), %xmm0
movl $0x2, %edi
callq 0x15b90
movsd %xmm0, 0x80(%rsp)
jmp 0x14995
movslq 0x1d0(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x78(%rsp)
jmp 0x149b1
movq 0x78(%rsp), %rax
movsd 0x80(%rsp), %xmm0
movsd %xmm0, (%rax)
jmp 0x14a6f
movl 0x1d0(%rsp), %eax
decl %eax
movslq %eax, %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x70(%rsp)
jmp 0x149e8
movq 0x70(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x60(%rsp)
movslq 0x1d0(%rsp), %rsi
leaq 0x208(%rsp), %rdi
callq 0xb000
movq %rax, 0x68(%rsp)
jmp 0x14a13
movq 0x68(%rsp), %rax
movsd (%rax), %xmm0
movl $0x2, %edi
callq 0x15b90
movsd %xmm0, 0x58(%rsp)
jmp 0x14a2e
movsd 0x58(%rsp), %xmm1
movsd 0x60(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
movslq 0x1d0(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x50(%rsp)
jmp 0x14a60
movq 0x50(%rsp), %rax
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x1b8(%rsp), %rdi
callq 0x3550
movl 0x1d0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d0(%rsp)
jmp 0x145ac
leaq 0x1b8(%rsp), %rdi
callq 0x3550
jmp 0x14ccc
movq 0x120(%rsp), %rax
movl 0x4(%rax), %eax
decl %eax
movslq %eax, %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x40(%rsp)
jmp 0x14ac8
movq 0x40(%rsp), %rax
movsd (%rax), %xmm1
leaq 0x148(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0xafa0
jmp 0x14ae3
leaq 0x148(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0xafd0
movsd %xmm0, 0x38(%rsp)
jmp 0x14b00
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x140(%rsp)
movl $0xffffffff, 0x13c(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x138(%rsp)
movl $0x0, 0x138(%rsp)
movq 0x120(%rsp), %rcx
movl 0x138(%rsp), %eax
cmpl 0x4(%rcx), %eax
jge 0x14b99
movslq 0x138(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x30(%rsp)
jmp 0x14b60
movq 0x30(%rsp), %rax
movsd (%rax), %xmm0
ucomisd 0x140(%rsp), %xmm0
jbe 0x14b84
movl 0x138(%rsp), %eax
movl %eax, 0x13c(%rsp)
jmp 0x14b99
jmp 0x14b86
movl 0x138(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x138(%rsp)
jmp 0x14b30
jmp 0x14b9b
movl 0x138(%rsp), %ecx
subl $0x1, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, 0x2f(%rsp)
jle 0x14c16
movslq 0x138(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x20(%rsp)
jmp 0x14bcc
movq 0x20(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movl 0x138(%rsp), %eax
decl %eax
movslq %eax, %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xb000
movq %rax, 0x18(%rsp)
jmp 0x14bfb
movsd 0x10(%rsp), %xmm0
movq 0x18(%rsp), %rax
ucomisd (%rax), %xmm0
sete %al
setnp %cl
andb %cl, %al
movb %al, 0x2f(%rsp)
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0x14c20
jmp 0x14c36
movl 0x13c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x13c(%rsp)
jmp 0x14b9b
cmpl $0x0, 0x13c(%rsp)
jle 0x14c42
jmp 0x14c61
leaq 0x6a71(%rip), %rdi      # 0x1b6ba
leaq 0x6732(%rip), %rsi      # 0x1b382
movl $0x10e, %edx            # imm = 0x10E
leaq 0x6a6a(%rip), %rcx      # 0x1b6c6
callq 0x2170
movq 0x120(%rsp), %rdi
movq %rdi, %rax
addq $0x30, %rax
movq %rax, (%rsp)
addq $0x48, %rdi
movslq 0x13c(%rsp), %rsi
callq 0x6f30
movq %rax, 0x8(%rsp)
jmp 0x14c8c
movq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x34e0
jmp 0x14c9c
leaq 0x1e0(%rsp), %rdi
callq 0x3550
leaq 0x208(%rsp), %rdi
callq 0x3550
movl 0x224(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x224(%rsp)
jmp 0x144b2
leaq 0x1e0(%rsp), %rdi
callq 0x3550
leaq 0x208(%rsp), %rdi
callq 0x3550
jmp 0x14cfd
leaq 0x248(%rsp), %rdi
callq 0xb0d0
addq $0x15d8, %rsp           # imm = 0x15D8
retq
leaq 0x248(%rsp), %rdi
callq 0xb0d0
movq 0x238(%rsp), %rdi
callq 0x2400
nopw (%rax,%rax)