// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1f8, %rsp            # imm = 0x1F8
xorpd %xmm0, %xmm0
leaq -0x160(%rbp), %rsi
movapd %xmm0, 0x50(%rsi)
movapd %xmm0, 0x40(%rsi)
movapd %xmm0, 0x30(%rsi)
movapd %xmm0, 0x20(%rsi)
movapd %xmm0, 0x10(%rsi)
movapd %xmm0, (%rsi)
movq $0x0, 0x68(%rsi)
movq $0x4, 0x60(%rsi)
leaq -0x58(%rbp), %rdi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x79da(%rip), %rdi      # 0xfff0
callq 0x2200
leaq -0x48(%rbp), %r14
movq -0x10(%r14), %rdi
cmpq %r14, %rdi
je 0x862d
callq 0x21c0
leaq -0x210(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2cea(%rip), %rsi      # 0xb329
leaq 0x2ce6(%rip), %rdx      # 0xb32c
leaq -0x220(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x220(%rbp), %rsi
movl $0x5, %edx
callq 0x259c
movq -0x220(%rbp), %rdi
cmpq %r15, %rdi
je 0x867b
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x7956(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x86ad
callq 0x21c0
leaq -0x1f0(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2e41(%rip), %rsi      # 0xb500
leaq 0x2e3e(%rip), %rdx      # 0xb504
leaq -0x200(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x200(%rbp), %rsi
movl $0xa, %edx
callq 0x259c
movq -0x200(%rbp), %rdi
cmpq %r15, %rdi
je 0x86fb
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x78d6(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x872d
callq 0x21c0
leaq -0x1d0(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2c42(%rip), %rsi      # 0xb381
leaq 0x2c41(%rip), %rdx      # 0xb387
leaq -0x1e0(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
movl $0x14, %edx
callq 0x259c
movq -0x1e0(%rbp), %rdi
cmpq %r15, %rdi
je 0x877b
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x7856(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x87ad
callq 0x21c0
leaq -0x1b0(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2b6a(%rip), %rsi      # 0xb329
leaq 0x2b66(%rip), %rdx      # 0xb32c
leaq -0x1c0(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
movl $0x5, %edx
callq 0x259c
movq -0x1c0(%rbp), %rdi
cmpq %r15, %rdi
je 0x87fb
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x77d6(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x882d
callq 0x21c0
leaq -0x190(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2cc1(%rip), %rsi      # 0xb500
leaq 0x2cbe(%rip), %rdx      # 0xb504
leaq -0x1a0(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
movl $0xa, %edx
callq 0x259c
movq -0x1a0(%rbp), %rdi
cmpq %r15, %rdi
je 0x887b
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x7756(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x88ad
callq 0x21c0
leaq -0x170(%rbp), %r15
movq %r15, -0x10(%r15)
leaq 0x2ac2(%rip), %rsi      # 0xb381
leaq 0x2ac1(%rip), %rdx      # 0xb387
leaq -0x180(%rbp), %rdi
callq 0xa378
leaq -0x160(%rbp), %rdi
leaq -0x180(%rbp), %rsi
movl $0x14, %edx
callq 0x259c
movq -0x180(%rbp), %rdi
cmpq %r15, %rdi
je 0x88fb
callq 0x21c0
leaq -0x58(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x3316
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x76d6(%rip), %rdi      # 0xfff0
callq 0x2200
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
je 0x892d
callq 0x21c0
leaq -0x50(%rbp), %rcx
movl $0x0, (%rcx)
xorl %eax, %eax
movq %rax, 0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
movq %rax, 0x20(%rcx)
leaq -0xb8(%rbp), %rbx
movl $0xc350, %r14d          # imm = 0xC350
leaq -0x160(%rbp), %r13
leaq -0x58(%rbp), %r12
leaq -0xc0(%rbp), %rdi
movq %r13, %rsi
callq 0x31ea
movq %r12, %rdi
movq %rbx, %rsi
callq 0x659c
leaq -0x50(%rbp), %rcx
cmpq %rcx, %rax
je 0x89a1
movq %r12, %rdi
movq %rbx, %rsi
callq 0x4392
movsd (%rax), %xmm0
addsd 0x26a5(%rip), %xmm0     # 0xb040
movsd %xmm0, (%rax)
jmp 0x89fa
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x90(%rbp), %r15
movq %r15, %rdi
callq 0x4420
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0x70(%rbp)
movq %r12, %rdi
movq %r15, %rsi
callq 0x6254
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x89fa
callq 0x21c0
movq -0xb8(%rbp), %rdi
leaq -0xa8(%rbp), %rax
cmpq %rax, %rdi
je 0x8a12
callq 0x21c0
decq %r14
jne 0x8961
movl $0x0, -0xb8(%rbp)
xorl %eax, %eax
movq %rax, -0xb0(%rbp)
movq %rbx, -0xa8(%rbp)
movq %rbx, -0xa0(%rbp)
movq %rax, -0x98(%rbp)
movq -0x40(%rbp), %rbx
leaq -0x50(%rbp), %rax
cmpq %rax, %rbx
je 0x8b1b
leaq -0xe0(%rbp), %r14
leaq -0xf0(%rbp), %r13
leaq -0x90(%rbp), %r15
leaq -0xc0(%rbp), %r12
movq %r14, -0xf0(%rbp)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x4420
movsd 0x40(%rbx), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd %xmm0, -0xd0(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0xf0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
addq %rsi, %rdx
movq %r15, %rdi
callq 0x4420
movsd -0x60(%rbp), %xmm0
divsd 0x27eb(%rip), %xmm0     # 0xb2b8
movsd %xmm0, -0x70(%rbp)
movq %r12, %rdi
movq %r15, %rsi
callq 0x6254
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x8af2
callq 0x21c0
movq -0xf0(%rbp), %rdi
cmpq %r14, %rdi
je 0x8b03
callq 0x21c0
movq %rbx, %rdi
callq 0x2210
movq %rax, %rbx
leaq -0x50(%rbp), %rax
cmpq %rax, %rbx
jne 0x8a70
leaq -0x90(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x391c
leaq -0xc0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x3aa4
movsd %xmm0, -0x60(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x3aa4
movsd %xmm0, -0xc8(%rbp)
movq 0x7488(%rip), %rdi      # 0xfff0
leaq 0x2913(%rip), %rsi      # 0xb482
movl $0x1b, %edx
callq 0x2200
movq 0x7470(%rip), %rdi      # 0xfff0
movsd -0x60(%rbp), %xmm0
callq 0x2260
leaq 0x29db(%rip), %rsi      # 0xb56c
movl $0x1, %edx
movq %rax, %rdi
callq 0x2200
movq 0x744b(%rip), %rdi      # 0xfff0
leaq 0x28f2(%rip), %rsi      # 0xb49e
movl $0x1b, %edx
callq 0x2200
movq 0x7433(%rip), %rdi      # 0xfff0
movsd -0xc8(%rbp), %xmm0
callq 0x2260
leaq 0x299b(%rip), %rsi      # 0xb56c
movl $0x1, %edx
movq %rax, %rdi
callq 0x2200
leaq -0x90(%rbp), %rdi
callq 0x4ee0
leaq -0xc0(%rbp), %rdi
callq 0x4ee0
leaq -0x58(%rbp), %rdi
callq 0x4ee0
leaq -0x128(%rbp), %rbx
movq %rbx, %rdi
callq 0xa150
movq -0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x8c1c
callq 0x21c0
movq -0x150(%rbp), %rax
testq %rax, %rax
je 0x8c39
leaq -0x160(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movb $0x1, %al
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rdi
callq 0x4411
jmp 0x8d11
jmp 0x8d3e
jmp 0x8cc2
jmp 0x8d09
movq %rax, %rbx
movq -0x180(%rbp), %rdi
jmp 0x8cdf
jmp 0x8d09
jmp 0x8cc2
jmp 0x8d09
movq %rax, %rbx
movq -0x1a0(%rbp), %rdi
jmp 0x8cdf
jmp 0x8d09
jmp 0x8cc2
jmp 0x8d09
movq %rax, %rbx
movq -0x1c0(%rbp), %rdi
jmp 0x8cdf
jmp 0x8d09
jmp 0x8cc2
jmp 0x8d09
movq %rax, %rbx
movq -0x1e0(%rbp), %rdi
jmp 0x8cdf
jmp 0x8d09
jmp 0x8cc2
jmp 0x8d09
movq %rax, %rbx
movq -0x200(%rbp), %rdi
jmp 0x8cdf
jmp 0x8d09
movq %rax, %rbx
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
jne 0x8ce8
jmp 0x8daa
jmp 0x8d09
movq %rax, %rbx
movq -0x220(%rbp), %rdi
cmpq %r15, %rdi
je 0x8daa
callq 0x21c0
jmp 0x8daa
jmp 0x8d09
movq %rax, %rbx
leaq -0x48(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
jne 0x8ce8
jmp 0x8daa
movq %rax, %rbx
jmp 0x8daa
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x4ee0
jmp 0x8d71
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x8d89
callq 0x21c0
jmp 0x8d89
jmp 0x8d86
movq %rax, %rbx
jmp 0x8d71
movq %rax, %rbx
jmp 0x8d60
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x8d60
callq 0x21c0
movq -0xf0(%rbp), %rdi
cmpq %r14, %rdi
je 0x8d71
callq 0x21c0
leaq -0xc0(%rbp), %rdi
callq 0x4ee0
jmp 0x8da1
jmp 0x8d86
movq %rax, %rbx
jmp 0x8da1
movq %rax, %rbx
movq -0xb8(%rbp), %rdi
leaq -0xa8(%rbp), %rax
cmpq %rax, %rdi
je 0x8da1
callq 0x21c0
leaq -0x58(%rbp), %rdi
callq 0x4ee0
leaq -0x160(%rbp), %rdi
callq 0x9fd6
movq %rbx, %rdi
callq 0x22b0