// File: /workspace/github_cpp_makefile_star2_O2/GenisGE[P]evalAdmix/evalAdmix.cpp
// Function: adaptF(double**, unsigned short**, int, double**, int, int, int, int, int**)
void adaptF(double **F, unsigned short int **G, int K, double **Q, int nInd, int nSites, int withoutInd, int nIts, int **isMissing){


  for(int it=0; it<nIts; it++){
    
    for(int j=0; j<nSites; j++){

	double sumAG[K];
	double sumBG[K];
    
	for(int k=0; k<K;k++){
	  sumAG[k] = 0;
	  sumBG[k] = 0;
	}

	for(int i=0; i<nInd;i++){
	
	  if(i == withoutInd)
	    continue;


	  if(!isMissing[j][i]){
	    double fpart=0;
	    double aNorm;
	    double bNorm;

	    for(int k=0;k<K;k++){
	      fpart+=F[j][k]*Q[i][k];
	    }
	   
	    
	    aNorm = 1.0/fpart;
	    bNorm = 1.0/(1-fpart);

	    for(int k=0; k<K; k++){
	    sumAG[k] += G[j][i]*F[j][k]*Q[i][k]*aNorm; // Minor allele
	    sumBG[k] += (2-G[j][i])*Q[i][k]*(1-F[j][k])*bNorm; // Major allele
	    }
	   
	
	  }
	}

	for(int k=0;k<K;k++){
	  F[j][k] = sumAG[k]/(sumAG[k]+sumBG[k]);
	  F[j][k] = std::max(1e-6, std::min(F[j][k],0.999999)); // make sure value is in (1e6, 0.999999) interval 
	  // if(F[j][k]==0)
	  // F[j][k] = 1e-6;
	}
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl 0x10(%rbp), %eax
movl %edx, %r10d
xorl %r11d, %r11d
testl %edx, %edx
cmovlel %r11d, %edx
movl 0x18(%rbp), %ebx
testl %r8d, %r8d
cmovlel %r11d, %r8d
testl %r9d, %r9d
cmovlel %r11d, %r9d
movq %r9, -0x48(%rbp)
testl %ebx, %ebx
cmovlel %r11d, %ebx
movl %ebx, -0x2c(%rbp)
leaq 0xf(,%r10,8), %r9
andq $-0x10, %r9
movq %r9, -0x40(%rbp)
movsd 0x270a(%rip), %xmm0     # 0xc788
movsd 0x270a(%rip), %xmm1     # 0xc790
movsd 0xf7a(%rip), %xmm2      # 0xb008
pushq $0x2
popq %r15
cmpl -0x2c(%rbp), %r11d
je 0xa208
movq %r11, -0x38(%rbp)
xorl %r12d, %r12d
cmpq -0x48(%rbp), %r12
je 0xa1fc
movq %rsp, -0x50(%rbp)
movq %rsp, %rbx
movq -0x40(%rbp), %r9
subq %r9, %rbx
movq %rbx, %rsp
movq %rsp, %r11
subq %r9, %r11
movq %r11, %rsp
xorl %r9d, %r9d
cmpq %r9, %rdx
je 0xa0de
andq $0x0, (%rbx,%r9,8)
andq $0x0, (%r11,%r9,8)
incq %r9
jmp 0xa0ca
xorl %r14d, %r14d
cmpq %r8, %r14
je 0xa1b9
cmpq %rax, %r14
je 0xa0fe
movq 0x20(%rbp), %r9
movq (%r9,%r12,8), %r9
cmpl $0x0, (%r9,%r14,4)
je 0xa103
incq %r14
jmp 0xa0e1
xorpd %xmm4, %xmm4
xorl %r9d, %r9d
cmpq %r9, %rdx
je 0xa12e
movq (%rdi,%r12,8), %r13
movsd (%r13,%r9,8), %xmm3
movq (%rcx,%r14,8), %r13
mulsd (%r13,%r9,8), %xmm3
addsd %xmm3, %xmm4
incq %r9
jmp 0xa10a
movapd %xmm2, %xmm3
divsd %xmm4, %xmm3
movapd %xmm2, %xmm5
subsd %xmm4, %xmm5
movapd %xmm2, %xmm4
divsd %xmm5, %xmm4
xorl %r9d, %r9d
cmpq %r9, %rdx
je 0xa0fe
movq (%rsi,%r12,8), %r13
movzwl (%r13,%r14,2), %r13d
cvtsi2sd %r13d, %xmm5
movq (%rdi,%r12,8), %r10
movsd (%r10,%r9,8), %xmm6
mulsd %xmm6, %xmm5
movq (%rcx,%r14,8), %r10
movsd (%r10,%r9,8), %xmm7
mulsd %xmm7, %xmm5
mulsd %xmm3, %xmm5
addsd (%rbx,%r9,8), %xmm5
movsd %xmm5, (%rbx,%r9,8)
movl %r15d, %r10d
subl %r13d, %r10d
cvtsi2sd %r10d, %xmm5
mulsd %xmm7, %xmm5
movapd %xmm2, %xmm7
subsd %xmm6, %xmm7
mulsd %xmm5, %xmm7
mulsd %xmm4, %xmm7
addsd (%r11,%r9,8), %xmm7
movsd %xmm7, (%r11,%r9,8)
incq %r9
jmp 0xa149
xorl %r9d, %r9d
cmpq %r9, %rdx
je 0xa1f0
movsd (%rbx,%r9,8), %xmm3
movsd (%r11,%r9,8), %xmm4
addsd %xmm3, %xmm4
divsd %xmm4, %xmm3
movapd %xmm0, %xmm4
minsd %xmm3, %xmm4
movq (%rdi,%r12,8), %r10
maxsd %xmm1, %xmm4
movsd %xmm4, (%r10,%r9,8)
incq %r9
jmp 0xa1bc
movq -0x50(%rbp), %rsp
incq %r12
jmp 0xa0a3
movq -0x38(%rbp), %r11
incl %r11d
jmp 0xa092
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq