From 50da503a36cde2cafc0c481f10a0ed12e1367a2b Mon Sep 17 00:00:00 2001
From: "Pavel N. Krivitsky"
Date: Tue, 12 Mar 2024 13:57:19 +1100
Subject: [PATCH 1/5] Added a Strict* family of dyad set and hashmap, which
expect the caller to handle the directedness: whether tail < head.
---
inst/include/ergm_dyad_hashmap.h | 123 ++++++++++++++++++++-----------
1 file changed, 80 insertions(+), 43 deletions(-)
diff --git a/inst/include/ergm_dyad_hashmap.h b/inst/include/ergm_dyad_hashmap.h
index b559ff2fe..31f407343 100644
--- a/inst/include/ergm_dyad_hashmap.h
+++ b/inst/include/ergm_dyad_hashmap.h
@@ -27,6 +27,7 @@ typedef struct TailHead_s{
/* Helper macros to construct TailHeads with the correct ordering. */
#define TH(T,H) ((TailHead){.tail=(T),.head=(H)})
+#define UTH(tail, head) tail < head ? TH(tail, head) : TH(head, tail)
/* Hash and comparison functions designed for tail-head pairs. */
// The of macro-ing this due to Bob Jenkins.
@@ -45,62 +46,98 @@ static inline unsigned int kh_scramble_int(unsigned int a){
#define kh_vertexvertex_hash_func(key) (khint32_t) (((key).tail<(key).head || h->directed) ? ((key).tail + (key).head*0xd7d4eb2du) : ((key).head + (key).tail*0xd7d4eb2du))
#define kh_vertexvertex_hash_equal(a,b) ((a.tail==b.tail && a.head==b.head) || (!h->directed && a.tail==b.head && a.head==b.tail))
+#define kh_vertexvertex_strict_hash_func(key) (khint32_t) ((key).tail + (key).head*0xd7d4eb2du)
+#define kh_vertexvertex_strict_hash_equal(a,b) (a.tail==b.tail && a.head==b.head)
+
+/* Accessors, modifiers, and incrementors. */
+#define AccessorTemplate(fname, type, valtype, th_impl) \
+ static inline valtype GET ## fname (Vertex tail, Vertex head, Store ## type *hashmap){ \
+ return kh_getval(type, hashmap, th_impl, 0); \
+ } \
+ static inline void SET ## fname (Vertex tail, Vertex head, valtype v, Store ## type *hashmap){ \
+ if(v == (valtype)0){ \
+ kh_unset(type, hashmap, th_impl); \
+ }else{ \
+ kh_set(type, hashmap, th_impl, v); \
+ } \
+ } \
+ static inline valtype HAS ## fname (Vertex tail, Vertex head, Store ## type *hashmap){ \
+ return kh_get(type, hashmap, th_impl) != kh_none; \
+ } \
+ static inline void DEL ## fname (Vertex tail, Vertex head, Store ## type *hashmap){ \
+ kh_unset(type, hashmap, th_impl); \
+ } \
+ static inline void SET ## fname ## 0 (Vertex tail, Vertex head, valtype v, Store ## type *hashmap){ \
+ kh_set(type, hashmap, th_impl, v); \
+ }
+
+#define IncDyadMapTemplate(fname, type, valtype, th_impl) \
+ static inline void fname(Vertex tail, Vertex head, int inc, Store ## type *h){ \
+ TailHead th = th_impl; \
+ if(inc!=0){ \
+ khiter_t pos = kh_get(type, h, th); \
+ valtype val = pos==kh_none ? 0 : kh_value(h, pos); \
+ val += inc; \
+ if(val==0){ \
+ kh_del(type, h, pos); \
+ }else{ \
+ if(pos==kh_none) \
+ pos = kh_put(type, h, th, NULL); \
+ kh_val(h, pos) = val; \
+ } \
+ } \
+ }
+
+
/* Predefined khash type for mapping dyads onto unsigned ints. */
KHASH_INIT(DyadMapUInt, TailHead, unsigned int, TRUE, kh_vertexvertex_hash_func, kh_vertexvertex_hash_equal, Rboolean directed;)
typedef khash_t(DyadMapUInt) StoreDyadMapUInt;
+AccessorTemplate(DMUI, DyadMapUInt, unsigned int, TH(tail,head))
+IncDyadMapTemplate(IncDyadMapUInt, DyadMapUInt, unsigned int, TH(tail, head))
-/* Accessors, modifiers, and incrementors. */
-#define GETDMUI(tail, head, hashmap)(kh_getval(DyadMapUInt, hashmap, TH(tail,head), 0))
-#define SETDMUI(tail, head, v, hashmap) {if(v==0) kh_unset(DyadMapUInt, hashmap, TH(tail,head)); else kh_set(DyadMapUInt, hashmap, TH(tail,head), v)}
-#define HASDMUI(tail, head, hashmap)(kh_get(DyadMapUInt, hashmap, TH(tail,head))!=kh_none)
-#define DELDMUI(tail, head, hashmap)(kh_unset(DyadMapUInt, hashmap, TH(tail,head)))
-#define SETDMUI0(tail, head, v, hashmap) {kh_set(DyadMapUInt, hashmap, TH(tail,head), v)}
-
-static inline void IncDyadMapUInt(Vertex tail, Vertex head, int inc, StoreDyadMapUInt *h){
- TailHead th = TH(tail, head);
- if(inc!=0){
- khiter_t pos = kh_get(DyadMapUInt, h, th);
- unsigned int val = pos==kh_none ? 0 : kh_value(h, pos);
- val += inc;
- if(val==0){
- kh_del(DyadMapUInt, h, pos);
- }else{
- if(pos==kh_none)
- pos = kh_put(DyadMapUInt, h, th, NULL);
- kh_val(h, pos) = val;
- }
- }
-}
+KHASH_INIT(StrictDyadMapUInt, TailHead, unsigned int, TRUE, kh_vertexvertex_strict_hash_func, kh_vertexvertex_strict_hash_equal,)
+typedef khash_t(StrictDyadMapUInt) StoreStrictDyadMapUInt;
+AccessorTemplate(DDMUI, StrictDyadMapUInt, unsigned int, TH(tail,head))
+AccessorTemplate(UDMUI, StrictDyadMapUInt, unsigned int, UTH(tail, head))
+IncDyadMapTemplate(IncDDyadMapUInt, StrictDyadMapUInt, unsigned int, TH(tail, head))
+IncDyadMapTemplate(IncUDyadMapUInt, StrictDyadMapUInt, unsigned int, UTH(tail, head))
/* Predefined khash type for mapping dyads onto signed ints. */
KHASH_INIT(DyadMapInt, TailHead, int, TRUE, kh_vertexvertex_hash_func, kh_vertexvertex_hash_equal, Rboolean directed;)
typedef khash_t(DyadMapInt) StoreDyadMapInt;
+AccessorTemplate(DMI, DyadMapInt, int, TH(tail,head))
+IncDyadMapTemplate(IncDyadMapInt, DyadMapInt, int, TH(tail, head))
-/* Accessors, modifiers, and incrementors. */
-#define GETDMI(tail, head, hashmap)(kh_getval(DyadMapInt, hashmap, TH(tail,head), 0))
-#define SETDMI(tail, head, v, hashmap) {if(v==0) kh_unset(DyadMapInt, hashmap, TH(tail,head)); else kh_set(DyadMapInt, hashmap, TH(tail,head), v)}
-#define HASDMI(tail, head, hashmap)(kh_get(DyadMapInt, hashmap, TH(tail,head))!=kh_none)
-#define DELDMI(tail, head, hashmap)(kh_unset(DyadMapInt, hashmap, TH(tail,head)))
-#define SETDMI0(tail, head, v, hashmap) {kh_set(DyadMapInt, hashmap, TH(tail,head), v)}
+KHASH_INIT(StrictDyadMapInt, TailHead, int, TRUE, kh_vertexvertex_strict_hash_func, kh_vertexvertex_strict_hash_equal,)
+typedef khash_t(StrictDyadMapInt) StoreStrictDyadMapInt;
+AccessorTemplate(DDMI, StrictDyadMapInt, int, TH(tail,head))
+AccessorTemplate(UDMI, StrictDyadMapInt, int, UTH(tail, head))
+IncDyadMapTemplate(IncDDyadMapInt, StrictDyadMapInt, int, TH(tail, head))
+IncDyadMapTemplate(IncUDyadMapInt, StrictDyadMapInt, int, UTH(tail, head))
/* Predefined khash type for dyad sets. This may or may not be faster than edgetree. */
-KHASH_INIT(DyadSet, TailHead, char, FALSE, kh_vertexvertex_hash_func, kh_vertexvertex_hash_equal, Rboolean directed;)
-typedef khash_t(DyadSet) StoreDyadSet;
// Toggle an element of a DyadSet.
-static inline Rboolean DyadSetToggle(Vertex tail, Vertex head, StoreDyadSet *h){
- TailHead th = TH(tail, head);
- kh_put_code ret;
- // Attempt insertion
- khiter_t i = kh_put(DyadSet, h, th, &ret);
- if(ret==0){
- // Already present: delete
- kh_del(DyadSet, h, i);
- return FALSE;
- }else{
- // Inserted by kh_put above
- return TRUE;
+#define DyadSetToggleTemplate(fname, type, th_impl) \
+ static inline Rboolean fname(Vertex tail, Vertex head, Store ## type *h){ \
+ TailHead th = th_impl; \
+ kh_put_code ret; \
+ khiter_t i = kh_put(type, h, th, &ret); \
+ if(ret==0){ \
+ kh_del(type, h, i); \
+ return FALSE; \
+ }else{ \
+ return TRUE; \
+ } \
}
-}
+
+KHASH_INIT(DyadSet, TailHead, char, FALSE, kh_vertexvertex_hash_func, kh_vertexvertex_hash_equal, Rboolean directed;)
+typedef khash_t(DyadSet) StoreDyadSet;
+DyadSetToggleTemplate(DyadSetToggle, DyadSet, TH(tail, head))
+
+KHASH_INIT(StrictDyadSet, TailHead, char, FALSE, kh_vertexvertex_strict_hash_func, kh_vertexvertex_strict_hash_equal,)
+typedef khash_t(StrictDyadSet) StoreStrictDyadSet;
+DyadSetToggleTemplate(DDyadSetToggle, StrictDyadSet, TH(tail, head))
+DyadSetToggleTemplate(UDyadSetToggle, StrictDyadSet, UTH(tail, head))
#endif // _ERGM_DYAD_HASHMAP_H_
From e8d03bd72cc6dd4a4b3b910802637f5f2cc78d3f Mon Sep 17 00:00:00 2001
From: "Pavel N. Krivitsky"
Date: Tue, 12 Mar 2024 14:02:51 +1100
Subject: [PATCH 2/5] HashEL type now uses StrictDyadMapUInt rather than
DyadMapUInt.
---
inst/include/ergm_hash_edgelist.h | 29 ++++++++++++++---------------
src/MHproposals.c | 2 +-
src/ergm_dyadgen.c | 23 +----------------------
3 files changed, 16 insertions(+), 38 deletions(-)
diff --git a/inst/include/ergm_hash_edgelist.h b/inst/include/ergm_hash_edgelist.h
index 8f64fcda0..728793e82 100644
--- a/inst/include/ergm_hash_edgelist.h
+++ b/inst/include/ergm_hash_edgelist.h
@@ -22,43 +22,42 @@
typedef struct {
UnsrtEL *list;
- StoreDyadMapUInt *hash;
+ StoreStrictDyadMapUInt *hash;
} HashEL;
/* Embed an existing UnsrtEL into a HashEL. */
-static inline HashEL *UnsrtELIntoHashEL(UnsrtEL *el, Rboolean directed) {
+static inline HashEL *UnsrtELIntoHashEL(UnsrtEL *el) {
HashEL *hash = Calloc(1, HashEL);
hash->list = el;
- hash->hash = kh_init(DyadMapUInt);
- hash->hash->directed = directed;
+ hash->hash = kh_init(StrictDyadMapUInt);
if(el->nedges > 0) {
- kh_resize(DyadMapUInt, hash->hash, 2*(el->nedges + 1));
+ kh_resize(StrictDyadMapUInt, hash->hash, 2*(el->nedges + 1));
for(unsigned int i = 1; i <= el->nedges; i++) {
- kh_set(DyadMapUInt, hash->hash, TH(el->tails[i], el->heads[i]), i);
+ kh_set(StrictDyadMapUInt, hash->hash, TH(el->tails[i], el->heads[i]), i);
}
}
return hash;
}
-static inline HashEL *HashELInitialize(unsigned int nedges, Vertex *tails, Vertex *heads, Rboolean copy, Rboolean directed) {
+static inline HashEL *HashELInitialize(unsigned int nedges, Vertex *tails, Vertex *heads, Rboolean copy) {
UnsrtEL *el = UnsrtELInitialize(nedges, tails, heads, copy);
- return UnsrtELIntoHashEL(el, directed);
+ return UnsrtELIntoHashEL(el);
}
static inline void HashELDestroy(HashEL *hash) {
- kh_destroy(DyadMapUInt, hash->hash);
+ kh_destroy(StrictDyadMapUInt, hash->hash);
UnsrtELDestroy(hash->list);
Free(hash);
}
static inline void HashELClear(HashEL *hash) {
UnsrtELClear(hash->list);
- kh_clear(DyadMapUInt, hash->hash);
+ kh_clear(StrictDyadMapUInt, hash->hash);
}
static inline void HashELGetRand(Vertex *tail, Vertex *head, HashEL *hash) {
@@ -67,7 +66,7 @@ static inline void HashELGetRand(Vertex *tail, Vertex *head, HashEL *hash) {
static inline void HashELInsert(Vertex tail, Vertex head, HashEL *hash) {
kh_put_code r;
- khiter_t pos = kh_put(DyadMapUInt, hash->hash, TH(tail, head), &r);
+ khiter_t pos = kh_put(StrictDyadMapUInt, hash->hash, TH(tail, head), &r);
if(r == kh_put_present) return; // Already in the list.
UnsrtELInsert(tail, head, hash->list);
@@ -75,12 +74,12 @@ static inline void HashELInsert(Vertex tail, Vertex head, HashEL *hash) {
}
static inline void HashELDelete(Vertex tail, Vertex head, HashEL *hash) {
- khint_t i = kh_get(DyadMapUInt, hash->hash, TH(tail, head));
+ khint_t i = kh_get(StrictDyadMapUInt, hash->hash, TH(tail, head));
unsigned int index = kh_value(hash->hash, i);
- kh_del(DyadMapUInt, hash->hash, i);
+ kh_del(StrictDyadMapUInt, hash->hash, i);
if(index < hash->list->nedges) {
- kh_set(DyadMapUInt,
+ kh_set(StrictDyadMapUInt,
hash->hash,
TH(hash->list->tails[hash->list->nedges],
hash->list->heads[hash->list->nedges]),
@@ -99,7 +98,7 @@ static inline void HashELToggleKnown(Vertex tail, Vertex head, HashEL *hash, int
}
static inline unsigned int HashELSearch(Vertex tail, Vertex head, HashEL *hash) {
- return kh_getval(DyadMapUInt, hash->hash, TH(tail, head), 0);
+ return kh_getval(StrictDyadMapUInt, hash->hash, TH(tail, head), 0);
}
#endif // _ERGM_HASH_EDGELIST_H_
diff --git a/src/MHproposals.c b/src/MHproposals.c
index f81deb711..f99dbcb6b 100644
--- a/src/MHproposals.c
+++ b/src/MHproposals.c
@@ -217,7 +217,7 @@ MH_I_FN(Mi_BDStratTNT) {
sto->hash[i] = HashELInitialize(els[i]->nedges,
els[i]->tails ? els[i]->tails + 1 : els[i]->tails,
els[i]->heads ? els[i]->heads + 1 : els[i]->heads,
- FALSE, DIRECTED);
+ FALSE);
Free(els[i]);
}
Free(els);
diff --git a/src/ergm_dyadgen.c b/src/ergm_dyadgen.c
index 1f49732bf..f3677e40a 100644
--- a/src/ergm_dyadgen.c
+++ b/src/ergm_dyadgen.c
@@ -68,28 +68,7 @@ void DyadGenSetUpIntersect(DyadGen *gen, void *track_nwp, Rboolean force){
void DyadGenUpgradeIntersect(DyadGen *gen){
if(gen->intertype == UnsrtELDyadGen){
- Rboolean directed;
- switch(gen->type){
- case RandDyadGen:
- case EdgeListGen:
- case RLEBDM1DGen:
- {
- Network *nwp = gen->nwp.b;
- directed = DIRECTED;
- }
- break;
- case WtRandDyadGen:
- case WtEdgeListGen:
- case WtRLEBDM1DGen:
- {
- WtNetwork *nwp = gen->nwp.w;
- directed = DIRECTED;
- }
- break;
- default:
- error("Undefined dyad generator type.");
- }
- gen->inter.hel = UnsrtELIntoHashEL(gen->inter.uel, directed);
+ gen->inter.hel = UnsrtELIntoHashEL(gen->inter.uel);
gen->intertype = HashELDyadGen;
}
}
From 60c72dd1c5c8abf7693e9c8762e457bce4aea65e Mon Sep 17 00:00:00 2001
From: "Pavel N. Krivitsky"
Date: Fri, 12 Apr 2024 17:29:01 +1000
Subject: [PATCH 3/5] Added print functions for the strict dyad hashmaps.
---
inst/include/ergm_dyad_hashmap_utils.h | 3 +++
src/ergm_dyad_hashmap_utils.c | 32 ++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/inst/include/ergm_dyad_hashmap_utils.h b/inst/include/ergm_dyad_hashmap_utils.h
index aa4440252..ec7742281 100644
--- a/inst/include/ergm_dyad_hashmap_utils.h
+++ b/inst/include/ergm_dyad_hashmap_utils.h
@@ -15,7 +15,10 @@
/* Utility function declarations. */
void PrintDyadMapUInt(StoreDyadMapUInt *h);
+void PrintStrictDyadMapUInt(StoreStrictDyadMapUInt *h);
void PrintDyadSet(StoreDyadSet *h);
+void PrintStrictDyadSet(StoreStrictDyadSet *h);
StoreDyadSet *NetworkToDyadSet(Network *nwp);
+StoreStrictDyadSet *NetworkToStrictDyadSet(Network *nwp);
#endif // _ERGM_DYAD_HASHMAP_H_
diff --git a/src/ergm_dyad_hashmap_utils.c b/src/ergm_dyad_hashmap_utils.c
index aaadd9c8d..5394757cf 100644
--- a/src/ergm_dyad_hashmap_utils.c
+++ b/src/ergm_dyad_hashmap_utils.c
@@ -23,6 +23,18 @@ void PrintDyadMapUInt(StoreDyadMapUInt *h){
}
}
+/* Print the contents of a khash table mapping dyads to unsigned
+ integers. Useful for debugging. */
+void PrintStrictDyadMapUInt(StoreStrictDyadMapUInt *h){
+ for(khiter_t i = kh_begin(h); i!=kh_end(h); ++i){
+ if(kh_exist(h, i)){
+ TailHead k = kh_key(h, i);
+ unsigned int v = kh_val(h, i);
+ Rprintf("(%d,%d)->%u\n",k.tail,k.head,v);
+ }
+ }
+}
+
/* Print the contents of a khash set of dyads. Useful for debugging. */
void PrintDyadSet(StoreDyadSet *h){
for(khiter_t i = kh_begin(h); i!=kh_end(h); ++i){
@@ -34,6 +46,17 @@ void PrintDyadSet(StoreDyadSet *h){
Rprintf("\n");
}
+/* Print the contents of a khash set of dyads. Useful for debugging. */
+void PrintStrictDyadSet(StoreStrictDyadSet *h){
+ for(khiter_t i = kh_begin(h); i!=kh_end(h); ++i){
+ if(kh_exist(h, i)){
+ TailHead k = kh_key(h, i);
+ Rprintf("(%d,%d) ",k.tail,k.head);
+ }
+ }
+ Rprintf("\n");
+}
+
/* Copy network to a khash set of dyads. */
StoreDyadSet *NetworkToDyadSet(Network *nwp){
StoreDyadSet *h = kh_init(DyadSet);
@@ -44,3 +67,12 @@ StoreDyadSet *NetworkToDyadSet(Network *nwp){
});
return h;
}
+
+StoreStrictDyadSet *NetworkToStrictDyadSet(Network *nwp){
+ StoreStrictDyadSet *h = kh_init(StrictDyadSet);
+
+ EXEC_THROUGH_NET_EDGES(tail, head, e, {
+ kh_put(StrictDyadSet, h, TH(tail,head), NULL);
+ });
+ return h;
+}
From d65020fbe9d67589a48b5fcf9f9b8913356648f8 Mon Sep 17 00:00:00 2001
From: "Pavel N. Krivitsky"
Date: Thu, 16 May 2024 00:34:00 +1000
Subject: [PATCH 4/5] Shared partner cache code now uses StrictDyadMap.
---
src/changestats_dgw_sp.c | 30 ++++++++---------
src/changestats_dgw_sp.h | 60 +++++++++++++++++-----------------
src/changestats_spcache.c | 68 +++++++++++++++++++--------------------
3 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/src/changestats_dgw_sp.c b/src/changestats_dgw_sp.c
index 39f520848..7af8ac65a 100644
--- a/src/changestats_dgw_sp.c
+++ b/src/changestats_dgw_sp.c
@@ -25,7 +25,7 @@
#define sp_args tail,head,mtp,nwp,edgestate,spcache,N_CHANGE_STATS,dvec,CHANGE_STAT
#define dvec_calc(term) \
- static inline void term ## _calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *spcache, int nd, Vertex *dvec, double *cs) { \
+ static inline void term ## _calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, int nd, Vertex *dvec, double *cs) { \
int echange = edgestate ? -1 : 1; \
term ## _change(L, { \
for(unsigned int j = 0; j < nd; j++){ \
@@ -41,7 +41,7 @@
}
#define dvec_calc2(term) \
- static inline void term ## _calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *spcache, int nd, Vertex *dvec, double *cs) { \
+ static inline void term ## _calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, int nd, Vertex *dvec, double *cs) { \
int echange = edgestate ? -1 : 1; \
term ## _change(L, { \
for(unsigned int j = 0; j < nd; j++){ \
@@ -60,7 +60,7 @@
#define spd_args tail,head,mtp,nwp,edgestate,spcache,N_CHANGE_STATS,CHANGE_STAT
#define dist_calc(term) \
- static inline void term ## _dist_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *spcache, int nd, double *cs) { \
+ static inline void term ## _dist_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, int nd, double *cs) { \
int echange = edgestate ? -1 : 1; \
term ## _change(L, { \
int nL = L + echange; \
@@ -74,7 +74,7 @@
}
#define dist_calc2(term) \
- static inline void term ## _dist_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *spcache, int nd, double *cs) { \
+ static inline void term ## _dist_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreStrictDyadMapUInt *spcache, int nd, double *cs) { \
int echange = edgestate ? -1 : 1; \
term ## _change(L, { \
int nL = L + echange; \
@@ -91,7 +91,7 @@
#define gwsp_args tail,head,mtp,nwp,edgestate,spcache,alpha,oneexpa
#define gw_calc(term) \
- static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *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 oneexpa) { \
double cumchange = 0; \
term ## _change(L, { \
cumchange += pow(oneexpa, L-edgestate); \
@@ -104,7 +104,7 @@
#define gw_calc2(term) \
- static inline double term ## _gw_calc(Vertex tail, Vertex head, ModelTerm *mtp, Network *nwp, Rboolean edgestate, StoreDyadMapUInt *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 oneexpa) { \
double cumchange = 0; \
term ## _change(L, { \
cumchange += pow(oneexpa, L-edgestate)*2; \
@@ -144,7 +144,7 @@ all_calcs2(dspRTP)
*/
C_CHANGESTAT_FN(c_ddsp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
Vertex *dvec = (Vertex*) IINPUT_PARAM+1; /*Get the pointer to the ESP stats list*/
@@ -163,7 +163,7 @@ C_CHANGESTAT_FN(c_ddsp) {
C_CHANGESTAT_FN(c_ddspdist) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
/*Obtain the ESP changescores (by type)*/
@@ -196,7 +196,7 @@ C_CHANGESTAT_FN(c_ddspdist) {
*/
C_CHANGESTAT_FN(c_dgwdsp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
@@ -245,7 +245,7 @@ all_calcs(espRTP)
*/
C_CHANGESTAT_FN(c_desp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
Vertex *dvec = (Vertex*) IINPUT_PARAM+1; /*Get the pointer to the ESP stats list*/
@@ -264,7 +264,7 @@ C_CHANGESTAT_FN(c_desp) {
C_CHANGESTAT_FN(c_despdist) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
/*Obtain the ESP changescores (by type)*/
@@ -297,7 +297,7 @@ C_CHANGESTAT_FN(c_despdist) {
*/
C_CHANGESTAT_FN(c_dgwesp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
@@ -339,7 +339,7 @@ C_CHANGESTAT_FN(c_dgwesp) {
#define NEGATE_CHANGE_STATS for(unsigned int i = 0; i < N_CHANGE_STATS; i++) CHANGE_STAT[i] *= -1;
C_CHANGESTAT_FN(c_dnsp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
Vertex *dvec = (Vertex*) IINPUT_PARAM+1; /*Get the pointer to the ESP stats list*/
@@ -382,7 +382,7 @@ C_CHANGESTAT_FN(c_dnsp) {
C_CHANGESTAT_FN(c_dnspdist) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
/*Obtain the ESP changescores (by type)*/
@@ -439,7 +439,7 @@ C_CHANGESTAT_FN(c_dnspdist) {
*/
C_CHANGESTAT_FN(c_dgwnsp) {
/*Set things up*/
- StoreDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
+ StoreStrictDyadMapUInt *spcache = N_AUX ? AUX_STORAGE : NULL;
double alpha = INPUT_PARAM[0]; /*Get alpha*/
double oneexpa = 1.0-exp(-alpha); /*Precompute (1-exp(-alpha))*/
int type = IINPUT_PARAM[0]; /*Get the ESP type code to be used*/
diff --git a/src/changestats_dgw_sp.h b/src/changestats_dgw_sp.h
index ebb087d2c..c40ef7bd4 100644
--- a/src/changestats_dgw_sp.h
+++ b/src/changestats_dgw_sp.h
@@ -52,7 +52,7 @@
EXEC_THROUGH_EDGES(head,e,u, { \
if (u!=tail){ \
int L2tu; \
- if(spcache) L2tu = GETDMUI(tail,u,spcache); \
+ if(spcache) L2tu = GETUDMUI(tail,u,spcache); \
else{ \
L2tu=0; \
/* step through edges of u */ \
@@ -66,7 +66,7 @@
EXEC_THROUGH_EDGES(tail,e,u, { \
if (u!=head){ \
int L2uh; \
- if(spcache) L2uh = GETDMUI(u,head,spcache); \
+ if(spcache) L2uh = GETUDMUI(u,head,spcache); \
else{ \
L2uh=0; \
/* step through edges of u */ \
@@ -90,7 +90,7 @@
EXEC_THROUGH_OUTEDGES(head, e, k, { \
if(k!=tail){ /*Only use contingent cases*/ \
int L2tk; \
- if(spcache) L2tk = GETDMUI(tail,k,spcache); \
+ if(spcache) L2tk = GETDDMUI(tail,k,spcache); \
else{ \
L2tk=0; \
/* step through inedges of k, incl. (head,k) itself */ \
@@ -105,7 +105,7 @@
EXEC_THROUGH_INEDGES(tail, e, k, { \
if (k!=head){ /*Only use contingent cases*/ \
int L2kh; \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETDDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/* step through outedges of k , incl. (k,tail) itself */ \
@@ -135,7 +135,7 @@
if((k!=tail)){ /*Only use contingent cases*/ \
int L2kt; \
/*We have a h->k->t two-path, so add it to our count.*/ \
- if(spcache) L2kt = GETDMUI(tail,k,spcache); /* spcache is an OTP cache. */ \
+ if(spcache) L2kt = GETDDMUI(tail,k,spcache); /* spcache is an OTP cache. */ \
else{ \
L2kt=0; \
/*Now, count # u such that k->u->h (so that we know k's ESP value)*/ \
@@ -150,7 +150,7 @@
EXEC_THROUGH_INEDGES(tail, e, k, { \
if((k!=head)){ /*Only use contingent cases*/ \
int L2hk; \
- if(spcache) L2hk = GETDMUI(k,head,spcache); \
+ if(spcache) L2hk = GETDDMUI(k,head,spcache); \
else{ \
L2hk=0; \
/*Now, count # u such that t->u->k (so that we know k's ESP value)*/ \
@@ -179,7 +179,7 @@
if(k!=tail){ \
int L2tk; \
/*Do we have a t->k,h->k SP? If so, add it to our count.*/ \
- if(spcache) L2tk = GETDMUI(tail,k,spcache); \
+ if(spcache) L2tk = GETUDMUI(tail,k,spcache); \
else{ \
L2tk=0; \
/*Now, count # u such that t->u,k->u (to get t->k's ESP value)*/ \
@@ -209,7 +209,7 @@
EXEC_THROUGH_OUTEDGES(tail, e, k, { \
int L2kh; \
if(k!=head){ \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETUDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/*Now, count # u such that u->h,u->k (to get h>k's ESP value)*/ \
@@ -241,7 +241,7 @@
EXEC_THROUGH_OUTEDGES(tail,e,k,{ \
if(k!=head&&IS_OUTEDGE(k,tail)){ \
int L2kh; \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETUDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/*Now, count # u such that k<->u<->h (to get k->h's SP value)*/ \
@@ -257,7 +257,7 @@
EXEC_THROUGH_OUTEDGES(head,e,k,{ \
if(k!=tail&&IS_OUTEDGE(k,head)){ \
int L2kt; \
- if(spcache) L2kt = GETDMUI(k,tail,spcache); \
+ if(spcache) L2kt = GETUDMUI(k,tail,spcache); \
else{ \
L2kt=0; \
/*Now, count # u such that k<->u<->t (to get k->t's SP value)*/ \
@@ -289,15 +289,15 @@
*/
#define espUTP_change(L, subroutine_path, subroutine_focus) \
int L2th; \
- if(spcache) L2th = GETDMUI(tail,head,spcache); else L2th=0; \
+ if(spcache) L2th = GETDDMUI(tail,head,spcache); else L2th=0; \
/* step through outedges of head */ \
EXEC_THROUGH_EDGES(head,e,u, { \
if (IS_UNDIRECTED_EDGE(u,tail) != 0){ \
int L2tu; \
int L2uh; \
if(spcache){ \
- L2tu = GETDMUI(tail,u,spcache); \
- L2uh = GETDMUI(u,head,spcache); \
+ L2tu = GETUDMUI(tail,u,spcache); \
+ L2uh = GETUDMUI(u,head,spcache); \
}else{ \
L2th++; \
L2tu=0; \
@@ -327,7 +327,7 @@
*/
#define espOTP_change(L, subroutine_path, subroutine_focus) \
int L2th; \
- if(spcache) L2th = GETDMUI(tail,head,spcache); else L2th=0; \
+ if(spcache) L2th = GETDDMUI(tail,head,spcache); else L2th=0; \
/* step through outedges of tail (i.e., k: t->k)*/ \
EXEC_THROUGH_OUTEDGES(tail,e,k, { \
if(!spcache&&(k!=head)&&(IS_OUTEDGE(k,head))){ \
@@ -336,7 +336,7 @@
} \
int L2tk; \
if((k!=head)&&(IS_OUTEDGE(head,k))){ /*Only use contingent cases*/ \
- if(spcache) L2tk = GETDMUI(tail,k,spcache); \
+ if(spcache) L2tk = GETDDMUI(tail,k,spcache); \
else{ \
L2tk=0; \
/*Now, count # u such that t->u->k (to find t->k's ESP value)*/ \
@@ -352,7 +352,7 @@
EXEC_THROUGH_INEDGES(head,e,k, { \
int L2kh; \
if((k!=tail)&&(IS_OUTEDGE(k,tail))){ /*Only use contingent cases*/ \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETDDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/*Now, count # u such that k->u->j (to find k->h's ESP value)*/ \
@@ -379,12 +379,12 @@
*/
#define espITP_change(L, subroutine_path, subroutine_focus) \
int L2th; \
- if(spcache) L2th = GETDMUI(head,tail,spcache); else L2th=0; \
+ if(spcache) L2th = GETDDMUI(head,tail,spcache); else L2th=0; \
/* step through outedges of head (i.e., k: h->k)*/ \
EXEC_THROUGH_OUTEDGES(head,e,k, { \
int L2hk; \
if((k!=tail)&&(IS_OUTEDGE(k,tail))){ /*Only use contingent cases*/ \
- if(spcache) L2hk = GETDMUI(k,head,spcache); \
+ if(spcache) L2hk = GETDDMUI(k,head,spcache); \
else{ \
/*We have a h->k->t two-path, so add it to our count.*/ \
L2th++; \
@@ -402,7 +402,7 @@
EXEC_THROUGH_INEDGES(tail,e,k, { \
int L2kt; \
if((k!=head)&&(IS_OUTEDGE(head,k))){ /*Only use contingent cases*/ \
- if(spcache) L2kt = GETDMUI(tail,k,spcache); \
+ if(spcache) L2kt = GETDDMUI(tail,k,spcache); \
else{ \
L2kt=0; \
/*Now, count # u such that t->u->k (so that we know k's ESP value)*/ \
@@ -429,7 +429,7 @@
*/
#define espOSP_change(L, subroutine_path, subroutine_focus) \
int L2th; \
- if(spcache) L2th = GETDMUI(tail,head,spcache); else L2th=0; \
+ if(spcache) L2th = GETUDMUI(tail,head,spcache); else L2th=0; \
/* step through outedges of tail (i.e., k: t->k, k->h, k!=h)*/ \
EXEC_THROUGH_OUTEDGES(tail,e,k, { \
if(k!=head){ \
@@ -439,7 +439,7 @@
\
if(IS_OUTEDGE(k,head)){ /*Only consider stats that could change*/ \
int L2tk; \
- if(spcache) L2tk = GETDMUI(tail,k,spcache); \
+ if(spcache) L2tk = GETUDMUI(tail,k,spcache); \
else{ \
L2tk=0; \
/*Now, count # u such that t->u,k->u (to get t->k's ESP value)*/ \
@@ -456,7 +456,7 @@
EXEC_THROUGH_INEDGES(tail,e,k, { \
if((k!=head)&&(IS_OUTEDGE(k,head))){ /*Only stats that could change*/ \
int L2kt; \
- if(spcache) L2kt = GETDMUI(k,tail,spcache); \
+ if(spcache) L2kt = GETUDMUI(k,tail,spcache); \
else{ \
L2kt=0; \
/*Now, count # u such that t->u,k->u (to get k->t's ESP value)*/ \
@@ -483,7 +483,7 @@
*/
#define espISP_change(L, subroutine_path, subroutine_focus) \
int L2th; \
- if(spcache) L2th = GETDMUI(tail,head,spcache); else L2th=0; \
+ if(spcache) L2th = GETUDMUI(tail,head,spcache); else L2th=0; \
/* step through inedges of head (i.e., k: k->h, t->k, k!=t)*/ \
EXEC_THROUGH_INEDGES(head,e,k, { \
if(k!=tail){ \
@@ -493,7 +493,7 @@
\
if(IS_OUTEDGE(tail,k)){ /*Only consider stats that could change*/ \
int L2kh; \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETUDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/*Now, count # u such that u->h,u->k (to get h>k's ESP value)*/ \
@@ -510,7 +510,7 @@
EXEC_THROUGH_OUTEDGES(head,e,k, { \
if((k!=tail)&&(IS_OUTEDGE(tail,k))){ /*Only stats that could change*/ \
int L2hk; \
- if(spcache) L2hk = GETDMUI(head,k,spcache); \
+ if(spcache) L2hk = GETUDMUI(head,k,spcache); \
else{ \
L2hk=0; \
/*Now, count # u such that u->h,u->k (to get k->h's ESP value)*/ \
@@ -539,7 +539,7 @@
*/
#define espRTP_change(L, subroutine_path, subroutine_focus) \
int L2th; /*Two-path counts for various edges*/ \
- if(spcache) L2th = GETDMUI(tail,head,spcache); else L2th=0; \
+ if(spcache) L2th = GETDDMUI(tail,head,spcache); else L2th=0; \
int htedge=IS_OUTEDGE(head,tail); /*Is there an h->t (reciprocating) edge?*/ \
/* step through inedges of tail (k->t: k!=h,h->t,k<->h)*/ \
EXEC_THROUGH_INEDGES(tail,e,k, { \
@@ -549,7 +549,7 @@
L2th+=(IS_OUTEDGE(tail,k)&&IS_OUTEDGE(head,k)&&IS_OUTEDGE(k,head)); \
if(htedge&&IS_OUTEDGE(head,k)&&IS_OUTEDGE(k,head)){ /*Only consider stats that could change*/ \
int L2kt; \
- if(spcache) L2kt = GETDMUI(k,tail,spcache); \
+ if(spcache) L2kt = GETUDMUI(k,tail,spcache); \
else{ \
L2kt=0; \
/*Now, count # u such that k<->u<->t (to get (k,t)'s ESP value)*/ \
@@ -567,7 +567,7 @@
if(k!=head){ \
if(htedge&&IS_OUTEDGE(head,k)&&IS_OUTEDGE(k,head)){ /*Only consider stats that could change*/ \
int L2tk; \
- if(spcache) L2tk = GETDMUI(tail,k,spcache); \
+ if(spcache) L2tk = GETUDMUI(tail,k,spcache); \
else{ \
L2tk=0; \
/*Now, count # u such that k<->u<->t (to get (tk)'s ESP value)*/ \
@@ -585,7 +585,7 @@
if(k!=tail){ \
if(htedge&&IS_OUTEDGE(tail,k)&&IS_OUTEDGE(k,tail)){ /*Only consider stats that could change*/ \
int L2kh; \
- if(spcache) L2kh = GETDMUI(k,head,spcache); \
+ if(spcache) L2kh = GETUDMUI(k,head,spcache); \
else{ \
L2kh=0; \
/*Now, count # u such that k<->u<->h (to get k->h's ESP value)*/ \
@@ -603,7 +603,7 @@
if(k!=tail){ \
if(htedge&&IS_OUTEDGE(tail,k)&&IS_OUTEDGE(k,tail)){ /*Only consider stats that could change*/ \
int L2hk; \
- if(spcache) L2hk = GETDMUI(head,k,spcache); \
+ if(spcache) L2hk = GETUDMUI(head,k,spcache); \
else{ \
L2hk=0; \
/*Now, count # u such that k<->u<->h (to get h->k's ESP value)*/ \
diff --git a/src/changestats_spcache.c b/src/changestats_spcache.c
index 0cfe1c0e6..375291c44 100644
--- a/src/changestats_spcache.c
+++ b/src/changestats_spcache.c
@@ -16,39 +16,39 @@
value is the number of directed two-paths from i to j. */
I_CHANGESTAT_FN(i__otp_wtnet){
- StoreDyadMapUInt *spcache = AUX_STORAGE = kh_init(DyadMapUInt); spcache->directed = TRUE;
+ StoreStrictDyadMapUInt *spcache = AUX_STORAGE = kh_init(StrictDyadMapUInt);
EXEC_THROUGH_NET_EDGES(i, j, e1, { // Since i->j
EXEC_THROUGH_FOUTEDGES(j, e2, k, { // and j->k
if(i!=k)
- IncDyadMapUInt(i,k,1,spcache); // increment i->k.
+ IncDDyadMapUInt(i,k,1,spcache); // increment i->k.
});
});
}
U_CHANGESTAT_FN(u__otp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
int echange = edgestate ? -1 : 1;
{
// Update all t->h->k two-paths.
EXEC_THROUGH_FOUTEDGES(head, e, k, {
if(tail!=k)
- IncDyadMapUInt(tail,k,echange,spcache);
+ IncDDyadMapUInt(tail,k,echange,spcache);
});
}
{
// Update all k->t->h two-paths.
EXEC_THROUGH_FINEDGES(tail, e, k, {
if(k!=head)
- IncDyadMapUInt(k,head,echange,spcache);
+ IncDDyadMapUInt(k,head,echange,spcache);
});
}
}
F_CHANGESTAT_FN(f__otp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
- kh_destroy(DyadMapUInt,spcache);
+ kh_destroy(StrictDyadMapUInt,spcache);
AUX_STORAGE=NULL;
}
@@ -57,30 +57,30 @@ F_CHANGESTAT_FN(f__otp_wtnet){
value is the number of outgoing shared partners of i and j. */
I_CHANGESTAT_FN(i__osp_wtnet){
- StoreDyadMapUInt *spcache = AUX_STORAGE = kh_init(DyadMapUInt); spcache->directed = FALSE;
+ StoreStrictDyadMapUInt *spcache = AUX_STORAGE = kh_init(StrictDyadMapUInt);
EXEC_THROUGH_NET_EDGES(i, j, e1, { // Since i->j
EXEC_THROUGH_FINEDGES(j, e2, k, { // and k->j
if(ih<-k shared partners.
EXEC_THROUGH_FINEDGES(head, e, k, {
if(tail!=k)
- IncDyadMapUInt(tail,k,echange,spcache);
+ IncUDyadMapUInt(tail,k,echange,spcache);
});
}
F_CHANGESTAT_FN(f__osp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
- kh_destroy(DyadMapUInt,spcache);
+ kh_destroy(StrictDyadMapUInt,spcache);
AUX_STORAGE=NULL;
}
@@ -88,30 +88,30 @@ F_CHANGESTAT_FN(f__osp_wtnet){
value is the number of incoming shared partners of i and j. */
I_CHANGESTAT_FN(i__isp_wtnet){
- StoreDyadMapUInt *spcache = AUX_STORAGE = kh_init(DyadMapUInt); spcache->directed = FALSE;
+ StoreStrictDyadMapUInt *spcache = AUX_STORAGE = kh_init(StrictDyadMapUInt);
EXEC_THROUGH_NET_EDGES(i, j, e1, { // Since i->j
EXEC_THROUGH_FOUTEDGES(i, e2, k, { // and i->k
if(jk shared partners.
EXEC_THROUGH_FOUTEDGES(tail, e, k, {
if(head!=k)
- IncDyadMapUInt(head,k,echange,spcache);
+ IncUDyadMapUInt(head,k,echange,spcache);
});
}
F_CHANGESTAT_FN(f__isp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
- kh_destroy(DyadMapUInt,spcache);
+ kh_destroy(StrictDyadMapUInt,spcache);
AUX_STORAGE=NULL;
}
@@ -119,37 +119,37 @@ F_CHANGESTAT_FN(f__isp_wtnet){
value is the number of reciprocated partners of i and j. */
I_CHANGESTAT_FN(i__rtp_wtnet){
- StoreDyadMapUInt *spcache = AUX_STORAGE = kh_init(DyadMapUInt); spcache->directed = FALSE;
+ StoreStrictDyadMapUInt *spcache = AUX_STORAGE = kh_init(StrictDyadMapUInt);
EXEC_THROUGH_NET_EDGES(i, j, e1, { // Since i->j
if(IS_OUTEDGE(j,i)) // and j->i
EXEC_THROUGH_FOUTEDGES(i, e2, k, { // and i->k
if(ji (and don't double-count)
- IncDyadMapUInt(j,k,1,spcache); // increment j-k.
+ IncDDyadMapUInt(j,k,1,spcache); // increment j-k.
});
});
}
U_CHANGESTAT_FN(u__rtp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
if(!IS_OUTEDGE(head,tail)) return; // If no reciprocating edge, no effect.
int echange = edgestate ? -1 : 1;
// Update all h?->t<->k shared partners.
EXEC_THROUGH_FOUTEDGES(tail, e, k, {
if(head!=k&&IS_OUTEDGE(k,tail))
- IncDyadMapUInt(head,k,echange,spcache);
+ IncUDyadMapUInt(head,k,echange,spcache);
});
// Update all k<->h?->t shared partners.
EXEC_THROUGH_FOUTEDGES(head, e, k, {
if(tail!=k&&IS_OUTEDGE(k,head))
- IncDyadMapUInt(tail,k,echange,spcache);
+ IncUDyadMapUInt(tail,k,echange,spcache);
});
}
F_CHANGESTAT_FN(f__rtp_wtnet){
- GET_AUX_STORAGE(StoreDyadMapUInt, spcache);
+ GET_AUX_STORAGE(StoreStrictDyadMapUInt, spcache);
- kh_destroy(DyadMapUInt,spcache);
+ kh_destroy(StrictDyadMapUInt,spcache);
AUX_STORAGE=NULL;
}
@@ -157,41 +157,41 @@ F_CHANGESTAT_FN(f__rtp_wtnet){
value is the number of undirected shared partners of i and j. */
I_CHANGESTAT_FN(i__utp_wtnet){
- StoreDyadMapUInt *spcache = AUX_STORAGE = kh_init(DyadMapUInt); spcache->directed = FALSE;
+ StoreStrictDyadMapUInt *spcache = AUX_STORAGE = kh_init(StrictDyadMapUInt);
EXEC_THROUGH_NET_EDGES(i, j, e1, { // Since i-j
EXEC_THROUGH_EDGES(i, e2, k, { // and i-k
if(j
Date: Thu, 16 May 2024 00:36:28 +1000
Subject: [PATCH 5/5] The DyadSet auxiliaries and the corresponding test code
now use StrictDyadSet.
---
inst/include/ergm_changestats_auxnet.h | 2 +-
src/changestats_auxnetalike.c | 72 +++++++++++++-------------
src/changestats_test.c | 6 +--
3 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/inst/include/ergm_changestats_auxnet.h b/inst/include/ergm_changestats_auxnet.h
index f1c88a3c9..4823e9a33 100644
--- a/inst/include/ergm_changestats_auxnet.h
+++ b/inst/include/ergm_changestats_auxnet.h
@@ -13,7 +13,7 @@
#include "ergm_changestat_auxnet.h"
#include "ergm_dyad_hashmap.h"
-typedef struct{StoreDyadSet *nwp; int *ref_el;} StoreDyadSetAndRefEL;
+typedef struct{StoreStrictDyadSet *nwp; int *ref_el;} StoreStrictDyadSetAndRefEL;
#define map_toggle_maxtoggles__discord_net_Network 1
MAP_TOGGLE_FN(map_toggle__discord_net_Network){
diff --git a/src/changestats_auxnetalike.c b/src/changestats_auxnetalike.c
index f7372a31f..b175a4a03 100644
--- a/src/changestats_auxnetalike.c
+++ b/src/changestats_auxnetalike.c
@@ -50,113 +50,113 @@ F_CHANGESTAT_FN(f__discord_isociomatrix){
}
I_CHANGESTAT_FN(i__discord_net_DyadSet){
- ALLOC_AUX_STORAGE(1, StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp = NetworkToDyadSet(nwp);
+ ALLOC_AUX_STORAGE(1, StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp = NetworkToStrictDyadSet(nwp);
int *ref_el = storage->ref_el = IINPUT_PARAM;
Edge nedges = *ref_el;
for(Edge i=0; inwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- DyadSetToggle(tail,head, dnwp);
+ DDyadSetToggle(tail,head, dnwp);
}
F_CHANGESTAT_FN(f__discord_net_DyadSet){
- GET_AUX_STORAGE(StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- kh_destroy(DyadSet, dnwp);
+ kh_destroy(StrictDyadSet, dnwp);
}
I_CHANGESTAT_FN(i__intersect_net_DyadSet){
- ALLOC_AUX_STORAGE(1, StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp = kh_init(DyadSet); dnwp->directed=DIRECTED;
+ ALLOC_AUX_STORAGE(1, StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp = kh_init(StrictDyadSet);
int *ref_el = storage->ref_el = IINPUT_PARAM;
Edge nedges = *ref_el;
for(Edge i=0; inwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
int *ref_el = storage->ref_el;
// only toggle if the edge is in y0. otherwise changing y1 won't matter.
if(iEdgeListSearch(tail, head, ref_el))
- DyadSetToggle(tail,head, dnwp);
+ DDyadSetToggle(tail,head, dnwp);
}
F_CHANGESTAT_FN(f__intersect_net_DyadSet){
- GET_AUX_STORAGE(StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- kh_destroy(DyadSet, dnwp);
+ kh_destroy(StrictDyadSet, dnwp);
}
I_CHANGESTAT_FN(i__intersect_net_toggles_in_list_DyadSet){
- ALLOC_AUX_STORAGE(1, StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp = kh_init(DyadSet); dnwp->directed=DIRECTED;
+ ALLOC_AUX_STORAGE(1, StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp = kh_init(StrictDyadSet);
int *ref_el = storage->ref_el = IINPUT_PARAM;
Edge nedges = *ref_el;
for(Edge i=0; inwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- DyadSetToggle(tail,head, dnwp);
+ DDyadSetToggle(tail,head, dnwp);
}
F_CHANGESTAT_FN(f__intersect_net_toggles_in_list_DyadSet){
- GET_AUX_STORAGE(StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- kh_destroy(DyadSet, dnwp);
+ kh_destroy(StrictDyadSet, dnwp);
}
I_CHANGESTAT_FN(i__union_net_DyadSet){
- ALLOC_AUX_STORAGE(1, StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp = NetworkToDyadSet(nwp);
+ ALLOC_AUX_STORAGE(1, StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp = NetworkToStrictDyadSet(nwp);
int *ref_el = storage->ref_el = IINPUT_PARAM;
Edge nedges = *ref_el;
for(Edge i=0; inwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
int *ref_el = storage->ref_el;
// If the edge is in y0, changing y1 won't matter.
if(iEdgeListSearch(tail, head, ref_el)==0)
- DyadSetToggle(tail,head, dnwp);
+ DDyadSetToggle(tail,head, dnwp);
}
F_CHANGESTAT_FN(f__union_net_DyadSet){
- GET_AUX_STORAGE(StoreDyadSetAndRefEL, storage);
- StoreDyadSet *dnwp = storage->nwp;
+ GET_AUX_STORAGE(StoreStrictDyadSetAndRefEL, storage);
+ StoreStrictDyadSet *dnwp = storage->nwp;
- kh_destroy(DyadSet, dnwp);
+ kh_destroy(StrictDyadSet, dnwp);
}
diff --git a/src/changestats_test.c b/src/changestats_test.c
index 0dc8d56ac..085123fb4 100644
--- a/src/changestats_test.c
+++ b/src/changestats_test.c
@@ -81,9 +81,9 @@ C_CHANGESTAT_FN(c_disc_inter_union_net_Network){
}
C_CHANGESTAT_FN(c_disc_inter_union_net_DyadSet){
- GET_AUX_STORAGE_NUM(StoreDyadSetAndRefEL, dstorage, 0);
- GET_AUX_STORAGE_NUM(StoreDyadSetAndRefEL, istorage, 1);
- GET_AUX_STORAGE_NUM(StoreDyadSetAndRefEL, ustorage, 2);
+ GET_AUX_STORAGE_NUM(StoreStrictDyadSetAndRefEL, dstorage, 0);
+ GET_AUX_STORAGE_NUM(StoreStrictDyadSetAndRefEL, istorage, 1);
+ GET_AUX_STORAGE_NUM(StoreStrictDyadSetAndRefEL, ustorage, 2);
int refedge = dEdgeListSearch(tail, head, INPUT_PARAM)!=0;