// File: /workspace/github_cpp_makefile_star2_O3/cegme[P]vose/VoseTree.cc
// Function: VoseTree::kl(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::less<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>>> const&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::less<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>>> const&)
double VoseTree::kl(const std::map<std::string, double> &a, const std::map<std::string, double> &b) {

  /*std::cerr<< "a: ";
  std::for_each(a.begin(), a.end(), [] (std::pair<const std::string, double> z) { 
    std::cerr << "<" << z.first << "," << z.second << ">";
  });
  std::cerr << "\nb: ";
  std::for_each(b.begin(), b.end(), [] (std::pair<const std::string, double> z) { 
    std::cerr << "<" << z.first << "," << z.second << ">";
  });*/

  std::vector<double> v;
  v.resize(a.size());
  std::transform(a.cbegin(), a.cend(), b.cbegin(), v.begin(), [&v] (std::pair<const std::string, double> a, std::pair<const std::string, double> b) {
    //printf("a:%f, b:%f, log(a/b):%f\n", a.second, b.second, log(a.second/b.second));
    return (double)log(a.second/b.second)*a.second;
  });
  return std::accumulate(v.cbegin(), v.cend(), 0.0, std::plus<double>());
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %r12
movq %rdi, %r14
xorpd %xmm0, %xmm0
leaq -0x70(%rbp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x28(%r14), %rsi
callq 0x435a
movq 0x18(%r14), %r15
addq $0x8, %r14
movq -0x70(%rbp), %rbx
cmpq %r14, %r15
je 0x3baa
movq 0x18(%r12), %r13
leaq -0x88(%rbp), %r12
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
movq 0x20(%r15), %rsi
movq 0x28(%r15), %rdx
addq %rsi, %rdx
leaq -0x58(%rbp), %rdi
callq 0x4420
movsd 0x40(%r15), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %r12, -0x98(%rbp)
movq 0x20(%r13), %rsi
movq 0x28(%r13), %rdx
addq %rsi, %rdx
leaq -0x98(%rbp), %rdi
callq 0x4420
movsd 0x40(%r13), %xmm1
movsd %xmm1, -0x78(%rbp)
movsd -0x38(%rbp), %xmm0
divsd %xmm1, %xmm0
callq 0x2190
mulsd -0x38(%rbp), %xmm0
movsd %xmm0, (%rbx)
movq -0x98(%rbp), %rdi
cmpq %r12, %rdi
je 0x3b71
callq 0x21c0
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3b83
callq 0x21c0
movq %r15, %rdi
callq 0x2210
movq %rax, %r15
movq %r13, %rdi
callq 0x2210
movq %rax, %r13
addq $0x8, %rbx
cmpq %r14, %r15
jne 0x3af9
movq -0x70(%rbp), %rbx
movq -0x68(%rbp), %rax
xorpd %xmm0, %xmm0
cmpq %rax, %rbx
je 0x3bc7
movq %rbx, %rcx
addsd (%rcx), %xmm0
addq $0x8, %rcx
cmpq %rax, %rcx
jne 0x3bba
testq %rbx, %rbx
je 0x3bde
movq %rbx, %rdi
movsd %xmm0, -0x30(%rbp)
callq 0x21c0
movsd -0x30(%rbp), %xmm0
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3bef
movq %rax, %rbx
jmp 0x3c09
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3c09
callq 0x21c0
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x3c17
callq 0x21c0
movq %rbx, %rdi
callq 0x22b0
nop