code: def test_non_negative_parafac(
      monkeypatch,
      true_rank,
      rank,
      init,
      normalize_factors,
      random_state,
      hals,
  ):
      """Test for non-negative PARAFAC"""
      tol_norm_2 = 0.07
      tol_max_abs = 0.1
      shape = (6, 3, 12)
      rng = tl.check_random_state(random_state)
      cp_factors = random_cp(
          shape,
          rank=true_rank,
          full=False,
          random_state=rng,
          normalise_factors=normalize_factors,
      )
      cp_factors = CPTensor(
          (cp_factors[0], [tl.abs(f) for f in cp_factors[1]])
      )
      tensor = tl.cp_to_tensor(cp_factors)
  
      if hals:
          func = non_negative_parafac_hals
      else:
          func = non_negative_parafac
  
      nn_res, errors = func(
          tensor,
          rank=rank,
          n_iter_max=80,
          tol=1.0e-6,
          init=init,
          normalize_factors=normalize_factors,
          random_state=rng,
          return_errors=True,
      )
      assert_(np.all(np.diff(errors) <= 1.0e-3))
  
      # Make sure all components are positive
      _, nn_factors = nn_res
      for factor in nn_factors:
          assert_(T.all(factor >= 0))
  
      assert_(
          errors[-1] < tol_norm_2,
          "norm 2 of reconstruction higher than tol",
      )
  
      # Test the max abs difference between the reconstruction and the tensor
      nn_reconstructed_tensor = cp_to_tensor(nn_res)
      assert_(
          T.max(T.abs(tensor - nn_reconstructed_tensor)) < tol_max_abs,
          "abs norm of reconstruction error higher than tol",
      )
  
      # Test fixing mode 0 or 1 with given init
      rec_svd_fixed_mode_0 = func(
          tensor,
          rank=true_rank,
          n_iter_max=1,
          init=cp_factors,
          fixed_modes=[0],
      )
      rec_svd_fixed_mode_1 = func(
          tensor,
          rank=true_rank,
          n_iter_max=1,
          init=cp_factors,
          fixed_modes=[1],
      )
      # Check if modified after 2 iterations
      assert_array_equal(
          rec_svd_fixed_mode_0.factors[0],
          cp_factors.factors[0],
          err_msg="Fixed mode 0 was modified in candecomp_parafac",
      )
      assert_array_equal(
          rec_svd_fixed_mode_1.factors[1],
          cp_factors.factors[1],
          err_msg="Fixed mode 1 was modified in candecomp_parafac",
      )
  
      if hals:
          assert_class_wrapper_correctly_passes_arguments(
              monkeypatch,
              non_negative_parafac_hals,
              CP_NN_HALS,
              ignore_args={"return_errors"},
              rank=3,
          )
  
          # Regression test: used wrong variable for convergence checking
          # Used mttkrp*factor instead of mttkrp*factors[-1], which resulted in
          # error when mode 2 was not constrained and erroneous convergence checking
          # when mode 2 was constrained.
          tensor = tl.tensor(rng.random_sample((3, 3, 3)) + 1)
          non_negative_parafac_hals(
              tensor,
              rank=2,
              n_iter_max=2,
              tol=1e-10,
              init="svd",
              nn_modes={
                  0,
              },
              return_errors=True,
          )
      else:
          assert_class_wrapper_correctly_passes_arguments(
              monkeypatch,
              non_negative_parafac,
              CP_NN,
              ignore_args={"return_errors"},
              rank=3,
          )
  
imports: import numpy
  import pytest
  import tensorly
  from .._cp import parafac, initialize_cp, sample_khatri_rao, randomised_parafac, CP, RandomizedCP, CPTensor
  from .._nn_cp import non_negative_parafac, non_negative_parafac_hals, CP_NN, CP_NN_HALS
  from ...cp_tensor import cp_to_tensor
  from ...cp_tensor import cp_to_tensor
  from ...random import random_cp
  from ...tenalg import khatri_rao
  from ...None import backend
  from ...testing import assert_array_equal, assert_, assert_class_wrapper_correctly_passes_arguments, assert_array_almost_equal
  from ...metrics.factors import congruence_coefficient
label_desc: Use image node_id 4 for calling a global function with example usage: test_non_negative_parafac(monkeypatch, true_rank, rank, init, normalize_factors, random_state, hals) without return types