Frameworks

Module for the functionality concerning frameworks.

Classes:

Framework(graph, realization)

This class provides the functionality for frameworks.

class pyrigi.framework.Framework(graph, realization)[source]

Bases: object

This class provides the functionality for frameworks.

Definitions

Parameters:
  • graph (Graph) – A graph without loops.

  • realization (Dict[Vertex, Point]) – A dictionary mapping the vertices of the graph to points in \(\RR^d\). The dimension d is retrieved from the points in realization. If graph is empty, and hence also the realization, the dimension is set to 0 (Framework.Empty() can be used to construct an empty framework with different dimension).

Examples

>>> F = Framework(Graph([[0,1]]), {0:[1,2], 1:[0,5]})
>>> F
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1] and edges [[0, 1]]
Realization {0:(1, 2), 1:(0, 5)}

Notice that the realization of a vertex can be accessed using [ ]:

>>> F[0]
Matrix([
[1],
[2]])

Todo

Use set_realization() in the constructor.

Methods

Attribute getters

dim()

Return the dimension of the framework.

dimension()

Alias for dim()

graph()

Return a copy of the underlying graph.

realization([as_points, numerical])

Return a copy of the realization.

Framework properties

is_congruent(other_framework[, numerical, ...])

Return whether the given framework is congruent to self.

is_congruent_realization(other_realization)

Return whether the given realization is congruent to self.

is_equivalent(other_framework[, numerical, ...])

Return whether the given framework is equivalent to self.

is_equivalent_realization(other_realization)

Return whether the given realization is equivalent to self.

is_injective([numerical, tolerance])

Return whether the realization is injective.

is_quasi_injective([numerical, tolerance])

Return whether the realization is quasi-injective.

Class methods

Circular(graph)

Return the framework with a regular unit circle realization in the plane.

Collinear(graph[, d])

Return the framework with a realization on the x-axis in the d-dimensional space.

Complete(points)

Generate a framework on the complete graph from a given list of points.

Empty([dim])

Generate an empty framework.

Random(graph[, dim, rand_range])

Return a framework with random realization.

Simplicial(graph[, d])

Return the framework with a realization on the d-simplex.

from_points(points)

Generate a framework from a list of points.

Framework manipulation

add_edge(edge)

Add an edge to the framework.

add_edges(edges)

Add a list of edges to the framework.

add_vertex(point[, vertex])

Add a vertex to the framework with the corresponding coordinates.

add_vertices(points[, vertices])

Add a list of vertices to the framework.

delete_edge(edge)

Delete an edge from the framework.

delete_edges(edges)

Delete a list of edges from the framework.

delete_vertex(vertex)

Delete a vertex from the framework.

delete_vertices(vertices)

Delete a list of vertices from the framework.

rotate2D(angle[, inplace])

Rotate the planar framework counter clockwise.

set_realization(realization)

Change the realization of the framework.

set_vertex_pos(vertex, point)

Change the coordinates of a single given vertex.

set_vertex_positions(subset_of_realization)

Change the coordinates of vertices given by a dictionary.

set_vertex_positions_from_lists(vertices, points)

Change the coordinates of a given list of vertices.

translate(vector[, inplace])

Translate the framework.

Infinitesimal rigidity

inf_flexes([include_trivial, vertex_order])

Return a basis of the space of infinitesimal flexes.

is_dependent()

Check whether the framework is dependent.

is_dict_inf_flex(vert_to_flex, **kwargs)

Return whether a dictionary specifies an infinitesimal flex of the framework.

is_dict_nontrivial_inf_flex(vert_to_flex, ...)

Return whether a dictionary specifies an infinitesimal flex which is nontrivial.

is_dict_trivial_inf_flex(vert_to_flex, **kwargs)

Return whether an infinitesimal flex specified by a dictionary is trivial.

is_independent()

Check whether the framework is independent.

is_inf_flexible()

Check whether the given framework is infinitesimally flexible.

is_inf_rigid()

Check whether the given framework is infinitesimally rigid.

is_isostatic()

Check whether the framework is independent and infinitesimally rigid.

is_min_inf_rigid()

Check whether a framework is minimally infinitesimally rigid.

is_nontrivial_flex(inf_flex, **kwargs)

Alias for Framework.is_vector_nontrivial_inf_flex() and Framework.is_dict_nontrivial_inf_flex().

is_redundantly_rigid()

Check if the framework is infinitesimally redundantly rigid.

is_stress(stress[, edge_order, numerical, ...])

Return whether a vector is a stress.

is_trivial_flex(inf_flex, **kwargs)

Alias for Framework.is_vector_trivial_inf_flex() and Framework.is_dict_trivial_inf_flex().

is_vector_inf_flex(inf_flex[, vertex_order, ...])

Return whether a vector is an infinitesimal flex of the framework.

is_vector_nontrivial_inf_flex(inf_flex[, ...])

Return whether an infinitesimal flex is nontrivial.

is_vector_trivial_inf_flex(inf_flex, **kwargs)

Return whether an infinitesimal flex is trivial.

nontrivial_inf_flexes([vertex_order])

Return non-trivial infinitesimal flexes.

rigidity_matrix([vertex_order, edge_order])

Construct the rigidity matrix of the framework.

rigidity_matrix_rank()

Compute the rank of the rigidity matrix.

stress_matrix(stress[, edge_order, vertex_order])

Construct the stress matrix from a stress of from its support.

stresses([edge_order])

Return a basis of the space of equilibrium stresses.

