// File: 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
movq %rsp, %rbp
subq $0xe0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movl %r9d, -0x20(%rbp)
movsd %xmm0, -0x28(%rbp)
movsd %xmm1, -0x30(%rbp)
movsd %xmm2, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x80(%rbp)
callq 0x1b00
movslq -0xc(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movb $0x1, -0x49(%rbp)
movq 0x10(%rbp), %rdi
movsd -0x38(%rbp), %xmm0
movl $0x4, %esi
callq 0x7480
movq 0x10(%rbp), %rdi
movl $0x4, %esi
callq 0x7540
movl %eax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x40(%rbp), %rax
movslq -0x50(%rbp), %rcx
ucomisd 0x30(%rax,%rcx,8), %xmm0
jbe 0x769c
movq -0x40(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd 0x30(%rax,%rcx,8), %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x60(%rbp)
jmp 0x76e4
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x40(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd 0x10(%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x76e2
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x40(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd 0x10(%rax,%rcx,8), %xmm0
movsd %xmm0, -0x60(%rbp)
jmp 0x76e4
callq 0x35a0
movq -0x80(%rbp), %rdi
movsd -0x60(%rbp), %xmm2
subsd -0x58(%rbp), %xmm2
movsd -0x58(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
callq 0x3860
movq -0x80(%rbp), %rdi
movl %eax, -0x44(%rbp)
movl -0x50(%rbp), %eax
movl %eax, -0x94(%rbp)
callq 0x1b00
movl -0x94(%rbp), %ecx
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
callq 0x1b00
movsd -0x90(%rbp), %xmm0
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movsd -0x28(%rbp), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
callq 0x1b00
movsd -0x88(%rbp), %xmm0
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movsd %xmm0, 0x60(%rax)
callq 0x3860
movl %eax, %ecx
movq -0x80(%rbp), %rax
movl %ecx, -0x48(%rbp)
movl 0x17d8(%rax), %ecx
subl $0x2, %ecx
movl %ecx, 0x17d8(%rax)
movl $0x0, -0x6c(%rbp)
cmpl $0x4, -0x6c(%rbp)
jge 0x78db
movq -0x18(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd 0x10(%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x7801
movq -0x18(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0xa0(%rbp)
jmp 0x7817
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd 0x10(%rax,%rcx,8), %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rdi
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
callq 0x1b00
movsd -0xa8(%rbp), %xmm0
movslq -0x44(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movslq -0x6c(%rbp), %rcx
movsd %xmm0, 0x10(%rax,%rcx,8)
movq -0x18(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
ucomisd 0x30(%rax,%rcx,8), %xmm0
jbe 0x7881
movq -0x18(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0xb0(%rbp)
jmp 0x7897
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movsd 0x30(%rax,%rcx,8), %xmm0
movsd %xmm0, -0xb0(%rbp)
movq -0x80(%rbp), %rdi
movsd -0xb0(%rbp), %xmm0
movsd %xmm0, -0xb8(%rbp)
callq 0x1b00
movsd -0xb8(%rbp), %xmm0
movslq -0x44(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movslq -0x6c(%rbp), %rcx
movsd %xmm0, 0x30(%rax,%rcx,8)
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x77bf
movl $0x0, -0x70(%rbp)
cmpl $0x2, -0x70(%rbp)
jge 0x7913
movq -0x80(%rbp), %rdi
callq 0x1b00
movslq -0x48(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movslq -0x70(%rbp), %rcx
movl $0x0, 0x68(%rax,%rcx,4)
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x78e2
movq -0x80(%rbp), %rdi
movl -0x48(%rbp), %esi
movq -0x18(%rbp), %rdx
movl -0x1c(%rbp), %ecx
callq 0x3900
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd -0x60(%rbp), %xmm0
jne 0x7942
jp 0x7942
movb $0x0, -0x49(%rbp)
jmp 0x7946
movb $0x1, -0x49(%rbp)
movq -0x80(%rbp), %rdi
movq -0x40(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0xbc(%rbp)
callq 0x1b00
movl -0xbc(%rbp), %ecx
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x58(%rax)
movq -0x40(%rbp), %rdi
callq 0x75b0
testb $0x1, %al
jne 0x79d0
movq -0x80(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, -0xc0(%rbp)
callq 0x1a50
movq %rax, %rcx
movl -0xc0(%rbp), %eax
movslq -0x10(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x8(%rcx), %eax
jne 0x79d0
movq -0x80(%rbp), %rdi
movl -0x44(%rbp), %eax
movl %eax, -0xc4(%rbp)
callq 0x1a50
movl -0xc4(%rbp), %ecx
movslq -0x10(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
jmp 0x7a10
movq -0x80(%rbp), %rdi
callq 0x1b00
movq -0x40(%rbp), %rcx
movslq 0x58(%rcx), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movl 0x50(%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x7a04
movl -0x44(%rbp), %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x50(%rax)
jmp 0x7a0e
movl -0x44(%rbp), %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x54(%rax)
jmp 0x7a10
movq -0x80(%rbp), %rdi
movl -0x44(%rbp), %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x58(%rax)
movl -0x44(%rbp), %eax
movl %eax, -0xc8(%rbp)
callq 0x1b00
movl -0xc8(%rbp), %ecx
movslq -0x48(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x58(%rax)
testb $0x1, -0x49(%rbp)
jne 0x7a94
movq -0x80(%rbp), %rdi
movl -0x48(%rbp), %eax
movl %eax, -0xd0(%rbp)
callq 0x1b00
movl -0xd0(%rbp), %ecx
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x54(%rax)
movl -0xc(%rbp), %eax
movl %eax, -0xcc(%rbp)
callq 0x1b00
movl -0xcc(%rbp), %ecx
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x50(%rax)
jmp 0x7ae0
movq -0x80(%rbp), %rdi
movl -0x48(%rbp), %eax
movl %eax, -0xd8(%rbp)
callq 0x1b00
movl -0xd8(%rbp), %ecx
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x50(%rax)
movl -0xc(%rbp), %eax
movl %eax, -0xd4(%rbp)
callq 0x1b00
movl -0xd4(%rbp), %ecx
movslq -0x44(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rax
movl %ecx, 0x54(%rax)
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)