time | Calls | line |
---|
| | 1 | function [V, D, flag] = eigs(varargin)
|
| | 2 | % EIGS Find a few eigenvalues and eigenvectors of a matrix
|
| | 3 | % D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues.
|
| | 4 | % A must be square and should be large and sparse.
|
| | 5 | %
|
| | 6 | % [V,D] = EIGS(A) returns a diagonal matrix D of A's 6 largest magnitude
|
| | 7 | % eigenvalues and a matrix V whose columns are the corresponding
|
| | 8 | % eigenvectors.
|
| | 9 | %
|
| | 10 | % [V,D,FLAG] = EIGS(A) also returns a convergence flag. If FLAG is 0 then
|
| | 11 | % all the eigenvalues converged; otherwise not all converged.
|
| | 12 | %
|
| | 13 | % EIGS(A,B) solves the generalized eigenvalue problem A*V == B*V*D. B must
|
| | 14 | % be the same size as A. EIGS(A,[],...) indicates the standard eigenvalue
|
| | 15 | % problem A*V == V*D.
|
| | 16 | %
|
| | 17 | % EIGS(A,K) and EIGS(A,B,K) return the K largest magnitude eigenvalues.
|
| | 18 | %
|
| | 19 | % EIGS(A,K,SIGMA) and EIGS(A,B,K,SIGMA) return K eigenvalues. If SIGMA is:
|
| | 20 | %
|
| | 21 | % 'largestabs' or 'smallestabs' - largest or smallest magnitude
|
| | 22 | % 'largestreal' or 'smallestreal' - largest or smallest real part
|
| | 23 | % 'bothendsreal' - K/2 values with largest and
|
| | 24 | % smallest real part, respectively
|
| | 25 | % (one more from largest if K is odd)
|
| | 26 | %
|
| | 27 | % For nonsymmetric problems, SIGMA can also be:
|
| | 28 | % 'largestimag' or 'smallestimag' - largest or smallest imaginary part
|
| | 29 | % 'bothendsimag' - K/2 values with largest and
|
| | 30 | % smallest imaginary part, respectively
|
| | 31 | % (one more from largest if K is odd)
|
| | 32 | %
|
| | 33 | % If SIGMA is a real or complex scalar including 0, EIGS finds the
|
| | 34 | % eigenvalues closest to SIGMA.
|
| | 35 | %
|
| | 36 | % EIGS(A,K,SIGMA,NAME,VALUE) and EIGS(A,B,K,SIGMA,NAME,VALUE) configures
|
| | 37 | % additional options specified by one or more name-value pair arguments:
|
| | 38 | %
|
| | 39 | % 'IsFunctionSymmetric' - Symmetry of matrix applied by function handle Afun
|
| | 40 | % 'Tolerance' - Convergence tolerance
|
| | 41 | % 'MaxIterations - Maximum number of iterations
|
| | 42 | % 'SubspaceDimension' - Size of subspace
|
| | 43 | % 'StartVector' - Starting vector
|
| | 44 | % 'FailureTreatment' - Treatment of non-converged eigenvalues
|
| | 45 | % 'Display' - Display diagnostic messages
|
| | 46 | % 'IsCholesky' - B is actually its Cholesky factor
|
| | 47 | % 'CholeskyPermutation' - Cholesky vector input refers to B(perm,perm)
|
| | 48 | % 'IsSymmetricDefinite' - B is symmetric positive definite
|
| | 49 | %
|
| | 50 | % EIGS(A,K,SIGMA,OPTIONS) and EIGS(A,B,K,SIGMA,OPTIONS) alternatively
|
| | 51 | % configures the additional options using a structure. See the
|
| | 52 | % documentation for more information.
|
| | 53 | %
|
| | 54 | % EIGS(AFUN,N) and EIGS(AFUN,N,B) accept the function AFUN instead of the
|
| | 55 | % matrix A. AFUN is a function handle and Y = AFUN(X) should return
|
| | 56 | % A*X if SIGMA is unspecified, or a string other than 'SM'
|
| | 57 | % A\X if SIGMA is 0 or 'SM'
|
| | 58 | % (A-SIGMA*I)\X if SIGMA is a nonzero scalar (standard problem)
|
| | 59 | % (A-SIGMA*B)\X if SIGMA is a nonzero scalar (generalized problem)
|
| | 60 | % N is the size of A. The matrix A, A-SIGMA*I or A-SIGMA*B represented by
|
| | 61 | % AFUN is assumed to be nonsymmetric unless specified otherwise
|
| | 62 | % by OPTS.issym.
|
| | 63 | %
|
| | 64 | % EIGS(AFUN,N,...) is equivalent to EIGS(A,...) for all previous syntaxes.
|
| | 65 | %
|
| | 66 | % Example:
|
| | 67 | % A = delsq(numgrid('C',15)); d1 = eigs(A,5,'SM');
|
| | 68 | %
|
| | 69 | % Equivalently, if dnRk is the following one-line function:
|
| | 70 | % %----------------------------%
|
| | 71 | % function y = dnRk(x,R,k)
|
| | 72 | % y = (delsq(numgrid(R,k))) \ x;
|
| | 73 | % %----------------------------%
|
| | 74 | %
|
| | 75 | % n = size(A,1); opts.issym = 1;
|
| | 76 | % d2 = eigs(@(x)dnRk(x,'C',15),n,5,'SM',opts);
|
| | 77 | %
|
| | 78 | % See also EIG, SVDS, FUNCTION_HANDLE.
|
| | 79 |
|
| | 80 | % Copyright 1984-2018 The MathWorks, Inc.
|
| | 81 | % References:
|
| | 82 | % [1] Stewart, G.W., "A Krylov-Schur Algorithm for Large Eigenproblems."
|
| | 83 | % SIAM. J. Matrix Anal. & Appl., 23(3), 601-614, 2001.
|
| | 84 | % [2] Lehoucq, R.B. , D.C. Sorensen and C. Yang, ARPACK Users' Guide,
|
| | 85 | % Society for Industrial and Applied Mathematics, 1998
|
| | 86 |
|
| | 87 |
|
| | 88 | % Error check inputs and derive some information from them
|
0.011 | 1 | 89 | [A, n, B, k, Amatrix, eigsSigma, shiftAndInvert, cholB, permB, scaleB, spdB,...
|
| 1 | 90 | innerOpts, randStr, useEig, originalB] = checkInputs(varargin{:});
|
| | 91 |
|
< 0.001 | 1 | 92 | if ~useEig || ismember(innerOpts.method, {'LI', 'SI'})
|
| | 93 | % Determine whether B is HPD and do a Cholesky decomp if necessary
|
< 0.001 | 1 | 94 | [R, permB, spdB] = CHOLfactorB(B, cholB, permB, shiftAndInvert, spdB);
|
| | 95 |
|
| | 96 | % Final argument checking before call to algorithm
|
< 0.001 | 1 | 97 | [innerOpts, useEig, eigsSigma] = extraChecks(innerOpts, B, n, k, spdB, useEig, eigsSigma);
|
< 0.001 | 1 | 98 | end
|
| | 99 |
|
< 0.001 | 1 | 100 | if innerOpts.disp
|
| | 101 | displayInitialInformation(innerOpts, B, n, k, spdB, useEig, eigsSigma, shiftAndInvert, Amatrix);
|
| | 102 | end
|
| | 103 |
|
| | 104 | % We fall back on using the full EIG code if p is too large (size of
|
| | 105 | % subspace to build = size of whole problem)
|
| | 106 | % The K == 0 case is also handled here
|
< 0.001 | 1 | 107 | if useEig
|
| | 108 | if nargout <= 1
|
| | 109 | V = fullEig(A, B, n, k, cholB, permB, scaleB, eigsSigma);
|
| | 110 | else
|
| | 111 | [V, D] = fullEig(A, B, n, k, cholB, permB, scaleB, eigsSigma);
|
| | 112 | if strcmp(innerOpts.fail,'keep')
|
| | 113 | flag = false(k,1);
|
| | 114 | else
|
| | 115 | flag = 0;
|
| | 116 | end
|
| | 117 | end
|
| | 118 | return
|
| | 119 | end
|
| | 120 |
|
| | 121 | % Define the operations needed for Krylov Schur algorithm
|
0.081 | 1 | 122 | [applyOP, applyM] = getOps(A, B, n, spdB, shiftAndInvert, R, cholB, permB,...
|
| 1 | 123 | Amatrix, innerOpts);
|
| | 124 |
|
| | 125 | % Send variables to KS and run algorithm
|
0.063 | 1 | 126 | [V, d, isNotConverged, spdBout, VV] = KrylovSchur(applyOP, applyM, innerOpts, n, k,...
|
| 1 | 127 | shiftAndInvert, randStr, spdB);
|
| | 128 |
|
| | 129 | % Do some post processing of the output for generalized problem
|
< 0.001 | 1 | 130 | [V, d, isNotConverged] = postProcessing(V, d, isNotConverged, eigsSigma, B, scaleB, ...
|
| 1 | 131 | shiftAndInvert, R, permB, spdB, nargout);
|
| | 132 |
|
| | 133 |
|
| | 134 |
|
< 0.001 | 1 | 135 | if spdB && ~spdBout && ~any(isNotConverged)
|
| | 136 | % This happens if B is symmetric positive semi-definite, and the rank
|
| | 137 | % of B is not larger than the subspace dimension used in KrylovSchur.
|
| | 138 | % Project both A and B into the orthogonal subspace VV found in
|
| | 139 | % KrylovSchur, and apply EIG directly to this generalized problem.
|
| | 140 |
|
| | 141 | applyA = createApplyA(A, Amatrix);
|
| | 142 | applyB = createApplyB(originalB, originalB, cholB, permB);
|
| | 143 | Asmall = VV'*applyA(VV);
|
| | 144 | if innerOpts.ishermprob
|
| | 145 | Asmall = (Asmall + Asmall')/2;
|
| | 146 | end
|
| | 147 | Bsmall = VV'*applyB(VV);
|
| | 148 | Bsmall = (Bsmall + Bsmall')/2;
|
| | 149 |
|
| | 150 | [V, D] = fullEig(Asmall, Bsmall, size(VV, 2), k, false, [], 1, eigsSigma);
|
| | 151 | V = VV*V;
|
| | 152 | d = diag(D);
|
| | 153 | end
|
| | 154 |
|
| | 155 | % Give correct output based on Failure Treatment option (replacenan is default)
|
< 0.001 | 1 | 156 | if strcmpi(innerOpts.fail,'keep')
|
| | 157 | flag = isNotConverged;
|
< 0.001 | 1 | 158 | elseif strcmpi(innerOpts.fail,'drop')
|
| | 159 | d = d(~isNotConverged);
|
| | 160 | if nargout > 1
|
| | 161 | V = V(:,~isNotConverged);
|
| | 162 | end
|
| | 163 | flag = double(any(isNotConverged));
|
< 0.001 | 1 | 164 | else
|
< 0.001 | 1 | 165 | d(isNotConverged) = NaN;
|
< 0.001 | 1 | 166 | flag = double(any(isNotConverged));
|
< 0.001 | 1 | 167 | end
|
| | 168 |
|
| | 169 | % If flag is not returned, give warning about convergence failure
|
< 0.001 | 1 | 170 | if nargout < 3 && any(isNotConverged)
|
| | 171 | if strcmpi(innerOpts.fail,'keep')
|
| | 172 | warning(message('MATLAB:eigs:NotAllEigsConvKeep', sum(~isNotConverged), k));
|
| | 173 | elseif strcmpi(innerOpts.fail,'drop')
|
| | 174 | warning(message('MATLAB:eigs:NotAllEigsConvDrop', sum(~isNotConverged), k));
|
| | 175 | else
|
| | 176 | warning(message('MATLAB:eigs:NotAllEigsConverged', sum(~isNotConverged), k));
|
| | 177 | end
|
| | 178 | end
|
| | 179 |
|
| | 180 | % Assign outputs
|
< 0.001 | 1 | 181 | if nargout <= 1
|
| | 182 | V = d;
|
< 0.001 | 1 | 183 | else
|
< 0.001 | 1 | 184 | D = diag(d);
|
< 0.001 | 1 | 185 | end
|
| | 186 |
|
0.003 | 1 | 187 | end
|
Other subfunctions in this file are not included in this listing.