Package structure¶
From user perspective, PyRigi follows object-oriented design.
The main functionality can be accessed via the methods of Graph, Framework,
or the classes inherited from Motion.
However, in order to have extendable and maintainable code,
most of the algorithms are implemented as functions and wrapped as methods of the corresponding classes.
As such, they are suggested by autocompletion tools once
an instance, like Graph, is available and therefore easy to search for and use.
This approach allows one to implement functionality in separate modules according to the topics,
see below.
The modules are considered non-public (they are in folders with a single leading underscore), hence their structure might change in backward incompatible manner.
Graph functionality¶
Functions implementing graph functionalities accept networkx.Graph as the first parameter
and are then wrapped as pyrigi.Graph methods.
For example, consider the method Graph.is_rigid().
In the file pyrigi/graph/graph.py it looks like:
from ._rigidity import generic as generic_rigidity
class Graph(nx.Graph):
@copy_doc(generic_rigidity.is_rigid)
def is_rigid(
self,
dim: int = 2,
algorithm: str = "default",
use_precomputed_pebble_digraph: bool = False,
prob: float = 0.0001,
) -> bool:
return generic_rigidity.is_rigid(
self,
dim=dim,
algorithm=algorithm,
use_precomputed_pebble_digraph=use_precomputed_pebble_digraph,
prob=prob,
)
As one can see, this method simply calls the function is_rigid
located in the file pyrigi/graph/rigidity/generic.py.
The decorator @copy_doc copies the docstring from the function.
If we now look at the function, we see
def is_rigid(
graph: nx.Graph,
dim: int = 2,
algorithm: str = "default",
use_precomputed_pebble_digraph: bool = False,
prob: float = 0.0001,
) -> bool:
"""
Return whether the graph is ``dim``-rigid.
...
"""
# implementation of the function
As one may notice, the parameters of the function is_rigid are the same as those
for the method Graph.is_rigid(), except for the first one,
which is of type networkx.Graph and is always called graph.
Therefore, if new graph functionalities are added,
they should be implemented as a function accepting networkx.Graph
and then wrapped as methods of pyrigi.Graph.
The decorator @copy_doc not only copies the docstring but also converts
function-style examples to method-style at import time.
Therefore, docstrings should be written in function-style, referring to the
graph as “the graph” rather than by the parameter name graph.
In the Parameters section of the functions docstrings, the first parameter has
to be a bare graph/framework (i.e., without any description),
which is removed automatically by @copy_doc (the description would remain, if present).
Writing examples for copy_doc-wrapped functions¶
Examples in function-style docstrings must follow these rules so copy_doc can
invert them to method-style at import time:
No chained instantiation. Assign the graph to a variable first:
>>> g = graphs.Diamond() >>> len(list(all_k_extensions(g, 1, 2, only_non_isomorphic=True)))
Chained calls like
all_k_extensions(graphs.Diamond(), ...)are not caught by the regex and will remain in function-style inside the method docstring.Outer wrappers are allowed (
list,len,type,sorted,print, etc.), as long as no argument to the function is itself a function call:>>> type(all_extensions(G)) # OK — no nested call in args >>> len(list(all_k_extensions(G, 0))) # OK — linear args
For multiline calls, place the graph variable alone on the first continuation line. This is the only multiline pattern that
copy_doccan invert:>>> print(to_tikz( # graph variable NOT on this line ... G, # graph variable alone here — OK ... layout_type="circular", ... vertex_style="myvertex"))
The following patterns are not converted and must be avoided:
>>> print(to_tikz(G, # G on the >>> line without closing paren — NOT handled ... layout_type="circular"))
Regarding type hinting, networkx.Graph should be used in the function signature,
while pyrigi.Graph should be used in the method signature.
This is needed, for example, when a function/method returns a Graph.
Framework functionality¶
Similarly to the graph case, the functions implementing framework functionalities
accept pyrigi.framework.base.FrameworkBase as the first parameter, called framework, and
are wrapped as methods of pyrigi.Framework,
which is inherited from pyrigi.framework.base.FrameworkBase.
Overview¶
_utils/
__init__.py
_conversion.py ............................... conversions between data types
_doc.py .................................. tools for generating documentation
_graph_alias_mapping.py
_input_check.py .................................. functions for input checks
_zero_check.py ........................ functions for checking symbolic zeros
linear_algebra.py .............................. functions for linear algebra
repetable_iterator.py
union_find.py
framework/
_export/
__init__.py
export.py ............................. functions for export to TikZ, STL
_plot/
__init__.py
plot.py .......................................... functions for plotting
_rigidity/
__init__.py
infinitesimal.py ................... functions for infinitesimal rigidity
matroidal.py ................... functions for framework rigidity matroid
redundant.py ........................... functions for redundant rigidity
second_order.py .... functions for prestress stability and 2nd order rig.
stress.py ........................................ functions for stresses
_transformations/
transformations.py ....................... functions like rotate or scale
__init__.py
_general.py ..................................... general framework functions
base.py ..................................... implementation of FrameworkBase
conftest.py
framework.py .................................... implementation of Framework
graph/
_constructions/
constructions.py ................... functions like t-sum or intersection
extensions.py ................................ functions for k-extensions
_export/
__init__.py
export.py .................................. functions for export to TikZ
_flexibility/
nac/
__init__.py
algorithms.py
check.py
core.py
cycle_detection.py
existence.py
facade.py
mono_classes.py
search.py
single.py
strategies.py
__init__.py
_other/
apex.py ....................................... functions for apex graphs
separating_set.py ................ functions for (stable) separating sets
_rigidity/
generic.py ............................... functions for generic rigidity
global_.py ................................ functions for global rigidity
matroidal.py ..................... functions for generic rigidity matroid
realization_counting.py
redundant.py ........................... functions for redundant rigidity
_sparsity/
_pebble_digraph.py ...................... implementation of PebbleDigraph
sparsity.py ................................ functions for (k,l)-sparsity
_utils/
_input_check.py .................................. input checks for Graph
utils.py
__init__.py
_general.py ......................................... general graph functions
conftest.py
graph.py ............................................ implementation of Graph
graph_drawer/
__init__.py
graph_drawer.py ............................... implementation of GraphDrawer
misc/
__init__.py
motion/
__init__.py
approximate_motion.py ................... implementation of ApproximateMotion
motion.py .......................................... implementation of Motion
parametric_motion.py ..................... implementation of ParametricMotion
__init__.py
data_type.py .......................................... definitions of data types
exception.py .......................................... definitions of exceptions
frameworkDB.py ........................................... database of frameworks
graphDB.py ................................................... database of graphs
plot_style.py ................................ implementation of Plotstyle(2D/3D)
warning.py .............................................. definitions of warnings