# Isomorphism reduction for conference designs

In this example, we show how to test if two conference designs are isomorphic. We consider conference designs with 10 runs and 3 factors, and calculate a reduction to their normal form. Using the reduction, we determine if the two designs are isomorphic.

[1]:

import oapackage
import numpy as np

A = np.array(
[0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1]
).reshape(10, 3)
B = np.array(
[0, 1, 1, 1, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 0, 1, -1, 1, 1, -1, 1, 1, -1, -1]
).reshape(10, 3)

array1.showarray()
array2.showarray()

array:
0   1   1
1   0   1
1   1   0
1   1   1
1   1  -1
1   1  -1
1  -1   1
1  -1   1
1  -1  -1
1  -1  -1
array:
0   1   1
1   0  -1
1   1   1
1   1   1
1   1  -1
1   1  -1
1  -1   0
1  -1   1
1  -1   1
1  -1  -1


We calculate the normal forms of the conference designs using the function reduceConference or reduceConferenceTransformation. The result of the former is the reduced design, while the result of the latter is an object describing the tranformation to normal form. The normal form is calculated using Nauty.

[2]:

help(oapackage.reduceConference)

Help on function reduceConference in module oalib:

reduceConference(arg1, verbose=0)

Reduce conference matrix to normal form using Nauty


[3]:

T1 = oapackage.reduceConferenceTransformation(array1, verbose=1)
T2 = oapackage.reduceConferenceTransformation(array2, verbose=1)
T1.show()

reduceConferenceTransformation: reduce design with 10 rows, 3 columns
reduceConferenceTransformation: reduce design with 10 rows, 3 columns
row permutation: {2,0,1,9,7,8,5,6,3,4}
row flips: {1,1,-1,1,1,1,1,1,1,1}
column permutation: {0,1,2}
col flips: {1,-1,-1}


We can check whether the designs are isomorphic by comparing the normal forms.

[4]:

design_equal = T1.apply(array1) == T2.apply(array2)
print("designs isomorphic? %s" % design_equal)

designs isomorphic? 1


The designs are isomorphic. So, it is possible to calculate a reduction of the second design into the first design.

[5]:

TT = T1.inverse() * T2
TT.show()

row permutation: {0,1,8,9,6,7,2,4,5,3}
row flips: {-1,1,1,1,1,1,1,1,1,1}
column permutation: {0,1,2}
col flips: {1,-1,-1}

[6]:

r1 = T1.apply(array1)
r1.showarray()
r2 = T2.apply(array2)
r2.showarray()

array:
1   0  -1
1  -1   0
0   1   1
1   1   1
1   1   1
1   1  -1
1   1  -1
1  -1   1
1  -1   1
1  -1  -1
array:
1   0  -1
1  -1   0
0   1   1
1   1   1
1   1   1
1   1  -1
1   1  -1
1  -1   1
1  -1   1
1  -1  -1


Calculate some properties of a conference design; see the section Properties of conference designs for details.

[7]:

print("array 1: is_conference() %d" % array1.is_conference())
print("array 1: J2-characteristics %s" % (oapackage.Jcharacteristics_conference(array1, number_of_columns=2),))

array 1: is_conference() 1
array 1: J2-characteristics (0, 0, 0)

[8]:

help(oapackage.Jcharacteristics_conference)

Help on function Jcharacteristics_conference in module oalib:

Jcharacteristics_conference(array, number_of_columns, verbose=0)
Jcharacteristics_conference(array_link array, int number_of_columns, int verbose=0) -> intVector
Jcharacteristics_conference(array_link array, int number_of_columns) -> intVector