class_docstr: CP tensor regression
  
  Learns a low rank CP tensor weight, This performs a partial least square regression to a tensor X (>= 2 modes)
  against a matrix Y. The first modes of X and Y will be considered coupled, and the decomposition will maximize
  the covariance between them.
  
  Parameters
  ----------
  n_components : int
      rank of the CP decomposition of the regression weights
  tol : float
      convergence value
  n_iter_max : int, optional, default is 100
      maximum number of iteration
  random_state : None, int or RandomState, optional, default is None
  verbose : bool, default is False
      whether to be verbose during fitting
  
  References
  ----------
  .. [1] Rasmus Bro, "Multiway calibration. Multilinear PLS", Chemometrics, 1996
class_docstr_tok: ["CP","tensor","regression","Learns","a","low","rank","CP","tensor","weight",",","This","performs","a","partial","least","square","regression","to","a","tensor","X","(",">","=","2","modes",")","against","a","matrix","Y",".","The","first","modes","of","X","and","Y","will","be","considered","coupled",",","and","the","decomposition","will","maximize","the","covariance","between","them",".","Parameters","--","--","--","--","--","n_components",":","int","rank","of","the","CP","decomposition","of","the","regression","weights","tol",":","float","convergence","value","n_iter_max",":","int",",","optional",",","default","is","100","maximum","number","of","iteration","random_state",":","None",",","int","or","RandomState",",","optional",",","default","is","None","verbose",":","bool",",","default","is","False","whether","to","be","verbose","during","fitting","References","--","--","--","--","--","..","[","1","]","Rasmus","Bro",",","``","Multiway","calibration",".","Multilinear","PLS","''",",","Chemometrics",",","1996"]
docstr: Apply the dimension reduction from fitting to a new tensor.
  
  Parameters
  ----------
  X : array-like of shape (n_samples, n_features)
      Samples to transform.
  Y : array-like of shape (n_samples, n_targets), default=None
      Target vectors.
  
  Returns
  -------
  X_scores, Y_scores : array-like or tuple of array-like
      Return `X_scores` if `Y` is not given, `(X_scores, Y_scores)` otherwise.
docstr_tok: ["Apply","the","dimension","reduction","from","fitting","to","a","new","tensor",".","Parameters","--","--","--","--","--","X",":","array-like","of","shape","(","n_samples",",","n_features",")","Samples","to","transform",".","Y",":","array-like","of","shape","(","n_samples",",","n_targets",")",",","default=None","Target","vectors",".","Returns","--","--","--","-","X_scores",",","Y_scores",":","array-like","or","tuple","of","array-like","Return","`","X_scores","`","if","`","Y","`","is","not","given",",","`","(","X_scores",",","Y_scores",")","`","otherwise","."]
code: def transform(self, X, Y=None):
      """Apply the dimension reduction from fitting to a new tensor.
  
      Parameters
      ----------
      X : array-like of shape (n_samples, n_features)
          Samples to transform.
      Y : array-like of shape (n_samples, n_targets), default=None
          Target vectors.
  
      Returns
      -------
      X_scores, Y_scores : array-like or tuple of array-like
          Return `X_scores` if `Y` is not given, `(X_scores, Y_scores)` otherwise.
      """
      if self.X_shape_[1:] != T.shape(X)[1:]:
          raise ValueError(
              f"Training X has shape {self.X_shape_}, while the new X has shape {T.shape(X)}"
          )
      X = T.copy(X)
      X -= self.X_mean_
      X_scores = T.zeros(
          (T.shape(X)[0], self.n_components), **T.context(X)
      )
  
      for component in range(self.n_components):
          X_scores = T.index_update(
              X_scores,
              T.index[:, component],
              multi_mode_dot(
                  X,
                  [ff[:, component] for ff in self.X_factors[1:]],
                  range(1, T.ndim(X)),
              ),
          )
          X -= outer(
              [X_scores[:, component]]
              + [ff[:, component] for ff in self.X_factors[1:]],
          )
  
      if Y is not None:
          Y = T.copy(Y)
          # Check on the shape of Y
          if (T.ndim(Y) != 1) and (T.ndim(Y) != 2):
              raise ValueError(
                  "Only a matrix (2-mode tensor) Y is allowed."
              )
          if T.ndim(Y) == 1:
              Y = T.reshape(Y, (-1, 1))
          if self.Y_shape_[1:] != T.shape(Y)[1:]:
              raise ValueError(
                  f"Training Y has shape {self.Y_shape_}, while the new Y has shape {T.shape(Y)}"
              )
  
          Y -= self.Y_mean_
          Y_scores = T.zeros(
              (T.shape(Y)[0], self.n_components), **T.context(X)
          )
          for component in range(self.n_components):
              Y_scores = T.index_update(
                  Y_scores,
                  T.index[:, component],
                  T.dot(Y, self.Y_factors[1][:, component]),
              )
  
              Y -= T.dot(
                  T.dot(
                      X_scores,
                      T.reshape(self.coef_[:, component], (-1, 1)),
                  ),
                  T.reshape(self.Y_factors[1][:, component], (1, -1)),
              )
          return X_scores, Y_scores
  
      return X_scores
  
file_path: tensorly/tensorly/regression/cp_plsr.py
imports: from ..tenalg import multi_mode_dot, outer
  from ..None import backend
  from ..None import tensor_to_vec
  from ..decomposition._cp import initialize_cp
label_desc: Use image node_id 6 for calling the CP_PLSR obj's underlying member method code with example usage: obj.transform(X, Y) and returns: X_scores, X_scores,  Y_scores