Ejemplo n.º 1
0
    def _forward(self):
        """
        Solves the lower triangular system Ly = b
        for y by forward substitution.
        """
        if self.b.ndim > 1:
            num_iters = self.b.shape[1]
            N = self.b.shape[0]
        else:
            num_iters = 1
            N = self.b.shape[0]

        self.y = np.zeros([N, num_iters])

        for k in range(num_iters):
            for i in range(N):
                acc = KahanSum()
                for j in range(i):
                    acc.add(self.L[i, j]*self.y[j, k])
                if self.b.ndim > 1:
                    self.y[i, k] = \
                        (self.b[i, k] - acc.cur_sum()) / (self.L[i, i])
                else:
                    self.y[i, k] = \
                        (self.b[i] - acc.cur_sum()) / (self.L[i, i])
Ejemplo n.º 2
0
def trace(A):
    """
    Computes the sum of the diagonal elements
    of a square matrix A.
    """
    # grab the diagonal elements
    diag = diagonal(A)

    # instantiate kahan summer
    summer = KahanSum()

    # compute sum of list
    for d in diag:
        summer.add(d)

    return summer.cur_sum()
Ejemplo n.º 3
0
def inverse(A):
    """
    Computes the inverse of a square matrix A.

    Concretely, solves the linear system Ax = I
    where x is a square matrix rather than a vector.

    The system is solved using LU decomposition with
    partial pivoting.

    Params
    ------
    - A: a numpy array of shape (N, N).

    Returns
    -------
    - a numpy array of shape (N, N).
    """
    N = A.shape[0]

    P, L, U = LU(A, pivoting='partial').decompose()

    # transpose P since LU returns A = PLU
    P = P.T

    # solve Ly = P for y
    y = np.zeros_like(L)
    for i in range(N):
        for j in range(N):
            summer = KahanSum()
            for k in range(i):
                summer.add(L[i, k] * y[k, j])
            sum = summer.cur_sum()
            y[i, j] = (P[i, j] - sum) / (L[i, i])

    # solve Ux = y for x
    x = np.zeros_like(U)
    for i in range(N - 1, -1, -1):
        for j in range(N):
            summer = KahanSum()
            for k in range(N - 1, i, -1):
                summer.add(U[i, k] * x[k, j])
            sum = summer.cur_sum()
            x[i, j] = (y[i, j] - sum) / (U[i, i])

    return x
Ejemplo n.º 4
0
def norm(x, p):
    """
    Returns the p norm of a vector.
    """
    v = np.array(x).flatten()

    error_msg = "x must be 1D"
    assert v.ndim == 1, error_msg
    error_msg = "p must be >= 1"
    assert p >= 1, error_msg

    N = v.shape[0]

    summer = KahanSum()
    for i in range(N):
        summer.add(np.power(np.abs(v[i]), p))

    return np.power(summer.cur_sum(), 1. / p)
Ejemplo n.º 5
0
    def _forward(self):
        """
        Solves the lower triangular system Ly = b
        for y by forward substitution.

        If partial pivoting is used, solves the system
        Ly = Pb and if full pivoting is used, solves
        the system Ly = PbQ.
        """

        if self.b.ndim > 1:
            num_iters = self.b.shape[1]
            N = self.b.shape[0]
        else:
            num_iters = 1
            N = self.b.shape[0]

        self.y = np.zeros([N, num_iters])

        if self.pivoting is None:
            right_hand = self.b
        elif self.pivoting == "partial":
            right_hand = np.dot(self.P, self.b)
        else:
            right_hand = np.dot(self.P, self.b)
            right_hand = np.dot(right_hand[:, np.newaxis].T, self.Q)
            right_hand = right_hand.squeeze().T

        for k in range(num_iters):
            for i in range(N):
                acc = KahanSum()
                for j in range(i):
                    acc.add(self.L[i, j]*self.y[j, k])
                if self.b.ndim > 1:
                    self.y[i, k] = right_hand[i, k] - acc.cur_sum()
                else:
                    self.y[i, k] = right_hand[i] - acc.cur_sum()
Ejemplo n.º 6
0
    def decompose(self, ret=True):

        N = len(self.R)

        self.L = np.zeros_like(self.R)

        if self.crout:
            for i in range(N):
                for j in range(i+1):
                    summer = KahanSum()
                    for k in range(j):
                        summer.add(self.L[i, k] * self.L[j, k])
                    sum = summer.cur_sum()

                    if (i == j):
                        self.L[j, j] = np.sqrt(self.R[j, j] - sum)
                    else:
                        self.L[i, j] = (self.R[i, j] - sum) / (self.L[j, j])
            if ret:
                return self.L
        else:
            for i in range(N):
                self.pivot = self.R[i, i]

                # eliminate subsequent rows
                for j in range(i+1, N):
                    for k in range(j, N):
                        self.R[j, k] -= self.R[i, k] * \
                                        (self.R[i, j] / self.pivot)

                # scale the current row
                for k in range(i, N):
                    self.R[i, k] /= np.sqrt(self.pivot)

            if ret:
                return self.R.T
Ejemplo n.º 7
0
    def _backward(self):
        """
        Solve the upper triangular system L^Tx = y
        for x by back substitution.
        """
        if self.b.ndim > 1:
            num_iters = self.b.shape[1]
            N = self.b.shape[0]
        else:
            num_iters = 1
            N = self.b.shape[0]

        self.x = np.zeros([N, num_iters])

        for k in range(num_iters):
            for i in range(N-1, -1, -1):
                acc = KahanSum()
                for j in range(N-1, i, -1):
                    acc.add(self.L.T[i, j]*self.x[j, k])
                self.x[i, k] = \
                    (self.y[i, k] - acc.cur_sum()) / (self.L.T[i, i])

        if self.b.ndim == 1:
            self.x = self.x.squeeze()