code: def tucker(
      x: Union[ivy.Array, ivy.NativeArray],
      rank: Optional[Sequence[int]] = None,
      /,
      *,
      fixed_factors: Optional[Sequence[int]] = None,
      n_iter_max: Optional[int] = 100,
      init: Optional[
          Union[Literal["svd", "random"], ivy.TuckerTensor]
      ] = "svd",
      svd: Optional[Literal["truncated_svd"]] = "truncated_svd",
      seed: Optional[int] = None,
      mask: Optional[Union[ivy.Array, ivy.NativeArray]] = None,
      svd_mask_repeats: Optional[int] = 5,
      tol: Optional[float] = 10e-5,
      verbose: Optional[bool] = False,
      return_errors: Optional[bool] = False,
  ):
      """Tucker decomposition via Higher Order Orthogonal Iteration (HOI)
  
          Decomposes `tensor` into a Tucker decomposition:
          ``tensor = [| core; factors[0], ...factors[-1] |]`` [1]_
  
      Parameters
      ----------
      x
          input tensor
      rank
          size of the core tensor, ``(len(ranks) == tensor.ndim)``
          if int, the same rank is used for all modes
      fixed_factors
          if not None, list of modes for which to keep the factors fixed.
          Only valid if a Tucker tensor is provided as init.
      n_iter_max
          maximum number of iteration
      init
          {'svd', 'random'}, or TuckerTensor optional
          if a TuckerTensor is provided, this is used for initialization
      svd
          str, default is 'truncated_svd'
          function to use to compute the SVD,
      seed
          Used to create a random seed distribution
          when init == 'random'
      mask
          array of booleans with the same shape as ``tensor`` should be 0 where
          the values are missing and 1 everywhere else. Note:  if tensor is
          sparse, then mask should also be sparse with a fill value of 1 (or
          True).
      svd_mask_repeats
          number of iterations for imputing the values in the SVD matrix when
          mask is not None
      tol
            tolerance: the algorithm stops when the variation in
            the reconstruction error is less than the tolerance
      verbose
          if True, different in reconstruction errors are returned at each
          iteration.
  
      return_errors
          Indicates whether the algorithm should return all reconstruction errors
          and computation time of each iteration or not
          Default: False
  
      Returns
      -------
          ivy.TuckerTensor or ivy.TuckerTensor and
          list of reconstruction errors if return_erros is True.
  
      References
      ----------
      .. [1] tl.G.Kolda and B.W.Bader, "Tensor Decompositions and Applications",
         SIAM REVIEW, vol. 51, n. 3, pp. 455-500, 2009.
      """
      if fixed_factors:
          try:
              (core, factors) = init
          except ValueError as e:
              raise ValueError(
                  f"Got fixed_factor={fixed_factors} but no appropriate Tucker tensor was"
                  ' passed for "init".'
              ) from e
          if len(fixed_factors) == len(factors):
              return ivy.TuckerTensor((core, factors))
  
          fixed_factors = sorted(fixed_factors)
          modes_fixed, factors_fixed = zip(
              *[
                  (i, f)
                  for (i, f) in enumerate(factors)
                  if i in fixed_factors
              ]
          )
          core = multi_mode_dot(core, factors_fixed, modes=modes_fixed)
          modes, factors = zip(
              *[
                  (i, f)
                  for (i, f) in enumerate(factors)
                  if i not in fixed_factors
              ]
          )
          init = (core, list(factors))
  
          rank = ivy.TuckerTensor.validate_tucker_rank(
              x.shape, rank=rank
          )
          (core, new_factors), rec_errors = partial_tucker(
              x,
              rank,
              modes,
              n_iter_max=n_iter_max,
              init=init,
              svd=svd,
              tol=tol,
              seed=seed,
              mask=mask,
              verbose=verbose,
              svd_mask_repeats=svd_mask_repeats,
              return_errors=True,
          )
  
          factors = list(new_factors)
          for i, e in enumerate(fixed_factors):
              factors.insert(e, factors_fixed[i])
          core = multi_mode_dot(
              core, factors_fixed, modes=modes_fixed, transpose=True
          )
  
          if return_errors:
              return ivy.TuckerTensor((core, factors)), rec_errors
          return ivy.TuckerTensor((core, factors))
  
      else:
          modes = list(range(len(x.shape)))
          rank = ivy.TuckerTensor.validate_tucker_rank(
              x.shape, rank=rank
          )
  
          (core, factors), rec_errors = partial_tucker(
              x,
              rank,
              modes,
              n_iter_max=n_iter_max,
              init=init,
              svd=svd,
              tol=tol,
              seed=seed,
              mask=mask,
              verbose=verbose,
              return_errors=True,
          )
          if return_errors:
              return ivy.TuckerTensor((core, factors)), rec_errors
          else:
              return ivy.TuckerTensor((core, factors))
  
imports: import logging
  from typing import Union, Optional, Tuple, List, Sequence, Literal
  import ivy
  from ivy.utils.backend import current_backend
  from ivy.func_wrapper import to_native_arrays_and_back, handle_out_argument, handle_nestable, handle_array_like_without_promotion, handle_array_function, handle_device, inputs_to_ivy_arrays, handle_backend_invalid
  from ivy.utils.exceptions import handle_exceptions
label_desc: Use image node_id 24 for calling a global function with example usage: tucker() and returns: ivy, ivy, ivy,  rec_errors, ivy,  rec_errors, ivy