Skip to content

Commit 39bdccb

Browse files
committed
gw*degree(0, fixed = TRUE) no longer produces NaNs and does not cause errors when the network has no *isolates. Thanks to Kevin Reuning (@reuning) for the report.
fixes #602
1 parent fb03910 commit 39bdccb

7 files changed

Lines changed: 38 additions & 25 deletions

R/InitErgmTerm.R

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,11 +2626,13 @@ InitErgmTerm.gwb1dsp<-function(nw, arglist, cache.sp=TRUE, gw.cutoff=30, ...) {
26262626
#' @templateVar name gwb2degree
26272627
#' @title Geometrically weighted degree distribution for the second mode in a bipartite network
26282628
#' @description This term adds one network statistic to the model equal to the weighted
2629-
#' degree distribution with decay controlled by the which should be non-negative,
2630-
#' for nodes in the
2631-
#' second mode of a bipartite network. The second mode of a bipartite network
2629+
#' degree distribution with decay controlled by the `decay` parameter, which should be non-negative,
2630+
#' for nodes in the second mode of a bipartite network. The second mode of a bipartite network
26322631
#' object is sometimes known as the "event" mode.
2633-
#'
2632+
#'
2633+
#' This term can only be used with undirected bipartite
2634+
#' networks.
2635+
#'
26342636
#' @usage
26352637
#' # binary: gwb2degree(decay, fixed=FALSE, attr=NULL, cutoff=30, levels=NULL)
26362638
#'
@@ -2738,7 +2740,7 @@ InitErgmTerm.gwidegree<-function(nw, arglist, gw.cutoff=30, ..., version=package
27382740
#' @title Geometrically weighted out-degree distribution
27392741
#' @description This term adds one network statistic to the model
27402742
#' equal to the weighted out-degree distribution with decay parameter
2741-
#' `decay` parameter, which should be non-negative. This
2743+
#' `decay` parameter, which should be positive. This
27422744
#' term can only be used with directed networks.
27432745
#'
27442746
#' @usage

man/gwb2degree-ergmTerm-584e787c.Rd

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/gwodegree-ergmTerm-276e606c.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/spcachenet-ergmAuxiliary-f1950bb3.Rd

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/changestats.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,9 @@ S_CHANGESTAT_FN(s_edges) {
18731873
/*****************
18741874
changestat: d_gwdegree
18751875
*****************/
1876+
1877+
#define GWD0(d0) ((decay) ? exp(loneexpd*(d0)) : (d0)==0)
1878+
18761879
C_CHANGESTAT_FN(c_gwdegree) {
18771880
int echange=0;
18781881
double decay, loneexpd, change;
@@ -1885,10 +1888,10 @@ C_CHANGESTAT_FN(c_gwdegree) {
18851888

18861889
/* *** don't forget tail -> head */
18871890
change = 0.0;
1888-
echange = edgestate ? -1:+1;
1889-
taild = od[tail] + id[tail] + (echange - 1)/2;
1890-
headd = od[head] + id[head] + (echange - 1)/2;
1891-
change += echange*(exp(loneexpd*taild)+exp(loneexpd*headd));
1891+
echange = edgestate ? -1:+1;
1892+
taild = od[tail] + id[tail] - edgestate;
1893+
headd = od[head] + id[head] - edgestate;
1894+
change += echange*(GWD0(taild) + GWD0(headd));
18921895

18931896
CHANGE_STAT[0] = change;
18941897

@@ -1914,13 +1917,13 @@ C_CHANGESTAT_FN(c_gwdegree_by_attr) {
19141917

19151918
/* *** don't forget tail -> head */
19161919
echange = edgestate ? -1:+1;
1917-
taild = od[tail] + id[tail] + (echange - 1)/2;
1920+
taild = od[tail] + id[tail] - edgestate;
19181921
tailattr = INPUT_PARAM[tail];
1919-
CHANGE_STAT[tailattr-1] += echange*exp(loneexpd*taild);
1922+
CHANGE_STAT[tailattr-1] += echange*GWD0(taild);
19201923

1921-
headd = od[head] + id[head] + (echange - 1)/2;
1924+
headd = od[head] + id[head] - edgestate;
19221925
headattr = INPUT_PARAM[head];
1923-
CHANGE_STAT[headattr-1] += echange*exp(loneexpd*headd);
1926+
CHANGE_STAT[headattr-1] += echange*GWD0(headd);
19241927

19251928
}
19261929

@@ -1937,7 +1940,7 @@ C_CHANGESTAT_FN(c_gwidegree) {
19371940

19381941
/* *** don't forget tail -> head */
19391942
headd = IN_DEG[head] - edgestate;
1940-
change += (edgestate? -1.0 : 1.0) * exp(loneexpd*headd);
1943+
change += (edgestate? -1.0 : 1.0) * GWD0(headd);
19411944
CHANGE_STAT[0]=change;
19421945
}
19431946

@@ -1959,9 +1962,9 @@ C_CHANGESTAT_FN(c_gwidegree_by_attr) {
19591962

19601963
/* *** don't forget tail -> head */
19611964
echange = edgestate ? -1 : 1;
1962-
headd = IN_DEG[head] + (echange - 1)/2;
1965+
headd = IN_DEG[head] - edgestate;
19631966
headattr = INPUT_PARAM[head - BIPARTITE]; /* BIPARTITE to make the b2 version a special case. */
1964-
CHANGE_STAT[headattr-1] += echange*exp(loneexpd*headd);
1967+
CHANGE_STAT[headattr-1] += echange*GWD0(headd);
19651968
}
19661969

19671970
/*****************
@@ -1977,7 +1980,7 @@ C_CHANGESTAT_FN(c_gwodegree) {
19771980

19781981
/* *** don't forget tail -> head */
19791982
taild = OUT_DEG[tail] - edgestate;
1980-
change += (edgestate? -1 : 1) * exp(loneexpd*taild);
1983+
change += (edgestate? -1 : 1) * GWD0(taild);
19811984
CHANGE_STAT[0] = change;
19821985
}
19831986

@@ -1999,9 +2002,9 @@ C_CHANGESTAT_FN(c_gwodegree_by_attr) {
19992002

20002003
/* *** don't forget tail -> head */
20012004
echange = edgestate ? -1 : 1;
2002-
taild = OUT_DEG[tail] + (echange - 1)/2;
2005+
taild = OUT_DEG[tail] - edgestate;
20032006
tailattr = INPUT_PARAM[tail];
2004-
CHANGE_STAT[tailattr-1] += echange*exp(loneexpd*taild);
2007+
CHANGE_STAT[tailattr-1] += echange*GWD0(taild);
20052008
}
20062009

20072010
/******************** changestats: H ***********/

tests/testthat/test-term-directed.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ test_that("gwodegree, directed", {
8888
expect_summary(head(s.d), e.d, setNames(c(0,0,1,5,7,5), paste0("gwodegree#",1:6)), c(gwodeg.fixed.0.4=-1.990492))
8989
expect_summary(s.df, e.df, 24.23040, 43.61801)
9090
expect_summary(s.dfa, e.dfa, c(7.735906, 4.419631, 7.736070), -c(4.1860720, 5.9706455, 0.4921623))
91+
92+
# Also, check that gwodegree(0) works correctly, including when there are none.
93+
expect_equal(summary(samplike~gwodegree(0, fixed = TRUE)), network.size(samplike), ignore_attr = TRUE)
94+
expect_equal(coef(ergm(samplike~edges + gwodegree(0, fixed = TRUE), estimate="MPLE"))[[2]], +Inf)
9195
})
9296

9397
test_that("idegree, directed", {

tests/testthat/test-term-undirected.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ test_that("gwdegree, undirected", {
126126
expect_summary(s.dfa, e.dfa,
127127
c(53.58148, 25.53534, 30.83418, 17.79934, 19.31326, 10.80933),
128128
-c(23.94060, 23.30646, 23.51430, 23.31140, 25.11103, 26.88088))
129+
130+
# Also, check that gwdegree(0) is evaluates correctly.
131+
expect_equal(summary(fmh ~ gwdegree(0, fixed=TRUE)), network.size(fmh) - summary(fmh ~ degree(0)), ignore_attr = TRUE)
129132
})
130133

131134
test_that("kstar, undirected", {

0 commit comments

Comments
 (0)