// File: 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:
subq $0x98, %rsp
movl %r9d, 0x44(%rsp)
movl %r8d, 0x48(%rsp)
movl %ecx, %eax
movl 0x44(%rsp), %ecx
movl %eax, 0x4c(%rsp)
movl %edx, %eax
movl 0x48(%rsp), %edx
movq %rsi, %r8
movl 0x4c(%rsp), %esi
movq %rdi, %r9
movb %al, %dil
movl 0xa8(%rsp), %eax
movb 0xa0(%rsp), %al
movq %r9, 0x90(%rsp)
movq %r8, 0x88(%rsp)
andb $0x1, %dil
movb %dil, 0x87(%rsp)
andb $0x1, %sil
movb %sil, 0x86(%rsp)
andb $0x1, %dl
movb %dl, 0x85(%rsp)
andb $0x1, %cl
movb %cl, 0x84(%rsp)
andb $0x1, %al
movb %al, 0x83(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x50(%rsp)
movl $0x1, 0x7c(%rsp)
movl $0x0, 0x78(%rsp)
movq 0x50(%rsp), %rdx
movl 0x78(%rsp), %eax
movl 0x84(%rdx), %ecx
addl 0x88(%rdx), %ecx
cmpl %ecx, %eax
jge 0x1f297
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jge 0x1eed4
movq 0x50(%rsp), %rdi
callq 0x1f560
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x1eeb3
movq 0x50(%rsp), %rcx
movl 0x78(%rsp), %eax
cmpl 0x84(%rcx), %eax
jne 0x1eef4
movq 0x50(%rsp), %rax
movl 0x8c(%rax), %eax
movl %eax, 0x7c(%rsp)
testb $0x1, 0x85(%rsp)
je 0x1ef4a
movq 0x50(%rsp), %rdi
callq 0x1fd30
movq 0x50(%rsp), %rdi
movq 0x88(%rsp), %rsi
movl 0x78(%rsp), %edx
callq 0x1fe80
movq 0x50(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x204f0
movq 0x50(%rsp), %rcx
movl 0x78(%rsp), %eax
cmpl 0x84(%rcx), %eax
jl 0x1ef48
movq 0x50(%rsp), %rdi
callq 0x20600
jmp 0x1ef4a
movq 0x50(%rsp), %rdi
callq 0x20700
testb $0x1, 0x87(%rsp)
je 0x1ef72
movq 0x50(%rsp), %rdi
callq 0x20900
movq 0x50(%rsp), %rdi
callq 0x20b10
movq 0x50(%rsp), %rcx
movl 0x78(%rsp), %eax
cmpl 0x84(%rcx), %eax
jl 0x1f09e
movq 0x50(%rsp), %rax
movsd 0x120(%rax), %xmm0
addsd 0x128(%rax), %xmm0
movsd %xmm0, 0x128(%rax)
movsd 0x120(%rax), %xmm0
movsd 0x120(%rax), %xmm2
movsd 0x148(%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x148(%rax)
testb $0x1, 0x86(%rsp)
je 0x1f00f
movq 0x50(%rsp), %rcx
movsd 0x120(%rcx), %xmm0
movsd %xmm0, 0x38(%rsp)
movq %rcx, %rdi
addq $0x130, %rdi            # imm = 0x130
movl 0x78(%rsp), %eax
subl 0x84(%rcx), %eax
movslq %eax, %rsi
callq 0x8c20
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%rax)
movq 0x50(%rsp), %rax
movsd 0x168(%rax), %xmm0
movsd 0x120(%rax), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
callq 0x339b0
movq 0x50(%rsp), %rax
movsd %xmm0, 0x168(%rax)
testb $0x1, 0x87(%rsp)
je 0x1f09c
movq 0x50(%rsp), %rax
movsd 0x150(%rax), %xmm0
addsd 0x158(%rax), %xmm0
movsd %xmm0, 0x158(%rax)
movsd 0x150(%rax), %xmm0
movsd 0x150(%rax), %xmm2
movsd 0x160(%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x160(%rax)
jmp 0x1f09e
testb $0x1, 0x84(%rsp)
je 0x1f17d
movq 0x50(%rsp), %rax
movq 0x88(%rsp), %rdi
addq $0xb70, %rdi            # imm = 0xB70
movl 0x1c(%rax), %esi
callq 0x4700
movq %rax, %rdi
leaq 0x3d156(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movl 0xa8(%rsp), %esi
addl $0x1, %esi
callq 0x4700
movq %rax, %rdi
leaq 0x3d135(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movq 0x50(%rsp), %rax
movl 0x78(%rsp), %esi
subl 0x84(%rax), %esi
addl $0x1, %esi
callq 0x4700
movq %rax, %rdi
leaq 0x3d10c(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movq 0x50(%rsp), %rax
movsd 0x120(%rax), %xmm0
callq 0x4790
movq %rax, %rdi
leaq 0x3d0e8(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movq 0x50(%rsp), %rax
movsd 0x150(%rax), %xmm0
callq 0x4790
movq %rax, %rdi
leaq 0x3d72e(%rip), %rsi     # 0x5c892
callq 0x4430
movq 0x88(%rsp), %rdi
addq $0xb70, %rdi            # imm = 0xB70
callq 0x42b0
testb $0x1, 0x83(%rsp)
je 0x1f285
movq 0x50(%rsp), %rax
movq 0x88(%rsp), %rdi
addq $0x1f70, %rdi           # imm = 0x1F70
movl 0x1c(%rax), %esi
callq 0x4700
movq %rax, %rdi
leaq 0x3d077(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movl 0xa8(%rsp), %esi
addl $0x1, %esi
callq 0x4700
movq %rax, %rdi
leaq 0x3d056(%rip), %rsi     # 0x5c228
callq 0x4430
movq %rax, %rdi
movq 0x50(%rsp), %rax
movl 0x78(%rsp), %esi
subl 0x84(%rax), %esi
addl $0x1, %esi
callq 0x4700
movl $0x0, 0x70(%rsp)
movq 0x50(%rsp), %rcx
movl 0x70(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x1f256
movq 0x88(%rsp), %rdi
addq $0x1f70, %rdi           # imm = 0x1F70
leaq 0x3d00b(%rip), %rsi     # 0x5c228
callq 0x4430
movq 0x50(%rsp), %rdi
movq %rax, 0x30(%rsp)
addq $0x90, %rdi
movslq 0x70(%rsp), %rsi
callq 0x8ba0
movq 0x30(%rsp), %rdi
movl (%rax), %esi
callq 0x4700
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x70(%rsp)
jmp 0x1f1f9
movq 0x88(%rsp), %rdi
addq $0x1f70, %rdi           # imm = 0x1F70
leaq 0x3d626(%rip), %rsi     # 0x5c892
callq 0x4430
movq 0x88(%rsp), %rdi
addq $0x1f70, %rdi           # imm = 0x1F70
callq 0x42b0
jmp 0x1f287
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x1ee8e
testb $0x1, 0x85(%rsp)
je 0x1f527
movl $0x0, 0x6c(%rsp)
movq 0x50(%rsp), %rcx
movl 0x6c(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x1f382
movl $0x0, 0x68(%rsp)
movq 0x50(%rsp), %rcx
movl 0x68(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x1f370
movq 0x50(%rsp), %rdi
addq $0x200, %rdi            # imm = 0x200
movslq 0x6c(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x68(%rsp), %rsi
callq 0x8c20
movq %rax, %rcx
movq 0x50(%rsp), %rax
movsd (%rcx), %xmm0
movsd %xmm0, 0x20(%rsp)
cvtsi2sdl 0x88(%rax), %xmm0
callq 0x4390
movaps %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
subsd %xmm1, %xmm0
callq 0x4760
movq 0x50(%rsp), %rdi
movsd %xmm0, 0x28(%rsp)
addq $0x218, %rdi            # imm = 0x218
movslq 0x6c(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x68(%rsp), %rsi
callq 0x8c20
movsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0x1f2c7
jmp 0x1f372
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x1f2ad
movq 0x50(%rsp), %rax
testb $0x1, 0x80(%rax)
je 0x1f525
movl $0x0, 0x64(%rsp)
movq 0x50(%rsp), %rcx
movl 0x64(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x1f46b
movl $0x0, 0x60(%rsp)
movq 0x50(%rsp), %rcx
movl 0x60(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x1f459
movq 0x50(%rsp), %rdi
addq $0x218, %rdi            # imm = 0x218
movslq 0x64(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x60(%rsp), %rsi
callq 0x8c20
movq %rax, %rcx
movq 0x50(%rsp), %rax
movsd (%rcx), %xmm0
movsd %xmm0, 0x18(%rsp)
addq $0x230, %rax            # imm = 0x230
movq %rax, 0x10(%rsp)
movq 0x88(%rsp), %rdi
addq $0x2cb8, %rdi           # imm = 0x2CB8
movslq 0x64(%rsp), %rsi
callq 0x8ba0
movq 0x10(%rsp), %rdi
movslq (%rax), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x60(%rsp), %rsi
callq 0x8c20
movsd 0x18(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x1f3b6
jmp 0x1f45b
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x1f39c
movl $0x0, 0x5c(%rsp)
movq 0x50(%rsp), %rdi
movl 0x5c(%rsp), %eax
movl %eax, 0xc(%rsp)
addq $0x58, %rdi
callq 0x16bb0
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x1f523
movl $0x0, 0x58(%rsp)
movq 0x50(%rsp), %rcx
movl 0x58(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x1f511
movq 0x88(%rsp), %rdi
addq $0x2ca0, %rdi           # imm = 0x2CA0
movslq 0x5c(%rsp), %rsi
callq 0x8ba0
movq 0x50(%rsp), %rdi
cvtsi2sdl (%rax), %xmm0
movsd %xmm0, (%rsp)
addq $0x230, %rdi            # imm = 0x230
movslq 0x5c(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x58(%rsp), %rsi
callq 0x8c20
movsd (%rsp), %xmm1
movsd (%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x1f4a0
jmp 0x1f513
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x1f473
jmp 0x1f525
jmp 0x1f527
movq 0x50(%rsp), %rax
cvtsi2sdl 0x88(%rax), %xmm0
callq 0x4390
movq 0x50(%rsp), %rax
subsd 0x168(%rax), %xmm0
movsd %xmm0, 0x168(%rax)
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)