From e863761b2d54adf5acc1954ecfd04f633a050df4 Mon Sep 17 00:00:00 2001 From: Jeremy Gresham Date: Mon, 11 May 2015 15:10:01 -0400 Subject: [PATCH 1/3] initial commit --- matrix_math.py | 84 +++++++++++++++++++++++++++++++++++++++++++++ test_matrix_math.py | 7 +++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/matrix_math.py b/matrix_math.py index 7c55a83..76eb00c 100644 --- a/matrix_math.py +++ b/matrix_math.py @@ -1,2 +1,86 @@ +import math + + class ShapeException(Exception): pass + + +def shape(vector): + """ + with no regard for poorly made lists + returns the shape of the list + """ + if isinstance(vector[0], list): + return (len(vector), len(vector[0])) + return (len(vector), ) + + +def compare(vect1, vect2): + return shape(vect1) == shape(vect2) + + +def vector_add(vect1, vect2): + + if compare(vect1, vect2): + return [coeff1 + coeff2 for (coeff1, coeff2) in list(zip(vect1,vect2))] + + raise ShapeException + + +def vector_sub(vect1, vect2): + return vector_add(vect1, [-num for num in vect2]) + + +def vector_sum(*vectors): + vectors = list(vectors) + if len(vectors) > 1: + return vector_add(vectors.pop(), vector_sum(*vectors)) + else: + return vectors[0] + + +def dot(vect1, vect2): + if compare(vect1, vect2): + return sum([coeff1 * coeff2 for (coeff1, coeff2) in list(zip(vect1,vect2))]) + + raise ShapeException + +def vector_multiply(vector, scalar): + return [entry * scalar for entry in vector] + + +def vector_mean(*vectors): + return vector_multiply(vector_sum(*vectors), 1/len(vectors)) + + +def magnitude(vector): + return math.sqrt(sum([entry**2 for entry in vector])) + + +def matrix_row(matrix, row): + return matrix[row] + + +def transpose(matrix): + return [[row[i] for row in matrix] for i in range(len(matrix[0]))] + + +def matrix_col(matrix, col): + return matrix_row(transpose(matrix),col) + + +def matrix_scalar_multiply(matrix, scalar): + return [vector_multiply(vect, scalar) for vect in matrix] + + +def matrix_vector_multiply(matrix, vector): + if compare(matrix[0], vector): + return [dot(row, vector) for row in matrix] + raise ShapeException + + +def matrix_matrix_multiply(mat1, mat2): + if shape(mat1)[1] == shape(mat2)[0]: + return [[dot(row,col) for col in transpose(mat2)] for row in mat1] + + raise ShapeException diff --git a/test_matrix_math.py b/test_matrix_math.py index a71ad36..265ca04 100644 --- a/test_matrix_math.py +++ b/test_matrix_math.py @@ -1,5 +1,6 @@ from matrix_math import * from nose.tools import raises +import nose def is_equal(x, y, tolerance=0.001): @@ -218,7 +219,7 @@ def test_matrix_matrix_multiply(): Matrix * Matrix = Matrix """ - assert matrix_matrix_multiply(A, B) == A + assert matrix_matrix_multiply(A, B) == B assert matrix_matrix_multiply(B, C) == [[8, 10], [20, 25], [32, 40]] @@ -233,3 +234,7 @@ def test_matrix_matrix_multiply_checks_shapes(): """Shape Rule: The number of columns of the first matrix must equal the number of rows of the second matrix.""" matrix_matrix_multiply(A, D) + + +if __name__ == '__main__': + nose.main() From 7dab6110635c7a7a6bf011697a46a5a41836bebd Mon Sep 17 00:00:00 2001 From: Jeremy Gresham Date: Mon, 11 May 2015 15:18:14 -0400 Subject: [PATCH 2/3] added docstrings --- matrix_math.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/matrix_math.py b/matrix_math.py index 76eb00c..6020c8c 100644 --- a/matrix_math.py +++ b/matrix_math.py @@ -16,22 +16,38 @@ def shape(vector): def compare(vect1, vect2): + """ + Checks if the shapes of the two entries + are the same + """ return shape(vect1) == shape(vect2) def vector_add(vect1, vect2): - + """ + Returns the sum of two vectors + if they are the same shape + """ if compare(vect1, vect2): - return [coeff1 + coeff2 for (coeff1, coeff2) in list(zip(vect1,vect2))] + return [coeff1 + coeff2 for (coeff1, coeff2) + in list(zip(vect1, vect2))] raise ShapeException def vector_sub(vect1, vect2): + """ + Returns the difference of two vectors + if their shapes are the same + """ return vector_add(vect1, [-num for num in vect2]) def vector_sum(*vectors): + """ + Returns the sum of any number of vectors + if their shapes are the same + """ vectors = list(vectors) if len(vectors) > 1: return vector_add(vectors.pop(), vector_sum(*vectors)) @@ -40,47 +56,87 @@ def vector_sum(*vectors): def dot(vect1, vect2): + """ + Returns the dot product of two vectors + if their shape is the same + """ if compare(vect1, vect2): - return sum([coeff1 * coeff2 for (coeff1, coeff2) in list(zip(vect1,vect2))]) + return sum([coeff1 * coeff2 for (coeff1, coeff2) + in list(zip(vect1, vect2))]) raise ShapeException + def vector_multiply(vector, scalar): + """ + Returns the result of multiplying a vector + by a scalar + """ return [entry * scalar for entry in vector] def vector_mean(*vectors): + """ + Returns the mean of any set of vectors + if their shape is the same + """ return vector_multiply(vector_sum(*vectors), 1/len(vectors)) def magnitude(vector): + """ + Returns the magnitude of a vector + in the Euclidean metric + """ return math.sqrt(sum([entry**2 for entry in vector])) def matrix_row(matrix, row): + """ + returns a specified row of a matrix + """ return matrix[row] def transpose(matrix): + """ + returns the transpose of a matrix + """ return [[row[i] for row in matrix] for i in range(len(matrix[0]))] def matrix_col(matrix, col): - return matrix_row(transpose(matrix),col) + """ + returns a specified column of a matrix + """ + return matrix_row(transpose(matrix), col) def matrix_scalar_multiply(matrix, scalar): + """ + Returns the matrix multiplied by a scalar + """ return [vector_multiply(vect, scalar) for vect in matrix] def matrix_vector_multiply(matrix, vector): + """ + Returns the result of multiplying + a given matrix by a given vector + if their shapes are appropriate + """ if compare(matrix[0], vector): return [dot(row, vector) for row in matrix] raise ShapeException def matrix_matrix_multiply(mat1, mat2): + """ + Returns the result of multiplying + a given two matrices + if their shapes are appropriate + """ if shape(mat1)[1] == shape(mat2)[0]: - return [[dot(row,col) for col in transpose(mat2)] for row in mat1] + return [[dot(row, col) for col in transpose(mat2)] for row in mat1] raise ShapeException From d78382af5b28cde99e1eed029f7aa5d2906a0ae1 Mon Sep 17 00:00:00 2001 From: Jeremy Gresham Date: Mon, 11 May 2015 15:28:13 -0400 Subject: [PATCH 3/3] bad indent fixed --- matrix_math.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix_math.py b/matrix_math.py index 6020c8c..dde26fa 100644 --- a/matrix_math.py +++ b/matrix_math.py @@ -131,11 +131,11 @@ def matrix_vector_multiply(matrix, vector): def matrix_matrix_multiply(mat1, mat2): - """ - Returns the result of multiplying - a given two matrices - if their shapes are appropriate - """ + """ + Returns the result of multiplying + a given two matrices + if their shapes are appropriate + """ if shape(mat1)[1] == shape(mat2)[0]: return [[dot(row, col) for col in transpose(mat2)] for row in mat1]