Skip to content

Commit 5db0155

Browse files
committed
%ergmlhs% constraint settings now use term_lists and helper functions.
1 parent e579814 commit 5db0155

5 files changed

Lines changed: 28 additions & 27 deletions

File tree

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: ergm.multi
2-
Version: 0.3.0-4260
3-
Date: 2026-03-18
2+
Version: 0.3.0-4261
3+
Date: 2026-03-20
44
Title: Fit, Simulate and Diagnose Exponential-Family Models for Multiple or Multilayer Networks
55
Authors@R: c(person(c("Pavel", "N."), "Krivitsky", role=c("aut","cre"), email="pavel@statnet.org", comment=c(ORCID="0000-0002-9101-3362")),
66
person(c("Mark", "S."), "Handcock", role=c("ctb"), email="handcock@stat.ucla.edu"),
@@ -10,7 +10,7 @@ Authors@R: c(person(c("Pavel", "N."), "Krivitsky", role=c("aut","cre"), email="p
1010
person("Joyce", "Cheng", role=c("ctb"), email="joyce.cheng@student.unsw.edu.au"))
1111
Depends:
1212
R (>= 4.2.0),
13-
ergm (>= 4.12.0),
13+
ergm (>= 4.13.0),
1414
network (>= 1.19.0)
1515
Imports:
1616
statnet.common (>= 4.14.0),

R/ergmlhs.R

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,26 @@ combine_ergmlhs <- function(nwl, ignore.settings=c()){
5353
#' @export
5454
ergmlhs_remove_blockdiag <- function(nw, vattr) {
5555
if (! vattr %in% list.vertex.attributes(nw)) {
56-
nw %ergmlhs% "constraints" <- filter_rhs.formula(nw %ergmlhs% "constraints", function(trm)
57-
! identical(trm, call("blockdiag", vattr, noncontig = "split")))
56+
todel <- blockdiag_term_list(vattr)
5857

59-
## TODO: filter_rhs.formula() should probably return NULL when it
60-
## deleted all the terms, so if this is ever the case, the
61-
## following could be removed.
62-
if (length(nw %ergmlhs% "constraints") < 2) nw %ergmlhs% "constraints" <- NULL
58+
con <- ergm_flatten_conterm_list(nw %ergmlhs% "constraints")
59+
nw %ergmlhs% "constraints" <- con[map(seq_along(con), \(i) con[i]) |>
60+
map_lgl(identical, todel) |>
61+
(`!`)()]
6362
}
6463
nw
6564
}
65+
66+
blockdiag_term_list <- function(vattr) {
67+
term_list(call("blockdiag", vattr, noncontig = "split"), env = baseenv())
68+
}
69+
70+
add_con <- function(x, y, from = x) {
71+
con <- ergm_flatten_conterm_list(from %ergmlhs% "constraints") %||%
72+
term_list(list())
73+
y <- ergm_flatten_conterm_list(y)
74+
75+
x %ergmlhs% "constraints" <- unique(c(con, y))
76+
x %ergmlhs% "obs.constraints" <- from %ergmlhs% "obs.constraints"
77+
x
78+
}

R/multilayer.R

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -575,16 +575,10 @@ Layer <- function(..., .symmetric=NULL, .bipartite=NULL, .active=NULL){
575575

576576
nw %n% "ergm" <- combine_ergmlhs(nwl)
577577

578-
nw %ergmlhs% "constraints" <-
579-
if(NVL(nwl[[1]] %ergmlhs% "constraints",base_env(~.))==base_env(~.))
580-
base_env(~blockdiag(".LayerID", noncontig = "split"))
581-
else
582-
append_rhs.formula(nwl[[1]] %ergmlhs% "constraints", list(call("blockdiag", ".LayerID", noncontig = "split")), TRUE)
578+
nw <- add_con(nw, blockdiag_term_list(".LayerID"), nwl[[1]])
583579

584-
if(any(symm)) nw %ergmlhs% "constraints" <- append_rhs.formula(nw %ergmlhs% "constraints", list(call("upper_tri",".undirected")), TRUE)
585-
if(any(blockout!=0)||!is.null(.active)) nw %ergmlhs% "constraints" <- append_rhs.formula(nw %ergmlhs% "constraints", list(call("blacklist_block")), TRUE)
586-
587-
if(!is.null(nwl[[1]]%ergmlhs%"obs.constraints")) nw %ergmlhs% "obs.constraints" <- nwl[[1]] %ergmlhs% "obs.constraints"
580+
if(any(symm)) nw <- add_con(nw, term_list(call("upper_tri", ".undirected"), env = baseenv()))
581+
if(any(blockout!=0)||!is.null(.active)) nw <- add_con(nw, term_list(call("blacklist_block"), env = baseenv()))
588582

589583
nw
590584
}

R/multinet.R

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,7 @@ Networks <- function(...){
5353
nw <- combine_networks(nwl, blockID.vattr=".NetworkID", blockName.vattr=".NetworkName", ignore.nattr = c(eval(formals(combine_networks)$ignore.nattr), "constraints", "obs.constraints", "ergm"), subnet.cache=TRUE)
5454

5555
nw %n% "ergm" <- combine_ergmlhs(nwl)
56-
57-
nw %ergmlhs% "constraints" <-
58-
if(NVL(nwl[[1]] %ergmlhs% "constraints",base_env(~.))==base_env(~.))
59-
base_env(~blockdiag(".NetworkID", noncontig = "split"))
60-
else
61-
append_rhs.formula(nwl[[1]]%ergmlhs%"constraints", list(call("blockdiag", ".NetworkID", noncontig = "split")), TRUE)
62-
if(!is.null(nwl[[1]]%ergmlhs%"obs.constraints")) nw %ergmlhs% "obs.constraints" <- nwl[[1]]%ergmlhs%"obs.constraints"
56+
nw <- add_con(nw, blockdiag_term_list(".NetworkID"), nwl[[1]])
6357

6458
nw
6559
}

tests/testthat/test-nesting.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ test_that("simulation of two multilayer networks with heterogeneous layer counts
2121
expect_error(unLayer(nw1), ".*not a multilayer network at the top level.*")
2222
unw <- unNetworks(nw1)
2323
expect_length(unw, 2L)
24-
expect_identical(unw[[1]] %ergmlhs% "constraints", statnet.common::base_env(~blockdiag(".LayerID", noncontig = "split")))
24+
expect_identical(unw[[1]] %ergmlhs% "constraints", statnet.common::term_list(quote(blockdiag(".LayerID", noncontig = "split")), env = baseenv()))
2525

2626
uunw1 <- unLayer(unw[[1]])
2727
uunw2 <- unLayer(unw[[2]])
2828
expect_length(uunw1, 3L)
2929
expect_length(uunw2, 2L)
3030

31-
expect_identical(uunw1[[1]] %ergmlhs% "constraints", NULL)
31+
expect_length(uunw1[[1]] %ergmlhs% "constraints", 0L)
3232
})

0 commit comments

Comments
 (0)