Example #1
0
def fourseven(iter_stack):
    # load matrices
    Ai = iter_stack.A
    Bi = iter_stack.B
    P1i_roc = iter_stack.P1_roc
    P1i_rpinv = iter_stack.P1_rpinv
    
    K2 = roc_hint("B", iter_stack.i, Bi) if mode=="manual" else al.right_ortho_complement(Bi)

    K1 = al.regular_completion(K2)

    K = st.concat_cols(K1, K2)

    assert al.is_regular_matrix(K), "K is not a regular matrix."

    Bi_tilde = al.custom_simplify(Bi*K1) # unit matrix

    if myStack.calc_G:
        Bi_tilde_lpinv = al.left_pseudo_inverse(Bi_tilde)
    else:
        Bi_tilde_lpinv = None

    P1i_tilde_roc = al.custom_simplify( P1i_roc*K1 )

    Zi = al.custom_simplify( P1i_roc*K2 )

    Zi_lpinv = al.Zi_left_pinv_with_restrictions(P1i_rpinv, P1i_tilde_roc, Zi)

    assert al.is_unit_matrix( Zi_lpinv*Zi ), "Zi_lpinv seems to be wrong."

    # store
    iter_stack.store_special_case_matrices( Zi, Zi_lpinv, Bi_tilde, Bi_tilde_lpinv, P1i_tilde_roc )

    return Bi_tilde
Example #2
0
def Zi_left_pinv_with_restrictions(P1i_rpinv, P1i_tilde_roc, Zi):
    """ Given a matrix Zi, this function calculates a matrix such that:
            Zi_left_pinv * Zi            = I
            Zi_left_pinv * P1i_tilde_roc = 0
            Zi_left_pinv * P1i_rpinv     = 0
    """
    assert check_row_compatibility(P1i_rpinv, P1i_tilde_roc, Zi),\
        "Matrices do not match in row dimension."

    C = st.concat_cols(P1i_rpinv, P1i_tilde_roc, Zi)

    assert is_regular_matrix(C), "C is not a regular matrix"
    C_det = C.berkowitz_det()
    C_inv = C.adjugate()/C_det
    C_inv = custom_simplify(C_inv)

    m, n = Zi.shape
    Zi_left_pinv = sp.Matrix([])
    for i in xrange(m-n,m):
        Zi_left_pinv = st.concat_rows(Zi_left_pinv,C_inv.row(i))

    o, p = Zi_left_pinv.shape
    assert o==n and p==m, "There must have been a problem with the\
                            computation of Zi_left_pinv"

    assert is_unit_matrix(Zi_left_pinv*Zi), "Zi_left_pinv is wrong"
    assert is_zero_matrix(Zi_left_pinv*P1i_tilde_roc), "Zi_left_pinv is wrong"
    assert is_zero_matrix(Zi_left_pinv*P1i_rpinv), "Zi_left_pinv is wrong"

    return Zi_left_pinv
Example #3
0
def Zi_left_pinv_with_restrictions(P1i_rpinv, P1i_tilde_roc, Zi):
    """ Given a matrix Zi, this function calculates a matrix such that:
            Zi_left_pinv * Zi            = I
            Zi_left_pinv * P1i_tilde_roc = 0
            Zi_left_pinv * P1i_rpinv     = 0
    """
    assert check_row_compatibility(P1i_rpinv, P1i_tilde_roc, Zi),\
        "Matrices do not match in row dimension."

    C = st.concat_cols(P1i_rpinv, P1i_tilde_roc, Zi)

    assert is_regular_matrix(C), "C is not a regular matrix"
    C_det = C.berkowitz_det()
    C_inv = C.adjugate() / C_det
    C_inv = custom_simplify(C_inv)

    m, n = Zi.shape
    Zi_left_pinv = sp.Matrix([])
    for i in range(m - n, m):
        Zi_left_pinv = st.concat_rows(Zi_left_pinv, C_inv.row(i))

    o, p = Zi_left_pinv.shape
    assert o == n and p == m, "There must have been a problem with the\
                            computation of Zi_left_pinv"

    assert is_unit_matrix(Zi_left_pinv * Zi), "Zi_left_pinv is wrong"
    assert is_zero_matrix(Zi_left_pinv *
                          P1i_tilde_roc), "Zi_left_pinv is wrong"
    assert is_zero_matrix(Zi_left_pinv * P1i_rpinv), "Zi_left_pinv is wrong"

    return Zi_left_pinv
