// File: bobverity[P]MavericK/MCMCobject_noAdmixture.cpp
// Function: MCMCobject_noAdmixture::chooseBestLabelPermutation(globals&, int)
void MCMCobject_noAdmixture::chooseBestLabelPermutation(globals &globals, int rep) {
    
    // calculate cost matrix from old and new Qmatrices
    for (int k1=0; k1<K; k1++) {
        for (int k2=0; k2<K; k2++) {
            costMat[k1][k2] = 0;
            for (int i=0; i<n; i++) {
                costMat[k1][k2] += exp(logQmatrix_ind_new[i][k1])*(logQmatrix_ind_new[i][k1]-logQmatrix_ind_running[i][k2]);
            }
        }
    }
    
    // find best permutation of current labels
    bestPerm = hungarian(costMat, edgesLeft, edgesRight, blockedLeft, blockedRight, globals.outputLog_on, globals.outputLog_fileStream);

    // define bestPermOrder. If the numbers 1:m_K are placed in best-perm-order then we arrive back at bestPerm. In R terms we would say bestPermOrder=order(bestPerm).
    bool performSwap = false;
    for (int k=0; k<K; k++) {
        bestPermOrder[bestPerm[k]] = k;
        if (bestPerm[k]!=k)
            performSwap = true;
    }
    
    // swap labels if necessary
    if (performSwap) {
        
        // update grouping to reflect swapped labels
        for (int i=0; i<n; i++) {
            group[i] = bestPerm[group[i]-1]+1;
        }
        
        // update allele counts to reflect swapped labels
        old_alleleCounts = alleleCounts;
        old_alleleCountsTotals = alleleCountsTotals;
        for (int k=0; k<K; k++) {
            alleleCounts[k] = old_alleleCounts[bestPermOrder[k]];
            alleleCountsTotals[k] = old_alleleCountsTotals[bestPermOrder[k]];
        }
        
        // update logQmatrix_ind_new to reflect swapped labels
        logQmatrix_ind_old = logQmatrix_ind_new;
        for (int i=0; i<n; i++) {
            for (int k=0; k<K; k++) {
                logQmatrix_ind_new[i][k] = logQmatrix_ind_old[i][bestPermOrder[k]];
            }
        }
        
    }
    
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xd0(%rsp)
movq %rsi, 0xc8(%rsp)
movl %edx, 0xc4(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x80(%rsp)
movl $0x0, 0xc0(%rsp)
movq 0x80(%rsp), %rcx
movl 0xc0(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x20085
movl $0x0, 0xbc(%rsp)
movq 0x80(%rsp), %rcx
movl 0xbc(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x2006d
movq 0x80(%rsp), %rdi
addq $0x248, %rdi            # imm = 0x248
movslq 0xc0(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0xbc(%rsp), %rsi
callq 0x8c20
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x0, 0xb8(%rsp)
movq 0x80(%rsp), %rcx
movl 0xb8(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x20055
movq 0x80(%rsp), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
movslq 0xb8(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0xc0(%rsp), %rsi
callq 0x8c20
movsd (%rax), %xmm0
callq 0x4760
movq 0x80(%rsp), %rdi
movsd %xmm0, 0x70(%rsp)
addq $0x1d0, %rdi            # imm = 0x1D0
movslq 0xb8(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0xc0(%rsp), %rsi
callq 0x8c20
movq 0x80(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
addq $0x1e8, %rdi            # imm = 0x1E8
movslq 0xb8(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0xbc(%rsp), %rsi
callq 0x8c20
movsd 0x68(%rsp), %xmm0
movq 0x80(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x78(%rsp)
addq $0x248, %rdi            # imm = 0x248
movslq 0xc0(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0xbc(%rsp), %rsi
callq 0x8c20
movsd 0x70(%rsp), %xmm0
movsd 0x78(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x1ff32
jmp 0x20057
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x1fedc
jmp 0x2006f
movl 0xc0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc0(%rsp)
jmp 0x1feb9
movq 0x80(%rsp), %r9
movq %r9, %rsi
addq $0x248, %rsi            # imm = 0x248
movq %r9, %rdx
addq $0x290, %rdx            # imm = 0x290
movq %r9, %rcx
addq $0x2a8, %rcx            # imm = 0x2A8
movq %r9, %r8
addq $0x2c0, %r8             # imm = 0x2C0
addq $0x2d8, %r9             # imm = 0x2D8
movq 0xc8(%rsp), %rax
movb 0x2c3c(%rax), %r10b
movq 0xc8(%rsp), %rax
addq $0x970, %rax            # imm = 0x970
leaq 0xa0(%rsp), %rdi
andb $0x1, %r10b
movzbl %r10b, %r10d
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xb540
movq 0x80(%rsp), %rdi
addq $0x260, %rdi            # imm = 0x260
leaq 0xa0(%rsp), %rsi
callq 0xc6a0
leaq 0xa0(%rsp), %rdi
callq 0xc6e0
movb $0x0, 0x9f(%rsp)
movl $0x0, 0x98(%rsp)
movq 0x80(%rsp), %rcx
movl 0x98(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x201da
movq 0x80(%rsp), %rdi
movl 0x98(%rsp), %eax
movl %eax, 0x64(%rsp)
movq %rdi, %rax
addq $0x278, %rax            # imm = 0x278
movq %rax, 0x58(%rsp)
addq $0x260, %rdi            # imm = 0x260
movslq 0x98(%rsp), %rsi
callq 0x8ba0
movq 0x58(%rsp), %rdi
movslq (%rax), %rsi
callq 0x8ba0
movl 0x64(%rsp), %ecx
movq 0x80(%rsp), %rdi
movl %ecx, (%rax)
addq $0x260, %rdi            # imm = 0x260
movslq 0x98(%rsp), %rsi
callq 0x8ba0
movl (%rax), %eax
cmpl 0x98(%rsp), %eax
je 0x201c2
movb $0x1, 0x9f(%rsp)
jmp 0x201c4
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0x20133
testb $0x1, 0x9f(%rsp)
je 0x204e1
movl $0x0, 0x94(%rsp)
movq 0x80(%rsp), %rcx
movl 0x94(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x20284
movq 0x80(%rsp), %rdi
movq %rdi, %rax
addq $0x260, %rax            # imm = 0x260
movq %rax, 0x48(%rsp)
addq $0x90, %rdi
movslq 0x94(%rsp), %rsi
callq 0x8ba0
movq 0x48(%rsp), %rdi
movl (%rax), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x8ba0
movq 0x80(%rsp), %rdi
movl (%rax), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
addq $0x90, %rdi
movslq 0x94(%rsp), %rsi
callq 0x8ba0
movl 0x54(%rsp), %ecx
movl %ecx, (%rax)
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x201f3
movq 0x80(%rsp), %rdi
movq %rdi, %rsi
addq $0xa8, %rsi
addq $0xf0, %rdi
callq 0x16070
movq 0x80(%rsp), %rdi
movq %rdi, %rsi
addq $0xc0, %rsi
addq $0x108, %rdi            # imm = 0x108
callq 0x16c30
movl $0x0, 0x90(%rsp)
movq 0x80(%rsp), %rcx
movl 0x90(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x203c3
movq 0x80(%rsp), %rdi
movq %rdi, %rax
addq $0xf0, %rax
movq %rax, 0x28(%rsp)
addq $0x278, %rdi            # imm = 0x278
movslq 0x90(%rsp), %rsi
callq 0x8ba0
movq 0x28(%rsp), %rdi
movslq (%rax), %rsi
callq 0x8c40
movq 0x80(%rsp), %rdi
movq %rax, 0x30(%rsp)
addq $0xa8, %rdi
movslq 0x90(%rsp), %rsi
callq 0x8c40
movq 0x30(%rsp), %rsi
movq %rax, %rdi
callq 0x16c30
movq 0x80(%rsp), %rdi
movq %rdi, %rax
addq $0x108, %rax            # imm = 0x108
movq %rax, 0x38(%rsp)
addq $0x278, %rdi            # imm = 0x278
movslq 0x90(%rsp), %rsi
callq 0x8ba0
movq 0x38(%rsp), %rdi
movslq (%rax), %rsi
callq 0x8c60
movq 0x80(%rsp), %rdi
movq %rax, 0x40(%rsp)
addq $0xc0, %rdi
movslq 0x90(%rsp), %rsi
callq 0x8c60
movq 0x40(%rsp), %rsi
movq %rax, %rdi
callq 0x16330
movl 0x90(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x90(%rsp)
jmp 0x202cb
movq 0x80(%rsp), %rdi
movq %rdi, %rsi
addq $0x1d0, %rsi            # imm = 0x1D0
addq $0x1b8, %rdi            # imm = 0x1B8
callq 0x16ef0
movl $0x0, 0x8c(%rsp)
movq 0x80(%rsp), %rcx
movl 0x8c(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x204df
movl $0x0, 0x88(%rsp)
movq 0x80(%rsp), %rcx
movl 0x88(%rsp), %eax
cmpl 0x1c(%rcx), %eax
jge 0x204c7
movq 0x80(%rsp), %rdi
addq $0x1b8, %rdi            # imm = 0x1B8
movslq 0x8c(%rsp), %rsi
callq 0x8bc0
movq 0x80(%rsp), %rdi
movq %rax, 0x18(%rsp)
addq $0x278, %rdi            # imm = 0x278
movslq 0x88(%rsp), %rsi
callq 0x8ba0
movq 0x18(%rsp), %rdi
movslq (%rax), %rsi
callq 0x8c20
movq 0x80(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
addq $0x1d0, %rdi            # imm = 0x1D0
movslq 0x8c(%rsp), %rsi
callq 0x8bc0
movq %rax, %rdi
movslq 0x88(%rsp), %rsi
callq 0x8c20
movsd 0x20(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x2040f
jmp 0x204c9
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x203ec
jmp 0x204e1
addq $0xd8, %rsp
retq
nopl (%rax)