heemod icon indicating copy to clipboard operation
heemod copied to clipboard

Transition Costs/Effects

Open jrdnmdhl opened this issue 8 years ago • 3 comments

I was taking a look at the way transitional cost/effects are currently implemented through tunnel states (relevant: #137) and was wondering if there might be a more parsimonious solution.

The counts of patients entering/exiting can be calculated directly from the Markov calculations without requiring the creation of tunnel states.

Would be interested in hearing thoughts on whether this is worthwhile enough to work on a pull request. Details of what I am doing below...

How this is currently done in compute_counts.eval_matrix:

  add_and_mult <- function(x, y) {
    (x + inflow) %*% y
  }
  
  list_counts <- Reduce(
    add_and_mult,
    x,
    init,
    accumulate = TRUE
  )

Alternately, one could do:

 # Make a diagonal matrix of inital state vector
  init_mat = diag(init)
  
  # Do element-wise multiplication to get the numbers
  # undergoing each transition
  calc_trans <- function(x, y) {
    (colSums(x) + diag(inflow)) * y
  }
  uncond_trans <- Reduce(
    calc_trans,
    x,
    init_mat,
    accumulate = TRUE
  )
  
  # Sum over columns to get trace
  list_counts <- lapply(
    uncond_trans,
    colSums
  )

uncond_trans then represents the counts undergoing each possible transition. These can then be used to calculate the entry/exit counts:

# Zero out diagonals
 zero_diag <- function(x) {
   n_cols = ncol(x)
   diag_one = diag(1,n_cols)
   return(x - x*diag_one)
 }
 zero_diag_trans <- lapply(
   uncond_trans,
   zero_diag
 )
 
 # Sum over rows and add inflow to get entry counts
 entry_counts <- lapply(
   zero_diag_trans,
   function(mat) colSums(mat) + inflow
 )
 
 # Add initial state vector to entry at time 0
 entry_counts[[1]] = entry_counts[[1]] + init

 # Sum over columns to get exit counts
 exit_counts <- lapply(
   zero_diag_trans,
   rowSums
 )

jrdnmdhl avatar Feb 07 '17 19:02 jrdnmdhl

Thanks, I'll have a look!

pierucci avatar Feb 08 '17 17:02 pierucci

This way of computing transitions indeed keeps track of everything. Implementing transition costs is just a simple matter of coding, except for the following questions:

  1. What kind of transition costs do we want to feature in heemod? Entry/exit costs, or more specific from-x-to-y-costs? (or both? I'd rather have both.)
  2. How do we specify them in the UI? (ideally in a way that is clear, readable, not too tedious)

Some random thoughts:

  • The transition costs should be defined by strategy, not by model.
  • They should work with model-time and state-time dependency.
  • They can impact any state values.

pierucci avatar Feb 19 '17 19:02 pierucci

My guess about the best way to handle the syntax would be to declare transitions in much the same way that users already declare states. Example:

define_transition = function(from=NULL, to=NULL, ...) {
  # implementation
}

This would allow for all three cases:

  • User specifies from only -> exit cost/effect
  • User specifies to only -> entry cost/effect
  • User specifies both from and to -> transition cost/effect

Another important note I should mention is that my code doesn't handle the case where tunnel states are present. This doesn't affect exit costs, but it would be important to zero out transitions into any tunnel (except the first), otherwise those entry costs would be calculated as if they were a state residency cost.

jrdnmdhl avatar Feb 19 '17 20:02 jrdnmdhl