// File: mapequation[P]partition-validation/./partition-validation.h
// Function: Partitions::wpJaccardDist(Partition*, Partition*)
double Partitions::wpJaccardDist(Partition *partition1, Partition *partition2) {
    auto partition1Id = partition1->partitionId;
    auto partition2Id = partition2->partitionId;

    if (partition1Id > partition2Id)
        swap(partition1Id, partition2Id);

    auto lookup = wpJaccardDistLookUp.find(make_pair(partition1Id, partition2Id));

    if (lookup != end(wpJaccardDistLookUp))
        return lookup->second;

    auto partition1Size = partition1->clusterSizes.size();
    auto partition2Size = partition2->clusterSizes.size();

    vector<double> maxClusterSimilarityPartition1(partition1Size, 0.0);
    vector<double> maxClusterSimilarityPartition2(partition2Size, 0.0);

    unordered_map<pair<int, int>, int, pairhash> jointM;

    for (int k = 0; k < nNodes; k++) {
        for (auto id1: partition1->assignments[k]) {
            for (auto &id2: partition2->assignments[k]) {
                jointM[make_pair(id1, id2)]++;
            }
        }
    }

    for (auto &[ids, nCommon]: jointM) {
        int nTotal = partition1->clusterSizes[ids.first] + partition2->clusterSizes[ids.second] - nCommon;
        double clusterSim = 1.0 * nCommon / nTotal;
        maxClusterSimilarityPartition1[ids.first] = max(clusterSim, maxClusterSimilarityPartition1[ids.first]);
        maxClusterSimilarityPartition2[ids.second] = max(clusterSim, maxClusterSimilarityPartition2[ids.second]);
    }

    int nAssignments1 = 0;
    double sim1 = 0.0;

    for (auto i = 0; i < static_cast<int>(partition1Size); i++) {
        sim1 += maxClusterSimilarityPartition1[i] * partition1->clusterSizes[i];
        nAssignments1 += partition1->clusterSizes[i];
    }

    sim1 /= 1.0 * nAssignments1;

    int nAssignments2 = 0;
    double sim2 = 0.0;

    for (auto i = 0; i < static_cast<int>(partition2Size); i++) {
        sim2 += maxClusterSimilarityPartition2[i] * partition2->clusterSizes[i];
        nAssignments2 += partition2->clusterSizes[i];
    }

    sim2 /= 1.0 * nAssignments2;

    double dist = 1.0 - 0.5 * sim1 - 0.5 * sim2;

    wpJaccardDistLookUp[make_pair(partition1Id, partition2Id)] = dist;

    return dist;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x28(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jle 0x3809
leaq -0x24(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x81b0
leaq -0x24(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x8210
movq -0x1b8(%rbp), %rdi
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %rsi
callq 0x81e0
movq -0x1b8(%rbp), %rdi
movq %rax, -0x30(%rbp)
callq 0x8270
movq %rax, -0x40(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x8240
testb $0x1, %al
jne 0x3851
jmp 0x3869
leaq -0x30(%rbp), %rdi
callq 0x82a0
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x3ffe
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
callq 0x82d0
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
callq 0x82d0
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x1c8(%rbp)
movq $0x0, -0x70(%rbp)
leaq -0x71(%rbp), %rdi
movq %rdi, -0x1c0(%rbp)
callq 0x82f0
movq -0x1c8(%rbp), %rsi
movq -0x1c0(%rbp), %rcx
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rdx
callq 0x8310
jmp 0x38cb
leaq -0x71(%rbp), %rdi
callq 0x8390
movq -0x50(%rbp), %rax
movq %rax, -0x1d8(%rbp)
movq $0x0, -0xa8(%rbp)
leaq -0xa9(%rbp), %rdi
movq %rdi, -0x1d0(%rbp)
callq 0x82f0
movq -0x1d8(%rbp), %rsi
movq -0x1d0(%rbp), %rcx
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
callq 0x8310
jmp 0x3920
leaq -0xa9(%rbp), %rdi
callq 0x8390
leaq -0xe8(%rbp), %rdi
callq 0x83b0
movl $0x0, -0xec(%rbp)
movq -0x1b8(%rbp), %rcx
movl -0xec(%rbp), %eax
cmpl 0x4d8(%rcx), %eax
jge 0x3b33
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movslq -0xec(%rbp), %rsi
callq 0x83d0
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rdi
callq 0x83f0
movq %rax, -0x100(%rbp)
movq -0xf8(%rbp), %rdi
callq 0x8420
movq %rax, -0x108(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x8450
testb $0x1, %al
jne 0x39b8
jmp 0x3b1d
leaq -0x100(%rbp), %rdi
callq 0x8490
movl (%rax), %eax
movl %eax, -0x10c(%rbp)
movq -0x20(%rbp), %rdi
addq $0x8, %rdi
movslq -0xec(%rbp), %rsi
callq 0x83d0
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rdi
callq 0x83f0
movq %rax, -0x120(%rbp)
movq -0x118(%rbp), %rdi
callq 0x8420
movq %rax, -0x128(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x8450
testb $0x1, %al
jne 0x3a29
jmp 0x3b0a
leaq -0x120(%rbp), %rdi
callq 0x8490
movq %rax, -0x130(%rbp)
movq -0x130(%rbp), %rsi
leaq -0x10c(%rbp), %rdi
callq 0x8210
movq %rax, -0x1e0(%rbp)
jmp 0x3a58
movq -0x1e0(%rbp), %rax
movq %rax, -0x138(%rbp)
leaq -0xe8(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x84b0
movq %rax, -0x1e8(%rbp)
jmp 0x3a82
movq -0x1e8(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
leaq -0x120(%rbp), %rdi
callq 0x84e0
jmp 0x3a0d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x71(%rbp), %rdi
callq 0x8390
jmp 0x400c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xa9(%rbp), %rdi
callq 0x8390
jmp 0x3ff3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x86f0
leaq -0xa0(%rbp), %rdi
callq 0x8710
jmp 0x3ff3
jmp 0x3b0c
leaq -0x100(%rbp), %rdi
callq 0x84e0
jmp 0x399c
jmp 0x3b1f
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0x3942
leaq -0xe8(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rdi
callq 0x8500
movq %rax, -0x148(%rbp)
movq -0x140(%rbp), %rdi
callq 0x8530
movq %rax, -0x150(%rbp)
leaq -0x148(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x8560
testb $0x1, %al
jne 0x3b83
jmp 0x3d1d
leaq -0x148(%rbp), %rdi
callq 0x8590
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rdi
callq 0x85c0
movq %rax, -0x160(%rbp)
movq -0x158(%rbp), %rdi
callq 0x85e0
movq %rax, -0x168(%rbp)
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
movq -0x160(%rbp), %rsi
callq 0x8600
movq %rax, -0x1f0(%rbp)
jmp 0x3bd9
movq -0x1f0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x1fc(%rbp)
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
movq -0x160(%rbp), %rsi
addq $0x4, %rsi
callq 0x8600
movq %rax, -0x1f8(%rbp)
jmp 0x3c09
movl -0x1fc(%rbp), %eax
movq -0x1f8(%rbp), %rcx
movl (%rcx), %ecx
addl %ecx, %eax
movq -0x168(%rbp), %rcx
movl (%rcx), %ecx
subl %ecx, %eax
movl %eax, -0x16c(%rbp)
movq -0x168(%rbp), %rax
cvtsi2sdl (%rax), %xmm0
cvtsi2sdl -0x16c(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x178(%rbp)
movq -0x160(%rbp), %rax
movslq (%rax), %rsi
leaq -0x68(%rbp), %rdi
callq 0x8670
movq %rax, %rsi
leaq -0x178(%rbp), %rdi
callq 0x8630
movq %rax, -0x208(%rbp)
jmp 0x3c75
movq -0x208(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x218(%rbp)
movq -0x160(%rbp), %rax
movslq (%rax), %rsi
leaq -0x68(%rbp), %rdi
callq 0x8670
movsd -0x218(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x160(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x8670
movq %rax, %rsi
leaq -0x178(%rbp), %rdi
callq 0x8630
movq %rax, -0x210(%rbp)
jmp 0x3cd6
movq -0x210(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x220(%rbp)
movq -0x160(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x8670
movsd -0x220(%rbp), %xmm0
movsd %xmm0, (%rax)
leaq -0x148(%rbp), %rdi
callq 0x8690
jmp 0x3b67
movl $0x0, -0x17c(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x188(%rbp)
movl $0x0, -0x18c(%rbp)
movl -0x18c(%rbp), %eax
movq -0x48(%rbp), %rcx
cmpl %ecx, %eax
jge 0x3df8
movslq -0x18c(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x8670
movsd (%rax), %xmm0
movsd %xmm0, -0x230(%rbp)
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
leaq -0x18c(%rbp), %rsi
callq 0x8600
movq %rax, -0x228(%rbp)
jmp 0x3d87
movsd -0x230(%rbp), %xmm0
movq -0x228(%rbp), %rax
cvtsi2sdl (%rax), %xmm2
movsd -0x188(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x188(%rbp)
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
leaq -0x18c(%rbp), %rsi
callq 0x8600
movq %rax, -0x238(%rbp)
jmp 0x3dcf
movq -0x238(%rbp), %rax
movl (%rax), %eax
addl -0x17c(%rbp), %eax
movl %eax, -0x17c(%rbp)
movl -0x18c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18c(%rbp)
jmp 0x3d3c
cvtsi2sdl -0x17c(%rbp), %xmm0
movsd 0x14200(%rip), %xmm1    # 0x18008
mulsd %xmm0, %xmm1
movsd -0x188(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x188(%rbp)
movl $0x0, -0x190(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x198(%rbp)
movl $0x0, -0x19c(%rbp)
movl -0x19c(%rbp), %eax
movq -0x50(%rbp), %rcx
cmpl %ecx, %eax
jge 0x3efe
movslq -0x19c(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x8670
movsd (%rax), %xmm0
movsd %xmm0, -0x248(%rbp)
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
leaq -0x19c(%rbp), %rsi
callq 0x8600
movq %rax, -0x240(%rbp)
jmp 0x3e8d
movsd -0x248(%rbp), %xmm0
movq -0x240(%rbp), %rax
cvtsi2sdl (%rax), %xmm2
movsd -0x198(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x198(%rbp)
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
leaq -0x19c(%rbp), %rsi
callq 0x8600
movq %rax, -0x250(%rbp)
jmp 0x3ed5
movq -0x250(%rbp), %rax
movl (%rax), %eax
addl -0x190(%rbp), %eax
movl %eax, -0x190(%rbp)
movl -0x19c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x19c(%rbp)
jmp 0x3e3f
movq -0x1b8(%rbp), %rax
cvtsi2sdl -0x190(%rbp), %xmm1
movsd -0x198(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x198(%rbp)
movsd -0x188(%rbp), %xmm1
movsd 0x140df(%rip), %xmm2    # 0x18010
mulsd %xmm2, %xmm1
movsd 0x140cb(%rip), %xmm0    # 0x18008
addsd %xmm0, %xmm1
movsd -0x198(%rbp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x1a8(%rbp)
movsd -0x1a8(%rbp), %xmm0
movsd %xmm0, -0x268(%rbp)
movq %rax, -0x260(%rbp)
leaq -0x24(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x8210
movq %rax, -0x258(%rbp)
jmp 0x3f86
movq -0x260(%rbp), %rdi
movq -0x258(%rbp), %rax
movq %rax, -0x1b0(%rbp)
leaq -0x1b0(%rbp), %rsi
callq 0x86c0
movq %rax, -0x270(%rbp)
jmp 0x3fb0
movq -0x270(%rbp), %rax
movsd -0x268(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x1a8(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x86f0
leaq -0xa0(%rbp), %rdi
callq 0x8710
leaq -0x68(%rbp), %rdi
callq 0x8710
jmp 0x3ffe
leaq -0x68(%rbp), %rdi
callq 0x8710
jmp 0x400c
movsd -0x8(%rbp), %xmm0
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x34a0
nopw %cs:(%rax,%rax)