code: def randomised_parafac(
      tensor,
      rank,
      n_samples,
      n_iter_max=100,
      init="random",
      svd="truncated_svd",
      tol=10e-9,
      max_stagnation=20,
      return_errors=False,
      random_state=None,
      verbose=0,
      callback=None,
  ):
      """Randomised CP decomposition via sampled ALS [3]_
  
      Parameters
      ----------
      tensor : ndarray
      rank   : int
              number of components
      n_samples : int
                  number of samples per ALS step
      n_iter_max : int
                   maximum number of iteration
      init : {'svd', 'random'}, optional
      svd : str, default is 'truncated_svd'
          function to use to compute the SVD, acceptable values in tensorly.SVD_FUNS
      tol : float, optional
            tolerance: the algorithm stops when the variation in
            the reconstruction error is less than the tolerance
      max_stagnation: int, optional, default is 0
                      if not zero, the maximum allowed number
                      of iterations with no decrease in fit
      random_state : {None, int, np.random.RandomState}, default is None
      return_errors : bool, default is False
          if True, return a list of all errors
      verbose : int, optional, default is 0
          level of verbosity
  
      Returns
      -------
      factors : ndarray list
              list of positive factors of the CP decomposition
              element `i` is of shape ``(tensor.shape[i], rank)``
  
      References
      ----------
      .. [3] Casey Battaglino, Grey Ballard and Tamara G. Kolda,
             "A Practical Randomized CP Tensor Decomposition",
      """
      rank = validate_cp_rank(tl.shape(tensor), rank=rank)
  
      if return_errors:
          DeprecationWarning(
              "return_errors argument will be removed in the next version of TensorLy. Please use a callback function instead."
          )
  
      rng = tl.check_random_state(random_state)
      weights, factors = initialize_cp(
          tensor, rank, init=init, svd=svd, random_state=random_state
      )
      rec_errors = []
      n_dims = tl.ndim(tensor)
      norm_tensor = tl.norm(tensor, 2)
      min_error = 0
  
      weights = tl.ones(rank, **tl.context(tensor))
  
      if callback is not None:
          rec_error = (
              tl.norm(tensor - cp_to_tensor((weights, factors)), 2)
              / norm_tensor
          )
  
          callback(CPTensor((weights, factors)))
  
      for iteration in range(n_iter_max):
          for mode in range(n_dims):
              kr_prod, indices_list = sample_khatri_rao(
                  factors, n_samples, skip_matrix=mode, random_state=rng
              )
              indices_list = [i.tolist() for i in indices_list]
              # Keep all the elements of the currently considered mode
              indices_list.insert(mode, slice(None, None, None))
              indices_list = tuple(indices_list)
              if mode:
                  sampled_unfolding = tensor[indices_list]
              else:
                  sampled_unfolding = tl.transpose(tensor[indices_list])
  
              pseudo_inverse = tl.dot(tl.transpose(kr_prod), kr_prod)
              factor = tl.dot(tl.transpose(kr_prod), sampled_unfolding)
              factor = tl.transpose(tl.solve(pseudo_inverse, factor))
              factors[mode] = factor
  
          if max_stagnation or tol or (callback is not None):
              rec_error = (
                  tl.norm(tensor - cp_to_tensor((weights, factors)), 2)
                  / norm_tensor
              )
  
          if callback is not None:
              retVal = callback(CPTensor((weights, factors)), rec_error)
              if retVal is True:
                  if verbose:
                      print(
                          "Received True from callback function. Exiting."
                      )
                  break
  
          if max_stagnation or tol:
              if not min_error or rec_error < min_error:
                  min_error = rec_error
                  stagnation = -1
              stagnation += 1
  
              rec_errors.append(rec_error)
  
              if iteration > 1:
                  if verbose:
                      print(
                          f"reconstruction error={rec_errors[-1]}, variation={rec_errors[-2]-rec_errors[-1]}."
                      )
  
                  if (
                      tol and abs(rec_errors[-2] - rec_errors[-1]) < tol
                  ) or (stagnation and (stagnation > max_stagnation)):
                      if verbose:
                          print(f"converged in {iteration} iterations.")
                      break
  
      if return_errors:
          return CPTensor((weights, factors)), rec_errors
      else:
          return CPTensor((weights, factors))
  
imports: import numpy
  import warnings
  import tensorly
  from ._base_decomposition import DecompositionMixin
  from ..random import random_cp
  from ..base import unfold
  from ..cp_tensor import cp_to_tensor, CPTensor, cp_norm, cp_normalize, validate_cp_rank
  from ..tenalg.svd import svd_interface
  from ..tenalg import unfolding_dot_khatri_rao
label_desc: Use image node_id 6 for calling a global function with example usage: randomised_parafac(tensor, rank, n_samples, n_iter_max, init, svd, tol, max_stagnation, return_errors, random_state, verbose, callback) and returns: CPTensor,  rec_errors, CPTensor