// File: adamiaonr[P]rid-analytics/src/prob.cpp
// Function: Prob::calc_fptree_probs(std::vector<std::vector<Prob::fp_data*, std::allocator<Prob::fp_data*>>, std::allocator<std::vector<Prob::fp_data*, std::allocator<Prob::fp_data*>>>>*, std::map<int, std::vector<unsigned char, std::allocator<unsigned char>>, std::less<int>, std::allocator<std::pair<int const, std::vector<unsigned char, std::allocator<unsigned char>>>>>*, std::vector<long double, std::allocator<long double>>*)
int Prob::calc_fptree_probs(
    std::vector<std::vector<Prob::fp_data *> > * iface_fp_data,
    std::map<int, std::vector<uint8_t> > * tree_bitmasks,
    std::vector<__float080> * in_fptree_prob) {

    // (1) calculate str[i][t] : shared tree ratios for iface i, size t
    std::vector<__float080> str_total(this->n + 1, 0.0);
    std::vector< std::vector<__float080> > str(this->iface_num, std::vector<__float080>(this->n + 1, 0.0));

    for (uint8_t i = 0; i < this->iface_num; i++) {
        // don't consider blocked ifaces
        if ((*iface_fp_data)[0][i]->is_blocked) continue;

        std::map<int, std::vector<uint8_t> >::iterator itr;
        for (itr = (*tree_bitmasks).begin(); itr != (*tree_bitmasks).end(); itr++) {

            int t = itr->first;
            if (t == 0) continue;

            // count shared trees w/ bitmask on iface i
            str[i][t] = (__float080) count_shared_trees(t, (*iface_fp_data)[0][i], tree_bitmasks);
            // keep track of total # of shared trees
            str_total[t] += str[i][t];
        }
    }

    // std::cout << "Prob::calc_fptree_probs() : shared tree ratios :" << std::endl;
    // for (uint8_t i = 0; i < this->iface_num; i++)
    //     for (uint8_t t = 1; t < (this->n + 1); t++)
    //         std::cout << "\tstr[" << (int) i << "][" << (int) t << "] = " << str[i][t] / ((str_total[t] > 0.0) ? str_total[t] : 1.0) << std::endl;

    // (2) calc P(T_i = t), for all {i,t} pairs
    for (uint8_t i = 0; i < this->iface_num; i++) {
        
        // if iface i is blocked, don't bother going on...
        if ((*iface_fp_data)[0][i]->is_blocked) continue;
        // uint8_t max_tree = 0;
        __float080 cumulative_fptree_prob[2] = {0.0, 0.0};
        for (uint8_t t = 1; t < (this->n + 1); t++) {

            // P(T_i > 0) = srt[i][t] * P(T_in = t)
            this->fptree_prob[0][i][t] = (str[i][t] / ((str_total[t] > 0.0) ? str_total[t] : 1.0)) * (*in_fptree_prob)[t];            
            // P(T_{~i} > 0) = P(T_in = t) - (srt[i][t] * P(T_in = t))
            this->fptree_prob[1][i][t] = ((*in_fptree_prob)[t] - this->fptree_prob[0][i][t]);

            // SUM {for all t > 0} [ srt[i][t] * P(T_in = t) ]
            //  - will be used in calc. of P(T_i = 0, B)
            cumulative_fptree_prob[0] += this->fptree_prob[0][i][t];
            cumulative_fptree_prob[1] += this->fptree_prob[1][i][t];
        }

        // P(T_i = 0) = 1.0 - SUM {for all t > 0} [ srt[i][t] * P(T_in = t) ]
        this->fptree_prob[0][i][0] = (__float080) ((float) 1.0 - (float) cumulative_fptree_prob[0]);
        this->fptree_prob[1][i][0] = (__float080) ((float) 1.0 - (float) cumulative_fptree_prob[1]);

        // std::cout << "Prob::calc_fptree_probs() : P(T[" << (int) i << "] = 0) = 1.0 - " 
        //     << cumulative_fptree_prob[0] << " = " << (this->fptree_prob[0][i][0]) << std::endl;
        // std::cout << "Prob::calc_fptree_probs() : P(T[~" << (int) i << "] = 0) = 1.0 - " 
        //     << cumulative_fptree_prob[1] << " = " << (this->fptree_prob[1][i][0]) << std::endl;
    }

    // std::cout << "Prob::calc_fptree_probs() : P(T_i = t) :" << std::endl;
    // for (uint8_t i = 0; i < this->iface_num; i++)
    //     for (uint8_t t = 0; t < (this->n + 1); t++)
    //         std::cout << "\tP(T[" << (int) i << "] = " << (int) t << "]) = " << this->fptree_prob[0][i][t] << std::endl;

    // std::cout << "Prob::calc_fptree_probs() : P(T_{~i} = t) :" << std::endl;
    // for (uint8_t i = 0; i < this->iface_num; i++)
    //     for (uint8_t t = 0; t < (this->n + 1); t++)
    //         std::cout << "\tP(T[~" << (int) i << "] = " << (int) t << "]) = " << this->fptree_prob[1][i][t] << std::endl;

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x240, %rsp            # imm = 0x240
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x160(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x7e26(%rip)            # 0x635fc
fxch %st(1)
fucomi %st(1), %st
fldz
fld %st(0)
fcmovnb %st(3), %st
fstp %st(3)
fxch %st(1)
fsubp %st, %st(2)
setae %al
fnstcw -0x142(%rbp)
movzwl -0x142(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x144(%rbp)
fldcw -0x144(%rbp)
fxch %st(1)
fistpll -0x120(%rbp)
fldcw -0x142(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x120(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x158(%rbp)
fstpt -0x50(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0x34a40
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rcx
leaq -0x38(%rbp), %rdi
leaq -0x50(%rbp), %rdx
callq 0x34a60
jmp 0x5b861
leaq -0x51(%rbp), %rdi
callq 0x34b70
movq -0x160(%rbp), %rax
movzbl 0xb0(%rax), %ecx
movq %rcx, -0x178(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x7d6d(%rip)            # 0x635fc
fxch %st(1)
fucomi %st(1), %st
fldz
fld %st(0)
fcmovnb %st(3), %st
fstp %st(3)
fxch %st(1)
fsubp %st, %st(2)
setae %al
fnstcw -0x146(%rbp)
movzwl -0x146(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x148(%rbp)
fldcw -0x148(%rbp)
fxch %st(1)
fistpll -0x128(%rbp)
fldcw -0x146(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x128(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x170(%rbp)
fstpt -0xb0(%rbp)
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x34a40
movq -0x170(%rbp), %rsi
movq -0x168(%rbp), %rcx
leaq -0x98(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
callq 0x34a60
jmp 0x5b926
leaq -0xb2(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0x35a40
movq -0x178(%rbp), %rsi
movq -0x180(%rbp), %rcx
leaq -0x80(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x35a60
jmp 0x5b959
leaq -0xb2(%rbp), %rdi
callq 0x35b40
leaq -0x98(%rbp), %rdi
callq 0x34b10
leaq -0xb1(%rbp), %rdi
callq 0x34b70
movb $0x0, -0xb3(%rbp)
movq -0x160(%rbp), %rcx
movzbl -0xb3(%rbp), %eax
movzbl 0xb0(%rcx), %ecx
cmpl %ecx, %eax
jge 0x5bbc2
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35850
movq %rax, %rdi
movzbl -0xb3(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq (%rax), %rax
testb $0x1, 0xb8(%rax)
je 0x5ba2d
jmp 0x5bbaf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x51(%rbp), %rdi
callq 0x34b70
jmp 0x5bfbc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5ba1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xb2(%rbp), %rdi
callq 0x35b40
leaq -0x98(%rbp), %rdi
callq 0x34b10
leaq -0xb1(%rbp), %rdi
callq 0x34b70
jmp 0x5bfb3
leaq -0xc0(%rbp), %rdi
callq 0x351b0
movq -0x18(%rbp), %rdi
callq 0x351d0
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x35230
movq %rax, -0xd0(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x35200
testb $0x1, %al
jne 0x5ba83
jmp 0x5bbad
leaq -0xc0(%rbp), %rdi
callq 0x352a0
movl (%rax), %eax
movl %eax, -0xd4(%rbp)
cmpl $0x0, -0xd4(%rbp)
jne 0x5baa5
jmp 0x5bb79
movl -0xd4(%rbp), %eax
movl %eax, -0x188(%rbp)
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35850
movq %rax, %rdi
movzbl -0xb3(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movl -0x188(%rbp), %edi
movq (%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x59e00
movl %eax, -0x184(%rbp)
jmp 0x5bae9
movl -0x184(%rbp), %eax
movl %eax, -0x140(%rbp)
fildl -0x140(%rbp)
fstpt -0x1ac(%rbp)
movzbl -0xb3(%rbp), %eax
movl %eax, %esi
leaq -0x80(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x358a0
movq %rax, %rdi
movslq -0xd4(%rbp), %rsi
callq 0x34c70
fldt -0x1ac(%rbp)
movq -0x1a0(%rbp), %rdi
fstpt (%rax)
movzbl -0xb3(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movslq -0xd4(%rbp), %rsi
callq 0x34c70
fldt (%rax)
fstpt -0x194(%rbp)
movslq -0xd4(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x34c70
fldt -0x194(%rbp)
fldt (%rax)
faddp %st, %st(1)
fstpt (%rax)
leaq -0xc0(%rbp), %rdi
xorl %esi, %esi
callq 0x35320
movq %rax, -0xe0(%rbp)
jmp 0x5ba57
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x35ae0
jmp 0x5bfb3
jmp 0x5bbaf
movb -0xb3(%rbp), %al
addb $0x1, %al
movb %al, -0xb3(%rbp)
jmp 0x5b984
movb $0x0, -0xe1(%rbp)
movq -0x160(%rbp), %rcx
movzbl -0xe1(%rbp), %eax
movzbl 0xb0(%rcx), %ecx
cmpl %ecx, %eax
jge 0x5bf96
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35850
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq (%rax), %rax
testb $0x1, 0xb8(%rax)
je 0x5bc15
jmp 0x5bf83
leaq -0x110(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x5290
movb $0x1, -0x111(%rbp)
movq -0x160(%rbp), %rax
movzbl -0x111(%rbp), %ecx
movl %ecx, -0x12c(%rbp)
fildl -0x12c(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5be90
jmp 0x5bc5f
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
leaq -0x80(%rbp), %rdi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt (%rax)
fstpt -0x1b8(%rbp)
movzbl -0x111(%rbp), %eax
movl %eax, %esi
leaq -0x38(%rbp), %rdi
callq 0x34c70
fldt (%rax)
fldz
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5bcc6
jmp 0x5bcaa
movzbl -0x111(%rbp), %eax
movl %eax, %esi
leaq -0x38(%rbp), %rdi
callq 0x34c70
fldt (%rax)
fstpt -0x1c4(%rbp)
jmp 0x5bcd0
fld1
fstpt -0x1c4(%rbp)
jmp 0x5bcd0
fldt -0x1b8(%rbp)
fldt -0x1c4(%rbp)
fdivrp %st, %st(1)
fstpt -0x210(%rbp)
movq -0x20(%rbp), %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x210(%rbp)
movq -0x160(%rbp), %rdi
fldt (%rax)
fmulp %st, %st(1)
fstpt -0x204(%rbp)
addq $0x60, %rdi
movq %rdi, -0x1d8(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x1e0(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x204(%rbp)
fstpt (%rax)
movq -0x20(%rbp), %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rdi
fldt (%rax)
fstpt -0x1f8(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x1f8(%rbp)
movq -0x1d8(%rbp), %rdi
fldt (%rax)
fsubrp %st, %st(1)
fstpt -0x1ec(%rbp)
movl $0x1, %esi
movq %rsi, -0x1d0(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x1ec(%rbp)
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rdi
fstpt (%rax)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
movq -0x1d8(%rbp), %rdi
movq -0x1d0(%rbp), %rsi
fldt (%rax)
fldt -0x110(%rbp)
faddp %st, %st(1)
fstpt -0x110(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x111(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt (%rax)
fldt -0x100(%rbp)
faddp %st, %st(1)
fstpt -0x100(%rbp)
movb -0x111(%rbp), %al
addb $0x1, %al
movb %al, -0x111(%rbp)
jmp 0x5bc2f
movq -0x160(%rbp), %rdi
fldt -0x110(%rbp)
fstps -0x130(%rbp)
movss -0x130(%rbp), %xmm1
movss 0x85d9(%rip), %xmm0     # 0x6448c
movss %xmm0, -0x234(%rbp)
subss %xmm1, %xmm0
movss %xmm0, -0x134(%rbp)
flds -0x134(%rbp)
fstpt -0x240(%rbp)
addq $0x60, %rdi
movq %rdi, -0x230(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x228(%rbp)
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x34c70
fldt -0x240(%rbp)
movss -0x234(%rbp), %xmm0
movq -0x230(%rbp), %rdi
fstpt (%rax)
fldt -0x100(%rbp)
fstps -0x138(%rbp)
movss -0x138(%rbp), %xmm1
subss %xmm1, %xmm0
movss %xmm0, -0x13c(%rbp)
flds -0x13c(%rbp)
fstpt -0x21c(%rbp)
movl $0x1, %esi
callq 0x5d910
movq %rax, %rdi
movzbl -0xe1(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x34c70
fldt -0x21c(%rbp)
fstpt (%rax)
movb -0xe1(%rbp), %al
addb $0x1, %al
movb %al, -0xe1(%rbp)
jmp 0x5bbc9
leaq -0x80(%rbp), %rdi
callq 0x35ae0
leaq -0x38(%rbp), %rdi
callq 0x34b10
xorl %eax, %eax
addq $0x240, %rsp            # imm = 0x240
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x34b10
movq -0x60(%rbp), %rdi
callq 0x5920
nopw %cs:(%rax,%rax)