// File: CastellanZhang[P]lambdaFM/./src/FTRL/ftrl_model.h
// Function: ftrl_model::predict(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, double>>>&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, ftrl_model_unit*, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, ftrl_model_unit*>>>&, std::vector<double, std::allocator<double>>&)
double ftrl_model::predict(unordered_map<string, double>& x, unordered_map<string, ftrl_model_unit*>& theta, vector<double>& sum)
{
    double result = 0;
    for(unordered_map<string, double>::iterator iter = x.begin(); iter != x.end(); ++iter)
    {
        const string& index = iter->first;
        result += theta[index]->wi * iter->second;
    }
    double sum_sqr, d;
    for(int f = 0; f < factor_num; ++f)
    {
        sum[f] = sum_sqr = 0.0;
        for(unordered_map<string, double>::iterator iter = x.begin(); iter != x.end(); ++iter)
        {
            const string& index = iter->first;
            d = theta[index]->vi[f] * iter->second;
            sum[f] += d;
            sum_sqr += d * d;
        }
        result += 0.5 * (sum[f] * sum[f] - sum_sqr);
    }
    return result;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq %rcx, 0x78(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x20(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
movq 0x88(%rsp), %rdi
callq 0x5680
movq %rax, 0x68(%rsp)
movq 0x88(%rsp), %rdi
callq 0x56d0
movq %rax, 0x60(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x56b0
testb $0x1, %al
jne 0x3bd3
jmp 0x3c39
leaq 0x68(%rsp), %rdi
callq 0x5700
movq %rax, 0x58(%rsp)
movq 0x80(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x5720
movq (%rax), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x5700
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rax), %xmm2
movsd 0x70(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x70(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x5750
jmp 0x3bac
movl $0x0, 0x44(%rsp)
movq 0x20(%rsp), %rcx
movl 0x44(%rsp), %eax
cmpl 0x38(%rcx), %eax
jge 0x3dde
xorps %xmm0, %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x78(%rsp), %rdi
movslq 0x44(%rsp), %rsi
callq 0x5780
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq 0x88(%rsp), %rdi
callq 0x5680
movq %rax, 0x38(%rsp)
movq 0x88(%rsp), %rdi
callq 0x56d0
movq %rax, 0x30(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x56b0
testb $0x1, %al
jne 0x3cae
jmp 0x3d5d
leaq 0x38(%rsp), %rdi
callq 0x5700
movq %rax, 0x28(%rsp)
movq 0x80(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x5720
movq (%rax), %rdi
addq $0x18, %rdi
movslq 0x44(%rsp), %rsi
callq 0x5780
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x5700
movsd 0x8(%rsp), %xmm0
mulsd 0x20(%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x78(%rsp), %rdi
movslq 0x44(%rsp), %rsi
callq 0x5780
movsd 0x10(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0x48(%rsp), %xmm0
movsd 0x48(%rsp), %xmm2
movsd 0x50(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x5750
jmp 0x3c84
movq 0x78(%rsp), %rdi
movslq 0x44(%rsp), %rsi
callq 0x5780
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq 0x78(%rsp), %rdi
movslq 0x44(%rsp), %rsi
callq 0x5780
movsd (%rsp), %xmm0
movsd (%rax), %xmm2
movsd 0x50(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x70(%rsp), %xmm1
movsd 0xe248(%rip), %xmm2     # 0x12008
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x70(%rsp)
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x3c41
movsd 0x70(%rsp), %xmm0
addq $0x98, %rsp
retq
nopl (%rax)