// File: /workspace/github_c_makefile_star2_O0/zpole[P]IICV/vl/gmm.c
// Function: vl_gmm_em_f
static double
VL_XCAT(_vl_gmm_em_, SFX)
(VlGMM * self,
 TYPE const * data,
 vl_size numData)
{
  vl_size iteration, restarted ;
  double previousLL = (TYPE)(-VL_INFINITY_D) ;
  double LL = (TYPE)(-VL_INFINITY_D) ;
  double time = 0 ;

  _vl_gmm_prepare_for_data (self, numData) ;

  VL_XCAT(_vl_gmm_apply_bounds_,SFX)(self) ;

  for (iteration = 0 ; 1 ; ++ iteration) {
    double eps ;

    /*
     Expectation: assign data to Gaussian modes
     and compute log-likelihood.
     */

    if (self->verbosity > 1) {
      VL_PRINTF("gmm: em: entering expectation step\n") ;
      time = vl_get_cpu_time() ;
    }

    LL = VL_XCAT(vl_get_gmm_data_posteriors_,SFX)
    (self->posteriors,
     self->numClusters,
     numData,
     self->priors,
     self->means,
     self->dimension,
     self->covariances,
     data) ;

    if (self->verbosity > 1) {
      VL_PRINTF("gmm: em: expectation step completed in %.2f s\n",
                vl_get_cpu_time() - time) ;
    }

    /*
     Check the termination conditions.
     */
    if (self->verbosity) {
      VL_PRINTF("gmm: em: iteration %d: loglikelihood = %f (variation = %f)\n",
                iteration, LL, LL - previousLL) ;
    }
    if (iteration >= self->maxNumIterations) {
      if (self->verbosity) {
        VL_PRINTF("gmm: em: terminating because "
                  "the maximum number of iterations "
                  "(%d) has been reached.\n", self->maxNumIterations) ;
      }
      break ;
    }

    eps = vl_abs_d ((LL - previousLL) / (LL));
    if ((iteration > 0) && (eps < 0.00001)) {
      if (self->verbosity) {
        VL_PRINTF("gmm: em: terminating because the algorithm "
                  "fully converged (log-likelihood variation = %f).\n", eps) ;
      }
      break ;
    }
    previousLL = LL ;

    /*
     Restart empty modes.
     */
    if (iteration > 1) {
      restarted = VL_XCAT(_vl_gmm_restart_empty_modes_, SFX)
        (self, data);
      if ((restarted > 0) & (self->verbosity > 0)) {
        VL_PRINTF("gmm: em: %d Gaussian modes restarted because "
                  "they had become empty.\n", restarted);
      }
    }

    /*
      Maximization: reestimate the GMM parameters.
    */
    VL_XCAT(_vl_gmm_maximization_, SFX)
      (self,self->posteriors,self->priors,self->covariances,self->means,data,numData) ;
  }
  return LL;
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movsd 0x3f395(%rip), %xmm0    # 0x59380
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
cvtsd2ss %xmm0, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x3f368(%rip), %xmm0    # 0x59380
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
cvtsd2ss %xmm0, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x60(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x1a6e0
movq 0x60(%rsp), %rdi
callq 0x1b7b0
movq $0x0, 0x48(%rsp)
movb $0x1, %al
testb $0x1, %al
jne 0x1a073
jmp 0x1a2a7
movq 0x60(%rsp), %rax
cmpl $0x1, 0x30(%rax)
jle 0x1a09c
callq 0x91a0
movq %rax, %rcx
leaq 0x3f485(%rip), %rdi     # 0x59512
movb $0x0, %al
callq *%rcx
callq 0x93b0
movsd %xmm0, 0x28(%rsp)
movq 0x60(%rsp), %rax
movq 0x50(%rax), %rdi
movq 0x60(%rsp), %rax
movq 0x10(%rax), %rsi
movq 0x50(%rsp), %rdx
movq 0x60(%rsp), %rax
movq 0x48(%rax), %rcx
movq 0x60(%rsp), %rax
movq 0x38(%rax), %r8
movq 0x60(%rsp), %rax
movq 0x8(%rax), %r9
movq 0x60(%rsp), %rax
movq 0x40(%rax), %r10
movq 0x58(%rsp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x9930
movsd %xmm0, 0x30(%rsp)
movq 0x60(%rsp), %rax
cmpl $0x1, 0x30(%rax)
jle 0x1a120
callq 0x91a0
movq %rax, 0x18(%rsp)
callq 0x93b0
movq 0x18(%rsp), %rcx
subsd 0x28(%rsp), %xmm0
leaq 0x3f41a(%rip), %rdi     # 0x59536
movb $0x1, %al
callq *%rcx
movq 0x60(%rsp), %rax
cmpl $0x0, 0x30(%rax)
je 0x1a155
callq 0x91a0
movq %rax, %rcx
movq 0x48(%rsp), %rsi
movsd 0x30(%rsp), %xmm0
movsd 0x30(%rsp), %xmm1
subsd 0x38(%rsp), %xmm1
leaq 0x3f414(%rip), %rdi     # 0x59565
movb $0x2, %al
callq *%rcx
movq 0x48(%rsp), %rax
movq 0x60(%rsp), %rcx
cmpq 0x20(%rcx), %rax
jb 0x1a191
movq 0x60(%rsp), %rax
cmpl $0x0, 0x30(%rax)
je 0x1a18c
callq 0x91a0
movq %rax, %rcx
movq 0x60(%rsp), %rax
movq 0x20(%rax), %rsi
leaq 0x3f419(%rip), %rdi     # 0x595a1
movb $0x0, %al
callq *%rcx
jmp 0x1a2a7
movsd 0x30(%rsp), %xmm0
subsd 0x38(%rsp), %xmm0
divsd 0x30(%rsp), %xmm0
callq 0x1c670
movsd %xmm0, 0x20(%rsp)
cmpq $0x0, 0x48(%rsp)
jbe 0x1a1ef
movsd 0x3f18a(%rip), %xmm0    # 0x59348
ucomisd 0x20(%rsp), %xmm0
jbe 0x1a1ef
movq 0x60(%rsp), %rax
cmpl $0x0, 0x30(%rax)
je 0x1a1ea
callq 0x91a0
movq %rax, %rcx
movsd 0x20(%rsp), %xmm0
leaq 0x3f411(%rip), %rdi     # 0x595f7
movb $0x1, %al
callq *%rcx
jmp 0x1a2a7
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
cmpq $0x1, 0x48(%rsp)
jbe 0x1a258
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x1c690
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
seta %al
andb $0x1, %al
movzbl %al, %eax
movq 0x60(%rsp), %rcx
cmpl $0x0, 0x30(%rcx)
setg %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1a256
callq 0x91a0
movq %rax, %rcx
movq 0x40(%rsp), %rsi
leaq 0x3f402(%rip), %rdi     # 0x59654
movb $0x0, %al
callq *%rcx
jmp 0x1a258
movq 0x60(%rsp), %rdi
movq 0x60(%rsp), %rax
movq 0x50(%rax), %rsi
movq 0x60(%rsp), %rax
movq 0x48(%rax), %rdx
movq 0x60(%rsp), %rax
movq 0x40(%rax), %rcx
movq 0x60(%rsp), %rax
movq 0x38(%rax), %r8
movq 0x58(%rsp), %r9
movq 0x50(%rsp), %rax
movq %rax, (%rsp)
callq 0x1acd0
movq 0x48(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x48(%rsp)
jmp 0x1a068
movsd 0x30(%rsp), %xmm0
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)