def test_single_matrix(self): mat = np.array([[1, 2, 3], [4, 5, 6]]) assert np.allclose(diff(mat), np.array([[-3, -3, -3]])) assert np.allclose(diff(mat, flatten=True), np.array([[-3, -3, -3]])) assert np.allclose( diff(mat, flatten=False), np.array([[[0, 0, 0], [-3, -3, -3]], [[3, 3, 3], [0, 0, 0]]]))
def test_matrices_row(self): mat1 = np.array([[1, 2, 3], [4, 5, 6]]) mat2 = np.array([[4, 5, 6], [7, 8, 9]]) assert np.allclose( diff(mat1, mat2), np.array([[[-3, -3, -3], [-6, -6, -6]], [[0, 0, 0], [-3, -3, -3]]]))
def test_matrices_column(self): mat1 = np.array([[1, 2, 3], [4, 5, 6]]) mat2 = np.array([[4, 5, 6], [7, 8, 9]]) assert np.allclose( diff(mat1, mat2, axis=1), np.array([[[-3, -3], [-4, -4], [-5, -5]], [[-2, -2], [-3, -3], [-4, -4]], [[-1, -1], [-2, -2], [-3, -3]]]))
def _get_mm_val(self, sam_set, p_dist_old, mm_val_old, r1, r2): # Create arrays containing new p_dist and mm_val p_dist = p_dist_old.copy() mm_val = np.zeros(self.n_sam) # Calculate new p_dist of row r1 and r2 p_dist_r1 = np.sum(abs(diff(sam_set[r1], sam_set)), axis=-1) p_dist_r2 = np.sum(abs(diff(sam_set[r2], sam_set)), axis=-1) # Update p_dist and mm_val with newly calculated values p_dist[r1] = p_dist[:, r1] = p_dist_r1 p_dist[r2] = p_dist[:, r2] = p_dist_r2 iets1 = p_dist_r1[np.arange(self.n_sam + self.n_sam_c) != r1] iets2 = p_dist_r2[np.arange(self.n_sam + self.n_sam_c) != r2] if ((iets1 == 0).any()): mm_val[r1] = np.infty else: mm_val[r1] = pow(np.sum(pow(iets1, -self.p)), 1 / self.p) if ((iets2 == 0).any()): mm_val[r2] = np.infty else: mm_val[r2] = pow(np.sum(pow(iets2, -self.p)), 1 / self.p) # Create list containing only indices of unchanged rows idx = list(range(self.n_sam)) idx.remove(r1) idx.remove(r2) # Update the mm_val of all unchanged rows mm_val[idx] = pow( pow(mm_val_old[idx], self.p) - pow(p_dist_old[r1, idx], -self.p) - pow(p_dist_old[r2, idx], -self.p) + pow(p_dist_r1[idx], -self.p) + pow(p_dist_r2[idx], -self.p), 1 / self.p) # Return it return (p_dist, mm_val)
def _get_mm_val_init(self, sam_set): # TODO: Check if masked arrays are really faster than lots of indexing # Calculate the pair-wise point distances masked_idx = np.diag_indices(self.n_sam, ndim=2) p_dist = np.sum(abs(diff(sam_set, axis=0, flatten=False)), axis=-1) p_dist = np.ma.array(p_dist, mask=False, hard_mask=True) p_dist.mask[masked_idx] = True p_dist.mask[self.n_sam:, self.n_sam:] = True # Create empty array containing the maximin values of all rows mm_val = np.zeros(self.n_sam) # Calculate maximin values for i, row_dist in enumerate(p_dist[:self.n_sam]): mm_val[i] = pow(np.sum(pow(row_dist, -self.p)), 1 / self.p) # Return it return (p_dist, mm_val)
def _get_mm_bounds(self): # Calculate the p_dist of the provided sam_set p_dist_slice = self.n_sam_c * self.n_sam + nCr(self.n_sam, 2) p_dist = abs(diff(self.sam_set, axis=0, flatten=True))[:p_dist_slice] # Calculate the average distance between randomly chosen samples self.dist_avg = np.average(np.sum(p_dist, axis=-1)) # TODO: Look at calculation of mm_lower once more # Calculate lower and upper boundaries of the maximin-rank self.mm_lower = pow(nCr(self.n_sam, 2), 1 / self.p) / self.dist_avg p_dist_sort = np.sum(np.sort(p_dist, axis=0), axis=-1) # TODO: This has many exception cases, so maybe make an extra method? # If (due to constraints) any value in p_dist is zero, change p_dist in # such a way that it resembles the worst p_dist possible with no zeros if ((p_dist_sort == 0).any()): values, counts = np.unique(p_dist_sort, return_counts=True) # p_dist_sort[:counts[0]] += values[1]/self.n_val # p_dist_sort[counts[0]:counts[1]] -= values[1]/self.n_val p_dist_sort[:counts[0]] += np.min(p_dist[p_dist != 0]) p_dist_sort[counts[0]:counts[1]] -= np.min(p_dist[p_dist != 0]) self.mm_upper = pow(np.sum(pow(p_dist_sort, -self.p)), 1 / self.p)
def test_two_diff_axes(self): mat1 = np.array([[1, 2, 3, 4], [4, 5, 6, 7]]) mat2 = np.array([[4, 5, 6], [7, 8, 9]]) with pytest.raises(ShapeError): diff(mat1, mat2)
def test_double_invalid_axis(self): vec1 = np.array([1, 2, 3]) vec2 = np.array([4, 5, 6]) with pytest.raises(InputError): diff(vec1, vec2, axis=1)
def test_single_invalid_axis(self): vec = np.array([7, 8, 9]) with pytest.raises(InputError): diff(vec, axis=1)
def test_single_scalar(self): assert diff(1) == 0
def test_scalars(self): assert diff(2, 1) == 1
def test_single_vector(self): vec = np.array([7, 8, 9]) assert np.allclose(diff(vec), [-1, -2, -1])
def test_vectors(self): vec1 = np.array([1, 2, 3]) vec2 = np.array([4, 5, 6]) assert np.allclose( diff(vec1, vec2), np.array([[-3, -4, -5], [-2, -3, -4], [-1, -2, -3]]))
def test_matrix_vector(self): mat = np.array([[1, 2, 3], [4, 5, 6]]) vec = np.array([7, 8, 9]) assert np.allclose(diff(mat, vec), np.array([[-6, -6, -6], [-3, -3, -3]])) assert np.allclose(diff(vec, mat), np.array([[6, 6, 6], [3, 3, 3]]))
def test_matrix_vector_diff_axes(self): mat = np.array([[1, 2, 3, 4], [4, 5, 6, 7]]) vec = np.array([7, 8, 9]) with pytest.raises(ShapeError): diff(mat, vec)
def test_matrix_vector_invalid_axis(self): mat = np.array([[1, 2, 3], [4, 5, 6]]) vec = np.array([7, 8, 9]) with pytest.raises(InputError): diff(mat, vec, axis=2)