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,0x14(%rsp)
  test   %r8d,%r8d
  jle    L97
  mov    %rdx,%rax
  mov    %r9d,%edx
  movslq %r9d,%r12
  mov    %rdi,0x20(%rsp)
  imul   %r9d,%edx
  mov    %rax,0x30(%rsp)
  lea    0x0(,%r12,8),%rbx
  lea    0x0(,%r12,4),%rax
  mov    %rbx,0x38(%rsp)
  mov    %rsi,0x50(%rsp)
  movslq %edx,%rdx
  mov    %rax,0x18(%rsp)
  lea    0x0(,%rdx,4),%rdi
  mov    %rsi,0x28(%rsp)
  mov    %rdi,0x40(%rsp)
  movl   $0x0,0x48(%rsp)
  movq   $0x0,0x8(%rsp)
  cs nopw 0x0(%rax,%rax,1)
L77:
  mov    0x14(%rsp),%r14d
  mov    0x30(%rsp),%rbx
  mov    0xa8(%rsp),%r9
  mov    0xa0(%rsp),%r8
  mov    0x28(%rsp),%rsi
  mov    0x20(%rsp),%rdi
  mov    %r14d,%ecx
  mov    %rbx,%rdx
  call   <_tram_estimate_transition_matrix@plt>
  test   %r14d,%r14d
  jle    L13
  xor    %r13d,%r13d
  xor    %ebp,%ebp
  nopl   (%rax)
L76:
  xor    %r15d,%r15d
  jmp    L72
  nopl   (%rax)
L12:
  call   <log@plt>
  pxor   %xmm0,%xmm0
  imul   %r14d,%eax
  cvtsi2sd %eax,%xmm0
  addsd  0x8(%rsp),%xmm0
  movsd  %xmm0,0x8(%rsp)
L47:
  add    $0x1,%r15
  cmp    %r12,%r15
  je     L146
L72:
  mov    (%rbx,%r15,4),%r14d
  test   %r14d,%r14d
  je     L47
  mov    0xa8(%rsp),%rax
  lea    0x0(%r13,%r15,1),%edx
  movslq %edx,%rdx
  movsd  (%rax,%rdx,8),%xmm0
  cmp    %r15d,%ebp
  jne    L12
  call   <log@plt>
  pxor   %xmm0,%xmm0
  pxor   %xmm1,%xmm1
  pxor   %xmm3,%xmm3
  cvtsi2sd %r14d,%xmm0
  add    $0x1,%r15
  cvtsi2sd %eax,%xmm1
  addsd  %xmm3,%xmm0
  mulsd  %xmm1,%xmm0
  addsd  0x8(%rsp),%xmm0
  movsd  %xmm0,0x8(%rsp)
  cmp    %r12,%r15
  jne    L72
  nopl   0x0(%rax,%rax,1)
L146:
  mov    0x14(%rsp),%eax
  add    $0x1,%ebp
  add    0x18(%rsp),%rbx
  add    %eax,%r13d
  cmp    %ebp,%eax
  jne    L76
L13:
  mov    0x48(%rsp),%eax
  mov    0x38(%rsp),%rsi
  mov    0x40(%rsp),%rcx
  add    %rsi,0x20(%rsp)
  add    %rsi,0x28(%rsp)
  add    $0x1,%eax
  add    %rcx,0x30(%rsp)
  cmp    %eax,0x4c(%rsp)
  je     L2
  mov    %eax,0x48(%rsp)
  jmp    L77
L2:
  mov    0x14(%rsp),%ebx
  mov    0x58(%rsp),%rcx
  xor    %edi,%edi
  pxor   %xmm0,%xmm0
  mov    0x50(%rsp),%r8
  mov    0x48(%rsp),%r9d
  mov    0x18(%rsp),%r10
  mov    0x38(%rsp),%r11
  lea    -0x1(%rbx),%esi
  nopl   0x0(%rax)
L130:
  test   %ebx,%ebx
  jle    L83
  xor    %eax,%eax
  jmp    L21
  nopl   0x0(%rax,%rax,1)
L14:
  mov    %rdx,%rax
L21:
  mov    (%rcx,%rax,4),%edx
  test   %edx,%edx
  jle    L132
  pxor   %xmm1,%xmm1
  cvtsi2sd %edx,%xmm1
  mulsd  (%r8,%rax,8),%xmm1
  addsd  %xmm1,%xmm0
L132:
  lea    0x1(%rax),%rdx
  cmp    %rax,%rsi
  jne    L14
L83:
  lea    0x1(%rdi),%eax
  add    %r10,%rcx
  add    %r11,%r8
  cmp    %edi,%r9d
  je     L79
  mov    %eax,%edi
  jmp    L130
L79:
  addsd  0x8(%rsp),%xmm0
  add    $0x68,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L97:
  add    $0x68,%rsp
  pxor   %xmm0,%xmm0
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

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;
}
```