docstr: N-mode product of a CP tensor and a matrix or vector at the
  specified mode.
  
  Parameters
  ----------
  cp_tensor
      ivy.CPTensor or (core, factors)
  
  matrix_or_vector
      1D or 2D array of shape ``(J, i_k)`` or ``(i_k, )``
      matrix or vectors to which to n-mode multiply the tensor
  mode : int
  
  Returns
  -------
  CPTensor = (core, factors)
      `mode`-mode product of `tensor` by `matrix_or_vector`
      * of shape :math:`(i_1, ..., i_{k-1}, J, i_{k+1}, ..., i_N)`
        if matrix_or_vector is a matrix
      * of shape :math:`(i_1, ..., i_{k-1}, i_{k+1}, ..., i_N)`
        if matrix_or_vector is a vector
  
  See Also
  --------
  cp_multi_mode_dot : chaining several mode_dot in one call
docstr_tok: ["N-mode","product","of","a","CP","tensor","and","a","matrix","or","vector","at","the","specified","mode",".","Parameters","--","--","--","--","--","cp_tensor","ivy.CPTensor","or","(","core",",","factors",")","matrix_or_vector","1D","or","2D","array","of","shape","``","(","J",",","i_k",")","``","or","``","(","i_k",",",")","``","matrix","or","vectors","to","which","to","n-mode","multiply","the","tensor","mode",":","int","Returns","--","--","--","-","CPTensor","=","(","core",",","factors",")","`","mode","`","-mode","product","of","`","tensor","`","by","`","matrix_or_vector","`","*","of","shape",":","math",":","`","(","i_1",",","...",",","i_","{","k-1","}",",","J",",","i_","{","k+1","}",",","...",",","i_N",")","`","if","matrix_or_vector","is","a","matrix","*","of","shape",":","math",":","`","(","i_1",",","...",",","i_","{","k-1","}",",","i_","{","k+1","}",",","...",",","i_N",")","`","if","matrix_or_vector","is","a","vector","See","Also","--","--","--","--","cp_multi_mode_dot",":","chaining","several","mode_dot","in","one","call"]
code: def cp_mode_dot(
      cp_tensor, matrix_or_vector, mode, keep_dim=False, copy=False
  ):
      """N-mode product of a CP tensor and a matrix or vector at the
      specified mode.
  
      Parameters
      ----------
      cp_tensor
          ivy.CPTensor or (core, factors)
  
      matrix_or_vector
          1D or 2D array of shape ``(J, i_k)`` or ``(i_k, )``
          matrix or vectors to which to n-mode multiply the tensor
      mode : int
  
      Returns
      -------
      CPTensor = (core, factors)
          `mode`-mode product of `tensor` by `matrix_or_vector`
          * of shape :math:`(i_1, ..., i_{k-1}, J, i_{k+1}, ..., i_N)`
            if matrix_or_vector is a matrix
          * of shape :math:`(i_1, ..., i_{k-1}, i_{k+1}, ..., i_N)`
            if matrix_or_vector is a vector
  
      See Also
      --------
      cp_multi_mode_dot : chaining several mode_dot in one call
      """
      shape, _ = ivy.CPTensor.validate_cp_tensor(cp_tensor)
      weights, factors = cp_tensor
      contract = False
  
      ndims = len(matrix_or_vector.shape)
      if ndims == 2:  # Tensor times matrix
          # Test for the validity of the operation
          if matrix_or_vector.shape[1] != shape[mode]:
              raise ValueError(
                  f"shapes {shape} and {matrix_or_vector.shape} not aligned in"
                  f" mode-{mode} multiplication: {shape[mode]} (mode {mode}) !="
                  f" {matrix_or_vector.shape[1]} (dim 1 of matrix)"
              )
  
      elif ndims == 1:  # Tensor times vector
          if matrix_or_vector.shape[0] != shape[mode]:
              raise ValueError(
                  f"shapes {shape} and {matrix_or_vector.shape} not aligned for"
                  f" mode-{mode} multiplication: {shape[mode]} (mode {mode}) !="
                  f" {matrix_or_vector.shape[0]} (vector size)"
              )
          if not keep_dim:
              contract = True  # Contract over that mode
      else:
          raise ValueError(
              "Can only take n_mode_product with a vector or a matrix."
          )
  
      if copy:
          factors = [ivy.copy_array(f) for f in factors]
          weights = ivy.copy_array(weights)
  
      if contract:
          factor = factors.pop(mode)
          factor = ivy.dot(matrix_or_vector, factor)
          mode = max(mode - 1, 0)
          factors[mode] *= factor
      else:
          factors[mode] = ivy.dot(matrix_or_vector, factors[mode])
  
      if copy:
          return CPTensor((weights, factors))
      else:
          cp_tensor.shape = tuple(f.shape[0] for f in factors)
          return cp_tensor
  
imports: from .base import FactorizedTensor
  import ivy
label_desc: Use image node_id 24 for calling the CPTensor obj's underlying member method code with example usage: obj.cp_mode_dot(cp_tensor, matrix_or_vector, mode, keep_dim, copy) and returns: CPTensor, cp_tensor