// File: /workspace/github_cpp_makefile_star2_O2/redpony[P]cpyp/./cpyp/mf_crp.h
// Function: cpyp::mf_crp<2u, unsigned int, std::hash<unsigned int>>::log_likelihood(double const&, double const&) const
double log_likelihood(const double& discount, const double& strength) const {
    double lp = 0.0;
    if (has_discount_prior())
      lp = Md::log_beta_density(discount, discount_prior_strength_, discount_prior_beta_);
    if (has_strength_prior())
      lp += Md::log_gamma_density(strength + discount, strength_prior_shape_, strength_prior_rate_);
    assert(lp <= 0.0);
    if (num_customers_) {  // if restaurant is not empty
      if (discount > 0.0) {  // two parameter case: discount > 0
        const double r = lgamma(1.0 - discount);
        if (strength)
          lp += lgamma(strength) - lgamma(strength / discount);
        lp += - lgamma(strength + num_customers_)
             + num_tables_ * log(discount) + lgamma(strength / discount + num_tables_);
        // above line implies
        // 1) when adding a customer to a restaurant containing N customers:
        //    lp -= log(strength + N)    [because \Gamma(s+N+1) = (s+N)\Gamma(s+N)
        // 2) when removing a customer from a restaurant containing N customers:
        //    lp += log(strength + N - 1)  [because \Gamma(s+N) = (s+N-1)\Gamma(s+N-1)]
        // 3) when adding a table to a restaurant containing T tables:
        //    lp += log(discount) + log(s / d + T)
        // 4) when removing a table from a restuarant containint T tables:
        //    lp -= log(discount) + log(s / d + T - 1)

        assert(std::isfinite(lp));
        for (auto& dish_loc : dish_locs_)
          for (unsigned floor = 0; floor < NumFloors; ++floor)
            for (auto& bin : dish_loc.second.h[floor])
              lp += (lgamma(bin.first - discount) - r) * bin.second;
         // above implies
         // 1) when adding to a table seating N > 1 customers
         //    lp += log(N - discount)
         // 2) when adding a new table
         //    do nothing
         // 3) when removing a customer from a table with N > 1 customers
         //    lp -= log(N - discount - 1)
         // 4) when closing a table
         //    do nothing
      } else if (!discount) { // discount == 0.0 (ie, Dirichlet Process)
        lp += lgamma(strength) + num_tables_ * log(strength) - lgamma(strength + num_tables_);
        assert(std::isfinite(lp));
        for (auto& dish_loc : dish_locs_)
          lp += lgamma(dish_loc.second.num_tables());
      } else { // should never happen
        assert(!"discount less than 0 detected!");
      }
    }
    assert(std::isfinite(lp));
    return lp;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
movsd 0x50(%rdi), %xmm0
ucomisd %xmm0, %xmm0
jp 0x776e
leaq 0x50(%rbx), %rsi
leaq 0x58(%rbx), %rdx
movq %r14, %rdi
callq 0x55ae
movsd %xmm0, (%rsp)
movsd 0x60(%rbx), %xmm0
ucomisd %xmm0, %xmm0
jp 0x7777
movsd (%r15), %xmm0
addsd (%r14), %xmm0
leaq 0x60(%rbx), %rsi
leaq 0x20(%rsp), %rdi
movsd %xmm0, (%rdi)
leaq 0x68(%rbx), %rdx
callq 0x56f0
movsd (%rsp), %xmm2
addsd %xmm0, %xmm2
xorpd %xmm0, %xmm0
ucomisd %xmm2, %xmm0
jb 0x7781
cmpl $0x0, 0x4(%rbx)
movabsq $0x7ff0000000000000, %r12 # imm = 0x7FF0000000000000
je 0x774c
movsd (%r14), %xmm1
ucomisd %xmm0, %xmm1
movsd %xmm2, (%rsp)
jbe 0x74e6
movsd 0x1b85(%rip), %xmm0     # 0x9010
subsd %xmm1, %xmm0
callq 0x2110
movsd %xmm0, 0x10(%rsp)
movsd (%r15), %xmm0
ucomisd 0x1bd1(%rip), %xmm0     # 0x9078
jne 0x74af
jnp 0x759a
callq 0x2110
movsd %xmm0, 0x8(%rsp)
movsd (%r15), %xmm0
divsd (%r14), %xmm0
callq 0x2110
movsd 0x8(%rsp), %xmm2
subsd %xmm0, %xmm2
movsd (%rsp), %xmm1
addsd %xmm2, %xmm1
movsd (%r15), %xmm0
jmp 0x759f
jne 0x77bf
jp 0x77bf
movsd (%r15), %xmm0
callq 0x2110
movsd %xmm0, 0x10(%rsp)
movl (%rbx), %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd (%r15), %xmm0
callq 0x2130
mulsd 0x8(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movl (%rbx), %eax
cvtsi2sd %rax, %xmm0
addsd (%r15), %xmm0
callq 0x2110
movsd 0x10(%rsp), %xmm1
subsd %xmm0, %xmm1
movsd (%rsp), %xmm0
addsd %xmm1, %xmm0
movq %xmm0, %rax
btrq $0x3f, %rax
cmpq %r12, %rax
jge 0x77fd
movsd %xmm0, (%rsp)
addq $0x18, %rbx
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x7590
movl 0x14(%rbx), %eax
cvtsi2sd %rax, %xmm0
callq 0x2110
movsd (%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
jmp 0x756b
movsd (%rsp), %xmm2
jmp 0x774c
movsd (%rsp), %xmm1
movsd %xmm1, (%rsp)
movl 0x4(%rbx), %eax
cvtsi2sd %rax, %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x2110
movsd %xmm0, 0x8(%rsp)
movl (%rbx), %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd (%r14), %xmm0
callq 0x2130
mulsd 0x18(%rsp), %xmm0
subsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd (%r15), %xmm1
divsd (%r14), %xmm1
movl (%rbx), %eax
cvtsi2sd %rax, %xmm0
addsd %xmm1, %xmm0
callq 0x2110
movapd %xmm0, %xmm2
addsd 0x8(%rsp), %xmm2
addsd (%rsp), %xmm2
movq %xmm2, %rax
btrq $0x3f, %rax
cmpq %r12, %rax
jge 0x77de
addq $0x18, %rbx
leaq 0x20(%rsp), %r15
leaq 0x40(%rsp), %r12
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x7742
movq %rbx, 0x38(%rsp)
leaq 0x18(%rbx), %rax
movq %rax, 0x18(%rsp)
xorl %ebx, %ebx
cmpq $0x2, %rbx
je 0x7738
movsd %xmm2, (%rsp)
movq %rbx, 0x8(%rsp)
shlq $0x7, %rbx
movq 0x18(%rsp), %rbp
leaq (%rbx,%rbp), %r13
movq %r15, %rdi
movq %r13, %rsi
callq 0x585e
movb 0x79(%rbp,%rbx), %al
movl %eax, %ecx
xorb $0x1, %cl
movb %cl, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
testb %al, %al
je 0x7699
andq $0x0, 0x50(%rsp)
jmp 0x76ae
movzbl 0x78(%r13), %eax
leaq (,%rax,8), %rax
addq %r13, %rax
movq %rax, 0x48(%rsp)
movq 0x8(%rsp), %rbx
movq %r15, %rdi
movq %r12, %rsi
callq 0x57fc
testb %al, %al
je 0x772b
cmpb $0x0, 0x20(%rsp)
je 0x76d0
movq 0x28(%rsp), %r13
jmp 0x76d9
movq 0x30(%rsp), %r13
addq $0x8, %r13
movl (%r13), %eax
cvtsi2sd %rax, %xmm0
subsd (%r14), %xmm0
callq 0x2110
subsd 0x10(%rsp), %xmm0
movl 0x4(%r13), %eax
cvtsi2sd %rax, %xmm1
mulsd %xmm0, %xmm1
movsd (%rsp), %xmm0
addsd %xmm1, %xmm0
cmpb $0x1, 0x20(%rsp)
movsd %xmm0, (%rsp)
jne 0x771c
addq $0x8, 0x28(%rsp)
jmp 0x76b3
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x76b3
incq %rbx
movsd (%rsp), %xmm2
jmp 0x764e
movq 0x38(%rsp), %rbx
jmp 0x7632
movabsq $0x7ff0000000000000, %r12 # imm = 0x7FF0000000000000
movq %xmm2, %rax
btrq $0x3f, %rax
cmpq %r12, %rax
jge 0x77a0
movapd %xmm2, %xmm0
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorpd %xmm0, %xmm0
jmp 0x7414
movsd (%rsp), %xmm2
jmp 0x7451
leaq 0x1de2(%rip), %rdi      # 0x956a
leaq 0x21fa(%rip), %rsi      # 0x9989
leaq 0x2203(%rip), %rcx      # 0x9999
movl $0x102, %edx            # imm = 0x102
callq 0x20d0
leaq 0x1e4e(%rip), %rdi      # 0x95f5
leaq 0x21db(%rip), %rsi      # 0x9989
leaq 0x21e4(%rip), %rcx      # 0x9999
movl $0x12b, %edx            # imm = 0x12B
callq 0x20d0
leaq 0x1e41(%rip), %rdi      # 0x9607
leaq 0x21bc(%rip), %rsi      # 0x9989
leaq 0x21c5(%rip), %rcx      # 0x9999
movl $0x128, %edx            # imm = 0x128
callq 0x20d0
leaq 0x1e10(%rip), %rdi      # 0x95f5
leaq 0x219d(%rip), %rsi      # 0x9989
leaq 0x21a6(%rip), %rcx      # 0x9999
movl $0x114, %edx            # imm = 0x114
callq 0x20d0
leaq 0x1df1(%rip), %rdi      # 0x95f5
leaq 0x217e(%rip), %rsi      # 0x9989
leaq 0x2187(%rip), %rcx      # 0x9999
movl $0x124, %edx            # imm = 0x124
callq 0x20d0