// File: epfml[P]Bi-Sent2Vec/src/productquantizer.cc
// Function: fasttext::ProductQuantizer::kmeans(float const*, float*, int, int)
void ProductQuantizer::kmeans(const real *x, real* c, int32_t n, int32_t d) {
  std::vector<int32_t> perm(n,0);
  std::iota(perm.begin(), perm.end(), 0);
  std::shuffle(perm.begin(), perm.end(), rng);
  for (auto i = 0; i < ksub_; i++) {
    memcpy (&c[i * d], x + perm[i] * d, d * sizeof(real));
  }
  uint8_t* codes = new uint8_t[n];
  for (auto i = 0; i < niter_; i++) {
    Estep(x, c, codes, d, n);
    MStep(x, c, codes, d, n);
  }
  delete [] codes;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movslq -0x1c(%rbp), %rax
movq %rax, -0x98(%rbp)
movl $0x0, -0x3c(%rbp)
leaq -0x3d(%rbp), %rdi
movq %rdi, -0x90(%rbp)
callq 0xe090
movq -0x98(%rbp), %rsi
movq -0x90(%rbp), %rcx
leaq -0x38(%rbp), %rdi
leaq -0x3c(%rbp), %rdx
callq 0xe0b0
jmp 0x1c838
leaq -0x3d(%rbp), %rdi
callq 0xe130
leaq -0x38(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0xea10
movq -0xa8(%rbp), %rdi
movq %rax, -0x58(%rbp)
callq 0xea40
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
movq -0x60(%rbp), %rsi
xorl %edx, %edx
callq 0x1d370
jmp 0x1c876
leaq -0x38(%rbp), %rdi
movq %rdi, -0xb0(%rbp)
callq 0xea10
movq -0xb0(%rbp), %rdi
movq %rax, -0x68(%rbp)
callq 0xea40
movq -0xa0(%rbp), %rdx
movq %rax, -0x70(%rbp)
addq $0x48, %rdx
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x1d3d0
jmp 0x1c8b4
movl $0x0, -0x74(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x74(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x1c96b
movq -0x18(%rbp), %rax
movl -0x74(%rbp), %ecx
imull -0x20(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movslq -0x74(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0xe240
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdi
movl (%rax), %eax
imull -0x20(%rbp), %eax
cltq
shlq $0x2, %rax
addq %rax, %rsi
movslq -0x20(%rbp), %rdx
shlq $0x2, %rdx
callq 0x5390
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x1c8bb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x3d(%rbp), %rdi
callq 0xe130
jmp 0x1ca28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0xe530
jmp 0x1ca28
movslq -0x1c(%rbp), %rdi
callq 0x5030
movq %rax, -0xc8(%rbp)
jmp 0x1c97d
movq -0xc8(%rbp), %rax
movq %rax, -0x80(%rbp)
movl $0x0, -0x84(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x84(%rbp), %eax
cmpl 0x14(%rcx), %eax
jge 0x1c9f9
movq -0xa0(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x80(%rbp), %rcx
movl -0x20(%rbp), %r8d
movl -0x1c(%rbp), %r9d
callq 0x1c270
movq -0xa0(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x80(%rbp), %rcx
movl -0x20(%rbp), %r8d
movl -0x1c(%rbp), %r9d
callq 0x1c2f0
jmp 0x1c9e6
jmp 0x1c9e8
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x1c992
movq -0x80(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpq $0x0, %rax
je 0x1ca16
movq -0xd0(%rbp), %rdi
callq 0x5580
leaq -0x38(%rbp), %rdi
callq 0xe530
addq $0xd0, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x57a0
nopw %cs:(%rax,%rax)