// File: tplinderoth[P]introDist/Dxyz.cpp
// Function: calcDxyzWindow(Matrix<double> const&, unsigned int, double*, int*, double, double*)
double calcDxyzWindow(const Matrix<double> &dxy, unsigned int lastidx, double* nseqavg, int *nsites, const double minmaf, double* dxy_comp) {
	/*
	 * calculates Dxyz statistic as average_Dxy(source_pop,sink_pop)/average_Dxy(source_pop,outgroup_pop)
	 * average_Dxy = 1/N*[sum_i=1_to_i=N(Dxy)], N = number of sites
	 *
	 * Encode windows with no data or with no source-outgroup differences as -9
	 */

	dxy_comp[0] = 0; // Source-Sink average dxy
	dxy_comp[1] = 0; // Source-Outgroup average dxy
	*nseqavg = 0;
	*nsites = 0;

	unsigned int i;
	for (i=0; i<=lastidx; ++i) {
		if (dxy(i,0) != -9 && dxy(i,1) != -9 && dxy(i,4) >= minmaf) {
			dxy_comp[0] += dxy(i,0);
			dxy_comp[1] += dxy(i,1);
			*nseqavg += dxy(i,3);
			++*nsites;
		}
	}

	dxy_comp[0] /= *nsites;
	dxy_comp[1] /= *nsites;
	*nseqavg /= *nsites;

	if (*nsites < 1) return -9;

	return (dxy_comp[1] > 0 ? dxy_comp[0]/dxy_comp[1] : -9);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movsd %xmm0, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq -0x38(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq -0x38(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x8(%rax)
movq -0x20(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq -0x28(%rbp), %rax
movl $0x0, (%rax)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x14(%rbp), %eax
ja 0xae0e
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
xorl %edx, %edx
callq 0xbf10
movsd 0x132bb(%rip), %xmm1    # 0x1e010
ucomisd %xmm1, %xmm0
jne 0xad62
jp 0xad62
jmp 0xadfe
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl $0x1, %edx
callq 0xbf10
movsd 0x13295(%rip), %xmm1    # 0x1e010
ucomisd %xmm1, %xmm0
jne 0xad85
jp 0xad85
jmp 0xadfe
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl $0x4, %edx
callq 0xbf10
ucomisd -0x30(%rbp), %xmm0
jb 0xadfe
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
xorl %edx, %edx
callq 0xbf10
movq -0x38(%rbp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl $0x1, %edx
callq 0xbf10
movq -0x38(%rbp), %rax
addsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rax)
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl $0x3, %edx
callq 0xbf10
movq -0x20(%rbp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq -0x28(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0xae00
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0xad33
movq -0x28(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
movq -0x38(%rbp), %rax
movsd (%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq -0x28(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
movq -0x38(%rbp), %rax
movsd 0x8(%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rax)
movq -0x28(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq -0x28(%rbp), %rax
cmpl $0x1, (%rax)
jge 0xae70
movsd 0x131a7(%rip), %xmm0    # 0x1e010
movsd %xmm0, -0x8(%rbp)
jmp 0xaeb3
movq -0x38(%rbp), %rax
movsd 0x8(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xae9a
movq -0x38(%rbp), %rax
movsd (%rax), %xmm0
movq -0x38(%rbp), %rax
divsd 0x8(%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
jmp 0xaea9
movsd 0x1316e(%rip), %xmm0    # 0x1e010
movsd %xmm0, -0x48(%rbp)
jmp 0xaea9
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x50, %rsp
popq %rbp
retq
nop