Skip to content

Commit 2f2732e

Browse files
committed
refactor: Move list of pairs to dedicated class
1 parent d127e67 commit 2f2732e

File tree

4 files changed

+214
-222
lines changed

4 files changed

+214
-222
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
cimport cython
2+
3+
cdef struct pair_s:
4+
size_t first
5+
size_t second
6+
7+
@cython.final
8+
cdef class BinaryList:
9+
cdef pair_s** _lists
10+
cdef size_t length
11+
12+
cdef inline int enlarge(self) except -1
13+
cdef inline int add(self, size_t first, size_t second) except -1
14+
cdef inline pair_s* get(self, size_t index) except NULL
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
r"""
2+
A data structure to store lists of integer pairs of large size.
3+
"""
4+
5+
# ****************************************************************************
6+
# Copyright (C) 2022 Jonathan Kliem <[email protected]>
7+
#
8+
# This program is free software: you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 2 of the License, or
11+
# (at your option) any later version.
12+
# https://www.gnu.org/licenses/
13+
# ****************************************************************************
14+
15+
from cysignals.memory cimport check_reallocarray, check_allocarray, sig_free
16+
from sage.rings.integer cimport smallInteger
17+
18+
# Should be a power of two.
19+
# Should be neither exposed nor modified.
20+
cdef size_t length_per_list = 16348
21+
22+
cdef class BinaryList:
23+
def __dealloc__(self):
24+
cdef size_t n_lists = self.length // length_per_list
25+
cdef size_t i
26+
for i in range(n_lists):
27+
sig_free(self._lists[i])
28+
sig_free(self._lists)
29+
30+
cdef inline int enlarge(self) except -1:
31+
"""
32+
Increase size of list by one.
33+
"""
34+
if self.length % length_per_list:
35+
self.length += 1
36+
return 0
37+
38+
cdef size_t n_lists = self.length // length_per_list
39+
self._lists = <pair_s**> check_reallocarray(self._lists, n_lists + 1, sizeof(pair_s*))
40+
self._lists[n_lists] = <pair_s*> check_allocarray(length_per_list, sizeof(pair_s))
41+
self.length += 1
42+
43+
cdef inline pair_s* get(self, size_t index) except NULL:
44+
if not (0 <= index < self.length):
45+
raise IndexError
46+
47+
cdef size_t list_index = index // length_per_list
48+
cdef size_t index_in_list = index - list_index * length_per_list
49+
50+
return &self._lists[list_index][index_in_list]
51+
52+
def __getitem__(self, size_t index):
53+
r"""
54+
Get item of specified index.
55+
56+
EXAMPLES::
57+
58+
sage: from sage.data_structures.binary_list import BinaryList
59+
sage: l = BinaryList()
60+
sage: l[0] = [1, 5]
61+
sage: l[0]
62+
(1, 5)
63+
sage: l[1]
64+
Traceback (most recent call last):
65+
...
66+
IndexError
67+
sage: l[-1]
68+
Traceback (most recent call last):
69+
...
70+
OverflowError: can't convert negative value to size_t
71+
"""
72+
cdef pair_s pair = self.get(index)[0]
73+
return (smallInteger(pair.first), smallInteger(pair.second))
74+
75+
def __setitem__(self, size_t index, value):
76+
r"""
77+
Set item of specified index.
78+
79+
Allows increasing the size of the list by at most 1.
80+
81+
EXAMPLES::
82+
83+
sage: from sage.data_structures.binary_list import BinaryList
84+
sage: l = BinaryList()
85+
sage: l[0] = (2, 1)
86+
sage: l[1] = (1, 2)
87+
sage: l[0]
88+
(2, 1)
89+
sage: l[1]
90+
(1, 2)
91+
sage: l[10] = (5, 3)
92+
Traceback (most recent call last):
93+
...
94+
IndexError
95+
sage: l[2] = 2
96+
Traceback (most recent call last):
97+
...
98+
TypeError: 'sage.rings.integer.Integer' object is not iterable
99+
"""
100+
cdef size_t first, second
101+
(first, second) = value
102+
103+
if (index == self.length):
104+
self.add(first, second)
105+
return
106+
107+
cdef pair_s* pair_pt = self.get(index)
108+
pair_pt[0].first = first
109+
pair_pt[0].second = second
110+
111+
cdef inline int add(self, size_t first, size_t second) except -1:
112+
"""
113+
Add a pair to the list.
114+
"""
115+
self.enlarge()
116+
cdef pair_s* last = self.get(self.length - 1)
117+
last[0].first = first
118+
last[0].second = second

