Exemplo n.º 1
0
def gram_schmidt(
    a: MatrixType, n: Optional[int] = None
) -> Tuple[MatrixType, List[int]]:
    cnt_vectors = min(a.ncols, n) if n else a.ncols
    q = a.copy()
    perm = list(range(cnt_vectors))

    for j in range(0, cnt_vectors):
        pivot_col_idx, pivot_norm = max(
            ((c, norm(q[:, c])) for c in range(j, cnt_vectors)), key=lambda x: x[1]
        )

        # Swap columns
        if j != pivot_col_idx:
            temp = q[:, j].copy()
            q[:, j] = q[:, pivot_col_idx]
            q[:, pivot_col_idx] = temp
            perm[pivot_col_idx], perm[j] = perm[j], perm[pivot_col_idx]

        # Normalize
        q[:, j] /= pivot_norm
        u = q[:, j]

        # Remove U component everywhere
        q[:, j + 1 :] -= u @ (u.T @ q[:, j + 1 :])

    return q, perm
Exemplo n.º 2
0
def lu_decompose(a: MatrixType) -> LuDecomposition:
    validate.is_true("matrix", "must be square", a.is_square())
    n = a.nrows

    # Init
    lu = a.copy()
    perm: List[int] = list(range(a.nrows))
    cnt_row_exchanges = 0

    for i in range(n):
        # All work will be done on sub-matrix lu[i:, i:]
        pivot_row_idx, pivot_value = max(
            enumerate(lu[i:, i], start=i), key=lambda x: abs(x[1])
        )

        if abs(pivot_value) < epsilon:
            raise ValueError(
                "Matrix has not independent rows (or columns) "
                "and hence cannot be LU decomposed"
            )

        if pivot_row_idx != i:
            # Execute row exchange on perm
            temp_idx = perm[pivot_row_idx]
            perm[pivot_row_idx] = perm[i]
            perm[i] = temp_idx

            # Execute Row exchange on LU
            temp_row = lu[pivot_row_idx].copy()
            lu[pivot_row_idx] = lu[i]
            lu[i] = temp_row

            cnt_row_exchanges += 1

        # Perform elimination
        factors_column = lu[i + 1 :, i] / pivot_value
        pivot_row = lu[i, i + 1 :]

        lu[i + 1 :, i] = factors_column
        lu[i + 1 :, i + 1 :] -= factors_column * pivot_row

    return LuDecomposition(lu, perm, cnt_row_exchanges)
Exemplo n.º 3
0
def echelon(a: MatrixType) -> EchelonForm:
    m, n = a.shape

    # Init
    lu = a.copy()
    perm: List[int] = list(range(m))
    cnt_row_exchanges = 0

    j = 0
    i = 0
    pivot_cols = []
    while i < m and j < n:
        # All work will be done on sub-matrix lu[i:, j:]
        pivot_row_idx, pivot_value = max(
            enumerate(lu[i:, j], start=i), key=lambda x: abs(x[1])
        )

        if abs(pivot_value) < epsilon:
            j += 1
            continue

        if pivot_row_idx != i:
            # Execute row exchange on perm
            temp_idx = perm[pivot_row_idx]
            perm[pivot_row_idx] = perm[i]
            perm[i] = temp_idx

            # Execute Row exchange on LU
            temp_row = lu[pivot_row_idx].copy()
            lu[pivot_row_idx] = lu[i]
            lu[i] = temp_row

            cnt_row_exchanges += 1

        # Perform elimination
        pivot_cols.append(j)
        factors_column = lu[i + 1 :, j] / pivot_value
        pivot_row = lu[i, j + 1 :]

        lu[i + 1 :, j] = factors_column
        lu[i + 1 :, j + 1 :] -= factors_column * pivot_row
        i += 1
        j += 1

    return EchelonForm(a, lu, perm, pivot_cols)
Exemplo n.º 4
0
def shaped(data: Collection[N], shape: Shape):
    return MatrixType.from_flat_collection(data, shape)
Exemplo n.º 5
0
def zeros(nrows: int = None, ncols: int = None, shape: Shape = None):
    return MatrixType.zeros(_shape(nrows, ncols, shape))
Exemplo n.º 6
0
def eye(nrows: int = None, ncols: int = None, shape: Shape = None):
    return MatrixType.eye(_shape(nrows, ncols, shape))
Exemplo n.º 7
0
def singleton(value: Number) -> MatrixType:
    return MatrixType.singleton(value)
Exemplo n.º 8
0
def det(m: MatrixType) -> float:
    if not m.is_square():
        raise ValueError("Determinants only make sense for square matrices")
    lu = elimination.lu_decompose(m)
    return lu.determinant()