// File: /workspace/github_c_makefile_star2_O3/xiongxu[P]bam2bedGraph2/samtools-0.1.19/bcftools/em.c
// Function: bcf_pair_freq
double bcf_pair_freq(const bcf1_t *b0, const bcf1_t *b1, double f[4])
{
	const bcf1_t *b[2];
	int i, j, n_smpl;
	double *pdg[2], flast[4], r, f0[2];
	// initialize others
	if (b0->n_smpl != b1->n_smpl) return -1; // different number of samples
	n_smpl = b0->n_smpl;
	b[0] = b0; b[1] = b1;
	f[0] = f[1] = f[2] = f[3] = -1.;
	if (b[0]->n_alleles < 2 || b[1]->n_alleles < 2) return -1; // one allele only
	pdg[0] = get_pdg3(b0); pdg[1] = get_pdg3(b1);
	if (pdg[0] == 0 || pdg[1] == 0) {
		free(pdg[0]); free(pdg[1]);
		return -1;
	}
	// set the initial value
	f0[0] = est_freq(n_smpl, pdg[0]);
	f0[1] = est_freq(n_smpl, pdg[1]);
	f[0] = (1 - f0[0]) * (1 - f0[1]); f[3] = f0[0] * f0[1];
	f[1] = (1 - f0[0]) * f0[1]; f[2] = f0[0] * (1 - f0[1]);
	// iteration
	for (j = 0; j < ITER_MAX; ++j) {
		double eps = 0;
		memcpy(flast, f, 4 * sizeof(double));
		pair_freq_iter(n_smpl, pdg, f);
		for (i = 0; i < 4; ++i) {
			double x = fabs(f[i] - flast[i]);
			if (x > eps) eps = x;
		}
		if (eps < EPS) break;
	}
	// free
	free(pdg[0]); free(pdg[1]);
	{ // calculate r^2
		double p[2], q[2], D;
		p[0] = f[0] + f[1]; q[0] = 1 - p[0];
		p[1] = f[0] + f[2]; q[1] = 1 - p[1];
		D = f[0] * f[3] - f[1] * f[2];
		r = sqrt(D * D / (p[0] * p[1] * q[0] * q[1]));
//		printf("R(%lf,%lf,%lf,%lf)=%lf\n", f[0], f[1], f[2], f[3], r);
		if (isnan(r)) r = -1.;
	}
	return r;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl 0x5c(%rdi), %r14d
movsd 0x344a(%rip), %xmm2     # 0x19098
cmpl 0x5c(%rsi), %r14d
jne 0x15f81
movq %rdx, %rbx
movapd 0x58bd(%rip), %xmm0     # 0x1b520
movupd %xmm0, 0x10(%rdx)
movupd %xmm0, (%rdx)
cmpl $0x2, 0x58(%rdi)
jl 0x15f81
movq %rsi, %r15
cmpl $0x2, 0x58(%rsi)
jl 0x15f81
callq 0x1573d
movq %rax, %r12
movq %r15, %rdi
callq 0x1573d
movq %rax, %r15
testq %r12, %r12
setne %al
testq %r15, %r15
setne %cl
testb %cl, %al
jne 0x15cc3
movq %r12, %rdi
callq 0x2060
movq %r15, %rdi
callq 0x2060
movsd 0x33da(%rip), %xmm2     # 0x19098
jmp 0x15f81
movl %r14d, %edi
movq %r12, %rsi
callq 0x15849
movapd %xmm0, 0x20(%rsp)
movl %r14d, %edi
movq %r15, %rsi
callq 0x15849
movsd 0x3391(%rip), %xmm1     # 0x19078
movapd %xmm1, %xmm2
movapd 0x20(%rsp), %xmm3
subsd %xmm3, %xmm2
subsd %xmm0, %xmm1
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
mulpd %xmm1, %xmm2
movupd %xmm2, (%rbx)
movapd %xmm3, %xmm0
unpcklpd %xmm3, %xmm0            # xmm0 = xmm0[0],xmm3[0]
mulpd %xmm1, %xmm0
movupd %xmm0, 0x10(%rbx)
leal (%r14,%r14), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
xorl %eax, %eax
xorpd %xmm1, %xmm1
movapd 0x5a49(%rip), %xmm2     # 0x1b780
movsd 0x5a51(%rip), %xmm3     # 0x1b790
movupd (%rbx), %xmm4
movupd 0x10(%rbx), %xmm5
movapd %xmm5, 0x40(%rsp)
movapd %xmm4, 0x30(%rsp)
movapd %xmm1, 0x10(%rsp)
movapd %xmm1, (%rsp)
testl %r14d, %r14d
jle 0x15e98
movsd (%rbx), %xmm4
movsd 0x8(%rbx), %xmm5
movsd 0x10(%rbx), %xmm6
movsd 0x18(%rbx), %xmm7
xorl %ecx, %ecx
leaq (,%rcx,8), %rdx
leaq (%rdx,%rdx,2), %rdx
leaq (%r12,%rdx), %rsi
addq %r15, %rdx
xorpd %xmm8, %xmm8
xorl %edi, %edi
movsd (%rbx,%rdi,8), %xmm9
movl %edi, %r8d
shrl %r8d
movl %edi, %r9d
andl $0x1, %r9d
leaq (%rdx,%r9,8), %r9
xorl %r10d, %r10d
movsd (%rbx,%r10,8), %xmm10
mulsd %xmm9, %xmm10
movl %r10d, %r11d
shrl %r11d
addl %r8d, %r11d
mulsd (%rsi,%r11,8), %xmm10
movl %r10d, %r11d
andl $0x1, %r11d
mulsd (%r9,%r11,8), %xmm10
addsd %xmm10, %xmm8
incq %r10
cmpq $0x4, %r10
jne 0x15db1
incq %rdi
cmpq $0x4, %rdi
jne 0x15d97
xorl %edi, %edi
movl %edi, %r8d
shrl %r8d
movl %edi, %r9d
andl $0x1, %r9d
movsd (%rdx,%r9,8), %xmm10
movsd 0x8(%rdx,%r9,8), %xmm9
movsd (%rsi,%r8,8), %xmm11
movsd 0x8(%rsi,%r8,8), %xmm12
movapd %xmm11, %xmm13
mulsd %xmm10, %xmm13
addsd %xmm13, %xmm13
mulsd %xmm4, %xmm13
mulsd %xmm9, %xmm11
addsd %xmm11, %xmm11
mulsd %xmm5, %xmm11
addsd %xmm13, %xmm11
mulsd %xmm12, %xmm10
addsd %xmm10, %xmm10
mulsd %xmm6, %xmm10
addsd %xmm11, %xmm10
mulsd %xmm12, %xmm9
addsd %xmm9, %xmm9
mulsd %xmm7, %xmm9
addsd %xmm10, %xmm9
mulsd (%rbx,%rdi,8), %xmm9
divsd %xmm8, %xmm9
addsd (%rsp,%rdi,8), %xmm9
movsd %xmm9, (%rsp,%rdi,8)
incq %rdi
cmpq $0x4, %rdi
jne 0x15df1
incq %rcx
cmpq %r14, %rcx
jne 0x15d7d
xorl %ecx, %ecx
movapd (%rsp,%rcx,8), %xmm4
divpd %xmm0, %xmm4
movupd %xmm4, (%rbx,%rcx,8)
addq $0x2, %rcx
cmpq $0x4, %rcx
jne 0x15e9a
xorpd %xmm4, %xmm4
xorl %ecx, %ecx
movapd %xmm4, %xmm5
movsd (%rbx,%rcx,8), %xmm4
subsd 0x30(%rsp,%rcx,8), %xmm4
andpd %xmm2, %xmm4
maxsd %xmm5, %xmm4
incq %rcx
cmpq $0x4, %rcx
jne 0x15eb8
ucomisd %xmm4, %xmm3
ja 0x15ee9
incl %eax
cmpl $0x32, %eax
jne 0x15d3f
movq %r12, %rdi
callq 0x2060
movq %r15, %rdi
callq 0x2060
movsd (%rbx), %xmm0
movupd 0x8(%rbx), %xmm1
movapd %xmm0, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
addpd %xmm1, %xmm2
movapd 0x30fa(%rip), %xmm3     # 0x19010
subpd %xmm2, %xmm3
movapd %xmm1, %xmm4
unpckhpd %xmm1, %xmm4            # xmm4 = xmm4[1],xmm1[1]
mulsd %xmm1, %xmm4
mulsd 0x18(%rbx), %xmm0
subsd %xmm4, %xmm0
mulsd %xmm0, %xmm0
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
mulsd %xmm2, %xmm1
mulsd %xmm3, %xmm1
unpckhpd %xmm3, %xmm3            # xmm3 = xmm3[1,1]
mulsd %xmm1, %xmm3
divsd %xmm3, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x15f5f
sqrtsd %xmm0, %xmm0
jmp 0x15f64
callq 0x24e0
movapd %xmm0, %xmm2
cmpunordsd %xmm0, %xmm2
movsd 0x3123(%rip), %xmm1     # 0x19098
andpd %xmm2, %xmm1
andnpd %xmm0, %xmm2
orpd %xmm1, %xmm2
movapd %xmm2, %xmm0
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq