Skip to content

Commit

Permalink
feat: max_degree() (#1403)
Browse files Browse the repository at this point in the history
  • Loading branch information
aviator-app[bot] committed Jul 2, 2024
2 parents e3196f1 + 1f52fbf commit 80b37bf
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 8 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ export(max_bipartite_match)
export(max_cardinality)
export(max_cliques)
export(max_cohesion)
export(max_degree)
export(max_flow)
export(maxcohesion)
export(maximal.cliques)
Expand Down
15 changes: 15 additions & 0 deletions R/aaa-auto.R
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,21 @@ reciprocity_impl <- function(graph, ignore.loops=TRUE, mode=c("default", "ratio"
res
}

maxdegree_impl <- function(graph, ..., v=V(graph), mode=c("all", "out", "in", "total"), loops=TRUE) {
# Argument checks
check_dots_empty()
ensure_igraph(graph)
v <- as_igraph_vs(graph, v)
mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L)
loops <- as.logical(loops)

on.exit( .Call(R_igraph_finalizer) )
# Function call
res <- .Call(R_igraph_maxdegree, graph, v-1, mode, loops)

res
}

density_impl <- function(graph, loops=FALSE) {
# Argument checks
ensure_igraph(graph)
Expand Down
12 changes: 10 additions & 2 deletions R/structural.properties.R
Original file line number Diff line number Diff line change
Expand Up @@ -595,14 +595,17 @@ mean_distance <- average_path_length_dijkstra_impl
#' @param normalized Logical scalar, whether to normalize the degree. If
#' `TRUE` then the result is divided by \eqn{n-1}, where \eqn{n} is the
#' number of vertices in the graph.
#' @param \dots Additional arguments to pass to `degree()`, e.g. `mode`
#' is useful but also `v` and `loops` make sense.
#' @inheritParams rlang::args_dots_empty
#' @return For `degree()` a numeric vector of the same length as argument
#' `v`.
#'
#' For `degree_distribution()` a numeric vector of the same length as the
#' maximum degree plus one. The first element is the relative frequency zero
#' degree vertices, the second vertices with degree one, etc.
#'
#' For `max_degree()`, the largest degree in the graph. When no vertices are
#' selected, or when the input is the null graph, zero is returned as this
#' is the smallest possible degree.
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
#' @keywords graphs
#' @family structural.properties
Expand All @@ -612,6 +615,7 @@ mean_distance <- average_path_length_dijkstra_impl
#' g <- make_ring(10)
#' degree(g)
#' g2 <- sample_gnp(1000, 10 / 1000)
#' max_degree(g2)
#' degree_distribution(g2)
#'
degree <- function(graph, v = V(graph),
Expand Down Expand Up @@ -641,6 +645,10 @@ degree <- function(graph, v = V(graph),
res
}

#' @rdname degree
#' @export
max_degree <- maxdegree_impl

#' @rdname degree
#' @param cumulative Logical; whether the cumulative degree distribution is to
#' be calculated.
Expand Down
19 changes: 16 additions & 3 deletions man/degree.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions man/degree.distribution.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ extern SEXP R_igraph_local_scan_k_ecount_them(SEXP, SEXP, SEXP, SEXP, SEXP);
extern SEXP R_igraph_local_scan_neighborhood_ecount(SEXP, SEXP, SEXP);
extern SEXP R_igraph_local_scan_subset_ecount(SEXP, SEXP, SEXP);
extern SEXP R_igraph_make_weak_ref(SEXP, SEXP, SEXP);
extern SEXP R_igraph_maxdegree(SEXP, SEXP, SEXP, SEXP);
extern SEXP R_igraph_maxflow(SEXP, SEXP, SEXP, SEXP);
extern SEXP R_igraph_maximal_cliques(SEXP, SEXP, SEXP, SEXP);
extern SEXP R_igraph_maximal_cliques_count(SEXP, SEXP, SEXP, SEXP);
Expand Down Expand Up @@ -787,6 +788,7 @@ static const R_CallMethodDef CallEntries[] = {
{"R_igraph_local_scan_neighborhood_ecount", (DL_FUNC) &R_igraph_local_scan_neighborhood_ecount, 3},
{"R_igraph_local_scan_subset_ecount", (DL_FUNC) &R_igraph_local_scan_subset_ecount, 3},
{"R_igraph_make_weak_ref", (DL_FUNC) &R_igraph_make_weak_ref, 3},
{"R_igraph_maxdegree", (DL_FUNC) &R_igraph_maxdegree, 4},
{"R_igraph_maxflow", (DL_FUNC) &R_igraph_maxflow, 4},
{"R_igraph_maximal_cliques", (DL_FUNC) &R_igraph_maximal_cliques, 4},
{"R_igraph_maximal_cliques_count", (DL_FUNC) &R_igraph_maximal_cliques_count, 4},
Expand Down
35 changes: 35 additions & 0 deletions src/rinterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -3936,6 +3936,41 @@ SEXP R_igraph_reciprocity(SEXP graph, SEXP ignore_loops, SEXP mode) {
return(r_result);
}

/*-------------------------------------------/
/ igraph_maxdegree /
/-------------------------------------------*/
SEXP R_igraph_maxdegree(SEXP graph, SEXP vids, SEXP mode, SEXP loops) {
/* Declarations */
igraph_t c_graph;
igraph_integer_t c_res;
igraph_vs_t c_vids;
igraph_neimode_t c_mode;
igraph_bool_t c_loops;
SEXP res;

SEXP r_result;
/* Convert input */
R_SEXP_to_igraph(graph, &c_graph);
c_res=0;
igraph_vector_int_t c_vids_data;
R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data);
c_mode = (igraph_neimode_t) Rf_asInteger(mode);
IGRAPH_R_CHECK_BOOL(loops);
c_loops = LOGICAL(loops)[0];
/* Call igraph */
IGRAPH_R_CHECK(igraph_maxdegree(&c_graph, &c_res, c_vids, c_mode, c_loops));

/* Convert output */
PROTECT(res=NEW_NUMERIC(1));
REAL(res)[0]=(double) c_res;
igraph_vector_int_destroy(&c_vids_data);
igraph_vs_destroy(&c_vids);
r_result = res;

UNPROTECT(1);
return(r_result);
}

/*-------------------------------------------/
/ igraph_density /
/-------------------------------------------*/
Expand Down
11 changes: 11 additions & 0 deletions tests/testthat/test-degree.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,14 @@ test_that("degree works", {
degree(g2, mode = "all", normalized = TRUE)
)
})

test_that("max_degree works", {
g <- make_graph(c(1,2, 2,2, 2,3), directed = TRUE)
expect_equal(max_degree(g), 4)
expect_equal(max_degree(g, mode = "out"), 2)
expect_equal(max_degree(g, loops = FALSE), 2)
expect_equal(max_degree(g, mode = "out", loops = FALSE), 1)
expect_equal(max_degree(g, mode = "in", loops = FALSE), 1)
expect_equal(max_degree(g, v = c()), 0)
expect_equal(max_degree(make_empty_graph()), 0)
})
4 changes: 3 additions & 1 deletion tools/stimulus/functions-R.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,9 @@ igraph_constraint:
IGNORE: RR, RC

igraph_maxdegree:
IGNORE: RR, RC, RInit
PARAM_ORDER: graph, *, vids, ...
PARAM_NAMES:
vids: v

igraph_density:

Expand Down

0 comments on commit 80b37bf

Please sign in to comment.