// File: /workspace/github_cpp_makefile_star2_O2/GenisGE[P]evalAdmix/Cinterface.cpp
// Function: emFrequency(double*, int, int, double, char*, int)
double emFrequency(double *loglike,int numInds, int iter,double start,char *keep,int keepInd){

  if(keepInd == 0)
    return 0.0;
  
  float W0;
  float W1;
  float W2;
  // fprintf(stderr,"start=%f\n",start);
  float p=(float)start;
  float temp_p=(float)start;
  double accu=0.00001;
  double accu2=0;
  float sum;


  int it=0;
  
  for(it=0;it<iter;it++){
    sum=0;
    for(int i=0;i<numInds;i++){
      if(keep!=NULL && keep[i]==0)
        continue;
      W0=(loglike[i*3+0])*(1-p)*(1-p);
      W1=(loglike[i*3+1])*2*p*(1-p);
      W2=(loglike[i*3+2])*p*p;
      sum+=(W1+2*W2)/(2*(W0+W1+W2));
      //  fprintf(stderr,"%f %f %f\n",W0,W1,W2);
      if(0&&std::isnan(sum)){
	//fprintf(stderr,"PRE[%d]: W %f\t%f\t%f sum=%f\n",i,W0,W1,W2,sum);
	exit(0);
      }
    }

    p=sum/keepInd;
    // fprintf(stderr,"it=%d\tp=%f\tsum=%f\tkeepInd=%d\n",it,p,log(sum),keepInd);
    if((p-temp_p<accu&&temp_p-p<accu)||(p/temp_p<1+accu2&&p/temp_p>1-accu2))
      break;
    temp_p=p;
  }



  if(std::isnan(p)){
    fprintf(stderr,"[%s] caught nan will not exit\n",__FUNCTION__);
    fprintf(stderr,"logLike (3*nInd). nInd=%d\n",numInds);
    //print_array(stderr,loglike,3*numInds);
    fprintf(stderr,"keepList (nInd)\n");
    //print_array(stderr,keep,numInds);
    fprintf(stderr,"used logLike (3*length(keep))=%d\n",keepInd);

    for(int ii=0;0&&ii<numInds;ii++){
      if(keep!=NULL && keep[ii]==1)
	    fprintf(stderr,"1\t");
	for(int gg=0;gg<3;gg++)
	  fprintf(stderr,"%f\t",loglike[ii*3+gg]);
      fprintf(stderr,"\n");
    }
    sum=0;
    for(int i=0;i<numInds;i++){
      if(keep!=NULL && keep[i]==0)
        continue;
      W0=(loglike[i*3+0])*(1-p)*(1-p);
      W1=(loglike[i*3+1])*2*p*(1-p);
      W2=(loglike[i*3+2])*p*p;
      sum+=(W1+2*W2)/(2*(W0+W1+W2));
      //fprintf(stderr,"p=%f W %f\t%f\t%f sum=%f loglike: %f\n",p,W0,W1,W2,sum,exp(loglike[i*3+2])*pow(1-p,2));
    }
    p=-999;
    // exit(0);
  }
  
  return(p);
}

// Assembly:
testl %r8d, %r8d
je 0x27f6
pushq %rbp
pushq %r14
pushq %rbx
movl %r8d, %ebx
movl %esi, %ebp
cvtsd2ss %xmm0, %xmm0
cvtsi2ss %r8d, %xmm1
xorl %eax, %eax
testl %esi, %esi
movl $0x0, %esi
cmovgl %ebp, %esi
testl %edx, %edx
cmovlel %eax, %edx
addq $0x10, %rdi
movss 0x8958(%rip), %xmm2     # 0xb060
movsd 0x8900(%rip), %xmm3     # 0xb010
cmpl %edx, %eax
je 0x27fd
movaps %xmm2, %xmm4
subss %xmm0, %xmm4
unpcklps %xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1]
cvtps2pd %xmm4, %xmm5
movapd %xmm5, %xmm6
unpcklpd %xmm5, %xmm6            # xmm6 = xmm6[0],xmm5[0]
movapd %xmm5, %xmm7
unpckhpd %xmm5, %xmm7            # xmm7 = xmm7[1],xmm5[1]
xorps %xmm4, %xmm4
movq %rdi, %r8
xorl %r9d, %r9d
cmpq %r9, %rsi
je 0x27c9
testq %rcx, %rcx
je 0x2753
cmpb $0x0, (%rcx,%r9)
je 0x27bd
movsd -0x8(%r8), %xmm8
addsd %xmm8, %xmm8
movsd -0x10(%r8), %xmm9
unpcklpd %xmm8, %xmm9            # xmm9 = xmm9[0],xmm8[0]
mulpd %xmm5, %xmm9
mulpd %xmm6, %xmm9
cvtpd2ps %xmm9, %xmm8
movsd (%r8), %xmm9
mulsd %xmm7, %xmm9
mulsd %xmm7, %xmm9
cvtsd2ss %xmm9, %xmm9
movapd %xmm8, %xmm10
shufps $0x55, %xmm8, %xmm10    # xmm10 = xmm10[1,1],xmm8[1,1]
movaps %xmm9, %xmm11
addss %xmm9, %xmm11
addss %xmm10, %xmm11
addss %xmm8, %xmm10
addss %xmm9, %xmm10
addss %xmm10, %xmm10
divss %xmm10, %xmm11
addss %xmm11, %xmm4
incq %r9
addq $0x18, %r8
jmp 0x273e
divss %xmm1, %xmm4
movaps %xmm4, %xmm5
subss %xmm0, %xmm5
cvtss2sd %xmm5, %xmm5
ucomisd %xmm5, %xmm3
jbe 0x27ec
subss %xmm4, %xmm0
cvtss2sd %xmm0, %xmm0
ucomisd %xmm0, %xmm3
ja 0x27fa
incl %eax
movaps %xmm4, %xmm0
jmp 0x2710
xorps %xmm0, %xmm0
retq
movaps %xmm4, %xmm0
ucomiss %xmm0, %xmm0
jp 0x280b
cvtss2sd %xmm0, %xmm0
popq %rbx
popq %r14
popq %rbp
retq
movq 0xe7c6(%rip), %r14      # 0x10fd8
movq (%r14), %rdi
leaq 0x885a(%rip), %rsi      # 0xb076
leaq 0x8872(%rip), %rdx      # 0xb095
xorl %eax, %eax
callq 0x2320
movq (%r14), %rdi
leaq 0x886d(%rip), %rsi      # 0xb0a1
movl %ebp, %edx
xorl %eax, %eax
callq 0x2320
movq (%r14), %rcx
leaq 0x8875(%rip), %rdi      # 0xb0bc
pushq $0x10
popq %rsi
pushq $0x1
popq %rdx
callq 0x2470
movq (%r14), %rdi
leaq 0x8871(%rip), %rsi      # 0xb0cd
movl %ebx, %edx
xorl %eax, %eax
callq 0x2320
movss 0x87f7(%rip), %xmm0     # 0xb064
jmp 0x2802