def __mul__(self, other):
        if getattr(other, 'is_Matrix', False):
            A = self
            B = other
            if A.cols != B.rows:
                raise ShapeError("Matrices size mismatch.")
            if A.cols == 0:
                return classof(A, B)._new(A.rows, B.cols, lambda i, j: 0)
            blst = B.T.tolist()
            alst = A.tolist()
            return classof(A, B)._new(A.rows, B.cols, lambda i, j:
                reduce(lambda k, l: k + l,
                    [a_ik * b_kj for a_ik, b_kj in zip(alst[i], blst[j])]))
        else:
            return self._new(self.rows, self.cols,
                [i*other for i in self._mat])
canonicalization of a tensor with respect to free indices
dataset/ETHPy150Open sympy/sympy/sympy/matrices/matrices.py/MatrixBase.__mul__--crossover with--dataset/ETHPy150Open sympy/sympy/sympy/combinatorics/tensor_can.py/canonical_free