Example #4
0
def is_linearly_independent(matrix, column_vector):
    m, n = matrix.shape

    rank1 = st.rnd_number_rank(matrix)
    tmp = st.concat_cols(matrix, column_vector)
    rank2 = st.rnd_number_rank(tmp)
    
    assert rank2 >= rank1
        
    return rank2 > rank1
Example #5
0
def remove_zero_columns(matrix):
    """ this function removes zero columns of a matrix
    """
    m, n = matrix.shape
    M = sp.Matrix([])

    for i in xrange(n):
        if not is_zero_matrix(matrix.col(i)):
            M = st.concat_cols(M, matrix.col(i))
    return M
Example #6
0
def is_linearly_independent(matrix, column_vector):
    m, n = matrix.shape

    rank1 = st.rnd_number_rank(matrix)
    tmp = st.concat_cols(matrix, column_vector)
    rank2 = st.rnd_number_rank(tmp)

    assert rank2 >= rank1

    return rank2 > rank1
Example #7
0
def remove_zero_columns(matrix):
    """ this function removes zero columns of a matrix
    """
    m, n = matrix.shape
    M = sp.Matrix([])

    for i in range(n):
        if not is_zero_matrix(matrix.col(i)):
            M = st.concat_cols(M, matrix.col(i))
    return M
Example #8
0
    def right_shift_all_in_matrix(self, matrix):
        # does nct-package provide this already?
        m,n = matrix.shape
        matrix_shifted = sp.Matrix([])
        t_dep_symbols = [symb for symb in st.atoms(matrix, sp.Symbol) if not symb == s]
        for i in xrange(n):
            col = matrix.col(i)
            col_shifted = sp.Matrix([nct.right_shift_all(expr,s,t, t_dep_symbols) for expr in col])
            matrix_shifted = st.concat_cols(matrix_shifted, col_shifted)

        return matrix_shifted
Example #9
0
    def right_shift_all_in_matrix(self, matrix):
        # does nct-package provide this already?
        m, n = matrix.shape
        matrix_shifted = sp.Matrix([])
        t_dep_symbols = [
            symb for symb in st.atoms(matrix, sp.Symbol) if not symb == s
        ]
        for i in range(n):
            col = matrix.col(i)
            col_shifted = sp.Matrix([
                nct.right_shift_all(expr, s, t, t_dep_symbols) for expr in col
            ])
            matrix_shifted = st.concat_cols(matrix_shifted, col_shifted)

        return matrix_shifted
Example #10
0
    def calculate_Gi_matrix(self, i):
        # 1) choose correct matrices for Gi[d/dt]
        # 2) change symbols to noncommutative symbols, calculate Gi[d/dt]
        # 3) G[d/dt] = G0[d/dt] * G1[d/dt] * ... * Gi[d/dt]
        # 4) special case procedure
        iteration = self._myStack.get_iteration(i)

        if not iteration.is_special_case:
            # get matrices
            P1_rpinv = iteration.P1_rpinv
            P1_roc = iteration.P1_roc
            B_lpinv = iteration.B_lpinv
            A = iteration.A

            P1_rpinv_nc, P1_roc_nc, B_lpinv_nc, A_nc = self.convert_to_nc_matrices(
                P1_rpinv, P1_roc, B_lpinv, A)

            Gi = P1_rpinv_nc - P1_roc_nc * (B_lpinv_nc * s_ +
                                            B_lpinv_nc * A_nc)

        else:
            # get matrices
            P1_rpinv = iteration.P1_rpinv
            P1_tilde_roc = iteration.P1_tilde_roc
            B_tilde_lpinv = iteration.B_tilde_lpinv
            A = iteration.A
            Z = iteration.Z

            # convert commutative symbols to non commutative
            P1_rpinv_nc = self.make_symbols_non_commutative(P1_rpinv)
            P1_tilde_roc_nc = self.make_symbols_non_commutative(P1_tilde_roc)
            B_tilde_lpinv_nc = self.make_symbols_non_commutative(B_tilde_lpinv)
            A_nc = self.make_symbols_non_commutative(A)
            Z_nc = self.make_symbols_non_commutative(Z)

            Gi = P1_rpinv_nc - P1_tilde_roc_nc * (B_tilde_lpinv_nc * s_ +
                                                  B_tilde_lpinv_nc * A_nc)

            Gi = st.concat_cols(Gi, Z_nc)

        if False:
            # show_Gi_matrices:
            pc.print_matrix("G", i, "", Gi)

        # store
        iteration.Gi = Gi

        return Gi
