// File: cegme[P]vose/test.cc
// Function: test::test5()
bool test::test5() {

  VoseTree tree;
  tree.set_max_marbles(4);
  tree.set_max_bags(5);

  // Generate a set of label names.
  std::string labels[7] = {"red", "yellow", "pink", "green", "purple", 
                           "orange", "blue"};

  // Make a random number generator for marble labels
  std::default_random_engine label_generator(VoseUtil::RANDOM_SEED); 
  std::uniform_int_distribution<size_t>
    label_distribution(0, 7-1);
  std::function<size_t()> random_label =
    std::bind(label_distribution, label_generator);
  
  // Make a random number generator for marble weights
  std::default_random_engine weight_generator(VoseUtil::RANDOM_SEED); 
  std::uniform_int_distribution<long>
    weight_distribution(1, 1000);
  std::function<long()> random_weight =
    std::bind(weight_distribution, weight_generator);

  for(size_t i = 0; i != 50; ++i) {
    // Get a random marble with random label and random weight.
    size_t label_idx = random_label();
    size_t weight = random_weight();
    //std::cerr << "label_idx: " << label_idx << ", " << labels[label_idx] << "\n";
    //std::cerr << " weight: " << weight << "\n";
    tree.add(std::string(labels[label_idx]), weight);
    std::cerr << tree.toString();
  }

  // Generate a histogram.
  auto hist = VoseTree::histogram(tree, 50000L);

  // Get the real probabilities
  auto prob = tree.probabilities();

  // Compare the results
  double kl1 = VoseTree::kl(hist, prob);
  double kl2 = VoseTree::kl(prob, hist);
  std::cerr << "kl(hist, prob): " << kl1 << "\n";
  std::cerr << "kl(prob, hist): " << kl2 << "\n";
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x450, %rsp            # imm = 0x450
movq %rdi, -0x10(%rbp)
leaq -0x80(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x18660
movq -0x360(%rbp), %rdi
movl $0x4, %esi
callq 0x186f0
jmp 0x170b2
leaq -0x80(%rbp), %rdi
movl $0x5, %esi
callq 0x18750
jmp 0x170c2
movb $0x1, -0x180(%rbp)
leaq -0x170(%rbp), %rax
movq %rax, -0x370(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x179(%rbp), %rdi
movq %rdi, -0x368(%rbp)
callq 0x2300
movq -0x370(%rbp), %rdi
movq -0x368(%rbp), %rdx
leaq 0x51d3(%rip), %rsi      # 0x1c2d9
callq 0x2270
jmp 0x1710d
leaq -0x150(%rbp), %rax
movq %rax, -0x380(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17a(%rbp), %rdi
movq %rdi, -0x378(%rbp)
callq 0x2300
movq -0x380(%rbp), %rdi
movq -0x378(%rbp), %rdx
leaq 0x51e7(%rip), %rsi      # 0x1c331
callq 0x2270
jmp 0x17151
leaq -0x130(%rbp), %rax
movq %rax, -0x390(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17b(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x2300
movq -0x390(%rbp), %rdi
movq -0x388(%rbp), %rdx
leaq 0x52dc(%rip), %rsi      # 0x1c46a
callq 0x2270
jmp 0x17195
leaq -0x110(%rbp), %rax
movq %rax, -0x3a0(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17c(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0x2300
movq -0x3a0(%rbp), %rdi
movq -0x398(%rbp), %rdx
leaq 0x529d(%rip), %rsi      # 0x1c46f
callq 0x2270
jmp 0x171d9
leaq -0xf0(%rbp), %rax
movq %rax, -0x3b0(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17d(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x2300
movq -0x3b0(%rbp), %rdi
movq -0x3a8(%rbp), %rdx
leaq 0x525f(%rip), %rsi      # 0x1c475
callq 0x2270
jmp 0x1721d
leaq -0xd0(%rbp), %rax
movq %rax, -0x3c0(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17e(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x2300
movq -0x3c0(%rbp), %rdi
movq -0x3b8(%rbp), %rdx
leaq 0x5222(%rip), %rsi      # 0x1c47c
callq 0x2270
jmp 0x17261
leaq -0xb0(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17f(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x2300
movq -0x3d0(%rbp), %rdi
movq -0x3c8(%rbp), %rdx
leaq 0x5212(%rip), %rsi      # 0x1c4b0
callq 0x2270
jmp 0x172a5
movb $0x0, -0x180(%rbp)
leaq -0x17f(%rbp), %rdi
callq 0x2240
leaq -0x17e(%rbp), %rdi
callq 0x2240
leaq -0x17d(%rbp), %rdi
callq 0x2240
leaq -0x17c(%rbp), %rdi
callq 0x2240
leaq -0x17b(%rbp), %rdi
callq 0x2240
leaq -0x17a(%rbp), %rdi
callq 0x2240
leaq -0x179(%rbp), %rdi
callq 0x2240
movq 0x13eb9(%rip), %rsi     # 0x2b1c0
leaq -0x188(%rbp), %rdi
callq 0x4a30
jmp 0x17315
xorl %eax, %eax
movl %eax, %esi
leaq -0x198(%rbp), %rdi
movl $0x6, %edx
callq 0x18770
jmp 0x1732c
leaq -0x1d0(%rbp), %rdi
leaq -0x198(%rbp), %rsi
leaq -0x188(%rbp), %rdx
callq 0x187a0
jmp 0x17348
leaq -0x1b8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x187e0
jmp 0x1735d
movq 0x13e5c(%rip), %rsi     # 0x2b1c0
leaq -0x1d8(%rbp), %rdi
callq 0x4a30
jmp 0x17372
leaq -0x1e8(%rbp), %rdi
movl $0x1, %esi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x18880
jmp 0x1738a
leaq -0x220(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
leaq -0x1d8(%rbp), %rdx
callq 0x188b0
jmp 0x173a6
leaq -0x208(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x188f0
jmp 0x173bb
movq $0x0, -0x228(%rbp)
cmpq $0x32, -0x228(%rbp)
je 0x1768d
leaq -0x1b8(%rbp), %rdi
callq 0x18990
movq %rax, -0x3d8(%rbp)
jmp 0x173e9
movq -0x3d8(%rbp), %rax
movq %rax, -0x230(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x189d0
movq %rax, -0x3e0(%rbp)
jmp 0x1740c
movq -0x3e0(%rbp), %rax
movq %rax, -0x238(%rbp)
movq -0x230(%rbp), %rax
shlq $0x5, %rax
leaq -0x170(%rbp,%rax), %rsi
leaq -0x258(%rbp), %rdi
callq 0x20e0
jmp 0x1743b
movq -0x238(%rbp), %rdx
leaq -0x80(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x24f0
jmp 0x17454
leaq -0x258(%rbp), %rdi
callq 0x2140
leaq -0x278(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3080
jmp 0x17472
movq 0x13b77(%rip), %rdi     # 0x2aff0
leaq -0x278(%rbp), %rsi
callq 0x21e0
jmp 0x17487
leaq -0x278(%rbp), %rdi
callq 0x2140
movq -0x228(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x228(%rbp)
jmp 0x173c6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1792c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17599
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1758d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17581
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17575
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17569
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1755d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x17f(%rbp), %rdi
callq 0x2240
leaq -0x17e(%rbp), %rdi
callq 0x2240
leaq -0x17d(%rbp), %rdi
callq 0x2240
leaq -0x17c(%rbp), %rdi
callq 0x2240
leaq -0x17b(%rbp), %rdi
callq 0x2240
leaq -0x17a(%rbp), %rdi
callq 0x2240
leaq -0x179(%rbp), %rdi
callq 0x2240
testb $0x1, -0x180(%rbp)
jne 0x175b0
jmp 0x175fd
movq -0x178(%rbp), %rax
leaq -0x170(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x3e8(%rbp)
je 0x175fb
movq -0x3e8(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x3f0(%rbp)
callq 0x2140
movq -0x3f0(%rbp), %rax
leaq -0x170(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x3e8(%rbp)
jne 0x175ca
jmp 0x175fd
jmp 0x1792c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x178de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17888
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1787c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x2140
jmp 0x1787c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x278(%rbp), %rdi
callq 0x2140
jmp 0x1787c
leaq -0x318(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x18a10
jmp 0x1769f
leaq -0x2a8(%rbp), %rdi
leaq -0x318(%rbp), %rsi
movl $0xc350, %edx           # imm = 0xC350
callq 0x3880
jmp 0x176b9
leaq -0x318(%rbp), %rdi
callq 0x18710
leaq -0x348(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3460
jmp 0x176d7
leaq -0x2a8(%rbp), %rdi
leaq -0x348(%rbp), %rsi
callq 0x3630
movsd %xmm0, -0x3f8(%rbp)
jmp 0x176f4
movsd -0x3f8(%rbp), %xmm0
movsd %xmm0, -0x350(%rbp)
leaq -0x348(%rbp), %rdi
leaq -0x2a8(%rbp), %rsi
callq 0x3630
movsd %xmm0, -0x400(%rbp)
jmp 0x17721
movsd -0x400(%rbp), %xmm0
movsd %xmm0, -0x358(%rbp)
movq 0x138b8(%rip), %rdi     # 0x2aff0
leaq 0x4d44(%rip), %rsi      # 0x1c483
callq 0x2210
movq %rax, -0x408(%rbp)
jmp 0x1774d
movq -0x408(%rbp), %rdi
movsd -0x350(%rbp), %xmm0
callq 0x2320
movq %rax, -0x410(%rbp)
jmp 0x1776a
movq -0x410(%rbp), %rdi
leaq 0x4da4(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x1777f
movq 0x1386a(%rip), %rdi     # 0x2aff0
leaq 0x4d07(%rip), %rsi      # 0x1c494
callq 0x2210
movq %rax, -0x418(%rbp)
jmp 0x1779b
movq -0x418(%rbp), %rdi
movsd -0x358(%rbp), %xmm0
callq 0x2320
movq %rax, -0x420(%rbp)
jmp 0x177b8
movq -0x420(%rbp), %rdi
leaq 0x4d56(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x177cd
movb $0x1, -0x1(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x5050
leaq -0x2a8(%rbp), %rdi
callq 0x5050
leaq -0x208(%rbp), %rdi
callq 0x18ad0
leaq -0x1b8(%rbp), %rdi
callq 0x18af0
leaq -0x170(%rbp), %rax
movq %rax, -0x430(%rbp)
addq $0xe0, %rax
movq %rax, -0x428(%rbp)
jmp 0x17896
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x318(%rbp), %rdi
callq 0x18710
jmp 0x1787c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x17870
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x5050
leaq -0x2a8(%rbp), %rdi
callq 0x5050
leaq -0x208(%rbp), %rdi
callq 0x18ad0
leaq -0x1b8(%rbp), %rdi
callq 0x18af0
jmp 0x178de
movq -0x428(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x438(%rbp)
callq 0x2140
movq -0x430(%rbp), %rcx
movq -0x438(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x428(%rbp)
jne 0x17896
leaq -0x80(%rbp), %rdi
callq 0x18710
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
leaq -0x170(%rbp), %rax
movq %rax, -0x448(%rbp)
addq $0xe0, %rax
movq %rax, -0x440(%rbp)
movq -0x440(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x450(%rbp)
callq 0x2140
movq -0x448(%rbp), %rcx
movq -0x450(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x440(%rbp)
jne 0x178f9
jmp 0x1792c
leaq -0x80(%rbp), %rdi
callq 0x18710
movq -0x88(%rbp), %rdi
callq 0x22f0
nopw %cs:(%rax,%rax)