trivial_inf_flexes([vertex_order])

Return a basis of the vector subspace of trivial infinitesimal flexes.

Other

_check_edge_order([edge_order])

Checks whether the provided edge_order contains the same elements as the graph's edge set.

_check_vertex_order([vertex_order])

Checks whether the provided vertex_order contains the same elements as the graph's vertex set.

_plot_using_projection_matrix(...)

Plot the framework with the realization projected using the given matrix.

_plot_with_2D_realization(realization[, ...])

Plot the graph of the framework with the given realization in the plane.

_transform_inf_flex_to_pointwise(inf_flex[, ...])

Transform the natural data type of a flex (Matrix) to a dictionary that maps a vertex to a Sequence of coordinates (i.e. a vector).

edge_lengths([numerical])

Return the dictionary of the edge lengths.

generate_stl_bars([scale, width_of_bars, ...])

Generate STL files for the bars of the framework.

plot(**kwargs)

Plot the framework.

plot2D([coordinates, inf_flex, ...])

Plot this framework in 2D.

to_tikz([vertex_style, edge_style, ...])

Create a TikZ code for the framework.

Waiting for implementation

Notes

Internally, the realization is represented as Dict[Vertex,Matrix]. However, realization() can also return Dict[Vertex,Point].

classmethod Circular(graph)[source]

Return the framework with a regular unit circle realization in the plane.

Parameters:

graph (Graph) – Underlying graph on which the framework is constructed.

Return type:

Framework

Examples

>>> import pyrigi.graphDB as graphs
>>> F = Framework.Circular(graphs.CompleteBipartite(4, 2))
>>> print(F)
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1, 2, 3, 4, 5] and edges ...
Realization {0:(1, 0), 1:(1/2, sqrt(3)/2), ...
classmethod Collinear(graph, d=1)[source]

Return the framework with a realization on the x-axis in the d-dimensional space.

Parameters:
  • graph (Graph) – Underlying graph on which the framework is constructed.

  • d (int)

Return type:

Framework

Examples

>>> import pyrigi.graphDB as graphs
>>> Framework.Collinear(graphs.Complete(3), d=2)
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1, 2] and edges [[0, 1], [0, 2], [1, 2]]
Realization {0:(0, 0), 1:(1, 0), 2:(2, 0)}
classmethod Complete(points)[source]

Generate a framework on the complete graph from a given list of points.

The vertices of the underlying graph are taken to be the list [0,...,len(points)-1].

Parameters:

points (List[Point]) – The realization of the framework that this method outputs is provided as a list of points.

Return type:

Framework

Examples

>>> F = Framework.Complete([(1,),(2,),(3,),(4,)]); F
Framework in 1-dimensional space consisting of:
Graph with vertices [0, 1, 2, 3] and edges [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
Realization {0:(1,), 1:(2,), 2:(3,), 3:(4,)}
classmethod Empty(dim=2)[source]

Generate an empty framework.

Parameters:

dim (int) – a natural number that determines the dimension in which the framework is realized

Return type:

Framework

Examples

>>> F = Framework.Empty(dim=1); F
Framework in 1-dimensional space consisting of:
Graph with vertices [] and edges []
Realization {}
classmethod Random(graph, dim=2, rand_range=None)[source]

Return a framework with random realization.

Parameters:
  • graph (Graph) – Graph on which the random realization should be constructed.

  • rand_range (int | List[int] | None) – Sets the range of random numbers from which the realization is sampled. The format is either an interval (a,b) or a single integer a, which produces the range (-a,a).

  • dim (int)

Return type:

Framework

Examples

>>> F = Framework.Random(Graph([(0,1), (1,2), (0,2)]))
>>> print(F) 
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1, 2] and edges [[0, 1], [0, 2], [1, 2]]
Realization {0:(122, 57), 1:(27, 144), 2:(50, 98)}

Notes

If rand_range=None, then the range is set to (-10 * n^2 * d).

Todo

Set the correct default range value.

classmethod Simplicial(graph, d=None)[source]

Return the framework with a realization on the d-simplex.

Parameters:
  • graph (Graph) – Underlying graph on which the framework is constructed.

  • d (int | None) – The dimension d has to be at least the number of vertices of the graph minus one. If d is not specified, then the least possible one is used.

Return type:

Framework

Examples

>>> F = Framework.Simplicial(Graph([(0,1), (1,2), (2,3), (0,3)]), 4);
>>> F.realization(as_points=True)
{0: [0, 0, 0, 0], 1: [1, 0, 0, 0], 2: [0, 1, 0, 0], 3: [0, 0, 1, 0]}
>>> F = Framework.Simplicial(Graph([(0,1), (1,2), (2,3), (0,3)]));
>>> F.realization(as_points=True)
{0: [0, 0, 0], 1: [1, 0, 0], 2: [0, 1, 0], 3: [0, 0, 1]}
__getitem__(vertex)[source]

Return the coordinates corresponding to the image of a given vertex under the realization map.

Examples

>>> F = Framework(Graph([[0,1]]), {0:[1,2], 1:[0,5]})
>>> F[0]
Matrix([
[1],
[2]])
Parameters:

vertex (Vertex)

Return type:

MutableDenseMatrix

__repr__()[source]

Return the representation

Return type:

str

__str__()[source]

Return the string representation.

Return type:

str

add_edge(edge)[source]

Add an edge to the framework.

Notes

This method only alters the graph attribute.

Parameters:

edge (Edge)

Return type:

