예제 #1
0
 def preprocess(self):
     self.VarList = tuple(self.Vars)
     self.NumVars = len(self.VarList)
     self.VarVector = BlockMatrix((tuple(self.Vars[var] for var in self.VarList),))
     self.NumDims = self.VarVector.shape[1]
     self.Mean = BlockMatrix((tuple(self.Param[('Mean', var)] for var in self.VarList),))
     self.DemeanedVarVector = self.VarVector - self.Mean
     cov = [self.NumVars * [None] for _ in range(self.NumVars)]   # careful not to create same mutable object
     for i in range(self.NumVars):
         for j in range(i):
             if ('Cov', self.VarList[i], self.VarList[j]) in self.Param:
                 cov[i][j] = self.Param[('Cov', self.VarList[i], self.VarList[j])]
                 cov[j][i] = cov[i][j].T
             else:
                 cov[j][i] = self.Param[('Cov', self.VarList[j], self.VarList[i])]
                 cov[i][j] = cov[j][i].T
         cov[i][i] = self.Param[('Cov', self.VarList[i])]
     self.Cov = BlockMatrix(cov)
     try:
         cov = CompyledFunc(var_names_and_syms={}, dict_or_expr=self.Cov)()
         sign, self.LogDetCov = slogdet(cov)
         self.LogDetCov *= sign
         self.InvCov = inv(cov)
     except:
         pass
     self.PreProcessed = True
예제 #2
0
def test_squareBlockMatrix():
    n,m,l,k = symbols('n m l k', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', n, m)
    C = MatrixSymbol('C', m, n)
    D = MatrixSymbol('D', m, m)
    X = BlockMatrix([[A,B],[C,D]])
    Y = BlockMatrix([[A]])

    assert X.is_square

    assert block_collapse(X+Identity(m+n)) == BlockMatrix(
        [[A+Identity(n), B], [C, D+Identity(m)]])
    Q = X+Identity(m+n)
    assert block_collapse(Inverse(Q)) == Inverse(block_collapse(Q))

    assert (X + MatrixSymbol('Q', n+m, n+m)).is_Add
    assert (X * MatrixSymbol('Q', n+m, n+m)).is_Mul

    assert Y.I[0,0] == A.I
    assert Inverse(X, expand=True) == BlockMatrix([
        [(-B*D.I*C + A).I, -A.I*B*(D+-C*A.I*B).I],
        [-(D-C*A.I*B).I*C*A.I, (D-C*A.I*B).I]])

    assert Inverse(X, expand=False).is_Inverse
    assert X.inverse().is_Inverse

    assert not X.is_Identity

    Z = BlockMatrix([[Identity(n),B],[C,D]])
    assert not Z.is_Identity
예제 #3
0
def test_BlockMatrix():
    n,m,l,k,p = symbols('n m l k p', integer=True)
    A = MatrixSymbol('A', n, m)
    B = MatrixSymbol('B', n, k)
    C = MatrixSymbol('C', l, m)
    D = MatrixSymbol('D', l, k)
    M = MatrixSymbol('M', m+k, p)
    N = MatrixSymbol('N', l+n, k+m)
    X = BlockMatrix(Matrix([[A,B],[C,D]]))

    # block_collapse does nothing on normal inputs
    E = MatrixSymbol('E', n, m)
    assert block_collapse(A+2*E) == A+2*E
    F = MatrixSymbol('F', m, m)
    assert block_collapse(E.T*A*F) == E.T*A*F

    assert X.shape == (l+n, k+m)
    assert (block_collapse(Transpose(X)) ==
            BlockMatrix(Matrix([[A.T, C.T], [B.T, D.T]])))
    assert Transpose(X).shape == X.shape[::-1]
    assert X.blockshape == (2,2)

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X*M).is_Mul
    assert X._blockmul(M).is_Mul
    assert (X*M).shape == (n+l, p)
    assert (X+N).is_Add
    assert X._blockadd(N).is_Add
    assert (X+N).shape == X.shape

    E = MatrixSymbol('E', m, 1)
    F = MatrixSymbol('F', k, 1)

    Y = BlockMatrix(Matrix([[E], [F]]))

    assert (X*Y).shape == (l+n, 1)
    assert block_collapse(X*Y)[0,0] == A*E + B*F
    assert block_collapse(X*Y)[1,0] == C*E + D*F
    assert (block_collapse(Transpose(block_collapse(Transpose(X*Y)))) ==
            block_collapse(X*Y))

    # block_collapse passes down into container objects, transposes, and inverse
    assert block_collapse((X*Y, 2*X)) == (block_collapse(X*Y), block_collapse(2*X))
    assert block_collapse(Tuple(X*Y, 2*X)) == (
            block_collapse(X*Y), block_collapse(2*X))
    assert (block_collapse(Transpose(X*Y)) ==
            block_collapse(Transpose(block_collapse(X*Y))))

    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol('Z', *A.shape)

    # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies
    assert block_collapse(Ab+Z) == BlockMatrix([[A+Z]])
    def exp_deriv_generators(self, params):
        '''
        constructs the generators for computing the first derivative of the
        time ordered exponential of self, with respect to params
        
        Note: I'll need to either add in stuff that keeps track of where the
        blocks go, or just have a convention that is maintained everywhere.
        
        Convention is easier, but it might be nice to also return some data
        structure with this info
        '''

        D, C = self.parameter_decomposition(params)

        new_mats = []

        for sys_idx in range(len(self.mat_list)):
            G = self.mat_list[sys_idx]
            m0 = zeros(self.shape[sys_idx])

            for d_idx in range(len(params)):

                A = C[d_idx].mat_list[sys_idx]
                new_mats.append(Matrix(BlockMatrix([[G, A], [m0, G]])))

        return Sym_UTB_Matrix(new_mats)
