// File: /workspace/github_cpp_makefile_star2_O2/millanek[P]evo/process_vcf_utils.cpp
// Function: calculateChiSqPvalForInbreeding(std::vector<int, std::allocator<int>>&)
double calculateChiSqPvalForInbreeding(std::vector<int>& individualsWithVariant) {
    // Get the observed numbers of genotypes
    int naa = 0; int nAa = 0; int nAA = 0;
    for (std::vector<int>::size_type i = 0; i != individualsWithVariant.size(); i++) {
        if (individualsWithVariant[i] == 0) naa++;
        if (individualsWithVariant[i] == 1) nAa++;
        if (individualsWithVariant[i] == 2) nAA++;
    }
    
    // Get the observed proportions of alt-hom and hets
    double pAA = (double)nAA / individualsWithVariant.size();
    double pAa = (double)nAa / individualsWithVariant.size();
    // Allele frequencies
    double p = pAA + (0.5 * pAa);
    double q = 1 - p;
    // Get the Hardy-Weinberg prediction for expected proportion of heterozygotes:
    double HWAa = 2*p*q;
    
    // Get the expected numbers of genotypes:
    double expAA = pow(p, 2) * individualsWithVariant.size();
    double expAa = HWAa * individualsWithVariant.size();
    double expaa = pow(q, 2) * individualsWithVariant.size();
    
    // Perform the chi-Sqared test
    std::vector<double> observed{static_cast<double>(nAA),static_cast<double>(nAa),static_cast<double>(naa)};
    std::vector<double> expected{expAA,expAa,expaa};
    double pVal = pearson_chi_sq_goodness_of_fit(observed, expected, 1);
    return pVal;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0xc8, %rsp
movq (%rdi), %rdx
movq 0x8(%rdi), %rcx
subq %rdx, %rcx
sarq $0x2, %rcx
pxor %xmm0, %xmm0
xorl %esi, %esi
movq 0x5e9f3(%rip), %xmm1    # 0x9f030
xorl %eax, %eax
cmpq %rsi, %rcx
je 0x40663
movl (%rdx,%rsi,4), %edi
cmpl $0x1, %edi
adcl $0x0, %eax
movd %edi, %xmm2
pshufd $0x50, %xmm2, %xmm2     # xmm2 = xmm2[0,0,1,1]
pcmpeqd %xmm1, %xmm2
psubd %xmm2, %xmm0
incq %rsi
jmp 0x4063f
cvtdq2pd %xmm0, %xmm0
movq %rcx, %xmm1
punpckldq 0x51bcc(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x51bd4(%rip), %xmm1    # 0x92250
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addpd %xmm1, %xmm2
movapd %xmm2, 0xa0(%rsp)
movapd %xmm0, %xmm1
leaq 0x20(%rsp), %rsi
movapd %xmm0, (%rsi)
divsd %xmm2, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
divsd %xmm2, %xmm1
mulsd 0x56f4e(%rip), %xmm1    # 0x97600
addsd %xmm0, %xmm1
movapd %xmm1, 0x90(%rsp)
movsd 0x56f29(%rip), %xmm0    # 0x975f0
subsd %xmm1, %xmm0
movapd %xmm0, 0x10(%rsp)
mulsd %xmm0, %xmm0
movapd %xmm0, 0x80(%rsp)
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsi)
leaq 0x68(%rsp), %rdi
pushq $0x3
popq %rbx
leaq 0xb0(%rsp), %r14
movq %rbx, %rdx
movq %r14, %rcx
callq 0x438f6
movapd 0xa0(%rsp), %xmm3
movapd 0x80(%rsp), %xmm4
mulsd %xmm3, %xmm4
movapd 0x90(%rsp), %xmm2
movapd %xmm2, %xmm0
addsd %xmm2, %xmm0
movapd %xmm2, %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
unpcklpd 0x10(%rsp), %xmm2       # xmm2 = xmm2[0],mem[0]
mulpd %xmm1, %xmm2
movapd %xmm3, %xmm0
unpcklpd %xmm3, %xmm0            # xmm0 = xmm0[0],xmm3[0]
mulpd %xmm2, %xmm0
movapd %xmm0, (%r14)
movsd %xmm4, 0x10(%r14)
leaq 0x20(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0xf(%rsp), %rcx
movq %rbx, %rdx
callq 0x438f6
leaq 0x50(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x2f816
leaq 0x38(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x2f816
leaq 0x50(%rsp), %rdi
leaq 0x38(%rsp), %rsi
pushq $0x1
popq %rcx
movl %ecx, %edx
callq 0x4392c
movsd %xmm0, 0x10(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x2b43c
leaq 0x50(%rsp), %rdi
callq 0x2b43c
leaq 0x20(%rsp), %rdi
callq 0x2b43c
leaq 0x68(%rsp), %rdi
callq 0x2b43c
movsd 0x10(%rsp), %xmm0
addq $0xc8, %rsp
popq %rbx
popq %r14
retq
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x2b43c
jmp 0x407ef
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x2b43c
jmp 0x407fe
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x2b43c
jmp 0x4080d
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x2b43c
movq %rbx, %rdi
callq 0x8870