user: Please show me the C implementation that matches the assembly code listed below:

```asm
<_tram_discrete_log_likelihood_lower_bound>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x68,%rsp
  mov    %rcx,0x58(%rsp)
  mov    %r8d,0x4c(%rsp)
  mov    %r9d,0x10(%rsp)
  test   %r8d,%r8d
  jle    L134
  mov    %rsi,%rax
  mov    %r9d,%ecx
  movslq %r9d,%rsi
  lea    0x0(,%rsi,8),%rbx
  mov    %rbx,0x38(%rsp)
  mov    %rdi,0x20(%rsp)
  mov    %rax,0x50(%rsp)
  imul   %r9d,%ecx
  movslq %ecx,%rcx
  shl    $0x2,%rcx
  mov    %rcx,0x40(%rsp)
  mov    %rdx,0x30(%rsp)
  lea    0x0(,%rsi,4),%rdx
  mov    %rdx,0x18(%rsp)
  mov    %rax,0x28(%rsp)
  movl   $0x0,0x48(%rsp)
  pxor   %xmm5,%xmm5
  movsd  %xmm5,0x8(%rsp)
  jmp    L118
L140:
  movslq %ebp,%rax
  mov    0xa8(%rsp),%rcx
  movsd  (%rcx,%rax,8),%xmm0
  call   <log@plt>
  pxor   %xmm0,%xmm0
  cvtsi2sd %r12d,%xmm0
  addsd  D0(%rip),%xmm0
  pxor   %xmm1,%xmm1
  cvtsi2sd %eax,%xmm1
  mulsd  %xmm1,%xmm0
  addsd  0x8(%rsp),%xmm0
  movsd  %xmm0,0x8(%rsp)
L20:
  add    $0x1,%rbx
  add    $0x1,%ebp
  cmp    %r14,%rbx
  je     L80
L51:
  mov    0x0(%r13,%rbx,4),%r12d
  test   %r12d,%r12d
  je     L20
  cmp    %ebx,%r15d
  je     L140
  movslq %ebp,%rax
  mov    0xa8(%rsp),%rdi
  movsd  (%rdi,%rax,8),%xmm0
  call   <log@plt>
  imul   %r12d,%eax
  pxor   %xmm0,%xmm0
  cvtsi2sd %eax,%xmm0
  addsd  0x8(%rsp),%xmm0
  movsd  %xmm0,0x8(%rsp)
  jmp    L20
L80:
  add    $0x1,%r15d
  mov    0x10(%rsp),%esi
  add    %esi,0x14(%rsp)
  add    0x18(%rsp),%r13
  cmp    %r15d,%esi
  je     L7
L14:
  mov    0x10(%rsp),%r14d
  mov    0x14(%rsp),%ebp
  mov    $0x0,%ebx
  jmp    L51
L7:
  mov    0x48(%rsp),%eax
  add    $0x1,%eax
  mov    0x38(%rsp),%rcx
  add    %rcx,0x20(%rsp)
  add    %rcx,0x28(%rsp)
  mov    0x40(%rsp),%rcx
  add    %rcx,0x30(%rsp)
  cmp    %eax,0x4c(%rsp)
  je     L44
  mov    %eax,0x48(%rsp)
L118:
  mov    0xa8(%rsp),%r9
  mov    0xa0(%rsp),%r8
  mov    0x10(%rsp),%ebx
  mov    %ebx,%ecx
  mov    0x30(%rsp),%r13
  mov    %r13,%rdx
  mov    0x28(%rsp),%rsi
  mov    0x20(%rsp),%rdi
  call   <_tram_estimate_transition_matrix@plt>
  test   %ebx,%ebx
  jle    L7
  movl   $0x0,0x14(%rsp)
  mov    $0x0,%r15d
  jmp    L14
L44:
  mov    0x58(%rsp),%rcx
  mov    $0x0,%edi
  pxor   %xmm1,%xmm1
  mov    0x10(%rsp),%ebx
  mov    %ebx,%esi
  mov    0x50(%rsp),%r8
  mov    0x48(%rsp),%r9d
  mov    0x18(%rsp),%r10
  mov    0x38(%rsp),%r11
  jmp    L17
L90:
  add    $0x1,%rax
  cmp    %rax,%rsi
  je     L39
L79:
  mov    (%rcx,%rax,4),%edx
  test   %edx,%edx
  jle    L90
  pxor   %xmm0,%xmm0
  cvtsi2sd %edx,%xmm0
  mulsd  (%r8,%rax,8),%xmm0
  addsd  %xmm0,%xmm1
  jmp    L90
L39:
  lea    0x1(%rdi),%eax
  add    %r11,%r8
  add    %r10,%rcx
  cmp    %edi,%r9d
  je     L42
  mov    %eax,%edi
L17:
  test   %ebx,%ebx
  jle    L39
  mov    $0x0,%eax
  jmp    L79
L134:
  pxor   %xmm4,%xmm4
  movsd  %xmm4,0x8(%rsp)
  movapd %xmm4,%xmm1
L42:
  movsd  0x8(%rsp),%xmm0
  addsd  %xmm1,%xmm0
  add    $0x68,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

tool_calls: name: disassemble_data
arguments: tag: D0
data_type: byte[8]

tool: {"D0": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]}

assistant: ```c
double _tram_discrete_log_likelihood_lower_bound(double *log_lagrangian_mult, double *biased_conf_energies, int *count_matrices, int *state_counts, int n_therm_states, int n_conf_states, double *scratch_M, double *scratch_MM) {
  double a, b;
  int K, i, j;
  int KM, KMM, Ki;
  int CKij;
  double *T_ij;
  a = 0;
  T_ij = scratch_MM;
  for (K = 0; K < n_therm_states; ++K) {
    KM = K * n_conf_states;
    KMM = KM * n_conf_states;
    _tram_estimate_transition_matrix(&log_lagrangian_mult[KM], &biased_conf_energies[KM], &count_matrices[KMM], n_conf_states, scratch_M, T_ij);
    for (i = 0; i < n_conf_states; ++i) {
      for (j = 0; j < n_conf_states; ++j) {
        CKij = count_matrices[KMM + i * n_conf_states + j];
        if (0 == CKij)
          continue;
        if (i == j) {
          a += ((double)CKij + 0) * log(T_ij[i * n_conf_states + j]);
        } else {
          a += CKij * log(T_ij[i * n_conf_states + j]);
        }
      }
    }
  }
  b = 0;
  for (K = 0; K < n_therm_states; ++K) {
    KM = K * n_conf_states;
    for (i = 0; i < n_conf_states; ++i) {
      Ki = KM + i;
      if (state_counts[Ki] > 0)
        b += (state_counts[Ki] + 0) * biased_conf_energies[Ki];
    }
  }
  return a + b;
}
```