// File: /workspace/github_cpp_makefile_star2_O1/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
movapd %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
leal (%r15,%r12), %eax
movl %eax, 0x14(%rsp)
leal (%rbx,%r14), %ecx
movl %ecx, 0x10(%rsp)
leal (%r14,%r12), %ecx
movl %ecx, 0xc(%rsp)
leal (%rbx,%r15), %ecx
movl %ecx, 0x8(%rsp)
movq 0x48(%rsp), %rsi
testq %rsi, %rsi
je 0x98d2b
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x98d3a
leaq 0x40(%rsp), %rdi
leaq 0x14(%rsp), %rdx
callq 0x4bc3a
movq 0x48(%rsp), %rsi
cmpq 0x50(%rsp), %rsi
je 0x98d57
movl 0x10(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x98d66
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x4bc3a
movq 0x48(%rsp), %rsi
cmpq 0x50(%rsp), %rsi
je 0x98d83
movl 0xc(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x98d92
leaq 0x40(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x4bc3a
movq 0x48(%rsp), %rsi
cmpq 0x50(%rsp), %rsi
je 0x98daf
movl 0x8(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%rsp)
jmp 0x98dbe
leaq 0x40(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x4bc3a
movq %r12, 0x60(%rsp)
movq %r15, 0x70(%rsp)
movq %r14, 0x78(%rsp)
movq %rbx, 0x80(%rsp)
movl 0x10(%rsp), %ecx
movl 0x14(%rsp), %eax
movl 0x8(%rsp), %esi
movl 0xc(%rsp), %edx
cmpl %edx, %esi
movl %edx, %edi
cmovll %esi, %edi
cmpl %eax, %ecx
movl %eax, %r12d
cmovll %ecx, %r12d
cmpl %r12d, %edi
cmovll %edi, %r12d
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
cmpl %esi, %r12d
jne 0x98e89
testl %r12d, %r12d
js 0x98fef
leal 0x1(%r12), %r15d
movl %r12d, %r13d
negl %r13d
xorl %ebp, %ebp
leaq 0x18(%rsp), %rbx
xorl %r14d, %r14d
movl 0x14(%rsp), %edi
addl %ebp, %edi
leal (%r12,%rbp), %ecx
leal (%r14,%r13), %edx
addl 0x10(%rsp), %edx
movl %r14d, %esi
callq 0x99ff0
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98e6d
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98e7a
leaq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0x79f34
incl %r14d
decl %ebp
cmpl %r14d, %r15d
jne 0x98e32
jmp 0x98fef
cmpl %edx, %r12d
jne 0x98f03
testl %r12d, %r12d
js 0x98fef
leal 0x1(%r12), %r15d
movl %r12d, %r13d
negl %r13d
xorl %ebp, %ebp
leaq 0x18(%rsp), %rbx
xorl %r14d, %r14d
movl 0x14(%rsp), %esi
addl %ebp, %esi
leal (%r12,%rbp), %edx
leal (%r14,%r13), %ecx
addl 0x10(%rsp), %ecx
movl %r14d, %edi
callq 0x99ff0
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98ee7
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98ef4
leaq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0x79f34
incl %r14d
decl %ebp
cmpl %r14d, %r15d
jne 0x98eac
jmp 0x98fef
cmpl %ecx, %r12d
jne 0x98f7a
testl %r12d, %r12d
js 0x98fef
leal 0x1(%r12), %r15d
movl %r12d, %r13d
negl %r13d
xorl %ebp, %ebp
leaq 0x18(%rsp), %rbx
xorl %r14d, %r14d
leal (%r12,%rbp), %edx
leal (%r14,%r13), %edi
addl 0xc(%rsp), %edi
movl 0x8(%rsp), %esi
addl %ebp, %esi
movl %r14d, %ecx
callq 0x99ff0
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98f61
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98f6e
leaq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0x79f34
incl %r14d
decl %ebp
cmpl %r14d, %r15d
jne 0x98f26
jmp 0x98fef
cmpl %eax, %r12d
jne 0x990a9
testl %r12d, %r12d
js 0x98fef
leal 0x1(%r12), %r15d
movl %r12d, %r13d
negl %r13d
xorl %ebp, %ebp
leaq 0x18(%rsp), %rbx
xorl %r14d, %r14d
leal (%r12,%rbp), %edi
leal (%r14,%r13), %edx
addl 0xc(%rsp), %edx
movl 0x8(%rsp), %ecx
addl %ebp, %ecx
movl %r14d, %esi
callq 0x99ff0
movsd %xmm0, 0x18(%rsp)
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x98fd8
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x98fe5
leaq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0x79f34
incl %r14d
decl %ebp
cmpl %r14d, %r15d
jne 0x98f9d
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq 0x80(%rsp), %rcx
callq 0x99ff0
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
subq %rdi, %rax
je 0x99054
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 0x99024
jmp 0x99058
xorpd %xmm4, %xmm4
testq %rdi, %rdi
movapd %xmm4, 0x60(%rsp)
je 0x99076
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movapd 0x60(%rsp), %xmm4
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x99093
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
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 0x71f38(%rip), %rdi     # 0x10afe8
leaq 0x4a607(%rip), %rsi     # 0xe36be
movl $0x3, %edx
callq 0x84e0
movq 0x71f20(%rip), %rdi     # 0x10afe8
movq 0x60(%rsp), %rsi
callq 0x8810
movq %rax, %rbx
leaq 0x4a5e6(%rip), %rsi     # 0xe36c2
movl $0x4, %edx
movq %rax, %rdi
callq 0x84e0
movq %rbx, %rdi
movq 0x70(%rsp), %rsi
callq 0x8810
movq %rax, %rdi
callq 0x8200
movq 0x71ee3(%rip), %rdi     # 0x10afe8
leaq 0x40410(%rip), %rsi     # 0xd951c
movl $0x3, %edx
callq 0x84e0
movq 0x71ecb(%rip), %rdi     # 0x10afe8
movq 0x78(%rsp), %rsi
callq 0x8810
movq %rax, %rbx
leaq 0x4a596(%rip), %rsi     # 0xe36c7
movl $0x4, %edx
movq %rax, %rdi
callq 0x84e0
movq %rbx, %rdi
movq 0x80(%rsp), %rsi
callq 0x8810
movq %rax, %rdi
callq 0x8200
movq 0x71e8b(%rip), %rdi     # 0x10afe8
leaq 0x4631c(%rip), %rsi     # 0xdf480
movl $0x3, %edx
callq 0x84e0
movq 0x71e73(%rip), %rdi     # 0x10afe8
movl %r12d, %esi
callq 0x8810
movq %rax, %rbx
leaq 0x4a545(%rip), %rsi     # 0xe36cc
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x4a528(%rip), %rsi     # 0xe36d2
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x8(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x4a50b(%rip), %rsi     # 0xe36d8
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x14(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rbx
leaq 0x4a4ee(%rip), %rsi     # 0xe36de
movl $0x5, %edx
movq %rax, %rdi
callq 0x84e0
movl 0x10(%rsp), %esi
movq %rbx, %rdi
callq 0x8810
movq %rax, %rdi
callq 0x8200
leaq 0x3cd35(%rip), %rdi     # 0xd5f4d
leaq 0x3df4e(%rip), %rsi     # 0xd716d
leaq 0x4a4be(%rip), %rcx     # 0xe36e4
movl $0xd7, %edx
callq 0x82c0
jmp 0x9923f
jmp 0x9923f
movq %rax, %rbx
jmp 0x99259
jmp 0x9923f
jmp 0x9923f
jmp 0x9923f
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x99259
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x99270
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x8480
movq %rbx, %rdi
callq 0x8840