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 = oapackage.makearraylink(A)
array2 = oapackage.makearraylink(B)

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)
    reduceConference(array_link arg1, int verbose=0) -> array_link
    reduceConference(array_link arg1) -> array_link



    Reduce conference matrix to normal form using Nauty

    See also: reduceConferenceTransformation

[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