예제 #1
0
def calcp(prev_r, curr_r):
    prev_c = sympy.shape(prev_r)[1]
    curr_c = sympy.shape(curr_r)[1]

    if prev_c != curr_c:
        return -1

    maxdiff = -1 * sys.maxsize
    for i in range(curr_c):
        diff = abs(curr_r[i] - prev_r[i])
        if diff > maxdiff:
            maxdiff = diff

    return maxdiff
예제 #2
0
def gseid_iter(m, b, out, k):
    a = None    # coeficiente que acompaña a xi
    acc = None  # acumulador reasignado en cada iteracion

    r, c = sympy.shape(m)
    for i in range(r):
        acc = b[i]
        for j in range(c):
            if i == j:
                a = m[i, j]
                continue
# aca se diferencian gseid_iter y jacobi_iter
            if j > i:
                acc -= out[k-1, j] * m[i, j]
            else:
                acc -= out[k, j] * m[i, j]
        acc /= a
        acc = acc.evalf()

        newrow = out.row(k)
        newrow[i] = acc
        out.row_del(k)
        out = out.row_insert(k, newrow)

    return out
 def AntiSymmetricMatrix(value):
     """
     That means all the values in the diagonal are zero
     And M[i, j] = -M[j, i] 
     """
     if not IS.SquareMatrix(value):
         return False
     if IS.NumpyArray(value):
         if np.any(np.diag(value) != 0):
             return False
         matrix = np.copy(value)
         return np.all(np.abs(matrix + np.transpose(matrix)) < 1e-13)
     if IS.SympyBasic(value):
         if IS.SympyMatrix(value):
             pass
         elif IS.SympyArray(value):
             value = sp.Matrix(value)
         else:
             return False
         n, = sp.shape(value)[0]
         return (value + value.T) == sp.zeros(n, n)
     if IS.Tuple(value) or IS.List(value):
         value = np.array(value)
         return IS.AntiSymmetricMatrix(value)
     return False
예제 #4
0
def report_plist(plist):
    c = sympy.shape(plist)[1]

    s = "\nPrecisiones obtenidas en cada iteracion:\n"
    for i in range(c):
        s += ("Iter %d" % i).center(20)
        s += str(plist[i]).center(25) + "\n"
    print(s)
예제 #5
0
def report_m(m, hdr=""):
    r, c = sympy.shape(m)

    s = hdr
    for i in range(r):
        for j in range(c):
            s += str(m[i, j]).center(25)
        s += "\n"
    print(s)
예제 #6
0
def inf_norm(m):
    maxval = -1 * sys.maxsize
    r, c = sympy.shape(m)
    for i in range(r):
        acc = 0
        for j in range(c):
            acc += abs(m[i, j])
        if maxval < acc:
            maxval = acc
    return maxval.evalf()
예제 #7
0
def cofactor_expansion(M):
    n = sym.shape(M)[0]
    if n == 1:
        return M[0,0]
    total = 0
    for i in range(n):
        minor = M.copy()
        minor.row_del(0)
        minor.col_del(i)
        total += (-1)**i * M[0,i] * cofactor_expansion(minor)
    return total
 def SquareMatrix(value):
     if not IS.Matrix(value):
         return False
     if IS.NumpyArray(value):
         shape = value.shape
         if shape[0] == shape[1]:
             return True
         return False
     if IS.SympyBasic(value):
         if IS.SympyMatrix(value):
             shape = sp.shape(value)
         elif IS.SympyArray(value):
             shape = sp.shape(value)
         else:
             return False
         if shape[0] == shape[1]:
             return True
         return False
     if IS.Tuple(value) or IS.List(value):
         value = np.array(value)
         return IS.SquareMatrix(value)
     return False
예제 #9
0
def m_err(x, y, f_expr, w_expr, prod, calc_prod, B, X):
    n = sympy.shape(B)[0]
    acc = 0
    for i in range(n):
        acc += X[i] * B[i]

    prod = prod.subs({"w": w_expr})
    p = prod.subs({"f": f_expr, "g": f_expr}).evalf()
    f_sq = calc_prod(x, y, p)

    err = (f_sq - acc)**(1 / 2)

    return err
예제 #10
0
def converg(m):
    acc = None  # suma de valores absolutos en la columna q no estan en la diagonal
    diag = None # valor absoluto del elemento de la columna que está en la diagonal

    r, c = sympy.shape(m)
    for i in range(r):
        acc = 0
        for j in range(c):
            if i == j:
                diag = abs(m[j, i])
            else:
                acc += abs(m[j, i])
        if diag < acc:
            return False

    return True
예제 #11
0
def report_iters(out, algoritmo):
    r, c = sympy.shape(out)

    s = "\nVectores X obtenidos por metodo de %s:\n" % ("JACOBI" if algoritmo
                                                        else "GAUSS-SEIDEL")
    s += ("vector X".center(20))
    for i in range(c):
        s += ("x%d" % i).center(25)
    s += "\n"

    for i in range(r):
        s += ("x%d" % i).center(20)
        for j in range(c):
            s += str(out[i, j]).center(25)
        s += "\n"
    print(s)
예제 #12
0
def sel(m, b, iter_fc, n=sys.maxsize, p=0):
    out = sympy.Matrix([])
    plist = sympy.Matrix([])

    c = sympy.shape(m)[1]
    out = out.row_insert(0, sympy.Matrix([[0 for i in range(c)]]))
    plist = plist.col_insert(0, sympy.Matrix([[sys.maxsize]]))

    k = 1
    while k < n + 1 and plist[k - 1] > p:
        out = out.row_insert(k, sympy.Matrix([[0 for i in range(c)]]))
        out = iter_fc(m, b, out, k)

        newp = calcp(out.row(k - 1), out.row(k))
        plist = plist.col_insert(k, sympy.Matrix([[newp]]))
        if plist[k] < 0:
            raise ValueError("Precision negativa, revisar input")
        k += 1
    return out, plist
예제 #13
0
if __name__ == "__main__":
    inputlist = parseargs(sys.argv[1:], NFIELDS)
    algoritmo = 1 if "j" in inputlist[0] else 0
    n = symparse(inputlist[1])
    n = n if n > 0 else sys.maxsize
    p = symparse(inputlist[2])
    p = p if p > 0 else 0
    norm_in = symparse(inputlist[3])

    b = symparse_seqline(inputlist[4])
    b = sympy.Matrix([b]).T

    m = sympy.Matrix([[]])
    for line in inputlist[5:]:
        newrow = symparse_seqline(line)
        idx = sympy.shape(m)[0]
        m = m.row_insert(idx, sympy.Matrix([newrow]))

    iter_fc = jacobi_iter if algoritmo else gseid_iter
    norm = inf_norm if norm_in != 1 else uno_norm

    minv = minvrs(m)
    x_direc = direc_sel(m, b)
    cond = cond_sel(m, minv, norm)

    nm = norm(m)
    nminv = norm(minv)
    conv = converg(m)

    out, plist = sel(m, b, iter_fc, n, p)
예제 #14
0
def direc_sel(m, b):
    ret = minvrs(m) * b
    r = sympy.shape(b)[0]
    for i in range(r):
        ret[i] = ret[i].evalf()
    return ret
예제 #15
0
    def eliminate_state_from_transition_matrix(
            self,
            labels: list = None,
            use_parameters: bool = False) -> Tuple[sp.Matrix, sp.Matrix]:
        """Returns a matrix, A, and vector, B, corresponding to a linear ODE system describing the state probabilities.

        Because the state occupancy probabilities must add up to zero, the
        transition matrix is always singular. We can use this fact to remove
        one state variable from the system of equations. The labels parameter
        allows you to choose which variable is eliminated and also the ordering
        of the states.

        :param labels: A list of labels. The order of which determines the ordering of outputted system.
        :param use_parameters: If true substitute in parameters of the transition rates
        :return: A pair of symbolic matrices, A & B, defining a system of ODEs of the format dX/dt = AX + B.
        """

        if labels is None:
            labels = list(self.graph.nodes)[:-1]

        for label in labels:
            if label not in self.graph.nodes():
                raise Exception(
                    f"Provided label, {label} is not present in the graph")

        _, matrix = self.get_transition_matrix()

        eliminated_states = [
            state for state in self.graph.nodes() if state not in labels
        ]
        assert len(eliminated_states) == 1
        eliminated_state = eliminated_states[0]

        matrix = matrix.T
        shape = sp.shape(matrix)
        assert shape[0] == shape[1]

        # List describing the mapping from self.graph.nodes to labels.
        # permutation[i] = j corresponds to a mapping which takes
        # graph.nodes[i] to graph.nodes[j]. Map the row to be eliminated to the
        # end.

        permutation = [
            list(self.graph.nodes()).index(n)
            for n in labels + [eliminated_state]
        ]

        assert len(np.unique(permutation)) == shape[0]
        matrix = matrix[permutation, permutation]

        M = sp.eye(shape[0])
        replacement_row = np.full(shape[0], -1)

        M[-1, :] = replacement_row[None, :]

        A_matrix = matrix @ M

        B_vec = matrix @ sp.Matrix([[0] * (shape[0] - 1) + [1]]).T

        if use_parameters:
            if len(self.rate_expressions) == 0:
                raise Exception()
            else:
                A_matrix = A_matrix.subs(self.rate_expressions)
                B_vec = B_vec.subs(self.rate_expressions)

        return A_matrix[0:-1, 0:-1], B_vec[0:-1, :]