// File: /workspace/github_cpp_makefile_star2_O3/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 $0x58, %rsp
movl %r8d, -0x30(%rbp)
movl %ecx, -0x2c(%rbp)
cmpl $0x0, 0x20(%rbp)
jle 0xc3a6
movq %rdx, %r8
movq %rsi, %r10
movq 0x18(%rbp), %r11
movl %r9d, %r13d
leaq (,%r13,8), %rax
movq %rax, -0x40(%rbp)
movl -0x2c(%rbp), %eax
movq %rax, -0x70(%rbp)
movl -0x30(%rbp), %r15d
xorl %eax, %eax
leaq 0xf(,%r13,8), %rcx
andq $-0x10, %rcx
movq %rcx, -0x68(%rbp)
movsd 0xe8d(%rip), %xmm7      # 0xd008
movsd 0x2664(%rip), %xmm8     # 0xe7e8
movsd 0x264b(%rip), %xmm9     # 0xe7d8
movsd 0x264a(%rip), %xmm10    # 0xe7e0
movl %r9d, -0x34(%rbp)
movq %rdx, -0x60(%rbp)
movq %rsi, -0x58(%rbp)
movq %rdi, -0x50(%rbp)
movq %rax, -0x48(%rbp)
cmpl $0x0, -0x2c(%rbp)
jle 0xc397
xorl %ebx, %ebx
movq %rsp, -0x78(%rbp)
movq %rsp, %r14
movq -0x68(%rbp), %rax
subq %rax, %r14
movq %r14, %rsp
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
testl %r9d, %r9d
jle 0xc228
movq %r14, %rdi
xorl %esi, %esi
movq -0x40(%rbp), %rdx
callq 0x2100
movq %r12, %rdi
xorl %esi, %esi
movq -0x40(%rbp), %rdx
callq 0x2100
movsd 0x25e6(%rip), %xmm10    # 0xe7e0
movsd 0x25d5(%rip), %xmm9     # 0xe7d8
movsd 0x25dc(%rip), %xmm8     # 0xe7e8
movsd 0xdf4(%rip), %xmm7      # 0xd008
movq 0x18(%rbp), %r11
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %r10
movq -0x60(%rbp), %r8
movl -0x34(%rbp), %r9d
cmpl $0x0, -0x30(%rbp)
jle 0xc34c
xorl %eax, %eax
movl 0x10(%rbp), %ecx
cmpq %rcx, %rax
je 0xc340
movq (%r11,%rbx,8), %rcx
cmpb $0x1, (%rcx,%rax)
jne 0xc340
testl %r9d, %r9d
jle 0xc279
movq (%rdi,%rbx,8), %rcx
movq (%r10,%rax,8), %rdx
xorpd %xmm0, %xmm0
xorl %esi, %esi
movsd (%rcx,%rsi,8), %xmm1
mulsd (%rdx,%rsi,8), %xmm1
addsd %xmm1, %xmm0
incq %rsi
cmpq %rsi, %r13
jne 0xc261
jmp 0xc27d
xorpd %xmm0, %xmm0
testl %r9d, %r9d
jle 0xc340
movapd %xmm7, %xmm1
divsd %xmm0, %xmm1
movapd %xmm7, %xmm3
subsd %xmm0, %xmm3
movapd %xmm7, %xmm2
divsd %xmm3, %xmm2
movapd %xmm3, %xmm4
mulsd %xmm3, %xmm4
movq (%r8,%rbx,8), %rcx
leaq (%rax,%rax,2), %rdx
mulsd 0x10(%rcx,%rdx,8), %xmm4
addsd %xmm3, %xmm3
mulsd %xmm0, %xmm3
mulsd 0x8(%rcx,%rdx,8), %xmm3
mulsd %xmm0, %xmm0
mulsd (%rcx,%rdx,8), %xmm0
addsd %xmm3, %xmm4
addsd %xmm0, %xmm4
addsd %xmm0, %xmm0
addsd %xmm3, %xmm0
divsd %xmm4, %xmm0
movq (%rdi,%rbx,8), %rcx
movq (%r10,%rax,8), %rdx
movapd %xmm8, %xmm3
subsd %xmm0, %xmm3
xorl %esi, %esi
movsd (%rcx,%rsi,8), %xmm4
movapd %xmm0, %xmm5
mulsd %xmm4, %xmm5
movapd %xmm7, %xmm6
subsd %xmm4, %xmm6
movsd (%rdx,%rsi,8), %xmm4
mulsd %xmm4, %xmm5
mulsd %xmm1, %xmm5
addsd (%r14,%rsi,8), %xmm5
mulsd %xmm3, %xmm6
mulsd %xmm4, %xmm6
mulsd %xmm2, %xmm6
addsd (%r12,%rsi,8), %xmm6
movsd %xmm5, (%r14,%rsi,8)
movsd %xmm6, (%r12,%rsi,8)
incq %rsi
cmpq %rsi, %r13
jne 0xc2f2
incq %rax
cmpq %r15, %rax
jne 0xc234
testl %r9d, %r9d
jle 0xc386
movq (%rdi,%rbx,8), %rax
xorl %ecx, %ecx
movsd (%r14,%rcx,8), %xmm0
movsd (%r12,%rcx,8), %xmm1
addsd %xmm0, %xmm1
divsd %xmm1, %xmm0
movapd %xmm9, %xmm1
minsd %xmm0, %xmm1
maxsd %xmm10, %xmm1
movsd %xmm1, (%rax,%rcx,8)
incq %rcx
cmpq %rcx, %r13
jne 0xc357
movq -0x78(%rbp), %rsp
incq %rbx
cmpq -0x70(%rbp), %rbx
jne 0xc1b6
movq -0x48(%rbp), %rax
incl %eax
cmpl 0x20(%rbp), %eax
jne 0xc1a6
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq