Example code for delete-one-factor projections

Any orthogonal array can be reduced to delete-one-factor projection form using reduceDOPform. The method is described in the article A canonical form for non-regular arrays based on generalized wordlength pattern values of delete-one-factor projections by Eendebak, P. T. In this notebook, we reduce an example array to its delete-one-factor projection form.

Load required libraries and select an example orthogonal array with 16 runs and 7 factors.

[1]:
import oapackage

al = oapackage.exampleArray(4)
al = oapackage.reduceDOPform(al)
al.showarray()
array:
  0   0   0   0   0   0   0
  0   0   0   0   0   0   1
  0   0   0   1   1   1   0
  0   0   0   1   1   1   1
  0   1   1   0   0   1   0
  0   1   1   0   0   1   1
  0   1   1   1   1   0   0
  0   1   1   1   1   0   1
  1   0   1   0   1   0   0
  1   0   1   0   1   1   1
  1   0   1   1   0   0   0
  1   0   1   1   0   1   1
  1   1   0   0   1   0   1
  1   1   0   0   1   1   0
  1   1   0   1   0   0   1
  1   1   0   1   0   1   0

A key property of the delete-of-factor projection form is that the generalized word length patterns (GWLPs) of the projections are ordered. For details on the GWLP, see Statistical properties of orthogonal arrays.

[5]:
print(f"GWLP {al.GWLP()}")
for ii in range(0, al.n_columns):
    bl = al.deleteColumn(ii)
    print("Delete column %d: GWLP %s" % (ii, str(bl.GWLP())))
GWLP (1.0, 0.0, 0.0, 3.5, 2.5, 0.5, 0.5, 0.0)
Delete column 0: GWLP (1.0, 0.0, 0.0, 1.5, 1.0, 0.5, 0.0)
Delete column 1: GWLP (1.0, 0.0, 0.0, 1.75, 0.75, 0.25, 0.25)
Delete column 2: GWLP (1.0, 0.0, 0.0, 1.75, 0.75, 0.25, 0.25)
Delete column 3: GWLP (1.0, 0.0, 0.0, 2.0, 1.0, 0.0, 0.0)
Delete column 4: GWLP (1.0, 0.0, 0.0, 2.0, 1.0, 0.0, 0.0)
Delete column 5: GWLP (1.0, 0.0, 0.0, 2.0, 1.0, 0.0, 0.0)
Delete column 6: GWLP (1.0, 0.0, 0.0, 3.0, 2.0, 0.0, 0.0)

The symmetry group of the projection GWLPs can be calculated. This symmetry group determines how fast an array can be reduced to normal form.

[6]:
dof_values = oapackage.projectionDOFvalues(al)
sg = oapackage.symmetry_group(dof_values, False)
sg.show(1)
symmetry group: 7 elements, 4 subgroups: 1 2 3 1

It is also possible to reduce mixed-level arrays to their delete-of-factor projection forms. We now show an example involving an orthogonal array with 24 runs, one four-level factor, one three-level factor and three two-level factors.

[8]:
al = oapackage.exampleArray(5)
al.showarray()
dopgwlp = oapackage.projectionGWLPs(al)
print(f"delete-one-factor GWLP values {[x.raw_values() for x in dopgwlp]}")
array:
  0   0   0   0   0
  0   0   0   0   0
  0   1   0   0   0
  0   1   1   1   1
  0   2   1   1   1
  0   2   1   1   1
  1   0   0   1   1
  1   0   0   1   1
  1   1   0   0   1
  1   1   1   1   0
  1   2   1   0   0
  1   2   1   0   0
  2   0   1   0   1
  2   0   1   0   1
  2   1   0   1   0
  2   1   1   0   1
  2   2   0   1   0
  2   2   0   1   0
  3   0   1   1   0
  3   0   1   1   0
  3   1   0   1   1
  3   1   1   0   0
  3   2   0   0   1
  3   2   0   0   1
delete-one-factor GWLP values [(1.0, 0.0, 0.0, 0.0, 0.6666666666666666), (1.0, 0.0, 0.0, 2.111111111111111, 0.0), (1.0, 0.0, 0.0, 1.8888888888888888, 0.4444444444444444), (1.0, 0.0, 0.0, 2.3333333333333335, 0.0), (1.0, 0.0, 0.0, 1.8888888888888888, 0.4444444444444444)]

The delete-of-factor values for mixel-level arrays consists of the factor level of the deleted column and the GWLP of the projection.

[9]:
oapackage.projectionGWLPs
dopgwp = oapackage.projectionGWLPs(al)
arrayclass = oapackage.arraylink2arraydata(al)
dofvalues = oapackage.projectionDOFvalues(al)
factor_levels = arrayclass.factor_levels()

for column, dof_value in enumerate(dofvalues):
    print("column %d: factor level %s" % (column, factor_levels[column]))
    print(f"   delete-of-factor value: {list(dof_value.raw_values())}")
column 0: factor level 4
   delete-of-factor value: [-4.0, 1.0, 0.0, 0.0, 0.0, 0.6666666666666666]
column 1: factor level 3
   delete-of-factor value: [-3.0, 1.0, 0.0, 0.0, 2.111111111111111, 0.0]
column 2: factor level 2
   delete-of-factor value: [-2.0, 1.0, 0.0, 0.0, 1.8888888888888888, 0.4444444444444444]
column 3: factor level 2
   delete-of-factor value: [-2.0, 1.0, 0.0, 0.0, 2.3333333333333335, 0.0]
column 4: factor level 2
   delete-of-factor value: [-2.0, 1.0, 0.0, 0.0, 1.8888888888888888, 0.4444444444444444]

Show the reduced array.

[10]:
reduced_array = al.reduceDOP()
al.showarray()
array:
  0   0   0   0   0
  0   0   0   0   0
  0   1   0   0   0
  0   1   1   1   1
  0   2   1   1   1
  0   2   1   1   1
  1   0   0   1   1
  1   0   0   1   1
  1   1   0   0   1
  1   1   1   1   0
  1   2   1   0   0
  1   2   1   0   0
  2   0   1   0   1
  2   0   1   0   1
  2   1   0   1   0
  2   1   1   0   1
  2   2   0   1   0
  2   2   0   1   0
  3   0   1   1   0
  3   0   1   1   0
  3   1   0   1   1
  3   1   1   0   0
  3   2   0   0   1
  3   2   0   0   1