code: def set_XY(self, X=None, Y=None):
          
          self.update_model(False)
          if Y is not None:
              if self.normalizer is not None:
                  self.normalizer.scale_by(Y)
                  self.Y_normalized = ObsAr(self.normalizer.normalize(Y))
                  self.Y = Y
              else:
                  self.Y = ObsAr(Y)
                  self.Y_normalized = self.Y
          if X is not None:
              if self.X in self.parameters:
                  # LVM models
                  if isinstance(self.X, VariationalPosterior):
                      assert isinstance(X, type(self.X)), "The given X must have the same type as the X in the model!"
                      index = self.X._parent_index_
                      self.unlink_parameter(self.X)
                      self.X = X
                      self.link_parameter(self.X, index=index)
                  else:
                      index = self.X._parent_index_
                      self.unlink_parameter(self.X)
                      from ..core import Param
                      self.X = Param('latent mean', X)
                      self.link_parameter(self.X, index=index)
              else:
                  self.X = ObsAr(X)
          self.update_model(True)
docs: Set the input / output data of the model
          This is useful if we wish to change our existing data but maintain the same model
  
          :param X: input observations
          :type X: np.ndarray
          :param Y: output observations
          :type Y: np.ndarray