def test_numpy_interface(verbose=0): A = np.eye(3, 4).astype(int) A[0, :] = [10, 20, 30, 50] A[2, :] = [-3, -4, -5, -6] if verbose: print('makearraylink') al = oapackage.makearraylink(A) np.testing.assert_array_equal(np.array(al), A) if verbose: al.showarray() if verbose: print('direct') al = oapackage.array_link(A) if verbose: al.showarray() Ax = np.array(al) if verbose: print(A) print(Ax) with np.testing.assert_raises(TypeError): # not possible right now... if verbose: print('direct float') A = np.eye(3).astype(float) al = oapackage.array_link(A) if verbose: al.showarray()
def test_double_conference_foldover_permutation(self): al = oapackage.exampleArray(37, 0) expected = [ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 11, 16, 19, 17, 18, 15, 14, 13, 12 ] permutation = oapackage.double_conference_foldover_permutation(al) self.assertEqual(list(permutation), expected) N = int(al.n_rows / 2) folded = np.array(oapackage.array_link(np.array(al)[permutation, :])) np.testing.assert_array_equal(folded[0:N, :], -folded[N:, :]) expected[5], expected[3] = expected[3], expected[5] expected[-1], expected[4] = expected[4], expected[-1] expected[-3], expected[7] = expected[7], expected[-3] al = oapackage.array_link(np.array(al)[expected, :]) permutation = oapackage.double_conference_foldover_permutation(al) folded = np.array(oapackage.array_link(np.array(al)[permutation, :])) N = int(al.n_rows / 2) np.testing.assert_array_equal(folded[0:N, :], -folded[N:, :]) al = oapackage.exampleArray(45, 0) permutation = oapackage.double_conference_foldover_permutation(al) self.assertEqual(permutation[0], -1) al = oapackage.exampleArray(5, 0) with self.assertRaises(RuntimeError): permutation = oapackage.double_conference_foldover_permutation(al) al = oapackage.array_link(3, 4, 0) with self.assertRaises(RuntimeError): permutation = oapackage.double_conference_foldover_permutation(al)
def test_basic_array_link_functionality(self): al2a = oapackage.array_link(2, 2, 0) al2b = oapackage.array_link(2, 2, 0) al2b.setconstant(1) al3 = oapackage.array_link(3, 2, 0) self.assertTrue(al2a != al2b) self.assertFalse(al2a == al2b) self.assertTrue(al2a.equalsize(al2b)) self.assertFalse(al2a.equalsize(al3)) self.assertTrue(al2a < al2b) self.assertFalse(al2b < al2a)
def DOPselect(N, cols): """ Generates columns of candidate designs according to the DOP selection criterion. Parameters ---------- cols : list List of columns numbers. Returns ------- out : list List of lists of columns numbers, in 1-based indexing, of the selected designs. """ r = int(np.log2(N)) B = Bmat(r) candicols = [i for i in range(1, N) if i not in cols] out = [] for col in candicols: tempcols = cols + [col] Dc = B[:, [i - 1 for i in tempcols]] wlplst = [] for j in range(Dc.shape[1]): DOP = np.delete(Dc, j, axis=1) wlplst.append(oa.array_link(DOP).GWLP()[3:]) if __isMA(wlplst): out.append(tempcols) return out
def NAUTYiso(C, r): """ Isomorphism class representative selection using NAUTY algorithm. Parameters ---------- C : list List of lists of column numbers, in 1-based indexing, of the conditate designs r : int Number of basic factors in the candidate designs. Returns ------- list List of lists of columns numbers, in 1-based indexing, of the design selected as representatives of their isomorphism classes. """ B = Bmat(r) # Converts columns to designs in OA al = [oa.array_link(B[:, [i - 1 for i in sorted(x)]]) for x in C] # Define the isomorphism classes ind, isoClass = selectIsomorphismClasses(al, verbose=0) # Select one rep. per class vals, zz = np.unique(ind, return_index=True) zz.sort() return [C[x] for x in list(zz)]
def test_modelmatrix_main_effects(self): # test model matrix main effects are helmert contrasts array = oapackage.array_link(np.array([[0, 1, 2, 3]]).T) M = oapackage.array2modelmatrix(array, 'm') hc = oapackage.oahelper.helmert_contrasts(4) np.testing.assert_array_almost_equal(hc, M[:, 1:])
def conferenceProjectionStatistics(array, ncolumns=4, verbose=0): """ Calculate the projection statistics of a conference design The PECk, PICk and PPCk are calculated with k the number of columns specified. The projection statistics are calculated by determined the :meth:`modelStatistics` of all k-column subdesigns and then taking the mean of the statistics for the subdesigns. For more details of the calculation, see https://oapackage.readthedocs.io/. Args: array (array): conference design ncolumns (int): number of columns on which to project Returns: pec, pic, ppc (float): calculated statistics """ nc = array.shape[1] number_combinations = oapackage.choose(nc, ncolumns) Eestx = np.zeros(number_combinations) Deff = np.zeros(number_combinations) invAPV_values = np.zeros(number_combinations) dsd = oapackage.conference2DSD(oapackage.array_link(array)) moment_matrix = momentMatrix(ncolumns) for idx, c in enumerate(list(itertools.combinations(range(nc), ncolumns))): proj_dsd = dsd.selectColumns(c) Eest, D, invAPV = modelStatistics(proj_dsd, verbose=0, moment_matrix=moment_matrix) Deff[idx] = D Eestx[idx] = Eest invAPV_values[idx] = invAPV pec, pic, ppc = np.mean(Eestx), np.mean(Deff), np.mean(invAPV_values) if verbose: print('conferenceProjectionStatistics: projection to %d columns: PEC %.3f PIC %.3f PPC %.3f ' % (ncolumns, pec, pic, ppc)) return pec, pic, ppc
def test_selectFirstColumns(self): al = oapackage.exampleArray(41, 0) al = al.selectFirstColumns(3) self.assertEqual(al.n_columns, 3) al = oapackage.array_link() with self.assertRaises(RuntimeError): al = al.selectFirstColumns(1)
def test_selectParetoArrays(self): arrays = [oapackage.array_link(np.array([[ii]])) for ii in range(5)] pareto_object = oapackage.ParetoLongLong() for ii in range(len(arrays)): value = [ii, ii % 2] pareto_object.addvalue(value, ii) pareto_object.show(2) selected = oapackage.oahelper.selectParetoArrays(arrays, pareto_object) self.assertEqual(selected, arrays[4, 5])
def test_LMC(self): al = oapackage.array_link(2, 2, 0) al[1, 1] = -1 self.assertRaises(RuntimeError, oapackage.reduceLMCform, al) al = oapackage.exampleArray(8, 0) alr = oapackage.reduceLMCform(al) self.assertTrue(alr == al) array0 = oapackage.exampleArray(1, 0).selectFirstColumns(3) array = array0.randomperm() reduced_array = oapackage.reduceLMCform(array) self.assertEqual(array0, reduced_array)
def test_array_class_functions(self): al = oapackage.exampleArray(1, 0) self.assertTrue(al.is2level()) self.assertFalse(al.is_mixed_level()) al = oapackage.exampleArray(11, 0) self.assertTrue(al.is2level()) self.assertFalse(al.is_mixed_level()) al = oapackage.array_link(2, 2, 0) al[1, 1] = -1 self.assertFalse(al.is2level()) self.assertFalse(al.is_mixed_level())
def distance_distribution(self): al = oapackage.array_link(2, 2, 0) distance_distrib = oapackage.distance_distribution(al) self.assertEqual(distance_distrib, (2.0, 0.0, 0.0)) al[1, 0] = 1 distance_distrib = oapackage.distance_distribution(al) self.assertEqual(distance_distrib, (1.0, 1.0, 0.0)) al = oapackage.exampleArray(2, 0) distance_distrib = oapackage.distance_distribution(al) self.assertEqual(distance_distrib, (1.25, 0.75, 1.5, 6.5, 5.25, 0.75, 0.0))
def test_jstruct_conference(self): conf_design = oapackage.exampleArray(30, 0) js = oapackage.jstructconference_t(conf_design, 4) self.assertEqual(js.Jvalues(), (4, 0)) with self.assertRaises(RuntimeError): js = oapackage.jstructconference_t(conf_design, 3) array = oapackage.array_link(10, 4, 0) with mock.patch('sys.stdout', new_callable=io.StringIO) as mock_stdout: with self.assertRaises(Exception): js = oapackage.jstructconference_t(array, 4) std_output = mock_stdout.getvalue() self.assertIn('array is not conference design', std_output)
def test_arraylink2arraydata(self): al = oapackage.exampleArray(0, 0) adata = oapackage.arraylink2arraydata(al) self.assertEqual( str(adata), r'arrayclass: N 8, k 2, strength 2, s {2,2}, order 0') al = oapackage.array_link(4, 4, 0) al.setconstant(0) adata = oapackage.arraylink2arraydata(al) al.setconstant(-1) with self.assertRaises(RuntimeError): _ = oapackage.arraylink2arraydata(al) for ii in [0, 4, 8, 10]: al = oapackage.exampleArray(ii, 0) arrayclass = oapackage.arraylink2arraydata(al, strength=-1) self.assertEqual(arrayclass.strength, al.strength())
def conferenceProjectionStatistics(array, ncolumns=4, verbose=0): """ Calculate the projection statistics of a conference design The PECk, PICk and PPCk are calculated with k the number of columns specified. The projection statistics are calculated by determined the :meth:`modelStatistics` of all k-column subdesigns and then taking the mean of the statistics for the subdesigns. For more details of the calculation, see https://oapackage.readthedocs.io/. Args: array (array): conference design ncolumns (int): number of columns on which to project Returns: pec, pic, ppc (float): calculated statistics """ nc = array.shape[1] number_combinations = oapackage.choose(nc, ncolumns) Eestx = np.zeros(number_combinations) Deff = np.zeros(number_combinations) invAPV_values = np.zeros(number_combinations) dsd = oapackage.conference2DSD(oapackage.array_link(array)) moment_matrix = momentMatrix(ncolumns) for idx, c in enumerate(list(itertools.combinations(range(nc), ncolumns))): proj_dsd = dsd.selectColumns(c) Eest, D, invAPV = modelStatistics(proj_dsd, verbose=0, moment_matrix=moment_matrix) Deff[idx] = D Eestx[idx] = Eest invAPV_values[idx] = invAPV pec, pic, ppc = np.mean(Eestx), np.mean(Deff), np.mean(invAPV_values) if verbose: print( 'conferenceProjectionStatistics: projection to %d columns: PEC %.3f PIC %.3f PPC %.3f ' % (ncolumns, pec, pic, ppc)) return pec, pic, ppc
def isoSelection(cat): al = [oa.array_link(x['design'].astype(int)) for x in cat] ind, isoClass = selectIsomorphismClasses(al, verbose=2) vals, zz = np.unique(ind, return_index=True) zz.sort() return [cat[x] for x in list(zz)]
print('---NAUTY procedure\t', '-' * 50) print('%i runs - up to %i factors\n' % (N, maxfac)) firstTic = time.time() for k in range(r + 1, maxfac): tic = time.time() # Get candidates candicols = [] for cols in startcols: candicols.append(tools.DOPselect(N, cols)) candicols = list(chain(*candicols)) # Isomorphism reduction al = [] for cols in candicols: candiD = B[:, [i - 1 for i in sorted(cols)]] al.append(oa.array_link(candiD)) isocols = NAUTYiso(al, candicols) for cols in isocols: cat = cat.append({'n': k + 1, 'cols': cols}, ignore_index=True) toc = time.time() # Initiate next run if verbose: print( '%i factors: %i candidates - %i representatives\t\t (%.2f sec.)' % (k + 1, nbrCandi, len(isocols), tic - toc)) startcols = isocols totalTime = time.time() - firstTic print('\nNAUTY procedure: Catalog generated in %.2f seconds' % totalTime) print('-' * 70, '\n')