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

  // Create a VoseTree structure
  VoseTree tree;
  tree.set_max_marbles(4);

  // Create new marbles and add them to the Vose tree
  std::cerr << tree.toString();
  tree.add("red", 5L);
  std::cerr << tree.toString();
  tree.add("blue", 10L);
  std::cerr << tree.toString();
  tree.add("yellow", 20L);
  std::cerr << tree.toString();

  tree.add("red", 5L);
  std::cerr << tree.toString();
  tree.add("blue", 10L);
  std::cerr << tree.toString();
  tree.add("yellow", 20L);
  std::cerr << tree.toString();

  // Sample from the tree with and save the results to a histogram
  std::map<std::string,double> histogram;
  long hist_sum = 0L;
  for (int i = 0; i != 50000; ++i) {
    auto idx = tree.rand_marble();

    if (histogram.find(idx.label) != histogram.end()) {
      histogram[idx.label] += 1.0;
      hist_sum += 1L;
    }
    else {
      histogram.insert(std::make_pair(idx.label, 1.0));
      hist_sum += 1L;
    }
  }
  
  std::map<std::string,double> new_hist;
  std::for_each(histogram.cbegin(), histogram.cend(),
    [&new_hist,hist_sum] (std::pair<const std::string, double> a) {
      //std::cerr << a.first << ", " << (double)a.second/hist_sum << "\n";
      new_hist.insert( std::make_pair(a.first,(double)a.second/hist_sum));
  });

  std::map<std::string, double> exact_prob = tree.probabilities();
 
  // Compare the results with kl divergence
  double kl1 = VoseTree::kl(new_hist, exact_prob);
  double kl2 = VoseTree::kl(exact_prob, new_hist);
  std::cerr << "kl(histogram, exact_prob): " << kl1 << "\n";
  std::cerr << "kl(exact_prob, histogram): " << kl2 << "\n";
  
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x460, %rsp            # imm = 0x460
movq %rdi, -0x8(%rbp)
leaq -0x78(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x18660
movq -0x3c0(%rbp), %rdi
movl $0x4, %esi
callq 0x186f0
jmp 0x161e2
leaq -0xa8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x161f4
movq 0x14df5(%rip), %rdi     # 0x2aff0
leaq -0xa8(%rbp), %rsi
callq 0x21e0
jmp 0x16209
leaq -0xa8(%rbp), %rdi
callq 0x2140
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x2300
movq -0x3c8(%rbp), %rdx
leaq 0x60a3(%rip), %rsi      # 0x1c2d9
leaq -0xc8(%rbp), %rdi
callq 0x2270
jmp 0x16244
leaq -0x78(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
movl $0x5, %edx
callq 0x24f0
jmp 0x1625b
leaq -0xc8(%rbp), %rdi
callq 0x2140
leaq -0xc9(%rbp), %rdi
callq 0x2240
leaq -0xf0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x16285
movq 0x14d64(%rip), %rdi     # 0x2aff0
leaq -0xf0(%rbp), %rsi
callq 0x21e0
jmp 0x1629a
leaq -0xf0(%rbp), %rdi
callq 0x2140
leaq -0x111(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
callq 0x2300
movq -0x3d0(%rbp), %rdx
leaq 0x61e9(%rip), %rsi      # 0x1c4b0
leaq -0x110(%rbp), %rdi
callq 0x2270
jmp 0x162d5
leaq -0x78(%rbp), %rdi
leaq -0x110(%rbp), %rsi
movl $0xa, %edx
callq 0x24f0
jmp 0x162ec
leaq -0x110(%rbp), %rdi
callq 0x2140
leaq -0x111(%rbp), %rdi
callq 0x2240
leaq -0x138(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x16316
movq 0x14cd3(%rip), %rdi     # 0x2aff0
leaq -0x138(%rbp), %rsi
callq 0x21e0
jmp 0x1632b
leaq -0x138(%rbp), %rdi
callq 0x2140
leaq -0x159(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x2300
movq -0x3d8(%rbp), %rdx
leaq 0x5fd9(%rip), %rsi      # 0x1c331
leaq -0x158(%rbp), %rdi
callq 0x2270
jmp 0x16366
leaq -0x78(%rbp), %rdi
leaq -0x158(%rbp), %rsi
movl $0x14, %edx
callq 0x24f0
jmp 0x1637d
leaq -0x158(%rbp), %rdi
callq 0x2140
leaq -0x159(%rbp), %rdi
callq 0x2240
leaq -0x180(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x163a7
movq 0x14c42(%rip), %rdi     # 0x2aff0
leaq -0x180(%rbp), %rsi
callq 0x21e0
jmp 0x163bc
leaq -0x180(%rbp), %rdi
callq 0x2140
leaq -0x1a1(%rbp), %rdi
movq %rdi, -0x3e0(%rbp)
callq 0x2300
movq -0x3e0(%rbp), %rdx
leaq 0x5ef0(%rip), %rsi      # 0x1c2d9
leaq -0x1a0(%rbp), %rdi
callq 0x2270
jmp 0x163f7
leaq -0x78(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
movl $0x5, %edx
callq 0x24f0
jmp 0x1640e
leaq -0x1a0(%rbp), %rdi
callq 0x2140
leaq -0x1a1(%rbp), %rdi
callq 0x2240
leaq -0x1c8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x16438
movq 0x14bb1(%rip), %rdi     # 0x2aff0
leaq -0x1c8(%rbp), %rsi
callq 0x21e0
jmp 0x1644d
leaq -0x1c8(%rbp), %rdi
callq 0x2140
leaq -0x1e9(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x2300
movq -0x3e8(%rbp), %rdx
leaq 0x6036(%rip), %rsi      # 0x1c4b0
leaq -0x1e8(%rbp), %rdi
callq 0x2270
jmp 0x16488
leaq -0x78(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
movl $0xa, %edx
callq 0x24f0
jmp 0x1649f
leaq -0x1e8(%rbp), %rdi
callq 0x2140
leaq -0x1e9(%rbp), %rdi
callq 0x2240
leaq -0x210(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x164c9
movq 0x14b20(%rip), %rdi     # 0x2aff0
leaq -0x210(%rbp), %rsi
callq 0x21e0
jmp 0x164de
leaq -0x210(%rbp), %rdi
callq 0x2140
leaq -0x231(%rbp), %rdi
movq %rdi, -0x3f0(%rbp)
callq 0x2300
movq -0x3f0(%rbp), %rdx
leaq 0x5e26(%rip), %rsi      # 0x1c331
leaq -0x230(%rbp), %rdi
callq 0x2270
jmp 0x16519
leaq -0x78(%rbp), %rdi
leaq -0x230(%rbp), %rsi
movl $0x14, %edx
callq 0x24f0
jmp 0x16530
leaq -0x230(%rbp), %rdi
callq 0x2140
leaq -0x231(%rbp), %rdi
callq 0x2240
leaq -0x258(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3080
jmp 0x1655a
movq 0x14a8f(%rip), %rdi     # 0x2aff0
leaq -0x258(%rbp), %rsi
callq 0x21e0
jmp 0x1656f
leaq -0x258(%rbp), %rdi
callq 0x2140
leaq -0x288(%rbp), %rdi
callq 0x4fd0
movq $0x0, -0x290(%rbp)
movl $0x0, -0x294(%rbp)
cmpl $0xc350, -0x294(%rbp)   # imm = 0xC350
je 0x169c2
leaq -0x2c8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2f00
jmp 0x165be
leaq -0x2c0(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x5320
movq %rax, -0x3f8(%rbp)
jmp 0x165da
movq -0x3f8(%rbp), %rax
movq %rax, -0x2d0(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x5350
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x52f0
testb $0x1, %al
jne 0x16617
jmp 0x168eb
leaq -0x2c0(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x5380
movq %rax, -0x400(%rbp)
jmp 0x16633
movq -0x400(%rbp), %rax
movsd 0x59c6(%rip), %xmm0     # 0x1c008
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq -0x290(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x290(%rbp)
jmp 0x16991
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x166c1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x2140
leaq -0xc9(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x1671e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x2140
leaq -0x111(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x1677b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x2140
leaq -0x159(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x167d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x2140
leaq -0x1a1(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x16835
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x2140
leaq -0x1e9(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x210(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x16892
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x2140
leaq -0x231(%rbp), %rdi
callq 0x2240
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x2140
jmp 0x16bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x16be8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x169b1
leaq -0x2c0(%rbp), %rsi
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0x308(%rbp)
leaq -0x300(%rbp), %rdi
leaq -0x308(%rbp), %rdx
callq 0x54a0
jmp 0x16918
leaq -0x288(%rbp), %rdi
leaq -0x300(%rbp), %rsi
callq 0x5460
movb %dl, -0x409(%rbp)
movq %rax, -0x408(%rbp)
jmp 0x1693a
movb -0x409(%rbp), %al
movq -0x408(%rbp), %rcx
movq %rcx, -0x318(%rbp)
movb %al, -0x310(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x54e0
movq -0x290(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x290(%rbp)
jmp 0x16991
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x54e0
jmp 0x169b1
leaq -0x2c8(%rbp), %rdi
callq 0x4200
movl -0x294(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x294(%rbp)
jmp 0x1659c
leaq -0x2c8(%rbp), %rdi
callq 0x4200
jmp 0x16be8
leaq -0x348(%rbp), %rdi
movq %rdi, -0x428(%rbp)
callq 0x4fd0
leaq -0x288(%rbp), %rdi
movq %rdi, -0x430(%rbp)
callq 0x5140
movq -0x430(%rbp), %rdi
movq %rax, -0x350(%rbp)
callq 0x5170
movq %rax, %rcx
movq -0x428(%rbp), %rax
movq %rcx, -0x358(%rbp)
movq %rax, -0x368(%rbp)
movq -0x290(%rbp), %rax
movq %rax, -0x360(%rbp)
movq -0x350(%rbp), %rdi
movq -0x358(%rbp), %rsi
movq -0x368(%rbp), %rdx
movq -0x360(%rbp), %rcx
callq 0x16c10
movq %rdx, -0x420(%rbp)
movq %rax, -0x418(%rbp)
jmp 0x16a52
movq -0x420(%rbp), %rax
movq -0x418(%rbp), %rcx
movq %rcx, -0x378(%rbp)
movq %rax, -0x370(%rbp)
leaq -0x3a8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3460
jmp 0x16a80
leaq -0x348(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
callq 0x3630
movsd %xmm0, -0x438(%rbp)
jmp 0x16a9d
movsd -0x438(%rbp), %xmm0
movsd %xmm0, -0x3b0(%rbp)
leaq -0x3a8(%rbp), %rdi
leaq -0x348(%rbp), %rsi
callq 0x3630
movsd %xmm0, -0x440(%rbp)
jmp 0x16aca
movsd -0x440(%rbp), %xmm0
movsd %xmm0, -0x3b8(%rbp)
movq 0x1450f(%rip), %rdi     # 0x2aff0
leaq 0x594a(%rip), %rsi      # 0x1c432
callq 0x2210
movq %rax, -0x448(%rbp)
jmp 0x16af6
movq -0x448(%rbp), %rdi
movsd -0x3b0(%rbp), %xmm0
callq 0x2320
movq %rax, -0x450(%rbp)
jmp 0x16b13
movq -0x450(%rbp), %rdi
leaq 0x59fb(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x16b28
movq 0x144c1(%rip), %rdi     # 0x2aff0
leaq 0x5918(%rip), %rsi      # 0x1c44e
callq 0x2210
movq %rax, -0x458(%rbp)
jmp 0x16b44
movq -0x458(%rbp), %rdi
movsd -0x3b8(%rbp), %xmm0
callq 0x2320
movq %rax, -0x460(%rbp)
jmp 0x16b61
movq -0x460(%rbp), %rdi
leaq 0x59ad(%rip), %rsi      # 0x1c51c
callq 0x2210
jmp 0x16b76
leaq -0x3a8(%rbp), %rdi
callq 0x5050
leaq -0x348(%rbp), %rdi
callq 0x5050
leaq -0x288(%rbp), %rdi
callq 0x5050
leaq -0x78(%rbp), %rdi
callq 0x18710
movb $0x1, %al
andb $0x1, %al
addq $0x460, %rsp            # imm = 0x460
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x16bdc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x3a8(%rbp), %rdi
callq 0x5050
leaq -0x348(%rbp), %rdi
callq 0x5050
leaq -0x288(%rbp), %rdi
callq 0x5050
leaq -0x78(%rbp), %rdi
callq 0x18710
movq -0x80(%rbp), %rdi
callq 0x22f0
nopw %cs:(%rax,%rax)