Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
trac #16227: Merged with updated #15310
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanncohen committed May 4, 2014
2 parents e86d26c + 4d6e964 commit 5cfee91
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions src/sage/combinat/designs/orthogonal_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,43 @@ def transversal_design(k,n,check=True,availability=False):
[4, 5, 11, 17, 23], [4, 6, 13, 15, 22], [4, 7, 10, 18, 21],
[4, 8, 12, 16, 20]]
Some examples of the maximal number of transversal Sage is able to build::
sage: TD_3_10 = designs.transversal_design(3,10)
sage: designs.transversal_design(4,10,availability=True)
Unknown
sage: TD_6_12 = designs.transversal_design(6,12)
sage: designs.transversal_design(7,12,availability=True)
Unknown
sage: TD_3_14 = designs.transversal_design(3, 14)
sage: designs.transversal_design(4, 14,availability=True)
Unknown
sage: TD_4_15 = designs.transversal_design(4, 15)
sage: designs.transversal_design(5, 15,availability=True)
Unknown
sage: TD_4_18 = designs.transversal_design(4, 18)
sage: designs.transversal_design(5, 18,availability=True)
Unknown
sage: TD_5_20 = designs.transversal_design(5, 20)
sage: designs.transversal_design(6, 20,availability=True)
Unknown
TESTS:
Obtained through Wilson's decomposition::
sage: _ = designs.transversal_design(4,38)
Obtained through product decomposition::
sage: _ = designs.transversal_design(6,60)
sage: _ = designs.transversal_design(5,60) # checks some tricky divisibility error
Unknown availability::
sage: designs.transversal_design(6,4,availability=True)
Expand All @@ -98,6 +129,14 @@ def transversal_design(k,n,check=True,availability=False):
OA = orthogonal_array(k,n, check = False)
TD = [[i*n+c for i,c in enumerate(l)] for l in OA]

elif TD_find_product_decomposition(k,n):
if availability:
return True
n1,n2 = TD_find_product_decomposition(k,n)
TD1 = transversal_design(k,n1, check = False)
TD2 = transversal_design(k,n2, check = False)
TD = TD_product(k,TD1,n1,TD2,n2, check = False)

elif find_wilson_decomposition(k,n):
if availability:
return True
Expand Down Expand Up @@ -348,6 +387,94 @@ def wilson_construction(k,m,t,u, check = True):

return TD

@cached_function
def TD_find_product_decomposition(k,n):
r"""
Attempts to find a factorization of `n` in order to build a `TD(k,n)`.
If Sage can build a `TD(k,n_1)` and a `TD(k,n_2)` such that `n=n_1\times
n_2` then a `TD(k,n)` can be built (from the function
:func:`transversal_design`). This method returns such a pair of integers if
it exists, and ``None`` otherwise.
INPUT:
- ``k,n`` (integers) -- see above.
.. SEEALSO::
:func:`TD_product` that actually build a product
EXAMPLES::
sage: from sage.combinat.designs.orthogonal_arrays import TD_find_product_decomposition
sage: TD_find_product_decomposition(6, 84)
(7, 12)
sage: TD1 = designs.transversal_design(6, 7)
sage: TD2 = designs.transversal_design(6, 12)
sage: from sage.combinat.designs.orthogonal_arrays import TD_product
sage: TD = TD_product(6, TD1, 7, TD2, 12)
"""
from sage.rings.arith import divisors
for n1 in divisors(n)[1:-1]: # we ignore 1 and n
n2 = n//n1
if transversal_design(k, n1, availability = True) and transversal_design(k, n2, availability = True):
return n1,n2
return None

def TD_product(k,TD1,n1,TD2,n2, check=True):
r"""
Returns the product of two transversal designs.
From a transversal design `TD_1` of parameters `k,n_1` and a transversal
design `TD_2` of parameters `k,n_2`, this function returns a transversal
design of parameters `k,n` where `n=n_1\times n_2`.
Formally, if the groups of `TD_1` are `V^1_1,\dots,V^1_k` and the groups of
`TD_2` are `V^2_1,\dots,V^2_k`, the groups of the product design are
`V^1_1\times V^2_1,\dots,V^1_k\times V^2_k` and its blocks are the
`\{(x^1_1,x^2_1),\dots,(x^1_k,x^2_k)\}` where `\{x^1_1,\dots,x^1_k\}` is a
block of `TD_1` and `\{x^2_1,\dots,x^2_k\}` is a block of `TD_2`.
INPUT:
- ``TD1, TD2`` -- transversal designs.
- ``k,n1,n2`` (integers) -- see above.
- ``check`` (boolean) -- Whether to check that output is correct before
returning it. As this is expected to be useless (but we are cautious
guys), you may want to disable it whenever you want speed. Set to ``True``
by default.
.. SEEALSO::
:func:`TD_find_product_decomposition`
.. NOTE::
This function uses transversal designs with
`V_1=\{0,\dots,n-1\},\dots,V_k=\{(k-1)n,\dots,kn-1\}` both as input and
ouptut.
EXAMPLES::
sage: from sage.combinat.designs.orthogonal_arrays import TD_product
sage: TD1 = designs.transversal_design(6,7)
sage: TD2 = designs.transversal_design(6,12)
sage: TD6_84 = TD_product(6,TD1,7,TD2,12)
"""
N = n1*n2
TD = []
for X1 in TD1:
for X2 in TD2:
TD.append([x1*n2+(x2%n2) for x1,x2 in zip(X1,X2)])
if check:
assert is_transversal_design(TD,k,N)

return TD

def orthogonal_array(k,n,t=2,check=True,availability=False):
r"""
Return an orthogonal array of parameters `k,n,t`.
Expand Down

0 comments on commit 5cfee91

Please sign in to comment.