Repository: sympy/sympy
File: sympy/matrices/expressions/matpow.py (Python)

Code before:
            return eval_power(exp)

        return MatPow(base, exp)

    def _eval_transpose(self):
        base, exp = self.args
        return MatPow(base.transpose(), exp)

    def _eval_adjoint(self):
        base, exp = self.args
        return MatPow(base.adjoint(), exp)

    def _eval_conjugate(self):
        base, exp = self.args
        return MatPow(base.conjugate(), exp)

    def _eval_derivative(self, x):
        assert not hasattr(x, "shape")
        # dbase = self.base.diff(x)
        dexp = self.exp.diff(x)
        if dexp != 0:
            raise NotImplementedError("cannot derive matrix power if exponent depends on the derivation variable")
        if self.exp.is_Integer:
            from sympy import MatMul
            return MatMul.fromiter(self.base for i in range(self.exp))._eval_derivative(x)
        raise NotImplementedError("cannot evaluate derivatives of matrix power is not a known integer")

    def _eval_derivative_matrix_lines(self, x):
        from sympy.tensor.array.expressions.array_expressions import ArrayContraction
        from ...tensor.array.expressions.array_expressions import ArrayTensorProduct
        from .matmul import MatMul
        from .inverse import Inverse
        exp = self.exp
        if self.base.shape == (1, 1) and not exp.has(x):
            lr = self.base._eval_derivative_matrix_lines(x)
            for i in lr:
                subexpr = ExprBuilder(
                    ArrayContraction,
                    [
                        ExprBuilder(
                            ArrayTensorProduct,
                            [
                                Identity(1),
                                i._lines[0],
                                exp*self.base**(exp-1),
                                i._lines[1],
                                Identity(1),
                            ]
                        ),
                        (0, 3, 4), (5, 7, 8)
                    ],

Review comment (bug):
This will fail if exp is a negative integer. Also I think i is beter o have unevaluated derivatives rather than raising an exceptions. The alternative conditions here do not mean that the derivatives is undefined or anything e.g.:
```
In [8]: M = MatPow(Matrix([[0, m], [n, 0]]), x)

In [9]: M
Out[9]:
      x
⎡0  m⎤
⎢    ⎥
⎣n  0⎦

In [10]: M.diff(m)
---------------------------------------------------------------------------
NotImplementedError
```

Code after:
            return eval_power(exp)

        return MatPow(base, exp)

    def _eval_transpose(self):
        base, exp = self.args
        return MatPow(base.transpose(), exp)

    def _eval_adjoint(self):
        base, exp = self.args
        return MatPow(base.adjoint(), exp)

    def _eval_conjugate(self):
        base, exp = self.args
        return MatPow(base.conjugate(), exp)

    def _eval_derivative(self, x):
        assert not hasattr(x, "shape")
        # dbase = self.base.diff(x)
        dexp = self.exp.diff(x)
        if dexp != 0:
            return None
        if self.exp.is_Integer:
            if self.exp > 0:
                from sympy import MatMul
                return MatMul.fromiter(self.base for _ in range(self.exp))._eval_derivative(x)
            elif self.exp == 0:
                from .special import ZeroMatrix
                return ZeroMatrix(*self.base.shape)
        return None

    def _eval_derivative_matrix_lines(self, x):
        from sympy.tensor.array.expressions.array_expressions import ArrayContraction
        from ...tensor.array.expressions.array_expressions import ArrayTensorProduct
        from .matmul import MatMul
        from .inverse import Inverse
        exp = self.exp
        if self.base.shape == (1, 1) and not exp.has(x):
            lr = self.base._eval_derivative_matrix_lines(x)
            for i in lr:
                subexpr = ExprBuilder(
                    ArrayContraction,
                    [
                        ExprBuilder(
                            ArrayTensorProduct,
                            [
                                Identity(1),
                                i._lines[0],
                                exp*self.base**(exp-1),
                                i._lines[1],
                                Identity(1),