Skip to content

Commit 725f46a

Browse files
CopilotkrlmlrCopilot
authored
refactor: replace .Call() with _impl functions and improve adjacency matrix implementation (#2546)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: krlmlr <[email protected]> Co-authored-by: Kirill Müller <[email protected]> Co-authored-by: Kirill Müller <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 1e48fa8 commit 725f46a

20 files changed

Lines changed: 758 additions & 337 deletions

R/aaa-auto.R

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ add_edges_impl <- function(
2626
) {
2727
# Argument checks
2828
ensure_igraph(graph)
29+
edges <- as_igraph_vs(graph, edges)
2930

3031
on.exit(.Call(R_igraph_finalizer))
3132
# Function call
3233
res <- .Call(
3334
R_igraph_add_edges,
3435
graph,
35-
edges
36+
edges - 1
3637
)
3738

3839
res
@@ -354,6 +355,7 @@ get_eids_impl <- function(
354355
) {
355356
# Argument checks
356357
ensure_igraph(graph)
358+
pairs <- as_igraph_vs(graph, pairs)
357359
directed <- as.logical(directed)
358360
error <- as.logical(error)
359361

@@ -362,7 +364,7 @@ get_eids_impl <- function(
362364
res <- .Call(
363365
R_igraph_get_eids,
364366
graph,
365-
pairs,
367+
pairs - 1,
366368
directed,
367369
error
368370
)
@@ -7247,7 +7249,7 @@ edgelist_percolation_impl <- function(
72477249
# Function call
72487250
res <- .Call(
72497251
R_igraph_edgelist_percolation,
7250-
edges
7252+
edges - 1
72517253
)
72527254

72537255
res
@@ -8769,6 +8771,7 @@ similarity_dice_pairs_impl <- function(
87698771
) {
87708772
# Argument checks
87718773
ensure_igraph(graph)
8774+
pairs <- as_igraph_vs(graph, pairs)
87728775
mode <- switch_igraph_arg(
87738776
mode,
87748777
"out" = 1L,
@@ -8783,7 +8786,7 @@ similarity_dice_pairs_impl <- function(
87838786
res <- .Call(
87848787
R_igraph_similarity_dice_pairs,
87858788
graph,
8786-
pairs,
8789+
pairs - 1,
87878790
mode,
87888791
loops
87898792
)
@@ -8889,6 +8892,7 @@ similarity_jaccard_pairs_impl <- function(
88898892
) {
88908893
# Argument checks
88918894
ensure_igraph(graph)
8895+
pairs <- as_igraph_vs(graph, pairs)
88928896
mode <- switch_igraph_arg(
88938897
mode,
88948898
"out" = 1L,
@@ -8903,7 +8907,7 @@ similarity_jaccard_pairs_impl <- function(
89038907
res <- .Call(
89048908
R_igraph_similarity_jaccard_pairs,
89058909
graph,
8906-
pairs,
8910+
pairs - 1,
89078911
mode,
89088912
loops
89098913
)

R/components.R

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,18 +204,15 @@ decompose <- function(
204204
) {
205205
ensure_igraph(graph)
206206
mode <- igraph_match_arg(mode)
207-
mode <- switch(mode, "weak" = 1L, "strong" = 2L)
208207

209208
if (is.na(max.comps)) {
210209
max.comps <- -1
211210
}
212-
on.exit(.Call(Rx_igraph_finalizer))
213-
.Call(
214-
Rx_igraph_decompose,
211+
decompose_impl(
215212
graph,
216-
as.numeric(mode),
217-
as.numeric(max.comps),
218-
as.numeric(min.vertices)
213+
mode,
214+
max.comps,
215+
min.vertices
219216
)
220217
}
221218

R/conversion.R

Lines changed: 23 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ get.adjacency.dense <- function(
223223
graph,
224224
type = c("both", "upper", "lower"),
225225
attr = NULL,
226-
weights = NULL,
227226
loops = c("once", "twice", "ignore"),
228227
names = TRUE
229228
) {
@@ -243,20 +242,17 @@ get.adjacency.dense <- function(
243242
)
244243
}
245244
loops <- igraph_match_arg(loops)
246-
loops <- switch(loops, "ignore" = 0L, "twice" = 1L, "once" = 2L)
247-
248-
if (!is.null(weights)) {
249-
weights <- as.numeric(weights)
245+
# Map "ignore" to "none" for get_adjacency_impl
246+
if (loops == "ignore") {
247+
loops <- "none"
250248
}
251249

252250
if (is.null(attr)) {
253-
on.exit(.Call(Rx_igraph_finalizer))
254-
type <- switch(type, "upper" = 0, "lower" = 1, "both" = 2)
255-
res <- .Call(
256-
Rx_igraph_get_adjacency,
251+
# FIXME: Use get_adjacency_impl() also for non-NULL attr
252+
res <- get_adjacency_impl(
257253
graph,
258-
as.numeric(type),
259-
weights,
254+
type,
255+
weights = numeric(),
260256
loops
261257
)
262258
} else {
@@ -287,67 +283,33 @@ get.adjacency.sparse <- function(
287283

288284
type <- igraph_match_arg(type)
289285

290-
vc <- vcount(graph)
291-
292-
el <- as_edgelist(graph, names = FALSE)
293-
use.last.ij <- FALSE
294-
295-
if (!is.null(attr)) {
286+
# Prepare weights parameter
287+
if (is.null(attr)) {
288+
weights <- numeric()
289+
} else {
296290
attr <- as.character(attr)
297291
if (!attr %in% edge_attr_names(graph)) {
298292
cli::cli_abort("No such edge attribute", call = call)
299293
}
300-
value <- edge_attr(graph, name = attr)
301-
if (!is.numeric(value) && !is.logical(value)) {
294+
weights <- edge_attr(graph, name = attr)
295+
if (!is.numeric(weights) && !is.logical(weights)) {
302296
cli::cli_abort(
303297
"Matrices must be either numeric or logical, and the edge attribute is not",
304298
call = call
305299
)
306300
}
307-
} else {
308-
value <- rep(1, nrow(el))
309301
}
310302

311-
if (is_directed(graph)) {
312-
res <- Matrix::sparseMatrix(
313-
dims = c(vc, vc),
314-
i = el[, 1],
315-
j = el[, 2],
316-
x = value,
317-
use.last.ij = use.last.ij
318-
)
319-
} else {
320-
if (type == "upper") {
321-
## upper
322-
res <- Matrix::sparseMatrix(
323-
dims = c(vc, vc),
324-
i = pmin(el[, 1], el[, 2]),
325-
j = pmax(el[, 1], el[, 2]),
326-
x = value,
327-
use.last.ij = use.last.ij
328-
)
329-
} else if (type == "lower") {
330-
## lower
331-
res <- Matrix::sparseMatrix(
332-
dims = c(vc, vc),
333-
i = pmax(el[, 1], el[, 2]),
334-
j = pmin(el[, 1], el[, 2]),
335-
x = value,
336-
use.last.ij = use.last.ij
337-
)
338-
} else if (type == "both") {
339-
## both
340-
res <- Matrix::sparseMatrix(
341-
dims = c(vc, vc),
342-
i = pmin(el[, 1], el[, 2]),
343-
j = pmax(el[, 1], el[, 2]),
344-
x = value,
345-
symmetric = TRUE,
346-
use.last.ij = use.last.ij
347-
)
348-
res <- as(res, "generalMatrix")
349-
}
350-
}
303+
# Use the library implementation
304+
tmp <- get_adjacency_sparse_impl(
305+
graph,
306+
type,
307+
weights,
308+
loops = "once"
309+
)
310+
311+
# Convert to proper Matrix object
312+
res <- igraph.i.spMatrix(tmp)
351313

352314
if (names && "name" %in% vertex_attr_names(graph)) {
353315
colnames(res) <- rownames(res) <- V(graph)$name
@@ -427,7 +389,6 @@ as_adjacency_matrix <- function(
427389
graph,
428390
type = type,
429391
attr = attr,
430-
weights = NULL,
431392
names = names,
432393
loops = "once"
433394
)

R/flow.R

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,11 @@ min_cut <- function(
417417
}
418418
} else {
419419
if (value.only) {
420-
res <- .Call(
421-
Rx_igraph_st_mincut_value,
422-
graph,
423-
as_igraph_vs(graph, source) - 1,
424-
as_igraph_vs(graph, target) - 1,
425-
capacity
420+
res <- st_mincut_value_impl(
421+
graph = graph,
422+
source = source,
423+
target = target,
424+
capacity = capacity
426425
)
427426
} else {
428427
res <- st_mincut_impl(
@@ -526,12 +525,10 @@ vertex_connectivity <- function(
526525
if (is.null(source) && is.null(target)) {
527526
vertex_connectivity_impl(graph = graph, checks = checks)
528527
} else if (!is.null(source) && !is.null(target)) {
529-
on.exit(.Call(Rx_igraph_finalizer))
530-
.Call(
531-
Rx_igraph_st_vertex_connectivity,
532-
graph,
533-
as_igraph_vs(graph, source) - 1,
534-
as_igraph_vs(graph, target) - 1
528+
st_vertex_connectivity_impl(
529+
graph = graph,
530+
source = source,
531+
target = target
535532
)
536533
} else {
537534
cli::cli_abort(c(
@@ -631,12 +628,10 @@ edge_connectivity <- function(
631628
if (is.null(source) && is.null(target)) {
632629
edge_connectivity_impl(graph = graph, checks = checks)
633630
} else if (!is.null(source) && !is.null(target)) {
634-
on.exit(.Call(Rx_igraph_finalizer))
635-
.Call(
636-
Rx_igraph_st_edge_connectivity,
637-
graph,
638-
as_igraph_vs(graph, source) - 1,
639-
as_igraph_vs(graph, target) - 1
631+
st_edge_connectivity_impl(
632+
graph = graph,
633+
source = source,
634+
target = target
640635
)
641636
} else {
642637
cli::cli_abort(c(
@@ -653,12 +648,10 @@ edge_disjoint_paths <- function(graph, source = NULL, target = NULL) {
653648
if (is.null(source) || is.null(target)) {
654649
cli::cli_abort("Both source and target must be given")
655650
}
656-
on.exit(.Call(Rx_igraph_finalizer))
657-
.Call(
658-
Rx_igraph_edge_disjoint_paths,
659-
graph,
660-
as_igraph_vs(graph, source) - 1,
661-
as_igraph_vs(graph, target) - 1
651+
edge_disjoint_paths_impl(
652+
graph = graph,
653+
source = source,
654+
target = target
662655
)
663656
}
664657

@@ -670,12 +663,10 @@ vertex_disjoint_paths <- function(graph, source = NULL, target = NULL) {
670663
cli::cli_abort("Both source and target must be given")
671664
}
672665

673-
on.exit(.Call(Rx_igraph_finalizer))
674-
.Call(
675-
Rx_igraph_vertex_disjoint_paths,
676-
graph,
677-
as_igraph_vs(graph, source) - 1,
678-
as_igraph_vs(graph, target) - 1
666+
vertex_disjoint_paths_impl(
667+
graph = graph,
668+
source = source,
669+
target = target
679670
)
680671
}
681672

0 commit comments

Comments
 (0)