예제 #5
0
파일: eulaC.py 프로젝트: jjuch/nlcontrol
    def convert_to_dynamic_controller(self):
        """
        The Euler-Lagrange formalism is transformed to the state and output equation notation of the DynamicController class.

        Returns:
        --------
        result : tuple
            The tuple contains the transformed matrices that are compatible with the function define_controller of DynamicController. 
        """
        dim_states = len(self.minimal_states)
        D0_inv = self.inertia_matrix**(-1)
        In = eye(dim_states)
        Z = zeros(dim_states)
        K0_D0 = -D0_inv * self.stiffness_matrix
        C0_D0 = -D0_inv * self.damping_matrix
        A = Matrix(BlockMatrix([[Z, In], [K0_D0, C0_D0]]))

        C1_D0 = D0_inv * self.nonlinear_coefficient_matrix
        Z = zeros(dim_states, len(self.nonlinear_stiffness_fcts))
        B = Matrix(BlockMatrix([[Z], [C1_D0]]))

        f = self.nonlinear_stiffness_fcts

        Z = zeros(dim_states, len(f))
        if self.nl_stiffness:
            C = Matrix(BlockMatrix([[self.nonlinear_coefficient_matrix], [Z]]))
        else:
            C = Matrix(BlockMatrix([[Z], [self.nonlinear_coefficient_matrix]]))

        NA_D0 = -D0_inv * self.gain_inputs
        NB_D0 = -D0_inv * self.gain_dinputs
        Z = zeros(dim_states, 1)
        eta = Matrix(
            BlockMatrix([[Z],
                         [
                             NA_D0 * Matrix(self.minimal_inputs) +
                             NB_D0 * Matrix(self.dinputs)
                         ]]))

        phi = self.gain_inputs.T * D0_inv * self.stiffness_matrix**(
            -1) * self.inertia_matrix * self.stiffness_matrix * Matrix(
                self.minimal_states
            ) - self.gain_dinputs.T * D0_inv * self.stiffness_matrix**(
                -1) * self.inertia_matrix * self.stiffness_matrix * Matrix(
                    self.minimal_dstates)

        return A, B, C, f, eta, phi
예제 #6
0
def test_squareBlockMatrix():
    n, m, l, k = symbols('n m l k', integer=True)
    A = MatrixSymbol('A', n, n)
    B = MatrixSymbol('B', n, m)
    C = MatrixSymbol('C', m, n)
    D = MatrixSymbol('D', m, m)
    X = BlockMatrix([[A, B], [C, D]])
    Y = BlockMatrix([[A]])

    assert X.is_square

    assert block_collapse(X + Identity(m + n)) == BlockMatrix(
        [[A + Identity(n), B], [C, D + Identity(m)]])
    Q = X + Identity(m + n)
    assert block_collapse(Inverse(Q)) == Inverse(block_collapse(Q))

    assert (X + MatrixSymbol('Q', n + m, n + m)).is_Add
    assert (X * MatrixSymbol('Q', n + m, n + m)).is_Mul

    assert Y.I.blocks[0, 0] == A.I
    assert Inverse(X, expand=True) == BlockMatrix([[
        (-B * D.I * C + A).I, -A.I * B * (D + -C * A.I * B).I
    ], [-(D - C * A.I * B).I * C * A.I, (D - C * A.I * B).I]])

    assert Inverse(X, expand=False).is_Inverse
    assert X.inverse().is_Inverse

    assert not X.is_Identity

    Z = BlockMatrix([[Identity(n), B], [C, D]])
    assert not Z.is_Identity
예제 #7
0
def test_BlockMatrix():
    n, m, l, k, p = symbols('n m l k p', integer=True)
    A = MatrixSymbol('A', n, m)
    B = MatrixSymbol('B', n, k)
    C = MatrixSymbol('C', l, m)
    D = MatrixSymbol('D', l, k)
    M = MatrixSymbol('M', m + k, p)
    N = MatrixSymbol('N', l + n, k + m)
    X = BlockMatrix(Matrix([[A, B], [C, D]]))

    # block_collapse does nothing on normal inputs
    E = MatrixSymbol('E', n, m)
    assert block_collapse(A + 2 * E) == A + 2 * E
    F = MatrixSymbol('F', m, m)
    assert block_collapse(E.T * A * F) == E.T * A * F

    assert X.shape == (l + n, k + m)
    assert (block_collapse(Transpose(X)) == BlockMatrix(
        Matrix([[A.T, C.T], [B.T, D.T]])))
    assert Transpose(X).shape == X.shape[::-1]
    assert X.blockshape == (2, 2)

    # Test that BlockMatrices and MatrixSymbols can still mix
    assert (X * M).is_Mul
    assert X._blockmul(M).is_Mul
    assert (X * M).shape == (n + l, p)
    assert (X + N).is_Add
    assert X._blockadd(N).is_Add
    assert (X + N).shape == X.shape

    E = MatrixSymbol('E', m, 1)
    F = MatrixSymbol('F', k, 1)

    Y = BlockMatrix(Matrix([[E], [F]]))

    assert (X * Y).shape == (l + n, 1)
    assert block_collapse(X * Y).blocks[0, 0] == A * E + B * F
    assert block_collapse(X * Y).blocks[1, 0] == C * E + D * F
    assert (block_collapse(Transpose(block_collapse(Transpose(
        X * Y)))) == block_collapse(X * Y))

    # block_collapse passes down into container objects, transposes, and inverse
    assert block_collapse(
        (X * Y, 2 * X)) == (block_collapse(X * Y), block_collapse(2 * X))
    assert block_collapse(Tuple(X * Y, 2 * X)) == (block_collapse(X * Y),
                                                   block_collapse(2 * X))
    assert (block_collapse(Transpose(X * Y)) == block_collapse(
        Transpose(block_collapse(X * Y))))

    Ab = BlockMatrix([[A]])
    Z = MatrixSymbol('Z', *A.shape)

    # Make sure that MatrixSymbols will enter 1x1 BlockMatrix if it simplifies
    assert block_collapse(Ab + Z) == BlockMatrix([[A + Z]])
예제 #8
0
파일: eulaC.py 프로젝트: jjuch/nlcontrol
 def nonlinear_stiffness_fcts(self, matrix: Matrix):
     if len(matrix) == len(self.minimal_states):
         Z = zeros(len(self.minimal_states), len(matrix))
         if self.nl_stiffness:
             C = Matrix(
                 BlockMatrix([[self.nonlinear_coefficient_matrix], [Z]]))
         else:
             C = Matrix(
                 BlockMatrix([[Z], [self.nonlinear_coefficient_matrix]]))
         argument = Array(C.T * Matrix(self.states))
         completed_f = []
         for idx, fct in enumerate(matrix):
             if callable(fct[0]):
                 completed_f.append([fct[0](argument[idx])])
             elif fct[0]:
                 completed_f.append(0)
             else:
                 error_text = '[EulerLagrangeController] f should be a callable function or identical 0.'
                 raise AssertionError(error_text)
         self._nl = Matrix(completed_f)
     else:
         error_text = '[EulerLagrangeController.nonlinear_stiffness_fcts (setter)] The stiffness matrix should have the same row dimension as the number of states.'
         raise ValueError(error_text)
예제 #9
0
def test_BlockMatrix_Trace():
    A, B, C, D = map(lambda s: MatrixSymbol(s, 3, 3), 'ABCD')
    X = BlockMatrix([[A, B], [C, D]])
    assert Trace(X) == Trace(A) + Trace(D)
예제 #10
0
    73.687667, 73.806480, 74.882408, 81.997367, 89.673179, 96.831947
]

x = Matrix(N, 1, xinit)

print x

A0 = ones(N, 1)
A1 = x
A2 = x.multiply_elementwise(x)

#print(A0)
#print(A1)
#print(A2)

A = BlockMatrix([A0, A1, A2])
A = A.as_explicit()

yErr = [0.0005205, 0.0006515, 0.0004069, 0.0047973, 0.0055708, 0.0055551, \
0.0054941, 0.0043147, 0.3925145, 0.0041837, 0.4294512, 0.0042747, \
0.4657444, 0.0038275, 0.0038912, 0.0037950, 0.2330908, 0.0038282, \
0.2650930, 0.0029776, 0.2709266, 0.0030374, 0.3159595, 0.0023857]

MatErr = [
    4.753 * 10**-6, 4.060 * 10**-6, 4.060 * 10**-6, 1.872 * 10**-5,
    2.800 * 10**-5, 2.800 * 10**-5, 1.061 * 10**-5, 1.061 * 10**-5,
    5.467 * 10**-6, 5.467 * 10**-6, 8.882 * 10**-6, 8.882 * 10**-6,
    1.315 * 10**-5, 9.930 * 10**-6, 4.358 * 10**-6, 4.358 * 10**-6,
    4.691 * 10**-6, 4.691 * 10**-6, 4.880 * 10**-6, 4.880 * 10**-6,
    9.760 * 10**-6, 8.704 * 10**-6, 8.388 * 10**-6, 8.370 * 10**-6
]
예제 #11
0
def gauss_cond(pdf, cond={}, **kw_cond):
    cond = combine_dict_and_kwargs(cond, kw_cond)
    new_cond = pdf.Cond.copy()
    new_cond.update(cond)
    scope = pdf.Scope.copy()
    for var in cond:
        del scope[var]
    point_cond = {}
    for var, value in list(cond.items()):
        if value is not None:
            point_cond[pdf.Vars[var]] = value
    cond_vars = tuple(cond)
    num_cond_vars = len(cond_vars)
    scope_vars = tuple(set(pdf.VarsList) - set(cond))
    num_scope_vars = len(scope_vars)
    x_c = BlockMatrix((tuple(pdf.Vars[cond_var] for cond_var in cond_vars),))
    m_c = BlockMatrix((tuple(pdf.Param[('Mean', cond_var)] for cond_var in cond_vars),))
    m_s = BlockMatrix((tuple(pdf.Param[('Mean', scope_var)] for scope_var in scope_vars),))

    S_c = [num_cond_vars * [None] for _ in range(num_cond_vars)]   # careful not to create same mutable object
    for i in range(num_cond_vars):
        for j in range(i):
            if ('Cov', cond_vars[i], cond_vars[j]) in pdf.Param:
                S_c[i][j] = pdf.Param[('Cov', cond_vars[i], cond_vars[j])]
                S_c[j][i] = S_c[i][j].T
            else:
                S_c[j][i] = pdf.Param[('Cov', cond_vars[j], cond_vars[i])]
                S_c[i][j] = S_c[j][i].T
        S_c[i][i] = pdf.Param[('Cov', cond_vars[i])]
    S_c = BlockMatrix(S_c)

    S_s = [num_scope_vars * [None] for _ in range(num_scope_vars)]   # careful not to create same mutable object
    for i in range(num_scope_vars):
        for j in range(i):
            if ('Cov', scope_vars[i], scope_vars[j]) in pdf.Param:
                S_s[i][j] = pdf.Param[('Cov', scope_vars[i], scope_vars[j])]
                S_s[j][i] = S_s[i][j].T
            else:
                S_s[j][i] = pdf.Param[('Cov', scope_vars[j], scope_vars[i])]
                S_s[i][j] = S_s[j][i].T
        S_s[i][i] = pdf.Param[('Cov', scope_vars[i])]
    S_s = BlockMatrix(S_s)

    S_cs = [num_scope_vars * [None] for _ in range(num_cond_vars)]   # careful not to create same mutable object
    for i, j in product(list(range(num_cond_vars)), list(range(num_scope_vars))):
        if ('Cov', cond_vars[i], scope_vars[j]) in pdf.Param:
            S_cs[i][j] = pdf.Param[('Cov', cond_vars[i], scope_vars[j])]
        else:
            S_cs[i][j] = pdf.Param[('Cov', scope_vars[j], cond_vars[i])].T
    S_cs = BlockMatrix(S_cs)
    S_sc = S_cs.T

    m = (m_s + (x_c - m_c) * S_c.inverse() * S_cs).xreplace(point_cond)
    S = S_s - S_sc * S_c.inverse() * S_cs

    param = {}
    index_ranges_from = []
    index_ranges_to = []
    k = 0
    for i in range(num_scope_vars):
        l = k + pdf.Vars[scope_vars[i]].shape[1]
        index_ranges_from += [k]
        index_ranges_to += [l]
        param[('Mean', scope_vars[i])] = m[0, index_ranges_from[i]:index_ranges_to[i]]
        for j in range(i):
            param[('Cov', scope_vars[j], scope_vars[i])] =\
                S[index_ranges_from[j]:index_ranges_to[j], index_ranges_from[i]:index_ranges_to[i]]
        param[('Cov', scope_vars[i])] =\
            S[index_ranges_from[i]:index_ranges_to[i], index_ranges_from[i]:index_ranges_to[i]]
        k = l

    return GaussPDF(var_names_and_syms=pdf.Vars.copy(), param=param, cond=new_cond, scope=scope)
예제 #12
0
def gauss_cond(pdf, cond={}, **kw_cond):
    cond = combine_dict_and_kwargs(cond, kw_cond)
    new_cond = pdf.Cond.copy()
    new_cond.update(cond)
    scope = pdf.Scope.copy()
    for var in cond:
        del scope[var]
    point_cond = {}
    for var, value in cond.items():
        if value is not None:
            point_cond[pdf.Vars[var]] = value
    cond_vars = tuple(cond)
    num_cond_vars = len(cond_vars)
    scope_vars = tuple(set(pdf.VarsList) - set(cond))
    num_scope_vars = len(scope_vars)
    x_c = BlockMatrix((tuple(pdf.Vars[cond_var] for cond_var in cond_vars),))
    m_c = BlockMatrix((tuple(pdf.Param[('Mean', cond_var)] for cond_var in cond_vars),))
    m_s = BlockMatrix((tuple(pdf.Param[('Mean', scope_var)] for scope_var in scope_vars),))

    S_c = [num_cond_vars * [None] for _ in range(num_cond_vars)]   # careful not to create same mutable object
    for i in range(num_cond_vars):
        for j in range(i):
            if ('Cov', cond_vars[i], cond_vars[j]) in pdf.Param:
                S_c[i][j] = pdf.Param[('Cov', cond_vars[i], cond_vars[j])]
                S_c[j][i] = S_c[i][j].T
            else:
                S_c[j][i] = pdf.Param[('Cov', cond_vars[j], cond_vars[i])]
                S_c[i][j] = S_c[j][i].T
        S_c[i][i] = pdf.Param[('Cov', cond_vars[i])]
    S_c = BlockMatrix(S_c)

    S_s = [num_scope_vars * [None] for _ in range(num_scope_vars)]   # careful not to create same mutable object
    for i in range(num_scope_vars):
        for j in range(i):
            if ('Cov', scope_vars[i], scope_vars[j]) in pdf.Param:
                S_s[i][j] = pdf.Param[('Cov', scope_vars[i], scope_vars[j])]
                S_s[j][i] = S_s[i][j].T
            else:
                S_s[j][i] = pdf.Param[('Cov', scope_vars[j], scope_vars[i])]
                S_s[i][j] = S_s[j][i].T
        S_s[i][i] = pdf.Param[('Cov', scope_vars[i])]
    S_s = BlockMatrix(S_s)

    S_cs = [num_scope_vars * [None] for _ in range(num_cond_vars)]   # careful not to create same mutable object
    for i, j in product(range(num_cond_vars), range(num_scope_vars)):
        if ('Cov', cond_vars[i], scope_vars[j]) in pdf.Param:
            S_cs[i][j] = pdf.Param[('Cov', cond_vars[i], scope_vars[j])]
        else:
            S_cs[i][j] = pdf.Param[('Cov', scope_vars[j], cond_vars[i])].T
    S_cs = BlockMatrix(S_cs)
    S_sc = S_cs.T

    m = (m_s + (x_c - m_c) * S_c.inverse() * S_cs).xreplace(point_cond)
    S = S_s - S_sc * S_c.inverse() * S_cs

    param = {}
    index_ranges_from = []
    index_ranges_to = []
    k = 0
    for i in range(num_scope_vars):
        l = k + pdf.Vars[scope_vars[i]].shape[1]
        index_ranges_from += [k]
        index_ranges_to += [l]
        param[('Mean', scope_vars[i])] = m[0, index_ranges_from[i]:index_ranges_to[i]]
        for j in range(i):
            param[('Cov', scope_vars[j], scope_vars[i])] =\
                S[index_ranges_from[j]:index_ranges_to[j], index_ranges_from[i]:index_ranges_to[i]]
        param[('Cov', scope_vars[i])] =\
            S[index_ranges_from[i]:index_ranges_to[i], index_ranges_from[i]:index_ranges_to[i]]
        k = l

    return GaussPDF(var_names_and_syms=pdf.Vars.copy(), param=param, cond=new_cond, scope=scope)