// File: /workspace/github_cpp_makefile_star2_O2/GenisGE[P]evalAdmix/ngsevalAdmix.cpp
// Function: adaptFandeG(double**, double**, double**, int, int, int, int, char**, int)
void adaptFandeG(double **F, double **Q, double **genos, int nSites, int nInd, int K, int withoutInd, char **keep, int nIts){
  
  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(keep[j][i] == 1){
	    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);

	    double pp0=(1-fpart)*(1-fpart)*        genos[j][3*i+2];
	    double pp1=2*(1-fpart)*fpart*  genos[j][3*i+1];
	    double pp2=fpart*fpart*genos[j][3*i+0];
	    double sum=pp0+pp1+pp2;
	    double eG = (pp1+2*pp2)/sum;
	  
	    for(int k=0; k<K;k++){
	      sumAG[k] += eG*F[j][k]*Q[i][k]*aNorm;
	      sumBG[k] += (2-eG)*(1-F[j][k])*Q[i][k]*bNorm;
	    }
	
	  }

	}

	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
movq 0x18(%rbp), %r10
movl %r9d, %r11d
xorl %ebx, %ebx
testl %r9d, %r9d
cmovlel %ebx, %r9d
movl 0x20(%rbp), %r14d
testl %r8d, %r8d
cmovlel %ebx, %r8d
testl %ecx, %ecx
cmovlel %ebx, %ecx
movq %rcx, -0x48(%rbp)
testl %r14d, %r14d
cmovlel %ebx, %r14d
movl %r14d, -0x2c(%rbp)
leaq 0xf(,%r11,8), %rcx
andq $-0x10, %rcx
movq %rcx, -0x40(%rbp)
movsd 0x1fd1(%rip), %xmm0     # 0xc788
movsd 0x1fd1(%rip), %xmm1     # 0xc790
movsd 0x841(%rip), %xmm2      # 0xb008
movsd 0x1fc9(%rip), %xmm3     # 0xc798
cmpl -0x2c(%rbp), %ebx
je 0xa98e
movq %rbx, -0x38(%rbp)
xorl %r15d, %r15d
cmpq -0x48(%rbp), %r15
je 0xa983
movq %rsp, %r12
movq %rsp, %r13
movq -0x40(%rbp), %rcx
subq %rcx, %r13
movq %r13, %rsp
movq %rsp, %rbx
subq %rcx, %rbx
movq %rbx, %rsp
xorl %r11d, %r11d
cmpq %r11, %r9
je 0xa81a
andq $0x0, (%r13,%r11,8)
andq $0x0, (%rbx,%r11,8)
incq %r11
jmp 0xa805
xorl %r11d, %r11d
cmpq %r8, %r11
je 0xa940
cmpq %rax, %r11
je 0xa938
movq (%r10,%r15,8), %r14
cmpb $0x1, (%r14,%r11)
jne 0xa938
xorpd %xmm4, %xmm4
xorl %r14d, %r14d
cmpq %r14, %r9
je 0xa867
movq (%rdi,%r15,8), %rcx
movsd (%rcx,%r14,8), %xmm5
movq (%rsi,%r11,8), %rcx
mulsd (%rcx,%r14,8), %xmm5
addsd %xmm5, %xmm4
incq %r14
jmp 0xa845
movapd %xmm2, %xmm5
movapd %xmm2, %xmm7
subsd %xmm4, %xmm7
movapd %xmm2, %xmm6
divsd %xmm7, %xmm6
movapd %xmm7, %xmm8
mulsd %xmm7, %xmm8
movq (%rdx,%r15,8), %r14
imulq $0x18, %r11, %rcx
mulsd 0x10(%r14,%rcx), %xmm8
addsd %xmm7, %xmm7
mulsd %xmm4, %xmm7
mulsd 0x8(%r14,%rcx), %xmm7
divsd %xmm4, %xmm5
mulsd %xmm4, %xmm4
mulsd (%r14,%rcx), %xmm4
addsd %xmm7, %xmm8
addsd %xmm4, %xmm8
addsd %xmm4, %xmm4
addsd %xmm7, %xmm4
divsd %xmm8, %xmm4
movapd %xmm3, %xmm7
subsd %xmm4, %xmm7
xorl %r14d, %r14d
cmpq %r14, %r9
je 0xa938
movq (%rdi,%r15,8), %rcx
movsd (%rcx,%r14,8), %xmm8
movapd %xmm4, %xmm9
mulsd %xmm8, %xmm9
movq (%rsi,%r11,8), %rcx
movsd (%rcx,%r14,8), %xmm10
mulsd %xmm10, %xmm9
mulsd %xmm5, %xmm9
addsd (%r13,%r14,8), %xmm9
movsd %xmm9, (%r13,%r14,8)
movapd %xmm2, %xmm9
subsd %xmm8, %xmm9
mulsd %xmm7, %xmm9
mulsd %xmm10, %xmm9
mulsd %xmm6, %xmm9
addsd (%rbx,%r14,8), %xmm9
movsd %xmm9, (%rbx,%r14,8)
incq %r14
jmp 0xa8d3
incq %r11
jmp 0xa81d
xorl %r11d, %r11d
cmpq %r11, %r9
je 0xa978
movsd (%r13,%r11,8), %xmm4
movsd (%rbx,%r11,8), %xmm5
addsd %xmm4, %xmm5
divsd %xmm5, %xmm4
movapd %xmm0, %xmm5
minsd %xmm4, %xmm5
movq (%rdi,%r15,8), %rcx
maxsd %xmm1, %xmm5
movsd %xmm5, (%rcx,%r11,8)
incq %r11
jmp 0xa943
movq %r12, %rsp
incq %r15
jmp 0xa7df
movq -0x38(%rbp), %rbx
incl %ebx
jmp 0xa7cf
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq