// File: 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:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movl %esi, 0x54(%rsp)
movl %edx, 0x50(%rsp)
movsd %xmm0, 0x48(%rsp)
movq %rcx, 0x40(%rsp)
movl %r8d, 0x3c(%rsp)
cmpl $0x0, 0x3c(%rsp)
jne 0x38a6
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
jmp 0x3dc4
movsd 0x48(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x2c(%rsp)
movsd 0x48(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x28(%rsp)
movsd 0x1474a(%rip), %xmm0    # 0x18018
movsd %xmm0, 0x20(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
movl $0x0, 0x10(%rsp)
movl $0x0, 0x10(%rsp)
movl 0x10(%rsp), %eax
cmpl 0x50(%rsp), %eax
jge 0x3b11
xorps %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x3a5d
cmpq $0x0, 0x40(%rsp)
je 0x393a
movq 0x40(%rsp), %rax
movslq 0xc(%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x393a
jmp 0x3a4d
movq 0x58(%rsp), %rax
imull $0x3, 0xc(%rsp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movss 0x146f1(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x146db(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x38(%rsp)
movq 0x58(%rsp), %rax
imull $0x3, 0xc(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd 0x14673(%rip), %xmm0    # 0x18010
mulsd (%rax,%rcx,8), %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x14690(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x34(%rsp)
movq 0x58(%rsp), %rax
imull $0x3, 0xc(%rsp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x30(%rsp)
movss 0x34(%rsp), %xmm1
movss 0x30(%rsp), %xmm0
addss %xmm0, %xmm0
addss %xmm1, %xmm0
movss 0x38(%rsp), %xmm2
addss 0x34(%rsp), %xmm2
addss 0x30(%rsp), %xmm2
movss 0x1460b(%rip), %xmm1    # 0x18044
mulss %xmm2, %xmm1
divss %xmm1, %xmm0
addss 0x14(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x390c
movss 0x14(%rsp), %xmm0
cvtsi2ssl 0x3c(%rsp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x2c(%rsp)
movss 0x2c(%rsp), %xmm0
subss 0x28(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x3aab
movss 0x28(%rsp), %xmm0
subss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x3af3
movss 0x2c(%rsp), %xmm0
divss 0x28(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x14545(%rip), %xmm0    # 0x18008
addsd 0x18(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x3af5
movss 0x2c(%rsp), %xmm0
divss 0x28(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x14521(%rip), %xmm1    # 0x18008
subsd 0x18(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x3af5
jmp 0x3b11
movss 0x2c(%rsp), %xmm0
movss %xmm0, 0x28(%rsp)
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x38ed
movss 0x2c(%rsp), %xmm0
callq 0x9100
testb $0x1, %al
jne 0x3b25
jmp 0x3db4
movq 0x1b4ac(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x14540(%rip), %rsi     # 0x18076
leaq 0x14558(%rip), %rdx     # 0x18095
movb $0x0, %al
callq 0x33c0
movq 0x1b48d(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movl 0x54(%rsp), %edx
leaq 0x14548(%rip), %rsi     # 0x180a1
movb $0x0, %al
callq 0x33c0
movq 0x1b471(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x1454b(%rip), %rsi     # 0x180bc
movb $0x0, %al
callq 0x33c0
movq 0x1b459(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movl 0x3c(%rsp), %edx
leaq 0x14540(%rip), %rsi     # 0x180cd
movb $0x0, %al
callq 0x33c0
movl $0x0, 0x8(%rsp)
xorl %eax, %eax
testb $0x1, %al
jne 0x3ba7
jmp 0x3c4c
cmpq $0x0, 0x40(%rsp)
je 0x3bda
movq 0x40(%rsp), %rax
movslq 0x8(%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x1, %eax
jne 0x3bda
movq 0x1b40f(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x1451c(%rip), %rsi     # 0x180ef
movb $0x0, %al
callq 0x33c0
movl $0x0, 0x4(%rsp)
cmpl $0x3, 0x4(%rsp)
jge 0x3c24
movq 0x1b3e8(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movq 0x58(%rsp), %rax
imull $0x3, 0x8(%rsp), %ecx
addl 0x4(%rsp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
leaq 0x144e2(%rip), %rsi     # 0x180f2
movb $0x1, %al
callq 0x33c0
movl 0x4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4(%rsp)
jmp 0x3be2
movq 0x1b3ad(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x1502c(%rip), %rsi     # 0x18c61
movb $0x0, %al
callq 0x33c0
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0x3b9c
xorps %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
movl $0x0, (%rsp)
movl (%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x3da6
cmpq $0x0, 0x40(%rsp)
je 0x3c88
movq 0x40(%rsp), %rax
movslq (%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x3c88
jmp 0x3d98
movq 0x58(%rsp), %rax
imull $0x3, (%rsp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movss 0x143a4(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x1438e(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x38(%rsp)
movq 0x58(%rsp), %rax
imull $0x3, (%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd 0x14327(%rip), %xmm0    # 0x18010
mulsd (%rax,%rcx,8), %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x14344(%rip), %xmm1    # 0x18048
subss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x34(%rsp)
movq 0x58(%rsp), %rax
imull $0x3, (%rsp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
movss 0x2c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x30(%rsp)
movss 0x34(%rsp), %xmm1
movss 0x30(%rsp), %xmm0
addss %xmm0, %xmm0
addss %xmm1, %xmm0
movss 0x38(%rsp), %xmm2
addss 0x34(%rsp), %xmm2
addss 0x30(%rsp), %xmm2
movss 0x142c0(%rip), %xmm1    # 0x18044
mulss %xmm2, %xmm1
divss %xmm1, %xmm0
addss 0x14(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movl (%rsp), %eax
addl $0x1, %eax
movl %eax, (%rsp)
jmp 0x3c5c
movss 0x14292(%rip), %xmm0    # 0x18040
movss %xmm0, 0x2c(%rsp)
movss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm0
addq $0x68, %rsp
retq
nop