diff --git a/DESCRIPTION b/DESCRIPTION index 3ca2e75a5..c1120d4a6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: ergm -Version: 4.7-7448 -Date: 2024-10-14 +Version: 4.7-7451 +Date: 2024-11-01 Title: Fit, Simulate and Diagnose Exponential-Family Models for Networks Authors@R: c( person(c("Mark", "S."), "Handcock", role=c("aut"), email="handcock@stat.ucla.edu"), diff --git a/inst/include/ergm_model.h b/inst/include/ergm_model.h index f42dd98dc..c796dd84c 100644 --- a/inst/include/ergm_model.h +++ b/inst/include/ergm_model.h @@ -103,6 +103,8 @@ int GetIndexForAttrValue(int value); /* *** don't forget tail-> head, so this function accepts toggletail first, not togglehead */ +void ChangeStatsDo(unsigned int ntoggles, Vertex *tails, Vertex *heads, Network *nwp, Model *m); +void ChangeStatsUndo(unsigned int ntoggles, Vertex *tails, Vertex *heads, Network *nwp, Model *m); void ChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, Network *nwp, Model *m); void ChangeStats1(Vertex tail, Vertex head, Network *nwp, Model *m, Rboolean edgestate); void ZStats(Network *nwp, Model *m, Rboolean skip_s); diff --git a/inst/include/ergm_wtmodel.h b/inst/include/ergm_wtmodel.h index ba271edf3..bdaebaea1 100644 --- a/inst/include/ergm_wtmodel.h +++ b/inst/include/ergm_wtmodel.h @@ -98,6 +98,8 @@ void WtModelDestroy(WtNetwork *nwp, WtModel *m); total numbers of terms, parameters, and statistics along with a pointer to an array of WtModelTerm structures. */ +void WtChangeStatsDo(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, WtNetwork *nwp, WtModel *m); +void WtChangeStatsUndo(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, WtNetwork *nwp, WtModel *m); void WtChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, WtNetwork *nwp, WtModel *m); void WtChangeStats1(Vertex tail, Vertex head, double weight, WtNetwork *nwp, WtModel *m, double edgestate); void WtZStats(WtNetwork *nwp, WtModel *m, Rboolean skip_s); diff --git a/src/MCMC.c.template.do_not_include_directly.h b/src/MCMC.c.template.do_not_include_directly.h index c533f3a83..ab92606c5 100644 --- a/src/MCMC.c.template.do_not_include_directly.h +++ b/src/MCMC.c.template.do_not_include_directly.h @@ -229,7 +229,7 @@ MCMCStatus DISPATCH_MetropolisHastings (DISPATCH_ErgmState *s, /* Calculate change statistics, remembering that tail -> head */ - PROP_CHANGESTATS; + PROP_CHANGESTATS_DO; if(verbose>=5) print_vector("stat diff", m->workspace, m->n_stats); @@ -251,8 +251,8 @@ MCMCStatus DISPATCH_MetropolisHastings (DISPATCH_ErgmState *s, Rprintf("Accepted.\n"); } - /* Make proposed toggles (updating timestamps--i.e., for real this time) */ - for(unsigned int i=0; i < MHp->ntoggles; i++) PROP_COMMIT; + /* Make the last (or sole) toggle. */ + PROP_FINISH; /* record network statistics for posterity */ addonto(networkstatistics, m->workspace, m->n_stats); taken++; @@ -260,6 +260,8 @@ MCMCStatus DISPATCH_MetropolisHastings (DISPATCH_ErgmState *s, if(verbose>=5){ Rprintf("Rejected.\n"); } + + PROP_CHANGESTATS_UNDO; } } diff --git a/src/ergm_type_defs_common.h b/src/ergm_type_defs_common.h index a5ac8d05e..a71db3e5e 100644 --- a/src/ergm_type_defs_common.h +++ b/src/ergm_type_defs_common.h @@ -9,7 +9,10 @@ */ #define PROP_PRINT Rprintf(" (%d, %d) ", MHp->toggletail[i], MHp->togglehead[i]) #define PROP_CHANGESTATS ChangeStats(MHp->ntoggles, MHp->toggletail, MHp->togglehead, nwp, m) +#define PROP_CHANGESTATS_DO ChangeStatsDo(MHp->ntoggles, MHp->toggletail, MHp->togglehead, nwp, m) +#define PROP_CHANGESTATS_UNDO ChangeStatsUndo(MHp->ntoggles, MHp->toggletail, MHp->togglehead, nwp, m) #define PROP_COMMIT ToggleEdge(MHp->toggletail[i], MHp->togglehead[i], nwp) +#define PROP_FINISH ToggleEdge(MHp->toggletail[MHp->ntoggles-1], MHp->togglehead[MHp->ntoggles-1], nwp) #define DISPATCH_ErgmState ErgmState #define DISPATCH_ErgmStateInit ErgmStateInit #define DISPATCH_Model Model diff --git a/src/ergm_wttype_defs_common.h b/src/ergm_wttype_defs_common.h index 20aa028ab..364fbd6cd 100644 --- a/src/ergm_wttype_defs_common.h +++ b/src/ergm_wttype_defs_common.h @@ -9,7 +9,10 @@ */ #define PROP_PRINT Rprintf(" (%d, %d) -> %f ", MHp->toggletail[i], MHp->togglehead[i], MHp->toggleweight[i]) #define PROP_CHANGESTATS WtChangeStats(MHp->ntoggles, MHp->toggletail, MHp->togglehead, MHp->toggleweight, nwp, m) +#define PROP_CHANGESTATS_DO WtChangeStatsDo(MHp->ntoggles, MHp->toggletail, MHp->togglehead, MHp->toggleweight, nwp, m) +#define PROP_CHANGESTATS_UNDO WtChangeStatsUndo(MHp->ntoggles, MHp->toggletail, MHp->togglehead, MHp->toggleweight, nwp, m) #define PROP_COMMIT WtSetEdge(MHp->toggletail[i], MHp->togglehead[i], MHp->toggleweight[i], nwp) +#define PROP_FINISH WtSetEdge(MHp->toggletail[MHp->ntoggles-1], MHp->togglehead[MHp->ntoggles-1], MHp->toggleweight[MHp->ntoggles-1], nwp) #define DISPATCH_ErgmState WtErgmState #define DISPATCH_ErgmStateInit WtErgmStateInit #define DISPATCH_Model WtModel diff --git a/src/model.c b/src/model.c index 3d8501152..084dc6fab 100644 --- a/src/model.c +++ b/src/model.c @@ -313,13 +313,8 @@ Model* ModelInitialize(SEXP mR, SEXP ext_state, Network *nwp, Rboolean noinit_s) return m; } -/* - ChangeStats - A helper's helper function to compute change statistics. - The vector of changes is written to m->workspace. -*/ -void ChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, - Network *nwp, Model *m){ +void ChangeStatsDo(unsigned int ntoggles, Vertex *tails, Vertex *heads, + Network *nwp, Model *m){ memset(m->workspace, 0, m->n_stats*sizeof(double)); /* Zero all change stats. */ /* Make a pass through terms with d_functions. */ @@ -364,15 +359,30 @@ void ChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, TOGGLE_KNOWN(tails[toggle],heads[toggle], edgestate); } } - /* Undo previous storage updates and toggles */ +} + +void ChangeStatsUndo(unsigned int ntoggles, Vertex *tails, Vertex *heads, + Network *nwp, Model *m){ + int toggle = ntoggles; UNDO_PREVIOUS(toggle){ TOGGLE(tails[toggle],heads[toggle]); } } +/* + ChangeStats + A helper's helper function to compute change statistics. + The vector of changes is written to m->workspace. +*/ +void ChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, + Network *nwp, Model *m){ + ChangeStatsDo(ntoggles, tails, heads, nwp, m); + ChangeStatsUndo(ntoggles, tails, heads, nwp, m); +} + /* ChangeStats1 - A simplified version of WtChangeStats for exactly one change. + A simplified version of ChangeStats for exactly one change. */ void ChangeStats1(Vertex tail, Vertex head, Network *nwp, Model *m, Rboolean edgestate){ diff --git a/src/wtmodel.c b/src/wtmodel.c index c29300879..47c6ddb74 100644 --- a/src/wtmodel.c +++ b/src/wtmodel.c @@ -315,13 +315,8 @@ WtModel* WtModelInitialize (SEXP mR, SEXP ext_state, WtNetwork *nwp, Rboolean no return m; } -/* - WtChangeStats - A helper's helper function to compute change statistics. - The vector of changes is written to m->workspace. -*/ -void WtChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, - WtNetwork *nwp, WtModel *m){ +void WtChangeStatsDo(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, + WtNetwork *nwp, WtModel *m){ memset(m->workspace, 0, m->n_stats*sizeof(double)); /* Zero all change stats. */ /* Make a pass through terms with d_functions. */ @@ -365,7 +360,11 @@ void WtChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, double * SETWT_WITH_BACKUP(); } } - /* Undo previous storage updates and toggles */ +} + + +void WtChangeStatsUndo(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, + WtNetwork *nwp, WtModel *m){ UNDO_PREVIOUS{ GETOLDTOGGLEINFO(); SETWT(TAIL,HEAD,weights[TOGGLEIND]); @@ -373,6 +372,18 @@ void WtChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, double * } } + +/* + WtChangeStats + A helper's helper function to compute change statistics. + The vector of changes is written to m->workspace. +*/ +void WtChangeStats(unsigned int ntoggles, Vertex *tails, Vertex *heads, double *weights, + WtNetwork *nwp, WtModel *m){ + WtChangeStatsDo(ntoggles, tails, heads, weights, nwp, m); + WtChangeStatsUndo(ntoggles, tails, heads, weights, nwp, m); +} + /* WtChangeStats1 A simplified version of WtChangeStats for exactly one change.