None

add_edges(edges)[source]

Add a list of edges to the framework.

Notes

For each edge that has to be added, add_edge() is called.

Parameters:

edges (List[Edge])

Return type:

None

add_vertex(point, vertex=None)[source]

Add a vertex to the framework with the corresponding coordinates.

If no vertex is provided (None), then the smallest, free integer is chosen instead.

Parameters:
  • point (Point) – the realization of the new vertex

  • vertex (Vertex | None) – the label of the new vertex

Return type:

None

Examples

>>> F = Framework.Empty(dim=2)
>>> F.add_vertex((1.5,2), 'a')
>>> F.add_vertex((3,1))
>>> F
Framework in 2-dimensional space consisting of:
Graph with vertices ['a', 1] and edges []
Realization {a:(1.50000000000000, 2), 1:(3, 1)}
add_vertices(points, vertices=[])[source]

Add a list of vertices to the framework.

Parameters:
  • points (List[Point]) – List of points consisting of coordinates in \(\RR^d\). It is checked that all points lie in the same ambient space.

  • vertices (List[Vertex]) – List of vertices. If the list of vertices is empty, we generate a vertex that is not yet taken with the method add_vertex(). Else, the list of vertices needs to have the same length as the list of points.

Return type:

None

Examples

>>> F = Framework.Empty(dim=2)
>>> F.add_vertices([(1.5,2), (3,1)], ['a',0])
>>> print(F)
Framework in 2-dimensional space consisting of:
Graph with vertices ['a', 0] and edges []
Realization {a:(1.50000000000000, 2), 0:(3, 1)}

Notes

For each vertex that has to be added, add_vertex() is called.

delete_edge(edge)[source]

Delete an edge from the framework.

Parameters:

edge (Edge)

Return type:

None

delete_edges(edges)[source]

Delete a list of edges from the framework.

Parameters:

edges (List[Edge])

Return type:

None

delete_vertex(vertex)[source]

Delete a vertex from the framework.

Parameters:

vertex (Vertex)

Return type:

None

delete_vertices(vertices)[source]

Delete a list of vertices from the framework.

Parameters:

vertices (List[Vertex])

Return type:

None

dim()[source]

Return the dimension of the framework.

Return type:

int

dimension()[source]

Alias for dim()

Return type:

int

edge_lengths(numerical=False)[source]

Return the dictionary of the edge lengths.

Parameters:

numerical (bool) – If True, numerical positions are used for the computation of the edge lengths.

Return type:

Dict[Edge, Coordinate]

Examples

>>> G = Graph([(0,1), (1,2), (2,3), (0,3)])
>>> F = Framework(G, {0:[0,0], 1:[1,0], 2:[1,'1/2 * sqrt(5)'], 3:['1/2','4/3']})
>>> F.edge_lengths(numerical=False)
{(0, 1): 1, (0, 3): sqrt(73)/6, (1, 2): sqrt(5)/2, (2, 3): sqrt((-4/3 + sqrt(5)/2)**2 + 1/4)}
>>> F.edge_lengths(numerical=True)
{(0, 1): 1.0, (0, 3): 1.4240006242195884, (1, 2): 1.118033988749895, (2, 3): 0.5443838790578374}
classmethod from_points(points)[source]

Generate a framework from a list of points.

The list of vertices of the underlying graph is taken to be [0,...,len(points)-1]. The underlying graph has no edges.

Parameters:

points (List[Point]) – The realization of the framework that this method outputs is provided as a list of points.

Return type:

Framework

Examples

>>> F = Framework.from_points([(1,2), (2,3)])
>>> print(F)
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1] and edges []
Realization {0:(1, 2), 1:(2, 3)}
generate_stl_bars(scale=1.0, width_of_bars=8.0, height_of_bars=3.0, holes_diameter=4.3, filename_prefix='bar_', output_dir='stl_output')[source]

Generate STL files for the bars of the framework.

Generates STL files for the bars of the framework. The files are generated in the working folder. The naming convention for the files is bar_i-j.stl, where i and j are the vertices of an edge.

Parameters:
  • scale (float) – Scale factor for the lengths of the edges, default is 1.0.

  • width_of_bars (float) – Width of the bars, default is 8.0 mm.

  • height_of_bars (float) – Height of the bars, default is 3.0 mm.

  • holes_diameter (float) – Diameter of the holes at the ends of the bars, default is 4.3 mm.

  • filename_prefix (str) – Prefix for the filenames of the generated STL files, default is bar_.

  • output_dir (str) – Name or path of the folder where the STL files are saved, default is stl_output. Relative to the working directory.

Return type:

None

Examples

>>> G = Graph([(0,1), (1,2), (2,3), (0,3)])
>>> F = Framework(G, {0:[0,0], 1:[1,0], 2:[1,'1/2 * sqrt(5)'], 3:[1/2,'4/3']})
>>> F.generate_stl_bars(scale=20)
STL files for the bars have been generated in the chosen folder.
graph()[source]

Return a copy of the underlying graph.

Examples

>>> F = Framework.Random(Graph([(0,1), (1,2), (0,2)]))
>>> F.graph()
Graph with vertices [0, 1, 2] and edges [[0, 1], [0, 2], [1, 2]]
Return type:

Graph

inf_flexes(include_trivial=False, vertex_order=None)[source]

Return a basis of the space of infinitesimal flexes.

