Exemple #1
0
def lu(M, info=None):
    if not isinstance(M, Matrix):
        return None
    rows, cols = M.size()
    if rows != cols:
        raise ArithmeticError("LU factorization requires a square matrix (rows == cols)") 
    A = copy.deepcopy(M)
    L = Matrix(rows, cols, mtype='i')
    U = Matrix(rows, cols)
    P = Matrix(rows, cols, mtype='i')
    # Adjust rows of A so largest element is in the pivot of each row
    l = 0
    swaps = 0
    for i in range(rows):
        max_l = abs(A[i][l])
        swap = i
        for j in range(i + 1, rows):
            if abs(A[j][l]) > max_l:
                max_l = abs(A[j][l])
                swap = j
        if i != swap:
            P.swap(i, swap)
            swaps += 1
        l += 1
    # Swap rows to get larger pivots
    A = P * A
    # Keep track of the current pivot we are at to determine side of diagonal
    l = 0
    for i in range(rows):
        for j in range(cols):
            # Upper diagonal of U, including diagonal
            if j >= l:
                U[i][j] = A[i][j] - __ludot(i, U, L, i, j)
            # Lower diagonal of L, not including the diagonal
            else:
                L[i][j] = 1 / U[j][j] * (A[i][j] - __ludot(j, U, L, i, j))
        l += 1
    if info and info == 's':
        return [L, U, P, swaps]
    return [L, U, P]
 def test_det(self):
     # Test property that determinant of identity matrix is 1
     A = Matrix(10, 10, mtype="i")
     self.assertAlmostEqual(lalg.det(A), 1, delta=0.001)
     # Test property row exchanges case that determinant is (-1)^swaps
     A.swap(1, 2)
     self.assertAlmostEqual(lalg.det(A), -1, delta=0.001)
     A.swap(3, 4)
     self.assertAlmostEqual(lalg.det(A), 1, delta=0.001)
     # Multiplying one row of a matrix by t results in the determinant being multiplied by t
     # | t*a t*b | = t * |a b|
     # | c   d   |       |c d|
     A = Matrix([4 * 2, 4 * 8], [3, 9])
     B = Matrix([2, 8], [3, 9])
     self.assertAlmostEqual(lalg.det(A), 4 * lalg.det(B), delta=0.001)
     # Adding to one row of a matrix results in a linear combination of the matrix and addition
     # | a+da b+db | = |a b| + |da db|
     # | c    d    |   |c d|   |c  d |
     A = Matrix([8 + 9, -2 + 7], [-5, 12])
     B = Matrix([8, -2], [-5, 12])
     C = Matrix([9, 7], [-5, 12])
     self.assertAlmostEqual(lalg.det(A), lalg.det(B) + lalg.det(C), delta=0.001)
     # If A has a row of all zeros the determinant should be 0
     A = Matrix(12, 12)
     for i in range(12):
         for j in range(12):
             A[i][j] = random.randint(-1000, 1000)
     A.set_row(3, [0] * 12)
     self.assertAlmostEqual(lalg.det(A), 0)
     # If two rows are equal the determinant is 0
     A = Matrix(12, 12)
     for i in range(12):
         for j in range(12):
             A[i][j] = random.randint(-1000, 1000)
     A.set_row(random.randint(0, 5), [i for i in range(12)])
     A.set_row(random.randint(6, 11), [i for i in range(12)])
     self.assertAlmostEqual(lalg.det(A), 0)
 def test_swap(self):
     m = Matrix([1, 2, 3], [4, 5, 6])
     m.swap(0, 1)
     self.assertEqual(m, Matrix([4, 5, 6], [1, 2, 3]))
     m = Matrix([1, 2], [3, 4], [5, 6], [7, 8], [9, 10])
     m.swap(0, 4)
     m.swap(1, 3)
     # Middle row shouldn't move
     m.swap(2, 2)
     self.assertEqual(m, Matrix([9, 10], [7, 8], [5, 6], [3, 4], [1, 2]))