// File: aalto-speech[P]ftk/src/Unigrams.cc
// Function: Unigrams::rank_candidates(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&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<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>>>&, std::vector<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double>>>&)
flt_type
Unigrams::rank_candidates(const map<string, flt_type> &words,
                          const map<string, flt_type> &vocab,
                          const set<string> &candidates,
                          map<string, flt_type> &new_freqs,
                          vector<pair<string, flt_type> > &removal_scores)
{
    new_freqs.clear();
    removal_scores.clear();

    StringSet ss_vocab(vocab);
    map<string, flt_type> ll_diffs;
    map<string, flt_type> token_diffs;
    set<string> problem_hypos;

    flt_type curr_ll = 0.0;
    flt_type token_count = 0.0;

    for (auto worditer = words.cbegin(); worditer != words.cend(); ++worditer) {

        map<string, flt_type> stats;
        flt_type orig_score = segf(ss_vocab, worditer->first, stats, this->utf8);

        if (stats.size() == 0) {
            cerr << "warning, no segmentation for word: " << worditer->first << endl;
            continue;
        }

        curr_ll += worditer->second * orig_score;
        token_count += worditer->second * stats.size();

        // Update statistics
        for (auto it = stats.cbegin(); it != stats.cend(); ++it)
            new_freqs[it->first] += worditer->second * it->second;

        for (auto hypoiter = stats.cbegin(); hypoiter != stats.cend(); ++hypoiter) {

            if (candidates.find(hypoiter->first) != candidates.end()) {

                flt_type stored_value = ss_vocab.remove(hypoiter->first);

                map<string, flt_type> hypo_stats;
                flt_type hypo_score = segf(ss_vocab, worditer->first, hypo_stats, this->utf8);

                if (hypo_stats.size() > 0) {
                    ll_diffs[hypoiter->first] += worditer->second * (hypo_score-orig_score);
                    token_diffs[hypoiter->first] += worditer->second * ((flt_type)(hypo_stats.size())-(flt_type)(stats.size()));
                }
                else
                    problem_hypos.insert(hypoiter->first);

                ss_vocab.add(hypoiter->first, stored_value);
            }
        }
    }

    for (auto iter = ll_diffs.begin(); iter != ll_diffs.end(); ++iter) {
        if (problem_hypos.find(iter->first) != problem_hypos.end()) continue;
        flt_type renormalizer = sub_log_domain_probs(0, vocab.at(iter->first));
        flt_type hypo_token_count = (token_count + token_diffs[iter->first]);
        flt_type normalizer_ll_diff = hypo_token_count * -renormalizer;
        pair<string, flt_type> removal_score = make_pair(iter->first, iter->second + normalizer_ll_diff);
        removal_scores.push_back(removal_score);
    }

    sort(removal_scores.begin(), removal_scores.end(), descending_sort);

    return curr_ll;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x490, %rsp            # imm = 0x490
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x348(%rbp)
movq -0x28(%rbp), %rdi
callq 0x47d90
movq -0x30(%rbp), %rdi
callq 0x588b0
movq -0x18(%rbp), %rsi
leaq -0x150(%rbp), %rdi
callq 0x19e70
leaq -0x180(%rbp), %rdi
callq 0x5fb0
leaq -0x1b0(%rbp), %rdi
callq 0x5fb0
leaq -0x1e0(%rbp), %rdi
callq 0x6050
xorps %xmm0, %xmm0
movsd %xmm0, -0x1e8(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x1f0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b260
movq %rax, -0x1f8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b2c0
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x1b290
testb $0x1, %al
jne 0x57246
jmp 0x5789b
leaq -0x230(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x5fb0
movq -0x348(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x358(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movq -0x348(%rbp), %rcx
movq -0x360(%rbp), %rdx
movq %rax, %rsi
movq -0x358(%rbp), %rax
movzbl 0x8(%rcx), %ecx
andl $0x1, %ecx
leaq -0x150(%rbp), %rdi
callq *%rax
movsd %xmm0, -0x350(%rbp)
jmp 0x572a8
movsd -0x350(%rbp), %xmm0
movsd %xmm0, -0x238(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
cmpq $0x0, %rax
jne 0x57345
movq 0x3cd17(%rip), %rdi     # 0x93fe8
leaq 0xf568(%rip), %rsi      # 0x66840
callq 0x43c0
movq %rax, -0x368(%rbp)
jmp 0x572e6
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movq -0x368(%rbp), %rdi
movq %rax, %rsi
callq 0x4380
movq %rax, -0x370(%rbp)
jmp 0x5730a
movq -0x370(%rbp), %rdi
movq 0x3cc80(%rip), %rsi     # 0x93f98
callq 0x4400
jmp 0x5731f
movl $0x4, -0x248(%rbp)
jmp 0x5785d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x5788a
leaq -0x1f8(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x1b2f0
movq -0x380(%rbp), %rdi
movsd 0x20(%rax), %xmm0
movsd -0x238(%rbp), %xmm2
movsd -0x1e8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x1e8(%rbp)
callq 0x1b2f0
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x378(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
movsd -0x378(%rbp), %xmm0
movq %rax, %xmm2
movaps 0xf46a(%rip), %xmm1     # 0x66820
punpckldq %xmm1, %xmm2    # xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
movapd 0xf46e(%rip), %xmm1     # 0x66830
subpd %xmm1, %xmm2
movaps %xmm2, %xmm1
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
addsd %xmm1, %xmm2
movsd -0x1f0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x1f0(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b260
movq %rax, -0x250(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b2c0
movq %rax, -0x258(%rbp)
leaq -0x250(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x1b290
testb $0x1, %al
jne 0x5742b
jmp 0x574cb
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x3a8(%rbp)
leaq -0x250(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
callq 0x1b2f0
movq -0x3a0(%rbp), %rdi
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x398(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x390(%rbp)
callq 0x1b2f0
movq -0x390(%rbp), %rdi
movq %rax, %rsi
callq 0x47db0
movq %rax, -0x388(%rbp)
jmp 0x57493
movq -0x388(%rbp), %rax
movsd -0x398(%rbp), %xmm2
movsd -0x3a8(%rbp), %xmm0
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
leaq -0x250(%rbp), %rdi
callq 0x1b320
jmp 0x573fc
leaq -0x230(%rbp), %rdi
callq 0x1b260
movq %rax, -0x260(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b2c0
movq %rax, -0x268(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x1b290
testb $0x1, %al
jne 0x5750d
jmp 0x57853
movq -0x20(%rbp), %rax
movq %rax, -0x3b8(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq -0x3b8(%rbp), %rdi
movq %rax, %rsi
callq 0x235e0
movq %rax, -0x3b0(%rbp)
jmp 0x5753c
movq -0x3b0(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x20(%rbp), %rdi
callq 0x23610
movq %rax, -0x278(%rbp)
leaq -0x270(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x57576
jmp 0x57840
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x150(%rbp), %rdi
callq 0x1aa80
movsd %xmm0, -0x3c0(%rbp)
jmp 0x5759b
movsd -0x3c0(%rbp), %xmm0
movsd %xmm0, -0x280(%rbp)
leaq -0x2b0(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x5fb0
movq -0x348(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movq -0x348(%rbp), %rcx
movq -0x3d8(%rbp), %rdx
movq %rax, %rsi
movq -0x3d0(%rbp), %rax
movzbl 0x8(%rcx), %ecx
andl $0x1, %ecx
leaq -0x150(%rbp), %rdi
callq *%rax
movsd %xmm0, -0x3c8(%rbp)
jmp 0x5760d
movsd -0x3c8(%rbp), %xmm0
movsd %xmm0, -0x2b8(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x5fd0
cmpq $0x0, %rax
jbe 0x577cb
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x3f0(%rbp)
movsd -0x2b8(%rbp), %xmm0
movsd -0x238(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x3e8(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x180(%rbp), %rdi
callq 0x47db0
movq %rax, -0x3e0(%rbp)
jmp 0x5768c
movq -0x3e0(%rbp), %rax
movsd -0x3e8(%rbp), %xmm2
movsd -0x3f0(%rbp), %xmm0
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
leaq -0x1f8(%rbp), %rdi
callq 0x1b2f0
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x438(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x5fd0
movq %rax, %xmm0
movaps 0xf13c(%rip), %xmm1     # 0x66820
movaps %xmm1, -0x430(%rbp)
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xf139(%rip), %xmm1     # 0x66830
movaps %xmm1, -0x420(%rbp)
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, -0x408(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
movaps -0x430(%rbp), %xmm3
movaps -0x420(%rbp), %xmm2
movsd -0x408(%rbp), %xmm0
movq %rax, %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x400(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x47db0
movq %rax, -0x3f8(%rbp)
jmp 0x5777f
movq -0x3f8(%rbp), %rax
movsd -0x400(%rbp), %xmm2
movsd -0x438(%rbp), %xmm0
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0x5780f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x6090
jmp 0x5788a
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x31820
movb %dl, -0x441(%rbp)
movq %rax, -0x440(%rbp)
jmp 0x577f5
movb -0x441(%rbp), %al
movq -0x440(%rbp), %rcx
movq %rcx, -0x2c8(%rbp)
movb %al, -0x2c0(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
movsd -0x280(%rbp), %xmm0
leaq -0x150(%rbp), %rdi
callq 0x1a2a0
jmp 0x57834
leaq -0x2b0(%rbp), %rdi
callq 0x6090
jmp 0x57842
leaq -0x260(%rbp), %rdi
callq 0x1b320
jmp 0x574de
movl $0x0, -0x248(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x6090
movl -0x248(%rbp), %eax
testl %eax, %eax
je 0x57877
jmp 0x57875
jmp 0x57879
jmp 0x57879
leaq -0x1f8(%rbp), %rdi
callq 0x1b320
jmp 0x5721a
leaq -0x230(%rbp), %rdi
callq 0x6090
jmp 0x57b71
leaq -0x180(%rbp), %rdi
callq 0x58790
movq %rax, -0x2d0(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x48c90
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x48c30
testb $0x1, %al
jne 0x578dd
jmp 0x57ada
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq %rax, %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x58b10
movq %rax, -0x450(%rbp)
jmp 0x57901
movq -0x450(%rbp), %rax
movq %rax, -0x2e0(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x23610
movq %rax, -0x2e8(%rbp)
leaq -0x2e0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x5793b
jmp 0x57957
jmp 0x57aa6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x57b71
movq -0x18(%rbp), %rax
movq %rax, -0x460(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq -0x460(%rbp), %rdi
movq %rax, %rsi
callq 0x48880
movq %rax, -0x458(%rbp)
jmp 0x57986
movq -0x458(%rbp), %rax
movsd (%rax), %xmm1
xorps %xmm0, %xmm0
callq 0x57bb0
movsd %xmm0, -0x468(%rbp)
jmp 0x579a3
movsd -0x468(%rbp), %xmm0
movsd %xmm0, -0x2f0(%rbp)
movsd -0x1f0(%rbp), %xmm0
movsd %xmm0, -0x478(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq %rax, %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x47db0
movq %rax, -0x470(%rbp)
jmp 0x579e7
movsd -0x478(%rbp), %xmm0
movq -0x470(%rbp), %rax
movsd (%rax), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x2f8(%rbp)
movsd -0x2f8(%rbp), %xmm0
movaps 0xed7b(%rip), %xmm2     # 0x66790
movsd -0x2f0(%rbp), %xmm1
pxor %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x300(%rbp)
leaq -0x2d0(%rbp), %rdi
movq %rdi, -0x488(%rbp)
callq 0x587c0
movq -0x488(%rbp), %rdi
movq %rax, -0x480(%rbp)
callq 0x587c0
movq -0x480(%rbp), %rsi
movsd 0x20(%rax), %xmm0
movsd -0x300(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x330(%rbp)
leaq -0x328(%rbp), %rdi
leaq -0x330(%rbp), %rdx
callq 0x58e10
jmp 0x57a88
movq -0x30(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0x58910
jmp 0x57a9a
leaq -0x328(%rbp), %rdi
callq 0x58980
leaq -0x2d0(%rbp), %rdi
callq 0x4bba0
jmp 0x578ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x328(%rbp), %rdi
callq 0x58980
jmp 0x57b71
movq -0x30(%rbp), %rdi
callq 0x58a30
movq %rax, -0x338(%rbp)
movq -0x30(%rbp), %rdi
callq 0x58a60
movq %rax, -0x340(%rbp)
movq -0x338(%rbp), %rdi
movq -0x340(%rbp), %rsi
leaq -0x2fdf(%rip), %rdx     # 0x54b30
callq 0x589e0
jmp 0x57b16
movsd -0x1e8(%rbp), %xmm0
movsd %xmm0, -0x490(%rbp)
movl $0x1, -0x248(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x6070
leaq -0x1b0(%rbp), %rdi
callq 0x6090
leaq -0x180(%rbp), %rdi
callq 0x6090
leaq -0x150(%rbp), %rdi
callq 0x1a3e0
movsd -0x490(%rbp), %xmm0
addq $0x490, %rsp            # imm = 0x490
popq %rbp
retq
leaq -0x1e0(%rbp), %rdi
callq 0x6070
leaq -0x1b0(%rbp), %rdi
callq 0x6090
leaq -0x180(%rbp), %rdi
callq 0x6090
leaq -0x150(%rbp), %rdi
callq 0x1a3e0
movq -0x240(%rbp), %rdi
callq 0x46e0
nopl (%rax)