⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fiedler.m

📁 This toolbox contains Matlab code for several graph and mesh partitioning methods, including geometr
💻 M
字号:
function [x,lambda] = fiedler(G,k,verbose);% FIEDLER : Fiedler vector of a graph.%% x = fiedler(G)  returns the eigenvector corresponding to %                 the second-smallest eigenvalue of the laplacian matrix %                 of the graph whose adjacency matrix is G|G'.%                 (If G is connected this is the smallest positive eval.)% [x,lambda] = fiedler(G)  also returns the eigenvalue.% [x,lambda] = fiedler(G,k) returns the k smallest nonzero eigenvalues%                 and their eigenvectors.% [x,lambda] = fiedler(G,k,verbose) prints some trace information:%                 verbose = 0 for none, 1 for some, 2 for more.%% If G is full or smaller than 100 vertices we use Matlab's full "eig";% if G is sparse we use an iterative method.% This is *not* an efficient implementation, it's just for playing with% small examples.%% See also LAPLACIAN, SPECPART.%% John Gilbert  2 February 1994% Copyright (c) 1990-1996 by Xerox Corporation.  All rights reserved.% HELP COPYRIGHT for complete copyright and licensing notice.if nargin < 3, verbose = 0; end;babble = verbose > 1;if nargin < 2, k = 1; end;[n,n] = size(G);if n < 100,     G = full(G); end;comp = components(G);if max(comp) > 1  % Add edges to connect the graph.    if verbose        disp('Fiedler:  Graph is disconnected.  Adding edges.');        [x,ignore] = hist(comp,max(comp));        Sizes = x    end;    for c = 1:max(comp)        i(c) = min(find(comp==c));    end;    S = sparse(i(1),i(2:max(comp)),1,n,n);    G = G | (S | S');end;L = laplacian(G);if babble    if issparse(L), ss = 'sparse'; else ss = 'full'; end;    fprintf(1,'Fiedler: %d vertices, %d edges, %s adjacency matrix.\n',...               n, (nnz(L)-n)/2, ss);end;if issparse(G)    x = ones(n,1)/sqrt(n);    lambda = 1;    shift = -eps^.25;    I = speye(n);    p = symmmd(L);    L = L(p,p);    R = chol(L-shift*I);    Rt = R';    for j = 1:k        if verbose            disp(['Eigenvector u' int2str(j+1) '...']);        end;        % Append the j+1'st eigenvector to x.            % Use a few power iterations with a small negative shift first.        if babble, fprintf(1,'Starting %d power iterations.\n',20*j);end;        y = rand(n,1);        y = y - x*(x'*y);        for i = 1:20*j            y = R\(Rt\y);            y = y - x*(x'*y);            y = y/norm(y);        end;        % Now use Rayleigh quotient iteration with a variable shift.        if babble, disp('Starting Rayleigh quotient iterations.');end;        tol = eps^.25;        maxiter = 10;        iteration = 0;        done = 0;        while ~done,            iteration = iteration+1;            estimate = y'*L*y;            if babble, iteration, end;            if babble, estimate, end;            newy = (L - estimate*I) \ y;            if any(isnan(newy)|isinf(newy))                if verbose                    disp(['Rayleigh iteration halted at iteration ' ...                    int2str(iteration)]);                end;                done = 1;            else                newy = newy/norm(newy);                measure = norm(newy-y)*norm(newy+y);                done = measure < tol;                y = newy;            end;            % Project y to be orthogonal to earlier eigenvectors.            y = y - x*(x'*y);            y = y/norm(y);            if iteration == maxiter                done = 1;                disp('Rayleigh iteration reached maxiter.');            end        end;        x = [x y];        lambda = [lambda estimate];    end;    x = x(:,2:k+1);    x(p,:) = x;    lambda = lambda(2:k+1);else    % Full graph -- just use eig.    [V,D] = eig(L);    [d,i] = sort(diag(D));    lambda = d(2:k+1);    x = V(:,i(2:k+1));end;if babble, lambda, end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -