def fit(self, X=None, u=None, s = None):
        """Fit X into an embedded space.
        Inputs
        ----------
        X : array, shape (n_samples, n_features)
        u,s,v : svd decomposition of X (optional)

        Assigns
        ----------
        embedding : array-like, shape (n_samples, n_components)
            Stores the embedding vectors.
        u,sv,v : singular value decomposition of data S, potentially with smoothing
        isort1 : sorting along first dimension of matrix
        isort2 : sorting along second dimension of matrix (if n_Y > 0)
        cmap: correlation of each item with all locations in the embedding map (before upsampling)
        A:    PC coefficients of each Fourier mode

        """
        X = X.copy()
        if self.mode is 'parallel':
            Xall = X.copy()
            X = np.reshape(Xall.copy(), (-1, Xall.shape[-1]))
        #X -= X.mean(axis=-1)[:,np.newaxis]
        if ((u is None)):
            # compute svd and keep iPC's of data
            nmin = min([X.shape[0], X.shape[1]])
            nmin = np.minimum(nmin-1, self.nPC)
            u,sv,v = svdecon(np.float64(X), k=nmin)
            u = u * sv

        NN, self.nPC = u.shape
        # first smooth in Y (if n_Y > 0)
        self.u = u

        if self.mode is 'parallel':
            NN = Xall.shape[1]
            X = np.zeros((2, NN, u.shape[1]), 'float64')
            for j in range(2):
                Xall[j] -= Xall[j].mean(axis=-1)[:, np.newaxis]
                X[j] = Xall[j] @ self.v

        utu = np.sum(u**2, axis=1)
        ikeep = np.argmax(utu)
        #ikeep = int(NN/2)
        #ikeep = np.random.randint(0, NN)
        ccu = u @ u[ikeep,:]
        cmax = np.maximum(0, ccu)**2/utu
        ikeep = np.argsort(cmax)[::-1]
        ikeep = ikeep[:int(NN/10)]
        ikeep = np.sort(ikeep)

        if self.init == 'pca':
            U = svdecon(u[ikeep,:], k=2)[0]
            #U = u[ikeep, :2]
            usort = U * np.sign(skew(U, axis=0))
            init_sort = np.argsort(usort[:, :self.n_components], axis=0)
        elif self.init == 'random':
            init_sort = np.random.permutation(len(ikeep))[:,np.newaxis]
            for j in range(1,self.n_components):
                init_sort = np.concatenate((init_sort, np.random.permutation(len(ikeep))[:,np.newaxis]), axis=-1)
        else:
            init_sort = self.init
        if self.n_components==1 and init_sort.ndim==1:
            init_sort = init_sort[:,np.newaxis]

        # now sort in X
        isort1, iclustup = self._map(u.copy(), self.n_components, self.n_X, init_sort, ikeep,  s)
        self.isort = isort1
        self.embedding = iclustup
        return self
Fit X into an embedded space.
        Inputs
        ----------
        X : array, shape (n_samples, n_features)
        u,s,v : svd decomposition of X (optional)

        Assigns
        ----------
        embedding : array-like, shape (n_samples, n_components)
            Stores the embedding vectors.
        u,sv,v : singular value decomposition of data S, potentially with smoothing
        isort1 : sorting along first dimension of matrix
        isort2 : sorting along second dimension of matrix (if n_Y > 0)
        cmap: correlation of each item with all locations in the embedding map (before upsampling)
        A:    PC coefficients of each Fourier mode