class_docstr: A product of matrix expressions
  
  Examples
  ========
  
  >>> from sympy import MatMul, MatrixSymbol
  >>> A = MatrixSymbol('A', 5, 4)
  >>> B = MatrixSymbol('B', 4, 3)
  >>> C = MatrixSymbol('C', 3, 6)
  >>> MatMul(A, B, C)
  A*B*C
class_docstr_tok: ["A","product","of","matrix","expressions","Examples","========",">",">",">","from","sympy","import","MatMul",",","MatrixSymbol",">",">",">","A","=","MatrixSymbol","(","'","A","'",",","5",",","4",")",">",">",">","B","=","MatrixSymbol","(","'","B","'",",","4",",","3",")",">",">",">","C","=","MatrixSymbol","(","'","C","'",",","3",",","6",")",">",">",">","MatMul","(","A",",","B",",","C",")","A","*","B","*","C"]
code: def _entry(self, i, j, expand=True, **kwargs):
      # Avoid cyclic imports
      from sympy.concrete.summations import Sum
      from sympy.matrices.immutable import ImmutableMatrix
  
      coeff, matrices = self.as_coeff_matrices()
  
      if len(matrices) == 1:  # situation like 2*X, matmul is just X
          return coeff * matrices[0][i, j]
  
      indices = [None] * (len(matrices) + 1)
      ind_ranges = [None] * (len(matrices) - 1)
      indices[0] = i
      indices[-1] = j
  
      def f():
          counter = 1
          while True:
              yield Dummy("i_%i" % counter)
              counter += 1
  
      dummy_generator = kwargs.get("dummy_generator", f())
  
      for i in range(1, len(matrices)):
          indices[i] = next(dummy_generator)
  
      for i, arg in enumerate(matrices[:-1]):
          ind_ranges[i] = arg.shape[1] - 1
      matrices = [
          arg._entry(
              indices[i],
              indices[i + 1],
              dummy_generator=dummy_generator,
          )
          for i, arg in enumerate(matrices)
      ]
      expr_in_sum = Mul.fromiter(matrices)
      if any(v.has(ImmutableMatrix) for v in matrices):
          expand = True
      result = coeff * Sum(
          expr_in_sum,
          *zip(indices[1:-1], [0] * len(ind_ranges), ind_ranges),
      )
  
      # Don't waste time in result.doit() if the sum bounds are symbolic
      if not any(isinstance(v, (Integer, int)) for v in ind_ranges):
          expand = False
      return result.doit() if expand else result
  
imports: from sympy.assumptions.ask import ask, Q
  from sympy.assumptions.refine import handlers_dict
  from sympy.core import Basic, sympify, S
  from sympy.core.mul import mul, Mul
  from sympy.core.numbers import Number, Integer
  from sympy.core.symbol import Dummy
  from sympy.functions import adjoint
  from sympy.strategies import rm_id, unpack, typed, flatten, exhaust, do_one, new
  from sympy.matrices.exceptions import NonInvertibleMatrixError
  from sympy.matrices.matrixbase import MatrixBase
  from sympy.utilities.exceptions import sympy_deprecation_warning
  from sympy.matrices.expressions._shape import validate_matmul_integer
  from .inverse import Inverse
  from .matexpr import MatrixExpr
  from .matpow import MatPow
  from .transpose import transpose
  from .permutation import PermutationMatrix
  from .special import ZeroMatrix, Identity, GenericIdentity, OneMatrix
label_desc: Use image node_id 4 for calling the MatMul obj's underlying member method code with example usage: obj._entry(i, j, expand) and returns: unknown, unknown