Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add C++ log-likelihood function to speed up optimization in dev_beta_binom() #66

Closed
wants to merge 1 commit into from

Conversation

nehill197
Copy link
Member

I wrote a non-vectorized C++ function to calculate the beta binomial log-likelihood, and used this in the call to optimize() within dev_beta_binom().
Microbenchmarking shows that optimizing using the C++ function is much faster than the previous version that optimized using the extras::log_lik_beta_binom() function.

image

Requires importing Rcpp.

@nehill197 nehill197 self-assigned this Jul 24, 2024
@nehill197 nehill197 requested a review from joethorley July 24, 2024 19:08
@joethorley joethorley requested a review from krlmlr July 24, 2024 19:12
@joethorley
Copy link
Member

@krlmlr - I've added you as a reviewer for discussion while we are working in Vancouver.

@krlmlr
Copy link
Collaborator

krlmlr commented Aug 5, 2024

Thanks, Nicole. Before adding native code to a package, can we explore how fast we can get with pure R? Something along the following lines might give a decent speed-up already:

log_lik_beta_binom <- function(x, size = 1, prob = 0.5, theta = 0) {
  alpha <- prob * 2 * (1 / theta)
  beta <- (1 - prob) * 2 * (1 / theta)
  lbeta_binom <- lgamma(size + 1) - lgamma(x + 1) - lgamma(size - x + 1) +
    lgamma(x + alpha) + lgamma(size - x + beta) - lgamma(size + alpha + beta) +
    lgamma(alpha + beta) - lgamma(alpha) - lgamma(beta)
  
  # FIXME: Rename bol to a more evocative name
  bol <- !is.na(x + size + prob + theta)
  if (length(bol) == 1) {
    # FIXME: Add fast path for scalar inputs
    ...
  } else if (length(bol) == 0) {
    numeric(0)
  } else {
    lbeta_binom[bol & ((x == 0 & prob == 0) | (x == size & prob == 1))] <- 0
    lbeta_binom[bol & x != 0 & prob == 0] <- -Inf
    lbeta_binom[bol & x != size & prob == 1] <- -Inf
    lbeta_binom[bol & x > size] <- -Inf
    bol_theta <- !is.na(theta)
    lbeta_binom[bol_theta & theta < 0] <- NaN
    use_binom <- bol_theta & theta == 0
    if (any(use_binom)) {
      lbinom <- log_lik_binom(x, size = size, prob = prob)
      lbeta_binom[use_binom] <- lbinom[use_binom]
    }
    lbeta_binom
  }
}

@nehill197
Copy link
Member Author

Closing this as we decided to go with speeding up the log-likelihood function in R, among other things, see #69

@nehill197 nehill197 closed this Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants