// File: auton1[P]viterbi/viterbi.cpp
// Function: inner_loop_viterbi(std::vector<double, std::allocator<double>> const&, double, double, std::vector<std::vector<bool, std::allocator<bool>>, std::allocator<std::vector<bool, std::allocator<bool>>>> const&, double, double, int, int, int, std::vector<int, std::allocator<int>> const&, bool, std::vector<std::vector<unsigned short, std::allocator<unsigned short>>, std::allocator<std::vector<unsigned short, std::allocator<unsigned short>>>>&, std::vector<double, std::allocator<double>>&)
void inner_loop_viterbi(const vector<double> &v, double p_rec, double p_no_rec,
		const vector<vector<bool> > &haps, double em_match, double em_mismatch,
		int i, int start, int end, const vector<int> &v_idx_to_hap_idx,
		bool allele,
		vector<vector<unsigned short> > &ptr, vector<double> &vb)
{
	vector<double> va(v.size());
	vector<double>::iterator it;

	for (int j=start; j < end; j++)
	{
		transform(v.begin(), v.end(), va.begin(), bind2nd(std::plus<double>(), p_rec));
		va[j] = v[j] + p_no_rec;
		it = max_element(va.begin(), va.end());
		ptr[i-1][j] = distance(va.begin(), it);

		if (haps[ v_idx_to_hap_idx[j] ][i] == allele)
		{	// Match
			vb[j] = em_match + *it;
		}
		else
		{	// Mismatch
			vb[j] = em_mismatch + *it;
		}
	}
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq 0x180(%rsp), %rax
movq 0x178(%rsp), %rax
movb 0x170(%rsp), %al
movq %rdi, 0x160(%rsp)
movsd %xmm0, 0x158(%rsp)
movsd %xmm1, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
movsd %xmm2, 0x140(%rsp)
movsd %xmm3, 0x138(%rsp)
movl %edx, 0x134(%rsp)
movl %ecx, 0x130(%rsp)
movl %r8d, 0x12c(%rsp)
movq %r9, 0x120(%rsp)
andb $0x1, %al
movb %al, 0x11f(%rsp)
movq 0x160(%rsp), %rdi
callq 0xe890
movq %rax, 0x68(%rsp)
leaq 0xff(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0xedd0
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
leaq 0x100(%rsp), %rdi
callq 0xede0
jmp 0x83d6
leaq 0xff(%rsp), %rdi
callq 0xee60
leaq 0xe0(%rsp), %rdi
callq 0xee70
movl 0x130(%rsp), %eax
movl %eax, 0xdc(%rsp)
movl 0xdc(%rsp), %eax
cmpl 0x12c(%rsp), %eax
jge 0x8737
movq 0x160(%rsp), %rdi
callq 0xef20
movq %rax, 0xd0(%rsp)
movq 0x160(%rsp), %rdi
callq 0xef50
movq %rax, 0xc8(%rsp)
leaq 0x100(%rsp), %rdi
callq 0xef80
movq %rax, 0xc0(%rsp)
leaq 0xaf(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0xefb0
movsd %xmm0, 0x60(%rsp)
jmp 0x846e
movsd 0x60(%rsp), %xmm0
movsd %xmm0, 0xb8(%rsp)
movq 0xd0(%rsp), %rdi
movq 0xc8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
movsd 0xb8(%rsp), %xmm0
callq 0xee90
movq %rax, 0x58(%rsp)
jmp 0x84aa
movq 0x58(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x160(%rsp), %rdi
movslq 0xdc(%rsp), %rsi
callq 0xeff0
movsd (%rax), %xmm0
movsd 0x150(%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
movslq 0xdc(%rsp), %rsi
leaq 0x100(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0xe870
movsd 0x40(%rsp), %xmm0
movq 0x48(%rsp), %rdi
movsd %xmm0, (%rax)
callq 0xef80
movq 0x48(%rsp), %rdi
movq %rax, 0x90(%rsp)
callq 0xf060
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0xf010
movq %rax, 0x50(%rsp)
jmp 0x8547
movq 0x50(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0xe0(%rsp)
leaq 0x100(%rsp), %rdi
callq 0xef80
movq %rax, 0x80(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0xf090
movq %rax, 0x38(%rsp)
jmp 0x859f
movq 0x38(%rsp), %rax
movw %ax, 0x26(%rsp)
movq 0x178(%rsp), %rdi
movl 0x134(%rsp), %eax
decl %eax
movslq %eax, %rsi
callq 0xf0d0
movq %rax, %rdi
movslq 0xdc(%rsp), %rsi
callq 0xf0f0
movw 0x26(%rsp), %cx
movw %cx, (%rax)
movq 0x148(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x120(%rsp), %rdi
movslq 0xdc(%rsp), %rsi
callq 0xf130
movq 0x28(%rsp), %rdi
movslq (%rax), %rsi
callq 0xf110
movq %rax, %rdi
movslq 0x134(%rsp), %rsi
callq 0xf150
movb %al, 0x37(%rsp)
jmp 0x861f
movb 0x37(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movb 0x11f(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x86d6
movsd 0x140(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0xf1a0
movsd 0x10(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x180(%rsp), %rdi
movslq 0xdc(%rsp), %rsi
callq 0xe870
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
jmp 0x871f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xff(%rsp), %rdi
callq 0xee60
jmp 0x874c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x100(%rsp), %rdi
callq 0xed10
jmp 0x874c
movsd 0x138(%rsp), %xmm0
movsd %xmm0, (%rsp)
leaq 0xe0(%rsp), %rdi
callq 0xf1a0
movsd (%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x180(%rsp), %rdi
movslq 0xdc(%rsp), %rsi
callq 0xe870
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rax)
jmp 0x8721
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x83fe
leaq 0x100(%rsp), %rdi
callq 0xed10
addq $0x168, %rsp            # imm = 0x168
retq
movq 0xf0(%rsp), %rdi
callq 0x69e0
nopl (%rax)