// File: /workspace/github_cpp_makefile_star2_O2/8igMac[P]random-forest/src/decision_tree.cpp
// Function: decision_tree::selectAttr(std::vector<data_inst, std::allocator<data_inst>>)
pair<int,float> decision_tree::selectAttr(vector<data_inst> sampleSet)
{
	float bestThreshold;
	float lowestImpurity = 2;
	int attrSelected;

	// attribute bagging
	int num_attr = sampleSet.at(0).attr.size();
	vector<int> attrList(rdmSelectSet(0,num_attr-1,ATTRBAGGING));

	
	// select attribut, and threshold
	for (auto attr_idx: attrList)
	{
		vector<float> valueList;
		vector<float> prunedValuList;
		vector<float> thresholdList;

		// get value list
		for (auto item: sampleSet)
			valueList.push_back(item.attr[attr_idx]);

		// sort value list
		sort(valueList.begin(), valueList.end());

		// prun value list
		for (int i=0; i<(int)valueList.size(); i++)
		{
			if (i==0)
				prunedValuList.push_back(valueList[i]);
			else
			{
				if (valueList[i] != valueList[i-1])
					prunedValuList.push_back(valueList[i]);
			}
		}

		// get threshold list
		if (prunedValuList.size() == 1)
			thresholdList.push_back(prunedValuList[0]);
		else
		{
			for (int i=0; i < ((int)prunedValuList.size()-1); i++)
				thresholdList.push_back((prunedValuList[i]+prunedValuList[i+1])/2);
		}

		// get gest threshold
		for (auto threshold: thresholdList)
		{
			// split samples into two groups
			vector<data_inst> leftSample, rightSample;
			for (auto sample: sampleSet)
			{
				if (sample.attr.at(attr_idx) <= threshold)
					leftSample.push_back(sample);
				else
					rightSample.push_back(sample);
			}

			// calculate gini impurity of two group
			float imp, leftImpurity, rightImpurity;
			if (leftSample.size() == 0)
				leftImpurity = 0;
			else
				leftImpurity = impurity(leftSample);

			if (rightSample.size() == 0)
				rightImpurity = 0;
			else
				rightImpurity = impurity(rightSample);
			
			imp = (((float)leftSample.size() * leftImpurity) +
								 	((float)rightSample.size() * rightImpurity) ) / (float) sampleSet.size();

			// updates lowest impurity and best threshold
			if (imp < lowestImpurity)
			{
				bestThreshold = threshold;
				lowestImpurity = imp;
				attrSelected = attr_idx;
			}
		}
	}

	//here
	return pair<int, float>(attrSelected, bestThreshold);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rsi, %rdi
movq %rsi, 0x18(%rsp)
xorl %esi, %esi
callq 0x4732
movq 0x10(%rax), %rdx
subq 0x8(%rax), %rdx
shrq $0x2, %rdx
decl %edx
leaq 0x130(%rsp), %rbx
pushq $0x2
popq %rcx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2cdc
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq %rcx, 0xb8(%rsp)
movss 0x2954(%rip), %xmm0     # 0x6088
movss %xmm0, 0x4(%rsp)
leaq 0xe0(%rsp), %r15
leaq 0x80(%rsp), %r13
leaq 0xd8(%rsp), %r14
cmpq 0xb8(%rsp), %rax
je 0x3b39
movq %rax, 0xc0(%rsp)
movslq (%rax), %rbp
andq $0x0, 0x70(%rsp)
andq $0x0, 0x50(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
andq $0x0, 0xb0(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0xa0(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rbx
movq 0x8(%rax), %r12
cmpq %r12, %rbx
je 0x37de
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2c00
leaq (,%rbp,4), %rsi
addq 0xe0(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x4970
leaq 0xe0(%rsp), %rdi
callq 0x2878
addq $0x28, %rbx
jmp 0x37a1
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x5339
xorl %ebx, %ebx
xorl %r12d, %r12d
movq 0x60(%rsp), %rsi
movq 0x68(%rsp), %rax
subq %rsi, %rax
shrq $0x2, %rax
cltq
cmpq %rax, %r12
jge 0x3833
testq %rbx, %rbx
je 0x3820
movss (%rsi,%rbx), %xmm0
ucomiss -0x4(%rsi,%rbx), %xmm0
jne 0x381d
jnp 0x382a
addq %rbx, %rsi
leaq 0x40(%rsp), %rdi
callq 0x4970
incq %r12
addq $0x4, %rbx
jmp 0x37f2
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rax
movq %rax, %rcx
subq %rsi, %rcx
cmpq $0x4, %rcx
jne 0x3adb
leaq 0xa0(%rsp), %rdi
callq 0x4970
movq 0xa0(%rsp), %rax
movq 0xa8(%rsp), %rcx
movq %rcx, 0xc8(%rsp)
cmpq 0xc8(%rsp), %rax
je 0x3aa9
movq %rax, 0xd0(%rsp)
movss (%rax), %xmm0
movss %xmm0, 0x8(%rsp)
andq $0x0, 0x30(%rsp)
andq $0x0, 0x90(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x80(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rbx
movq 0x8(%rax), %r12
cmpq %r12, %rbx
je 0x3901
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2c00
movq %r15, %rdi
movq %rbp, %rsi
callq 0x494e
movss 0x8(%rsp), %xmm0
ucomiss (%rax), %xmm0
movq %r13, %rdi
jb 0x38eb
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x4706
movq %r15, %rdi
callq 0x2878
addq $0x28, %rbx
jmp 0x38bd
movq 0x28(%rsp), %rax
xorps %xmm0, %xmm0
movss %xmm0, 0x10(%rsp)
movss %xmm0, 0x14(%rsp)
cmpq 0x20(%rsp), %rax
je 0x394c
leaq 0x118(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x276e
leaq 0x118(%rsp), %rbx
movq %rbx, %rsi
callq 0x3c08
movss %xmm0, 0x14(%rsp)
movq %rbx, %rdi
callq 0x27c8
movq 0x88(%rsp), %rsi
movq %rsi, %rcx
cmpq 0x80(%rsp), %rsi
je 0x399f
leaq 0x100(%rsp), %rdi
movq %r13, %rsi
callq 0x276e
leaq 0x100(%rsp), %rbx
movq %rbx, %rsi
callq 0x3c08
movss %xmm0, 0x10(%rsp)
movq %rbx, %rdi
callq 0x27c8
movq 0x80(%rsp), %rsi
movq 0x88(%rsp), %rcx
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
cqto
pushq $0x28
popq %rdi
idivq %rdi
testq %rax, %rax
js 0x39bd
cvtsi2ss %rax, %xmm3
jmp 0x39d2
movq %rax, %rdx
shrq %rdx
andl $0x1, %eax
orq %rdx, %rax
cvtsi2ss %rax, %xmm3
addss %xmm3, %xmm3
subq %rsi, %rcx
movq %rcx, %rax
cqto
pushq $0x28
popq %rcx
idivq %rcx
testq %rax, %rax
js 0x39ec
cvtsi2ss %rax, %xmm0
jmp 0x3a01
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
movq 0x18(%rsp), %rcx
movq 0x8(%rcx), %rax
subq (%rcx), %rax
cqto
pushq $0x28
popq %rcx
idivq %rcx
testq %rax, %rax
js 0x3a21
cvtsi2ss %rax, %xmm1
jmp 0x3a36
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
movl (%rsp), %eax
movss 0x10(%rsp), %xmm2
mulss %xmm0, %xmm2
mulss 0x14(%rsp), %xmm3
addss %xmm2, %xmm3
divss %xmm1, %xmm3
movss 0x4(%rsp), %xmm0
ucomiss %xmm3, %xmm0
cmoval %ebp, %eax
movl %eax, (%rsp)
ja 0x3a6e
movss 0xc(%rsp), %xmm0
movss %xmm0, 0x8(%rsp)
minss 0x4(%rsp), %xmm3
movss %xmm3, 0x4(%rsp)
movq %r13, %rdi
callq 0x27c8
leaq 0x20(%rsp), %rdi
callq 0x27c8
movq 0xd0(%rsp), %rax
addq $0x4, %rax
movss 0x8(%rsp), %xmm0
movss %xmm0, 0xc(%rsp)
jmp 0x3872
leaq 0xa0(%rsp), %rdi
callq 0x2878
leaq 0x40(%rsp), %rdi
callq 0x2878
leaq 0x60(%rsp), %rdi
callq 0x2878
movq 0xc0(%rsp), %rax
addq $0x4, %rax
jmp 0x3752
xorl %ebx, %ebx
subq %rsi, %rax
shlq $0x1e, %rax
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
addq %rcx, %rax
sarq $0x20, %rax
cmpq %rax, %rbx
jge 0x385a
movss (%rsi,%rbx,4), %xmm0
addss 0x4(%rsi,%rbx,4), %xmm0
mulss 0x257b(%rip), %xmm0     # 0x608c
movss %xmm0, 0xd8(%rsp)
leaq 0xa0(%rsp), %rdi
movq %r14, %rsi
callq 0x5794
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rax
incq %rbx
jmp 0x3add
leaq 0x130(%rsp), %rdi
callq 0x4b42
movd 0xc(%rsp), %xmm0
movd %xmm0, %ecx
shlq $0x20, %rcx
movl (%rsp), %eax
orq %rcx, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3b91
jmp 0x3b91
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
jmp 0x3b88
movq %rax, %rbx
leaq 0x118(%rsp), %rdi
callq 0x27c8
jmp 0x3bba
jmp 0x3b91
movq %rax, %rbx
jmp 0x3bd1
movq %rax, %rbx
leaq 0xe0(%rsp), %rdi
callq 0x2878
jmp 0x3bd1
jmp 0x3baa
movq %rax, %rbx
jmp 0x3bba
movq %rax, %rbx
movq %r15, %rdi
callq 0x2878
leaq 0x80(%rsp), %rdi
callq 0x27c8
leaq 0x20(%rsp), %rdi
callq 0x27c8
leaq 0xa0(%rsp), %rdi
callq 0x2878
leaq 0x40(%rsp), %rdi
callq 0x2878
leaq 0x60(%rsp), %rdi
callq 0x2878
leaq 0x130(%rsp), %rdi
callq 0x4b42
movq %rbx, %rdi
callq 0x2230
nop