def construction_3_3(k,n,m,i): r""" Return an `OA(k,nm+i)`. This is Wilson's construction with `i` truncated columns of size 1 and such that a block `B_0` of the incomplete OA intersects all truncated columns. As a consequence, all other blocks intersect only `0` or `1` of the last `i` columns. This allow to consider the block `B_0` only up to its first `k` coordinates and then use a `OA(k,i)` instead of a `OA(k,m+i) - i.OA(k,1)`. This is construction 3.3 from [AC07]_. INPUT: - ``k,n,m,i`` (integers) such that the following designs are available : `OA(k,n),OA(k,m),OA(k,m+1),OA(k,r)`. .. SEEALSO:: :func:`find_construction_3_3` EXAMPLES:: sage: from sage.combinat.designs.orthogonal_arrays_recursive import find_construction_3_3 sage: from sage.combinat.designs.orthogonal_arrays_recursive import construction_3_3 sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: k=11;n=177 sage: is_orthogonal_array(construction_3_3(*find_construction_3_3(k,n)[1]),k,n,2) True """ from orthogonal_arrays import wilson_construction, OA_relabel, incomplete_orthogonal_array # Builds an OA(k+i,n) containing a block [0]*(k+i) OA = incomplete_orthogonal_array(k+i,n,(1,)) OA = [[(x+1)%n for x in B] for B in OA] # Truncated version OA = [B[:k]+[0 if x == 0 else None for x in B[k:]] for B in OA] OA = wilson_construction(OA,k,n,m,i,[1]*i,check=False)[:-i] matrix = [range(m)+range(n*m,n*m+i)]*k OA.extend(OA_relabel(orthogonal_array(k,m+i),k,m+i,matrix=matrix)) assert is_orthogonal_array(OA,k,n*m+i) return OA
def simple_wilson_construction(k,r,m,u): r""" Return an `OA(k,rm + \sum u_i)` from Wilson construction. INPUT: - ``k,r,m`` -- integers - ``u`` -- list of positive integers .. TODO:: As soon as wilson construction accepts an empty master design we should remove this intermediate functions. EXAMPLES:: sage: from sage.combinat.designs.orthogonal_arrays_recursive import simple_wilson_construction sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: OA = simple_wilson_construction(6,7,12,()) sage: is_orthogonal_array(OA,6,84) True sage: OA = simple_wilson_construction(4,5,7,(3,)) sage: is_orthogonal_array(OA,4,38) True sage: OA = simple_wilson_construction(5,7,7,(4,5)) sage: is_orthogonal_array(OA,5,58) True """ from sage.combinat.designs.orthogonal_arrays import wilson_construction, OA_relabel n = r*m + sum(u) n_trunc = len(u) OA = orthogonal_array(k+n_trunc,r,check=False) matrix = [range(r)]*k for uu in u: matrix.append(range(uu)+[None]*(r-uu)) OA = OA_relabel(OA,k+n_trunc,r,matrix=matrix) return wilson_construction(OA,k,r,m,n_trunc,u,False)
def construction_3_6(k,n,m,i): r""" Return a `OA(k,nm+i)` This is Wilson's construction with `r` columns of order `1`, in which each block intersects at most two truncated columns. Such a design exists when `n` is a prime power and is returned by :func:`OA_and_oval`. INPUT: - ``k,n,m,i`` (integers) -- `n` must be a prime power. The following designs must be available: `OA(k+r,q),OA(k,m),OA(k,m+1),OA(k,m+2)`. This is construction 3.6 from [AC07]_. .. SEEALSO:: - :func:`construction_3_6` - :func:`OA_and_oval` EXAMPLES:: sage: from sage.combinat.designs.orthogonal_arrays_recursive import find_construction_3_6 sage: from sage.combinat.designs.orthogonal_arrays_recursive import construction_3_6 sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: k=8;n=95 sage: is_orthogonal_array(construction_3_6(*find_construction_3_6(k,n)[1]),k,n,2) True """ from orthogonal_arrays import wilson_construction OA = OA_and_oval(n) OA = [B[:k+i] for B in OA] OA = [B[:k] + [x if x==0 else None for x in B[k:]] for B in OA] OA = wilson_construction(OA,k,n,m,i,[1]*i) assert is_orthogonal_array(OA,k,n*m+i) return OA
def construction_3_5(k,n,m,r,s,t): r""" Return an `OA(k,nm+r+s+t)`. This is exactly Wilson's construction with three truncated groups except we make sure that all blocks have size `>k`, so we don't need a `OA(k,m+0)` but only `OA(k,m+1),OA(k,m+2),OA(k,m+3)`. This is construction 3.5 from [AC07]_. INPUT: - ``k,n,m`` (integers) - ``r,s,t`` (integers) -- sizes of the three truncated groups, such that `r\leq s` and `(q-r-1)(q-s) \geq (q-s-1)*(q-r)`. The following designs must be available : `OA(k,n),OA(k,r),OA(k,s),OA(k,t),OA(k,m+1),OA(k,m+2),OA(k,m+3)`. .. SEEALSO:: :func:`find_construction_3_5` EXAMPLES:: sage: from sage.combinat.designs.orthogonal_arrays_recursive import find_construction_3_5 sage: from sage.combinat.designs.orthogonal_arrays_recursive import construction_3_5 sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: k=8;n=111 sage: is_orthogonal_array(construction_3_5(*find_construction_3_5(k,n)[1]),k,n,2) True """ from orthogonal_arrays import wilson_construction, OA_relabel assert r <= s q = n assert (q-r-1)*(q-s) >= (q-s-1)*(q-r) master_design = orthogonal_array(k+3,q) # group k+1 has cardinality r # group k+2 has cardinality s # group k+3 has cardinality t # Taking q-s blocks going through 0 in the last block blocks_crossing_0 = [B[-3:] for B in master_design if B[-1] == 0][:q-s] # defining the undeleted points of the groups k+1,k+2 group_k_1 = [x[0] for x in blocks_crossing_0] group_k_1 = [x for x in range(q) if x not in group_k_1][:r] group_k_2 = [x[1] for x in blocks_crossing_0] group_k_2 = [x for x in range(q) if x not in group_k_2][:s] # All blocks that have a deleted point in groups k+1 and k+2 MUST contain a # point in group k+3 group_k_3 = [B[-1] for B in master_design if B[-3] not in group_k_1 and B[-2] not in group_k_2] group_k_3 = list(set(group_k_3)) assert len(group_k_3) <= t group_k_3.extend([x for x in range(q) if x not in group_k_3]) group_k_3 = group_k_3[:t] # Relabelling the OA r1 = [None]*q r2 = [None]*q r3 = [None]*q for i,x in enumerate(group_k_1): r1[x] = i for i,x in enumerate(group_k_2): r2[x] = i for i,x in enumerate(group_k_3): r3[x] = i OA = OA_relabel(master_design, k+3,q, matrix=[range(q)]*k+[r1,r2,r3]) OA = wilson_construction(OA,k,q,m,3,[r,s,t], check=False) return OA
def construction_3_4(k,n,m,r,s): r""" Return a `OA(k,nm+rs)`. This is Wilson's construction applied to a truncated `OA(k+r+1,n)` with `r` columns of size `1` and one column of size `s`. The unique elements of the `r` truncated columns are picked so that a block `B_0` contains them all. - If there exists an `OA(k,m+r+1)` the column of size `s` is truncated in order to intersect `B_0`. - Otherwise, if there exists an `OA(k,m+r)`, the last column must not intersect `B_0` This is construction 3.4 from [AC07]_. INPUT: - ``k,n,m,r,s`` (integers) -- we assume that `s<n` and `1\leq r,s` The following designs must be available: `OA(k,n),OA(k,m),OA(k,m+1),OA(k,m+2),OA(k,s)`. Additionnally, it requires either a `OA(k,m+r)` or a `OA(k,m+r+1)`. .. SEEALSO:: :func:`find_construction_3_4` EXAMPLES:: sage: from sage.combinat.designs.orthogonal_arrays_recursive import find_construction_3_4 sage: from sage.combinat.designs.orthogonal_arrays_recursive import construction_3_4 sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: k=8;n=196 sage: is_orthogonal_array(construction_3_4(*find_construction_3_4(k,n)[1]),k,n,2) True """ from orthogonal_arrays import wilson_construction, OA_relabel assert s<n master_design = orthogonal_array(k+r+1,n) # Defines the first k+r columns of the matrix of labels matrix = [range(n)]*k + [[None]*n]*(r) + [[None]*n] B0 = master_design[0] for i in range(k,k+r): matrix[i][B0[i]] = 0 # Last column if orthogonal_array(k,m+r,existence=True): last_group = [x for x in range(s+1) if x != B0[-1]][:s] elif orthogonal_array(k,m+r+1,existence=True): last_group = [x for x in range(s+1) if x != B0[-1]][:s-1] + [B0[-1]] else: raise Exception for i,x in enumerate(last_group): matrix[-1][x] = i OA = OA_relabel(master_design,k+r+1,n, matrix=matrix) OA = wilson_construction(OA,k,n,m,r+1,[1]*r+[s],check=False) return OA