// File: /workspace/github_cpp_makefile_star2_O1/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, %r15
movq %rdi, %rbx
xorpd %xmm0, %xmm0
leaq -0x70(%rbp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x28(%rbx), %rsi
callq 0x467c
movq 0x18(%rbx), %r14
addq $0x8, %rbx
cmpq %rbx, %r14
je 0x3fdf
movq 0x18(%r15), %r15
movq -0x70(%rbp), %r13
leaq -0x88(%rbp), %r12
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
movq 0x20(%r14), %rsi
movq 0x28(%r14), %rdx
addq %rsi, %rdx
leaq -0x58(%rbp), %rdi
callq 0x4742
movsd 0x40(%r14), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %r12, -0x98(%rbp)
movq 0x20(%r15), %rsi
movq 0x28(%r15), %rdx
addq %rsi, %rdx
leaq -0x98(%rbp), %rdi
callq 0x4742
movsd 0x40(%r15), %xmm1
movsd %xmm1, -0x78(%rbp)
movsd -0x38(%rbp), %xmm0
divsd %xmm1, %xmm0
callq 0x2190
mulsd -0x38(%rbp), %xmm0
movsd %xmm0, (%r13)
movq -0x98(%rbp), %rdi
cmpq %r12, %rdi
je 0x3faa
callq 0x21c0
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3fbc
callq 0x21c0
movq %r14, %rdi
callq 0x2210
movq %rax, %r14
movq %r15, %rdi
callq 0x2210
movq %rax, %r15
addq $0x8, %r13
cmpq %rbx, %r14
jne 0x3f30
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rax
xorpd %xmm0, %xmm0
cmpq %rax, %rdi
je 0x4000
movq %rdi, %rcx
addsd (%rcx), %xmm0
addq $0x8, %rcx
cmpq %rax, %rcx
jne 0x3ff3
testq %rdi, %rdi
je 0x4014
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 0x4025
movq %rax, %rbx
jmp 0x403f
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x403f
callq 0x21c0
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x404d
callq 0x21c0
movq %rbx, %rdi
callq 0x22b0
nop