src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
cimport cython
2-
from sage.structure.sage_object cimport SageObject
3-
from .face_iterator cimport FaceIterator, CombinatorialFace
4-
from .list_of_faces cimport ListOfFaces
5-
from .face_data_structure cimport face_t
6-
from .polyhedron_face_lattice cimport PolyhedronFaceLattice
2+
from sage.data_structures.binary_list cimport BinaryList
3+
from sage.structure.sage_object cimport SageObject
4+
from .face_iterator cimport FaceIterator, CombinatorialFace
5+
from .list_of_faces cimport ListOfFaces
6+
from .face_data_structure cimport face_t
7+
from .polyhedron_face_lattice cimport PolyhedronFaceLattice
78

89
@cython.final
910
cdef class CombinatorialPolyhedron(SageObject):
@@ -24,22 +25,10 @@ cdef class CombinatorialPolyhedron(SageObject):
2425
cdef tuple _far_face_tuple
2526
cdef tuple _f_vector
2627

27-
# Edges, ridges and incidences are stored in a pointer of pointers.
28-
# The first edge has vertices ``edges[0][0]`` and ``edges[0][1]``,
29-
# the second edge has vertices ``edges[0][2]`` and ``edges[0][3]``, etc.
30-
# There are ``_length_edges_list`` edges in ``edges[i]``, so the edge
31-
# ``_length_edges_list + 1`` has vertices ``edges[1][0]`` and ``edges[1][1]``.
32-
# Likewise for ridges and incidences.
33-
cdef size_t _length_edges_list
34-
35-
36-
cdef size_t **_edges # stores edges labeled by vertex indices
37-
cdef size_t _n_edges
38-
cdef size_t **_ridges # stores ridges labeled by facet indices
39-
cdef size_t _n_ridges
40-
cdef size_t **_face_lattice_incidences # stores incidences in Hasse diagram labeled indices of the faces
41-
cdef size_t _n_face_lattice_incidences
42-
cdef PolyhedronFaceLattice _all_faces # class to generate Hasse diagram incidences
28+
cdef BinaryList _edges # stores edges labeled by vertex indices
29+
cdef BinaryList _ridges # stores ridges labeled by facet indices
30+
cdef BinaryList _face_lattice_incidences # stores incidences in Hasse diagram labeled indices of the faces
31+
cdef PolyhedronFaceLattice _all_faces # class to generate Hasse diagram incidences
4332

4433
cdef tuple Vrep(self)
4534
cdef tuple facet_names(self)
@@ -69,10 +58,6 @@ cdef class CombinatorialPolyhedron(SageObject):
6958
cdef int _compute_edges_or_ridges(self, int dual, bint do_edges) except -1
7059
cdef size_t _compute_edges_or_ridges_with_iterator(
7160
self, FaceIterator face_iter, const bint do_atom_rep, const bint do_f_vector,
72-
size_t ***edges_pt, size_t *counter_pt, size_t *current_length_pt,
73-
size_t* f_vector) except -1
74-
cdef int _compute_face_lattice_incidences(self) except -1
61+
BinaryList edges, size_t* f_vector) except -1
7562

76-
cdef inline int _set_edge(self, size_t a, size_t b, size_t ***edges_pt, size_t *counter_pt, size_t *current_length_pt) except -1
77-
cdef inline void _free_edges(self, size_t ***edges_pt, size_t counter)
78-
cdef inline size_t _get_edge(self, size_t **edges, size_t edge_number, size_t vertex) except -1
63+
cdef int _compute_face_lattice_incidences(self) except -1

0 commit comments

Comments
 (0)