// File: ADAPTLab[P]MuDBSCAN/partition.cpp
// Function: get_median(std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>&, int*, int, ompi_communicator_t*&)
double get_median(vector< vector< double> >& objects, int* num_points, int d, MPI_Comm& new_comm)
{	
	double median;

	// vector<double> data;
	vectorc* data = (vectorc*)malloc(sizeof(struct vectorc));
	// assert(data != NULL);

	VECTOR_INIT(data, DOUBLE);
	addHelper[0] = 0; 
	VECTOR_RESIZE(data, *num_points, (void*)addHelper);
	// data.resize(*num_points, 0);

	for (int k=0; k < *num_points; k++)
		data->doubleItems[k] = (objects)[k][d];

	median = findKMedian(data, VECTOR_TOTAL(data)/2);

	VECTOR_FREE(data);
	free(data);

	// data.clear();

	int proc_count;
	MPI_Comm_size(new_comm, &proc_count);

	vectorc* all_medians = (vectorc*)malloc(sizeof(struct vectorc));
	// assert(all_medians!=NULL);

	VECTOR_INIT(all_medians, DOUBLE);
	VECTOR_RESIZE(all_medians, proc_count, (void*)addHelper);

	// vector<double> all_medians;
	// all_medians.resize(proc_count);

	MPI_Allgather(&median, 1, MPI_DOUBLE, &all_medians->doubleItems[0], 1, MPI_DOUBLE, new_comm);	

	median = findKMedian(all_medians, VECTOR_TOTAL(all_medians)/2); 

	VECTOR_FREE(all_medians);
	free(all_medians);

	// all_medians.clear();	

	return median;	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x30, %edi
callq 0x9910
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movl $0x2, %esi
callq 0xa170
leaq 0x1ebe6(%rip), %rax     # 0x38800
movq (%rax), %rax
movl $0x0, (%rax)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0x1ebcc(%rip), %rax     # 0x38800
movq (%rax), %rdx
callq 0xa2d0
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x19c87
movq -0x8(%rbp), %rdi
movslq -0x34(%rbp), %rsi
callq 0xf850
movq %rax, %rdi
movslq -0x14(%rbp), %rsi
callq 0xf870
movsd (%rax), %xmm0
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x34(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x19c43
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rdi
callq 0xa2b0
movq -0x50(%rbp), %rdi
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
callq 0x19ab0
movsd %xmm0, -0x28(%rbp)
movq -0x30(%rbp), %rdi
callq 0xa7f0
movq -0x30(%rbp), %rdi
callq 0x97c0
movq -0x20(%rbp), %rax
movq (%rax), %rdi
leaq -0x38(%rbp), %rsi
callq 0x9790
movl $0x30, %edi
callq 0x9910
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0xa170
movq -0x40(%rbp), %rdi
movl -0x38(%rbp), %esi
leaq 0x1eb04(%rip), %rax     # 0x38800
movq (%rax), %rdx
callq 0xa2d0
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x20(%rbp), %rax
movq (%rax), %rax
leaq -0x28(%rbp), %rdi
movl $0x1, %r8d
movq 0x1e294(%rip), %r9      # 0x37fb8
movl %r8d, %esi
movq %r9, %rdx
movq %rax, (%rsp)
callq 0x9070
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
callq 0xa2b0
movq -0x48(%rbp), %rdi
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
callq 0x19ab0
movsd %xmm0, -0x28(%rbp)
movq -0x40(%rbp), %rdi
callq 0xa7f0
movq -0x40(%rbp), %rdi
callq 0x97c0
movsd -0x28(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)