Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs and consistency cleanup for rustworkx-core generators #784

Merged
merged 21 commits into from
Feb 4, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions rustworkx-core/src/generators/barbell_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,32 @@ use super::utils::get_num_nodes;
use super::utils::pairwise;
use super::InvalidInputError;

/// Generate an undirected barbell graph where two identical mesh graphs are
/// Generate an undirected barbell graph where two identical complete graphs are
/// connected by a path.
///
/// .. note::
///
/// If neither `num_path_nodes` nor `path_weights` (described below) is not specified
/// then this is equivalent to two mesh graphs joined together.
/// If neither `num_path_nodes` nor `path_weights` (described below) are
/// specified, then this is equivalent to two complete graphs joined together.
///
/// Arguments:
///
/// * `num_mesh_nodes` - The number of nodes to generate the mesh graph
/// with. Node weights will be None if this is specified. If both
/// `num_mesh_nodes` and `mesh_weights` are set this will be ignored and
/// `num_mesh_nodes` and `mesh_weights` are set, this will be ignored and
/// `mesh_weights` will be used.
/// * `num_path_nodes` - The number of nodes to generate the path
/// with. Node weights will be None if this is specified. If both
/// `num_path_nodes` and `path_weights` are set this will be ignored and
/// `num_path_nodes` and `path_weights` are set, this will be ignored and
/// `path_weights` will be used.
/// * `mesh_weights` - A list of node weights for the mesh graph. If both
/// `num_mesh_nodes` and `mesh_weights` are set `num_mesh_nodes` will
/// `num_mesh_nodes` and `mesh_weights` are set, `num_mesh_nodes` will
/// be ignored and `mesh_weights` will be used.
/// * `path_weights` - A list of node weights for the path. If both
/// `num_path_nodes` and `path_weights` are set `num_path_nodes` will
/// `num_path_nodes` and `path_weights` are set, `num_path_nodes` will
/// be ignored and `path_weights` will be used.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if weights are specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if node weights are specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
///
Expand Down Expand Up @@ -147,7 +146,7 @@ where
}
};
let pathlen = path_nodes.len();
if pathlen > 0 {
if !path_nodes.is_empty() {
graph.add_edge(
graph.from_index(meshlen - 1),
graph.from_index(meshlen),
Expand Down
57 changes: 18 additions & 39 deletions rustworkx-core/src/generators/binomial_tree_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ use super::InvalidInputError;
///
/// * `order` - The order of the binomial tree.
/// * `weights` - A `Vec` of node weight objects. If the number of weights is
/// less than 2**order extra nodes with None will be appended.
/// less than 2**order, extra nodes with None will be appended.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down Expand Up @@ -104,22 +103,6 @@ where
None => graph.add_node(default_node_weight()),
};
}

fn find_edge<G>(graph: &mut G, source: usize, target: usize) -> bool
where
G: NodeIndexable,
for<'b> &'b G: GraphBase<NodeId = G::NodeId> + IntoEdgeReferences,
{
let mut found = false;
for edge in graph.edge_references() {
if graph.to_index(edge.source()) == source && graph.to_index(edge.target()) == target {
found = true;
break;
}
}
found
}

let mut n = 1;
let zero_index = 0;
for _ in 0..order {
Expand All @@ -132,30 +115,26 @@ where
let source_index = source + n;
let target_index = target + n;

if !find_edge(&mut graph, source_index, target_index) {
graph.add_edge(
graph.from_index(source_index),
graph.from_index(target_index),
default_edge_weight(),
);
}
if bidirectional && !find_edge(&mut graph, target_index, source_index) {
graph.add_edge(
graph.update_edge(
graph.from_index(source_index),
graph.from_index(target_index),
default_edge_weight(),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't quite the same because if the edge already exists we're replacing the weight with the output of default_edge_weight(). This won't matter if default_edge_weight() returns the same value every time, but there is no guarantee that will be the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, missed that. Was thinking of the defaults as fixed. I can return to doing the find and then the add if not there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 63d2307.

if bidirectional {
graph.update_edge(
graph.from_index(target_index),
graph.from_index(source_index),
default_edge_weight(),
);
}
}
if !find_edge(&mut graph, zero_index, n) {
graph.add_edge(
graph.from_index(zero_index),
graph.from_index(n),
default_edge_weight(),
);
}
if bidirectional && !find_edge(&mut graph, n, zero_index) {
graph.add_edge(
graph.update_edge(
graph.from_index(zero_index),
graph.from_index(n),
default_edge_weight(),
);
if bidirectional {
graph.update_edge(
graph.from_index(n),
graph.from_index(zero_index),
default_edge_weight(),
Expand Down
5 changes: 2 additions & 3 deletions rustworkx-core/src/generators/complete_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ use super::InvalidInputError;
/// Arguments:
///
/// * `num_nodes` - The number of nodes to create a complete graph for. Either this or
/// `weights must be specified. If both this and `weights are specified, weights
/// `weights` must be specified. If both this and `weights` are specified, `weights`
/// will take priorty and this argument will be ignored
/// * `weights` - A `Vec` of node weight objects.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
///
Expand Down
9 changes: 4 additions & 5 deletions rustworkx-core/src/generators/cycle_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ use super::InvalidInputError;
/// Arguments:
///
/// * `num_nodes` - The number of nodes to create a cycle graph for. Either this or
/// `weights must be specified. If both this and `weights are specified, weights
/// `weights` must be specified. If both this and `weights` are specified, `weights`
/// will take priorty and this argument will be ignored.
/// * `weights` - A `Vec` of node weight objects.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
11 changes: 6 additions & 5 deletions rustworkx-core/src/generators/full_rary_tree_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@ use super::InvalidInputError;
/// Creates a full r-ary tree of `n` nodes.
/// Sometimes called a k-ary, n-ary, or m-ary tree.
///
/// Arguments:
///
/// * `branching factor` - The number of children at each node.
/// * `num_nodes` - The number of nodes in the graph.
/// * `weights` - A list of node weights. If the number of weights is
/// less than n, extra nodes with with None weight will be appended.
/// less than n, extra nodes with None weight will be appended.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
7 changes: 3 additions & 4 deletions rustworkx-core/src/generators/grid_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::InvalidInputError;
///
/// * `rows` - The number of rows to generate the graph with.
/// If specified, cols also need to be specified.
/// * `cols`: The number of rows to generate the graph with.
/// * `cols`: The number of columns to generate the graph with.
/// If specified, rows also need to be specified. rows*cols
/// defines the number of nodes in the graph.
/// * `weights`: A `Vec` of node weights. Nodes are filled row wise.
Expand All @@ -32,11 +32,10 @@ use super::InvalidInputError;
/// If number of nodes(rows*cols) is greater than length of
/// weights list, extra nodes with None weight are appended.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a parallel edge.
///
Expand Down
13 changes: 7 additions & 6 deletions rustworkx-core/src/generators/heavy_hex_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,17 @@ use super::InvalidInputError;
/// ... D D-S-D ...
///
///
/// * `d` - Distance of the code. If ``d`` is set to ``1`` a graph with a
/// single node will be returned. d must be an odd number.
/// Arguments:
///
/// * `d` - Distance of the code. If `d` is set to `1` a graph with a
/// single node will be returned. `d` must be an odd number.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
17 changes: 11 additions & 6 deletions rustworkx-core/src/generators/heavy_square_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,17 @@ use super::InvalidInputError;
/// This function implements Fig 10.b left of the `paper <https://arxiv.org/abs/1907.09528>`_.
/// This function doesn't support the variant Fig 10.b right.
///
/// :param int d: distance of the code. If ``d`` is set to ``1`` a
/// :class:`~rustworkx.PyDiGraph` with a single node will be returned.
/// :param bool multigraph: When set to False the output
/// :class:`~rustworkx.PyDiGraph` object will not be not be a multigraph and
/// won't allow parallel edges to be added. Instead
/// calls which would create a parallel edge will update the existing edge.
/// Arguments:
///
/// * `d` - Distance of the code. If `d` is set to `1` a graph with a
/// single node will be returned. `d` must be an odd number.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
7 changes: 3 additions & 4 deletions rustworkx-core/src/generators/hexagonal_lattice_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ use super::InvalidInputError;
/// * `rows` - The number of rows to generate the graph with.
/// * `cols` - The number of columns to generate the graph with.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
29 changes: 11 additions & 18 deletions rustworkx-core/src/generators/lollipop_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@ use std::hash::Hash;
use petgraph::data::{Build, Create};
use petgraph::visit::{Data, GraphProp, NodeIndexable};

use super::utils::pairwise;
use super::utils::{get_num_nodes, pairwise};
use super::InvalidInputError;

/// Generate a lollipop graph
/// Generate an undirected lollipop graph where a complete graph is connected to a
/// path.
///
/// Arguments:
/// .. note::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this syntax will work in rustdoc since it's markdown based. I'm not sure what the correct syntax is off the top of my head, we'll have to check the docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This passes the tests. Is there somewhere this would fail and not be tested?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will just render in the docs as plain text ... note:: without anything special (as this is a sphinx directive and the rustworkx-core docs are built using rustdoc). You can test the output with cargo doc --open and see what the rendered docs look like: https://github.com/Qiskit/rustworkx/blob/main/CONTRIBUTING.md#rustworkx-core-documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that info. I went back through all the docs in core and I think everything should be clean now. I removed all the markdown and made things prettier. Turns out the trick for displaying Ascii is to use text instead of rust for code-like sections.
Should be done in 63d2307 and b0e4dfc.

///
/// Generate an undirected lollipop graph where a mesh graph is connected to a
/// path.
/// If neither `num_path_nodes` nor `path_weights` (described below) are
/// specified, then this is equivalent to a complete graph.
///
/// If neither `num_path_nodes` nor `path_weights` (both described
/// below) are specified then this is equivalent to
/// :func:`~rustworkx.generators.mesh_graph`
/// Arguments:
///
/// * `num_mesh_nodes` - The number of nodes to generate the mesh graph
/// with. Node weights will be None if this is specified. If both
Expand All @@ -44,8 +43,7 @@ use super::InvalidInputError;
/// `num_path_nodes` and `path_weights` are set `num_path_nodes` will
/// be ignored and `path_weights` will be used.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
///
Expand Down Expand Up @@ -98,12 +96,7 @@ where
if num_mesh_nodes.is_none() && mesh_weights.is_none() {
return Err(InvalidInputError {});
}
let num_nodes: usize;
if let Some(mesh_nodes) = num_mesh_nodes {
num_nodes = mesh_nodes;
} else {
num_nodes = mesh_weights.as_ref().unwrap().len();
}
let num_nodes = get_num_nodes(&num_mesh_nodes, &mesh_weights);
let num_edges = (num_nodes * (num_nodes - 1)) / 2;
let mut graph = G::with_capacity(num_nodes, num_edges);

Expand Down Expand Up @@ -138,8 +131,7 @@ where
}
}
};
let pathlen = path_nodes.len();
if pathlen > 0 {
if !path_nodes.is_empty() {
graph.add_edge(
graph.from_index(meshlen - 1),
graph.from_index(meshlen),
Expand All @@ -160,6 +152,7 @@ mod tests {
use crate::generators::lollipop_graph;
use crate::generators::InvalidInputError;
use crate::petgraph::visit::EdgeRef;

#[test]
fn test_lollipop_mesh_path() {
let expected_edge_list = vec![
Expand Down
2 changes: 1 addition & 1 deletion rustworkx-core/src/generators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ mod path_graph;
mod petersen_graph;
mod star_graph;

mod utils;
pub mod utils;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this expose rustworkx_core::generators::mod::utils as a public facing interface. Do we want to commit to the interface on the util functions there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just there since rustworkx/src/steiner_tree.rs was using the pairwise fn in generators.rs. I moved pairwise to utils since it was being used by a couple of the generators, but no longer used in generators.rs. If you don't want pub here, the simplest would be to just duplicate pairwise in steiner_tree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I missed that when I went through this earlier. I think that's fine but I just wonder about the rest of the utils module. If we only need pairwise maybe we should just export only that one function. I'm just worried about committing the API surface for what were previously internal functions in the python side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So where should we put pairwise so it's accessible from both rustworkx and rustworkx-core?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think we should be conservative on what we make public here. We can always add more public things later if the need arises and we're confident with the API, but it's much harder to walk something back after we make it public.

I would keep the module private and change this to be pub use utils::pairwise or maybe make a top level public utils module that only contains the pairwise function for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a top-level utils with pairwise in it. In 5c3ea62.


use std::{error::Error, fmt};

Expand Down
9 changes: 4 additions & 5 deletions rustworkx-core/src/generators/path_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ use super::InvalidInputError;
/// Arguments:
///
/// * `num_nodes` - The number of nodes to create a path graph for. Either this or
/// `weights must be specified. If both this and `weights are specified, weights
/// `weights` must be specified. If both this and `weights` are specified, `weights`
/// will take priorty and this argument will be ignored
/// * `weights` - A `Vec` of node weight objects.
/// * `default_node_weight` - A callable that will return the weight to use
/// for newly created nodes. This is ignored if `weights` is specified,
/// as the weights from that argument will be used instead.
/// for newly created nodes. This is ignored if `weights` is specified.
/// * `default_edge_weight` - A callable that will return the weight object
/// to use for newly created edges.
/// * `bidirectional` - Whether edges are added bidirectionally, if set to
/// * `bidirectional` - Whether edges are added bidirectionally. If set to
/// `true` then for any edge `(u, v)` an edge `(v, u)` will also be added.
/// If the graph is undirected this will result in a pallel edge.
/// If the graph is undirected this will result in a parallel edge.
///
/// # Example
/// ```rust
Expand Down
Loading