Skip to content

Commit

Permalink
sagemathgh-38664: graphs: make init_short_digraph always sort neighbo…
Browse files Browse the repository at this point in the history
…rs but without the extra log complexity (2nd try)

    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

This PR is based on the closed PR sagemath#38427 (by myself) that was breaking
too much doctests.

This PR improve the `init_short_digraph` function that is used to
initialize `StaticSparseCGraph` (used for immutable `Graph` and
`DiGraph`).

Before, a boolean parameter `sort_neighbors` was used to specify if we
wanted to sort the neighbors or not. It implied an extra `log` in the
complexity (as `qsort` was called).
With this PR, the neighbors are always sorted at no extra cost. It is
done by appending to the neighbors list the vertices in the correct
order so the call to `qsort` is not needed anymore.

This PR partly reverts sagemath#38198 and mostly reverts sagemath#37662


Contrary to PR sagemath#38427, I did not include the patch that remove the
sorting of vertices when StaticSparseGraph are initialized because it
was breaking too many doctests. Instead I added a option to disabled
said sorting and use it in my doctests to check that the new code works.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#38664
Reported by: cyrilbouvier
Reviewer(s): David Coudert
  • Loading branch information
Release Manager committed Sep 18, 2024
2 parents fa859bb + a18eaff commit 04b5114
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 183 deletions.
3 changes: 1 addition & 2 deletions src/sage/graphs/asteroidal_triples.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ def is_asteroidal_triple_free(G, certificate=False):
# module sage.graphs.base.static_sparse_graph
cdef list int_to_vertex = list(G)
cdef short_digraph sd
init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex,
sort_neighbors=False)
init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex)

cdef bitset_t seen
bitset_init(seen, n)
Expand Down
11 changes: 6 additions & 5 deletions src/sage/graphs/base/static_sparse_backend.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ cdef class StaticSparseCGraph(CGraph):

cdef class StaticSparseBackend(CGraphBackend):

def __init__(self, G, loops=False, multiedges=False):
def __init__(self, G, loops=False, multiedges=False, sort=True):
"""
A graph :mod:`backend <sage.graphs.base.graph_backends>` for static
sparse graphs.
Expand Down Expand Up @@ -511,10 +511,11 @@ cdef class StaticSparseBackend(CGraphBackend):
True
"""
vertices = list(G)
try:
vertices.sort()
except TypeError:
pass
if sort:
try:
vertices.sort()
except TypeError:
pass
cdef StaticSparseCGraph cg = <StaticSparseCGraph> StaticSparseCGraph(G, vertices)
self._cg = cg

Expand Down
10 changes: 1 addition & 9 deletions src/sage/graphs/base/static_sparse_graph.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,19 @@ ctypedef unsigned int uint

cdef extern from "stdlib.h":
ctypedef void const_void "const void"
void qsort(void *base, int nmemb, int size,
int(*compar)(const_void *, const_void *)) nogil

void *bsearch(const_void *key, const_void *base, size_t nmemb,
size_t size, int(*compar)(const_void *, const_void *)) nogil

cdef extern from "search.h":
void *lfind(const_void *key, const_void *base, size_t *nmemb,
size_t size, int(*compar)(const_void *, const_void *)) nogil

ctypedef struct short_digraph_s:
uint32_t * edges
uint32_t ** neighbors
PyObject * edge_labels
int m
int n
bint sorted_neighbors

ctypedef short_digraph_s short_digraph[1]

cdef int init_short_digraph(short_digraph g, G, edge_labelled=?, vertex_list=?, sort_neighbors=?) except -1
cdef int init_short_digraph(short_digraph g, G, edge_labelled=?, vertex_list=?) except -1
cdef void free_short_digraph(short_digraph g) noexcept
cdef int init_reverse(short_digraph dst, short_digraph src) except -1
cdef int out_degree(short_digraph g, int u) noexcept
Expand Down
Loading

0 comments on commit 04b5114

Please sign in to comment.