// File: epfml[P]Bi-Sent2Vec/src/productquantizer.cc
// Function: fasttext::ProductQuantizer::train(int, float const*)
void ProductQuantizer::train(int32_t n, const real * x) {
  if (n < ksub_) {
    std::cerr<<"Matrix too small for quantization, must have > 256 rows"<<std::endl;
    exit(1);
  }
  std::vector<int32_t> perm(n, 0);
  std::iota(perm.begin(), perm.end(), 0);
  auto d = dsub_;
  auto np = std::min(n, max_points_);
  real* xslice = new real[np * dsub_];
  for (auto m = 0; m < nsubq_; m++) {
    if (m == nsubq_-1) {d = lastdsub_;}
    if (np != n) {std::shuffle(perm.begin(), perm.end(), rng);}
    for (auto j = 0; j < np; j++) {
      memcpy (xslice + j * d, x + perm[j] * dim_ + m * dsub_, d * sizeof(real));
    }
    kmeans(xslice, get_centroids(m, 0), np, d);
  }
  delete [] xslice;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x90(%rbp)
movl -0xc(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x1ca95
movq 0x42580(%rip), %rdi     # 0x5eff0
leaq 0x2620b(%rip), %rsi     # 0x42c82
callq 0x5420
movq %rax, %rdi
movq 0x4250a(%rip), %rsi     # 0x5ef90
callq 0x5460
movl $0x1, %edi
callq 0x54f0
movslq -0xc(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0x0, -0x34(%rbp)
leaq -0x35(%rbp), %rdi
movq %rdi, -0x98(%rbp)
callq 0xe090
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rcx
leaq -0x30(%rbp), %rdi
leaq -0x34(%rbp), %rdx
callq 0xe0b0
jmp 0x1cad4
leaq -0x35(%rbp), %rdi
callq 0xe130
leaq -0x30(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0xea10
movq -0xa8(%rbp), %rdi
movq %rax, -0x50(%rbp)
callq 0xea40
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
xorl %edx, %edx
callq 0x1d370
jmp 0x1cb12
movq -0x90(%rbp), %rsi
movl 0x24(%rsi), %eax
movl %eax, -0x5c(%rbp)
addq $0xc, %rsi
leaq -0xc(%rbp), %rdi
callq 0x1d640
movq %rax, -0xb0(%rbp)
jmp 0x1cb35
movq -0x90(%rbp), %rcx
movq -0xb0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %eax
movl 0x24(%rcx), %ecx
imull %ecx, %eax
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x5030
movq %rax, -0xb8(%rbp)
jmp 0x1cb77
movq -0xb8(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movq -0x90(%rbp), %rcx
movl -0x6c(%rbp), %eax
cmpl 0x20(%rcx), %eax
jge 0x1cd2e
movq -0x90(%rbp), %rcx
movl -0x6c(%rbp), %eax
movl 0x20(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1cbf3
movq -0x90(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x5c(%rbp)
jmp 0x1cbf3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x35(%rbp), %rdi
callq 0xe130
jmp 0x1cd5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xe530
jmp 0x1cd5d
movl -0x60(%rbp), %eax
cmpl -0xc(%rbp), %eax
je 0x1cc3b
leaq -0x30(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0xea10
movq -0xc0(%rbp), %rdi
movq %rax, -0x78(%rbp)
callq 0xea40
movq -0x90(%rbp), %rdx
movq %rax, -0x80(%rbp)
addq $0x48, %rdx
movq -0x78(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x1d3d0
jmp 0x1cc39
jmp 0x1cc3b
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpl -0x60(%rbp), %eax
jge 0x1cce3
movq -0x68(%rbp), %rax
movl -0x84(%rbp), %ecx
imull -0x5c(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0xc8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xd0(%rbp)
movslq -0x84(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xe240
movq -0xd0(%rbp), %rsi
movq -0x90(%rbp), %rcx
movq -0xc8(%rbp), %rdi
movl (%rax), %eax
imull 0x1c(%rcx), %eax
cltq
shlq $0x2, %rax
addq %rax, %rsi
movl -0x6c(%rbp), %eax
imull 0x24(%rcx), %eax
cltq
shlq $0x2, %rax
addq %rax, %rsi
movslq -0x5c(%rbp), %rdx
shlq $0x2, %rdx
callq 0x5390
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x1cc45
movq -0x90(%rbp), %rdi
movq -0x68(%rbp), %rax
movq %rax, -0xd8(%rbp)
movl -0x6c(%rbp), %esi
xorl %edx, %edx
callq 0x1c110
movq -0x90(%rbp), %rdi
movq -0xd8(%rbp), %rsi
movq %rax, %rdx
movl -0x60(%rbp), %ecx
movl -0x5c(%rbp), %r8d
callq 0x1c7d0
jmp 0x1cd1e
jmp 0x1cd20
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x1cb89
movq -0x68(%rbp), %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, %rax
je 0x1cd4b
movq -0xe0(%rbp), %rdi
callq 0x5580
leaq -0x30(%rbp), %rdi
callq 0xe530
addq $0xe0, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x57a0
nopw %cs:(%rax,%rax)