// File: /workspace/github_cpp_makefile_star2_O3/aalto-speech[P]ftk/src/Bigrams.cc
// Function: Bigrams::kn_smooth(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, 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>>>, 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, 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>>, 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>>>, 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, 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>>>>>>&, double, double)
void
Bigrams::kn_smooth(const transitions_t &counts,
                   transitions_t &kn,
                   double D,
                   double min_lp)
{
    kn.clear();

    map<string, double> ctxt_totals;
    map<string, double> ctxt_count;
    map<string, double> unigram_count;
    double u_total = 0;
    for (auto srcit = counts.begin(); srcit != counts.end(); ++srcit) {
        for (auto tgtit = srcit->second.begin(); tgtit != srcit->second.end(); ++tgtit) {
            if (tgtit->second > D) {
                ctxt_totals[srcit->first] += tgtit->second;
                ctxt_count[srcit->first] += D;
                unigram_count[tgtit->first] += D;
                u_total += D;
            }
            else {
                ctxt_totals[srcit->first] += tgtit->second;
                ctxt_count[srcit->first] += tgtit->second;
                unigram_count[tgtit->first] += tgtit->second;
                u_total += tgtit->second;
            }
        }
    }

    for (auto srcit = counts.begin(); srcit != counts.end(); ++srcit) {
        for (auto tgtit = srcit->second.begin(); tgtit != srcit->second.end(); ++tgtit) {
            double term1 = max(tgtit->second-D, 0.0);
            term1 /= ctxt_totals[srcit->first];
            double term2 = ctxt_count[srcit->first] / ctxt_totals[srcit->first];
            term2 *= unigram_count[tgtit->first] / u_total;
            double kn_prob = log(term1+term2);
            if (kn_prob < min_lp || std::isinf(kn_prob) || std::isnan(kn_prob)) kn_prob = min_lp;
            kn[srcit->first][tgtit->first] = kn_prob;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movapd %xmm1, -0x90(%rbp)
movsd %xmm0, -0x58(%rbp)
movq %rdi, %rbx
movq %rsi, -0x78(%rbp)
movq %rsi, %rdi
callq 0x1c43c
leaq -0xe8(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, (%rax)
movq %rcx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rcx, 0x20(%rax)
leaq -0xb8(%rbp), %rax
movl %ecx, (%rax)
movq %rcx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rcx, 0x20(%rax)
leaq -0x118(%rbp), %rax
movl %ecx, (%rax)
movq %rcx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rcx, 0x20(%rax)
movq 0x18(%rbx), %rax
leaq 0x8(%rbx), %rcx
movq %rcx, -0x60(%rbp)
cmpq %rcx, %rax
je 0x21ab0
movq %rbx, -0x70(%rbp)
xorpd %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
leaq -0x120(%rbp), %r15
movq 0x58(%rax), %rbx
leaq 0x48(%rax), %r13
cmpq %r13, %rbx
movq %rax, -0x48(%rbp)
je 0x21a93
leaq 0x20(%rax), %r14
leaq 0x20(%rbx), %r12
movsd 0x40(%rbx), %xmm0
movsd %xmm0, -0x40(%rbp)
ucomisd -0x58(%rbp), %xmm0
jbe 0x21a08
leaq -0xf0(%rbp), %rdi
movq %r14, %rsi
callq 0x1af86
movsd -0x40(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
leaq -0xc0(%rbp), %rdi
movq %r14, %rsi
callq 0x1af86
movsd (%rax), %xmm0
addsd -0x58(%rbp), %xmm0
movsd %xmm0, (%rax)
movq %r15, %rdi
movq %r12, %rsi
callq 0x1af86
movsd (%rax), %xmm0
movsd -0x58(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movapd %xmm1, %xmm0
jmp 0x21a71
leaq -0xf0(%rbp), %rdi
movq %r14, %rsi
callq 0x1af86
movsd -0x40(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0x40(%rbx), %xmm0
movsd %xmm0, -0x40(%rbp)
leaq -0xc0(%rbp), %rdi
movq %r14, %rsi
callq 0x1af86
movsd -0x40(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0x40(%rbx), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x1af86
movsd -0x40(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0x40(%rbx), %xmm0
movsd -0x50(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x50(%rbp)
movq %rbx, %rdi
callq 0x4410
movq %rax, %rbx
cmpq %r13, %rax
jne 0x21999
movq -0x48(%rbp), %rdi
callq 0x4410
cmpq -0x60(%rbp), %rax
jne 0x21980
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
jmp 0x21ab9
xorpd %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
cmpq -0x60(%rbp), %rax
je 0x21c2f
leaq -0xf0(%rbp), %r15
movq 0x58(%rax), %r14
movq %rax, -0x48(%rbp)
leaq 0x48(%rax), %r13
cmpq %r13, %r14
je 0x21c1c
movq -0x48(%rbp), %rax
leaq 0x20(%rax), %rbx
movsd 0x40(%r14), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1af86
movsd -0x40(%rbp), %xmm1
subsd -0x58(%rbp), %xmm1
xorpd %xmm0, %xmm0
maxsd %xmm1, %xmm0
divsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
leaq -0xc0(%rbp), %rdi
movq %rbx, %rsi
callq 0x1af86
movsd (%rax), %xmm0
movsd %xmm0, -0x70(%rbp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1af86
leaq 0x20(%r14), %r12
movsd (%rax), %xmm0
movsd %xmm0, -0x80(%rbp)
leaq -0x120(%rbp), %rdi
movq %r12, %rsi
callq 0x1af86
movsd -0x70(%rbp), %xmm0
divsd -0x80(%rbp), %xmm0
movsd (%rax), %xmm1
divsd -0x50(%rbp), %xmm1
mulsd %xmm0, %xmm1
movsd -0x40(%rbp), %xmm0
addsd %xmm1, %xmm0
callq 0x42f0
movapd %xmm0, -0x40(%rbp)
movq %xmm0, %rax
btrq $0x3f, %rax
movapd -0x90(%rbp), %xmm0
movapd %xmm0, -0x70(%rbp)
movabsq $0x7ff0000000000000, %rcx # imm = 0x7FF0000000000000
cmpq %rcx, %rax
je 0x21bb1
movapd -0x40(%rbp), %xmm0
movapd %xmm0, -0x70(%rbp)
movq -0x78(%rbp), %rdi
movq %rbx, %rsi
callq 0x1b318
movq %rax, %rdi
movq %r12, %rsi
callq 0x1af86
movapd -0x40(%rbp), %xmm3
movapd %xmm3, %xmm0
movapd -0x90(%rbp), %xmm2
cmpltsd %xmm2, %xmm0
movapd %xmm0, %xmm1
andnpd -0x70(%rbp), %xmm1
andpd %xmm2, %xmm0
orpd %xmm1, %xmm0
cmpunordsd %xmm3, %xmm3
movapd %xmm3, %xmm1
andnpd %xmm0, %xmm1
andpd %xmm2, %xmm3
orpd %xmm1, %xmm3
movsd %xmm3, (%rax)
movq %r14, %rdi
callq 0x4410
movq %rax, %r14
cmpq %r13, %rax
jne 0x21ae7
movq -0x48(%rbp), %rdi
callq 0x4410
cmpq -0x60(%rbp), %rax
jne 0x21aca
leaq -0x120(%rbp), %rdi
callq 0x5ce4
leaq -0xc0(%rbp), %rdi
callq 0x5ce4
leaq -0xf0(%rbp), %rdi
callq 0x5ce4
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x21c6b
jmp 0x21c6b
jmp 0x21c6b
movq %rax, %rbx
leaq -0x120(%rbp), %rdi
callq 0x5ce4
leaq -0xc0(%rbp), %rdi
callq 0x5ce4
leaq -0xf0(%rbp), %rdi
callq 0x5ce4
movq %rbx, %rdi
callq 0x4650