def test_expr_fns(): from sympy.strategies.rl import rebuild x, y = map(Symbol, 'xy') expr = x + y**3 e = bottom_up(lambda x: x+1, expr_fns)(expr) b = bottom_up(lambda x: x+1, basic_fns)(expr) assert b!=e assert rebuild(b) == e
def test_expr_fns(): from sympy.strategies.rl import rebuild from sympy import Add x, y = map(Symbol, 'xy') expr = x + y**3 e = bottom_up(lambda x: x + 1, expr_fns)(expr) b = bottom_up(lambda x: Basic.__new__(Add, x, 1), basic_fns)(expr) assert rebuild(b) == e
def test_expr_fns(): from sympy.strategies.rl import rebuild x, y = map(Symbol, 'xy') expr = x + y**3 e = bottom_up(lambda x: x + 1, expr_fns)(expr) b = bottom_up(lambda x: x + 1, basic_fns)(expr) assert b != e assert rebuild(b) == e
def remove_matelement(expr, i1, i2): def repl_match(pos): def func(x): if not isinstance(x, MatrixElement): return False if x.args[pos] != i1: return False if x.args[3-pos] == 0: if x.args[0].shape[2-pos] == 1: return True else: return False return True return func expr = expr.replace(repl_match(1), lambda x: x.args[0]) expr = expr.replace(repl_match(2), lambda x: transpose(x.args[0])) # Make sure that all Mul are transformed to MatMul and that they # are flattened: rule = bottom_up(lambda x: reduce(lambda a, b: a*b, x.args) if isinstance(x, (Mul, MatMul)) else x) return rule(expr)
def combine_kronecker(expr): """Combine KronekeckerProduct with expression. If possible write operations on KroneckerProducts of compatible shapes as a single KroneckerProduct. Examples ======== >>> from sympy.matrices.expressions import MatrixSymbol, KroneckerProduct, combine_kronecker >>> from sympy import symbols >>> m, n = symbols(r'm, n', integer=True) >>> A = MatrixSymbol('A', m, n) >>> B = MatrixSymbol('B', n, m) >>> combine_kronecker(KroneckerProduct(A, B)*KroneckerProduct(B, A)) KroneckerProduct(A*B, B*A) >>> combine_kronecker(KroneckerProduct(A, B)+KroneckerProduct(B.T, A.T)) KroneckerProduct(A + B.T, B + A.T) >>> combine_kronecker(KroneckerProduct(A, B)**m) KroneckerProduct(A**m, B**m) """ def haskron(expr): return isinstance(expr, MatrixExpr) and expr.has(KroneckerProduct) rule = exhaust( bottom_up(exhaust(condition(haskron, typed( {MatAdd: kronecker_mat_add, MatMul: kronecker_mat_mul, MatPow: kronecker_mat_pow}))))) result = rule(expr) doit = getattr(result, 'doit', None) if doit is not None: return doit() else: return result
def block_collapse(expr): """Evaluates a block matrix expression >>> from sympy import MatrixSymbol, BlockMatrix, symbols, \ Identity, Matrix, ZeroMatrix, block_collapse >>> n,m,l = symbols('n m l') >>> X = MatrixSymbol('X', n, n) >>> Y = MatrixSymbol('Y', m ,m) >>> Z = MatrixSymbol('Z', n, m) >>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]]) >>> print(B) Matrix([ [X, Z], [0, Y]]) >>> C = BlockMatrix([[Identity(n), Z]]) >>> print(C) Matrix([[I, Z]]) >>> print(block_collapse(C*B)) Matrix([[X, Z*Y + Z]]) """ hasbm = lambda expr: isinstance(expr, MatrixExpr) and expr.has(BlockMatrix) rule = exhaust( bottom_up(exhaust(condition(hasbm, typed( {MatAdd: do_one(bc_matadd, bc_block_plus_ident), MatMul: do_one(bc_matmul, bc_dist), Transpose: bc_transpose, Inverse: bc_inverse, BlockMatrix: do_one(bc_unpack, deblock)}))))) result = rule(expr) try: return result.doit() except AttributeError: return result
def combine_kronecker(expr): """Combine KronekeckerProduct with expression. If possible write operations on KroneckerProducts of compatible shapes as a single KroneckerProduct. Examples ======== >>> from sympy.matrices.expressions import MatrixSymbol, KroneckerProduct, combine_kronecker >>> from sympy import symbols >>> m, n = symbols(r'm, n', integer=True) >>> A = MatrixSymbol('A', m, n) >>> B = MatrixSymbol('B', n, m) >>> combine_kronecker(KroneckerProduct(A, B)*KroneckerProduct(B, A)) KroneckerProduct(A*B, B*A) >>> combine_kronecker(KroneckerProduct(A, B)+KroneckerProduct(B.T, A.T)) KroneckerProduct(A + B.T, B + A.T) >>> combine_kronecker(KroneckerProduct(A, B)**m) KroneckerProduct(A**m, B**m) """ def haskron(expr): return isinstance(expr, MatrixExpr) and expr.has(KroneckerProduct) rule = exhaust( bottom_up(exhaust(condition(haskron, typed( {MatAdd: kronecker_mat_add, MatMul: kronecker_mat_mul, MatPow: kronecker_mat_pow}))))) result = rule(expr) try: return result.doit() except AttributeError: return result
def block_collapse(expr): """Evaluates a block matrix expression >>> from sympy import MatrixSymbol, BlockMatrix, symbols, \ Identity, Matrix, ZeroMatrix, block_collapse >>> n,m,l = symbols('n m l') >>> X = MatrixSymbol('X', n, n) >>> Y = MatrixSymbol('Y', m ,m) >>> Z = MatrixSymbol('Z', n, m) >>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]]) >>> print(B) Matrix([ [X, Z], [0, Y]]) >>> C = BlockMatrix([[Identity(n), Z]]) >>> print(C) Matrix([[I, Z]]) >>> print(block_collapse(C*B)) Matrix([[X, Z + Z*Y]]) """ from sympy.strategies.util import expr_fns hasbm = lambda expr: isinstance(expr, MatrixExpr) and expr.has(BlockMatrix) conditioned_rl = condition( hasbm, typed( {MatAdd: do_one(bc_matadd, bc_block_plus_ident), MatMul: do_one(bc_matmul, bc_dist), MatPow: bc_matmul, Transpose: bc_transpose, Inverse: bc_inverse, BlockMatrix: do_one(bc_unpack, deblock)} ) ) rule = exhaust( bottom_up( exhaust(conditioned_rl), fns=expr_fns ) ) result = rule(expr) doit = getattr(result, 'doit', None) if doit is not None: return doit() else: return result
def test_expr_fns(): expr = x + y**3 e = bottom_up(lambda v: v + 1, expr_fns)(expr) b = bottom_up(lambda v: Basic.__new__(Add, v, S(1)), basic_fns)(expr) assert rebuild(b) == e