<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def transform(self, X=None, t_max=100, plot_optimal_t=False, ax=None):
 """Computes the position of the cells in the embedding space Parameters X : array, optional, shape=[n_samples, n_features] input data with `n_samples` samples and `n_dimensions` dimensions. Not required, since PHATE does not currently embed cells not given in the input matrix to `PHATE.fit()`. Accepted data types: `numpy.ndarray`, `scipy.sparse.spmatrix`, `pd.DataFrame`, `anndata.AnnData`. If `knn_dist` is 'precomputed', `data` should be a n_samples x n_samples distance or affinity matrix t_max : int, optional, default: 100 maximum t to test if `t` is set to 'auto' plot_optimal_t : boolean, optional, default: False If true and `t` is set to 'auto', plot the Von Neumann entropy used to select t ax : matplotlib.axes.Axes, optional If given and `plot_optimal_t` is true, plot will be drawn on the given axis. Returns ------- embedding : array, shape=[n_samples, n_dimensions] The cells embedded in a lower dimensional space using PHATE """

        if self.graph is None:
            raise NotFittedError("This PHATE instance is not fitted yet. Call "
                                 "'fit' with appropriate arguments before "
                                 "using this method.")
        elif X is not None and not utils.matrix_is_equivalent(X, self.X):
            # fit to external data
            warnings.warn("Pre-fit PHATE cannot be used to transform a "
                          "new data matrix. Please fit PHATE to the new"
                          " data by running 'fit' with the new data.",
                          RuntimeWarning)
            if isinstance(self.graph, graphtools.graphs.TraditionalGraph) and \
                    self.graph.precomputed is not None:
                raise ValueError("Cannot transform additional data using a "
                                 "precomputed distance matrix.")
            else:
                transitions = self.graph.extend_to_data(X)
                return self.graph.interpolate(self.embedding,
                                              transitions)
        else:
            diff_potential = self.calculate_potential(
                t_max=t_max, plot_optimal_t=plot_optimal_t, ax=ax)
            if self.embedding is None:
                tasklogger.log_start("{} MDS".format(self.mds))
                self.embedding = mds.embed_MDS(
                    diff_potential, ndim=self.n_components, how=self.mds,
                    distance_metric=self.mds_dist, n_jobs=self.n_jobs,
                    seed=self.random_state, verbose=max(self.verbose - 1, 0))
                tasklogger.log_complete("{} MDS".format(self.mds))
            if isinstance(self.graph, graphtools.graphs.LandmarkGraph):
                tasklogger.log_debug("Extending to original data...")
                return self.graph.interpolate(self.embedding)
            else:
                return self.embedding