Skip to content

Commit

Permalink
Added docstrings to some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jerela committed Nov 10, 2023
1 parent 79a7f60 commit 16e4953
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 2 deletions.
4 changes: 2 additions & 2 deletions documentation/mola.clustering.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
Arguments:<br>
p1&nbsp;--&nbsp;list:&nbsp;the&nbsp;first&nbsp;point<br>
p2&nbsp;--&nbsp;list:&nbsp;the&nbsp;second&nbsp;point</tt></dd></dl>
<dl><dt><a name="-find_c_means"><strong>find_c_means</strong></a>(data: mola.matrix.Matrix, num_centers=2, max_iterations=100, distance_function=&lt;function distance_euclidean_pow at 0x000002348F1974C0&gt;, initial_centers=None)</dt><dd><tt>Return&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;and&nbsp;the&nbsp;membership&nbsp;matrix&nbsp;of&nbsp;points&nbsp;using&nbsp;soft&nbsp;k-means&nbsp;clustering&nbsp;(also&nbsp;known&nbsp;as&nbsp;fuzzy&nbsp;c-means).<br>
<dl><dt><a name="-find_c_means"><strong>find_c_means</strong></a>(data: mola.matrix.Matrix, num_centers=2, max_iterations=100, distance_function=&lt;function distance_euclidean_pow at 0x00000208A1C724C0&gt;, initial_centers=None)</dt><dd><tt>Return&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;and&nbsp;the&nbsp;membership&nbsp;matrix&nbsp;of&nbsp;points&nbsp;using&nbsp;soft&nbsp;k-means&nbsp;clustering&nbsp;(also&nbsp;known&nbsp;as&nbsp;fuzzy&nbsp;c-means).<br>
&nbsp;<br>
Fuzzy&nbsp;c-means&nbsp;clustering&nbsp;is&nbsp;an&nbsp;iterative&nbsp;algorithm&nbsp;that&nbsp;finds&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;by&nbsp;first&nbsp;assigning&nbsp;each&nbsp;point&nbsp;to&nbsp;each&nbsp;cluster&nbsp;center&nbsp;with&nbsp;a&nbsp;certain&nbsp;membership&nbsp;value&nbsp;(0&nbsp;to&nbsp;1)&nbsp;and&nbsp;then&nbsp;updating&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;to&nbsp;be&nbsp;the&nbsp;weighted&nbsp;mean&nbsp;of&nbsp;the&nbsp;points&nbsp;assigned&nbsp;to&nbsp;them.&nbsp;This&nbsp;process&nbsp;is&nbsp;repeated&nbsp;for&nbsp;a&nbsp;set&nbsp;number&nbsp;of&nbsp;iterations&nbsp;or&nbsp;until&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;converge.&nbsp;The&nbsp;initial&nbsp;cluster&nbsp;centers&nbsp;are&nbsp;either&nbsp;randomized&nbsp;or&nbsp;given&nbsp;by&nbsp;the&nbsp;user.<br>
A&nbsp;major&nbsp;difference&nbsp;between&nbsp;hard&nbsp;k-means&nbsp;clustering&nbsp;and&nbsp;fuzzy&nbsp;c-means&nbsp;clustering&nbsp;is&nbsp;that&nbsp;in&nbsp;fuzzy&nbsp;c-means&nbsp;clustering,&nbsp;the&nbsp;points&nbsp;may&nbsp;belong&nbsp;partially&nbsp;to&nbsp;several&nbsp;clusters&nbsp;instead&nbsp;of&nbsp;belonging&nbsp;completely&nbsp;to&nbsp;one&nbsp;cluster,&nbsp;like&nbsp;in&nbsp;hard&nbsp;k-means&nbsp;clustering.&nbsp;Therefore,&nbsp;this&nbsp;algorithm&nbsp;is&nbsp;well-suited&nbsp;to&nbsp;cluster&nbsp;data&nbsp;that&nbsp;is&nbsp;not&nbsp;clearly&nbsp;separable&nbsp;into&nbsp;distinct&nbsp;clusters&nbsp;(e.g.,&nbsp;symmetric&nbsp;distribution&nbsp;of&nbsp;data&nbsp;points).<br>
Expand All @@ -47,7 +47,7 @@
max_iterations&nbsp;--&nbsp;int:&nbsp;the&nbsp;maximum&nbsp;number&nbsp;of&nbsp;iterations&nbsp;where&nbsp;cluster&nbsp;centers&nbsp;are&nbsp;updated&nbsp;(default&nbsp;100)<br>
distance_function&nbsp;--&nbsp;function:&nbsp;the&nbsp;distance&nbsp;function&nbsp;to&nbsp;be&nbsp;used&nbsp;(default&nbsp;Euclidean&nbsp;distance);&nbsp;options&nbsp;are&nbsp;squared&nbsp;Euclidean&nbsp;distance&nbsp;(distance_euclidean_pow)&nbsp;and&nbsp;taxicab&nbsp;distance&nbsp;(distance_taxicab)<br>
initial_centers&nbsp;--&nbsp;Matrix:&nbsp;the&nbsp;initial&nbsp;cluster&nbsp;centers;&nbsp;if&nbsp;not&nbsp;specified,&nbsp;they&nbsp;are&nbsp;initialized&nbsp;randomly&nbsp;(default&nbsp;None)</tt></dd></dl>
<dl><dt><a name="-find_k_means"><strong>find_k_means</strong></a>(data: mola.matrix.Matrix, num_centers=2, max_iterations=100, distance_function=&lt;function distance_euclidean_pow at 0x000002348F1974C0&gt;, initial_centers=None)</dt><dd><tt>Return&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;using&nbsp;hard&nbsp;k-means&nbsp;clustering.<br>
<dl><dt><a name="-find_k_means"><strong>find_k_means</strong></a>(data: mola.matrix.Matrix, num_centers=2, max_iterations=100, distance_function=&lt;function distance_euclidean_pow at 0x00000208A1C724C0&gt;, initial_centers=None)</dt><dd><tt>Return&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;using&nbsp;hard&nbsp;k-means&nbsp;clustering.<br>
&nbsp;<br>
K-means&nbsp;clustering&nbsp;is&nbsp;an&nbsp;iterative&nbsp;algorithm&nbsp;that&nbsp;finds&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;by&nbsp;first&nbsp;assigning&nbsp;each&nbsp;point&nbsp;to&nbsp;the&nbsp;closest&nbsp;cluster&nbsp;center&nbsp;and&nbsp;then&nbsp;updating&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;to&nbsp;be&nbsp;the&nbsp;mean&nbsp;of&nbsp;the&nbsp;points&nbsp;assigned&nbsp;to&nbsp;them.&nbsp;This&nbsp;process&nbsp;is&nbsp;repeated&nbsp;for&nbsp;a&nbsp;set&nbsp;number&nbsp;of&nbsp;iterations&nbsp;or&nbsp;until&nbsp;the&nbsp;cluster&nbsp;centers&nbsp;converge.&nbsp;The&nbsp;initial&nbsp;cluster&nbsp;centers&nbsp;are&nbsp;either&nbsp;randomized&nbsp;or&nbsp;given&nbsp;by&nbsp;the&nbsp;user.<br>
&nbsp;<br>
Expand Down
2 changes: 2 additions & 0 deletions tests/clustering_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@


