def test_smith_normal_form(): one = np.matrix([[1, 1],[0, 1]]) assert np.all(smith_normal_form(one)[0] == np.eye(2)) two = np.matrix([[1, 0],[1, 1]]) assert np.all(smith_normal_form(two)[0] == np.eye(2)) three = np.matrix([[1, -17], [0, 1]]) assert np.all(smith_normal_form(three)[0] == np.eye(2)) four = np.matrix([[1, 3], [4, -9]]) four = smith_normal_form(four)[0] assert four[0, 0] == 1 assert four[1, 0] == 0 assert four[0, 1] == 0 five = np.matrix([[100, 0], [41, 89]]) five = smith_normal_form(five)[0] assert all_zero_facade(five) assert divides(five[0, 0], five[1, 1]) six = np.matrix([[-5, -2], [-2, -4]]) assert np.all(smith_normal_form(six)[0] == np.matrix([[1, 0], [0, 16]])) seven = np.matrix([[-2, 1, 0, 0, 0], [1, -3, 1, 1, 0], [0, 1, -2, 0, 0], [0, 1, 0, -2, 1], [0, 0, 0, 1, -2]]) smith_seven = np.matrix(np.eye(5)) smith_seven[4, 4] = 16 assert np.all(smith_seven == smith_normal_form(seven)[0]) eight = np.matrix([[88, 56, 97], [31, 32, 12], [78, 58, 43]]) smith_eight = np.matrix(np.eye(3)) smith_eight[2, 2] = 30098 assert np.all(smith_eight == smith_normal_form(eight)[0])
def test_random_smith_normal_form(m): '''Checks that the smith normal form routine behaves appropriately''' s, _ = smith_normal_form(m) def close_enough(a, b, max_rel_diff): # Don't have a good workaround for this. a = math.fabs(a) b = math.fabs(b) if math.log(a + 1) > 15: return True diff = math.fabs(a - b) largest = max(a, b) return diff <= largest * max_rel_diff assert close_enough(det(m), det(s), 0.1) assert is_diagonal(s) assert diagonal_chaining(s) for i in xrange(s.shape[0] - 1): if not divides(s[i, i], s[i + 1, i + 1]): print s print m assert divides(s[i, i], s[i + 1, i + 1])