// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq 0x8f85(%rip), %rdi      # 0xfff0
leaq 0x32f5(%rip), %rsi      # 0xa367
callq 0x21e0
leaq -0x188(%rbp), %rdi
movl $0x90, %edx
xorl %esi, %esi
callq 0x2110
leaq 0x3258(%rip), %rsi      # 0xa2e9
leaq -0xf8(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x20b0
leaq -0x188(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
pushq $0x5
popq %rdx
callq 0x5cb4
leaq -0xf8(%rbp), %rdi
callq 0x20d0
leaq 0x33f3(%rip), %rsi      # 0xa4c0
leaq -0xd8(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x20b0
leaq -0x188(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
pushq $0xa
popq %rdx
callq 0x5cb4
leaq -0xd8(%rbp), %rdi
callq 0x20d0
leaq 0x3238(%rip), %rsi      # 0xa341
leaq -0xb8(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x20b0
leaq -0x188(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
pushq $0x14
popq %rdx
callq 0x5cb4
leaq -0xb8(%rbp), %rdi
callq 0x20d0
leaq -0x188(%rbp), %rdi
callq 0x5d72
movq 0x8e9f(%rip), %rdi      # 0xfff0
leaq 0x3251(%rip), %rsi      # 0xa3a9
callq 0x21e0
xorl %ebx, %ebx
pushq $0x30
popq %r14
leaq 0x324d(%rip), %r15      # 0xa3b7
leaq 0x33bb(%rip), %r12      # 0xa52c
xorl %r13d, %r13d
movq -0x140(%rbp), %rax
subq -0x148(%rbp), %rax
cqto
idivq %r14
cmpq %rax, %r13
je 0x71dc
movq 0x8e5d(%rip), %rdi      # 0xfff0
leaq 0x321b(%rip), %rsi      # 0xa3b5
callq 0x21e0
movq %rax, %rdi
movq %r13, %rsi
callq 0x2130
movq %rax, %rdi
movq %r15, %rsi
callq 0x21e0
movq -0x148(%rbp), %rcx
movq (%rcx,%rbx), %rsi
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
movq %r12, %rsi
callq 0x21e0
incq %r13
addq $0x30, %rbx
jmp 0x7174
movq 0x8e0d(%rip), %rdi      # 0xfff0
leaq 0x3342(%rip), %rsi      # 0xa52c
callq 0x21e0
xorl %ebx, %ebx
leaq -0x90(%rbp), %r14
leaq -0x188(%rbp), %r15
leaq 0x3326(%rip), %r13      # 0xa52c
movq %r14, %rdi
movq %r15, %rsi
callq 0x86f2
movq -0x88(%rbp), %r12
subq -0x90(%rbp), %r12
sarq $0x3, %r12
movq %r14, %rdi
callq 0x3a5e
cmpq %r12, %rbx
je 0x729a
movq 0x8db9(%rip), %rdi      # 0xfff0
leaq 0x3177(%rip), %rsi      # 0xa3b5
callq 0x21e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2130
movq %rax, %rdi
leaq 0x315f(%rip), %rsi      # 0xa3b7
callq 0x21e0
movq %rax, %r12
movq %r14, %rdi
movq %r15, %rsi
callq 0x86f2
movq -0x90(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
callq 0x2280
movq %rax, %rdi
movq %r13, %rsi
callq 0x21e0
movq %r14, %rdi
callq 0x3a5e
incq %rbx
jmp 0x7206
movq 0x8d4f(%rip), %rdi      # 0xfff0
leaq 0x3284(%rip), %rsi      # 0xa52c
callq 0x21e0
movq 0x8d3c(%rip), %rdi      # 0xfff0
leaq 0x3100(%rip), %rsi      # 0xa3bb
callq 0x21e0
leaq -0x88(%rbp), %r12
andl $0x0, (%r12)
andq $0x0, 0x8(%r12)
movq %r12, 0x10(%r12)
movq %r12, 0x18(%r12)
andq $0x0, 0x20(%r12)
movl $0xc350, %r13d          # imm = 0xC350
leaq -0x188(%rbp), %rbx
leaq -0x90(%rbp), %r14
leaq -0x40(%rbp), %r15
subq $0x1, %r13
jb 0x7348
movq %rbx, %rdi
callq 0x5ff8
movq %rax, -0x40(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x8c06
cmpq %r12, %rax
je 0x732b
movq %r14, %rdi
movq %r15, %rsi
callq 0x8736
incl (%rax)
jmp 0x72fa
movq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
movl $0x1, -0x58(%rbp)
movq %r14, %rdi
leaq -0x60(%rbp), %rsi
callq 0x8eea
jmp 0x72fa
movq 0x8ca1(%rip), %rdi      # 0xfff0
leaq 0x3099(%rip), %rsi      # 0xa3ef
callq 0x21e0
xorpd %xmm0, %xmm0
leaq -0x60(%rbp), %rbx
andq $0x0, 0x10(%rbx)
movapd %xmm0, (%rbx)
movq -0x78(%rbp), %r13
leaq 0x31b5(%rip), %r14      # 0xa52c
leaq -0x40(%rbp), %r15
cmpq %r12, %r13
je 0x73fa
movq 0x8c69(%rip), %rdi      # 0xfff0
leaq 0x3027(%rip), %rsi      # 0xa3b5
callq 0x21e0
movq 0x20(%r13), %rsi
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
leaq 0x300e(%rip), %rsi      # 0xa3b7
callq 0x21e0
cvtsi2sdl 0x28(%r13), %xmm0
divsd 0x2ebc(%rip), %xmm0     # 0xa278
movq %rax, %rdi
callq 0x2280
movq %rax, %rdi
movq %r14, %rsi
callq 0x21e0
cvtsi2sdl 0x28(%r13), %xmm0
divsd 0x2e9b(%rip), %xmm0     # 0xa278
movsd %xmm0, -0x40(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x65b0
movq %r13, %rdi
callq 0x2140
movq %rax, %r13
jmp 0x737b
leaq -0x40(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x86f2
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x60a6
movsd %xmm0, -0x98(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3a5e
movq 0x8bc1(%rip), %rdi      # 0xfff0
leaq 0x2fd0(%rip), %rsi      # 0xa406
callq 0x21e0
movq %rax, %rdi
movsd -0x98(%rbp), %xmm0
callq 0x2280
leaq 0x30da(%rip), %rsi      # 0xa52c
movq %rax, %rdi
callq 0x21e0
movq 0x8b8f(%rip), %rdi      # 0xfff0
leaq 0x2fbc(%rip), %rsi      # 0xa424
callq 0x21e0
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x86f2
leaq -0x60(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x60a6
movq %rbx, %rdi
callq 0x2280
leaq 0x3090(%rip), %rsi      # 0xa52c
movq %rax, %rdi
callq 0x21e0
leaq -0x40(%rbp), %rdi
callq 0x3a5e
leaq -0x60(%rbp), %rdi
callq 0x3a5e
leaq -0x90(%rbp), %rdi
callq 0x89dc
leaq -0x188(%rbp), %rdi
callq 0x3436
movb $0x1, %al
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x754d
jmp 0x7519
jmp 0x754d
jmp 0x7535
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
jmp 0x7510
jmp 0x7567
movq %rax, %rbx
leaq -0xd8(%rbp), %rdi
jmp 0x7510
jmp 0x7567
movq %rax, %rbx
leaq -0xf8(%rbp), %rdi
callq 0x20d0
jmp 0x756a
jmp 0x7567
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x3a5e
jmp 0x7550
jmp 0x754d
jmp 0x7567
jmp 0x7535
jmp 0x754d
jmp 0x7535
jmp 0x7567
jmp 0x7567
movq %rax, %rbx
jmp 0x7559
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x3a5e
jmp 0x756a
jmp 0x7567
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x3a5e
leaq -0x90(%rbp), %rdi
callq 0x89dc
jmp 0x756a
movq %rax, %rbx
leaq -0x188(%rbp), %rdi
callq 0x3436
movq %rbx, %rdi
callq 0x22d0