code: def active_set_nnls(Utm, UtU, x=None, n_iter_max=100, tol=10e-8):
      """
      Active set algorithm for non-negative least square solution.
  
      Computes an approximate non-negative solution for Ux=m linear system.
  
      Parameters
      ----------
      Utm : vectorized ndarray
         Pre-computed product of the transposed of U and m
      UtU : ndarray
         Pre-computed Kronecker product of the transposed of U and U
      x : init
         Default: None
      n_iter_max : int
          Maximum number of iteration
          Default: 100
      tol : float
          Early stopping criterion
  
      Returns
      -------
      x : ndarray
  
      Notes
      -----
      This function solves following problem:
      .. math::
         \\begin{equation}
              \\min_{x} ||Ux - m||^2
         \\end{equation}
  
      According to [1], non-negativity-constrained least square estimation problem becomes:
      .. math::
         \\begin{equation}
              x' = (Utm) - (UTU)\\times x
         \\end{equation}
  
      Reference
      ----------
      [1] : Bro, R., & De Jong, S. (1997). A fast non‐negativity‐constrained
            least squares algorithm. Journal of Chemometrics: A Journal of
            the Chemometrics Society, 11(5), 393-401.
      """
      if tl.get_backend() == "tensorflow":
          raise ValueError(
              "Active set is not supported with the tensorflow backend. Consider using fista method with tensorflow."
          )
  
      if x is None:
          x_vec = tl.zeros(tl.shape(UtU)[1], **tl.context(UtU))
      else:
          x_vec = tl.base.tensor_to_vec(x)
  
      x_gradient = Utm - tl.dot(UtU, x_vec)
      active_set = x_vec <= 0
      support_vec = tl.zeros(tl.shape(x_vec), **tl.context(x_vec))
  
      for iteration in range(n_iter_max):
          if iteration > 0 or tl.all(x_vec == 0):
              indice = tl.argmax(x_gradient)
              active_set = tl.index_update(
                  active_set, tl.index[indice], False
              )
          # To avoid singularity error when initial x exists
          try:
              passive_solution = tl.solve(
                  UtU[~active_set, :][:, ~active_set], Utm[~active_set]
              )
          # Start from zeros if solve is not achieved
          except:
              x_vec = tl.zeros(tl.shape(UtU)[1])
              support_vec = tl.zeros(
                  tl.shape(x_vec), **tl.context(x_vec)
              )
              active_set = x_vec <= 0
              if tl.any(active_set):
                  indice = tl.argmax(x_gradient)
                  active_set = tl.index_update(
                      active_set, tl.index[indice], False
                  )
              passive_solution = tl.solve(
                  UtU[~active_set, :][:, ~active_set], Utm[~active_set]
              )
  
          # Update support vector with passive solution
          support_vec = tl.zeros(
              tl.shape(support_vec), **tl.context(support_vec)
          )
          support_vec = tl.index_update(
              support_vec, ~active_set, passive_solution
          )
  
          # update support vector if it is necessary
          if tl.min(support_vec[~active_set]) <= 0:
              for _ in range(len(active_set)):
                  alpha = tl.min(
                      x_vec[~active_set][support_vec[~active_set] <= 0]
                      / (
                          x_vec[~active_set][
                              support_vec[~active_set] <= 0
                          ]
                          - support_vec[~active_set][
                              support_vec[~active_set] <= 0
                          ]
                      )
                  )
                  update = alpha * (support_vec - x_vec)
                  x_vec = x_vec + update
                  active_set = x_vec <= 0
                  passive_solution = tl.solve(
                      UtU[~active_set, :][:, ~active_set],
                      Utm[~active_set],
                  )
  
                  # Update support vector with passive solution
                  support_vec = tl.zeros(
                      tl.shape(support_vec), **tl.context(support_vec)
                  )
                  support_vec = tl.index_update(
                      support_vec, ~active_set, passive_solution
                  )
  
                  # Break if finished updating
                  if (
                      tl.all(active_set) != True
                      or tl.min(support_vec[~active_set]) > 0
                  ):
                      break
          # set x to s
          x_vec = tl.clip(support_vec, 0, tl.max(support_vec))
  
          # gradient update
          x_gradient = Utm - tl.dot(UtU, x_vec)
  
          if (
              tl.any(active_set) != True
              or tl.max(x_gradient[active_set]) <= tol
          ):
              break
  
      return x_vec
  
file_path: tensorly/tensorly/tenalg/proximal.py
imports: import tensorly
  import numpy
label_desc: Use image node_id 17 for calling a global function with example usage: active_set_nnls(Utm, UtU, x, n_iter_max, tol) and returns: x_vec