Model matrices for mixed-level orthogonal arrays ================================================ For mixed-level orthogonal arrays, we generate model matrices using Helmert contrasts. First, we define an example array and calculate the Helmert contrasts for 2 and 3 levels. The Helmert contrasts for a given number of levels can be generated with :meth:`~oapackage.oahelper.helmert_contrasts`. The rows of the array generated by the method correspond to the levels. :meth:`oapackage.oahelper.helmert_contrasts`. The contrasts are orthogonal and normalized. .. testsetup:: import numpy as np np.set_printoptions(precision=3, suppress=True) import oapackage .. admonition:: Define mixed-level array and calculate Helmert contrasts .. doctest:: >>> array = oapackage.exampleArray(54,1) exampleArray 54: root array in OA(6,2,3^1 2^1) >>> array.showarray() array: 0 0 0 1 1 0 1 1 2 0 2 1 >>> hc3 = oapackage.oahelper.helmert_contrasts(3) >>> hc2 = oapackage.oahelper.helmert_contrasts(2) >>> print(hc3) [[-1.225 -0.707] [ 1.225 -0.707] [ 0. 1.414]] >>> print(hc2) [[-1.] [ 1.]] >>> # the Helmert contrasts are orthognal and normalized >>> print(hc3.T.dot(hc3)) [[3. 0.] [0. 3.]] >>> print(hc2.T.dot(hc2)) [[2.]] The main effects for a mixel-level array are created by replacing each level in the array by the corresponding Helmert contrast .. admonition:: Intercept and main effects .. doctest:: >>> X=oapackage.array2modelmatrix(array, 'main') >>> print(X) [[ 1. -1.225 -0.707 -1. ] [ 1. -1.225 -0.707 1. ] [ 1. 1.225 -0.707 -1. ] [ 1. 1.225 -0.707 1. ] [ 1. 0. 1.414 -1. ] [ 1. 0. 1.414 1. ]] Note the Helmert contrasts for the 2-level column are +1 and -1. So the calculation for mixel-level arrays for a 2-level array yields the same results as the direct calculation for a 2-level design. The interaction effects are created by determining for all pair-wise combinations of columns the product between the elements of the contrast vectors. For this array, there is only one column combination: one 3-level factor and one 2-level factor. The number of columns in the interaction part is therefore :math:`(3-1)(2-1) = 2`. .. admonition:: Interaction model and information matrix .. doctest:: >>> X=oapackage.array2modelmatrix(array, 'interaction') >>> print(X) [[ 1. -1.225 -0.707 -1. 1.225 0.707] [ 1. -1.225 -0.707 1. -1.225 -0.707] [ 1. 1.225 -0.707 -1. -1.225 0.707] [ 1. 1.225 -0.707 1. 1.225 -0.707] [ 1. 0. 1.414 -1. -0. -1.414] [ 1. 0. 1.414 1. 0. 1.414]] >>> M=X.T.dot(X) >>> print(M) [[6. 0. 0. 0. 0. 0.] [0. 6. 0. 0. 0. 0.] [0. 0. 6. 0. 0. 0.] [0. 0. 0. 6. 0. 0.] [0. 0. 0. 0. 6. 0.] [0. 0. 0. 0. 0. 6.]]