code: def test_multi_mode_dot():
      """Test for multi_mode_dot
  
      Notes
      -----
      First a numerical test (ie compute by hand and check)
      Then use that the following expressions are equivalent:
  
      * X x_1 U_1 x ... x_n U_n
      * U_1 x unfold(X, 1) x kronecker(U_2, ..., U_n).T
      * U_1 x unfold(X x_2 U_2 x ... x_n U_n)
      """
      X = T.tensor([[1, 2], [0, -1]])
      U = [T.tensor([2, 1]), T.tensor([-1, 1])]
      true_res = T.tensor([1])
      res = multi_mode_dot(X, U, [0, 1])
      assert_array_equal(true_res, res)
  
      X = T.tensor(np.arange(12, dtype=float).reshape((3, 4)))
      U = T.tensor(np.random.random((3, 5)))
      res_1 = multi_mode_dot(X, [U], modes=[0], transpose=True)
      res_2 = T.dot(T.transpose(U), X)
      assert_array_almost_equal(res_1, res_2)
  
      dims = [2, 3, 4, 5]
      X = T.tensor(np.random.randn(*dims))
      factors = [
          T.tensor(np.random.rand(dims[i], X.shape[i]))
          for i in range(T.ndim(X))
      ]
      true_res = T.dot(
          T.dot(factors[0], unfold(X, 0)),
          T.transpose(kronecker(factors[1:])),
      )
      n_mode_res = multi_mode_dot(X, factors)
      assert_array_almost_equal(
          true_res, unfold(n_mode_res, 0), decimal=5
      )
      for i in range(T.ndim(X)):
          indices = [j for j in range(T.ndim(X)) if j != i]
          sub_factors = [factors[j] for j in indices]
          true_res = T.dot(
              T.dot(factors[i], unfold(X, i)),
              T.transpose(kronecker(sub_factors)),
          )
          res = unfold(n_mode_res, i)
          temp = multi_mode_dot(X, sub_factors, modes=indices)
          res2 = T.dot(factors[i], unfold(temp, i))
          assert_equal(
              true_res.shape,
              res.shape,
              err_msg=f"shape should be {true_res.shape}, is {res.shape}",
          )
          assert_array_almost_equal(true_res, res, decimal=5)
          assert_array_almost_equal(true_res, res2, decimal=5)
  
      # Test skipping a factor
      dims = [2, 3, 4, 5]
      X = T.tensor(np.random.randn(*dims))
      factors = [
          T.tensor(np.random.rand(dims[i], X.shape[i]))
          for i in range(T.ndim(X))
      ]
      res_1 = multi_mode_dot(X, factors, skip=1)
      res_2 = multi_mode_dot(
          X, [factors[0]] + factors[2:], modes=[0, 2, 3]
      )
      assert_array_equal(res_1, res_2)
  
      # Test contracting with a vector
      shape = (3, 5, 4, 2)
      X = T.ones(shape)
      vecs = [T.ones(s) for s in shape]
      res = multi_mode_dot(X, vecs)
      # result should be a scalar
      assert_equal(T.shape(res), ())
      assert_array_almost_equal(res, np.prod(shape))
  
      # Average pooling each mode
      # Order should not matter
      vecs = [vecs[i] / s for i, s in enumerate(shape)]
      for modes in itertools.permutations(range(len(shape))):
          res = multi_mode_dot(X, [vecs[i] for i in modes], modes=modes)
          assert_equal(T.shape(res), ())
          assert_array_almost_equal(res, 1)
  
file_path: tensorly/tensorly/tenalg/tests/test_n_mode_product.py
imports: import itertools
  import numpy
  from ...None import backend
  from ...testing import assert_array_equal, assert_equal, assert_array_almost_equal, assert_raises
  from ...base import fold, unfold
  from ..None import kronecker
  from ..None import mode_dot, multi_mode_dot
label_desc: Use image node_id 2 for calling a global function with example usage: test_multi_mode_dot() without return types