def _eval_derivative_matrix_lines(self, x): from .transpose import Transpose with_x_ind = [i for i, arg in enumerate(self.args) if arg.has(x)] lines = [] for ind in with_x_ind: left_args = self.args[:ind] right_args = self.args[ind + 1:] if right_args: right_mat = MatMul.fromiter(right_args) else: right_mat = Identity(self.shape[1]) if left_args: left_rev = MatMul.fromiter([ Transpose(i).doit() if i.is_Matrix else i for i in reversed(left_args) ]) else: left_rev = Identity(self.shape[0]) d = self.args[ind]._eval_derivative_matrix_lines(x) for i in d: i.append_first(left_rev) i.append_second(right_mat) lines.append(i) return lines
def refine_MatMul(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine >>> X = MatrixSymbol('X', 2, 2) >>> expr = X * X.T >>> print(expr) X*X.T >>> with assuming(Q.orthogonal(X)): ... print(refine(expr)) I """ newargs = [] exprargs = [] for args in expr.args: if args.is_Matrix: exprargs.append(args) else: newargs.append(args) last = exprargs[0] for arg in exprargs[1:]: if arg == last.T and ask(Q.orthogonal(arg), assumptions): last = Identity(arg.shape[0]) elif arg == last.conjugate() and ask(Q.unitary(arg), assumptions): last = Identity(arg.shape[0]) else: newargs.append(last) last = arg newargs.append(last) return MatMul(*newargs)
def __new__(cls, *args, **kwargs): args = list(map(sympify, args)) if all(a.is_Identity for a in args): ret = Identity(prod(a.rows for a in args)) if all(isinstance(a, MatrixBase) for a in args): return ret.as_explicit() else: return ret check = kwargs.get('check', True) if check: validate(*args) return super(KroneckerProduct, cls).__new__(cls, *args)
def __new__(cls, *args, **kwargs): args = list(map(sympify, args)) if all(a.is_Identity for a in args): ret = Identity(prod(a.rows for a in args)) if all(isinstance(a, MatrixBase) for a in args): return ret.as_explicit() else: return ret check = kwargs.get('check', True) if check: validate(*args) return super(KroneckerProduct, cls).__new__(cls, *args)
def test_PermutationMatrix_matpow(): p1 = Permutation([1, 2, 0]) P1 = PermutationMatrix(p1) p2 = Permutation([2, 0, 1]) P2 = PermutationMatrix(p2) assert P1**2 == P2 assert P1**3 == Identity(3)
def test_MatrixPermute_doit(): p = Permutation(0, 1, 2) A = MatrixSymbol('A', 3, 3) assert MatrixPermute(A, p).doit() == MatrixPermute(A, p) p = Permutation(0, size=3) A = MatrixSymbol('A', 3, 3) assert MatrixPermute(A, p).doit().as_explicit() == \ MatrixPermute(A, p).as_explicit() p = Permutation(0, 1, 2) A = Identity(3) assert MatrixPermute(A, p, 0).doit().as_explicit() == \ MatrixPermute(A, p, 0).as_explicit() assert MatrixPermute(A, p, 1).doit().as_explicit() == \ MatrixPermute(A, p, 1).as_explicit() A = ZeroMatrix(3, 3) assert MatrixPermute(A, p).doit() == A A = OneMatrix(3, 3) assert MatrixPermute(A, p).doit() == A A = MatrixSymbol('A', 4, 4) p1 = Permutation(0, 1, 2, 3) p2 = Permutation(0, 2, 3, 1) expr = MatrixPermute(MatrixPermute(A, p1, 0), p2, 0) assert expr.as_explicit() == expr.doit().as_explicit() expr = MatrixPermute(MatrixPermute(A, p1, 1), p2, 1) assert expr.as_explicit() == expr.doit().as_explicit()
def prove(Eq): n = Symbol.n(domain=Interval(2, oo, integer=True)) i = Symbol.i(domain=Interval(0, n - 1, integer=True)) j = Symbol.j(domain=Interval(0, n - 1, integer=True)) assert Identity(n).is_integer w = Symbol.w(integer=True, shape=(n, n, n, n), definition=LAMBDA[j, i](Swap(n, i, j))) Eq << apply(w) Eq << w[j, i].equality_defined() Eq << Eq[0] @ Eq[-1] Eq << Eq[-1].this.rhs.expand() Eq << Eq[-1].this.rhs.simplify(deep=True, wrt=Eq[-1].rhs.variable) Eq << Eq[-1].this.rhs.function.as_KroneckerDelta() Eq << Eq[0] @ Eq[0] Eq << Eq[-1].subs(Eq[-2].reversed) Eq << w[i, j].inverse() @ Eq[-1] Eq << Eq[-1].forall((i,), (j,))
def column_transformation(*limits): n = limits[0][-1] + 1 (i, *_), (j, *_) = limits # return Identity(n) + LAMBDA[j:n, i:n](Piecewise((0, i < n - 1), (KroneckerDelta(j, n - 1) - 1, True))) # return Identity(n) + LAMBDA[j:n, i:n](Piecewise((KroneckerDelta(j, n - 1) - 1, Equality(i, n - 1)), (0, True))) return Identity(n) + LAMBDA[j:n, i:n](KroneckerDelta(i, n - 1) * (KroneckerDelta(j, n - 1) - 1)) return LAMBDA( Piecewise((KroneckerDelta(i, j), i < n - 1), (2 * KroneckerDelta(j, n - 1) - 1, True)), *limits)
def xxinv(mul): """ Y * X * X.I -> Y """ factor, matrices = mul.as_coeff_matrices() for i, (X, Y) in enumerate(zip(matrices[:-1], matrices[1:])): try: if X.is_square and Y.is_square and X == Y.inverse(): I = Identity(X.rows) return newmul(factor, *(matrices[:i] + [I] + matrices[i + 2:])) except ValueError: # Y might not be invertible pass return mul
def bc_block_plus_ident(expr): idents = [arg for arg in expr.args if arg.is_Identity] if not idents: return expr blocks = [arg for arg in expr.args if isinstance(arg, BlockMatrix)] if (blocks and all(b.structurally_equal(blocks[0]) for b in blocks) and blocks[0].is_structurally_symmetric): block_id = BlockDiagMatrix( *[Identity(k) for k in blocks[0].rowblocksizes]) return MatAdd(block_id * len(idents), *blocks).doit() return expr
def test_sympy__matrices__expressions__matexpr__Identity(): from sympy.matrices.expressions.matexpr import Identity assert _test_args(Identity(3))
def row_transformation(a, *limits): n = limits[0][-1] + 1 (i, *_), (j, *_) = limits return Identity(n) - LAMBDA[j:n, i:n](a[0] * KroneckerDelta(i, j + 1))
def apply(n, a): i = Symbol.i(integer=True) return Equality(Det(1 + a[:n] * Identity(n)), (1 + Sum[i:0:n - 1](1 / a[i])) * Product[i:0:n - 1](a[i]))
def __new__(cls, *args, **kwargs): # check = kwargs.get('check', True) check = kwargs.get('check', False) if not args: return cls.identity if len(args) == 1: return args[0] # This must be removed aggressively in the constructor to avoid # TypeErrors from GenericIdentity().shape args = list(map(sympify, args)) if any(arg.is_MatMul for arg in args): def generator(): for arg in args: if arg.is_MatMul: yield from arg.args else: yield arg args = [*generator()] coeffs = [] matrices = [] def append(mat): if matrices: last = matrices[-1] if last.is_MatPow: if mat.is_MatPow: if last.base == mat.base: matrices[-1] = last.func(last.base, last.exp + mat.exp) return elif last.base == mat: matrices[-1] = last.func(last.base, last.exp + 1) return elif last == mat: if mat._eval_inverse() == last: matrices.pop() else: matrices[-1] = MatPow(last, 2) return matrices.append(mat) for arg in args: if not arg.is_Mul: append(arg) continue coeff = [] matrix = [] for t in arg.args: if t.shape: matrix.append(t) else: coeff.append(t) if coeff: coeffs.append(Mul(*coeff)) append(Mul(*matrix)) else: append(arg) if not matrices: return Identity(args[0].shape[-1]) matrices = [*filter(lambda X: not X.is_Identity, matrices)] if len(matrices) == 1: mat = matrices.pop() else: mat = Basic.__new__(cls, *matrices) factor, matrices = mat.as_coeff_matrices() if check: validate(*matrices) if not matrices: # Should it be # # return Basic.__neq__(cls, factor, GenericIdentity()) ? mat = factor if coeffs: mat = Mul(*coeffs) * mat return mat
def apply(A): n = A.shape[0] return Equality(A @ Cofactors(A).T, Determinant(A) * Identity(n))