// File: 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
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movq %rsi, -0x200(%rbp)
movq %rdi, %rax
movq -0x200(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
movq %rax, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movss 0x900e(%rip), %xmm0     # 0xf06c
movss %xmm0, -0x20(%rbp)
xorl %eax, %eax
movl %eax, %esi
callq 0x7f00
movq %rax, %rdi
addq $0x8, %rdi
callq 0x4610
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %edx
subl $0x1, %edx
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x2, %ecx
callq 0x4c80
leaq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x7b50
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x7fa0
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x7fd0
testb $0x1, %al
jne 0x60c9
jmp 0x68d0
leaq -0x50(%rbp), %rdi
callq 0x8010
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x85e0
leaq -0x90(%rbp), %rdi
callq 0x85e0
leaq -0xa8(%rbp), %rdi
callq 0x85e0
movq -0x1f8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x7e00
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x7e30
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x7e60
testb $0x1, %al
jne 0x6148
jmp 0x61d7
leaq -0xb8(%rbp), %rdi
callq 0x7ea0
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x44d0
jmp 0x6165
leaq -0xe0(%rbp), %rdi
movslq -0x5c(%rbp), %rsi
callq 0x7d30
movq %rax, %rsi
leaq -0x78(%rbp), %rdi
callq 0x8600
jmp 0x6183
leaq -0xe8(%rbp), %rdi
callq 0x3540
leaq -0xb8(%rbp), %rdi
callq 0x7ee0
jmp 0x612c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
jmp 0x68ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x3540
jmp 0x68ad
leaq -0x78(%rbp), %rdi
movq %rdi, -0x208(%rbp)
callq 0x86b0
movq -0x208(%rbp), %rdi
movq %rax, -0x100(%rbp)
callq 0x86e0
movq %rax, -0x108(%rbp)
movq -0x100(%rbp), %rdi
movq -0x108(%rbp), %rsi
callq 0x8670
jmp 0x6216
movl $0x0, -0x10c(%rbp)
movl -0x10c(%rbp), %eax
movl %eax, -0x20c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x4610
movq %rax, %rcx
movl -0x20c(%rbp), %eax
cmpl %ecx, %eax
jge 0x62ef
cmpl $0x0, -0x10c(%rbp)
jne 0x6272
movslq -0x10c(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x7d30
movq %rax, %rsi
leaq -0x90(%rbp), %rdi
callq 0x8600
jmp 0x6270
jmp 0x62d9
movslq -0x10c(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x7d30
movss (%rax), %xmm0
movss %xmm0, -0x210(%rbp)
movl -0x10c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq -0x78(%rbp), %rdi
callq 0x7d30
movss -0x210(%rbp), %xmm0
ucomiss (%rax), %xmm0
jne 0x62b4
jp 0x62b4
jmp 0x62d7
movslq -0x10c(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x7d30
movq %rax, %rsi
leaq -0x90(%rbp), %rdi
callq 0x8600
jmp 0x62d5
jmp 0x62d7
jmp 0x62d9
jmp 0x62db
movl -0x10c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10c(%rbp)
jmp 0x6220
leaq -0x90(%rbp), %rdi
callq 0x4610
cmpq $0x1, %rax
jne 0x6327
xorl %eax, %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
callq 0x7d30
movq %rax, %rsi
leaq -0xa8(%rbp), %rdi
callq 0x8600
jmp 0x6322
jmp 0x63eb
movl $0x0, -0x110(%rbp)
movl -0x110(%rbp), %eax
movl %eax, -0x214(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x4610
movq %rax, %rcx
movl -0x214(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x63e9
movslq -0x110(%rbp), %rsi
leaq -0x90(%rbp), %rdi
movq %rdi, -0x220(%rbp)
callq 0x7d30
movq -0x220(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0x218(%rbp)
movl -0x110(%rbp), %eax
incl %eax
movslq %eax, %rsi
callq 0x7d30
movss -0x218(%rbp), %xmm0
movss (%rax), %xmm1
addss %xmm1, %xmm0
movss 0x8cbe(%rip), %xmm1     # 0xf070
mulss %xmm1, %xmm0
movss %xmm0, -0x114(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0x114(%rbp), %rsi
callq 0x8710
jmp 0x63d3
jmp 0x63d5
movl -0x110(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x110(%rbp)
jmp 0x6331
jmp 0x63eb
leaq -0xa8(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rdi
callq 0x86b0
movq %rax, -0x128(%rbp)
movq -0x120(%rbp), %rdi
callq 0x86e0
movq %rax, -0x130(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x8740
testb $0x1, %al
jne 0x643b
jmp 0x687e
leaq -0x128(%rbp), %rdi
callq 0x8780
movss (%rax), %xmm0
movss %xmm0, -0x134(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x28a0
leaq -0x168(%rbp), %rdi
callq 0x28a0
movq -0x1f8(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %rdi
callq 0x7e00
movq %rax, -0x178(%rbp)
movq -0x170(%rbp), %rdi
callq 0x7e30
movq %rax, -0x180(%rbp)
leaq -0x178(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x7e60
testb $0x1, %al
jne 0x64bb
jmp 0x658e
leaq -0x178(%rbp), %rdi
callq 0x7ea0
movq %rax, %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x44d0
jmp 0x64d8
leaq -0x1a0(%rbp), %rdi
movslq -0x5c(%rbp), %rsi
callq 0x85a0
movq %rax, -0x228(%rbp)
jmp 0x64f1
movq -0x228(%rbp), %rax
movss (%rax), %xmm1
movss -0x134(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jb 0x655a
leaq -0x150(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x7d90
jmp 0x651e
jmp 0x6571
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
jmp 0x6864
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x1a8(%rbp), %rdi
callq 0x3540
jmp 0x6864
leaq -0x168(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x7d90
jmp 0x656f
jmp 0x6571
leaq -0x1a8(%rbp), %rdi
callq 0x3540
leaq -0x178(%rbp), %rdi
callq 0x7ee0
jmp 0x649f
leaq -0x150(%rbp), %rdi
callq 0x3f80
cmpq $0x0, %rax
jne 0x65ad
xorps %xmm0, %xmm0
movss %xmm0, -0x1b0(%rbp)
jmp 0x6620
leaq -0x1d0(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x2a60
jmp 0x65c2
movq -0x1f0(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x6920
movss %xmm0, -0x22c(%rbp)
jmp 0x65df
movss -0x22c(%rbp), %xmm0
movss %xmm0, -0x1b0(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x2b50
jmp 0x6620
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x2b50
jmp 0x6864
leaq -0x168(%rbp), %rdi
callq 0x3f80
cmpq $0x0, %rax
jne 0x663f
xorps %xmm0, %xmm0
movss %xmm0, -0x1b4(%rbp)
jmp 0x66b2
leaq -0x1e8(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x2a60
jmp 0x6654
movq -0x1f0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x6920
movss %xmm0, -0x230(%rbp)
jmp 0x6671
movss -0x230(%rbp), %xmm0
movss %xmm0, -0x1b4(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x2b50
jmp 0x66b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x2b50
jmp 0x6864
leaq -0x150(%rbp), %rdi
callq 0x3f80
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x238(%rbp)
testq %rax, %rax
movss %xmm0, -0x234(%rbp)
js 0x66ff
movss -0x238(%rbp), %xmm0
movss %xmm0, -0x234(%rbp)
movss -0x234(%rbp), %xmm0
movss %xmm0, -0x248(%rbp)
movss -0x1b0(%rbp), %xmm0
movss %xmm0, -0x244(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x3f80
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x240(%rbp)
testq %rax, %rax
movss %xmm0, -0x23c(%rbp)
js 0x676c
movss -0x240(%rbp), %xmm0
movss %xmm0, -0x23c(%rbp)
movq -0x1f8(%rbp), %rdi
movss -0x244(%rbp), %xmm2
movss -0x248(%rbp), %xmm0
movss -0x23c(%rbp), %xmm1
movss -0x1b4(%rbp), %xmm3
mulss %xmm3, %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x254(%rbp)
callq 0x3f80
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x250(%rbp)
testq %rax, %rax
movss %xmm0, -0x24c(%rbp)
js 0x67ed
movss -0x250(%rbp), %xmm0
movss %xmm0, -0x24c(%rbp)
movss -0x254(%rbp), %xmm0
movss -0x24c(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x1ac(%rbp)
movss -0x1ac(%rbp), %xmm1
movss -0x20(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x683b
movss -0x134(%rbp), %xmm0
movss %xmm0, -0x1c(%rbp)
movss -0x1ac(%rbp), %xmm0
movss %xmm0, -0x20(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x24(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x2b50
leaq -0x150(%rbp), %rdi
callq 0x2b50
leaq -0x128(%rbp), %rdi
callq 0x87a0
jmp 0x641f
leaq -0x168(%rbp), %rdi
callq 0x2b50
leaq -0x150(%rbp), %rdi
callq 0x2b50
jmp 0x68ad
leaq -0xa8(%rbp), %rdi
callq 0x2ee0
leaq -0x90(%rbp), %rdi
callq 0x2ee0
leaq -0x78(%rbp), %rdi
callq 0x2ee0
leaq -0x50(%rbp), %rdi
callq 0x8030
jmp 0x60b3
leaq -0xa8(%rbp), %rdi
callq 0x2ee0
leaq -0x90(%rbp), %rdi
callq 0x2ee0
leaq -0x78(%rbp), %rdi
callq 0x2ee0
jmp 0x690b
leaq -0x8(%rbp), %rdi
leaq -0x24(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x87c0
jmp 0x68e3
leaq -0x40(%rbp), %rdi
callq 0x7c40
movq -0x8(%rbp), %rax
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x7c40
movq -0xf0(%rbp), %rdi
callq 0x2270