// File: /workspace/github_cpp_makefile_star2_O1/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 0x2ece
pushq %rax
cvtsd2ss %xmm0, %xmm3
testl %edx, %edx
jle 0x2ed2
xorps %xmm0, %xmm0
cvtsi2ss %r8d, %xmm0
movl %esi, %eax
addq $0x10, %rdi
xorl %r9d, %r9d
movss 0xa2c7(%rip), %xmm1     # 0xd0a0
movsd 0xa22f(%rip), %xmm2     # 0xd010
testl %esi, %esi
jle 0x2e97
movaps %xmm1, %xmm4
subss %xmm3, %xmm4
unpcklps %xmm3, %xmm4            # xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[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, %r10
xorl %r11d, %r11d
testq %rcx, %rcx
je 0x2e1b
cmpb $0x0, (%rcx,%r11)
je 0x2e85
movsd -0x8(%r10), %xmm8
addsd %xmm8, %xmm8
movsd -0x10(%r10), %xmm9
unpcklpd %xmm8, %xmm9            # xmm9 = xmm9[0],xmm8[0]
mulpd %xmm5, %xmm9
mulpd %xmm6, %xmm9
cvtpd2ps %xmm9, %xmm8
movsd (%r10), %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 %r11
addq $0x18, %r10
cmpq %r11, %rax
jne 0x2e0f
jmp 0x2e9a
xorps %xmm4, %xmm4
divss %xmm0, %xmm4
movaps %xmm4, %xmm5
subss %xmm3, %xmm5
cvtss2sd %xmm5, %xmm5
ucomisd %xmm5, %xmm2
jbe 0x2ebd
subss %xmm4, %xmm3
cvtss2sd %xmm3, %xmm3
ucomisd %xmm3, %xmm2
ja 0x2ed5
incl %r9d
movaps %xmm4, %xmm3
cmpl %edx, %r9d
jl 0x2de1
jmp 0x2ed5
xorps %xmm0, %xmm0
retq
movaps %xmm3, %xmm4
ucomiss %xmm4, %xmm4
jp 0x2ee6
xorps %xmm0, %xmm0
cvtss2sd %xmm4, %xmm0
addq $0x8, %rsp
retq
movl %esi, %edi
movl %r8d, %esi
callq 0x2813
movss 0xa1ac(%rip), %xmm4     # 0xd0a4
jmp 0x2eda