neuralqx.graph.core.utils.signs module

Edge sign utilities used by GraphHandler.

This module computes orientation dependent sign data associated with ordered edge pairs in planar embeddings and ordered edge triples in non planar embeddings.

Planar case For a vertex \(v\) and two outgoing directed edges \(e_1=(v\to v_1)\) and \(e_2=(v\to v_2)\), let \(t_1,t_2\in\mathbb R^2\) be the corresponding tangent vectors in the embedding. The sign is determined by the relative orientation of the two directions, which can be understood via the oriented area

\[\operatorname{sgn}\bigl(t_1 \times t_2\bigr) = \operatorname{sgn}\bigl(t_{1x} t_{2y} - t_{1y} t_{2x}\bigr)\]

In practice this module uses angular ordering derived from numpy.arctan2() and a deterministic convention for clockwise versus anticlockwise comparison, combined with a handler supplied factor that accounts for edge direction conventions.

Non planar case For a vertex \(v\) and three incident directed edges, a sign is computed from the determinant of the matrix whose columns are the three tangent vectors \(c_1,c_2,c_3\in\mathbb R^3\)

\[\varepsilon(e_1,e_2,e_3) = \operatorname{sgn}\bigl(\det[c_1\ c_2\ c_3]\bigr)\]

This yields values in \(\{-1,0,+1\}\) where zero indicates coplanarity or numerical degeneracy. For non planar multigraphs, the higher level NonplanarSigns helper is used to ensure a generic configuration by applying small deterministic perturbations to coincident tangents before evaluating determinants.

compute_sgn_det(handler, edge_set)

Compute the sign of the determinant formed by three incident edge tangents in 3D.

Given a list of three keyed edges (u, v, key), this constructs three 3D direction vectors \(c_1,c_2,c_3\) from the handler stored non planar coordinates and computes

\[s = \operatorname{sgn}\bigl(\det[c_1\ c_2\ c_3]\bigr)\]

where the columns are the three vectors. The sign takes values in \(\{-1,0,+1\}\).

The orientation of each tangent is chosen consistently with the handler’s original edge orientation. If a reversed directed edge exists in handler._original_edges, the corresponding tangent is flipped so that the local direction at the incident vertex is used consistently.

Parameters:
  • handler (GraphHandler) – GraphHandler instance providing _nonplanar_int2orig_map and _original_edges.

  • edge_set (list[tuple[int, int, int]]) – List of exactly three keyed edges as (u, v, key).

Return type:

float

Returns:

Sign of the determinant, as a float that is numerically one of -1.0, 0.0, +1.0.

Raises:
  • KeyError – If a vertex label in edge_set is missing from the handler coordinate map.

  • ValueError – If edge_set does not contain exactly three edges.

compute_sign_at_vertex(handler, vertex)

Compute determinant signs for all ordered triples of keyed edges incident to a vertex.

This enumerates all ordered triples of incident keyed edges at vertex and stores, for each triple, the sign returned by compute_sgn_det().

If \(E(v)\) is the set of incident keyed edges at vertex \(v\), then this evaluates

\[\varepsilon(e_i,e_j,e_k) = \operatorname{sgn}\bigl(\det[c_i\ c_j\ c_k]\bigr)\]

for all ordered triples \((e_i,e_j,e_k)\in E(v)^3\) with distinct edges.

The returned dictionary uses stringified triples as keys, suitable for JSON style logging.

Parameters:
  • handler (GraphHandler) – GraphHandler instance providing access to the NetworkX multigraph and coordinate map.

  • vertex – Vertex identifier as used by the handler NetworkX graph.

Return type:

dict[str, float]

Returns:

Mapping from stringified ordered edge triples to determinant sign values.

compute_non_planar_graph_signs(handler, graph_type='graph')

Compute and store non planar sign tables for every vertex of the selected graph.

This routine delegates to NonplanarSigns, which computes per vertex \(\varepsilon\) tables based on determinant signs of triplets of tangents on \(\mathbb R^3\). For a vertex \(v\) and three incident edges, the sign is

\[\varepsilon(e_1,e_2,e_3) = \operatorname{sgn}\bigl(\det[c_1\ c_2\ c_3]\bigr)\]

where each \(c_i\) is a unit tangent at \(v\). For multiedges that would produce coincident tangents, NonplanarSigns applies a small deterministic perturbation to produce a generic configuration before taking determinants.

Depending on graph_type, the results are stored into either handler.graph_signs or handler.dual_graph_signs using stringified vertex identifiers as top level keys.

Parameters:
  • handler (GraphHandler) – GraphHandler instance providing graphs and storage dictionaries.

  • graph_type (str) – Either "graph" for the primal graph or any other value for the dual graph.

Return type:

None

Returns:

None.

compute_signs(handler, graph_type='graph', show_plots=False)

Compute and store edge sign data for planar or non planar graphs, primal or dual.

This is the main entry point used by GraphHandler. It chooses between planar and non planar logic based on the handler flag.

Non planar graphs For non planar graphs, this calls compute_non_planar_graph_signs() and returns.

Planar graphs For planar graphs, this computes signs for ordered pairs of edges incident at each vertex using _find_sign(). For a chosen vertex \(u\) and two edges \((u\to v_1)\) and \((u\to v_2)\), it constructs direction vectors

\[t_1 = p(v_1) - p(u), \qquad t_2 = p(v_2) - p(u)\]

and assigns a sign based on angular ordering of \(t_1\) and \(t_2\). The raw sign is then multiplied by handler._get_edge_direction_factor to enforce a consistent convention under edge orientation changes.

Results are stored into the appropriate handler dictionaries

  • handler.graph_signs and handler.graph_positions for graph_type equal to "graph"

  • handler.dual_graph_signs and handler.dual_graph_positions otherwise

The stored positions capture the origin shifted vectors used to compute the sign, which is useful for debugging and optional plotting.

Parameters:
  • handler (GraphHandler) – GraphHandler instance providing layout positions, connectivity information, and storage.

  • graph_type (str) – Either "graph" for the primal graph or any other value for the dual graph.

  • show_plots (bool) – If True, enable optional plotting in _find_sign(). Currently this raises an error because plotting is not implemented in the low level helper.

Return type:

None

Returns:

None.