Skip to content

quality_control

complex_quality(complex)

Computes various regularity estimators on a simplicial complex.

Parameters:

Name Type Description Default
complex SimplicialComplex

The n-simplicial complex to analyze.

required

Returns:

Type Description
DataFrame

A pandas DataFrame containing regularity estimator values for each n-simplex of the considered n-complex.

Notes

List of the regularity estimators computed: * regularity score * well-centeredness score

Source code in src/dxtr/utils/quality_control.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def complex_quality(complex: SimplicialComplex) -> pd.DataFrame[float]:
    """Computes various regularity estimators on a simplicial complex.

    Parameters
    ----------
    complex : SimplicialComplex
        The n-simplicial complex to analyze.

    Returns
    -------
    pd.DataFrame
        A pandas DataFrame containing regularity estimator values 
        for each n-simplex of the considered n-complex.

    Notes
    -----
    List of the regularity estimators computed:
    * regularity score
    * well-centeredness score
    """

    shape_regularity = shape_regularity_score(complex, return_scores=True)
    wc_ratio, well_centeredness = well_centered_score(complex,
                                                      return_scores=True)

    is_well_centered = [score<0 for score in well_centeredness]

    return pd.DataFrame({'Shape regularity score': shape_regularity,
                         'Well-centeredness score': well_centeredness,
                         'Well-centered': is_well_centered
                        })

shape_regularity_score(cplx, return_scores=False)

Quantifies the regularity of a simplicial complex.

Parameters:

Name Type Description Default
cplx SimplicialComplex

The n-simplicial complex to consider.

required
return_scores bool

If True, returns an array with the regularity scores of all n-simplices. Else returns only the median value and the standard deviation. Default is False.

False

Returns:

Type Description
tuple of float or np.ndarray

(Median, standard deviation) or array of all n-simplex regularity scores.

Notes
  • The computed scores are only relevant for k-simplices with k>=2.
  • The score is based on the comparison of the edge lenghts. A regular k-simplex with edges of the same length will score 1.
See also

The simplex_shape_regularity_score() function within the same sub-module.

Source code in src/dxtr/utils/quality_control.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def shape_regularity_score(cplx: SimplicialComplex, 
                           return_scores: bool = False
                           ) -> Tuple[float] | np.ndarray[float, int]:
    """Quantifies the regularity of a simplicial complex.

    Parameters
    ----------
    cplx : SimplicialComplex
        The n-simplicial complex to consider.
    return_scores : bool, optional
        If True, returns an array with the regularity scores of all n-simplices.
        Else returns only the median value and the standard deviation. Default is False.

    Returns
    -------
    tuple of float or np.ndarray
        (Median, standard deviation) or array of all n-simplex regularity scores.

    Notes
    -----
    * The computed scores are only relevant for k-simplices with k>=2.
    * The score is based on the comparison of the edge lenghts. A regular k-simplex with edges of the same length will score 1.

    See also
    --------
    The `simplex_shape_regularity_score()` function within the same sub-module.
    """

    scores = np.array([simplex_shape_regularity_score(splx) 
                       for splx in cplx[-1]])

    if return_scores:
        return scores
    else:
        return np.median(scores), scores.std()

simplex_shape_regularity_score(splx)

Quantifies the regularity of a simplex.

Parameters:

Name Type Description Default
splx Simplex

The simplex to analyze.

required

Returns:

Type Description
float

A float between 0 and 1 defined as: 1 - std(edge_lengths) / mean(edge_lengths)

Notes

A score of 1 corresponds to the most regular simplex; i.e. one with all its edges of equal length.

This measure is meaningful only for k-simplices with k >= 2. Therefore, we return 1 for all k-simplices with k < 2.

Source code in src/dxtr/utils/quality_control.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def simplex_shape_regularity_score(splx: Simplex) -> float:
    """Quantifies the regularity of a simplex.

    Parameters
    ----------
    splx : Simplex
        The simplex to analyze.

    Returns
    -------
    float
        A float between 0 and 1 defined as: 
        1 - std(edge_lengths) / mean(edge_lengths)

    Notes
    -----
    A score of 1 corresponds to the most regular simplex; i.e. one with
    all its edges of equal length.

    This measure is meaningful only for k-simplices with k >= 2.
    Therefore, we return 1 for all k-simplices with k < 2.
    """

    if splx.dim < 2: return 1

    edges = splx.vertices - np.vstack((splx.vertices[1:],
                                       splx.vertices[:1]))

    edge_lengths = lng.norm(edges, axis=1)

    avg_edge_length = edge_lengths.mean()
    std_edge_length = edge_lengths.std()

    if np.isclose(avg_edge_length, 0):
        return 0
    else:
        return 1 - std_edge_length / avg_edge_length

well_centered_score(mfld, return_scores=False, verbose=False)

Quantifies how well-centered are simplices within a manifold.

Parameters:

Name Type Description Default
mfld SimplicialManifold

The simplicial manifold to investigate.

required
return_scores bool

If True, returns scores of all n-simplices. Default is False.

False
verbose bool

Prints a summary if True. Default is False.

False

Returns:

Type Description
float or tuple of float and np.ndarray

The ratio of well-centered n-simplices within the n-manifold and the scores (optional).

Notes

We arbitrarily consider well-centered simplices with circumcenter lying on an edge (i.e. one of its barycentric coordinates vanishes). This is debatable.

In its current version, this method does not quantify how much the ill-centered simplices are ill-centered. The closer it is to zero, the less ill-centered the simplex is.

The individual score of ill-centered simplices corresponds to the negative barycentric coordinate. The more negative it is, the worse the triangle is.

Source code in src/dxtr/utils/quality_control.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def well_centered_score(mfld: SimplicialManifold, 
                        return_scores: bool = False,
                        verbose: bool = False
                        ) -> float | np.ndarray[float, int]:
    """Quantifies how well-centered are simplices within a manifold.

    Parameters
    ----------
    mfld : SimplicialManifold
        The simplicial manifold to investigate.
    return_scores : bool, optional
        If True, returns scores of all n-simplices. Default is False.
    verbose : bool, optional
        Prints a summary if True. Default is False.

    Returns
    -------
    float or tuple of float and np.ndarray
        The ratio of well-centered n-simplices within the n-manifold and
        the scores (optional).

    Notes
    -----
    We arbitrarily consider well-centered simplices 
    with circumcenter lying on an edge (i.e. one of its 
    barycentric coordinates vanishes). This is debatable.

    In its current version, this method does not quantify how much 
    the ill-centered simplices are ill-centered. The closer it is to zero, the 
    less ill-centered the simplex is.

    The individual score of ill-centered simplices corresponds to the negative 
    barycentric coordinate. The more negative it is, the worse the triangle is.
    """
    nbr_splcs_tot = mfld.shape[-1]
    vertices =  mfld[-1].vertices

    ccntr_pos = np.array([circumcenter_barycentric_coordinates(vtcs).min()
                          for vtcs in vertices])

    ill_centered_sids = np.where(ccntr_pos < 0)[0]

    nbr_ill_centered = len(ill_centered_sids)
    well_centered_ratio = 1 - nbr_ill_centered / nbr_splcs_tot

    if verbose: 
      logger.info(f'{well_centered_ratio:.1%} of well-centered '
            + f'{mfld.dim}-simplices. {nbr_ill_centered} ill-centered '
            + f'ones over {nbr_splcs_tot} in total.')
    if return_scores:
        return well_centered_ratio, ccntr_pos

    else:
        return well_centered_ratio