'Returns true if a matrix is diagonalizable.
Parameters
reals_only : bool. If reals_only=True, determine whether the matrix can be
diagonalized without complex numbers. (Default: False)
kwargs
clear_cache : bool. If True, clear the result of any computations when finished.
(Default: True)
Examples
>>> from sympy import Matrix
>>> m = Matrix(3, 3, [1, 2, 0, 0, 3, 0, 2, -4, 2])
>>> m
Matrix([
[1,  2, 0],
[0,  3, 0],
[2, -4, 2]])
>>> m.is_diagonalizable()
True
>>> m = Matrix(2, 2, [0, 1, 0, 0])
>>> m
Matrix([
[0, 1],
[0, 0]])
>>> m.is_diagonalizable()
False
>>> m = Matrix(2, 2, [0, 1, -1, 0])
>>> m
Matrix([
[ 0, 1],
[-1, 0]])
>>> m.is_diagonalizable()
True
>>> m.is_diagonalizable(reals_only=True)
False
See Also
is_diagonal
diagonalize'

def is_diagonalizable(self, reals_only=False, **kwargs):

    clear_cache = kwargs.get('clear_cache', True)
    if ('clear_subproducts' in kwargs):
        clear_cache = kwargs.get('clear_subproducts')
    def cleanup():
        'Clears    any    cached    values    if    requested'
        if clear_cache:
            self._cache_eigenvects = None
            self._cache_is_diagonalizable = None
    if (not self.is_square):
        cleanup()
        return False
    if (self._cache_is_diagonalizable is not None):
        ret = self._cache_is_diagonalizable
        cleanup()
        return ret
    if (all((e.is_real for e in self)) and self.is_symmetric()):
        self._cache_is_diagonalizable = True
        cleanup()
        return True
    self._cache_eigenvects = self.eigenvects(simplify=True)
    ret = True
    for (val, mult, basis) in self._cache_eigenvects:
        if (reals_only and (not val.is_real)):
            ret = False
        if (mult != len(basis)):
            ret = False
    cleanup()
    return ret
