Пример #1
0
def simplified_matrix_multiplication(left, right):
    left, right = preprocess_binary(left, right)
    if pybamm.is_matrix_zero(left) or pybamm.is_matrix_zero(right):
        return pybamm.zeros_like(pybamm.MatrixMultiplication(left, right))

    if isinstance(right, Multiplication) and left.is_constant():
        # Simplify A @ (b * c) to (A * b) @ c if (A * b) is constant
        if right.left.evaluates_to_constant_number():
            r_left, r_right = right.orphans
            new_left = left * r_left
            return new_left @ r_right
        # Simplify A @ (b * c) to (A * c) @ b if (A * c) is constant
        elif right.right.evaluates_to_constant_number():
            r_left, r_right = right.orphans
            new_left = left * r_right
            return new_left @ r_left
    elif isinstance(right, Division) and left.is_constant():
        # Simplify A @ (b / c) to (A / c) @ b if (A / c) is constant
        if right.right.evaluates_to_constant_number():
            r_left, r_right = right.orphans
            new_left = left / r_right
            new_mul = new_left @ r_left
            # Keep the domain of the old left
            new_mul.copy_domains(left)
            return new_mul

    # Simplify A @ (B @ c) to (A @ B) @ c if (A @ B) is constant
    # This is a common construction that appears from discretisation of spatial
    # operators
    if (isinstance(right, MatrixMultiplication) and right.left.is_constant()
            and left.is_constant()):
        r_left, r_right = right.orphans
        new_left = left @ r_left
        # be careful about domains to avoid weird errors
        new_left.clear_domains()
        new_mul = new_left @ r_right
        # Keep the domain of the old right
        new_mul.copy_domains(right)
        return new_mul

    # Simplify A @ (b + c) to (A @ b) + (A @ c) if (A @ b) or (A @ c) is constant
    # This is a common construction that appears from discretisation of spatial
    # operators
    # Don't do this if either b or c is a number as this will lead to matmul errors
    elif isinstance(right, Addition):
        if (right.left.is_constant() or right.right.is_constant()
            ) and not (right.left.size_for_testing == 1
                       or right.right.size_for_testing == 1):
            r_left, r_right = right.orphans
            return (left @ r_left) + (left @ r_right)

    return pybamm.simplify_if_constant(pybamm.MatrixMultiplication(
        left, right))
Пример #2
0
    def test_to_equation(self):
        # Test print_name
        pybamm.Addition.print_name = "test"
        self.assertEqual(pybamm.Addition(1, 2).to_equation(), sympy.symbols("test"))

        # Test Power
        self.assertEqual(pybamm.Power(7, 2).to_equation(), 49)

        # Test Division
        self.assertEqual(pybamm.Division(10, 2).to_equation(), 5)

        # Test Matrix Multiplication
        arr1 = pybamm.Array([[1, 0], [0, 1]])
        arr2 = pybamm.Array([[4, 1], [2, 2]])
        self.assertEqual(
            pybamm.MatrixMultiplication(arr1, arr2).to_equation(),
            sympy.Matrix([[4.0, 1.0], [2.0, 2.0]]),
        )

        # Test EqualHeaviside
        self.assertEqual(pybamm.EqualHeaviside(1, 0).to_equation(), False)

        # Test NotEqualHeaviside
        self.assertEqual(pybamm.NotEqualHeaviside(2, 4).to_equation(), True)
Пример #3
0
 def __rmatmul__(self, other):
     """return a :class:`MatrixMultiplication` object"""
     return pybamm.simplify_if_constant(pybamm.MatrixMultiplication(
         other, self),
                                        keep_domains=True)
Пример #4
0
 def __rmatmul__(self, other):
     """return a :class:`MatrixMultiplication` object"""
     if isinstance(other, (Symbol, numbers.Number)):
         return pybamm.MatrixMultiplication(other, self)
     else:
         raise NotImplementedError