def _test_all_null_solvers(solvers_to_test, S): for largest in [True, False]: Null_Space = {}; for eigen_solver in solvers_to_test: nullspace, errors = null_space(S, k = 3, eigen_solver = eigen_solver) Null_Space[eigen_solver] = nullspace # pairwise comparison: for i in range(len(solvers_to_test)): for j in range(i+1, len(solvers_to_test)): print largest print(str(solvers_to_test[i]) + " + " + str(solvers_to_test[j])) _check_with_col_sign_flipping(Null_Space[solvers_to_test[i]], Null_Space[solvers_to_test[j]], 0.05)
def ltsa(Geometry, n_components, eigen_solver='auto', tol=1e-6, max_iter=100,random_state=None): """ Perform a Locally Linear Embedding analysis on the data. Read more in the :ref:`User Guide <locally_linear_embedding>`. Parameters ---------- n_components : integer number of coordinates for the manifold. eigen_solver : {'auto', 'dense', 'arpack', 'lobpcg', or 'amg'} auto : algorithm will attempt to choose the best method for input data dense : use standard dense matrix operations for the eigenvalue decomposition. For this method, M must be an array or matrix type. This method should be avoided for large problems. arpack : use arnoldi iteration in shift-invert mode. For this method, M may be a dense matrix, sparse matrix, or general linear operator. Warning: ARPACK can be unstable for some problems. It is best to try several random seeds in order to check results. lobpcg : Locally Optimal Block Preconditioned Conjugate Gradient Method. a preconditioned eigensolver for large symmetric positive definite (SPD) generalized eigenproblems. amg : AMG requires pyamg to be installed. It can be faster on very large, sparse problems, but may also lead to instabilities. tol : float, optional Tolerance for 'arpack' method Not used if eigen_solver=='dense'. max_iter : integer maximum number of iterations for the arpack solver. random_state: numpy.RandomState or int, optional The generator or seed used to determine the starting vector for arpack iterations. Defaults to numpy.random. Returns ------- embedding : array-like, shape [n_samples, n_components] Embedding vectors. squared_error : float Reconstruction error for the embedding vectors. Equivalent to ``norm(Y - W Y, 'fro')**2``, where W are the reconstruction weights. References ---------- .. [1] `Zhang, Z. & Zha, H. Principal manifolds and nonlinear dimensionality reduction via tangent space alignment. Journal of Shanghai Univ. 8:406 (2004)` """ if Geometry.X is None: raise ValueError("Must pass data matrix X to Geometry") X = Geometry.X (N, d_in) = X.shape if eigen_solver not in ('auto', 'arpack', 'dense', 'amg', 'lobpcg'): raise ValueError("unrecognised eigen_solver '%s'" % eigen_solver) if n_components > d_in: raise ValueError("output dimension must be less than or equal " "to input dimension") # get the distance matrix and neighbors list distance_matrix = Geometry.get_distance_matrix() (rows, cols) = distance_matrix.nonzero() M_sparse = (eigen_solver != 'dense') if M_sparse: M = sparse.csr_matrix((N, N)) else: M = np.zeros((N, N)) for i in range(N): neighbors_i = cols[rows == i] n_neighbors_i = len(neighbors_i) use_svd = (n_neighbors_i > d_in) Xi = X[neighbors_i] Xi -= Xi.mean(0) # compute n_components largest eigenvalues of Xi * Xi^T if use_svd: v = svd(Xi, full_matrices=True)[0] else: Ci = np.dot(Xi, Xi.T) v = eigh(Ci)[1][:, ::-1] Gi = np.zeros((n_neighbors_i, n_components + 1)) Gi[:, 1:] = v[:, :n_components] Gi[:, 0] = 1. / np.sqrt(n_neighbors_i) GiGiT = np.dot(Gi, Gi.T) nbrs_x, nbrs_y = np.meshgrid(neighbors_i, neighbors_i) with warnings.catch_warnings(): # sparse will complain this is better with lil_matrix but it doesn't work warnings.simplefilter("ignore") M[nbrs_x, nbrs_y] -= GiGiT M[neighbors_i, neighbors_i] += 1 return null_space(M, n_components, k_skip=1, eigen_solver=eigen_solver, tol=tol, max_iter=max_iter, random_state=random_state)
def locally_linear_embedding(Geometry, n_components, reg=1e-3, max_iter=100, eigen_solver='auto', tol=1e-6, random_state=None): """ Perform a Locally Linear Embedding analysis on the data. Read more in the :ref:`User Guide <locally_linear_embedding>`. Parameters ---------- n_components : integer number of coordinates for the manifold. reg : float regularization constant, multiplies the trace of the local covariance matrix of the distances. eigen_solver : {'auto', 'dense', 'arpack', 'lobpcg', or 'amg'} auto : algorithm will attempt to choose the best method for input data dense : use standard dense matrix operations for the eigenvalue decomposition. For this method, M must be an array or matrix type. This method should be avoided for large problems. arpack : use arnoldi iteration in shift-invert mode. For this method, M may be a dense matrix, sparse matrix, or general linear operator. Warning: ARPACK can be unstable for some problems. It is best to try several random seeds in order to check results. lobpcg : Locally Optimal Block Preconditioned Conjugate Gradient Method. a preconditioned eigensolver for large symmetric positive definite (SPD) generalized eigenproblems. amg : AMG requires pyamg to be installed. It can be faster on very large, sparse problems, but may also lead to instabilities. tol : float, optional Tolerance for 'arpack' method Not used if eigen_solver=='dense'. max_iter : integer maximum number of iterations for the arpack solver. random_state: numpy.RandomState or int, optional The generator or seed used to determine the starting vector for arpack iterations. Defaults to numpy.random. Geometry : a Geometry object from Mmani.geometry.geometry Returns ------- Y : array-like, shape [n_samples, n_components] Embedding vectors. squared_error : float Reconstruction error for the embedding vectors. Equivalent to ``norm(Y - W Y, 'fro')**2``, where W are the reconstruction weights. References ---------- .. [1] `Roweis, S. & Saul, L. Nonlinear dimensionality reduction by locally linear embedding. Science 290:2323 (2000).` """ if eigen_solver not in ('auto', 'arpack', 'dense', 'amg', 'lobpcg'): raise ValueError("unrecognized eigen_solver '%s'" % eigen_solver) if Geometry.X is None: raise ValueError("Must pass data matrix X to Geometry") X = Geometry.X M_sparse = (eigen_solver != 'dense') W = barycenter_graph(Geometry.get_distance_matrix(), X, reg=reg) # we'll compute M = (I-W)'(I-W) # depending on the solver, we'll do this differently if M_sparse: M = eye(*W.shape, format=W.format) - W M = (M.T * M).tocsr() else: M = (W.T * W - W.T - W).toarray() M.flat[::M.shape[0] + 1] += 1 # W = W - I = W - I return null_space(M, n_components, k_skip=1, eigen_solver=eigen_solver, tol=tol, max_iter=max_iter, random_state=random_state)