// File: cegme[P]vose/Vose.cc
// Function: Vose::init()
void Vose::init() {

  // Reset the random number generators
  reset_scores_die();
  reset_random_double();

  // clear alias array
  //vose_alias.clear();
  alias.resize(scores.size(), 0);

  // clear prob array
  //vose_prob.clear();
  prob.resize(scores.size(), 0);

  // Work lists
  std::list<size_t> small;
  std::list<size_t> large;

  size_t n = scores.size();

  std::vector<double> probs_list(n);
  for(size_t i = 0; i != n; ++i) {
    // Compute the weighted probabilies, times the size
    double prob = (double) n * scores[i].weight / total_weight;
    probs_list[i] = prob;
    //std:: cerr << "probs_list[" << i << "]: " << probs_list[i] << "\n";

    // Build work lists
    if(prob < 1) 
      small.push_back(i);
    else
      large.push_back(i);
  }

  while(!small.empty() && !large.empty()) {
    size_t from_small = small.front(); small.pop_front();
    size_t from_large = large.front(); large.pop_front();
    
    prob[from_small] = probs_list[from_small];
    alias[from_small] = from_large;

    probs_list[from_large] += probs_list[from_small] - 1;

    if(probs_list[from_large] < 1)
      small.push_front(from_large);
    else
      large.push_front(from_large);
  }

  while(!small.empty()) {
    size_t from_small = small.front(); small.pop_front();
    prob[from_small] = 1;
  }
  while (!large.empty()) {
    size_t from_large = large.front(); large.pop_front();
    prob[from_large] =  1;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x11ab0
movq -0xd8(%rbp), %rdi
callq 0x11b60
movq -0xd8(%rbp), %rdi
movq %rdi, %rax
addq $0x60, %rax
movq %rax, -0xe0(%rbp)
addq $0x40, %rdi
movq %rdi, -0xc8(%rbp)
callq 0x5ba0
movq -0xe0(%rbp), %rdi
movq %rax, %rsi
movq $0x0, -0x10(%rbp)
leaq -0x10(%rbp), %rdx
callq 0x11bc0
movq -0xd8(%rbp), %rax
movq -0xc8(%rbp), %rdi
addq $0x78, %rax
movq %rax, -0xd0(%rbp)
callq 0x5ba0
movq -0xd0(%rbp), %rdi
movq %rax, %rsi
movq $0x0, -0x18(%rbp)
leaq -0x18(%rbp), %rdx
callq 0x11c70
leaq -0x30(%rbp), %rdi
callq 0x11d20
leaq -0x48(%rbp), %rdi
callq 0x11d20
movq -0xc8(%rbp), %rdi
callq 0x5ba0
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0x69(%rbp), %rdi
movq %rdi, -0xb8(%rbp)
callq 0x9ff0
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
leaq -0x68(%rbp), %rdi
callq 0x11d40
jmp 0x10e2a
leaq -0x69(%rbp), %rdi
callq 0x6ad0
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x50(%rbp), %rax
je 0x10f75
movq -0xd8(%rbp), %rdi
movaps 0xb1c3(%rip), %xmm1     # 0x1c020
movq -0x50(%rbp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xb1c2(%rip), %xmm1     # 0x1c030
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, -0xf0(%rbp)
addq $0x40, %rdi
movq -0x88(%rbp), %rsi
callq 0x11db0
movsd -0xf0(%rbp), %xmm0
movq %rax, %rcx
movq -0xd8(%rbp), %rax
cvtsi2sdq (%rcx), %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdq 0x58(%rax), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0xe8(%rbp)
movq -0x88(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x11dd0
movsd -0xe8(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd 0xb112(%rip), %xmm0     # 0x1c008
ucomisd -0x90(%rbp), %xmm0
jbe 0x10f48
leaq -0x30(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x11df0
jmp 0x10f12
jmp 0x10f5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x69(%rbp), %rdi
callq 0x6ad0
jmp 0x111b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5290
jmp 0x111b4
leaq -0x48(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x11df0
jmp 0x10f5a
jmp 0x10f5c
jmp 0x10f5e
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x10e3e
jmp 0x10f77
leaq -0x30(%rbp), %rdi
callq 0x11e30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xf1(%rbp)
jne 0x10fa0
leaq -0x48(%rbp), %rdi
callq 0x11e30
xorb $-0x1, %al
movb %al, -0xf1(%rbp)
movb -0xf1(%rbp), %al
testb $0x1, %al
jne 0x10faf
jmp 0x110e8
leaq -0x30(%rbp), %rdi
callq 0x11e50
movq (%rax), %rax
movq %rax, -0x98(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x11e80
leaq -0x48(%rbp), %rdi
callq 0x11e50
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x11e80
movq -0x98(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x11dd0
movq -0xd8(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x110(%rbp)
addq $0x78, %rdi
movq -0x98(%rbp), %rsi
callq 0x11dd0
movsd -0x110(%rbp), %xmm0
movq -0xd8(%rbp), %rdi
movsd %xmm0, (%rax)
movq -0xa0(%rbp), %rax
movq %rax, -0x108(%rbp)
addq $0x60, %rdi
movq -0x98(%rbp), %rsi
callq 0x11eb0
movq -0x108(%rbp), %rcx
movq %rcx, (%rax)
movq -0x98(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x11dd0
movsd (%rax), %xmm0
movsd 0xaf97(%rip), %xmm1     # 0x1c008
subsd %xmm1, %xmm0
movsd %xmm0, -0x100(%rbp)
movq -0xa0(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x11dd0
movsd -0x100(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq -0xa0(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x11dd0
movsd 0xaf53(%rip), %xmm0     # 0x1c008
ucomisd (%rax), %xmm0
jbe 0x110cf
leaq -0x30(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x11ed0
jmp 0x110cd
jmp 0x110e3
leaq -0x48(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x11ed0
jmp 0x110e1
jmp 0x110e3
jmp 0x10f77
jmp 0x110ea
leaq -0x30(%rbp), %rdi
callq 0x11e30
xorb $-0x1, %al
testb $0x1, %al
jne 0x110fb
jmp 0x1113c
leaq -0x30(%rbp), %rdi
callq 0x11e50
movq (%rax), %rax
movq %rax, -0xa8(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x11e80
movq -0xd8(%rbp), %rdi
addq $0x78, %rdi
movq -0xa8(%rbp), %rsi
callq 0x11dd0
movsd 0xaed2(%rip), %xmm0     # 0x1c008
movsd %xmm0, (%rax)
jmp 0x110ea
jmp 0x1113e
leaq -0x48(%rbp), %rdi
callq 0x11e30
xorb $-0x1, %al
testb $0x1, %al
jne 0x1114f
jmp 0x11190
leaq -0x48(%rbp), %rdi
callq 0x11e50
movq (%rax), %rax
movq %rax, -0xb0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x11e80
movq -0xd8(%rbp), %rdi
addq $0x78, %rdi
movq -0xb0(%rbp), %rsi
callq 0x11dd0
movsd 0xae7e(%rip), %xmm0     # 0x1c008
movsd %xmm0, (%rax)
jmp 0x1113e
leaq -0x68(%rbp), %rdi
callq 0x5290
leaq -0x48(%rbp), %rdi
callq 0x11f10
leaq -0x30(%rbp), %rdi
callq 0x11f10
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0x11f10
leaq -0x30(%rbp), %rdi
callq 0x11f10
movq -0x78(%rbp), %rdi
callq 0x22f0
nop