// File: cegme[P]vose/test.cc
// Function: test::test2()
bool test::test2() {
  std::cerr << "Check that the vose data structure comes close to actual values.\n";

  Vose vose;
  vose.add("red", 5);
  vose.add("blue", 10);
  vose.add("yellow", 20);

  vose.init();
  
  std::cerr << "Vose Dist: ";
  for (size_t i = 0; i != vose.scores.size(); ++i) {
    std::cerr << "\t" << i << "-->" << vose.scores[i].weight << "\n";
  }
  std::cerr << "\n";
  for (size_t i = 0; i != vose.probabilities().size(); ++i) {
    std::cerr << "\t" << i << "-->" << vose.probabilities()[i] << "\n";
  }
  std::cerr << "\n";

  std::cerr << "Create a histogram by sampling the vose structure.\n";
  std::map<size_t,int> histogram;
  auto hist_sum = 0L;
  for (int i = 0; i != 50000; ++i) {
    size_t idx = vose.rand();

    if (histogram.find(idx) != histogram.end()) {
      histogram[idx] += 1;
      hist_sum += 1L;
    }
    else {
      histogram.insert(std::make_pair(idx, 1));
      hist_sum += 1L;
    }
  }

  std::cerr << "Sampled Distribution:\n";

  // Create the new dist
  std::vector<double> new_dist;
  for (auto& h : histogram) {
    std::cerr << "\t" << h.first <<  "-->" << (double)h.second/hist_sum << "\n";
    new_dist.push_back((double)h.second/hist_sum);
  }

  double kl_result = Vose::kl(vose.probabilities(), new_dist); 
  std::cerr << "kl(probabilities, new_dist): " << kl_result << "\n";
  std::cerr << "kl(new_dist, probabilities): " << Vose::kl(new_dist, vose.probabilities()) << "\n";

  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x360, %rsp            # imm = 0x360
movq %rdi, -0x8(%rbp)
movq 0x1580a(%rip), %rdi     # 0x2aff0
leaq 0x6b6a(%rip), %rsi      # 0x1c357
callq 0x2210
leaq -0x98(%rbp), %rdi
callq 0x4480
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x2300
movq -0x270(%rbp), %rdx
leaq 0x6aba(%rip), %rsi      # 0x1c2d9
leaq -0xb8(%rbp), %rdi
callq 0x2270
jmp 0x1582d
leaq -0x98(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
movl $0x5, %edx
callq 0x10c00
jmp 0x15847
leaq -0xb8(%rbp), %rdi
callq 0x2140
leaq -0xb9(%rbp), %rdi
callq 0x2240
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x2300
movq -0x278(%rbp), %rdx
leaq 0x6c30(%rip), %rsi      # 0x1c4b0
leaq -0xf0(%rbp), %rdi
callq 0x2270
jmp 0x1588e
leaq -0x98(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
movl $0xa, %edx
callq 0x10c00
jmp 0x158a8
leaq -0xf0(%rbp), %rdi
callq 0x2140
leaq -0xf1(%rbp), %rdi
callq 0x2240
leaq -0x119(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0x2300
movq -0x280(%rbp), %rdx
leaq 0x6a50(%rip), %rsi      # 0x1c331
leaq -0x118(%rbp), %rdi
callq 0x2270
jmp 0x158ef
leaq -0x98(%rbp), %rdi
leaq -0x118(%rbp), %rsi
movl $0x14, %edx
callq 0x10c00
jmp 0x15909
leaq -0x118(%rbp), %rdi
callq 0x2140
leaq -0x119(%rbp), %rdi
callq 0x2240
leaq -0x98(%rbp), %rdi
callq 0x10d30
jmp 0x1592f
movq 0x156ba(%rip), %rdi     # 0x2aff0
leaq 0x6a5c(%rip), %rsi      # 0x1c399
callq 0x2210
jmp 0x15944
movq $0x0, -0x128(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x288(%rbp)
leaq -0x98(%rbp), %rdi
addq $0x40, %rdi
callq 0x5ba0
movq %rax, %rcx
movq -0x288(%rbp), %rax
cmpq %rcx, %rax
je 0x15b0a
movq 0x15669(%rip), %rdi     # 0x2aff0
leaq 0x6a17(%rip), %rsi      # 0x1c3a5
callq 0x2210
movq %rax, -0x290(%rbp)
jmp 0x1599c
movq -0x290(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x2080
movq %rax, -0x298(%rbp)
jmp 0x159b8
movq -0x298(%rbp), %rdi
leaq 0x69e1(%rip), %rsi      # 0x1c3a7
callq 0x2210
movq %rax, -0x2a0(%rbp)
jmp 0x159d4
leaq -0x58(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x11db0
movq -0x2a0(%rbp), %rdi
movq (%rax), %rsi
callq 0x2310
movq %rax, -0x2a8(%rbp)
jmp 0x159fc
movq -0x2a8(%rbp), %rdi
leaq 0x6b12(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x15a11
jmp 0x15a13
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x1594f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x15a5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x2140
leaq -0xb9(%rbp), %rdi
callq 0x2240
jmp 0x16190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x15a9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x2140
leaq -0xf1(%rbp), %rdi
callq 0x2240
jmp 0x16190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x15ae2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x2140
leaq -0x119(%rbp), %rdi
callq 0x2240
jmp 0x16190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x16190
movq 0x154df(%rip), %rdi     # 0x2aff0
leaq 0x6a04(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x15b1f
movq $0x0, -0x130(%rbp)
movq -0x130(%rbp), %rax
movq %rax, -0x2b0(%rbp)
leaq -0x148(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x182e0
jmp 0x15b4d
leaq -0x148(%rbp), %rdi
callq 0x6a10
movq %rax, -0x2b8(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x5290
movq -0x2b8(%rbp), %rcx
movq -0x2b0(%rbp), %rax
cmpq %rcx, %rax
je 0x15c73
movq 0x15466(%rip), %rdi     # 0x2aff0
leaq 0x6814(%rip), %rsi      # 0x1c3a5
callq 0x2210
movq %rax, -0x2c0(%rbp)
jmp 0x15b9f
movq -0x2c0(%rbp), %rdi
movq -0x130(%rbp), %rsi
callq 0x2080
movq %rax, -0x2c8(%rbp)
jmp 0x15bbb
movq -0x2c8(%rbp), %rdi
leaq 0x67de(%rip), %rsi      # 0x1c3a7
callq 0x2210
movq %rax, -0x2d0(%rbp)
jmp 0x15bd7
leaq -0x160(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x182e0
jmp 0x15bec
movq -0x130(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x11dd0
movq -0x2d0(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x2320
movq %rax, -0x2d8(%rbp)
jmp 0x15c18
movq -0x2d8(%rbp), %rdi
leaq 0x68f6(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x15c2d
leaq -0x160(%rbp), %rdi
callq 0x5290
movq -0x130(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x130(%rbp)
jmp 0x15b2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x5290
jmp 0x16190
movq 0x15376(%rip), %rdi     # 0x2aff0
leaq 0x689b(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x15c88
movq 0x15361(%rip), %rdi     # 0x2aff0
leaq 0x6715(%rip), %rsi      # 0x1c3ab
callq 0x2210
jmp 0x15c9d
leaq -0x190(%rbp), %rdi
callq 0x183c0
movq $0x0, -0x198(%rbp)
movl $0x0, -0x19c(%rbp)
cmpl $0xc350, -0x19c(%rbp)   # imm = 0xC350
je 0x15e63
leaq -0x98(%rbp), %rdi
callq 0x111d0
movq %rax, -0x2e0(%rbp)
jmp 0x15ce3
movq -0x2e0(%rbp), %rax
movq %rax, -0x1a8(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x18410
movq %rax, -0x2e8(%rbp)
jmp 0x15d0d
movq -0x2e8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x18440
movq %rax, -0x1b8(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x183e0
testb $0x1, %al
jne 0x15d47
jmp 0x15d9f
leaq -0x190(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x18470
movq %rax, -0x2f0(%rbp)
jmp 0x15d63
movq -0x2f0(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x198(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x198(%rbp)
jmp 0x15e4d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x16184
movl $0x1, -0x1cc(%rbp)
leaq -0x1a8(%rbp), %rdi
leaq -0x1cc(%rbp), %rsi
callq 0x18590
movl %edx, -0x2fc(%rbp)
movq %rax, -0x2f8(%rbp)
jmp 0x15dcb
movl -0x2fc(%rbp), %eax
movq -0x2f8(%rbp), %rcx
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1d8(%rbp)
movl -0x1d8(%rbp), %eax
movl %eax, -0x1c0(%rbp)
movq -0x1e0(%rbp), %rax
movq %rax, -0x1c8(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x18550
movb %dl, -0x309(%rbp)
movq %rax, -0x308(%rbp)
jmp 0x15e21
movb -0x309(%rbp), %al
movq -0x308(%rbp), %rcx
movq %rcx, -0x1f0(%rbp)
movb %al, -0x1e8(%rbp)
movq -0x198(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x198(%rbp)
jmp 0x15e4f
movl -0x19c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x19c(%rbp)
jmp 0x15cbe
movq 0x15186(%rip), %rdi     # 0x2aff0
leaq 0x656e(%rip), %rsi      # 0x1c3df
callq 0x2210
jmp 0x15e78
leaq -0x208(%rbp), %rdi
callq 0x5070
leaq -0x190(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x210(%rbp), %rdi
callq 0x185c0
movq %rax, -0x218(%rbp)
movq -0x210(%rbp), %rdi
callq 0x18440
movq %rax, -0x220(%rbp)
leaq -0x218(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x183e0
testb $0x1, %al
jne 0x15ed4
jmp 0x15fe1
leaq -0x218(%rbp), %rdi
callq 0x185f0
movq %rax, -0x228(%rbp)
movq 0x15102(%rip), %rdi     # 0x2aff0
leaq 0x64b0(%rip), %rsi      # 0x1c3a5
callq 0x2210
movq %rax, -0x318(%rbp)
jmp 0x15f03
movq -0x318(%rbp), %rdi
movq -0x228(%rbp), %rax
movq (%rax), %rsi
callq 0x2080
movq %rax, -0x320(%rbp)
jmp 0x15f22
movq -0x320(%rbp), %rdi
leaq 0x6477(%rip), %rsi      # 0x1c3a7
callq 0x2210
movq %rax, -0x328(%rbp)
jmp 0x15f3e
movq -0x328(%rbp), %rdi
movq -0x228(%rbp), %rax
cvtsi2sdl 0x8(%rax), %xmm0
cvtsi2sdq -0x198(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x2320
movq %rax, -0x330(%rbp)
jmp 0x15f6c
movq -0x330(%rbp), %rdi
leaq 0x65a2(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x15f81
movq -0x228(%rbp), %rax
cvtsi2sdl 0x8(%rax), %xmm0
cvtsi2sdq -0x198(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x230(%rbp)
leaq -0x208(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x11f70
jmp 0x15fb7
jmp 0x15fb9
leaq -0x218(%rbp), %rdi
callq 0x18610
jmp 0x15eb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x16178
leaq -0x250(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x182e0
jmp 0x15ff6
leaq -0x250(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x11310
movsd %xmm0, -0x338(%rbp)
jmp 0x16013
leaq -0x250(%rbp), %rdi
callq 0x5290
movsd -0x338(%rbp), %xmm0
movsd %xmm0, -0x238(%rbp)
movq 0x14fba(%rip), %rdi     # 0x2aff0
leaq 0x63b9(%rip), %rsi      # 0x1c3f6
callq 0x2210
movq %rax, -0x340(%rbp)
jmp 0x1604b
movq -0x340(%rbp), %rdi
movsd -0x238(%rbp), %xmm0
callq 0x2320
movq %rax, -0x348(%rbp)
jmp 0x16068
movq -0x348(%rbp), %rdi
leaq 0x64a6(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x1607d
movq 0x14f6c(%rip), %rdi     # 0x2aff0
leaq 0x6389(%rip), %rsi      # 0x1c414
callq 0x2210
movq %rax, -0x350(%rbp)
jmp 0x16099
leaq -0x268(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x182e0
jmp 0x160ae
leaq -0x208(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x11310
movsd %xmm0, -0x358(%rbp)
jmp 0x160cb
movsd -0x358(%rbp), %xmm0
movq -0x350(%rbp), %rdi
callq 0x2320
movq %rax, -0x360(%rbp)
jmp 0x160e8
movq -0x360(%rbp), %rdi
leaq 0x6426(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x160fd
leaq -0x268(%rbp), %rdi
callq 0x5290
leaq -0x208(%rbp), %rdi
callq 0x5290
leaq -0x190(%rbp), %rdi
callq 0x18640
leaq -0x98(%rbp), %rdi
callq 0x46f0
movb $0x1, %al
andb $0x1, %al
addq $0x360, %rsp            # imm = 0x360
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x250(%rbp), %rdi
callq 0x5290
jmp 0x16178
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x5290
leaq -0x208(%rbp), %rdi
callq 0x5290
leaq -0x190(%rbp), %rdi
callq 0x18640
leaq -0x98(%rbp), %rdi
callq 0x46f0
movq -0xc8(%rbp), %rdi
callq 0x22f0
nopl (%rax,%rax)