// File: hanhwi[P]SimPoint/analysiscode/Simpoint.cpp
// Function: Simpoint::loadInitialCentersFromLabels(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Dataset const&)
Dataset *Simpoint::loadInitialCentersFromLabels(const string &file, const Dataset &data) {
    Utilities::check(isRegularFile(file), 
        "Simpoint::loadInitialCentersFromLabels() not regular file: " + file);
    int n = data.numRows(), d = data.numCols();
    ifstream input(file.c_str());
    Utilities::check(input.is_open(),
        "Simpoint::loadInitialCentersFromLabels() could not open file " + file);

    // load all the labels, find the largest one in the process (this is
    // the number of clusters)
    map<string, int> labelMap; // map from user-given (external) label to actual (internal) label
    vector<int> labels(n);
    for (int i = 0; i < n; i++) {
        string externalLabel;
        input >> externalLabel;
        map<string, int>::iterator itr = labelMap.find(externalLabel);
        if (itr == labelMap.end()) {
            int lmsize = labelMap.size();
            labelMap[externalLabel] = lmsize;
            itr = labelMap.find(externalLabel);
        }
        labels[i] = itr->second;
    }

    int k = labelMap.size();

    // create the initial centers
    Dataset *centers = new Dataset(k, d);
    for (int i = 0; i < k; i++) { centers->setWeight(i, 0.0); }

    // assign each datapoint to each center
    for (int i = 0; i < n; i++) {
        double wt = data.getWeight(i);
        (*centers)[labels[i]].multAndAdd(data[i], wt);
        centers->setWeight(labels[i], centers->getWeight(labels[i]) + wt);
    }

    // normalize each center
    for (int i = 0; i < k; i++) { (*centers)[i] /= centers->getWeight(i); }

    return centers;
}

