code: def validate_tr_tensor(factors):
      n_factors = len(factors)
  
      if n_factors < 2:
          raise ValueError(
              "A Tensor Ring tensor should be composed of at least two factors."
              f"However, {n_factors} factor was given."
          )
  
      rank = []
      shape = []
      next_rank = None
      for index, factor in enumerate(factors):
          current_rank, current_shape, next_rank = ivy.shape(factor)
  
          # Check that factors are third order tensors
          if len(factor.shape) != 3:
              raise ValueError(
                  "TR expresses a tensor as third order factors (tr-cores).\n"
                  f"However, ivy.ndim(factors[{index}]) = {len(factor.shape)}"
              )
  
          # Consecutive factors should have matching ranks
          if ivy.shape(factors[index - 1])[2] != current_rank:
              raise ValueError(
                  "Consecutive factors should have matching ranks\n -- e.g."
                  " ivy.shape(factors[0])[2]) == ivy.shape(factors[1])[0])\nHowever,"
                  f" ivy.shape(factor[{index-1}])[2] =="
                  f" {ivy.shape(factors[index-1])[2]} but"
                  f" ivy.shape(factor[{index}])[0] == {current_rank}"
              )
  
          shape.append(current_shape)
          rank.append(current_rank)
  
      # Add last rank (boundary condition)
      rank.append(next_rank)
  
      return tuple(shape), tuple(rank)
  
imports: from .base import FactorizedTensor
  import ivy
  import warnings
label_desc: Use image node_id 11 for calling the TRTensor obj's underlying member method code with example usage: obj.validate_tr_tensor(factors) and returns: tuple,  tuple