def test_k_means_clustering():
"""Test hard k-means clustering."""
initial_centers = Matrix([[0,0],[20,0]])
symmetric_points = Matrix([[-1,0],[-2,2],[1,1],[20,2],[18,0],[22,-1],[23,-1]])
centers = clustering.find_k_means(data=symmetric_points,num_centers=2,initial_centers=initial_centers)
assert(utils.equals_approx(centers,Matrix([[-0.6667, 1.0],[20.75, 0.0]]),precision = 1e-4))

def test_c_means_clustering():
"""Test fuzzy c-means clustering."""
initial_centers = Matrix([[-1,0],[1,0]])
symmetric_points = Matrix([[-1,1],[-2,2],[1,1],[2,2],[0,0],[-1,-1],[1,-1]])
centers, membership = clustering.find_c_means(data=symmetric_points,num_centers=2,initial_centers = initial_centers)
Expand Down
1 change: 1 addition & 0 deletions tests/decomposition_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from mola import decomposition

def test_qr_decomposition():
"""Test QR decomposition."""
mat = Matrix([ [12, -51, 4], [6, 167, -68], [-4, 24, -41] ])
Q, R = decomposition.qrd(mat)
q = Matrix([ [0.8571, -0.3943, 0.3314], [0.4286, 0.9029, -0.0343], [-0.2857, 0.1714, 0.9429]])
Expand Down
14 changes: 14 additions & 0 deletions tests/matrix_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,42 @@


def test_equals_approx():
"""Test the equals_approx() method of utils, which we will be using in comparing some matrices."""
assert(utils.equals_approx([1,2],[1,2]))
assert(utils.equals_approx(3.5,3.5))
assert(utils.equals_approx((1,2),(1,2)))
assert(utils.equals_approx(Matrix(1,2),Matrix(1,2)))

def test_inverse():
"""Test matrix inversion."""
matrix = Matrix([[2,1,-1],[-3,-1,2],[-2,1,2]])
inverse = matrix.get_inverse()
identity_matrix = utils.identity(3)
product = matrix*inverse
assert(product==identity_matrix)

