// File: /workspace/github_cpp_makefile_star2_O2/bobverity[P]MavericK/MCMCobject_noAdmixture.cpp
// Function: MCMCobject_noAdmixture::perform_MCMC(globals&, bool, bool, bool, bool, bool, int)
void MCMCobject_noAdmixture::perform_MCMC(globals &globals, bool drawAlleleFreqs, bool storeLoglike, bool fixLabels, bool outputLikelihood, bool outputPosteriorGrouping, int mainRep) {
    
    // perform MCMC
    int thinSwitch = 1;
    for (int rep=0; rep<(burnin+samples); rep++) {
        
        // thinning loop (becomes active after burn-in)
        for (int thin=0; thin<thinSwitch; thin++) {
            
            // update group allocation of all individuals
            group_update();
            
        }
        if (rep==burnin)
            thinSwitch = thinning;
        
        // if fix label-switching problem
        if (fixLabels) {
            // calculate logQmatrix_ind_new for this iteration
            produceQmatrix();
        
            // fix label-switching problem
            chooseBestLabelPermutation(globals, rep);
        
            // add logQmatrix_ind_new to logQmatrix_ind_running
            updateQmatrix(rep);
            
            // store Qmatrix values if no longer in burn-in
            if (rep>=burnin)
                storeQmatrix();
        }
        
        // calculate marginal likelihood
        d_logLikeGroup();
        
        // optionally draw allele frequencies and calculate joint likelihood
        if (drawAlleleFreqs) {
            drawFreqs();
            d_logLikeJoint();
        }
        
        // add likelihoods to running sums
        if (rep>=burnin) {
            logLikeGroup_sum += logLikeGroup;
            logLikeGroup_sumSquared += logLikeGroup*logLikeGroup;
            
            if (storeLoglike) {
                logLikeGroup_store[rep-burnin] = logLikeGroup;
            }

            harmonic = logSum(harmonic, -logLikeGroup);
            if (drawAlleleFreqs) {
                logLikeJoint_sum += logLikeJoint;
                logLikeJoint_sumSquared += logLikeJoint*logLikeJoint;
            }
        }
        
        // write to outputLikelihoods file
        if (outputLikelihood) {
            globals.outputLikelihood_fileStream << K << "," << mainRep+1 << "," << rep-burnin+1 << "," << logLikeGroup << "," << logLikeJoint << "\n";
            globals.outputLikelihood_fileStream.flush();
        }
        
        // write to outputPosteriorGrouping file
        if (outputPosteriorGrouping) {
            globals.outputPosteriorGrouping_fileStream << K << "," << mainRep+1 << "," << rep-burnin+1;
            for (int i=0; i<n; i++) {
                globals.outputPosteriorGrouping_fileStream << "," << group[i];
            }
            globals.outputPosteriorGrouping_fileStream << "\n";
            globals.outputPosteriorGrouping_fileStream.flush();
        }
            
    } // end of MCMC

    
    // finish off Qmatrices
    if (fixLabels) {
        
        // finish off individual level Qmatrix
        for (int i=0; i<n; i++) {
            for (int k=0; k<K; k++) {
                Qmatrix_ind[i][k] = exp(logQmatrix_ind[i][k] - log(double(samples)));
            }
        }
        
        // calculate population level Qmatrices
        if (outputQmatrix_pop_on) {
            for (int i=0; i<n; i++) {
                for (int k=0; k<K; k++) {
                    Qmatrix_pop[globals.pop_index[i]][k] += Qmatrix_ind[i][k];
                }
            }
            for (int i=0; i<int(uniquePops.size()); i++) {
                for (int k=0; k<K; k++) {
                    Qmatrix_pop[i][k] /= double(globals.uniquePop_counts[i]);
                }
            }
        }
    } // end if fixLabels
    
    // finish off harmonic mean
    harmonic = log(double(samples))-harmonic;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %r9d, 0x1c(%rsp)
movl %r8d, 0x4(%rsp)
movl %ecx, 0x18(%rsp)
movl %edx, 0x8(%rsp)
movq %rdi, %rbx
movl 0x68(%rsp), %eax
leaq 0xb70(%rsi), %rcx
movq %rcx, 0x20(%rsp)
incl %eax
movl %eax, (%rsp)
movq %rsi, 0x10(%rsp)
leaq 0x1f70(%rsi), %r15
pushq $0x1
popq %r12
xorl %r14d, %r14d
leaq 0x1bb84(%rip), %rbp     # 0x27240
movl 0x88(%rbx), %eax
addl 0x84(%rbx), %eax
cmpl %eax, %r14d
jge 0xb939
testl %r12d, %r12d
movl $0x0, %r13d
cmovgl %r12d, %r13d
subl $0x1, %r13d
jb 0xb6ee
movq %rbx, %rdi
callq 0xbab2
jmp 0xb6de
cmpl 0x84(%rbx), %r14d
jne 0xb6fe
movl 0x8c(%rbx), %r12d
cmpb $0x0, 0x4(%rsp)
je 0xb733
movq %rbx, %rdi
callq 0xbd72
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0xbe30
movq %rbx, %rdi
callq 0xc0dc
cmpl 0x84(%rbx), %r14d
jl 0xb733
movq %rbx, %rdi
callq 0xc152
movq %rbx, %rdi
callq 0xc1c8
cmpb $0x0, 0x8(%rsp)
je 0xb752
movq %rbx, %rdi
callq 0xc2d8
movq %rbx, %rdi
callq 0xc3d2
movl %r14d, %eax
subl 0x84(%rbx), %eax
jl 0xb806
movsd 0x120(%rbx), %xmm1
movsd 0x128(%rbx), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x128(%rbx)
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
addsd 0x148(%rbx), %xmm0
movsd %xmm0, 0x148(%rbx)
cmpb $0x0, 0x18(%rsp)
je 0xb7b2
cltq
movq 0x130(%rbx), %rcx
movsd %xmm1, (%rcx,%rax,8)
movsd 0x120(%rbx), %xmm1
xorpd 0x1b876(%rip), %xmm1    # 0x27030
movsd 0x168(%rbx), %xmm0
callq 0x14ce5
movsd %xmm0, 0x168(%rbx)
cmpb $0x0, 0x8(%rsp)
je 0xb806
movsd 0x150(%rbx), %xmm0
movsd 0x158(%rbx), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x158(%rbx)
mulsd %xmm0, %xmm0
addsd 0x160(%rbx), %xmm0
movsd %xmm0, 0x160(%rbx)
cmpb $0x0, 0x1c(%rsp)
je 0xb8a2
movl 0x1c(%rbx), %esi
movq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0x3570
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
movq %rax, %rdi
movl (%rsp), %esi
callq 0x3570
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
movl %r14d, %esi
subl 0x84(%rbx), %esi
incl %esi
movq %rax, %rdi
callq 0x3570
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
movsd 0x120(%rbx), %xmm0
movq %rax, %rdi
callq 0x34d0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
movsd 0x150(%rbx), %xmm0
movq %rax, %rdi
callq 0x34d0
movq %rax, %rdi
leaq 0x1c026(%rip), %rsi     # 0x278bb
callq 0x3350
movq %r13, %rdi
callq 0x3230
cmpb $0x0, 0x60(%rsp)
je 0xb918
movl 0x1c(%rbx), %esi
movq %r15, %rdi
callq 0x3570
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
movq %rax, %rdi
movl (%rsp), %esi
callq 0x3570
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3350
incl %r14d
movl %r14d, %esi
subl 0x84(%rbx), %esi
movq %rax, %rdi
callq 0x3570
xorl %r13d, %r13d
movslq 0x20(%rbx), %rax
movq %r15, %rdi
cmpq %rax, %r13
jge 0xb920
movq %rbp, %rsi
callq 0x3350
movq 0x90(%rbx), %rcx
movl (%rcx,%r13,4), %esi
movq %rax, %rdi
callq 0x3570
incq %r13
jmp 0xb8ec
incl %r14d
jmp 0xb6bc
leaq 0x1bf94(%rip), %rsi     # 0x278bb
callq 0x3350
movq %r15, %rdi
callq 0x3230
jmp 0xb6bc
cmpb $0x0, 0x4(%rsp)
je 0xba85
xorl %r14d, %r14d
movslq 0x20(%rbx), %rax
cmpq %rax, %r14
jge 0xb9b2
imulq $0x18, %r14, %r15
xorl %r12d, %r12d
movslq 0x1c(%rbx), %rax
cmpq %rax, %r12
jge 0xb9ad
movq 0x200(%rbx), %rax
movq (%rax,%r15), %rax
movsd (%rax,%r12,8), %xmm0
movsd %xmm0, 0x8(%rsp)
cvtsi2sdl 0x88(%rbx), %xmm0
callq 0x32d0
movsd 0x8(%rsp), %xmm1
subsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x35c0
movq 0x218(%rbx), %rax
movq (%rax,%r15), %rax
movsd %xmm0, (%rax,%r12,8)
incq %r12
jmp 0xb957
incq %r14
jmp 0xb947
cmpb $0x1, 0x80(%rbx)
jne 0xba85
movl 0x1c(%rbx), %ecx
xorl %edx, %edx
testl %ecx, %ecx
cmovlel %edx, %ecx
testl %eax, %eax
cmovlel %edx, %eax
cmpq %rax, %rdx
je 0xba24
imulq $0x18, %rdx, %rsi
addq 0x218(%rbx), %rsi
movq 0x10(%rsp), %rdi
movq 0x2cb8(%rdi), %rdi
movq 0x230(%rbx), %r8
xorl %r9d, %r9d
cmpq %r9, %rcx
je 0xba1f
movq (%rsi), %r10
movsd (%r10,%r9,8), %xmm0
movslq (%rdi,%rdx,4), %r10
imulq $0x18, %r10, %r10
movq (%r8,%r10), %r10
addsd (%r10,%r9,8), %xmm0
movsd %xmm0, (%r10,%r9,8)
incq %r9
jmp 0xb9f4
incq %rdx
jmp 0xb9ce
movq 0x60(%rbx), %rax
subq 0x58(%rbx), %rax
shrq $0x5, %rax
movl 0x1c(%rbx), %ecx
xorl %edx, %edx
testl %ecx, %ecx
cmovlel %edx, %ecx
testl %eax, %eax
cmovlel %edx, %eax
cmpq %rax, %rdx
je 0xba85
movq 0x10(%rsp), %rsi
movq 0x2ca0(%rsi), %rsi
imulq $0x18, %rdx, %rdi
addq 0x230(%rbx), %rdi
xorl %r8d, %r8d
cmpq %r8, %rcx
je 0xba80
cvtsi2sdl (%rsi,%rdx,4), %xmm0
movq (%rdi), %r9
movsd (%r9,%r8,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%r9,%r8,8)
incq %r8
jmp 0xba5e
incq %rdx
jmp 0xba3f
cvtsi2sdl 0x88(%rbx), %xmm0
callq 0x32d0
subsd 0x168(%rbx), %xmm0
movsd %xmm0, 0x168(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop