Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/sage/combinat/combinat_cython.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ cdef mpz_stirling_s2(mpz_t s, unsigned long n, unsigned long k):
mpz_clear(t)
mpz_clear(u)


def _stirling_number2(n, k):
"""
Python wrapper of mpz_stirling_s2.
Expand All @@ -148,8 +149,9 @@ def _stirling_number2(n, k):
mpz_stirling_s2(s.value, n, k)
return s


#####################################################################
## Lyndon word iterator
# Lyndon word iterator

def lyndon_word_iterator(Py_ssize_t n, Py_ssize_t k):
r"""
Expand Down Expand Up @@ -204,7 +206,8 @@ def lyndon_word_iterator(Py_ssize_t n, Py_ssize_t k):
while a[i] == n - 1:
i -= 1

## Perfect matchings iterator

# Perfect matchings iterator

def perfect_matchings_iterator(Py_ssize_t n):
r"""
Expand Down Expand Up @@ -276,6 +279,7 @@ def perfect_matchings_iterator(Py_ssize_t n):
sig_free(e)
sig_free(f)


cdef list convert(Py_ssize_t* f, Py_ssize_t n):
"""
Convert a list ``f`` representing a fixed-point free involution
Expand All @@ -288,8 +292,9 @@ cdef list convert(Py_ssize_t* f, Py_ssize_t n):
ret.append((i, f[i]))
return ret


#####################################################################
## Set partition composition
# Set partition composition

def set_partition_composition(tuple sp1, tuple sp2):
r"""
Expand Down
31 changes: 16 additions & 15 deletions src/sage/combinat/debruijn_sequence.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,16 @@ AUTHOR:

"""

#*******************************************************************************
# ******************************************************************************
# Copyright (C) 2011 Eviatar Bach <[email protected]>
#
# Distributed under the terms of the GNU General Public License (GPL)
# http://www.gnu.org/licenses/
#*******************************************************************************
# https://www.gnu.org/licenses/
# ******************************************************************************

from sage.data_structures.bitset_base cimport *


def debruijn_sequence(int k, int n):
"""
The generating function for De Bruijn sequences. This avoids the object
Expand Down Expand Up @@ -93,6 +94,7 @@ def debruijn_sequence(int k, int n):
gen(1, 1, k, n)
return sequence


cdef gen(int t, int p, k, n):
"""
The internal generation function. This should not be accessed by the
Expand Down Expand Up @@ -183,13 +185,15 @@ def is_debruijn_sequence(seq, k, n):

return answer


from sage.categories.finite_sets import FiniteSets
from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.parent import Parent

from sage.rings.integer cimport Integer
from sage.rings.integer_ring import ZZ


class DeBruijnSequences(UniqueRepresentation, Parent):
"""
Represents the De Bruijn sequences of given parameters `k` and `n`.
Expand Down Expand Up @@ -256,35 +260,32 @@ class DeBruijnSequences(UniqueRepresentation, Parent):
"""
Constructor.

Checks the consistency of the given arguments.
This checks the consistency of the given arguments.

TESTS:

Setting ``n`` orr ``k`` to anything under 1 will return a ValueError:

::
Setting ``n`` or ``k`` to anything under 1 will return
a :class:`ValueError`::

sage: DeBruijnSequences(3, 0).an_element()
Traceback (most recent call last):
...
ValueError: k and n cannot be under 1.
ValueError: k and n cannot be under 1

Setting ``n`` or ``k`` to any type except an integer will return a
TypeError:

::
:class:`TypeError`::

sage: DeBruijnSequences(2.5, 3).an_element()
Traceback (most recent call last):
...
TypeError: k and n must be integers.
TypeError: k and n must be integers
"""
Parent.__init__(self, category=FiniteSets())
if n < 1 or k < 1:
raise ValueError('k and n cannot be under 1.')
raise ValueError('k and n cannot be under 1')
if (not isinstance(n, (Integer, int)) or
not isinstance(k, (Integer,int))):
raise TypeError('k and n must be integers.')
not isinstance(k, (Integer, int))):
raise TypeError('k and n must be integers')

self.k = k
self.n = n
Expand Down
54 changes: 28 additions & 26 deletions src/sage/combinat/degree_sequences.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ An integer sequence need not necessarily be a degree sequence. Indeed, in a
degree sequence of length `n` no integer can be larger than `n-1` -- the degree
of a vertex is at most `n-1` -- and the sum of them is at most `n(n-1)`.

Degree sequences are completely characterized by a result from Erdos and Gallai:
Degree sequences are completely characterized by a result from Erdős and Gallai:

**Erdos and Gallai:** *The sequence of integers* `d_1 \geq \cdots \geq d_n`
**Erdős and Gallai:** *The sequence of integers* `d_1 \geq \cdots \geq d_n`
*is a degree sequence if and only if* `\sum_i d_i` is even and `\forall i`

.. MATH::
Expand Down Expand Up @@ -281,6 +281,7 @@ from cysignals.signals cimport sig_on, sig_off
cdef unsigned char * seq
cdef list sequences


class DegreeSequences:

def __init__(self, n):
Expand All @@ -307,16 +308,16 @@ class DegreeSequences:
sage: DegreeSequences(-1)
Traceback (most recent call last):
...
ValueError: The input parameter must be >= 0.
ValueError: the input parameter must be >= 0
"""
if n < 0:
raise ValueError("The input parameter must be >= 0.")
raise ValueError("the input parameter must be >= 0")
self._n = n

def __contains__(self, seq):
"""
Checks whether a given integer sequence is the degree sequence
of a graph on `n` elements
Check whether a given integer sequence is the degree sequence
of a graph on `n` elements.

EXAMPLES::

Expand All @@ -342,7 +343,7 @@ class DegreeSequences:
[[0]]
"""
cdef int n = self._n
if len(seq)!=n:
if len(seq) != n:
return False

# Is the sum even ?
Expand All @@ -352,13 +353,13 @@ class DegreeSequences:
# Partial represents the left side of Erdos and Gallai's inequality,
# i.e. the sum of the i first integers.
cdef int partial = 0
cdef int i,d,dd, right
cdef int i, d, dd, right

# Temporary variable to ensure that the sequence is indeed
# non-increasing
cdef int prev = n-1
cdef int prev = n - 1

for i,d in enumerate(seq):
for i, d in enumerate(seq):

# Non-increasing ?
if d > prev:
Expand All @@ -370,9 +371,9 @@ class DegreeSequences:
partial += d

# Evaluating the right hand side
right = i*(i+1)
for dd in seq[i+1:]:
right += min(dd,i+1)
right = i * (i + 1)
for dd in seq[i + 1:]:
right += min(dd, i + 1)

# Comparing the two
if partial > right:
Expand Down Expand Up @@ -404,14 +405,15 @@ class DegreeSequences:
sage: all(seq in DS for seq in DS)
True
"""
return iter( init(self._n) )
yield from init(self._n)

def __dealloc__():
"""
Freeing the memory
"""
sig_free(seq)


cdef init(int n):
"""
Initializes the memory and starts the enumeration algorithm.
Expand All @@ -432,7 +434,7 @@ cdef init(int n):

N = n
sequences = []
enum(1,0)
enum(1, 0)
sig_free(seq)
return sequences

Expand Down Expand Up @@ -467,7 +469,7 @@ cdef void enum(int k, int M):
- ``k`` -- depth of the partial degree sequence
- ``M`` -- value of a maximum element in the partial degree sequence
"""
cdef int i,j
cdef int i, j
global seq
cdef int taken = 0
cdef int current_box
Expand All @@ -491,21 +493,21 @@ cdef void enum(int k, int M):
if M == 0:

seq[0] += 1
enum(k+1, M)
enum(k + 1, M)
seq[0] -= 1

# We need not automatically increase the degree at each step. In this case,
# we have no other choice but to link the new vertex of degree M to vertices
# of degree M-1, which will become vertices of degree M too.
elif seq[M-1] >= M:
elif seq[M - 1] >= M:

seq[M] += M+1
seq[M-1] -= M
seq[M] += M + 1
seq[M - 1] -= M

enum(k+1, M)
enum(k + 1, M)

seq[M] -= M+1
seq[M-1] += M
seq[M] -= M + 1
seq[M - 1] += M

###############################################
# Creating vertices of Vertices of degree > M #
Expand Down Expand Up @@ -542,13 +544,13 @@ cdef void enum(int k, int M):
seq[current_box] -= i
seq[current_box+1] += i

for max(0,((M+1)-taken-i)) <= j <= n_previous_box:
for max(0, ((M+1)-taken-i)) <= j <= n_previous_box:
seq[current_box-1] -= j
seq[current_box] += j

new_vertex = taken + i + j
seq[new_vertex] += 1
enum(k+1,new_vertex)
enum(k+1, new_vertex)
seq[new_vertex] -= 1

seq[current_box-1] += j
Expand All @@ -566,7 +568,7 @@ cdef void enum(int k, int M):
# Now current_box = 0. All the vertices of nonzero degree are taken, we just
# want to know how many vertices of degree 0 will be neighbors of the new
# vertex.
for max(0,((M+1)-taken)) <= i <= seq[0]:
for max(0, ((M+1)-taken)) <= i <= seq[0]:

seq[1] += i
seq[0] -= i
Expand Down
6 changes: 6 additions & 0 deletions src/sage/combinat/designs/designs_pyx.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ from cysignals.memory cimport sig_malloc, sig_calloc, sig_realloc, sig_free

from sage.misc.unknown import Unknown


def is_covering_array(array, strength=None, levels=None, verbose=False, parameters=False):
r"""
Check if the input is a covering array with given strength.
Expand Down Expand Up @@ -349,6 +350,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O
bitset_free(seen)
return True


def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=False):
r"""
Checks that input is a Group Divisible Design on `\{0,...,v-1\}`
Expand Down Expand Up @@ -588,6 +590,7 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False):
lambd=lambd,
verbose=verbose)


def is_projective_plane(blocks, verbose=False):
r"""
Test whether the blocks form a projective plane on `\{0,...,v-1\}`
Expand Down Expand Up @@ -661,6 +664,7 @@ def is_projective_plane(blocks, verbose=False):
lambd=1,
verbose=verbose)


def is_difference_matrix(M,G,k,lmbda=1,verbose=False):
r"""
Test if `M` is a `(G,k,\lambda)`-difference matrix.
Expand Down Expand Up @@ -725,6 +729,7 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False):
"""
return is_quasi_difference_matrix(M,G,k,lmbda=lmbda,mu=lmbda,u=0,verbose=verbose)


def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False):
r"""
Test if the matrix is a `(G,k;\lambda,\mu;u)`-quasi-difference matrix
Expand Down Expand Up @@ -938,6 +943,7 @@ def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False):
sig_free(M_c)
return True


# Cached information for OA constructions (see .pxd file for more info)

_OA_cache = <cache_entry *> sig_malloc(2*sizeof(cache_entry))
Expand Down
2 changes: 2 additions & 0 deletions src/sage/combinat/designs/gen_quadrangles_with_spread.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def generalised_quadrangle_with_spread(const int s, const int t,
raise RuntimeError(
f"Sage can't build a GQ of order ({s}, {t}) with a spread")


def is_GQ_with_spread(GQ, S, s=None, t=None):
r"""
Check if GQ is a generalised quadrangle of order `(s,t)` and
Expand Down Expand Up @@ -233,6 +234,7 @@ def dual_GQ_ovoid(GQ, O):
D = IncidenceStructure(newBlocks)
return (D, S)


def generalised_quadrangle_hermitian_with_ovoid(const int q):
r"""
Construct the generalised quadrangle `H(3,q^2)` with an ovoid.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ from .orthogonal_arrays import orthogonal_array
from sage.rings.integer cimport smallInteger
from sage.arith.misc import prime_powers


@cached_function
def find_recursive_construction(k, n):
r"""
Expand Down Expand Up @@ -114,6 +115,7 @@ def find_recursive_construction(k, n):
return res
return False


cpdef find_product_decomposition(int k,int n):
r"""
Find `n_1n_2=n` to obtain an `OA(k,n)` by the product construction.
Expand Down Expand Up @@ -880,6 +882,7 @@ def int_as_sum(int value, list S, int k_max):

return None


cpdef find_brouwer_van_rees_with_one_truncated_column(int k,int n):
r"""
Find `rm+x_1+...+x_c=n` such that the Brouwer-van Rees constructions yields a `OA(k,n)`.
Expand Down
Loading