def test_read_write():
"""Test reading and writing matrices to files."""
mat1 = Matrix([ [1,2,3],[4,5,6],[5,6,7] ])
utils.write_matrix_to_file(mat1,'data.txt')
mat2 = utils.read_matrix_from_file('data.txt')
assert(mat2==Matrix([ [1,2,3],[4,5,6],[5,6,7] ]))

def test_multiplication():
"""Test matrix multiplication."""
mat1 = Matrix(3,5,1)
mat2 = utils.identity(3,3)
assert(mat2*mat1==mat1)

def test_singularity():
"""Test matrix singularity and invertibility functions."""
# create a singular matrix
sing = Matrix([[4, 2, 0], [2, 1, 0], [5,12,-5]])
assert(sing.is_invertible() == False)
assert(sing.is_singular() == True)

def test_rank():
"""Test the get_rank() method of Matrix."""
sing = Matrix([[4, 2, 0], [2, 1, 0], [5,12,-5]])
A = Matrix([[1, 1, 0, 2], [-1, -1, 0, -2]])
B = Matrix([[5]])
Expand All @@ -45,41 +51,49 @@ def test_rank():

# TESTS FOR LABELED MATRICES BEGIN HERE
def test_labeled_from_dict():
"""Test the constructor of LabeledMatrix that takes a dictionary as an argument."""
labeled_matrix_dict = {'first_column': [1, 2, 3], 'its_square': [1, 4, 9]}
labeled_matrix = LabeledMatrix(labeled_matrix_dict)
matrix = Matrix([[1, 1], [2, 4], [3, 9]])
assert(labeled_matrix == matrix)

def test_labeled_from_lists():
"""Test the constructor of LabeledMatrix that takes a list of lists as an argument."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
matrix = Matrix([[1,2,3], [4,5,6], [7,8,9]])
assert(labeled_matrix == matrix)

def test_labeled_get_set():
"""Test the get() and set() methods of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
labeled_matrix.set('first row', 'third column', 0)
assert(labeled_matrix.get('first row', 'third column') == 0)

def test_labeled_getitem():
"""Test the __getitem__() method of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
assert(labeled_matrix['first row'] == labeled_matrix[0])
assert(labeled_matrix['second row','third column'] == labeled_matrix[1,2])

def test_labeled_setitem():
"""Test the __setitem__() method of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
labeled_matrix['second row','third column'] = 0
assert(labeled_matrix['second row','third column'] == 0)

def test_labeled_get_row():
"""Test the get_row() method of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
assert(labeled_matrix.get_row('second row') == labeled_matrix.get_row(1))

def test_labeled_set_row():
"""Test the set_row() method of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
labeled_matrix.set_row('first row', [0,0,0])
assert(labeled_matrix.get_row('first row') == [0,0,0])

def test_labeled_get_column():
"""Test the get_column() method of LabeledMatrix."""
labeled_matrix = LabeledMatrix([[1,2,3], [4,5,6], [7,8,9]], labels_col = ['first column', 'second column', 'third column'], labels_row=['first row', 'second row', 'third row'])
assert(labeled_matrix.get_column('third column') == labeled_matrix.get_column(2))

4 changes: 4 additions & 0 deletions tests/regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@
from mola import utils

def test_linear_regression():
"""Test linear regression (fitting of a first-degree polynomial with an intercept)."""
H = Matrix([[2,1],[4,1],[6,1]])
y = Matrix([[0],[1],[2]])
th = regression.linear_least_squares(H,y)
assert(th[0]-0.5 < 1e-6 and th[1]-1 < 1e-6)

def test_second_order_polynomial_regression():
"""Test second-order polynomial regression (fitting of a second-degree polynomial)."""
independent_values = Matrix([[-1],[0],[2]])
dependent_values = Matrix([[1],[0],[4]])
th = regression.fit_univariate_polynomial(independent_values,dependent_values, degrees=[2], intercept=False)
assert(utils.equals_approx(th[0],1))

def test_first_order_polynomial_regression():
"""Test first-order polynomial regression (fitting of a first-degree polynomial)."""
independent_values = Matrix([ [2],[4],[6] ])
dependent_values = Matrix([[0],[1],[2]])
assert(utils.equals_approx(regression.fit_univariate_polynomial(independent_values, dependent_values, degrees=[1, 2], intercept=True), (0.5, 0, -1)))

def test_nonlinear_regression():
"""Test nonlinear regression with Gauss-Newton iteration."""
h = Matrix([lambda a,x: pow(a,x)])
independents = Matrix([1, 2, 3])
y = Matrix([2, 4, 8])
Expand Down

0 comments on commit 16e4953

Please sign in to comment.