Skip to content

feat: expose widest paths functions as widest_paths() and widest_path_widths()#2408

Open
krlmlr with Copilot wants to merge 1 commit into
mainfrom
copilot/expose-widest-paths-functions
Open

feat: expose widest paths functions as widest_paths() and widest_path_widths()#2408
krlmlr with Copilot wants to merge 1 commit into
mainfrom
copilot/expose-widest-paths-functions

Conversation

Copilot AI commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

Exposes the C widest paths implementation to R users
with two new experimental functions.

Fixes #1566.

API

Both functions follow the argument-zoning policy for new functions:
defining arguments come first,
all modifiers are keyword-only behind ...
(guarded by rlang::check_dots_empty()),
and all arguments use snake_case.

widest_path_widths(
  graph,
  from = V(graph),
  to = V(graph),
  ...,
  mode = c("all", "out", "in"),
  weights = NULL,
  algorithm = c("automatic", "dijkstra", "floyd-warshall")
)

widest_paths(
  graph,
  from,
  to = V(graph),
  ...,
  mode = c("out", "all", "in"),
  weights = NULL,
  output = c("vpath", "epath", "both"),
  predecessors = FALSE,
  inbound_edges = FALSE
)
  • widest_path_widths() (analogous to distances())
    returns the matrix of widest path (bottleneck) widths
    between two vertex sets.
    With algorithm = "automatic" (the default),
    Dijkstra is used for sparse graphs
    and Floyd-Warshall for dense graphs.
  • widest_paths() (analogous to shortest_paths())
    returns one widest path per target vertex.
    output selects vertex paths, edge paths, or both;
    predecessors and inbound_edges optionally return
    the widest path tree,
    reporting the start vertex and unreached vertices as NA.

Weights requirement

The C implementation requires edge weights (interpreted as widths),
so unlike distances(), these functions error
when no weights are available:

  • the weight edge attribute is used when weights = NULL;
  • a clear error is raised when the graph has no weight attribute,
    and for weights = NA.

Bug fix required by this feature

create_es() did not forward na_ok to simple_es_index(),
so an edge sequence containing NA could not be created,
and the cli edge-sequence printer failed on NA edge IDs.
Both are fixed here,
which also repairs shortest_paths(inbound.edges = TRUE):
it previously errored with "Unknown edge selected".

Usage

g <- make_ring(10)
E(g)$weight <- seq_len(ecount(g))

# Calculate widest path widths (like distances())
widest_path_widths(g)

# Get actual widest paths (like shortest_paths())
widest_paths(g, from = 5, to = c(1, 3, 7))

Tests

  • tests/testthat/test-aaa-auto.R:
    snapshot and structured tests for
    widest_path_widths_dijkstra_impl() and
    widest_path_widths_floyd_warshall_impl(),
    the two _impl() functions that had no coverage yet
    (get_widest_path_impl() and get_widest_paths_impl()
    were already covered).
  • tests/testthat/test-paths.R:
    structured tests for widths, algorithm equivalence, modes,
    vertex names, unreachable vertices, and path/tree outputs,
    plus snapshot tests for all error paths
    and for printing NA-containing vertex/edge sequences.

Copilot AI changed the title [WIP] Expose widest paths functions as optional feat: Expose widest paths functions as widest_paths() and widest_path_widths() Oct 26, 2025
Copilot AI requested a review from krlmlr October 26, 2025 11:13
Comment thread R/paths.R Outdated
@krlmlr
krlmlr requested a review from szhorvat October 26, 2025 11:14
@krlmlr krlmlr removed their assignment Oct 26, 2025
@szhorvat

Copy link
Copy Markdown
Member

I want to have a careful look at this as I get the time.

@krlmlr krlmlr changed the title feat: Expose widest paths functions as widest_paths() and widest_path_widths() feat: expose widest paths functions as widest_paths() and widest_path_widths() Jul 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This is how benchmark results would change (along with a 95% confidence interval in relative change) if c176ff7 is merged into main:

  • ✔️as_adjacency_matrix: 603ms -> 611ms [-0.14%, +2.54%]
  • ✔️as_biadjacency_matrix: 590ms -> 592ms [-1.2%, +1.89%]
  • ✔️as_data_frame_both: 1.26ms -> 1.27ms [-1.13%, +2.77%]
  • ✔️as_long_data_frame: 3.32ms -> 3.32ms [-1.73%, +1.57%]
  • ✔️es_attr_filter: 2.37ms -> 2.38ms [-1.86%, +3.06%]
  • ✔️graph_from_adjacency_matrix: 110ms -> 107ms [-6.71%, +2.02%]
  • ✔️graph_from_data_frame: 2.82ms -> 2.79ms [-2.7%, +0.2%]
  • ✔️vs_attr_filter: 1.29ms -> 1.25ms [-5.25%, +0.48%]
  • ✔️vs_by_name: 816µs -> 800µs [-4.11%, +0.35%]
    Further explanation regarding interpretation and methodology can be found in the documentation.

@krlmlr
krlmlr marked this pull request as ready for review July 26, 2026 15:04
Flattened onto the current main (post-#2779 rebase); content unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016M32izVHZPfxAqemAe4BrX
@krlmlr
krlmlr force-pushed the copilot/expose-widest-paths-functions branch from c176ff7 to 5f7926e Compare July 26, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose widest paths functions

4 participants