// File: /workspace/github_cpp_makefile_star2_O3/big-data-lab-team[P]OrpailleCC/./src/mondrian_coarse.hpp
// Function: CoarseMondrianForest<double, funct, KappaMetrics<2, false>, 4, 2, 6000>::extend_node(int, int, double const*, int, int, double, double*, double, double)
void extend_node(int const node_id, int const tree_id, feature_type const* features, int const label, int const parent_id, double const parent_tau, double* probabilities, double const E, double const sum){
		Node& node = nodes()[node_id];
		int new_parent_id, new_sibling_id;
		bool current_node_on_left = true;
		Utils::turn_array_into_probability(probabilities, feature_count, sum);
		//sample features with probability proportional to e_lower[i] + e_upper[i]
		int const dimension = Utils::pick_from_distribution<func>(probabilities, feature_count);

		//Select the bound to choose the split from
		double lower_value, upper_value;
		if(features[dimension] > node.bound_upper[dimension]){
			lower_value = node.bound_upper[dimension];
			upper_value = features[dimension];
		}
		else if(features[dimension] < node.bound_lower[dimension]){
			lower_value = features[dimension];
			upper_value = node.bound_lower[dimension];
		}

		//sample the split between [lower_value, upper_value]
		double const split_value = func::rand_uniform()*(upper_value - lower_value) + lower_value;
		//insert new node above the current one
		new_parent_id = available_node();
		nodes()[new_parent_id].split_dimension = dimension;
		nodes()[new_parent_id].split_value = split_value;
		nodes()[new_parent_id].tau = parent_tau + E;
		//insert new leaf, sibbling of the current one
		new_sibling_id = available_node();
		node_available -= 2;

		//Update the box of the new parent
		for(int i = 0; i < feature_count; ++i){
			nodes()[new_parent_id].bound_lower[i] = features[i] < node.bound_lower[i] ? features[i] : node.bound_lower[i];
			nodes()[new_parent_id].bound_upper[i] = features[i] > node.bound_upper[i] ? features[i] : node.bound_upper[i];
		}
		//NOTE Creates counters for the label of the new parent
		//for(int i = 0; i < label_count; ++i)
		//nodes[new_parent_id].counters[i] = node.counters[i];
		//nodes[new_parent_id].counters[label] += 1;

		//Creates counters for the label of the new sibling
		for(int i = 0; i < label_count; ++i)
			nodes()[new_sibling_id].counters[i] = 0;
		//No need to increase the counter for the current label because we will call sample_block soon on new_sibling

		sample_block(new_sibling_id, features, label);
		if(features[dimension] == upper_value){ //right
			current_node_on_left = false;
		}
		else{
			current_node_on_left = true;
		}

		//Make the connections between the new nodes
		nodes()[new_parent_id].parent = node.parent;
		if(!node.has_parent() && node_id == tree_bases()[tree_id].root)//We introduce a parent to the root
			tree_bases()[tree_id].root = new_parent_id;
		else{
			Node& parent = nodes()[node.parent];
			if(parent.child_left == node_id)
				parent.child_left = new_parent_id;
			else
				parent.child_right = new_parent_id;
		}


		node.parent = new_parent_id;

		nodes()[new_sibling_id].parent = new_parent_id;
		if(!current_node_on_left){ //right
			nodes()[new_parent_id].child_right = new_sibling_id;
			nodes()[new_parent_id].child_left = node_id;
		}
		else{ //left
			nodes()[new_parent_id].child_left = new_sibling_id;
			nodes()[new_parent_id].child_right = node_id;
		}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movsd %xmm1, 0x30(%rsp)
movsd %xmm0, 0x28(%rsp)
movl %r8d, 0x8(%rsp)
movq %rcx, %r15
movl %edx, (%rsp)
movq %rdi, %r14
movq 0x70(%rsp), %rax
movslq %esi, %rcx
shlq $0x7, %rcx
xorpd %xmm0, %xmm0
ucomisd %xmm2, %xmm0
jbe 0x3ee6
xorl %edx, %edx
xorpd %xmm2, %xmm2
addsd (%rax,%rdx,8), %xmm2
incq %rdx
cmpq $0x4, %rdx
jne 0x3ed8
leaq 0x44(%r14), %rbp
leaq (%r14,%rcx), %r12
addq $0x44, %r12
movsd (%rax), %xmm0
divsd %xmm2, %xmm0
movsd %xmm0, (%rax)
movl $0x1, %ecx
movsd (%rax,%rcx,8), %xmm1
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
cmpq $0x4, %rcx
jne 0x3f03
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
movsd (%rax,%rcx,8), %xmm1
ucomisd %xmm0, %xmm1
jae 0x3f3d
incq %rcx
cmpq $0x4, %rcx
jne 0x3f24
movl $0x4, %ecx
cmpl $0x4, %ecx
movl $0x4, %r13d
cmovll %ecx, %r13d
movslq %r13d, %rax
movsd (%r15,%rax,8), %xmm0
movsd 0x30(%r12,%rax,8), %xmm1
ucomisd %xmm1, %xmm0
movl %esi, 0xc(%rsp)
movq %rax, 0x18(%rsp)
jbe 0x3f73
movapd %xmm0, %xmm2
movapd %xmm1, %xmm0
jmp 0x3f7a
movsd 0x10(%r12,%rax,8), %xmm2
movsd %xmm2, 0x20(%rsp)
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
xorpd %xmm2, %xmm2
mulsd %xmm1, %xmm2
addsd %xmm0, %xmm2
movsd %xmm2, 0x10(%rsp)
movq %r14, %rdi
callq 0x26e4
movl %eax, 0x4(%rsp)
movslq %eax, %rbx
shlq $0x7, %rbx
movl %r13d, (%rbp,%rbx)
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x8(%rbp,%rbx)
movsd 0x28(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x60(%rbp,%rbx)
movq %r14, %rdi
callq 0x26e4
addl $-0x2, 0x17d8(%r14)
leaq (%rbx,%r14), %rcx
addq $0x74, %rcx
xorl %edx, %edx
movsd (%r15,%rdx,8), %xmm0
minsd 0x10(%r12,%rdx,8), %xmm0
movsd %xmm0, -0x20(%rcx,%rdx,8)
movsd (%r15,%rdx,8), %xmm0
maxsd 0x30(%r12,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rdx
cmpq $0x4, %rdx
jne 0x3fea
movslq %eax, %rcx
shlq $0x7, %rcx
movq $0x0, 0xac(%r14,%rcx)
leaq (%rcx,%rbp), %rdx
xorl %esi, %esi
movl 0xc(%rsp), %r8d
movsd (%r15,%rsi,8), %xmm0
movsd %xmm0, 0x10(%rdx,%rsi,8)
movsd %xmm0, 0x30(%rdx,%rsi,8)
incq %rsi
cmpq $0x4, %rsi
jne 0x4036
movslq 0x8(%rsp), %rsi
incl 0x68(%rdx,%rsi,4)
movsd 0x17e8(%r14), %xmm0
movsd %xmm0, 0x60(%rdx)
movq 0x18(%rsp), %rdx
movsd (%r15,%rdx,8), %xmm0
movslq 0x58(%r12), %rdx
movl %edx, 0x58(%rbp,%rbx)
cmpq $-0x1, %rdx
movsd 0x20(%rsp), %xmm1
jne 0x40b5
movslq 0x17dc(%r14), %rsi
imulq $-0x38, %rsi, %rsi
addq %r14, %rsi
movslq (%rsp), %rdi
imulq $0x38, %rdi, %rdi
cmpl %r8d, 0x17bc(%rdi,%rsi)
jne 0x40b5
leaq (%rdi,%rsi), %rdx
addq $0x17bc, %rdx           # imm = 0x17BC
jmp 0x40cd
shlq $0x7, %rdx
leaq (%rdx,%rbp), %rsi
addq $0x50, %rsi
cmpl %r8d, (%rsi)
leaq 0x54(%rbp,%rdx), %rdx
cmoveq %rsi, %rdx
movl 0x4(%rsp), %esi
movl %esi, (%rdx)
ucomisd %xmm1, %xmm0
movl %esi, 0x58(%r12)
movl %esi, 0x58(%rbp,%rcx)
movl %r8d, %ecx
cmovnel %eax, %ecx
cmovpl %eax, %ecx
cmovnel %r8d, %eax
cmovpl %r8d, %eax
movl %ecx, 0x50(%rbp,%rbx)
movl %eax, 0x54(%rbp,%rbx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq