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
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
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)
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)