]> gitweb.michael.orlitzky.com - dunshire.git/commitdiff
Add a new unit test suite for the dunshire.matrices module.
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 1 Nov 2016 18:36:54 +0000 (14:36 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 1 Nov 2016 18:36:54 +0000 (14:36 -0400)
TODO
dunshire/matrices.py
test/__init__.py
test/matrices_test.py [new file with mode: 0644]

diff --git a/TODO b/TODO
index 21b47eb21370e1d6d5328ff668dca76feb042bc6..afcffc533072cba19efd7ee027ee1e91fc11079d 100644 (file)
--- a/TODO
+++ b/TODO
        3.2630685083642352,
        0.8991268260361712]
 
-11. Add random tests for the matrices module.
+11. Complete the unit tests for the matrices module. We still need to
+    document it, and finish adding all of the tests.
 
 12. Investigate this test failure too. It looks like it was really
     close to being solved, but we would have needed a fudge factor
index 13e8150f5c807914782dbcb49733f36be513912c..bcf83778d62752436f7894b5a6fbad4cc3e1012e 100644 (file)
@@ -140,7 +140,10 @@ def eigenvalues(symmat):
 
     domain_dim = symmat.size[0]
     eigs = matrix(0, (domain_dim, 1), tc='d')
-    syevr(symmat, eigs)
+
+    # Create a copy of ``symmat`` here because ``syevr`` clobbers it.
+    dummy = matrix(symmat, symmat.size)
+    syevr(dummy, eigs)
     return list(eigs)
 
 
index 1d7c9a907394483b2542fa3253b2d24c58e8a9b2..ec1bed0b8a5544091c56bbb457059af112f5d338 100644 (file)
@@ -14,6 +14,7 @@ from dunshire import cones
 from dunshire import errors
 from dunshire import matrices
 from dunshire import games
+from test import matrices_test
 from test import randomgen
 from test import symmetric_linear_game_test
 
@@ -30,6 +31,8 @@ def build_suite():
     suite.addTest(DocTestSuite(randomgen))
     slg_tests = TestLoader().loadTestsFromModule(symmetric_linear_game_test)
     suite.addTest(slg_tests)
+    mat_tests = TestLoader().loadTestsFromModule(matrices_test)
+    suite.addTest(mat_tests)
     return suite
 
 def run_suite(suite):
diff --git a/test/matrices_test.py b/test/matrices_test.py
new file mode 100644 (file)
index 0000000..195549f
--- /dev/null
@@ -0,0 +1,88 @@
+"""
+Unit tests for the functions in the ``matrices`` module.
+"""
+
+from unittest import TestCase
+
+from cvxopt import matrix
+
+from dunshire.matrices import (append_col, append_row, condition_number,
+                               eigenvalues, eigenvalues_re, identity,
+                               inner_product, norm)
+from dunshire.options import ABS_TOL
+from .randomgen import random_matrix, random_natural, random_scalar
+
+class AppendColTest(TestCase):
+
+    def test_size_increases(self):
+        """
+        If we append a column to a matrix, the result should be bigger
+        than the original matrix.
+        """
+        dims = random_natural()
+        mat1 = random_matrix(dims)
+        mat2 = random_matrix(dims)
+        bigmat = append_col(mat1, mat2)
+        self.assertTrue(bigmat.size[0] >= mat1.size[0])
+        self.assertTrue(bigmat.size[1] >= mat1.size[1])
+
+
+class AppendRowTest(TestCase):
+
+    def test_size_increases(self):
+        """
+        If we append a row to a matrix, the result should be bigger
+        than the original matrix.
+        """
+        dims = random_natural()
+        mat1 = random_matrix(dims)
+        mat2 = random_matrix(dims)
+        bigmat = append_row(mat1, mat2)
+        self.assertTrue(bigmat.size[0] >= mat1.size[0])
+        self.assertTrue(bigmat.size[1] >= mat1.size[1])
+
+
+class EigenvaluesTest(TestCase):
+
+    def test_eigenvalues_input_not_clobbered(self):
+        mat = random_matrix(random_natural())
+        symmat = mat + mat.trans()
+        symmat_copy = matrix(symmat, symmat.size)
+        eigs = eigenvalues(symmat)
+        self.assertTrue(norm(symmat - symmat_copy) < ABS_TOL)
+
+    def test_eigenvalues_re_input_not_clobbered(self):
+        mat = random_matrix(random_natural())
+        mat_copy = matrix(mat, mat.size)
+        eigs = eigenvalues_re(mat)
+        self.assertTrue(norm(mat - mat_copy) < ABS_TOL)
+
+    def test_eigenvalues_of_symmetric_are_real(self):
+        mat = random_matrix(random_natural())
+        symmat = mat + mat.trans()
+        eigs1 = sorted(eigenvalues(symmat))
+        eigs2 = sorted(eigenvalues_re(symmat))
+        diffs = [abs(e1-e2) for (e1,e2) in zip(eigs1,eigs2)]
+        self.assertTrue(all([diff < ABS_TOL for diff in diffs]))
+
+
+    def test_eigenvalues_of_identity(self):
+        mat = identity(random_natural(), typecode='d')
+        eigs1 = eigenvalues(mat)
+        eigs2 = eigenvalues_re(mat)
+        self.assertTrue(all([abs(e1 - 1) < ABS_TOL for e1 in eigs1]))
+        self.assertTrue(all([abs(e2 - 1) < ABS_TOL for e2 in eigs2]))
+
+
+class InnerProductTest(TestCase):
+
+    def test_norm_is_nonnegative(self):
+        vec = matrix([random_scalar() for _ in range(random_natural())])
+        self.assertTrue(inner_product(vec,vec) >= 0)
+
+
+def ConditionNumberTest(TestCase):
+
+    def test_condition_number_ge_one(self):
+        mat = random_matrix(random_natural())
+        self.assertTrue(condition_number(mat) >= 1)