// File: /workspace/github_cpp_makefile_star2_O3/millanek[P]evo/./process_vcf_stats_utils.h
// Function: fisher_exact(int, int, int, int)
inline double fisher_exact(int a, int b, int c, int d) {
    
    std::vector<int> mTotals;
    int r1 = a + b; int r2 = c + d;
    int c1 = a + c; int c2 = b + d;
    mTotals.push_back(r1); mTotals.push_back(r2); mTotals.push_back(c1); mTotals.push_back(c2);
    int m = std::min(std::min(r1, r2), std::min(c1,c2)); // The smallest margin total
    // int min_index = (int)(std::min_element(mTotals.begin(), mTotals.end()) - mTotals.begin()); // Position of the ssmallest margin total
    
    std::vector<double> allPvals;
    if (m == c2) {
        for (int i = 0; i <= m; i++) {
            double thisP = fisher_exactTable(r1-i,i,r2-(m-i),m-i);
            allPvals.push_back(thisP);
        }
    } else if (m == c1) {
        for (int i = 0; i <= m; i++) {
            double thisP = fisher_exactTable(i,r1-i,m-i,r2-(m-i));
            allPvals.push_back(thisP);
        }
    } else if (m == r2) {
        for (int i = 0; i <= m; i++) {
            double thisP = fisher_exactTable(c1-(m-i),c2-i,m-i,i);
            allPvals.push_back(thisP);
        }
    } else if (m == r1){
        for (int i = 0; i <= m; i++) {
            double thisP = fisher_exactTable(m-i,i,c1-(m-i),c2-i);
            allPvals.push_back(thisP);
        }
    } else {
        std::cerr << "a: " << a << " b: " << b << std::endl;
        std::cerr << "c: " << c << " d: " << d << std::endl;
        std::cerr << "m: " << m << " c1: " << c1 << " c2: " << c2 << " r1: " << r1 << " r2: " << r2 << std::endl;
        assert(false);
    }
    
    double thisTablePval = fisher_exactTable(a,b,c,d);
    double p = 0;
    for (std::vector<double>::size_type i = 0; i != allPvals.size(); i++) {
        if (allPvals[i] <= thisTablePval) {
            p += allPvals[i];
        }
    }
    /*if (m == r2) {
        std::cerr << "a: " << a << " b: " << b << std::endl;
        std::cerr << "c: " << c << " d: " << d << std::endl;
        std::cerr << "p: " << p << std::endl;
    } */
    
//    std::cerr << "this pval:" << thisTablePval << std::endl;
//    print_vector_stream(allPvals, std::cerr);
    return p;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movl %ecx, %ebx
movl %edx, %r14d
movl %esi, %r15d
movl %edi, %r12d
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
leal (%r15,%r12), %eax
leaq 0x14(%rsp), %rdx
movl %eax, (%rdx)
leal (%rbx,%r14), %eax
movl %eax, 0x10(%rsp)
leal (%r14,%r12), %eax
movl %eax, 0xc(%rsp)
leal (%rbx,%r15), %eax
movl %eax, 0x8(%rsp)
xorl %esi, %esi
callq 0x48c2e
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rax
cmpq %rax, %rsi
je 0x982d6
movl 0x10(%rsp), %ecx
movl %ecx, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x982ef
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x48c2e
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rax
cmpq %rax, %rsi
je 0x98305
movl 0xc(%rsp), %ecx
movl %ecx, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x9831e
leaq 0x40(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x48c2e
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rax
cmpq %rax, %rsi
movq %rbx, 0x60(%rsp)
movq %r14, 0x80(%rsp)
movq %r15, 0x78(%rsp)
movq %r12, 0x70(%rsp)
je 0x9834d
movl 0x8(%rsp), %r14d
movl %r14d, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x98361
leaq 0x40(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x48c2e
movl 0x8(%rsp), %r14d
movl 0x10(%rsp), %r15d
movl 0x14(%rsp), %r13d
movl 0xc(%rsp), %r12d
cmpl %r12d, %r14d
movl %r12d, %eax
cmovll %r14d, %eax
cmpl %r13d, %r15d
movl %r13d, %ebp
cmovll %r15d, %ebp
cmpl %ebp, %eax
cmovll %eax, %ebp
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
cmpl %r14d, %ebp
jne 0x98415
testl %r14d, %r14d
js 0x98579
leal 0x1(%r14), %r15d
movl %r14d, %r12d
negl %r12d
xorl %r13d, %r13d
leaq 0x18(%rsp), %rbp
xorl %ebx, %ebx
movl 0x14(%rsp), %edi
addl %r13d, %edi
leal (%r14,%r13), %ecx
leal (%r12,%rbx), %edx
addl 0x10(%rsp), %edx
movl %ebx, %esi
callq 0x99566
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x983f9
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98406
leaq 0x20(%rsp), %rdi
movq %rbp, %rdx
callq 0x79b8e
incl %ebx
decl %r13d
cmpl %ebx, %r15d
jne 0x983be
jmp 0x98579
cmpl %r12d, %ebp
jne 0x9848f
testl %r12d, %r12d
js 0x98579
leal 0x1(%r12), %r14d
movl %r12d, %r15d
negl %r15d
xorl %r13d, %r13d
leaq 0x18(%rsp), %rbp
xorl %ebx, %ebx
movl 0x14(%rsp), %esi
addl %r13d, %esi
leal (%r12,%r13), %edx
leal (%r15,%rbx), %ecx
addl 0x10(%rsp), %ecx
movl %ebx, %edi
callq 0x99566
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98473
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98480
leaq 0x20(%rsp), %rdi
movq %rbp, %rdx
callq 0x79b8e
incl %ebx
decl %r13d
cmpl %ebx, %r14d
jne 0x98438
jmp 0x98579
cmpl %r15d, %ebp
jne 0x98505
testl %r15d, %r15d
js 0x98579
leal 0x1(%r15), %r14d
movl %r15d, %r12d
negl %r12d
xorl %r13d, %r13d
leaq 0x18(%rsp), %rbp
xorl %ebx, %ebx
leal (%r15,%r13), %edx
leal (%r12,%rbx), %edi
addl 0xc(%rsp), %edi
movl 0x8(%rsp), %esi
addl %r13d, %esi
movl %ebx, %ecx
callq 0x99566
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x984ec
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x984f9
leaq 0x20(%rsp), %rdi
movq %rbp, %rdx
callq 0x79b8e
incl %ebx
decl %r13d
cmpl %ebx, %r14d
jne 0x984b1
jmp 0x98579
cmpl %r13d, %ebp
jne 0x98639
testl %r13d, %r13d
js 0x98579
leal 0x1(%r13), %r15d
movl %r13d, %r12d
negl %r12d
xorl %r14d, %r14d
leaq 0x18(%rsp), %rbp
xorl %ebx, %ebx
leal (%r14,%r13), %edi
leal (%r12,%rbx), %edx
addl 0xc(%rsp), %edx
movl 0x8(%rsp), %ecx
addl %r14d, %ecx
movl %ebx, %esi
callq 0x99566
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98562
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x9856f
leaq 0x20(%rsp), %rdi
movq %rbp, %rdx
callq 0x79b8e
incl %ebx
decl %r14d
cmpl %ebx, %r15d
jne 0x98527
movq 0x70(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq 0x60(%rsp), %rcx
callq 0x99566
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
subq %rdi, %rax
je 0x985de
sarq $0x3, %rax
xorpd %xmm1, %xmm1
xorl %ecx, %ecx
movsd (%rdi,%rcx,8), %xmm4
movapd %xmm1, %xmm2
addsd %xmm4, %xmm2
cmpnlesd %xmm0, %xmm4
movapd %xmm4, %xmm3
andnpd %xmm2, %xmm3
andpd %xmm1, %xmm4
orpd %xmm3, %xmm4
incq %rcx
movapd %xmm4, %xmm1
cmpq %rcx, %rax
jne 0x985ae
jmp 0x985e7
xorpd %xmm4, %xmm4
testq %rdi, %rdi
je 0x98600
movapd %xmm4, 0x60(%rsp)
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movapd 0x60(%rsp), %xmm4
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x98623
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
movapd %xmm4, 0x60(%rsp)
callq 0x8480
movapd 0x60(%rsp), %xmm4
movapd %xmm4, %xmm0
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x699a8(%rip), %rdi     # 0x101fe8
leaq 0x43667(%rip), %rsi     # 0xdbcae
movl $0x3, %edx
callq 0x84e0
movq 0x69990(%rip), %rdi     # 0x101fe8
movq 0x70(%rsp), %rsi
callq 0x8810
movq %rax, %rbx
leaq 0x43646(%rip), %rsi     # 0xdbcb2
movl $0x4, %edx
movq %rax, %rdi
callq 0x84e0
movq %rbx, %rdi
movq 0x78(%rsp), %rsi
callq 0x8810
movq %rax, %rdi
callq 0x8200
movq 0x69953(%rip), %rdi     # 0x101fe8
leaq 0x3a9c0(%rip), %rsi     # 0xd305c
movl $0x3, %edx
callq 0x84e0
movq 0x6993b(%rip), %rdi     # 0x101fe8
movq 0x80(%rsp), %rsi
callq 0x8810
movq %rax, %rbx
leaq 0x435f3(%rip), %rsi     # 0xdbcb7
movl $0x4, %edx
movq %rax, %rdi
callq 0x84e0
movq %rbx, %rdi
movq 0x60(%rsp), %rsi
callq 0x8810
movq %rax, %rdi
callq 0x8200
movq 0x698fb(%rip), %rdi     # 0x101fe8
leaq 0x3f36c(%rip), %rsi     # 0xd7a60
movl $0x3, %edx
callq 0x84e0
movq 0x698e3(%rip), %rdi     # 0x101fe8
movl %ebp, %esi
callq 0x8810
movq %rax, %rbx
leaq 0x435a6(%rip), %rsi     # 0xdbcbc
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x43589(%rip), %rsi     # 0xdbcc2
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x8(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x4356c(%rip), %rsi     # 0xdbcc8
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x14(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x4354f(%rip), %rsi     # 0xdbcce
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x10(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rdi
callq 0x8200
leaq 0x36a12(%rip), %rdi     # 0xcf1b9
leaq 0x37eeb(%rip), %rsi     # 0xd0699
leaq 0x4351f(%rip), %rcx     # 0xdbcd4
movl $0xd7, %edx
callq 0x82c0
jmp 0x987ce
jmp 0x987ce
movq %rax, %rbx
jmp 0x987e8
jmp 0x987ce
jmp 0x987ce
jmp 0x987ce
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x987e8
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x987ff
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movq %rbx, %rdi
callq 0x8840