ocbe-uio / BayesSurvive

Bayesian survival models for high-dimensional data
GNU General Public License v3.0
1 stars 1 forks source link

Translate `func_MCMC()`'s subfunctions to C++ #11

Open wleoncio opened 6 months ago

wleoncio commented 6 months ago

Files to be translated

Cleanup

Combinations of BayesSurvive() to test

Not all combos are valid, see https://github.com/ocbe-uio/BayesSurvive/issues/11#issuecomment-2358401978.

Test number model.type MRF_G MRF_2b
1 Pooled FALSE FALSE
2 Pooled TRUE FALSE
3 CoxBVSSL FALSE FALSE
4 CoxBVSSL TRUE FALSE
5 Sub-struct FALSE FALSE
6 Sub-struct FALSE TRUE
7 Sub-struct TRUE FALSE
8 Sub-struct TRUE TRUE
wleoncio commented 3 months ago

Benchmark results for calling BayesSurvive() after translation of func_MCMC_graph():

Unit: seconds
 expr       min        lq     mean    median       uq      max neval cld
    R 48.663260 52.858755 56.45211 54.208202 58.65805 82.42916    30  a 
  C++  7.715861  8.870257 10.02130  9.466554 10.06589 24.06125    30   b
zhizuio commented 3 months ago

Benchmark results for calling BayesSurvive() after translation of func_MCMC_graph():

Unit: seconds
 expr       min        lq     mean    median       uq      max neval cld
    R 48.663260 52.858755 56.45211 54.208202 58.65805 82.42916    30  a 
  C++  7.715861  8.870257 10.02130  9.466554 10.06589 24.06125    30   b

Supert!

zhizuio commented 3 months ago

Hi Waldir,

I have the following error when installing the package from GitHub. One solution is to always keep the folder inst/doc/... with vignettes. Probably you have another better solution?

image
wleoncio commented 3 months ago

Hi George,

I can reproduce the error and your solution. Keeping track of built files (i.e., anything under /inst/doc) is not ideal, though.

What's the use of that build folder anyway? I tried deleting it and the package still installs with vignettes, you can also try it from the fix-vignettes branch:

remotes::install_github("ocbe-uio/BayesSurvive@fix-vignettes", build_vignettes = TRUE)
browseVignettes("BayesSurvive")
zhizuio commented 3 months ago

Hi George,

I can reproduce the error and your solution. Keeping track of built files (i.e., anything under /inst/doc) is not ideal, though.

What's the use of that build folder anyway? I tried deleting it and the package still installs with vignettes, you can also try it from the fix-vignettes branch:

remotes::install_github("ocbe-uio/BayesSurvive@fix-vignettes", build_vignettes = TRUE)
browseVignettes("BayesSurvive")

This solution works. Do you know if we can set up something, so that the usual installation still works?

wleoncio commented 3 months ago

Hi George,

I'm trying to create a second dataset to test the case of multiple subgroups ($S > 1$). The second subgroup is simply simData[[2]], so I created the following *_S2 objects:

dataset <- list(
  "X" = simData[[1]]$X,
  "t" = simData[[1]]$time,
  "di" = simData[[1]]$status
)
dataset_2S <- list(
  dataset,
  list(
    "X" = simData[[2]]$X,
    "t" = simData[[2]]$time,
    "di" = simData[[2]]$status
  )
)

initial <- list("gamma.ini" = rep(0, ncol(dataset$X)))
initial_2S <- list(
  initial,
  list("gamma.ini" = rep(0, ncol(dataset_2S[[2]]$X)))
)

hyperparPooled = list(
  "c0"     = 2,                      # prior of baseline hazard
  "tau"    = 0.0375,                 # sd (spike) for coefficient prior
  "cb"     = 20,                     # sd (slab) for coefficient prior
  "pi.ga"  = 0.02,                   # prior variable selection probability for standard Cox models
  "a"      = -4,                     # hyperparameter in MRF prior
  "b"      = 0.1,                    # hyperparameter in MRF prior
  "G"      = simData$G               # hyperparameter in MRF prior
)
hyperparPooled_2S = list(hyperparPooled, hyperparPooled)

However, if I run BayesSurvive(dataset_2S...) I get an error regarding incorrect dimensions of the hyperparameters (both for CoxBVSSL and Sub-struct models). What would be a proper formulation for hyperparPooled_2S?

zhizuio commented 3 months ago

Hi Waldir,

Most hyperparameters are not set as subgroup-specific currently, so that hyperparPooled is always a simple list, not a list of two combined lists. If we will allow most hyperparameters subgroup-specific, it will be a methodological extension:-) As for how much gain from this methodological extension, it requires more benchmarking studies.

Note that hyperparPooled$G should always be one matrix, see G <- G.MRF <- ini$G.ini in function func_MCMC_graph(). If there there are multiple subgroups, one simple construction of hyperparPooled$G is to put subgroup-specific graphs as block diagonals of a big matrix.

wleoncio commented 3 months ago

Thanks for checking, George!

Unfortunately, using hyperpooled for the sub-groups yields the same error. Since this is also observed in the original code, it's not related to this issue, so I'll open a different one to handle it later.

zhizuio commented 2 months ago

Thank you very much, Waldir, for updating and testing the package! If I remember correctly, the argument MRF_2b = TRUE is only valid when model.type ="Sub-struct". Then only the following 8 tests are needed, right?

Test number model.type MRF_G MRF_2b
1 Pooled FALSE FALSE
2 Pooled TRUE FALSE
3 CoxBVSSL FALSE FALSE
4 CoxBVSSL TRUE FALSE
5 Sub-struct FALSE FALSE
6 Sub-struct FALSE TRUE
7 Sub-struct TRUE FALSE
8 Sub-struct TRUE TRUE

It might be also helpful to add the following table in the help file or README.

Model Fix MRF_G Infer MRF_G
Pooled
CoxBVSSL
Sub-struct
wleoncio commented 2 months ago

Thanks for checking, will edit accordingly! :)

wleoncio commented 1 month ago

Question: when we have a situation like below (triggered when method != "Pooled" or !MRF_G), is it safe to assume that these objects are the same size across the $g = \{1, \ldots, S\}$ subgroups? For example, sobj$X[[g]] has the same dimensions for all values of g on that loop?

https://github.com/ocbe-uio/BayesSurvive/blob/83698c9f745b926dfa0bd1a8d4b8189205a5081e/R/UpdateRPlee11.R#L48-L56

zhizuio commented 1 month ago

Question: when we have a situation like below (triggered when method != "Pooled" or !MRF_G), is it safe to assume that these objects are the same size across the g = { 1 , … , S } subgroups? For example, sobj$X[[g]] has the same dimensions for all values of g on that loop?

https://github.com/ocbe-uio/BayesSurvive/blob/83698c9f745b926dfa0bd1a8d4b8189205a5081e/R/UpdateRPlee11.R#L48-L56

Yes, the same dimension across subgroups should be required according to the model setting.

wleoncio commented 1 month ago

Great news, thanks! Then I can just implement those as cubes on C++... :)