code: def cp_normalize(cp_tensor):
      """Returns cp_tensor with factors normalised to unit length
  
      Turns ``factors = [|U_1, ... U_n|]`` into ``[weights; |V_1, ... V_n|]``,
      where the columns of each `V_k` are normalized to unit Euclidean length
      from the columns of `U_k` with the normalizing constants absorbed into
      `weights`. In the special case of a symmetric tensor, `weights` holds the
      eigenvalues of the tensor.
  
      Parameters
      ----------
      cp_tensor : CPTensor = (weight, factors)
          factors is list of matrices, all with the same number of columns
          i.e.::
  
              for u in U:
                  u[i].shape == (s_i, R)
  
          where `R` is fixed while `s_i` can vary with `i`
  
      Returns
      -------
      CPTensor = (normalisation_weights, normalised_factors)
      """
      _, rank = _validate_cp_tensor(cp_tensor)
      weights, factors = cp_tensor
  
      if weights is None:
          weights = T.ones(rank, **T.context(factors[0]))
  
      normalized_factors = []
      for i, factor in enumerate(factors):
          if i == 0:
              factor = factor * weights
              weights = T.ones(rank, **T.context(factor))
  
          scales = T.norm(factor, axis=0)
          scales_non_zero = T.where(
              scales == 0,
              T.ones(T.shape(scales), **T.context(factor)),
              scales,
          )
          weights = weights * scales
          normalized_factors.append(
              factor / T.reshape(scales_non_zero, (1, -1))
          )
  
      return CPTensor((weights, normalized_factors))
  
imports: from .None import backend
  from .base import fold, tensor_to_vec
  from ._factorized_tensor import FactorizedTensor
  from .tenalg import khatri_rao, unfolding_dot_khatri_rao
  from .metrics.factors import congruence_coefficient
  import numpy
label_desc: Use image node_id 4 for calling a global function with example usage: cp_normalize(cp_tensor) and returns: CPTensor