Skip to content

Commit

Permalink
Improved the precision of GW decay calculations in dgw*sp() and in R …
Browse files Browse the repository at this point in the history
…by doing more of them on log scale.
  • Loading branch information
krivit committed Nov 24, 2024
1 parent baa6f5b commit 0359bde
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 18 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: ergm
Version: 4.7.5-7458
Date: 2024-11-04
Version: 4.7.5-7485
Date: 2024-11-24
Title: Fit, Simulate and Diagnose Exponential-Family Models for Networks
Authors@R: c(
person(c("Mark", "S."), "Handcock", role=c("aut"), email="[email protected]"),
Expand Down
8 changes: 4 additions & 4 deletions R/InitErgmTerm.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@
ergm_GWDECAY <- list(
map = function(x,n,...) {
i <- 1:n
x[1] * ifelse(i==1, 1, (exp(x[2])*(1-(1-exp(-x[2]))^i)))
x[1] * exp(x[2] + log1mexp(-log1mexp(x[2])*i))
},
gradient = function(x,n,...) {
i <- 1:n
e2 <- exp(x[2])
a <- 1-exp(-x[2])
rbind((1-a^i)*e2, ifelse(i==1, 0, x[1] * ( (1-a^i)*e2 - i*a^(i-1) ) ) )
a <- log1mexp(x[2])
w <- exp(x[2] + log1mexp(-a*i))
rbind(w, x[1] * (w - i*exp(a*(i-1))))
},
minpar = c(-Inf, 0)
)
Expand Down
3 changes: 3 additions & 0 deletions R/ergm.utility.R
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,6 @@ is.const.sample <- function(x){
if(is.mcmc.list(x)) x <- as.matrix(x)
isTRUE(all.equal(apply(x,2,stats::sd), rep(0,ncol(x)), check.names=FALSE))
}

## Implementation of the C macro in R.
log1mexp <- function(x) ifelse(-x > -log(2), log(-expm1(-x)), log1p(-exp(-x)))
22 changes: 10 additions & 12 deletions src/changestats_dgw_sp.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,29 +88,27 @@
}


#define gwsp_args tail,head,mtp,nwp,edgestate,spcache,alpha,oneexpa
#define gwsp_args tail,head,mtp,nwp,edgestate,spcache,alpha,loneexpa

#define gw_calc(term) \
static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, double alpha, double oneexpa) { \
static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, double alpha, double loneexpa) { \
double cumchange = 0; \
term ## _change({ \
cumchange += pow(oneexpa, L2-edgestate); \
cumchange += exp(loneexpa*(L2-edgestate)); \
},{ \
if(alpha < 100.0) cumchange += exp(alpha)*(1-pow(oneexpa, L2)); \
else cumchange += L2; \
cumchange += exp(alpha + log1mexp(-loneexpa*L2)); \
}); \
return cumchange; \
}


#define gw_calc2(term) \
static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, double alpha, double oneexpa) { \
static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, double alpha, double loneexpa) { \
double cumchange = 0; \
term ## _change({ \
cumchange += pow(oneexpa, L2-edgestate)*2; \
cumchange += exp(loneexpa*(L2-edgestate))*2; \
},{ \
if(alpha < 100.0) cumchange += exp(alpha)*(1-pow(oneexpa, L2)); \
else cumchange += L2; \
cumchange += exp(alpha + log1mexp(-loneexpa*L2)); \
}); \
return cumchange; \
}
Expand Down Expand Up @@ -198,7 +196,7 @@ C_CHANGESTAT_FN(c_dgwdsp) {
/*Set things up*/
StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
double loneexpa = log1mexp(alpha); /*Precompute log(1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
double cumchange = 0;

Expand Down Expand Up @@ -299,7 +297,7 @@ C_CHANGESTAT_FN(c_dgwesp) {
/*Set things up*/
StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
double loneexpa = log1mexp(alpha); /*Precompute (1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
double cumchange = 0;

Expand Down Expand Up @@ -441,7 +439,7 @@ C_CHANGESTAT_FN(c_dgwnsp) {
/*Set things up*/
StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
double loneexpa = log1mexp(alpha); /*Precompute (1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
double cumchange = 0;

Expand Down

0 comments on commit 0359bde

Please sign in to comment.