Example #11
0
    def calculate_Gi_matrix(self, i):
        # 1) choose correct matrices for Gi[d/dt]
        # 2) change symbols to noncommutative symbols, calculate Gi[d/dt]
        # 3) G[d/dt] = G0[d/dt] * G1[d/dt] * ... * Gi[d/dt]
        # 4) special case procedure
        iteration = self._myStack.get_iteration(i)

        if not iteration.is_special_case:
            # get matrices
            P1_rpinv = iteration.P1_rpinv
            P1_roc = iteration.P1_roc
            B_lpinv = iteration.B_lpinv
            A = iteration.A
            
            P1_rpinv_nc, P1_roc_nc, B_lpinv_nc, A_nc = self.convert_to_nc_matrices(P1_rpinv, P1_roc, B_lpinv, A)

            Gi = P1_rpinv_nc - P1_roc_nc*( B_lpinv_nc*s_ + B_lpinv_nc*A_nc )

        else:
            # get matrices
            P1_rpinv = iteration.P1_rpinv
            P1_tilde_roc = iteration.P1_tilde_roc
            B_tilde_lpinv = iteration.B_tilde_lpinv
            A = iteration.A
            Z = iteration.Z

            # convert commutative symbols to non commutative
            P1_rpinv_nc = self.make_symbols_non_commutative(P1_rpinv)
            P1_tilde_roc_nc = self.make_symbols_non_commutative(P1_tilde_roc)
            B_tilde_lpinv_nc = self.make_symbols_non_commutative(B_tilde_lpinv)
            A_nc = self.make_symbols_non_commutative(A)
            Z_nc = self.make_symbols_non_commutative(Z)

            Gi = P1_rpinv_nc - P1_tilde_roc_nc*( B_tilde_lpinv_nc*s_ + B_tilde_lpinv_nc*A_nc )

            Gi = st.concat_cols(Gi, Z_nc)

        if False:
            # show_Gi_matrices:
            pc.print_matrix("G", i, "", Gi)

        # store
        iteration.Gi = Gi

        return Gi
Example #12
0
def fourseven(iter_stack):
    # load matrices
    Ai = iter_stack.A
    Bi = iter_stack.B
    P1i_roc = iter_stack.P1_roc
    P1i_rpinv = iter_stack.P1_rpinv

    K2 = roc_hint("B", iter_stack.i,
                  Bi) if mode == "manual" else al.right_ortho_complement(Bi)

    K1 = al.regular_completion(K2)

    K = st.concat_cols(K1, K2)

    assert al.is_regular_matrix(K), "K is not a regular matrix."

    Bi_tilde = al.custom_simplify(Bi * K1)  # unit matrix

    if myStack.calc_G:
        Bi_tilde_lpinv = al.left_pseudo_inverse(Bi_tilde)
    else:
        Bi_tilde_lpinv = None

    P1i_tilde_roc = al.custom_simplify(P1i_roc * K1)

    Zi = al.custom_simplify(P1i_roc * K2)

    Zi_lpinv = al.Zi_left_pinv_with_restrictions(P1i_rpinv, P1i_tilde_roc, Zi)

    assert al.is_unit_matrix(Zi_lpinv * Zi), "Zi_lpinv seems to be wrong."

    # store
    iter_stack.store_special_case_matrices(Zi, Zi_lpinv, Bi_tilde,
                                           Bi_tilde_lpinv, P1i_tilde_roc)

    return Bi_tilde
Example #13
0
def reshape_matrix_columns(P):
    m0, n0 = P.shape

    # pick m0 of the simplest lin. independent columns of P:
    P_new = remove_zero_columns(P)
    m1, n1 = P_new.shape

    list_of_cols = matrix_to_vectorlist(P_new)

    # sort by "complexity"
    if pinv_optimization=="free_symbols":
        cols_sorted_by_atoms = sorted( list_of_cols, key=lambda x: x.free_symbols, reverse=False)
    elif pinv_optimization=="count_ops":
        cols_sorted_by_atoms = sorted( list_of_cols, key=lambda x: nr_of_ops(x), reverse=False)
    elif pinv_optimization=="none":
        cols_sorted_by_atoms = list_of_cols

    # sort by number of zero entries
    colvecs_sorted = sorted( cols_sorted_by_atoms, key=lambda x: count_zero_entries(x), reverse=True)

    # pick m suitable column vectors and add to new matrix A: ----------
    A = colvecs_sorted[0]
    for j in xrange(len(colvecs_sorted)-1):
        column = colvecs_sorted[j+1]
        if is_linearly_independent(A,column):
            A = st.concat_cols(A,column)

        if st.rnd_number_rank(A)==m1:
            break

    assert A.is_square
            
    # calculate transformation matrix R: -------------------------------
    #R_tilde = sp.Matrix([])
    used_cols = []
    R = sp.Matrix([])
    for k in xrange(m1):
        new_column_index = k
        old_column_index = get_column_index_of_matrix(P,A.col(k))
        used_cols.append(old_column_index)
        tmp = sp.zeros(n0,1)
        tmp[old_column_index] = 1

        #R_tilde = st.concat_cols(R_tilde,tmp)
        R = st.concat_cols(R,tmp)
    #R=R_tilde

    # remainder columns of R matrix
    #m2,n2 = R_tilde.shape
    m2,n2 = R.shape
    for l in xrange(n0):
        if l not in used_cols:
            R_col = sp.zeros(n0,1)
            R_col[l] = 1
            R = st.concat_cols(R,R_col)

    m3, n3 = A.shape
    r2 = st.rnd_number_rank(A)
    assert m3==r2, "A problem occured in reshaping the matrix."

    # calculate B matrix: ----------------------------------------------
    B = sp.Matrix([])
    tmp = P*R
    for i in xrange(n0-m0):
        B = st.concat_cols(B,tmp.col(m0+i))

    
    assert is_zero_matrix( (P*R) - st.concat_cols(A,B)), "A problem occured in reshaping the matrix."

    return A, B, R
Example #14
0
    def gen_leqs_for_acc_llmd(self, parameter_values=None):
        """
        Create a callable function which returns A, bnum of the linear eqn-system
                A*ww = bnum,
        where ww := (ttheta_dd, llmnd).


        :return: None, set self.leqs_acc_lmd_func
        """

        if self.leqs_acc_lmd_func is not None and self.acc_of_lmd_func is not None:
            return

        if parameter_values is None:
            parameter_values = []

        ntt = self.ntt
        nll = self.nll

        self.generate_constraints_funcs()

        # also respect those values, which have been passed to the constructor
        parameter_values = list(self.parameter_values) + list(parameter_values)

        # we use mod.eqns here because we do not want ydot-vars inside
        eqns = st.concat_rows(self.mod.eqns.subs(parameter_values), self.constraints_dd)

        ww = st.concat_rows(self.mod.ttdd, self.mod.llmd)

        A = eqns.jacobian(ww)
        b = -eqns.subz0(ww)  # rhs of the leqs

        Ab = st.concat_cols(A, b)

        fvars = st.concat_rows(self.mod.tt, self.mod.ttd, self.mod.tau)

        actual_symbs = Ab.atoms(sp.Symbol)
        expected_symbs = set(fvars)
        unexpected_symbs = actual_symbs.difference(expected_symbs)
        if unexpected_symbs:
            msg = "Equations can only converted to numerical func if all parameters are passed for substitution. " \
                  "Unexpected symbols: {}".format(unexpected_symbs)
            raise ValueError(msg)

        A_fnc = st.expr_to_func(fvars, A, keep_shape=True)
        b_fnc = st.expr_to_func(fvars, b)

        nargs = len(fvars)

        # noinspection PyShadowingNames
        def leqs_acc_lmd_func(*args):
            """
            Calculate the matrices of the linear equation system for ttheta and llmd.
            Assume args = (ttheta, theta_d, ttau)
            :param args:
            :return:
            """
            assert len(args) == nargs
            Anum = A_fnc(*args)
            bnum = b_fnc(*args)

            # theese arrays can now be passed to a linear equation solver
            return Anum, bnum

        self.leqs_acc_lmd_func = leqs_acc_lmd_func

        def acc_of_lmd_func(*args):
            """
            Calculate ttheta in dependency of args= (yy, ttau) = ((ttheta, ttheta_d, llmd), ttau)

            :param args:
            :return:
            """

            ttheta = args[:ntt]
            ttheta_d = args[ntt:2 * ntt]
            llmd = args[2 * ntt:2 * ntt + nll]
            ttau = args[2 * ntt + nll:]

            args1 = np.concatenate((ttheta, ttheta_d, ttau))

            Anum = A_fnc(*args1)
            A1 = Anum[:ntt, :ntt]
            A2 = Anum[:ntt, ntt:]

            b1 = b_fnc(*args1)[:ntt]

            ttheta_dd_res = np.linalg.solve(A1, b1 - np.dot(A2, llmd))

            return ttheta_dd_res

        self.acc_of_lmd_func = acc_of_lmd_func
Example #15
0
def reshape_matrix_columns(P):
    m0, n0 = P.shape

    # pick m0 of the simplest lin. independent columns of P:
    P_new = remove_zero_columns(P)
    m1, n1 = P_new.shape

    list_of_cols = matrix_to_vectorlist(P_new)

    # sort by "complexity"
    if pinv_optimization == "free_symbols":
        cols_sorted_by_atoms = sorted(list_of_cols,
                                      key=lambda x: x.free_symbols,
                                      reverse=False)
    elif pinv_optimization == "count_ops":
        cols_sorted_by_atoms = sorted(list_of_cols,
                                      key=lambda x: nr_of_ops(x),
                                      reverse=False)
    elif pinv_optimization == "none":
        cols_sorted_by_atoms = list_of_cols

    # sort by number of zero entries
    colvecs_sorted = sorted(cols_sorted_by_atoms,
                            key=lambda x: count_zero_entries(x),
                            reverse=True)

    # pick m suitable column vectors and add to new matrix A: ----------
    A = colvecs_sorted[0]
    for j in range(len(colvecs_sorted) - 1):
        column = colvecs_sorted[j + 1]
        if is_linearly_independent(A, column):
            A = st.concat_cols(A, column)

        if st.rnd_number_rank(A) == m1:
            break

    assert A.is_square

    # calculate transformation matrix R: -------------------------------
    #R_tilde = sp.Matrix([])
    used_cols = []
    R = sp.Matrix([])
    for k in range(m1):
        new_column_index = k
        old_column_index = get_column_index_of_matrix(P, A.col(k))
        used_cols.append(old_column_index)
        tmp = sp.zeros(n0, 1)
        tmp[old_column_index] = 1

        #R_tilde = st.concat_cols(R_tilde,tmp)
        R = st.concat_cols(R, tmp)
    #R=R_tilde

    # remainder columns of R matrix
    #m2,n2 = R_tilde.shape
    m2, n2 = R.shape
    for l in range(n0):
        if l not in used_cols:
            R_col = sp.zeros(n0, 1)
            R_col[l] = 1
            R = st.concat_cols(R, R_col)

    m3, n3 = A.shape
    r2 = st.rnd_number_rank(A)
    assert m3 == r2, "A problem occured in reshaping the matrix."

    # calculate B matrix: ----------------------------------------------
    B = sp.Matrix([])
    tmp = P * R
    for i in range(n0 - m0):
        B = st.concat_cols(B, tmp.col(m0 + i))

    assert is_zero_matrix(
        (P * R) -
        st.concat_cols(A, B)), "A problem occured in reshaping the matrix."

    return A, B, R