Return a lift of a basis of the quotient of the vector space of infinitesimal flexes modulo trivial infinitesimal flexes, if include_trivial=False. Return a basis of the vector space of infinitesimal flexes if include_trivial=True. Else, return the entire kernel.

Definitions

Parameters:
  • include_trivial (bool) – Boolean that decides, whether the trivial flexes should be included (True) or not (False)

  • vertex_order (List[Vertex] | None) – A list of vertices, providing the ordering for the entries of the infinitesimal flexes. If none is provided, the list from vertex_list() is taken.

Return type:

List[MutableDenseMatrix]

Examples

>>> F = Framework.Complete([[0,0], [1,0], [1,1], [0,1]])
>>> F.delete_edges([(0,2), (1,3)])
>>> F.inf_flexes(include_trivial=False)
[Matrix([
[1],
[0],
[1],
[0],
[0],
[0],
[0],
[0]])]
>>> F = Framework(Graph([[0, 1], [0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]), {0: [0, 0], 1: [0, 1], 2: [0, 2], 3: [1, 2], 4: [-1, 2]})
>>> F.inf_flexes()
[Matrix([
[0],
[0],
[0],
[0],
[0],
[1],
[0],
[0],
[0],
[0]])]
is_congruent(other_framework, numerical=False, tolerance=1e-09)[source]

Return whether the given framework is congruent to self.

Parameters:
  • other_framework (Framework) – The framework for checking the congruence.

  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

is_congruent_realization(other_realization, numerical=False, tolerance=1e-09)[source]

Return whether the given realization is congruent to self.

Parameters:
  • other_realization (Dict[Vertex, Point]) – The realization for checking the congruence.

  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

is_dependent()[source]

Check whether the framework is dependent.

Notes

See also is_independent().

Return type:

bool

is_dict_inf_flex(vert_to_flex, **kwargs)[source]

Return whether a dictionary specifies an infinitesimal flex of the framework.

Definitions

Infinitesimal flex

Parameters:

vert_to_flex (Dict[Vertex, Sequence[Coordinate]]) – Dictionary that maps the vertex labels to vectors of the same dimension as the framework is.

Return type:

bool

Notes

See Framework.is_vector_inf_flex().

Examples

>>> F = Framework.Complete([[0,0], [1,1]])
>>> F.is_dict_inf_flex({0:[0,0], 1:[-1,1]})
True
>>> F.is_dict_inf_flex({0:[0,0], 1:["sqrt(2)","-sqrt(2)"]})
True
is_dict_nontrivial_inf_flex(vert_to_flex, **kwargs)[source]

Return whether a dictionary specifies an infinitesimal flex which is nontrivial.

Definitions

Nontrivial infinitesimal Flex

Parameters:
  • inf_flex – An infinitesimal flex of the framework in the form of a dictionary.

  • vert_to_flex (Dict[Vertex, Sequence[Coordinate]])

Return type:

bool

Notes

See Framework.is_vector_nontrivial_inf_flex() for details, particularly concerning the possible parameters.

Examples

>>> from pyrigi import frameworkDB as fws
>>> F = fws.Square()
>>> q = {0:[0,0], 1: [0,0], 2:[-2,0], 3:[-2,0]}
>>> F.is_dict_nontrivial_inf_flex(q)
True
>>> q = {0:[1,-1], 1: [1,1], 2:[-1,1], 3:[-1,-1]}
>>> F.is_dict_nontrivial_inf_flex(q)
False
is_dict_trivial_inf_flex(vert_to_flex, **kwargs)[source]

Return whether an infinitesimal flex specified by a dictionary is trivial.

Definitions

Trivial infinitesimal flex

Parameters:
  • inf_flex – An infinitesimal flex of the framework in the form of a dictionary.

  • vert_to_flex (Dict[Vertex, Sequence[Coordinate]])

Return type:

bool

Notes

See Framework.is_vector_trivial_inf_flex() for details, particularly concerning the possible parameters.

Examples

>>> from pyrigi import frameworkDB as fws
>>> F = fws.Square()
>>> q = {0:[0,0], 1: [0,0], 2:[-2,0], 3:[-2,0]}
>>> F.is_dict_trivial_inf_flex(q)
False
>>> q = {0:[1,-1], 1: [1,1], 2:[-1,1], 3:[-1,-1]}
>>> F.is_dict_trivial_inf_flex(q)
True
is_equivalent(other_framework, numerical=False, tolerance=1e-09)[source]

Return whether the given framework is equivalent to self.

Parameters:
  • other_framework (Framework) – The framework for checking the equivalence.

  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

is_equivalent_realization(other_realization, numerical=False, tolerance=1e-09)[source]

Return whether the given realization is equivalent to self.

Parameters:
  • other_realization (Dict[Vertex, Point]) – The realization for checking the equivalence.

  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

is_independent()[source]

Check whether the framework is independent.

Examples

>>> F = Framework.Complete([[0,0], [1,0], [1,1], [0,1]])
>>> F.is_independent()
False
>>> F.delete_edge((0,2))
>>> F.is_independent()
True
Return type:

bool

is_inf_flexible()[source]

Check whether the given framework is infinitesimally flexible.

See is_inf_rigid()

Return type:

bool

is_inf_rigid()[source]

Check whether the given framework is infinitesimally rigid.

The check is based on rigidity_matrix_rank().

Definitions

Examples

>>> from pyrigi import frameworkDB
>>> F1 = frameworkDB.CompleteBipartite(4,4)
>>> F1.is_inf_rigid()
True
>>> F2 = frameworkDB.Cycle(4,d=2)
>>> F2.is_inf_rigid()
False
Return type:

bool

is_injective(numerical=False, tolerance=1e-09)[source]

Return whether the realization is injective.

Parameters:
  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

Notes

For comparing whether two vectors are the same, misc.is_zero_vector() is used. See its documentation for the description of the parameters.

is_isostatic()[source]

Check whether the framework is independent and infinitesimally rigid.

Return type:

bool

is_min_inf_rigid()[source]

Check whether a framework is minimally infinitesimally rigid.

Definitions

Minimal infinitesimal rigidity

Examples

>>> F = Framework.Complete([[0,0], [1,0], [1,1], [0,1]])
>>> F.is_min_inf_rigid()
False
>>> F.delete_edge((0,2))
>>> F.is_min_inf_rigid()
True
Return type:

bool

is_nontrivial_flex(inf_flex, **kwargs)[source]

Alias for Framework.is_vector_nontrivial_inf_flex() and Framework.is_dict_nontrivial_inf_flex().

Notes

We distinguish between instances of list and instances of dict to call one of the alias methods.

Parameters:

inf_flex (List[Coordinate] | Dict[Vertex, Sequence[Coordinate]])

Return type:

bool

is_prestress_stable()[source]

Todo

Implement

Return type:

bool

is_quasi_injective(numerical=False, tolerance=1e-09)[source]

Return whether the realization is quasi-injective.

Parameters:
  • numerical (bool) – Whether the check is symbolic (default) or numerical.

  • tolerance (float) – Used tolerance when checking numerically.

Return type:

bool

Notes

For comparing whether two vectors are the same, misc.is_zero_vector() is used. See its documentation for the description of the parameters.

is_redundantly_rigid()[source]

Check if the framework is infinitesimally redundantly rigid.

Definitions

Redundant infinitesimal rigidity

Todo

tests

Examples

>>> F = Framework.Empty(dim=2)
>>> F.add_vertices([(1,0), (1,1), (0,3), (-1,1)], ['a','b','c','d'])
>>> F.add_edges([('a','b'), ('b','c'), ('c','d'), ('a','d'), ('a','c'), ('b','d')])
>>> F.is_redundantly_rigid()
True
>>> F.delete_edge(('a','c'))
>>> F.is_redundantly_rigid()
False
Return type:

bool

is_stress(stress, edge_order=None, numerical=False, tolerance=1e-09)[source]

Return whether a vector is a stress.

Definitions

Equilibrium stress

Parameters:
  • stress (Sequence[int | float | str]) – A vector to be checked whether it is a stress of the framework.

  • edge_order (List[Edge] | None) – A list of edges, providing the ordering for the entries of the stress. If none is provided, the list from edge_list() is taken.

  • numerical (bool) – A Boolean determining whether the evaluation of the product of the stress and the rigidity matrix is symbolic or numerical.

  • tolerance – Absolute tolerance that is the threshold for acceptable equilibrium stresses. This parameter is used to determine the number of digits, to which accuracy the symbolic expressions are evaluated.

Return type:

bool

Examples

>>> G = Graph([[0,1],[0,2],[0,3],[1,2],[2,3],[3,1]])
>>> pos = {0: (0, 0), 1: (0,1), 2: (-1,-1), 3: (1,-1)}
>>> F = Framework(G, pos)
>>> omega1 = [-8, -4, -4, 2, 2, 1]
>>> F.is_stress(omega1)
True
>>> omega1[0] = 0
>>> F.is_stress(omega1)
False
is_trivial_flex(inf_flex, **kwargs)[source]

Alias for Framework.is_vector_trivial_inf_flex() and Framework.is_dict_trivial_inf_flex().

Notes

We distinguish between instances of list and instances of dict to call one of the alias methods.

Parameters:

inf_flex (List[Coordinate] | Dict[Vertex, Sequence[Coordinate]])

Return type:

bool

is_vector_inf_flex(inf_flex, vertex_order=None, numerical=False, tolerance=1e-09)[source]

Return whether a vector is an infinitesimal flex of the framework.

Definitions

Infinitesimal Flex Rigidity Matrix

Parameters:
  • inf_flex (List[Coordinate]) – An infinitesimal flex of the framework specified by a vector.

  • vertex_order (List[Vertex] | None) – A list of vertices specifying the order in which inf_flex is given. If none is provided, the list from vertex_list() is taken.

  • numerical (bool) – A Boolean determining whether the evaluation of the product of the inf_flex and the rigidity matrix is symbolic or numerical.

  • tolerance (float) – Absolute tolerance that is the threshold for acceptable numerical flexes. This parameter is used to determine the number of digits, to which accuracy the symbolic expressions are evaluated.

Return type:

bool

Examples

>>> from pyrigi import frameworkDB as fws
>>> F = fws.Square()
>>> q = [0,0,0,0,-2,0,-2,0]
>>> F.is_vector_inf_flex(q)
True
>>> q[0] = 1
>>> F.is_vector_inf_flex(q)
False
>>> F = Framework.Complete([[0,0], [1,1]])
>>> F.is_vector_inf_flex(["sqrt(2)","-sqrt(2)",0,0], vertex_order=[1,0])
True
is_vector_nontrivial_inf_flex(inf_flex, vertex_order=None, numerical=False, tolerance=1e-09)[source]

Return whether an infinitesimal flex is nontrivial.

Definitions

Nontrivial infinitesimal Flex

Parameters:
  • inf_flex (List[Coordinate]) – An infinitesimal flex of the framework.

  • vertex_order (List[Vertex] | None) – A list of vertices specifying the order in which inf_flex is given. If none is provided, the list from vertex_list() is taken.

  • numerical (bool) – A Boolean determining whether the evaluation of the product of the inf_flex and the rigidity matrix is symbolic or numerical.

  • tolerance (float) – Absolute tolerance that is the threshold for acceptable numerical flexes. This parameter is used to determine the number of digits, to which accuracy the symbolic expressions are evaluated.

Return type:

bool

Notes

This is done by solving a linear system composed of a matrix A whose columns are given by a basis of the trivial flexes and the vector b given by the input flex. b is trivial if and only if there is a linear combination of the columns in A producing b. In other words, when there is a solution to Ax=b, then b is a trivial infinitesimal motion. Otherwise, b is nontrivial.

In the numerical=True case we compute a least squares solution x of the overdetermined linear system and compare the values in Ax to the values in b.

Examples

>>> from pyrigi import frameworkDB as fws
>>> F = fws.Square()
>>> q = [0,0,0,0,-2,0,-2,0]
>>> F.is_vector_nontrivial_inf_flex(q)
True
>>> q = [1,-1,1,1,-1,1,-1,-1]
>>> F.is_vector_inf_flex(q)
True
>>> F.is_vector_nontrivial_inf_flex(q)
False
is_vector_trivial_inf_flex(inf_flex, **kwargs)[source]

Return whether an infinitesimal flex is trivial.

Definitions

Trivial infinitesimal Flex

Parameters:

inf_flex (List[Coordinate]) – An infinitesimal flex of the framework.

Return type:

bool

Notes

See Framework.is_nontrivial_vector_inf_flex() for details, particularly concerning the possible parameters.

Examples

>>> from pyrigi import frameworkDB as fws
>>> F = fws.Square()
>>> q = [0,0,0,0,-2,0,-2,0]
>>> F.is_vector_trivial_inf_flex(q)
False
>>> q = [1,-1,1,1,-1,1,-1,-1]
>>> F.is_vector_trivial_inf_flex(q)
True
nontrivial_inf_flexes(vertex_order=None)[source]

Return non-trivial infinitesimal flexes.

Definitions

Infinitesimal flex

Parameters:

vertex_order (List[Vertex] | None) – A list of vertices, providing the ordering for the entries of the infinitesimal flexes. If none is provided, the list from vertex_list() is taken.

Return type:

List[MutableDenseMatrix]

Examples

>>> import pyrigi.graphDB as graphs
>>> F = Framework.Circular(graphs.CompleteBipartite(3, 3))
>>> F.nontrivial_inf_flexes()
[Matrix([
[       3/2],
[-sqrt(3)/2],
[         1],
[         0],
[         0],
[         0],
[       3/2],
[-sqrt(3)/2],
[         1],
[         0],
[         0],
[         0]])]

Notes

See trivial_inf_flexes().

pinned_rigidity_matrix(pinned_vertices=None, vertex_order=None, edge_order=None)[source]

Construct the rigidity matrix of the framework.

Parameters:
  • vertex_order (List[Vertex] | None) – A list of vertices, providing the ordering for the columns of the rigidity matrix.

  • edge_order (List[Edge] | None) – A list of edges, providing the ordering for the rows of the rigidity matrix.

  • pinned_vertices (Dict[Vertex, List[int]] | None)

Return type:

MutableDenseMatrix

Todo

definition of pinned rigidity matrix, tests

Examples

>>> F = Framework(Graph([[0, 1], [0, 2]]), {0: [0, 0], 1: [1, 0], 2: [1, 1]})
>>> F.pinned_rigidity_matrix()
Matrix([
[-1,  0, 1, 0, 0, 0],
[-1, -1, 0, 0, 1, 1],
[ 1,  0, 0, 0, 0, 0],
[ 0,  1, 0, 0, 0, 0],
[ 0,  0, 1, 0, 0, 0]])
plot(**kwargs)[source]

Plot the framework.

If the dimension of the framework is greater than 2, ValueError is raised, use Framework.plot2D() instead. For various formatting options, see Graph.plot().

Todo

Implement plotting in dimension 3 and better plotting for dimension 1 using connectionstyle

Return type:

None

plot2D(coordinates=None, inf_flex=None, projection_matrix=None, return_matrix=False, random_seed=None, **kwargs)[source]

Plot this framework in 2D.

If this framework is in dimensions higher than 2 and projection_matrix with coordinates are None a random projection matrix containing two orthonormal vectors is generated and used for projection into 2D. This matrix is then returned. For various formatting options, see Graph.plot(). Only coordinates or projection_matrix parameter can be used, not both!

Parameters:
  • projection_matrix (MutableDenseMatrix | None) – The matrix used for projecting the placement of vertices only when they are in dimension higher than 2. The matrix must have dimensions (2, dim), where dim is the dimension of the currect placements of vertices. If None, a random projection matrix is generated.

  • random_seed (int | None) – The random seed used for generating the projection matrix. When the same value is provided, the framework will plot exactly same.

  • coordinates (tuple | List | None) – Indexes of two coordinates that will be used as the placement in 2D.

  • inf_flex (MutableDenseMatrix | int | Dict[Vertex, Sequence[Coordinate]] | None) – Optional parameter for plotting a given infinitesimal flex. It is important to use the same vertex order as the one from Graph.vertex_list(). Alternatively, an int can be specified to choose the 0,1,2,…-th nontrivial infinitesimal flex for plotting. Lastly, a Dict[Vertex, Sequence[Coordinate]] can be provided, which maps the vertex labels to vectors (i.e. a sequence of coordinates).

  • return_matrix (bool) – If True the matrix used for projection into 2D is returned.

Return type:

MutableDenseMatrix | None

Todo

project the inf-flex as well in _plot_using_projection_matrix.

realization(as_points=False, numerical=False)[source]

Return a copy of the realization.

Parameters:
  • as_points (bool) – If True, then the vertex positions type is Point, otherwise Matrix (default).

  • numerical (bool) – If True, the vertex positions are converted to floats.

Return type:

Dict[Vertex, Point]

Examples

>>> F = Framework.Complete([(0,0), (1,0), (1,1)])
>>> F.realization(as_points=True)
{0: [0, 0], 1: [1, 0], 2: [1, 1]}
>>> F.realization()
{0: Matrix([
[0],
[0]]), 1: Matrix([
[1],
[0]]), 2: Matrix([
[1],
[1]])}

Notes

The format returned by this method with as_points=True can be read by networkx.

rigidity_matrix(vertex_order=None, edge_order=None)[source]

Construct the rigidity matrix of the framework.

Definitions

Parameters:
  • vertex_order (List[Vertex] | None) – A list of vertices, providing the ordering for the columns of the rigidity matrix. If none is provided, the list from vertex_list() is taken.

  • edge_order (List[Edge] | None) – A list of edges, providing the ordering for the rows of the rigidity matrix. If none is provided, the list from edge_list() is taken.

Return type:

MutableDenseMatrix

Examples

>>> F = Framework.Complete([(0,0),(2,0),(1,3)])
>>> F.rigidity_matrix()
Matrix([
[-2,  0, 2,  0,  0, 0],
[-1, -3, 0,  0,  1, 3],
[ 0,  0, 1, -3, -1, 3]])
rigidity_matrix_rank()[source]

Compute the rank of the rigidity matrix.

Examples

>>> K4 = Framework.Complete([[0,0], [1,0], [1,1], [0,1]])
>>> K4.rigidity_matrix_rank()   # the complete graph is a circuit
5
>>> K4.delete_edge([0,1])
>>> K4.rigidity_matrix_rank()   # deleting a bar gives full rank
5
>>> K4.delete_edge([2,3])
>>> K4.rigidity_matrix_rank()   #so now deleting an edge lowers the rank
4
Return type:

int

rotate2D(angle, inplace=True)[source]

Rotate the planar framework counter clockwise.

Parameters:
  • angle (float) – Rotation angle

  • inplace (bool) – If True (default), then this framework is rotated. Otherwise, a new rotated framework is returned.

Return type:

None | Framework

set_realization(realization)[source]

Change the realization of the framework.

Parameters:

realization (Dict[Vertex, Point]) – a realization of the underlying graph of the framework

Return type:

None

Notes

It is assumed that the realization contains all vertices from the underlying graph. Furthermore, all points in the realization need to be contained in \(\RR^d\) for a fixed \(d\).

Examples

>>> F = Framework.Complete([(0,0), (1,0), (1,1)])
>>> F.set_realization({vertex:(vertex,vertex+1) for vertex in F.graph().vertex_list()})
>>> print(F)
Framework in 2-dimensional space consisting of:
Graph with vertices [0, 1, 2] and edges [[0, 1], [0, 2], [1, 2]]
Realization {0:(0, 1), 1:(1, 2), 2:(2, 3)}
set_vertex_pos(vertex, point)[source]

Change the coordinates of a single given vertex.

Examples

>>> F = Framework.from_points([(0,0)])
>>> F.set_vertex_pos(0, (6,2))
>>> print(F)
Framework in 2-dimensional space consisting of:
Graph with vertices [0] and edges []
Realization {0:(6, 2)}
Parameters:
  • vertex (Vertex)

  • point (Point)

Return type:

None

set_vertex_positions(subset_of_realization)[source]

Change the coordinates of vertices given by a dictionary.

Examples

>>> F = Framework.Complete([(0,0),(0,0),(1,0),(1,0)]);
>>> F.realization(as_points=True)
{0: [0, 0], 1: [0, 0], 2: [1, 0], 3: [1, 0]}
>>> F.set_vertex_positions({1:(0,1),3:(1,1)});
>>> F.realization(as_points=True)
{0: [0, 0], 1: [0, 1], 2: [1, 0], 3: [1, 1]}

Notes

See set_vertex_pos().

Parameters:

subset_of_realization (Dict[Vertex, Point])

set_vertex_positions_from_lists(vertices, points)[source]

Change the coordinates of a given list of vertices.

Examples

>>> F = Framework.Complete([(0,0),(0,0),(1,0),(1,0)]);
>>> F.realization(as_points=True)
{0: [0, 0], 1: [0, 0], 2: [1, 0], 3: [1, 0]}
>>> F.set_vertex_positions_from_lists([1,3], [(0,1),(1,1)]);
>>> F.realization(as_points=True)
{0: [0, 0], 1: [0, 1], 2: [1, 0], 3: [1, 1]}

Notes

It is necessary that both lists have the same length. No vertex from vertices can be contained multiple times. We apply the method set_vertex_pos() to vertices and points.

Parameters:
  • vertices (List[Vertex])

  • points (List[Point])

Return type:

None

stress_matrix(stress, edge_order=None, vertex_order=None)[source]

Construct the stress matrix from a stress of from its support.

The matrix order is the one from vertex_list().

Definitions

Parameters:
  • stress (Sequence[int | float | str]) – A stress of the framework.

  • edge_order (List[Edge] | None) – A list of edges, providing the ordering for the rows of the stress matrix.

  • vertex_order (List[Vertex] | None) – By listing vertices in the preferred order, the rigidity matrix can be computed in a way the user expects.

Return type:

MutableDenseMatrix

Examples

>>> G = Graph([[0,1],[0,2],[0,3],[1,2],[2,3],[3,1]])
>>> pos = {0: (0, 0), 1: (0,1), 2: (-1,-1), 3: (1,-1)}
>>> F = Framework(G, pos)
>>> omega = [-8, -4, -4, 2, 2, 1]
>>> F.stress_matrix(omega)
Matrix([
[-16,  8,  4,  4],
[  8, -4, -2, -2],
[  4, -2, -1, -1],
[  4, -2, -1, -1]])
stresses(edge_order=None)[source]

Return a basis of the space of equilibrium stresses.

Definitions

Equilibrium stress

Parameters:

edge_order (List[Edge] | None) – A list of edges, providing the ordering for the entries of the stresses. If none is provided, the list from edge_list() is taken.

Return type:

List[MutableDenseMatrix]

Examples

>>> G = Graph([[0,1],[0,2],[0,3],[1,2],[2,3],[3,1]])
>>> pos = {0: (0, 0), 1: (0,1), 2: (-1,-1), 3: (1,-1)}
>>> F = Framework(G, pos)
>>> F.stresses()
[Matrix([
[-8],
[-4],
[-4],
[ 2],
[ 2],
[ 1]])]

Todo

tests

to_tikz(vertex_style='fvertex', edge_style='edge', label_style='labelsty', figure_opts='', vertex_in_labels=False, vertex_out_labels=False, default_styles=True)[source]

Create a TikZ code for the framework. Works for dimension 2 only.

For using it in LaTeX you need to use the tikz package.

Parameters:
  • vertex_style (Union(str, dict[str:list[Vertex]])) – If a single style is given as a string, then all vertices get this style. If a dictionary from styles to a list of vertices is given, vertices are put in style accordingly. The vertices missing in the dictionary do not get a style.

  • edge_style (Union(str, dict[str:list[Edge]])) – If a single style is given as a string, then all edges get this style. If a dictionary from styles to a list of edges is given, edges are put in style accordingly. The edges missing in the dictionary do not get a style.

  • label_style (str) – The style for labels that are placed next to vertices.

  • figure_opts (str) – Options for the tikzpicture environment.

  • vertex_in_labels (bool) – A bool on whether vertex names should be put as labels on the vertices.

  • vertex_out_labels (bool) – A bool on whether vertex names should be put next to vertices.

  • default_styles (bool) – A bool on whether default style definitions should be put to the options.

Return type:

str

Examples

>>> G = Graph([(0, 1), (1, 2), (2, 3), (0, 3)])
>>> F=Framework(G,{0: [0, 0], 1: [1, 0], 2: [1, 1], 3: [0, 1]})
>>> print(F.to_tikz()) 
\begin{tikzpicture}[fvertex/.style={circle,inner sep=0pt,minimum size=3pt,fill=white,draw=black,double=white,double distance=0.25pt,outer sep=1pt},edge/.style={line width=1.5pt,black!60!white}]
   \node[fvertex] (0) at (0, 0) {};
   \node[fvertex] (1) at (1, 0) {};
   \node[fvertex] (2) at (1, 1) {};
   \node[fvertex] (3) at (0, 1) {};
   \draw[edge] (0) to (1) (0) to (3) (1) to (2) (2) to (3);
\end{tikzpicture}
>>> print(F.to_tikz(vertex_in_labels=True)) 
\begin{tikzpicture}[fvertex/.style={circle,inner sep=1pt,minimum size=3pt,fill=white,draw=black,double=white,double distance=0.25pt,outer sep=1pt,font=\scriptsize},edge/.style={line width=1.5pt,black!60!white}]
   \node[fvertex] (0) at (0, 0) {$0$};
   \node[fvertex] (1) at (1, 0) {$1$};
   \node[fvertex] (2) at (1, 1) {$2$};
   \node[fvertex] (3) at (0, 1) {$3$};
   \draw[edge] (0) to (1) (0) to (3) (1) to (2) (2) to (3);
\end{tikzpicture}

For more examples on formatting options, see also Graph.to_tikz().

translate(vector, inplace=True)[source]

Translate the framework.

Parameters:
  • vector (Point) – Translation vector

  • inplace (bool) – If True (default), then this framework is translated. Otherwise, a new translated framework is returned.

Return type:

None | Framework

trivial_inf_flexes(vertex_order=None)[source]

Return a basis of the vector subspace of trivial infinitesimal flexes.

Definitions

Parameters:

vertex_order (List[Vertex] | None) – A list of vertices, providing the ordering for the entries of the infinitesimal flexes.

Return type:

List[MutableDenseMatrix]

Examples

>>> F = Framework.Complete([(0,0), (2,0), (0,2)])
>>> F.trivial_inf_flexes()
[Matrix([
[1],
[0],
[1],
[0],
[1],
[0]]), Matrix([
[0],
[1],
[0],
[1],
[0],
[1]]), Matrix([
[ 0],
[ 0],
[ 0],
[ 2],
[-2],
[ 0]])]