code: def _parafac2_reconstruction_error(
      tensor_slices,
      decomposition,
      norm_matrices=None,
      projected_tensor=None,
  ):
      """Calculates the reconstruction error of the PARAFAC2 decomposition. This implementation
      uses the inner product with each matrix for efficiency, as this avoids needing to
      reconstruct the tensor. This is based on the property that:
  
      .. math::
  
          ||tensor - rec||^2 = ||tensor||^2 + ||rec||^2 - 2*<tensor, rec>
  
      Parameters
      ----------
      tensor_slices : ndarray or list of ndarrays
          The data itself. Either a third order tensor or a list of second order tensors that
          may have different number of rows.
      decomposition : (weight, factors, projection_matrices)
          * weights : 1D array of shape (rank, )
              weights of the (normalized) factors
          * factors : List of factors of the CP decomposition element `i` is of shape
              (tensor.shape[i], rank)
          * projections : List of projection matrices used to create evolving factors.
      norm_matrices : float, optional
          The norm of the data. This can be optionally provided to avoid recalculating it.
      projected_tensor : ndarray, optional
          The projections of X into an aligned tensor for CP decomposition. This can be optionally
          provided to avoid recalculating it.
  
      Returns
      -------
      error : float
          The norm of the reconstruction error of the PARAFAC2 decomposition.
      """
      _validate_parafac2_tensor(decomposition)
  
      if norm_matrices is None:
          norm_X_sq = sum(
              tl.norm(t_slice, 2) ** 2 for t_slice in tensor_slices
          )
      else:
          norm_X_sq = norm_matrices**2
  
      weights, (A, B, C), projections = decomposition
      if weights is not None:
          A = A * weights
  
      norm_cmf_sq = 0
      inner_product = 0
      CtC = tl.dot(tl.transpose(C), C)
  
      for i, t_slice in enumerate(tensor_slices):
          B_i = (projections[i] @ B) * A[i]
  
          if projected_tensor is None:
              tmp = tl.dot(tl.transpose(B_i), t_slice)
          else:
              tmp = (
                  tl.reshape(A[i], (-1, 1))
                  * tl.transpose(B)
                  @ projected_tensor[i]
              )
  
          inner_product += tl.trace(tl.dot(tmp, C))
  
          norm_cmf_sq += tl.sum((tl.transpose(B_i) @ B_i) * CtC)
  
      return tl.sqrt(norm_X_sq - 2 * inner_product + norm_cmf_sq)
  
imports: from warnings import warn
  from typing import Iterable
  import tensorly
  from ._base_decomposition import DecompositionMixin
  from tensorly.random import random_parafac2
  from tensorly import backend
  from .None import parafac, non_negative_parafac_hals
  from ..parafac2_tensor import Parafac2Tensor, _validate_parafac2_tensor
  from ..cp_tensor import CPTensor, cp_normalize
  from ..tenalg.svd import svd_interface
label_desc: Use image node_id 4 for calling a global function with example usage: _parafac2_reconstruction_error(tensor_slices, decomposition, norm_matrices, projected_tensor) and returns: tl