From 3e4fd8186b5a034ad3b68534a8d8cb8620c3b40a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 11:43:08 +0000 Subject: [PATCH 01/10] Initial plan From 0f394933543a486b6503017613689ff6a606a8e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 11:58:41 +0000 Subject: [PATCH 02/10] feat: Add join() function to R interface - Add join() function and %j% operator in R/operators.R - Add comprehensive tests for join() in test-operators.R - Update documentation with examples - Export join and %j% in NAMESPACE Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- .gitignore | 1 + NAMESPACE | 2 + R/operators.R | 59 ++++++++++++++ man/add_edges.Rd | 1 + man/add_vertices.Rd | 1 + man/complementer.Rd | 1 + man/compose.Rd | 1 + man/contract.Rd | 1 + man/delete_edges.Rd | 1 + man/delete_vertices.Rd | 1 + man/difference.Rd | 1 + man/difference.igraph.Rd | 1 + man/disjoint_union.Rd | 1 + man/edge.Rd | 1 + man/ego.Rd | 1 + man/igraph-minus.Rd | 1 + man/intersection.Rd | 1 + man/intersection.igraph.Rd | 1 + man/join.Rd | 113 +++++++++++++++++++++++++++ man/path.Rd | 1 + man/permute.Rd | 1 + man/plus-.igraph.Rd | 1 + man/rep.igraph.Rd | 1 + man/reverse_edges.Rd | 1 + man/simplify.Rd | 1 + man/union.Rd | 1 + man/union.igraph.Rd | 1 + man/vertex.Rd | 1 + tests/testthat/test-operators.R | 58 ++++++++++++++ tests/testthat/testthat-problems.rds | Bin 46380 -> 0 bytes 30 files changed, 257 insertions(+) create mode 100644 man/join.Rd delete mode 100644 tests/testthat/testthat-problems.rds diff --git a/.gitignore b/.gitignore index dd12d586c35..220e6421b1b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ cran /src/*.d /src/symbols.rds /covr +tests/testthat/testthat-problems.rds diff --git a/NAMESPACE b/NAMESPACE index 95be07fb203..2e162cacee9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -91,6 +91,7 @@ export("%<-%") export("%>%") export("%c%") export("%du%") +export("%j%") export("%m%") export("%s%") export("%u%") @@ -579,6 +580,7 @@ export(isomorphism_class) export(isomorphisms) export(ivs) export(ivs_size) +export(join) export(k.regular.game) export(k_shortest_paths) export(kautz_graph) diff --git a/R/operators.R b/R/operators.R index 20cea8fc969..43c6a5d7d5b 100644 --- a/R/operators.R +++ b/R/operators.R @@ -302,6 +302,65 @@ disjoint_union <- function(...) { disjoint_union(x, y) } +#' Join of two graphs +#' +#' The join of two graphs is created by connecting all vertices from +#' the first graph to all vertices in the second graph. +#' +#' `join()` creates the join of two graphs. The graphs must be disjoint, +#' i.e., have distinct vertex sets. First the vertices of the second graph will +#' be relabeled with new vertex IDs, then the union of the two graphs is formed. +#' Finally, all vertices from the first graph will be connected to all vertices +#' from the second graph. If the two graphs have |V1| and |V2| vertices and +#' |E1| and |E2| edges respectively, then the new graph will have |V1|+|V2| +#' vertices and |E1|+|E2|+|V1|*|V2| edges. This function can also be used via +#' the `%j%` operator. +#' +#' The vertex ordering of the graphs is preserved. In other words, the vertex +#' IDs of the first graph map to identical values in the new graph, while the +#' vertex IDs of the second graph map to IDs incremented by the vertex count +#' of the first graph. +#' +#' Both graphs need to have the same directedness, i.e. either both directed or +#' both undirected. If both graphs are directed, then for each pair of vertices +#' v, u in graphs G1, G2 we add edges (v, u) and (u, v) to maintain completeness. +#' +#' Note that the current version of this function cannot handle graph, vertex +#' and edge attributes; they will be lost in the result. +#' +#' An error is generated if some input graphs are directed and others are +#' undirected. +#' +#' @aliases %j% +#' @param g1,g2 Graph objects. +#' @return A new graph object. +#' @author Gabor Csardi \email{csardi.gabor@@gmail.com} +#' @export +#' @keywords graphs +#' @family functions for manipulating graph structure +#' @examples +#' +#' ## A star and a ring +#' g1 <- make_star(10, mode = "undirected") +#' g2 <- make_ring(5) +#' print_all(g1 %j% g2) +#' @export +#' @cdocs igraph_join +join <- function(g1, g2) { + ensure_igraph(g1) + ensure_igraph(g2) + + on.exit(.Call(R_igraph_finalizer)) + join_impl(g1, g2) +} + +#' @family functions for manipulating graph structure +#' @export +#' @rdname join +"%j%" <- function(x, y) { + join(x, y) +} + .igraph.graph.union.or.intersection <- function( call, ..., diff --git a/man/add_edges.Rd b/man/add_edges.Rd index 3289635293e..61a9b35af07 100644 --- a/man/add_edges.Rd +++ b/man/add_edges.Rd @@ -63,6 +63,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/add_vertices.Rd b/man/add_vertices.Rd index 54fb0fcf714..c985d917650 100644 --- a/man/add_vertices.Rd +++ b/man/add_vertices.Rd @@ -58,6 +58,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/complementer.Rd b/man/complementer.Rd index dc9d08799af..9c4f23cc820 100644 --- a/man/complementer.Rd +++ b/man/complementer.Rd @@ -57,6 +57,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/compose.Rd b/man/compose.Rd index 4d0a4ab5157..f95f0ed003c 100644 --- a/man/compose.Rd +++ b/man/compose.Rd @@ -87,6 +87,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/contract.Rd b/man/contract.Rd index e76972702aa..bad40fb5db1 100644 --- a/man/contract.Rd +++ b/man/contract.Rd @@ -61,6 +61,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/delete_edges.Rd b/man/delete_edges.Rd index 62c7f23b37c..b04ab92793f 100644 --- a/man/delete_edges.Rd +++ b/man/delete_edges.Rd @@ -50,6 +50,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/delete_vertices.Rd b/man/delete_vertices.Rd index f8e261f0620..96940d5e0fd 100644 --- a/man/delete_vertices.Rd +++ b/man/delete_vertices.Rd @@ -45,6 +45,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/difference.Rd b/man/difference.Rd index 42d56d3007d..a2fb0bfcff4 100644 --- a/man/difference.Rd +++ b/man/difference.Rd @@ -38,6 +38,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/difference.igraph.Rd b/man/difference.igraph.Rd index 393eb215b08..96168915bb7 100644 --- a/man/difference.igraph.Rd +++ b/man/difference.igraph.Rd @@ -76,6 +76,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/disjoint_union.Rd b/man/disjoint_union.Rd index 626248720ee..a459ee0fff9 100644 --- a/man/disjoint_union.Rd +++ b/man/disjoint_union.Rd @@ -68,6 +68,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/edge.Rd b/man/edge.Rd index ed963639f10..7f09121880b 100644 --- a/man/edge.Rd +++ b/man/edge.Rd @@ -67,6 +67,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/ego.Rd b/man/ego.Rd index 69c018240fe..99308ebb709 100644 --- a/man/ego.Rd +++ b/man/ego.Rd @@ -166,6 +166,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/igraph-minus.Rd b/man/igraph-minus.Rd index 4648ba984b5..5ddfe6ff6fd 100644 --- a/man/igraph-minus.Rd +++ b/man/igraph-minus.Rd @@ -73,6 +73,7 @@ Other functions for manipulating graph structure: \code{\link{edge}()}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/intersection.Rd b/man/intersection.Rd index 078f966349f..869f01d9919 100644 --- a/man/intersection.Rd +++ b/man/intersection.Rd @@ -38,6 +38,7 @@ Other functions for manipulating graph structure: \code{\link{edge}()}, \code{\link{igraph-minus}}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/intersection.igraph.Rd b/man/intersection.igraph.Rd index fc193b0ac89..aaf4aa09ed9 100644 --- a/man/intersection.igraph.Rd +++ b/man/intersection.igraph.Rd @@ -74,6 +74,7 @@ Other functions for manipulating graph structure: \code{\link{edge}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/join.Rd b/man/join.Rd new file mode 100644 index 00000000000..ce4a88adf4e --- /dev/null +++ b/man/join.Rd @@ -0,0 +1,113 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/operators.R +\name{join} +\alias{join} +\alias{\%j\%} +\title{Join of two graphs} +\usage{ +join(g1, g2) + +x \%j\% y +} +\arguments{ +\item{g1, g2}{Graph objects.} +} +\value{ +A new graph object. +} +\description{ +The join of two graphs is created by connecting all vertices from +the first graph to all vertices in the second graph. +} +\details{ +\code{join()} creates the join of two graphs. The graphs must be disjoint, +i.e., have distinct vertex sets. First the vertices of the second graph will +be relabeled with new vertex IDs, then the union of the two graphs is formed. +Finally, all vertices from the first graph will be connected to all vertices +from the second graph. If the two graphs have |V1| and |V2| vertices and +|E1| and |E2| edges respectively, then the new graph will have |V1|+|V2| +vertices and |E1|+|E2|+|V1|*|V2| edges. This function can also be used via +the \verb{\%j\%} operator. + +The vertex ordering of the graphs is preserved. In other words, the vertex +IDs of the first graph map to identical values in the new graph, while the +vertex IDs of the second graph map to IDs incremented by the vertex count +of the first graph. + +Both graphs need to have the same directedness, i.e. either both directed or +both undirected. If both graphs are directed, then for each pair of vertices +v, u in graphs G1, G2 we add edges (v, u) and (u, v) to maintain completeness. + +Note that the current version of this function cannot handle graph, vertex +and edge attributes; they will be lost in the result. + +An error is generated if some input graphs are directed and others are +undirected. +} +\examples{ + +## A star and a ring +g1 <- make_star(10, mode = "undirected") +g2 <- make_ring(5) +print_all(g1 \%j\% g2) +} +\seealso{ +Other functions for manipulating graph structure: +\code{\link{+.igraph}()}, +\code{\link{add_edges}()}, +\code{\link{add_vertices}()}, +\code{\link{complementer}()}, +\code{\link{compose}()}, +\code{\link{connect}()}, +\code{\link{contract}()}, +\code{\link{delete_edges}()}, +\code{\link{delete_vertices}()}, +\code{\link{difference}()}, +\code{\link{difference.igraph}()}, +\code{\link{disjoint_union}()}, +\code{\link{edge}()}, +\code{\link{igraph-minus}}, +\code{\link{intersection}()}, +\code{\link{intersection.igraph}()}, +\code{\link{path}()}, +\code{\link{permute}()}, +\code{\link{rep.igraph}()}, +\code{\link{reverse_edges}()}, +\code{\link{simplify}()}, +\code{\link{union}()}, +\code{\link{union.igraph}()}, +\code{\link{vertex}()} + +Other functions for manipulating graph structure: +\code{\link{+.igraph}()}, +\code{\link{add_edges}()}, +\code{\link{add_vertices}()}, +\code{\link{complementer}()}, +\code{\link{compose}()}, +\code{\link{connect}()}, +\code{\link{contract}()}, +\code{\link{delete_edges}()}, +\code{\link{delete_vertices}()}, +\code{\link{difference}()}, +\code{\link{difference.igraph}()}, +\code{\link{disjoint_union}()}, +\code{\link{edge}()}, +\code{\link{igraph-minus}}, +\code{\link{intersection}()}, +\code{\link{intersection.igraph}()}, +\code{\link{path}()}, +\code{\link{permute}()}, +\code{\link{rep.igraph}()}, +\code{\link{reverse_edges}()}, +\code{\link{simplify}()}, +\code{\link{union}()}, +\code{\link{union.igraph}()}, +\code{\link{vertex}()} +} +\author{ +Gabor Csardi \email{csardi.gabor@gmail.com} +} +\concept{functions for manipulating graph structure} +\keyword{graphs} +\section{Related documentation in the C library}{\href{https://igraph.org/c/html/latest/igraph-Operators.html#igraph_join}{\code{join()}}.} + diff --git a/man/path.Rd b/man/path.Rd index 0e20b51dfe8..3f6feb03a4f 100644 --- a/man/path.Rd +++ b/man/path.Rd @@ -62,6 +62,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, \code{\link{reverse_edges}()}, diff --git a/man/permute.Rd b/man/permute.Rd index 2dab221f426..4c5518c148e 100644 --- a/man/permute.Rd +++ b/man/permute.Rd @@ -65,6 +65,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{rep.igraph}()}, \code{\link{reverse_edges}()}, diff --git a/man/plus-.igraph.Rd b/man/plus-.igraph.Rd index cf500e99ce9..f6edc9aad05 100644 --- a/man/plus-.igraph.Rd +++ b/man/plus-.igraph.Rd @@ -118,6 +118,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/rep.igraph.Rd b/man/rep.igraph.Rd index 6fb7562540b..9d88e9af9da 100644 --- a/man/rep.igraph.Rd +++ b/man/rep.igraph.Rd @@ -46,6 +46,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{reverse_edges}()}, diff --git a/man/reverse_edges.Rd b/man/reverse_edges.Rd index c4afc1e66c6..504e58c29f1 100644 --- a/man/reverse_edges.Rd +++ b/man/reverse_edges.Rd @@ -49,6 +49,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/simplify.Rd b/man/simplify.Rd index 9ebaa39c3ca..3dd112c021e 100644 --- a/man/simplify.Rd +++ b/man/simplify.Rd @@ -88,6 +88,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/union.Rd b/man/union.Rd index 91bfdcc7545..3a2e737a451 100644 --- a/man/union.Rd +++ b/man/union.Rd @@ -39,6 +39,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/union.igraph.Rd b/man/union.igraph.Rd index 67973087403..07512bb9289 100644 --- a/man/union.igraph.Rd +++ b/man/union.igraph.Rd @@ -72,6 +72,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/vertex.Rd b/man/vertex.Rd index 86c68845bda..5286e34c104 100644 --- a/man/vertex.Rd +++ b/man/vertex.Rd @@ -55,6 +55,7 @@ Other functions for manipulating graph structure: \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, +\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/tests/testthat/test-operators.R b/tests/testthat/test-operators.R index afa804d5f16..7beedc74d40 100644 --- a/tests/testthat/test-operators.R +++ b/tests/testthat/test-operators.R @@ -66,6 +66,64 @@ test_that("disjoint_union() does not convert vertex types", { expect_s3_class(vertex_attr(u, "date"), c("POSIXct", "POSIXt")) }) +test_that("join() works", { + # Test basic join of undirected graphs + g1 <- make_ring(5) + g2 <- make_ring(3) + gj <- join(g1, g2) + + # Check vertex and edge counts + expect_vcount(gj, 8) # 5 + 3 + expect_ecount(gj, 23) # 5 + 3 + 5*3 = 23 + + # Check that original edges are preserved + # Edges from g1 should be 1-2, 2-3, 3-4, 4-5, 5-1 + # Edges from g2 should be 6-7, 7-8, 8-6 (shifted by vcount(g1)=5) + # Plus all cross edges between vertices 1-5 and vertices 6-8 + + # Test with operator + gj2 <- g1 %j% g2 + expect_equal(vcount(gj2), 8) + expect_equal(ecount(gj2), 23) + + # Test directed graphs + g1_dir <- make_ring(4, directed = TRUE) + g2_dir <- make_ring(3, directed = TRUE) + gj_dir <- join(g1_dir, g2_dir) + + expect_vcount(gj_dir, 7) # 4 + 3 + # For directed: original edges + 2 * v1 * v2 = 4 + 3 + 2*4*3 = 31 + expect_ecount(gj_dir, 31) + + # Test mixed directedness should error + expect_error( + join(g1, g1_dir), + "Cannot create join" + ) +}) + +test_that("join() preserves vertex ordering", { + g1 <- make_ring(3) + g2 <- make_ring(2) + + gj <- join(g1, g2) + + # Check that edges from g1 are preserved + el1 <- as_edgelist(g1) + el_joined <- as_edgelist(gj) + + # First graph edges should be in the result + expect_true(all(apply(el1, 1, function(row) { + any(apply(el_joined, 1, function(r) all(r == row))) + }))) + + # Second graph edges should be shifted by vcount(g1) + el2_shifted <- as_edgelist(g2) + vcount(g1) + expect_true(all(apply(el2_shifted, 1, function(row) { + any(apply(el_joined, 1, function(r) all(r == row))) + }))) +}) + test_that("intersection() works", { g1 <- make_ring(10) g2 <- make_star(11, center = 11, mode = "undirected") diff --git a/tests/testthat/testthat-problems.rds b/tests/testthat/testthat-problems.rds deleted file mode 100644 index 95cf1759297186292377247df7cb3d1a15c7620e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46380 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 Date: Sun, 26 Oct 2025 12:03:40 +0000 Subject: [PATCH 03/10] fix: Remove duplicate @family tag in join documentation Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 1 - man/join.Rd | 26 -------------------------- 2 files changed, 27 deletions(-) diff --git a/R/operators.R b/R/operators.R index 43c6a5d7d5b..d3e1d2f5371 100644 --- a/R/operators.R +++ b/R/operators.R @@ -354,7 +354,6 @@ join <- function(g1, g2) { join_impl(g1, g2) } -#' @family functions for manipulating graph structure #' @export #' @rdname join "%j%" <- function(x, y) { diff --git a/man/join.Rd b/man/join.Rd index ce4a88adf4e..b7932639a3a 100644 --- a/man/join.Rd +++ b/man/join.Rd @@ -52,32 +52,6 @@ g2 <- make_ring(5) print_all(g1 \%j\% g2) } \seealso{ -Other functions for manipulating graph structure: -\code{\link{+.igraph}()}, -\code{\link{add_edges}()}, -\code{\link{add_vertices}()}, -\code{\link{complementer}()}, -\code{\link{compose}()}, -\code{\link{connect}()}, -\code{\link{contract}()}, -\code{\link{delete_edges}()}, -\code{\link{delete_vertices}()}, -\code{\link{difference}()}, -\code{\link{difference.igraph}()}, -\code{\link{disjoint_union}()}, -\code{\link{edge}()}, -\code{\link{igraph-minus}}, -\code{\link{intersection}()}, -\code{\link{intersection.igraph}()}, -\code{\link{path}()}, -\code{\link{permute}()}, -\code{\link{rep.igraph}()}, -\code{\link{reverse_edges}()}, -\code{\link{simplify}()}, -\code{\link{union}()}, -\code{\link{union.igraph}()}, -\code{\link{vertex}()} - Other functions for manipulating graph structure: \code{\link{+.igraph}()}, \code{\link{add_edges}()}, From 343f2112dbafab0c4cab6fa38443e705a5a63738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 26 Oct 2025 18:22:26 +0100 Subject: [PATCH 04/10] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 220e6421b1b..dd12d586c35 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,3 @@ cran /src/*.d /src/symbols.rds /covr -tests/testthat/testthat-problems.rds From d16997372e4a7422c89b9f8e835b909b943ce474 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 17:35:48 +0000 Subject: [PATCH 05/10] docs: Use math notation for formulas in join() documentation Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 6 +++--- man/join.Rd | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/operators.R b/R/operators.R index d3e1d2f5371..6c3c4c4fc77 100644 --- a/R/operators.R +++ b/R/operators.R @@ -311,9 +311,9 @@ disjoint_union <- function(...) { #' i.e., have distinct vertex sets. First the vertices of the second graph will #' be relabeled with new vertex IDs, then the union of the two graphs is formed. #' Finally, all vertices from the first graph will be connected to all vertices -#' from the second graph. If the two graphs have |V1| and |V2| vertices and -#' |E1| and |E2| edges respectively, then the new graph will have |V1|+|V2| -#' vertices and |E1|+|E2|+|V1|*|V2| edges. This function can also be used via +#' from the second graph. If the two graphs have \eqn{|V_1|} and \eqn{|V_2|} vertices and +#' \eqn{|E_1|} and \eqn{|E_2|} edges respectively, then the new graph will have \eqn{|V_1|+|V_2|} +#' vertices and \eqn{|E_1|+|E_2|+|V_1| \times |V_2|} edges. This function can also be used via #' the `%j%` operator. #' #' The vertex ordering of the graphs is preserved. In other words, the vertex diff --git a/man/join.Rd b/man/join.Rd index b7932639a3a..b4a9e4e77d3 100644 --- a/man/join.Rd +++ b/man/join.Rd @@ -24,9 +24,9 @@ the first graph to all vertices in the second graph. i.e., have distinct vertex sets. First the vertices of the second graph will be relabeled with new vertex IDs, then the union of the two graphs is formed. Finally, all vertices from the first graph will be connected to all vertices -from the second graph. If the two graphs have |V1| and |V2| vertices and -|E1| and |E2| edges respectively, then the new graph will have |V1|+|V2| -vertices and |E1|+|E2|+|V1|*|V2| edges. This function can also be used via +from the second graph. If the two graphs have \eqn{|V_1|} and \eqn{|V_2|} vertices and +\eqn{|E_1|} and \eqn{|E_2|} edges respectively, then the new graph will have \eqn{|V_1|+|V_2|} +vertices and \eqn{|E_1|+|E_2|+|V_1| \times |V_2|} edges. This function can also be used via the \verb{\%j\%} operator. The vertex ordering of the graphs is preserved. In other words, the vertex From e49da0ad3ca6aa8c383650f1fb205858043fb12e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:12:42 +0000 Subject: [PATCH 06/10] fix: Use named arguments when calling join_impl() Align with project convention to use named arguments for all _impl function calls. Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 2 +- src/cpp11.dd | 252 ++++++++++++++++++++++++++++++++++++++++ src/rinterface.dd | 108 +++++++++++++++++ src/rinterface_extra.dd | 111 ++++++++++++++++++ 4 files changed, 472 insertions(+), 1 deletion(-) diff --git a/R/operators.R b/R/operators.R index 2937521a77f..577ef73d041 100644 --- a/R/operators.R +++ b/R/operators.R @@ -351,7 +351,7 @@ join <- function(g1, g2) { ensure_igraph(g2) on.exit(.Call(R_igraph_finalizer)) - join_impl(g1, g2) + join_impl(left = g1, right = g2) } #' @export diff --git a/src/cpp11.dd b/src/cpp11.dd index 9abbae1fcad..de42af19ba0 100644 --- a/src/cpp11.dd +++ b/src/cpp11.dd @@ -2,3 +2,255 @@ cpp11.o: \ cpp11.cpp \ igraph_types.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/R.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/altrep.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/as.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/attribute_proxy.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/data_frame.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/declarations.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/doubles.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/environment.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/external_pointer.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/function.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/integers.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/list.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/list_of.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/logicals.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/matrix.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/named_arg.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/protect.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/r_bool.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/r_string.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/r_vector.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/raws.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/sexp.hpp \ + /home/runner/work/_temp/Library/cpp11/include/cpp11/strings.hpp \ + /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Visibility.h \ + /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.1/lib/R/include/Rconfig.h \ + /opt/R/4.5.1/lib/R/include/Rinternals.h \ + /opt/R/4.5.1/lib/R/include/Rversion.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/c++/13/algorithm \ + /usr/include/c++/13/backward/auto_ptr.h \ + /usr/include/c++/13/backward/binders.h \ + /usr/include/c++/13/bits/algorithmfwd.h \ + /usr/include/c++/13/bits/align.h \ + /usr/include/c++/13/bits/alloc_traits.h \ + /usr/include/c++/13/bits/allocated_ptr.h \ + /usr/include/c++/13/bits/allocator.h \ + /usr/include/c++/13/bits/atomic_base.h \ + /usr/include/c++/13/bits/atomic_lockfree_defines.h \ + /usr/include/c++/13/bits/basic_ios.h \ + /usr/include/c++/13/bits/basic_ios.tcc \ + /usr/include/c++/13/bits/basic_string.h \ + /usr/include/c++/13/bits/basic_string.tcc \ + /usr/include/c++/13/bits/char_traits.h \ + /usr/include/c++/13/bits/charconv.h \ + /usr/include/c++/13/bits/concept_check.h \ + /usr/include/c++/13/bits/cpp_type_traits.h \ + /usr/include/c++/13/bits/cxxabi_forced.h \ + /usr/include/c++/13/bits/cxxabi_init_exception.h \ + /usr/include/c++/13/bits/exception.h \ + /usr/include/c++/13/bits/exception_defines.h \ + /usr/include/c++/13/bits/exception_ptr.h \ + /usr/include/c++/13/bits/functexcept.h \ + /usr/include/c++/13/bits/functional_hash.h \ + /usr/include/c++/13/bits/hash_bytes.h \ + /usr/include/c++/13/bits/locale_classes.h \ + /usr/include/c++/13/bits/locale_classes.tcc \ + /usr/include/c++/13/bits/locale_facets.h \ + /usr/include/c++/13/bits/locale_facets.tcc \ + /usr/include/c++/13/bits/localefwd.h \ + /usr/include/c++/13/bits/memory_resource.h \ + /usr/include/c++/13/bits/memoryfwd.h \ + /usr/include/c++/13/bits/move.h \ + /usr/include/c++/13/bits/nested_exception.h \ + /usr/include/c++/13/bits/new_allocator.h \ + /usr/include/c++/13/bits/ostream.tcc \ + /usr/include/c++/13/bits/ostream_insert.h \ + /usr/include/c++/13/bits/postypes.h \ + /usr/include/c++/13/bits/predefined_ops.h \ + /usr/include/c++/13/bits/ptr_traits.h \ + /usr/include/c++/13/bits/range_access.h \ + /usr/include/c++/13/bits/refwrap.h \ + /usr/include/c++/13/bits/requires_hosted.h \ + /usr/include/c++/13/bits/shared_ptr.h \ + /usr/include/c++/13/bits/shared_ptr_atomic.h \ + /usr/include/c++/13/bits/shared_ptr_base.h \ + /usr/include/c++/13/bits/specfun.h \ + /usr/include/c++/13/bits/std_abs.h \ + /usr/include/c++/13/bits/stl_algobase.h \ + /usr/include/c++/13/bits/stl_bvector.h \ + /usr/include/c++/13/bits/stl_construct.h \ + /usr/include/c++/13/bits/stl_function.h \ + /usr/include/c++/13/bits/stl_heap.h \ + /usr/include/c++/13/bits/stl_iterator.h \ + /usr/include/c++/13/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/13/bits/stl_iterator_base_types.h \ + /usr/include/c++/13/bits/stl_pair.h \ + /usr/include/c++/13/bits/stl_raw_storage_iter.h \ + /usr/include/c++/13/bits/stl_vector.h \ + /usr/include/c++/13/bits/stream_iterator.h \ + /usr/include/c++/13/bits/streambuf.tcc \ + /usr/include/c++/13/bits/streambuf_iterator.h \ + /usr/include/c++/13/bits/string_view.tcc \ + /usr/include/c++/13/bits/uniform_int_dist.h \ + /usr/include/c++/13/bits/uses_allocator.h \ + /usr/include/c++/13/bits/uses_allocator_args.h \ + /usr/include/c++/13/bits/vector.tcc \ + /usr/include/c++/13/cctype \ + /usr/include/c++/13/clocale \ + /usr/include/c++/13/compare \ + /usr/include/c++/13/csetjmp \ + /usr/include/c++/13/cstdint \ + /usr/include/c++/13/cstdio \ + /usr/include/c++/13/cstring \ + /usr/include/c++/13/debug/assertions.h \ + /usr/include/c++/13/ext/aligned_buffer.h \ + /usr/include/c++/13/ext/alloc_traits.h \ + /usr/include/c++/13/ext/atomicity.h \ + /usr/include/c++/13/ext/concurrence.h \ + /usr/include/c++/13/ext/numeric_traits.h \ + /usr/include/c++/13/ext/string_conversions.h \ + /usr/include/c++/13/ext/type_traits.h \ + /usr/include/c++/13/initializer_list \ + /usr/include/c++/13/limits \ + /usr/include/c++/13/math.h \ + /usr/include/c++/13/memory \ + /usr/include/c++/13/ostream \ + /usr/include/c++/13/pstl/execution_defs.h \ + /usr/include/c++/13/pstl/glue_algorithm_defs.h \ + /usr/include/c++/13/pstl/glue_memory_defs.h \ + /usr/include/c++/13/pstl/pstl_config.h \ + /usr/include/c++/13/streambuf \ + /usr/include/c++/13/string \ + /usr/include/c++/13/system_error \ + /usr/include/c++/13/tr1/bessel_function.tcc \ + /usr/include/c++/13/tr1/beta_function.tcc \ + /usr/include/c++/13/tr1/ell_integral.tcc \ + /usr/include/c++/13/tr1/exp_integral.tcc \ + /usr/include/c++/13/tr1/hypergeometric.tcc \ + /usr/include/c++/13/tr1/legendre_function.tcc \ + /usr/include/c++/13/tr1/modified_bessel_func.tcc \ + /usr/include/c++/13/tr1/poly_hermite.tcc \ + /usr/include/c++/13/tr1/poly_laguerre.tcc \ + /usr/include/c++/13/tr1/riemann_zeta.tcc \ + /usr/include/c++/13/tr1/special_function_util.h \ + /usr/include/c++/13/utility \ + /usr/include/c++/13/vector \ + /usr/include/errno.h \ + /usr/include/features-time64.h \ + /usr/include/inttypes.h \ + /usr/include/limits.h \ + /usr/include/linux/errno.h \ + /usr/include/linux/limits.h \ + /usr/include/pthread.h \ + /usr/include/wchar.h \ + /usr/include/wctype.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \ + /usr/include/x86_64-linux-gnu/bits/fp-fast.h \ + /usr/include/x86_64-linux-gnu/bits/fp-logb.h \ + /usr/include/x86_64-linux-gnu/bits/iscanonical.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/math-vector.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++allocator.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/c++locale.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/cpu_defines.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/ctype_base.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/ctype_inline.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/error_constants.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/13/bits/os_defines.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stdbool.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/stdint.h \ + /usr/lib/gcc/x86_64-linux-gnu/13/include/syslimits.h \ + vendor/cigraph/include/igraph_decls.h \ + vendor/cigraph/include/igraph_types.h \ + vendor/igraph_config.h \ diff --git a/src/rinterface.dd b/src/rinterface.dd index 4e60bfc2463..571daf68b19 100644 --- a/src/rinterface.dd +++ b/src/rinterface.dd @@ -2,3 +2,111 @@ rinterface.o: \ rinterface.c \ rinterface.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Constants.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.1/lib/R/include/R_ext/RS.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Random.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.1/lib/R/include/Rconfig.h \ + /opt/R/4.5.1/lib/R/include/Rdefines.h \ + /opt/R/4.5.1/lib/R/include/Rinternals.h \ + vendor/cigraph/include/igraph_adjlist.h \ + vendor/cigraph/include/igraph_arpack.h \ + vendor/cigraph/include/igraph_array.h \ + vendor/cigraph/include/igraph_array_pmt.h \ + vendor/cigraph/include/igraph_attributes.h \ + vendor/cigraph/include/igraph_attributes.h \ + vendor/cigraph/include/igraph_bipartite.h \ + vendor/cigraph/include/igraph_bitset.h \ + vendor/cigraph/include/igraph_bitset_list.h \ + vendor/cigraph/include/igraph_blas.h \ + vendor/cigraph/include/igraph_centrality.h \ + vendor/cigraph/include/igraph_cliques.h \ + vendor/cigraph/include/igraph_cocitation.h \ + vendor/cigraph/include/igraph_cohesive_blocks.h \ + vendor/cigraph/include/igraph_coloring.h \ + vendor/cigraph/include/igraph_community.h \ + vendor/cigraph/include/igraph_complex.h \ + vendor/cigraph/include/igraph_components.h \ + vendor/cigraph/include/igraph_constants.h \ + vendor/cigraph/include/igraph_constants.h \ + vendor/cigraph/include/igraph_constructors.h \ + vendor/cigraph/include/igraph_conversion.h \ + vendor/cigraph/include/igraph_cycles.h \ + vendor/cigraph/include/igraph_datatype.h \ + vendor/cigraph/include/igraph_datatype.h \ + vendor/cigraph/include/igraph_decls.h \ + vendor/cigraph/include/igraph_dqueue.h \ + vendor/cigraph/include/igraph_dqueue_pmt.h \ + vendor/cigraph/include/igraph_eigen.h \ + vendor/cigraph/include/igraph_embedding.h \ + vendor/cigraph/include/igraph_epidemics.h \ + vendor/cigraph/include/igraph_error.h \ + vendor/cigraph/include/igraph_error.h \ + vendor/cigraph/include/igraph_eulerian.h \ + vendor/cigraph/include/igraph_flow.h \ + vendor/cigraph/include/igraph_foreign.h \ + vendor/cigraph/include/igraph_games.h \ + vendor/cigraph/include/igraph_graph_list.h \ + vendor/cigraph/include/igraph_graphicality.h \ + vendor/cigraph/include/igraph_graphlets.h \ + vendor/cigraph/include/igraph_heap.h \ + vendor/cigraph/include/igraph_heap_pmt.h \ + vendor/cigraph/include/igraph_hrg.h \ + vendor/cigraph/include/igraph_interface.h \ + vendor/cigraph/include/igraph_interrupt.h \ + vendor/cigraph/include/igraph_iterators.h \ + vendor/cigraph/include/igraph_lapack.h \ + vendor/cigraph/include/igraph_layout.h \ + vendor/cigraph/include/igraph_lsap.h \ + vendor/cigraph/include/igraph_matching.h \ + vendor/cigraph/include/igraph_matrix.h \ + vendor/cigraph/include/igraph_matrix_list.h \ + vendor/cigraph/include/igraph_matrix_pmt.h \ + vendor/cigraph/include/igraph_microscopic_update.h \ + vendor/cigraph/include/igraph_mixing.h \ + vendor/cigraph/include/igraph_motifs.h \ + vendor/cigraph/include/igraph_neighborhood.h \ + vendor/cigraph/include/igraph_nongraph.h \ + vendor/cigraph/include/igraph_operators.h \ + vendor/cigraph/include/igraph_paths.h \ + vendor/cigraph/include/igraph_pmt.h \ + vendor/cigraph/include/igraph_pmt_off.h \ + vendor/cigraph/include/igraph_progress.h \ + vendor/cigraph/include/igraph_psumtree.h \ + vendor/cigraph/include/igraph_qsort.h \ + vendor/cigraph/include/igraph_random.h \ + vendor/cigraph/include/igraph_reachability.h \ + vendor/cigraph/include/igraph_scan.h \ + vendor/cigraph/include/igraph_separators.h \ + vendor/cigraph/include/igraph_sparsemat.h \ + vendor/cigraph/include/igraph_stack.h \ + vendor/cigraph/include/igraph_stack_pmt.h \ + vendor/cigraph/include/igraph_statusbar.h \ + vendor/cigraph/include/igraph_structural.h \ + vendor/cigraph/include/igraph_strvector.h \ + vendor/cigraph/include/igraph_strvector.h \ + vendor/cigraph/include/igraph_topology.h \ + vendor/cigraph/include/igraph_transitivity.h \ + vendor/cigraph/include/igraph_typed_list_pmt.h \ + vendor/cigraph/include/igraph_types.h \ + vendor/cigraph/include/igraph_types.h \ + vendor/cigraph/include/igraph_vector.h \ + vendor/cigraph/include/igraph_vector.h \ + vendor/cigraph/include/igraph_vector_list.h \ + vendor/cigraph/include/igraph_vector_pmt.h \ + vendor/cigraph/include/igraph_vector_ptr.h \ + vendor/cigraph/include/igraph_vector_type.h \ + vendor/cigraph/include/igraph_visitor.h \ + vendor/cigraph/src/graph/attributes.h \ + vendor/cigraph/src/graph/internal.h \ + vendor/igraph_config.h \ + vendor/igraph_export.h \ + vendor/igraph_version.h \ diff --git a/src/rinterface_extra.dd b/src/rinterface_extra.dd index 8abe00ad47b..926028a14e2 100644 --- a/src/rinterface_extra.dd +++ b/src/rinterface_extra.dd @@ -3,3 +3,114 @@ rinterface_extra.o: \ rinterface.h \ rinterface_extra.c \ rrandom.h \ + /opt/R/4.5.1/lib/R/include/R.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Altrep.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Constants.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.1/lib/R/include/R_ext/RS.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Random.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.1/lib/R/include/R_ext/Visibility.h \ + /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.1/lib/R/include/Rdefines.h \ + /opt/R/4.5.1/lib/R/include/Rinternals.h \ + /opt/R/4.5.1/lib/R/include/Rversion.h \ + vendor/cigraph/include/igraph_adjlist.h \ + vendor/cigraph/include/igraph_arpack.h \ + vendor/cigraph/include/igraph_array.h \ + vendor/cigraph/include/igraph_array_pmt.h \ + vendor/cigraph/include/igraph_attributes.h \ + vendor/cigraph/include/igraph_attributes.h \ + vendor/cigraph/include/igraph_bipartite.h \ + vendor/cigraph/include/igraph_bitset.h \ + vendor/cigraph/include/igraph_bitset_list.h \ + vendor/cigraph/include/igraph_blas.h \ + vendor/cigraph/include/igraph_centrality.h \ + vendor/cigraph/include/igraph_cliques.h \ + vendor/cigraph/include/igraph_cocitation.h \ + vendor/cigraph/include/igraph_cohesive_blocks.h \ + vendor/cigraph/include/igraph_coloring.h \ + vendor/cigraph/include/igraph_community.h \ + vendor/cigraph/include/igraph_complex.h \ + vendor/cigraph/include/igraph_components.h \ + vendor/cigraph/include/igraph_constants.h \ + vendor/cigraph/include/igraph_constants.h \ + vendor/cigraph/include/igraph_constructors.h \ + vendor/cigraph/include/igraph_conversion.h \ + vendor/cigraph/include/igraph_cycles.h \ + vendor/cigraph/include/igraph_datatype.h \ + vendor/cigraph/include/igraph_datatype.h \ + vendor/cigraph/include/igraph_decls.h \ + vendor/cigraph/include/igraph_dqueue.h \ + vendor/cigraph/include/igraph_dqueue_pmt.h \ + vendor/cigraph/include/igraph_eigen.h \ + vendor/cigraph/include/igraph_embedding.h \ + vendor/cigraph/include/igraph_epidemics.h \ + vendor/cigraph/include/igraph_error.h \ + vendor/cigraph/include/igraph_error.h \ + vendor/cigraph/include/igraph_eulerian.h \ + vendor/cigraph/include/igraph_flow.h \ + vendor/cigraph/include/igraph_foreign.h \ + vendor/cigraph/include/igraph_games.h \ + vendor/cigraph/include/igraph_graph_list.h \ + vendor/cigraph/include/igraph_graphicality.h \ + vendor/cigraph/include/igraph_graphlets.h \ + vendor/cigraph/include/igraph_heap.h \ + vendor/cigraph/include/igraph_heap_pmt.h \ + vendor/cigraph/include/igraph_hrg.h \ + vendor/cigraph/include/igraph_interface.h \ + vendor/cigraph/include/igraph_interrupt.h \ + vendor/cigraph/include/igraph_iterators.h \ + vendor/cigraph/include/igraph_lapack.h \ + vendor/cigraph/include/igraph_layout.h \ + vendor/cigraph/include/igraph_lsap.h \ + vendor/cigraph/include/igraph_matching.h \ + vendor/cigraph/include/igraph_matrix.h \ + vendor/cigraph/include/igraph_matrix_list.h \ + vendor/cigraph/include/igraph_matrix_pmt.h \ + vendor/cigraph/include/igraph_microscopic_update.h \ + vendor/cigraph/include/igraph_mixing.h \ + vendor/cigraph/include/igraph_motifs.h \ + vendor/cigraph/include/igraph_neighborhood.h \ + vendor/cigraph/include/igraph_nongraph.h \ + vendor/cigraph/include/igraph_operators.h \ + vendor/cigraph/include/igraph_paths.h \ + vendor/cigraph/include/igraph_pmt.h \ + vendor/cigraph/include/igraph_pmt_off.h \ + vendor/cigraph/include/igraph_progress.h \ + vendor/cigraph/include/igraph_psumtree.h \ + vendor/cigraph/include/igraph_qsort.h \ + vendor/cigraph/include/igraph_random.h \ + vendor/cigraph/include/igraph_reachability.h \ + vendor/cigraph/include/igraph_scan.h \ + vendor/cigraph/include/igraph_separators.h \ + vendor/cigraph/include/igraph_sparsemat.h \ + vendor/cigraph/include/igraph_stack.h \ + vendor/cigraph/include/igraph_stack_pmt.h \ + vendor/cigraph/include/igraph_statusbar.h \ + vendor/cigraph/include/igraph_structural.h \ + vendor/cigraph/include/igraph_strvector.h \ + vendor/cigraph/include/igraph_strvector.h \ + vendor/cigraph/include/igraph_topology.h \ + vendor/cigraph/include/igraph_transitivity.h \ + vendor/cigraph/include/igraph_typed_list_pmt.h \ + vendor/cigraph/include/igraph_types.h \ + vendor/cigraph/include/igraph_types.h \ + vendor/cigraph/include/igraph_vector.h \ + vendor/cigraph/include/igraph_vector.h \ + vendor/cigraph/include/igraph_vector_list.h \ + vendor/cigraph/include/igraph_vector_pmt.h \ + vendor/cigraph/include/igraph_vector_ptr.h \ + vendor/cigraph/include/igraph_vector_type.h \ + vendor/cigraph/include/igraph_visitor.h \ + vendor/cigraph/src/graph/attributes.h \ + vendor/cigraph/src/graph/internal.h \ + vendor/igraph_config.h \ + vendor/igraph_export.h \ + vendor/igraph_version.h \ From d8582cb4f3a5cef4129730e8fcc2ec5c17b05d7d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Oct 2025 00:11:08 +0000 Subject: [PATCH 07/10] docs: Add missing x,y parameters documentation for %j% operator Fix R CMD check WARNING by documenting the x and y parameters used by the %j% operator. Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 1 + man/join.Rd | 2 ++ 2 files changed, 3 insertions(+) diff --git a/R/operators.R b/R/operators.R index 577ef73d041..ebb4dfecd50 100644 --- a/R/operators.R +++ b/R/operators.R @@ -333,6 +333,7 @@ disjoint_union <- function(...) { #' #' @aliases %j% #' @param g1,g2 Graph objects. +#' @param x,y Graph objects. #' @return A new graph object. #' @author Gabor Csardi \email{csardi.gabor@@gmail.com} #' @export diff --git a/man/join.Rd b/man/join.Rd index b4a9e4e77d3..70b1e3d741f 100644 --- a/man/join.Rd +++ b/man/join.Rd @@ -11,6 +11,8 @@ x \%j\% y } \arguments{ \item{g1, g2}{Graph objects.} + +\item{x, y}{Graph objects.} } \value{ A new graph object. From ce0cce78afd2e1648da33da8559df7b01222f7e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 11:11:05 +0000 Subject: [PATCH 08/10] refactor: Rename join() to graph_join() Rename the function from join() to graph_join() to avoid name conflicts with other packages and make the purpose clearer. The %j% operator is retained for convenience. Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- NAMESPACE | 2 +- R/operators.R | 8 ++++---- man/add_edges.Rd | 2 +- man/add_vertices.Rd | 2 +- man/complementer.Rd | 2 +- man/compose.Rd | 2 +- man/contract.Rd | 2 +- man/delete_edges.Rd | 2 +- man/delete_vertices.Rd | 2 +- man/difference.Rd | 2 +- man/difference.igraph.Rd | 2 +- man/disjoint_union.Rd | 2 +- man/edge.Rd | 2 +- man/ego.Rd | 2 +- man/{join.Rd => graph_join.Rd} | 9 +++++---- man/igraph-minus.Rd | 2 +- man/intersection.Rd | 2 +- man/intersection.igraph.Rd | 2 +- man/path.Rd | 2 +- man/permute.Rd | 2 +- man/plus-.igraph.Rd | 2 +- man/rep.igraph.Rd | 2 +- man/reverse_edges.Rd | 2 +- man/simplify.Rd | 2 +- man/transitive_closure.Rd | 1 + man/union.Rd | 2 +- man/union.igraph.Rd | 2 +- man/vertex.Rd | 2 +- src/cpp11.dd | 26 ++++++++++++------------ src/rinterface.dd | 30 +++++++++++++-------------- src/rinterface_extra.dd | 36 ++++++++++++++++----------------- tests/testthat/test-operators.R | 12 +++++------ 32 files changed, 87 insertions(+), 85 deletions(-) rename man/{join.Rd => graph_join.Rd} (94%) diff --git a/NAMESPACE b/NAMESPACE index 0a558846b47..060181fb210 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -472,6 +472,7 @@ export(graph_from_isomorphism_class) export(graph_from_lcf) export(graph_from_literal) export(graph_id) +export(graph_join) export(graph_version) export(graphlet_basis) export(graphlet_proj) @@ -585,7 +586,6 @@ export(isomorphism_class) export(isomorphisms) export(ivs) export(ivs_size) -export(join) export(k.regular.game) export(k_shortest_paths) export(kautz_graph) diff --git a/R/operators.R b/R/operators.R index 57e160d8225..258e8b74eb7 100644 --- a/R/operators.R +++ b/R/operators.R @@ -307,7 +307,7 @@ disjoint_union <- function(...) { #' The join of two graphs is created by connecting all vertices from #' the first graph to all vertices in the second graph. #' -#' `join()` creates the join of two graphs. The graphs must be disjoint, +#' `graph_join()` creates the join of two graphs. The graphs must be disjoint, #' i.e., have distinct vertex sets. First the vertices of the second graph will #' be relabeled with new vertex IDs, then the union of the two graphs is formed. #' Finally, all vertices from the first graph will be connected to all vertices @@ -347,7 +347,7 @@ disjoint_union <- function(...) { #' print_all(g1 %j% g2) #' @export #' @cdocs igraph_join -join <- function(g1, g2) { +graph_join <- function(g1, g2) { ensure_igraph(g1) ensure_igraph(g2) @@ -356,9 +356,9 @@ join <- function(g1, g2) { } #' @export -#' @rdname join +#' @rdname graph_join "%j%" <- function(x, y) { - join(x, y) + graph_join(x, y) } .igraph.graph.union.or.intersection <- function( diff --git a/man/add_edges.Rd b/man/add_edges.Rd index e365a3b968d..a7871920a37 100644 --- a/man/add_edges.Rd +++ b/man/add_edges.Rd @@ -60,10 +60,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/add_vertices.Rd b/man/add_vertices.Rd index e198288e1bf..19443f04f57 100644 --- a/man/add_vertices.Rd +++ b/man/add_vertices.Rd @@ -55,10 +55,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/complementer.Rd b/man/complementer.Rd index 16898443f24..67a81485751 100644 --- a/man/complementer.Rd +++ b/man/complementer.Rd @@ -54,10 +54,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/compose.Rd b/man/compose.Rd index fb65c082ad0..c915f3e71cf 100644 --- a/man/compose.Rd +++ b/man/compose.Rd @@ -84,10 +84,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/contract.Rd b/man/contract.Rd index 335df7e8253..cbefaec391f 100644 --- a/man/contract.Rd +++ b/man/contract.Rd @@ -58,10 +58,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/delete_edges.Rd b/man/delete_edges.Rd index 40141592c89..82b92a23e12 100644 --- a/man/delete_edges.Rd +++ b/man/delete_edges.Rd @@ -47,10 +47,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/delete_vertices.Rd b/man/delete_vertices.Rd index 810a4ca6248..4328d098480 100644 --- a/man/delete_vertices.Rd +++ b/man/delete_vertices.Rd @@ -42,10 +42,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/difference.Rd b/man/difference.Rd index 4f5b20fcb51..112a702848a 100644 --- a/man/difference.Rd +++ b/man/difference.Rd @@ -35,10 +35,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/difference.igraph.Rd b/man/difference.igraph.Rd index 3318c8f7029..2847e946b83 100644 --- a/man/difference.igraph.Rd +++ b/man/difference.igraph.Rd @@ -73,10 +73,10 @@ Other functions for manipulating graph structure: \code{\link{difference}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/disjoint_union.Rd b/man/disjoint_union.Rd index a4fe1e2fdc5..d61f23ab792 100644 --- a/man/disjoint_union.Rd +++ b/man/disjoint_union.Rd @@ -65,10 +65,10 @@ Other functions for manipulating graph structure: \code{\link{difference}()}, \code{\link{difference.igraph}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/edge.Rd b/man/edge.Rd index c29bb8fb3ac..ac504febe4a 100644 --- a/man/edge.Rd +++ b/man/edge.Rd @@ -64,10 +64,10 @@ Other functions for manipulating graph structure: \code{\link{difference}()}, \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/ego.Rd b/man/ego.Rd index 3d8940a4aef..616862a879f 100644 --- a/man/ego.Rd +++ b/man/ego.Rd @@ -163,10 +163,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/join.Rd b/man/graph_join.Rd similarity index 94% rename from man/join.Rd rename to man/graph_join.Rd index 70b1e3d741f..db6d63076fa 100644 --- a/man/join.Rd +++ b/man/graph_join.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/operators.R -\name{join} -\alias{join} +\name{graph_join} +\alias{graph_join} \alias{\%j\%} \title{Join of two graphs} \usage{ -join(g1, g2) +graph_join(g1, g2) x \%j\% y } @@ -22,7 +22,7 @@ The join of two graphs is created by connecting all vertices from the first graph to all vertices in the second graph. } \details{ -\code{join()} creates the join of two graphs. The graphs must be disjoint, +\code{graph_join()} creates the join of two graphs. The graphs must be disjoint, i.e., have distinct vertex sets. First the vertices of the second graph will be relabeled with new vertex IDs, then the union of the two graphs is formed. Finally, all vertices from the first graph will be connected to all vertices @@ -76,6 +76,7 @@ Other functions for manipulating graph structure: \code{\link{rep.igraph}()}, \code{\link{reverse_edges}()}, \code{\link{simplify}()}, +\code{\link{transitive_closure}()}, \code{\link{union}()}, \code{\link{union.igraph}()}, \code{\link{vertex}()} diff --git a/man/igraph-minus.Rd b/man/igraph-minus.Rd index e86d9adae73..7286596a6c4 100644 --- a/man/igraph-minus.Rd +++ b/man/igraph-minus.Rd @@ -71,9 +71,9 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/intersection.Rd b/man/intersection.Rd index 78402a6b517..7b507283a3a 100644 --- a/man/intersection.Rd +++ b/man/intersection.Rd @@ -36,9 +36,9 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/intersection.igraph.Rd b/man/intersection.igraph.Rd index 6c7fd64ea8b..17c5f7f5d28 100644 --- a/man/intersection.igraph.Rd +++ b/man/intersection.igraph.Rd @@ -72,9 +72,9 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/path.Rd b/man/path.Rd index 96f3bfe9a75..bf1dba6602a 100644 --- a/man/path.Rd +++ b/man/path.Rd @@ -59,10 +59,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, \code{\link{reverse_edges}()}, diff --git a/man/permute.Rd b/man/permute.Rd index c3e99756ad2..ce6745ba86a 100644 --- a/man/permute.Rd +++ b/man/permute.Rd @@ -62,10 +62,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{rep.igraph}()}, \code{\link{reverse_edges}()}, diff --git a/man/plus-.igraph.Rd b/man/plus-.igraph.Rd index 5cda86b4b07..ba38a2457f7 100644 --- a/man/plus-.igraph.Rd +++ b/man/plus-.igraph.Rd @@ -115,10 +115,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/rep.igraph.Rd b/man/rep.igraph.Rd index 19283e14738..a3e99de320f 100644 --- a/man/rep.igraph.Rd +++ b/man/rep.igraph.Rd @@ -43,10 +43,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{reverse_edges}()}, diff --git a/man/reverse_edges.Rd b/man/reverse_edges.Rd index 4b68129fe56..d0b6d874290 100644 --- a/man/reverse_edges.Rd +++ b/man/reverse_edges.Rd @@ -46,10 +46,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/simplify.Rd b/man/simplify.Rd index 28d1b23c016..b4a171542d0 100644 --- a/man/simplify.Rd +++ b/man/simplify.Rd @@ -85,10 +85,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/transitive_closure.Rd b/man/transitive_closure.Rd index 01461959e4d..7b02ee54ae7 100644 --- a/man/transitive_closure.Rd +++ b/man/transitive_closure.Rd @@ -60,6 +60,7 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, diff --git a/man/union.Rd b/man/union.Rd index 2de8ea16250..10ff4bfd2fc 100644 --- a/man/union.Rd +++ b/man/union.Rd @@ -36,10 +36,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/union.igraph.Rd b/man/union.igraph.Rd index fae10e08fa2..cd359f2deea 100644 --- a/man/union.igraph.Rd +++ b/man/union.igraph.Rd @@ -69,10 +69,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/man/vertex.Rd b/man/vertex.Rd index 954c4b29278..9b9800c4e56 100644 --- a/man/vertex.Rd +++ b/man/vertex.Rd @@ -52,10 +52,10 @@ Other functions for manipulating graph structure: \code{\link{difference.igraph}()}, \code{\link{disjoint_union}()}, \code{\link{edge}()}, +\code{\link{graph_join}()}, \code{\link{igraph-minus}}, \code{\link{intersection}()}, \code{\link{intersection.igraph}()}, -\code{\link{join}()}, \code{\link{path}()}, \code{\link{permute}()}, \code{\link{rep.igraph}()}, diff --git a/src/cpp11.dd b/src/cpp11.dd index de42af19ba0..3eb6766ac81 100644 --- a/src/cpp11.dd +++ b/src/cpp11.dd @@ -26,19 +26,19 @@ cpp11.o: \ /home/runner/work/_temp/Library/cpp11/include/cpp11/raws.hpp \ /home/runner/work/_temp/Library/cpp11/include/cpp11/sexp.hpp \ /home/runner/work/_temp/Library/cpp11/include/cpp11/strings.hpp \ - /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Visibility.h \ - /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ - /opt/R/4.5.1/lib/R/include/Rconfig.h \ - /opt/R/4.5.1/lib/R/include/Rinternals.h \ - /opt/R/4.5.1/lib/R/include/Rversion.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Visibility.h \ + /opt/R/4.5.2/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.2/lib/R/include/Rconfig.h \ + /opt/R/4.5.2/lib/R/include/Rinternals.h \ + /opt/R/4.5.2/lib/R/include/Rversion.h \ /usr/include/asm-generic/errno.h \ /usr/include/c++/13/algorithm \ /usr/include/c++/13/backward/auto_ptr.h \ diff --git a/src/rinterface.dd b/src/rinterface.dd index 571daf68b19..81e02afe963 100644 --- a/src/rinterface.dd +++ b/src/rinterface.dd @@ -2,21 +2,21 @@ rinterface.o: \ rinterface.c \ rinterface.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Constants.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ - /opt/R/4.5.1/lib/R/include/R_ext/RS.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Random.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ - /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ - /opt/R/4.5.1/lib/R/include/Rconfig.h \ - /opt/R/4.5.1/lib/R/include/Rdefines.h \ - /opt/R/4.5.1/lib/R/include/Rinternals.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Constants.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.2/lib/R/include/R_ext/RS.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Random.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.2/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.2/lib/R/include/Rconfig.h \ + /opt/R/4.5.2/lib/R/include/Rdefines.h \ + /opt/R/4.5.2/lib/R/include/Rinternals.h \ vendor/cigraph/include/igraph_adjlist.h \ vendor/cigraph/include/igraph_arpack.h \ vendor/cigraph/include/igraph_array.h \ diff --git a/src/rinterface_extra.dd b/src/rinterface_extra.dd index 926028a14e2..ce88125123e 100644 --- a/src/rinterface_extra.dd +++ b/src/rinterface_extra.dd @@ -3,24 +3,24 @@ rinterface_extra.o: \ rinterface.h \ rinterface_extra.c \ rrandom.h \ - /opt/R/4.5.1/lib/R/include/R.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Altrep.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Arith.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Boolean.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Complex.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Constants.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Error.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Memory.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Print.h \ - /opt/R/4.5.1/lib/R/include/R_ext/RS.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Random.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Rdynload.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Utils.h \ - /opt/R/4.5.1/lib/R/include/R_ext/Visibility.h \ - /opt/R/4.5.1/lib/R/include/R_ext/libextern.h \ - /opt/R/4.5.1/lib/R/include/Rdefines.h \ - /opt/R/4.5.1/lib/R/include/Rinternals.h \ - /opt/R/4.5.1/lib/R/include/Rversion.h \ + /opt/R/4.5.2/lib/R/include/R.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Altrep.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Arith.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Boolean.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Complex.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Constants.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Error.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Memory.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Print.h \ + /opt/R/4.5.2/lib/R/include/R_ext/RS.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Random.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Rdynload.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Utils.h \ + /opt/R/4.5.2/lib/R/include/R_ext/Visibility.h \ + /opt/R/4.5.2/lib/R/include/R_ext/libextern.h \ + /opt/R/4.5.2/lib/R/include/Rdefines.h \ + /opt/R/4.5.2/lib/R/include/Rinternals.h \ + /opt/R/4.5.2/lib/R/include/Rversion.h \ vendor/cigraph/include/igraph_adjlist.h \ vendor/cigraph/include/igraph_arpack.h \ vendor/cigraph/include/igraph_array.h \ diff --git a/tests/testthat/test-operators.R b/tests/testthat/test-operators.R index 2e85500b707..503555a2a95 100644 --- a/tests/testthat/test-operators.R +++ b/tests/testthat/test-operators.R @@ -66,11 +66,11 @@ test_that("disjoint_union() does not convert vertex types", { expect_s3_class(vertex_attr(u, "date"), c("POSIXct", "POSIXt")) }) -test_that("join() works", { +test_that("graph_join() works", { # Test basic join of undirected graphs g1 <- make_ring(5) g2 <- make_ring(3) - gj <- join(g1, g2) + gj <- graph_join(g1, g2) # Check vertex and edge counts expect_vcount(gj, 8) # 5 + 3 @@ -89,7 +89,7 @@ test_that("join() works", { # Test directed graphs g1_dir <- make_ring(4, directed = TRUE) g2_dir <- make_ring(3, directed = TRUE) - gj_dir <- join(g1_dir, g2_dir) + gj_dir <- graph_join(g1_dir, g2_dir) expect_vcount(gj_dir, 7) # 4 + 3 # For directed: original edges + 2 * v1 * v2 = 4 + 3 + 2*4*3 = 31 @@ -97,16 +97,16 @@ test_that("join() works", { # Test mixed directedness should error expect_error( - join(g1, g1_dir), + graph_join(g1, g1_dir), "Cannot create join" ) }) -test_that("join() preserves vertex ordering", { +test_that("graph_join() preserves vertex ordering", { g1 <- make_ring(3) g2 <- make_ring(2) - gj <- join(g1, g2) + gj <- graph_join(g1, g2) # Check that edges from g1 are preserved el1 <- as_edgelist(g1) From 643da28ffc7358ebf173fcf88519c7409487ad84 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 16:47:58 +0000 Subject: [PATCH 09/10] docs: Add experimental badge and concept tag to graph_join() Add lifecycle experimental badge and @concept tag per AGENTS.md requirements for new functions. Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 3 +++ man/graph_join.Rd | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/R/operators.R b/R/operators.R index 31eab7b89f1..36adb78ff46 100644 --- a/R/operators.R +++ b/R/operators.R @@ -304,6 +304,8 @@ disjoint_union <- function(...) { #' Join of two graphs #' +#' `r lifecycle::badge("experimental")` +#' #' The join of two graphs is created by connecting all vertices from #' the first graph to all vertices in the second graph. #' @@ -338,6 +340,7 @@ disjoint_union <- function(...) { #' @author Gabor Csardi \email{csardi.gabor@@gmail.com} #' @export #' @keywords graphs +#' @concept graph_operators #' @family functions for manipulating graph structure #' @examples #' diff --git a/man/graph_join.Rd b/man/graph_join.Rd index db6d63076fa..eb0c3776f3e 100644 --- a/man/graph_join.Rd +++ b/man/graph_join.Rd @@ -18,10 +18,12 @@ x \%j\% y A new graph object. } \description{ -The join of two graphs is created by connecting all vertices from -the first graph to all vertices in the second graph. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} } \details{ +The join of two graphs is created by connecting all vertices from +the first graph to all vertices in the second graph. + \code{graph_join()} creates the join of two graphs. The graphs must be disjoint, i.e., have distinct vertex sets. First the vertices of the second graph will be relabeled with new vertex IDs, then the union of the two graphs is formed. @@ -85,6 +87,7 @@ Other functions for manipulating graph structure: Gabor Csardi \email{csardi.gabor@gmail.com} } \concept{functions for manipulating graph structure} +\concept{graph_operators} \keyword{graphs} \section{Related documentation in the C library}{\href{https://igraph.org/c/html/latest/igraph-Operators.html#igraph_join}{\code{join()}}.} From 1252ceb5435c4431c1fae5bcc5c228c29d77aecb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:31:58 +0000 Subject: [PATCH 10/10] Changes before error encountered Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com> --- R/operators.R | 3 +-- man/graph_join.Rd | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/R/operators.R b/R/operators.R index 36adb78ff46..9df4b057c90 100644 --- a/R/operators.R +++ b/R/operators.R @@ -325,7 +325,7 @@ disjoint_union <- function(...) { #' #' Both graphs need to have the same directedness, i.e. either both directed or #' both undirected. If both graphs are directed, then for each pair of vertices -#' v, u in graphs G1, G2 we add edges (v, u) and (u, v) to maintain completeness. +#' \eqn{v}, \eqn{u} in graphs \eqn{G_1}, \eqn{G_2} we add edges \eqn{(v, u)} and \eqn{(u, v)} to maintain completeness. #' #' Note that the current version of this function cannot handle graph, vertex #' and edge attributes; they will be lost in the result. @@ -354,7 +354,6 @@ graph_join <- function(g1, g2) { ensure_igraph(g1) ensure_igraph(g2) - on.exit(.Call(R_igraph_finalizer)) join_impl(left = g1, right = g2) } diff --git a/man/graph_join.Rd b/man/graph_join.Rd index eb0c3776f3e..fd96968bd08 100644 --- a/man/graph_join.Rd +++ b/man/graph_join.Rd @@ -40,7 +40,7 @@ of the first graph. Both graphs need to have the same directedness, i.e. either both directed or both undirected. If both graphs are directed, then for each pair of vertices -v, u in graphs G1, G2 we add edges (v, u) and (u, v) to maintain completeness. +\eqn{v}, \eqn{u} in graphs \eqn{G_1}, \eqn{G_2} we add edges \eqn{(v, u)} and \eqn{(u, v)} to maintain completeness. Note that the current version of this function cannot handle graph, vertex and edge attributes; they will be lost in the result.