def test_gen_matrix_5(x): a = randrange(2, 100) b = randrange(2, 100) while a == b: b = randrange(2, 100) with pytest.raises(ValueError): gen_matrix(a, b, square=True)
def test_solve_5(): A = gen_matrix(10, 10, square=True) B = gen_matrix(100, 2) # ensure that B has more rows than A while B.shape[0] <= A.shape[0]: B = gen_matrix(100, 2) try: np.linalg.solve(A, B) except ValueError: pass else: raise AssertionError("Solve should not solve for incorrect dimensions")
def test_multiplication_2(): A = gen_matrix(100, 100, square=True) # use square to make sure dimensions line up scalar = random() * 2 - 1 scalar_product = np.dot(scalar * A, A) dot = scalar * np.dot(A, A) assert_matrix_equals(scalar_product, dot)
def test_addition_3(): A = gen_matrix(100, 100) B = gen_matrix(100, 100) # need to ensure that A and B have different dimensions, and none of the dimensions are 1 # otherwise numpy "Broadcasts" which isn't true matrix addition but is defined and is intended functionality while B.shape == A.shape or min(A.shape) == 1 or min(B.shape) == 1: A = gen_matrix(100, 100) B = gen_matrix(100, 100) try: np.add(A, B) except ValueError: pass else: raise AssertionError( "Addition is defined for matrixes with dimensions {} and {}". format(A.shape, B.shape))
def test_determinant_2(): A = gen_matrix(25, 25, square=True) B = np.copy(A) scale_factor = random() B[randrange(0, B.shape[0] ), :] *= scale_factor # scale a random row by scale_factor assert_delta(scale_factor * np.linalg.det(A), np.linalg.det(B))
def test_solve_4(): A = gen_matrix(100, 100, non_square=True) try: np.linalg.solve(A, A) except np.linalg.LinAlgError: pass else: raise AssertionError("Solver should not solve for non-square matrices")
def test_inverse_3(): A = gen_matrix(100, 100, non_square=True) try: np.linalg.inv(A) except np.linalg.LinAlgError: pass else: raise AssertionError("Inverse of a non square matrix is defined")
def test_determinant_4(): A = gen_matrix(5, 5, non_square=True) try: np.linalg.det(A) except np.linalg.LinAlgError: return "Determinant of the following non square matrix is not defined:\n{}".format( A) else: raise AssertionError("Determinant of a non square matrix is defined")
def test_eigen_3(): A = gen_matrix(100, 100, non_square=True) try: np.linalg.eig(A) except np.linalg.LinAlgError: pass else: raise AssertionError( "Eigensolver should not be able to solve a non square matrix")
def test_eigen_2(): A = gen_matrix(100, 100, square=True) eigenvalues, eigenvectors = np.linalg.eig(A) # assert the property holds for each vector and value pair Ax = np.dot(A, eigenvectors) lx = eigenvalues.reshape( 1, A.shape[0] ) * eigenvectors # multiply each eigenvalue by corresponding vector assert_matrix_equals(Ax, lx)
def test_gen_matrix_1(x): height_max = randrange( 2, 100) # max needs to be at least 2 so randrange(1, max) is not empty width_max = randrange(2, 100) A = gen_matrix(height_max, width_max) assert len(A.shape) == 2, "Matrix is not 2 dimnesional" assert A.shape[0] <= height_max and A.shape[ 1] <= width_max, "Dimensions out of range" return "gen_matrix({}, {}) gave a matrix of dimensions {}".format( height_max, width_max, A.shape)
def test_addition_2(): A = gen_matrix(5, 5) B = random() * A + random() # make B based on A so that dimensions fit add1 = np.add(A, B) add2 = np.add(B, A) assert_matrix_equals(add1, add2) # some test functions return output of the correct test case # so we can use it as evidence in our written Report return """A =\n{}\nB =\n{}\nA + B =\n{}\nB + A =\n{}\n Addition is commutative so test passed""".format(A, B, add1, add2)
def test_eigen_1(): A = gen_matrix(100, 100, square=True) # calculate the eigenvalues and sort them so we can compare (as eigenvalue are given in not necessarily the same order) A_eigenvalues = np.sort(np.linalg.eig(A)[0]) AT_eigenvalues = np.sort(np.linalg.eig(A.T)[0]) # reshape into a 2 dimensional matrix so we can use assert_matrix_equals to compare shape = [A.shape[0], 1] assert_matrix_equals(A_eigenvalues.reshape(shape), AT_eigenvalues.reshape(shape))
def test_rank_1(): A = gen_matrix(100, 100) B = np.copy(A) # swap two random rows in B row1, row2 = randrange(0, B.shape[0]), randrange(0, B.shape[0]) B[[row1, row2]] = B[[row2, row1]] assert np.linalg.matrix_rank(A) == np.linalg.matrix_rank( B), "ranks not equal"
def test_pseudo_inverse_4(): A = gen_matrix( 5, 5, non_square=True) # force it to be non square for reporting purposes B = np.linalg.pinv(A) AB = np.dot(A, B) assert_matrix_equals(AB, AB.T) return """A =\n{}\nA_pseudoinverse =\n{}\nA*A_pinv =\n{}\nTranspose of A*A_pinv =\n{}\n i.e. A*A_pinv is hermitian (equal to it's own transpose), a required property of the psuedo inverse, so the test passes""".format(A, B, AB, AB.T)
def test_rank_2(): A = gen_matrix(100, 100) B = np.copy(A) # make one row = a linearly scaled version of another row1, row2 = randrange(0, B.shape[0]), randrange(0, B.shape[0]) B[row1, :] = random() * B[row2, :] + random() assert np.linalg.matrix_rank(A) == np.linalg.matrix_rank( B), "ranks not equal"
def test_solve_1(): A = gen_matrix(5, 5, square=True) I = np.identity(A.shape[0]) X1 = np.linalg.solve(A, I) X2 = np.linalg.solve(I, A) X2_inv = np.linalg.inv(X2) assert_matrix_equals(X1, X2_inv) return """A = \n{}\nI = \n{} Solution of Ax = I:\n{}\nSolution of Ix = A:\n{}\nInverse of solution to Ix = A:\n{}\n The solution to the first and inverse solution to the second are equal hence test passes""".format( A, I, X1, X2, X2_inv)
def test_determinant_1(): # determinant can become quite large for large matrices # throwing off assert_delta, so the dimension must be restricted to 50 A = gen_matrix(25, 25, square=True) B = np.copy(A) # swap two random rows in B row1, row2 = randrange(0, B.shape[0]), randrange(0, B.shape[0]) B[[row1, row2]] = B[[row2, row1]] assert_delta(abs(np.linalg.det(A)), abs(np.linalg.det(B)))
def test_multiplication_5(): A = gen_matrix(100, 100) B = np.copy(A) # add extra rows of zeros to B zeros = np.zeros((A.shape[1] + randrange(1, 100), B.shape[1])) B = np.concatenate((B, zeros)) # assert valueerror is raised try: np.dot(A, B) except ValueError: pass else: raise AssertionError( "Multiplication of incompatible matrices is defined")
def test_multiplication_4(): A = gen_matrix(100, 100, non_square=True, non_singular=True) A_inv = np.linalg.pinv(A) dot = np.dot(A_inv, np.dot(A, A.T)) # note all matrices are non square assert_matrix_equals(dot, A.T)
def test_multiplication_3(): A = gen_matrix(100, 100, square=True) I = np.identity(A.shape[0]) dot = np.dot(I, np.dot(A, I)) # IAI should = A assert_matrix_equals(dot, A)
def test_addition_1(): A = gen_matrix(100, 100) O = np.zeros( A.shape) # additive inverse (zero matrix of the same dimensions as A) result = np.add(A, -A) assert_matrix_equals(result, O)
def test_multiplication_1(): A = gen_matrix(100, 100, square=True) B = np.linalg.inv(A) dot = np.dot(A, B) assert_matrix_equals(dot, np.identity(A.shape[0]))
def test_norm_2(): A = gen_matrix(100, 100) scalar = random() * 2 - 1 # random number on interval [-1, 1] assert_delta(np.linalg.norm(scalar * A), abs(scalar) * np.linalg.norm(A))
def test_solve_3(): A = gen_matrix(100, 100, square=True) Ainv = np.linalg.inv(A) X = np.linalg.solve(A, Ainv) assert_matrix_equals(X, np.dot(Ainv, Ainv))
def test_solve_2(): vector = gen_matrix( 100, 2) # generates a random vector with size randrange(1, 100), 1 X = np.linalg.solve(np.identity(vector.shape[0]), vector) assert_matrix_equals(X, vector)
def test_transpose_2(): A = gen_matrix(100, 100) assert list(A.T.shape) == list(reversed(A.shape)), "Dimensions don't swap"
def test_norm_3(): A = gen_matrix(100, 100) assert np.linalg.norm(A) >= 0
def test_inverse_1(): A = gen_matrix( 100, 100, square=True, non_singular=True) # matrix needs to be non_singular to inver B = np.linalg.inv(np.linalg.inv(A)) assert_matrix_equals(A, B)
def test_norm_1(): A = gen_matrix(100, 100) assert_delta(np.linalg.norm(A), np.linalg.norm(A.T))