diff --git a/R/aaa-auto.R b/R/aaa-auto.R index 190ba1df80..6151c6d7f4 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -9730,6 +9730,7 @@ fundamental_cycles_impl <- function( call = rlang::caller_env() ) } + start <- start - 1 } bfs_cutoff <- as.numeric(bfs_cutoff) if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { @@ -9746,7 +9747,7 @@ fundamental_cycles_impl <- function( res <- .Call( R_igraph_fundamental_cycles, graph, - start - 1, + start, bfs_cutoff, weights ) @@ -9971,7 +9972,7 @@ minimum_spanning_tree_prim_impl <- function( random_spanning_tree_impl <- function( graph, - vid = 0 + vid = NULL ) { # Argument checks ensure_igraph(graph) @@ -9983,6 +9984,7 @@ random_spanning_tree_impl <- function( call = rlang::caller_env() ) } + vid <- vid - 1 } on.exit(.Call(R_igraph_finalizer)) @@ -9990,7 +9992,7 @@ random_spanning_tree_impl <- function( res <- .Call( R_igraph_random_spanning_tree, graph, - vid - 1 + vid ) if (igraph_opt("return.vs.es")) { res <- create_es(graph, res) @@ -10316,6 +10318,7 @@ vertex_path_from_edge_path_impl <- function( call = rlang::caller_env() ) } + start <- start - 1 } edge_path <- as_igraph_es(graph, edge_path) mode <- switch_igraph_arg( @@ -10331,7 +10334,7 @@ vertex_path_from_edge_path_impl <- function( res <- .Call( R_igraph_vertex_path_from_edge_path, graph, - start - 1, + start, edge_path - 1, mode ) diff --git a/R/trees.R b/R/trees.R index 03adbc86ee..693f897627 100644 --- a/R/trees.R +++ b/R/trees.R @@ -152,7 +152,7 @@ to_prufer <- function(graph) { #' @param graph The input graph to sample from. Edge directions are ignored if #' the graph is directed. #' @param vid When the graph is disconnected, this argument specifies how to -#' handle the situation. When the argument is zero (the default), the sampling +#' handle the situation. When the argument is `NULL` (the default), the sampling #' will be performed component-wise, and the result will be a spanning forest. #' When the argument contains a vertex ID, only the component containing the #' given vertex will be processed, and the result will be a spanning tree of the @@ -171,7 +171,7 @@ to_prufer <- function(graph) { #' @family trees #' @export #' @cdocs igraph_random_spanning_tree -sample_spanning_tree <- function(graph, vid = 0) { +sample_spanning_tree <- function(graph, vid = NULL) { random_spanning_tree_impl( graph = graph, vid = vid diff --git a/man/sample_spanning_tree.Rd b/man/sample_spanning_tree.Rd index 69efb56e52..1100e6a41a 100644 --- a/man/sample_spanning_tree.Rd +++ b/man/sample_spanning_tree.Rd @@ -4,14 +4,14 @@ \alias{sample_spanning_tree} \title{Samples from the spanning trees of a graph randomly and uniformly} \usage{ -sample_spanning_tree(graph, vid = 0) +sample_spanning_tree(graph, vid = NULL) } \arguments{ \item{graph}{The input graph to sample from. Edge directions are ignored if the graph is directed.} \item{vid}{When the graph is disconnected, this argument specifies how to -handle the situation. When the argument is zero (the default), the sampling +handle the situation. When the argument is \code{NULL} (the default), the sampling will be performed component-wise, and the result will be a spanning forest. When the argument contains a vertex ID, only the component containing the given vertex will be processed, and the result will be a spanning tree of the diff --git a/src/rinterface.c b/src/rinterface.c index e627617568..b352b672e0 100644 --- a/src/rinterface.c +++ b/src/rinterface.c @@ -13168,7 +13168,7 @@ SEXP R_igraph_fundamental_cycles(SEXP graph, SEXP start, SEXP bfs_cutoff, SEXP w Rz_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, &c_basis, (Rf_isNull(start) ? 0 : c_start), c_bfs_cutoff, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, &c_basis, (Rf_isNull(start) ? -1 : c_start), c_bfs_cutoff, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(basis=Ry_igraph_vector_int_list_to_SEXPp1(&c_basis)); @@ -13482,7 +13482,7 @@ SEXP R_igraph_random_spanning_tree(SEXP graph, SEXP vid) { c_vid = (igraph_integer_t) REAL(vid)[0]; } /* Call igraph */ - IGRAPH_R_CHECK(igraph_random_spanning_tree(&c_graph, &c_res, (Rf_isNull(vid) ? 0 : c_vid))); + IGRAPH_R_CHECK(igraph_random_spanning_tree(&c_graph, &c_res, (Rf_isNull(vid) ? -1 : c_vid))); /* Convert output */ PROTECT(res=Ry_igraph_vector_int_to_SEXPp1(&c_res)); @@ -13869,7 +13869,7 @@ SEXP R_igraph_vertex_path_from_edge_path(SEXP graph, SEXP start, SEXP edge_path, IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_path); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_vertex_path_from_edge_path(&c_graph, (Rf_isNull(start) ? 0 : c_start), &c_edge_path, &c_vertex_path, c_mode)); + IGRAPH_R_CHECK(igraph_vertex_path_from_edge_path(&c_graph, (Rf_isNull(start) ? -1 : c_start), &c_edge_path, &c_vertex_path, c_mode)); /* Convert output */ igraph_vector_int_destroy(&c_edge_path); diff --git a/tools/py-stimulus/src/stimulus/generators/r.py b/tools/py-stimulus/src/stimulus/generators/r.py index 088964b58a..dc8a5023b8 100644 --- a/tools/py-stimulus/src/stimulus/generators/r.py +++ b/tools/py-stimulus/src/stimulus/generators/r.py @@ -255,7 +255,15 @@ def handle_argument_check(param: ParamSpec) -> str: if param.is_optional and param.is_input and res: res = optional_wrapper_r(res) - + # For optional VERTEX parameters, add the subtraction inside the NULL check + if param.type == "VERTEX": + # Add the subtraction at the end of the wrapped block + name = get_r_parameter_name(param) + res = res.rstrip() + if res.endswith("}"): + # Insert before the closing brace + res = res[:-1] + f" {name} <- {name} - 1\n}}" + # Replace template placeholders res = indent(res).replace("%I%", get_r_parameter_name(param)) for i, dep in enumerate(param.dependencies): @@ -299,9 +307,13 @@ def handle_argument_check(param: ParamSpec) -> str: name = get_r_parameter_name(param) call = type.get("CALL", name) if call: - call_formatted = call.replace("%I%", name) - # Add spaces around arithmetic operators - call_formatted = re.sub(r'(\w+)(\+|\-|\*|/)(\d+)', r'\1 \2 \3', call_formatted) + # For optional VERTEX parameters, subtraction is done in INCONV, so just use the name + if param.is_optional and param.type == "VERTEX": + call_formatted = name + else: + call_formatted = call.replace("%I%", name) + # Add spaces around arithmetic operators + call_formatted = re.sub(r'(\w+)(\+|\-|\*|/)(\d+)', r'\1 \2 \3', call_formatted) parts.append(call_formatted) # Format .Call() as multi-line with each argument on its own line diff --git a/tools/stimulus/functions-R.yaml b/tools/stimulus/functions-R.yaml index 7470eaf8f5..f2f3d45946 100644 --- a/tools/stimulus/functions-R.yaml +++ b/tools/stimulus/functions-R.yaml @@ -992,7 +992,7 @@ igraph_minimum_spanning_tree_unweighted: igraph_minimum_spanning_tree_prim: igraph_random_spanning_tree: - PARAMS: GRAPH graph, OUT EDGE_INDICES res, OPTIONAL VERTEX vid=0 + PARAMS: GRAPH graph, OUT EDGE_INDICES res, OPTIONAL VERTEX vid ####################################### # Coloring