metrumresearchgroup / mrgsolve

Simulate from ODE-based population PK/PD and QSP models in R
https://mrgsolve.org
129 stars 36 forks source link

Add mwrite_cpp; more verbose matrix objects in yaml #1213

Closed kylebaron closed 1 month ago

kylebaron commented 1 month ago

Opening this PR to address some additional issues discovered when scrutinizing #1190

reprex

library(mrgsolve)
#> 
#> Attaching package: 'mrgsolve'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

mod <- modlib("popex")
#> Building popex ...
#> done.

Write to yaml

a <- mwrite_yaml(mod, "popex-2.yaml")

yam <- readLines("popex-2.yaml")

omega rendered like this

cat(yam[21:37], sep = "\n")
#> omega:
#>   data:
#>     matrix1:
#>       row1: 0.3
#>       row2:
#>       - 0.0
#>       - 0.1
#>       row3:
#>       - 0.0
#>       - 0.0
#>       - 0.5
#>   labels:
#>     matrix1:
#>     - ECL
#>     - EV
#>     - EKA
#>   names: '...'

Now, write to native mrgsolve format

x <- mwrite_cpp(mod, "popex-2.mod")

mod2 <- mread(x$file)
#> Building popex-2_mod ... done.

cat(mod2@code[14:26], sep = "\n")
#> $OMEGA
#> @block
#> @labels ECL EV EKA
#> // row 1
#> 0.3
#> // row 2
#> 0
#> 0.1
#> // row 3
#> 0
#> 0
#> 0.5

Simulate from this

mrgsim(mod2, ev(amt = 100, ID = 1:10)) %>% plot()

Convert a matrix to something for writing out

omat(mod)
#> $...
#>       [,1] [,2] [,3]
#> ECL:   0.3  0.0  0.0
#> EV:    0.0  0.1  0.0
#> EKA:   0.0  0.0  0.5

mrgsolve:::get_upper_tri(omat(mod))
#> $row1
#> [1] 0.3
#> 
#> $row2
#> [1] 0.0 0.1
#> 
#> $row3
#> [1] 0.0 0.0 0.5

Created on 2024-07-20 with reprex v2.1.1

kyleam commented 1 month ago

Aside from the check for labels "." and the mwrite_cpp doc destination, these changes off feature/transport look good to me.