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

Remove fit_tmb #5

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: dsem
Type: Package
Title: Fit Dynamic Structural Equation Models
Version: 1.0.0
Date: 2023-12-04
Version: 1.0.1
Date: 2024-01-17
Authors@R:
c(person(given = "James",
family = "Thorson",
Expand Down
674 changes: 0 additions & 674 deletions LICENSE

This file was deleted.

3 changes: 2 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ S3method(vcov,dsem)
export(TMBAIC)
export(as_fitted_DAG)
export(as_sem)
export(checkDepPackageVersion)
export(classify_variables)
export(dsem)
export(dsem_control)
export(fit_tmb)
export(list_parameters)
export(make_dsem_ram)
export(parse_path)
Expand All @@ -40,4 +40,5 @@ importFrom(stats,rnorm)
importFrom(stats,simulate)
importFrom(stats,time)
importFrom(stats,vcov)
importFrom(utils,packageVersion)
useDynLib(dsem, .registration = TRUE)
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Fix bug in `simulate.dsem` to keep up with changing interface in `dsem`
* Update CITATION to indicate accepted paper
* Remove fit_tmb to eliminate cryptic warning messages and simplify code

# dsem 1.0.0

Expand Down
83 changes: 67 additions & 16 deletions R/dsem.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#' the stationary distribution
#' @param control Output from \code{\link{dsem_control}}, used to define user
#' settings, and see documentation for that function for details.
#' @param ... Additional parameters passed to \code{\link{fit_tmb}}
#'
#' @importFrom TMB compile dynlib MakeADFun sdreport summary.sdreport
#' @importFrom stats .preformat.ts na.omit nlminb optimHess pnorm rnorm simulate time tsp<-
Expand Down Expand Up @@ -61,7 +60,8 @@
#' \item{ram}{RAM parsed by \code{make_dsem_ram}}
#' \item{model}{SEM structure parsed by \code{make_dsem_ram} as intermediate description of model linkages}
#' \item{tmb_inputs}{The list of inputs passed to \code{\link[TMB]{MakeADFun}}}
#' \item{opt}{The output from \code{\link{fit_tmb}}}
#' \item{opt}{The output from \code{\link[stats]{nlminb}}}
#' \item{sdrep}{The output from \code{\link[TMB]{sdreport}}}
#' }
#'
#' @references
Expand Down Expand Up @@ -98,7 +98,6 @@
#' # Fit model
#' fit = dsem( sem=sem,
#' tsdata = tsdata,
#' newtonsteps = 0,
#' estimate_delta0 = TRUE,
#' control = dsem_control(quiet=TRUE) )
#' summary( fit )
Expand All @@ -112,8 +111,7 @@ function( sem,
tsdata,
family = rep("fixed",ncol(tsdata)),
estimate_delta0 = FALSE,
control = dsem_control(),
... ){
control = dsem_control() ){

# General error checks
if( isFALSE(is(control, "dsem_control")) ) stop("`control` must be made by `dsem_control()`")
Expand Down Expand Up @@ -198,10 +196,40 @@ function( sem,

# Fit
obj$env$beSilent() # if(!is.null(Random))
out$opt = fit_tmb( obj,
quiet = control$quiet,
control = list(eval.max=10000, iter.max=10000, trace=ifelse(control$quiet==TRUE,0,1) ),
... )
#out$opt = fit_tmb( obj,
# quiet = control$quiet,
# control = list(eval.max=10000, iter.max=10000, trace=ifelse(control$quiet==TRUE,0,1) ),
# ... )

# Optimize
out$opt = list( "par"=obj$par )
for( i in seq_len(max(0,control$nlminb_loops)) ){
if( isFALSE(control$quiet) ) message("Running nlminb_loop #", i)
out$opt = nlminb( start = out$opt$par,
objective = obj$fn,
gradient = obj$gr,
control = list( eval.max = control$eval.max,
iter.max = control$iter.max,
trace = control$trace ) )
}

# Newtonsteps
for( i in seq_len(max(0,control$newton_loops)) ){
if( isFALSE(control$quiet) ) message("Running newton_loop #", i)
g = as.numeric( obj$gr(out$opt$par) )
h = optimHess(out$opt$par, fn=obj$fn, gr=obj$gr)
out$opt$par = out$opt$par - solve(h, g)
out$opt$objective = obj$fn(out$opt$par)
}

# Run sdreport
if( isTRUE(control$getsd) ){
if( isTRUE(control$verbose) ) message("Running sdreport")
Hess_fixed = optimHess( par=out$opt$par, fn=obj$fn, gr=obj$gr )
out$sdrep = sdreport( obj, hessian.fixed=Hess_fixed )
}else{
out$sdrep = NULL
}

# output
class(out) = "dsem"
Expand All @@ -214,6 +242,17 @@ function( sem,
#' the format of this input is likely to change more rapidly than that of
#' \code{\link{dsem}}
#'
#' @param nlminb_loops Integer number of times to call \code{\link[stats]{nlminb}}.
#' @param newton_loops Integer number of Newton steps to do after running
#' \code{\link[stats]{nlminb}}.
#' @param trace Parameter values are printed every `trace` iteration
#' for the outer optimizer. Passed to
#' `control` in \code{\link[stats]{nlminb}}.
#' @param eval.max Maximum number of evaluations of the objective function
#' allowed. Passed to `control` in \code{\link[stats]{nlminb}}.
#' @param iter.max Maximum number of iterations allowed. Passed to `control` in
#' \code{\link[stats]{nlminb}}.
#' @param getsd Boolean indicating whether to call \code{\link[TMB]{sdreport}}
#' @param run_model Boolean indicating whether to estimate parameters (the default), or
#' instead to return the model inputs and compiled TMB object without running;
#' @param quiet Boolean indicating whether to run model printing messages to terminal or not;
Expand All @@ -231,14 +270,26 @@ function( sem,
#'
#' @export
dsem_control <-
function( quiet = FALSE,
function( nlminb_loops = 1,
newton_loops = 1,
trace = 0,
eval.max = 1000,
iter.max = 1000,
getsd = TRUE,
quiet = FALSE,
run_model = TRUE,
use_REML = TRUE,
parameters = NULL,
map = NULL ){

# Return
structure( list(
nlminb_loops = nlminb_loops,
newton_loops = newton_loops,
trace = trace,
eval.max = eval.max,
iter.max = iter.max,
getsd = getsd,
quiet = quiet,
run_model = run_model,
use_REML = use_REML,
Expand Down Expand Up @@ -302,8 +353,8 @@ function( object, ... ){
#
coefs = data.frame( model, "Estimate"=c(NA,ParHat$beta_z)[ as.numeric(model[,'parameter'])+1 ] ) # parameter=0 outputs NA
coefs$Estimate = ifelse( is.na(coefs$Estimate), as.numeric(model[,4]), coefs$Estimate )
if( "SD" %in% names(object$opt) ){
SE = as.list( object$opt$SD, report=FALSE, what="Std. Error")
if( "sdrep" %in% names(object) ){
SE = as.list( object$sdrep, report=FALSE, what="Std. Error")
coefs = data.frame( coefs, "Std_Error"=c(NA,SE$beta_z)[ as.numeric(model[,'parameter'])+1 ] ) # parameter=0 outputs NA
coefs = data.frame( coefs, "z_value"=coefs[,'Estimate']/coefs[,'Std_Error'] )
coefs = data.frame( coefs, "p_value"=pnorm(-abs(coefs[,'z_value'])) * 2 )
Expand Down Expand Up @@ -424,10 +475,10 @@ function( object,
par_zr[obj$env$random,] = par_zr[obj$env$random,,drop=FALSE] + eps_zr
}
if( variance=="both" ){
if(is.null(object$opt$SD$jointPrecision)){
if(is.null(object$sdrep$jointPrecision)){
stop("Please re-run `dsem` with `getsd=TRUE` and `getJointPrecision=TRUE`, or confirm that the model is converged")
}
eps_zr = rmvnorm_prec( rep(0,length(obj$env$last.par)), object$opt$SD$jointPrecision, nsim=nsim )
eps_zr = rmvnorm_prec( rep(0,length(obj$env$last.par)), object$sdrep$jointPrecision, nsim=nsim )
par_zr = par_zr + eps_zr
}

Expand Down Expand Up @@ -485,7 +536,7 @@ function( object,
which = match.arg(which)

if( which=="fixed" ){
V = object$opt$SD$cov.fixed
V = object$sdrep$cov.fixed
if(is.null(V)){
warning("Please re-run `dsem` with `getsd=TRUE`, or confirm that the model is converged")
}
Expand All @@ -494,7 +545,7 @@ function( object,
V = solve(object$obj$env$spHess(random=TRUE))
}
if( which=="both" ){
H = object$opt$SD$jointPrecision
H = object$sdrep$jointPrecision
if(is.null(H)){
warning("Please re-run `dsem` with `getsd=TRUE` and `getJointPrecision=TRUE`, or confirm that the model is converged")
V = NULL
Expand Down
Loading
Loading