// Assembly:
subq $0x3e8, %rsp            # imm = 0x3E8
movq %rdi, 0x3e0(%rsp)
movq %rsi, 0x3d8(%rsp)
movq 0x3e0(%rsp), %rdi
callq 0x12540
movb %al, 0xb7(%rsp)
movq 0x3e0(%rsp), %rdx
leaq 0x1f99a(%rip), %rsi     # 0x336a4
leaq 0x3b8(%rsp), %rdi
movq %rdi, 0xb8(%rsp)
callq 0x7880
movb 0xb7(%rsp), %al
movq 0xb8(%rsp), %rsi
movzbl %al, %edi
callq 0x7480
jmp 0x13d38
leaq 0x3b8(%rsp), %rdi
callq 0x5788
movq 0x3d8(%rsp), %rdi
callq 0xc0c0
movl %eax, 0x3a8(%rsp)
movq 0x3d8(%rsp), %rdi
callq 0xc0d0
movl %eax, 0x3a4(%rsp)
movq 0x3e0(%rsp), %rdi
callq 0x5190
movq %rax, %rsi
leaq 0x198(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
movl $0x8, %edx
callq 0x56d0
movq 0xa8(%rsp), %rdi
callq 0x5630
movb %al, 0xb6(%rsp)
jmp 0x13dad
movq 0x3e0(%rsp), %rdx
leaq 0x1f924(%rip), %rsi     # 0x336e0
leaq 0x178(%rsp), %rdi
callq 0x7880
jmp 0x13dcb
movb 0xb6(%rsp), %al
movzbl %al, %edi
andl $0x1, %edi
leaq 0x178(%rsp), %rsi
callq 0x7480
jmp 0x13de7
leaq 0x178(%rsp), %rdi
callq 0x5788
leaq 0x148(%rsp), %rdi
callq 0x1a220
movslq 0x3a8(%rsp), %rax
movq %rax, 0x98(%rsp)
leaq 0x12f(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x10e30
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rdx
leaq 0x130(%rsp), %rdi
callq 0x10e40
jmp 0x13e45
leaq 0x12f(%rsp), %rdi
callq 0x10ec0
movl $0x0, 0x128(%rsp)
movl 0x128(%rsp), %eax
cmpl 0x3a8(%rsp), %eax
jge 0x1408e
leaq 0x108(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x5540
movq 0x90(%rsp), %rsi
leaq 0x198(%rsp), %rdi
callq 0x54c0
jmp 0x13e9d
leaq 0x148(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x7c00
movq %rax, 0x88(%rsp)
jmp 0x13ebc
movq 0x88(%rsp), %rax
movq %rax, 0x100(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x7c50
movq %rax, 0xf8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x7c30
testb $0x1, %al
jne 0x13eff
jmp 0x1403c
leaq 0x148(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x1a230
movq 0x70(%rsp), %rdi
movl %eax, 0xf4(%rsp)
movl 0xf4(%rsp), %eax
movl %eax, 0x7c(%rsp)
leaq 0x108(%rsp), %rsi
callq 0x1a240
movq %rax, 0x80(%rsp)
jmp 0x13f3f
movq 0x80(%rsp), %rax
movl 0x7c(%rsp), %ecx
movl %ecx, (%rax)
leaq 0x148(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x7c00
movq %rax, 0x68(%rsp)
jmp 0x13f69
movq 0x68(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0x100(%rsp)
jmp 0x1403c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
leaq 0x3b8(%rsp), %rdi
callq 0x5788
jmp 0x14383
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
jmp 0x14376
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x5788
jmp 0x14376
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
leaq 0x12f(%rsp), %rdi
callq 0x10ec0
jmp 0x14369
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x5788
jmp 0x1435c
leaq 0x100(%rsp), %rdi
callq 0x7ca0
movl 0x20(%rax), %eax
movl %eax, 0x64(%rsp)
movslq 0x128(%rsp), %rsi
leaq 0x130(%rsp), %rdi
callq 0x10dd0
movl 0x64(%rsp), %ecx
movl %ecx, (%rax)
leaq 0x108(%rsp), %rdi
callq 0x5788
movl 0x128(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x128(%rsp)
jmp 0x13e5d
leaq 0x148(%rsp), %rdi
callq 0x1a230
movl %eax, 0xe4(%rsp)
movl $0x30, %edi
callq 0x5380
movq %rax, 0x58(%rsp)
jmp 0x140b3
movq 0x58(%rsp), %rdi
movl 0xe4(%rsp), %esi
movl 0x3a4(%rsp), %edx
callq 0xaf10
jmp 0x140cd
movq 0x58(%rsp), %rax
movq %rax, 0xd8(%rsp)
movl $0x0, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x14164
movq 0xd8(%rsp), %rdi
movl 0xd4(%rsp), %esi
xorps %xmm0, %xmm0
callq 0xc150
jmp 0x1410e
jmp 0x14110
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x140e5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
jmp 0x1435c
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3b0(%rsp)
movl %eax, 0x3ac(%rsp)
movl $0x30, %esi
callq 0x5390
jmp 0x1435c
movl $0x0, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
cmpl 0x3a8(%rsp), %eax
jge 0x142aa
movq 0x3d8(%rsp), %rdi
movl 0xd0(%rsp), %esi
callq 0x10d30
movsd %xmm0, 0x50(%rsp)
jmp 0x1419f
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0xc8(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x40(%rsp)
movslq 0xd0(%rsp), %rsi
leaq 0x130(%rsp), %rdi
callq 0x10dd0
movq 0x40(%rsp), %rdi
movslq (%rax), %rsi
callq 0xc130
movq %rax, 0x48(%rsp)
movq 0x3d8(%rsp), %rdi
movslq 0xd0(%rsp), %rsi
callq 0xc0f0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
movsd 0xc8(%rsp), %xmm0
callq 0x91b0
jmp 0x1420f
movq 0xd8(%rsp), %rax
movq %rax, 0x18(%rsp)
movslq 0xd0(%rsp), %rsi
leaq 0x130(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x10dd0
movq 0x20(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x2c(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x30(%rsp)
movslq 0xd0(%rsp), %rsi
callq 0x10dd0
movq 0x30(%rsp), %rdi
movl (%rax), %esi
callq 0x10d30
movsd %xmm0, 0x38(%rsp)
jmp 0x1426f
movl 0x2c(%rsp), %esi
movq 0x18(%rsp), %rdi
movsd 0x38(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
addsd %xmm1, %xmm0
callq 0xc150
jmp 0x14292
jmp 0x14294
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x1416f
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jge 0x1431b
movq 0xd8(%rsp), %rdi
movl 0xc4(%rsp), %esi
callq 0x10d30
movsd %xmm0, 0x10(%rsp)
jmp 0x142e1
movq 0xd8(%rsp), %rdi
movslq 0xc4(%rsp), %rsi
callq 0xc130
movsd 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x9130
jmp 0x14306
jmp 0x14308
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x142b5
movq 0xd8(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x10ed0
leaq 0x148(%rsp), %rdi
callq 0x1a330
leaq 0x198(%rsp), %rdi
callq 0x5100
movq 0x8(%rsp), %rax
addq $0x3e8, %rsp            # imm = 0x3E8
retq
leaq 0x130(%rsp), %rdi
callq 0x10ed0
leaq 0x148(%rsp), %rdi
callq 0x1a330
leaq 0x198(%rsp), %rdi
callq 0x5100
movq 0x3b0(%rsp), %rdi
callq 0x5690