// File: adamiaonr[P]rid-analytics/src/prob.cpp
// Function: Prob::calc_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>>>>>*, long double, std::vector<long double, std::allocator<long double>>*, std::vector<std::vector<long double, std::allocator<long double>>, std::allocator<std::vector<long double, std::allocator<long double>>>>&, std::vector<std::vector<long double, std::allocator<long double>>, std::allocator<std::vector<long double, std::allocator<long double>>>>&)
int Prob::calc_probs(
    std::vector<std::vector<Prob::fp_data *> > * iface_fp_data,
    std::map<int, std::vector<uint8_t> > * tree_bitmasks,    // tree bitmasks from prev router
    __float080 in_prob,
    std::vector<__float080> * in_fptree_prob,
    std::vector<std::vector<__float080> > & iface_probs,
    std::vector<std::vector<__float080> > & out_fptree_probs) {

    // calc P(P_i = p) and P(P_{~i} = p)
    // time complexity : O(N * I)
    if (calc_fptree_probs(iface_fp_data, tree_bitmasks, in_fptree_prob) < 0)
        return -1;
    // if (calc_fptree_probs(iface_fp_data, tree_bitmask, in_fptree_prob, true) < 0)
    //     return -1;

    // calc P(L_i = l | P_i = p) and P(L_{~i} = l | P_{~i} = p)
    // time complexity : O(N^2 * I)
    for (unsigned i = 0; i < this->iface_num; i++) {
        this->lm_cond_prob.push_back(std::vector<std::vector<__float080> > ((n + 1), std::vector<__float080> ((n + 1), 0.0)));
        this->lm_complement_cond_prob.push_back(std::vector<std::vector<__float080> > ((n + 1), std::vector<__float080> ((n + 1), 0.0)));
    }

    if (calc_lm_probs(iface_fp_data, tree_bitmasks) < 0) 
        return -1;

    // calc P(iface = i)
    // time complexity : O(N^2 * I)

    //  - P(L_i = l) and P(L_{~i} = l)
    this->lm_marg_prob = std::vector<std::vector<__float080> >((this->iface_num), std::vector<__float080> ((this->n + 1), 0.0));
    this->lm_complement_marg_prob = std::vector<std::vector<__float080> >((this->iface_num), std::vector<__float080> ((this->n + 1), 0.0));

    for (uint8_t i = 0; i < this->iface_num; i++) {

        calc_iface_prob(i, iface_fp_data, in_fptree_prob, iface_probs[i]);
        // for joint event '& got into this router'
        iface_probs[i][0] *= in_prob;
        iface_probs[i][1] *= in_prob;
        iface_probs[i][2] *= in_prob;
    }

    // calc P(T_{out,i} = t)
    // for joint event '& got into this router
    for (uint8_t i = 0; i < this->iface_num; i++) {

        // std::fill(out_fptree_probs[i].begin(), out_fptree_probs[i].end(), 0.0);
        // out_fptree_probs[i][0] = 1.0;
        calc_out_fptree_prob(i, (*iface_fp_data)[0][i], tree_bitmasks, in_fptree_prob, out_fptree_probs);

        // std::cout << "Prob::calc_out_fptree_prob() : P(T_{out," << (int) i << "} = t) :" << std::endl;
        for (uint8_t t = 0; t <= this->n; t++) {
            out_fptree_probs[i][t] *= in_prob;
            // std::cout << "\tP(T_{out," << (int) i << "} = " << (int) t << ") = " << out_fptree_probs[i][t] << std::endl;
        }
    }

    // clear the conditional and marginal probability placeholder vectors
    this->lm_cond_prob.clear();
    this->lm_complement_cond_prob.clear();
    this->lm_marg_prob.clear();
    this->lm_complement_marg_prob.clear();

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
fldt 0x10(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
fstpt -0x30(%rbp)
movq %rcx, -0x38(%rbp)
movq %r8, -0x40(%rbp)
movq %r9, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x1d8(%rbp)
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x5b7a0
cmpl $0x0, %eax
jge 0x5cc56
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x5d557
movl $0x0, -0x4c(%rbp)
movq -0x1d8(%rbp), %rcx
movl -0x4c(%rbp), %eax
movzbl 0xb0(%rcx), %ecx
cmpl %ecx, %eax
jae 0x5cfb4
movq -0x1d8(%rbp), %rax
movq %rax, %rcx
movq %rcx, -0x1f0(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x6965(%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 -0x1c2(%rbp)
movzwl -0x1c2(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x1c4(%rbp)
fldcw -0x1c4(%rbp)
fxch %st(1)
fistpll -0x1b8(%rbp)
fldcw -0x1c2(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x1b8(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x1e8(%rbp)
fstpt -0x90(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0x34a40
movq -0x1e8(%rbp), %rsi
movq -0x1e0(%rbp), %rcx
leaq -0x80(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x34a60
jmp 0x5cd2b
leaq -0xa5(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x35a40
movq -0x1e8(%rbp), %rsi
movq -0x1f8(%rbp), %rcx
leaq -0x68(%rbp), %rdi
leaq -0x80(%rbp), %rdx
callq 0x35a60
jmp 0x5cd5b
movq -0x1f0(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x35a10
jmp 0x5cd6d
leaq -0x68(%rbp), %rdi
callq 0x35ae0
leaq -0xa5(%rbp), %rdi
callq 0x35b40
leaq -0x80(%rbp), %rdi
callq 0x34b10
leaq -0x91(%rbp), %rdi
callq 0x34b70
movq -0x1d8(%rbp), %rax
movq %rax, %rcx
addq $0x18, %rcx
movq %rcx, -0x210(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x6840(%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 -0x1c6(%rbp)
movzwl -0x1c6(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x1c8(%rbp)
fldcw -0x1c8(%rbp)
fxch %st(1)
fistpll -0x1c0(%rbp)
fldcw -0x1c6(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x1c0(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x208(%rbp)
fstpt -0xf0(%rbp)
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x34a40
movq -0x208(%rbp), %rsi
movq -0x200(%rbp), %rcx
leaq -0xd8(%rbp), %rdi
leaq -0xf0(%rbp), %rdx
callq 0x34a60
jmp 0x5ce53
leaq -0xf2(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0x35a40
movq -0x208(%rbp), %rsi
movq -0x218(%rbp), %rcx
leaq -0xc0(%rbp), %rdi
leaq -0xd8(%rbp), %rdx
callq 0x35a60
jmp 0x5ce89
movq -0x210(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x35a10
jmp 0x5ce9e
leaq -0xc0(%rbp), %rdi
callq 0x35ae0
leaq -0xf2(%rbp), %rdi
callq 0x35b40
leaq -0xd8(%rbp), %rdi
callq 0x34b10
leaq -0xf1(%rbp), %rdi
callq 0x34b70
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x5cc5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5cf34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5cf1f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x35ae0
leaq -0xa5(%rbp), %rdi
callq 0x35b40
leaq -0x80(%rbp), %rdi
callq 0x34b10
leaq -0x91(%rbp), %rdi
callq 0x34b70
jmp 0x5d563
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5cfa3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5cf8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x35ae0
leaq -0xf2(%rbp), %rdi
callq 0x35b40
leaq -0xd8(%rbp), %rdi
callq 0x34b10
leaq -0xf1(%rbp), %rdi
callq 0x34b70
jmp 0x5d563
movq -0x1d8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x5adf0
cmpl $0x0, %eax
jge 0x5cfd9
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x5d557
movq -0x1d8(%rbp), %rax
movzbl 0xb0(%rax), %ecx
movq %rcx, -0x230(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x65fe(%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 -0x1ca(%rbp)
movzwl -0x1ca(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x1cc(%rbp)
fldcw -0x1cc(%rbp)
fxch %st(1)
fistpll -0x1a0(%rbp)
fldcw -0x1ca(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x1a0(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x228(%rbp)
fstpt -0x140(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x220(%rbp)
callq 0x34a40
movq -0x228(%rbp), %rsi
movq -0x220(%rbp), %rcx
leaq -0x128(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0x34a60
jmp 0x5d095
leaq -0x142(%rbp), %rdi
movq %rdi, -0x238(%rbp)
callq 0x35a40
movq -0x230(%rbp), %rsi
movq -0x238(%rbp), %rcx
leaq -0x110(%rbp), %rdi
leaq -0x128(%rbp), %rdx
callq 0x35a60
jmp 0x5d0cb
movq -0x1d8(%rbp), %rdi
addq $0x30, %rdi
leaq -0x110(%rbp), %rsi
movq %rsi, -0x258(%rbp)
callq 0x5d930
movq -0x258(%rbp), %rdi
callq 0x35ae0
leaq -0x142(%rbp), %rdi
callq 0x35b40
leaq -0x128(%rbp), %rdi
callq 0x34b10
leaq -0x141(%rbp), %rdi
callq 0x34b70
movq -0x1d8(%rbp), %rax
movzbl 0xb0(%rax), %ecx
movq %rcx, -0x250(%rbp)
fldt 0x90(%rax)
fld1
faddp %st, %st(1)
flds 0x64be(%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 -0x1ce(%rbp)
movzwl -0x1ce(%rbp), %ecx
orl $0xc00, %ecx            # imm = 0xC00
movw %cx, -0x1d0(%rbp)
fldcw -0x1d0(%rbp)
fxch %st(1)
fistpll -0x1a8(%rbp)
fldcw -0x1ce(%rbp)
movzbl %al, %eax
movl %eax, %ecx
shlq $0x3f, %rcx
movq -0x1a8(%rbp), %rax
xorq %rcx, %rax
movq %rax, -0x248(%rbp)
fstpt -0x190(%rbp)
leaq -0x191(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x34a40
movq -0x248(%rbp), %rsi
movq -0x240(%rbp), %rcx
leaq -0x178(%rbp), %rdi
leaq -0x190(%rbp), %rdx
callq 0x34a60
jmp 0x5d1d5
leaq -0x192(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x35a40
movq -0x250(%rbp), %rsi
movq -0x260(%rbp), %rcx
leaq -0x160(%rbp), %rdi
leaq -0x178(%rbp), %rdx
callq 0x35a60
jmp 0x5d20b
movq -0x1d8(%rbp), %rdi
addq $0x48, %rdi
leaq -0x160(%rbp), %rsi
callq 0x5d930
leaq -0x160(%rbp), %rdi
callq 0x35ae0
leaq -0x192(%rbp), %rdi
callq 0x35b40
leaq -0x178(%rbp), %rdi
callq 0x34b10
leaq -0x191(%rbp), %rdi
callq 0x34b70
movb $0x0, -0x193(%rbp)
movq -0x1d8(%rbp), %rcx
movzbl -0x193(%rbp), %eax
movzbl 0xb0(%rcx), %ecx
cmpl %ecx, %eax
jge 0x5d413
movzbl -0x193(%rbp), %eax
movl %eax, -0x29c(%rbp)
movq -0x18(%rbp), %rcx
movq %rcx, -0x298(%rbp)
movq -0x38(%rbp), %rcx
movq %rcx, -0x290(%rbp)
movq -0x40(%rbp), %rdi
movl %eax, %esi
callq 0x358a0
movq -0x1d8(%rbp), %rdi
movl -0x29c(%rbp), %esi
movq -0x298(%rbp), %rdx
movq -0x290(%rbp), %rcx
movq %rax, %r8
callq 0x5bfd0
fldt -0x30(%rbp)
fstpt -0x284(%rbp)
movq -0x40(%rbp), %rdi
movzbl -0x193(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x34c70
fldt -0x284(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt (%rax)
fldt -0x30(%rbp)
fstpt -0x278(%rbp)
movq -0x40(%rbp), %rdi
movzbl -0x193(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movl $0x1, %esi
callq 0x34c70
fldt -0x278(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt (%rax)
fldt -0x30(%rbp)
fstpt -0x26c(%rbp)
movq -0x40(%rbp), %rdi
movzbl -0x193(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movl $0x2, %esi
callq 0x34c70
fldt -0x26c(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt (%rax)
movb -0x193(%rbp), %al
addb $0x1, %al
movb %al, -0x193(%rbp)
jmp 0x5d259
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5d3b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x142(%rbp), %rdi
callq 0x35b40
leaq -0x128(%rbp), %rdi
callq 0x34b10
leaq -0x141(%rbp), %rdi
callq 0x34b70
jmp 0x5d563
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5d402
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x192(%rbp), %rdi
callq 0x35b40
leaq -0x178(%rbp), %rdi
callq 0x34b10
leaq -0x191(%rbp), %rdi
callq 0x34b70
jmp 0x5d563
movb $0x0, -0x194(%rbp)
movq -0x1d8(%rbp), %rcx
movzbl -0x194(%rbp), %eax
movzbl 0xb0(%rcx), %ecx
cmpl %ecx, %eax
jge 0x5d514
movb -0x194(%rbp), %al
movb %al, -0x29d(%rbp)
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35850
movq %rax, %rdi
movzbl -0x194(%rbp), %eax
movl %eax, %esi
callq 0x358e0
movq -0x1d8(%rbp), %rdi
movq %rax, %rcx
movb -0x29d(%rbp), %al
movq (%rcx), %rdx
movq -0x20(%rbp), %rcx
movq -0x38(%rbp), %r8
movq -0x48(%rbp), %r9
movzbl %al, %esi
callq 0x5aec0
movb $0x0, -0x195(%rbp)
movq -0x1d8(%rbp), %rax
movzbl -0x195(%rbp), %ecx
movl %ecx, -0x1ac(%rbp)
fildl -0x1ac(%rbp)
fldt 0x90(%rax)
fucompi %st(1), %st
fstp %st(0)
jb 0x5d4ff
jmp 0x5d4b7
fldt -0x30(%rbp)
fstpt -0x2a8(%rbp)
movq -0x48(%rbp), %rdi
movzbl -0x194(%rbp), %eax
movl %eax, %esi
callq 0x358a0
movq %rax, %rdi
movzbl -0x195(%rbp), %eax
movl %eax, %esi
callq 0x34c70
fldt -0x2a8(%rbp)
fldt (%rax)
fmulp %st, %st(1)
fstpt (%rax)
movb -0x195(%rbp), %al
addb $0x1, %al
movb %al, -0x195(%rbp)
jmp 0x5d48f
jmp 0x5d501
movb -0x194(%rbp), %al
addb $0x1, %al
movb %al, -0x194(%rbp)
jmp 0x5d41a
movq -0x1d8(%rbp), %rdi
callq 0x5d960
movq -0x1d8(%rbp), %rdi
addq $0x18, %rdi
callq 0x5d960
movq -0x1d8(%rbp), %rdi
addq $0x30, %rdi
callq 0x5d980
movq -0x1d8(%rbp), %rdi
addq $0x48, %rdi
callq 0x5d980
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
movq -0xa0(%rbp), %rdi
callq 0x5920
nop