diff --git a/gerrychain/graph/__init__.py b/gerrychain/graph/__init__.py index 7ee558e6..0d8cf19d 100644 --- a/gerrychain/graph/__init__.py +++ b/gerrychain/graph/__init__.py @@ -1,19 +1,32 @@ """ -This module provides the Graph class that is used +This module implements the Graph class that is used by GerryChain code. +It exposes standard graph functionality for a dual-graph +containing nodes and edges. Both nodes and edges can have +data associated with them. + A Graph object is typically created by first creating -a NetworkX Graph object and then converting it to +a NetworkX.Graph object and then converting it to a GerryChain Graph object using from_networkx(). -Internally, a Graph object contains and embedded graph +For instance: + + import networkx + from gerrychain import Graph + + # Create a NetworkX graph + nx_graph = networkx.Graph() + nx_graph.add_edges_from(...) + + # Create a GerryChain graph from the NetworkX graph + my_gerrychain_graph = Graph.from_networkx(nx_graph) + +Internally, a Graph object contains an embedded graph object based either on NetworkX or RustworkX. After creating a Partition object in GerryChain, the embedded graph object is converted to be based on RustworkX (for performance reasons). - -The class Graph is the only part of this module that -is intended to be used directly by users of GerryChain. """ from .adjacency import * diff --git a/v1.0.0_changelog.md b/v1.0.0_changelog.md new file mode 100644 index 00000000..b165bb21 --- /dev/null +++ b/v1.0.0_changelog.md @@ -0,0 +1,175 @@ +## [v1.0.0] - August 2026 + +### Added + +#### Markov chains (module: chain) +* Added ability to incrementally configure the chain. + + You can explicitly set class attributes, such as: `chain.initial_partition = ...`. + + Functions to add constraints and updaters: + + * add_constraint() + * add_constraints() + * add_updater() + * add_updaters() + + Function to check whether a chain is fully configured: + + * check_valid() + +#### Graphs (module: graph) +* Added methods to query and access the embedded NetworkX/RustworkX graph. + + * is_nx_graph() + * is_rx_graph() + * get_nx_graph() + * get_rx_graph() + +* Added methods for converting between GerryChain, NetworkX, and RustworkX graphs, and to create an empty graph. + + * from_networkx() + * from_rustworkx() + * from_null_networkx() + * to_networkx_graph() + +* Added method to create a fictional 8x8 grid graph of 64 unit-population nodes that is used in the User Guide. + + * gerrymandria() + + +* Added methods to translate node_ids between NetworkX and RustworkX and between parent graphs and subgraphs - to deal with the differences between the way NetworkX and RustworkX implement node_ids. + + * original_nx_node_id_for_internal_node_id() + * internal_node_id_for_original_nx_node_id() + * get_nx_to_rx_node_id_map() + * translate_subgraph_node_ids_for_set_of_nodes() + * original_nx_node_ids_for_list() + * original_nx_node_ids_for_set() + * translate_subgraph_node_ids_for_flips() + +* Added methods to handle the fact that in RustworkX, edges are different from edge_ids. In both NetworkX and RustworkX, an edge is a tuple of node_ids. In NetworkX, there is no difference between an edge and an edge_id, but in RustworkX an edge_id is an integer. + + * get_edge_id_from_edge() + * get_edge_from_edge_id() + +#### Proposals (module: proposals) + +* Added new names for legacy functions. The new names adhere to the naming convention for creating proposal functions, "build_xxx_proposal_fn". Note that the legacy functions continue to exist. + + * build_any_node_flip_proposal_fn() == propose_any_node_flip() + * build_random_flip_proposal_fn() == propose_random_flip() + * build_flip_every_district_proposal_fn() == propose_flip_every_district() + * build_chunk_flip_proposal_fn() == propose_chunk_flip() + * build_slow_reversible_proposal_fn() == slow_reversible_propose() + * build_slow_reversible_bi_proposal_fn() == slow_reversible_propose_bi() + +#### ReCom proposals (module: proposals) +* Changed the ReCom class to be a namespace that defines the five variants of recom that were discussed in the article, "Spanning Tree Methods for Sampling Graph Partitions": + + * A = cut_edges_mst() + * B = district_pairs_mst() + * C = cut_edges_ust() + * D = district_pairs_ust() + * R = reversible() + +* Added convenience functions to create recom proposal functions: + + * build_recom_proposal_fn() + * build_reversible_recom_proposal_fn() + +#### Multi-member ReCom (module: proposals) + +* Added functions and the MultiMemberReCom class to support multi-member ReCom. These new functions and the MultiMemberReCom class mirror the routines and class for standard ReCom: + + * multi_member_recom() + * build_multi_member_recom_proposal_fn() + * epsilon_tree_bipartition_multi_member() + * class MultiMemberReCom + * cut_edges_mst() + * district_pairs_mst() + * cut_edges_ust() + * district_pairs_ust() + +#### Constraints for multi-member ReCom (module: constraints) + +* Added a new constraint to support multi-member ReCom + + * within_percent_of_ideal_population_per_member() + +### Changed + +#### Graphs + +* `GerryChain.Graph` no longer subclasses `networkx.Graph`. Node and edge data access has changed. See the v1.0 migration guide. [link-name](https://ibm.com) + + frm: TODO: Add link to the v1.0 migration guide. + +* Changed the way to access node and edge data + + * To access node data, use: my_graph.node_data(...node_id...) + * To access edge data, use: my_graph.edge_data(...edge_id...) + +* GerryChain now uses independent random number generators configured through parameters, `rng= `. See the reproducibility guide. [link-name](https://ibm.com) + + frm: TODO: add link to reproducibility guide + +#### Changes to function names: + +* In module grid: + + * create_grid_graph() renamed to be: create_grid_nx_graph() + +#### Renamed parameters that accept functions + +* Parameters accepting functions now generally have names that use the _fn suffix: + + This is only an issue for function calls using named parameters. + + An example of this is the renaming of "proposal" to "proposal_fn" in the constructor for a MarkovChain object: + + Old: + ``` + my_chain = MarkovChain( + proposal = my_proposal, + ... + ) + ``` + New: + ``` + my_chain = MarkovChain( + proposal_fn = my_proposal, + ... + ) + ``` +### Removed + +#### Removed the pre-1.0 NetworkX-derived Graph interface. + +* gerrychain.Graph is no longer a subclass of networkx.Graph. + + See the migration guide for the replacement graph operations. + + frm: TODO: Add link for migration guide above. + +#### Removed the old instantiable and callable ReCom interface. + +* The old ReCom class was instantiable and callable. It has been replaced with an interface that implements a namespace that defines functions that generate proposal functions. + + See the ??? #### The `ReCom` Namespace for details. + + frm: TODO: Add link for ??? the discussion in the Migration Guide for details. + +### Deprecated + +#### Pre-1.0 proposal and acceptance callbacks that lack `rng= `. + +* The callbacks now support a "reproducibility" parameter, `rng= `, that defines a random number generator. This allows the user to control the initial conditions so that the behavior of GerryChain is deterministic. + + For more details see the reproducibility guide. [link-name](https://ibm.com) + + frm: TODO: add link to reproducibility guide + +#### Legacy constructor and method parameter names for MarkovChain, Gingleator, SingleMetricOptimizer, etc. + +* The legacy versions of these remain temporarily supported with warnings. \ No newline at end of file