Commit aad0bc23 authored by Tim Mitchell's avatar Tim Mitchell
Browse files

Initial commit for v2.0; v1.0 will no longer be available.

parents
This diff is collapsed.
eigsPlus and its subroutines are licensed under the AGPL v3.
The only exception is:
1) isOctave.m
which contains publicly available code taken directly from
the Octave website.
\ No newline at end of file
eigsPlus provides an enhanced, alternative version to Matlab's eigs
routine, supported on Matlab R2012b and later and Octave.
eigsPlus is AGPL licensed. See the LICENSE_INFO folder for more
information.
For documentation, in Matlab type:
> help eigsPlus
> help makeEigsPlus
> help cleanEigsPlus
and/or see:
http://www.timmitchell.com/software/eigsPlus/
\ No newline at end of file
function cleanEigsPlus(varargin)
% cleanEigsPlus:
% Removes the version-specific eigsPlus files that are created
% anytime makeEigsPlus is run.
%
% USAGE:
% % Removes all versions of the files created by each call to
% % makeEigsPlus(), called on whichver versions of Matlab.
% > cleanEigsPlus()
%
% % Remove a specific version of the files created by makeEigsPlus()
% % The single input must be a string with the following form:
% %
% % XXXX[ab] where X is a digit 0-9, e.g. 2015a
% %
% % and the string/release is at least 2006a
% > cleanEigsPlus('2015a')
%
% NOTE:
% This command is only applicable on Matlab, not Octave, as the
% eigs patching features are Matlab-only features.
%
% See also eigsPlus, makeEigsPlus.
%
%
% For comments/bug reports, please visit the eigsPlus GitLab webpage:
% https://gitlab.com/timmitchell/eigsPlus
%
% eigsPlus Version 2.0, 2016, see AGPL license info below.
% cleanEigsPlus.m introduced in eigsPlus Version 2.0.
%
%##########################################################################
%# eigsPlus #
%# Copyright (C) 2016 Tim Mitchell #
%# #
%# This file is part of eigsPlus. #
%# #
%# eigsPlus is free software: you can redistribute it and/or modify #
%# it under the terms of the GNU Affero General Public License as #
%# published by the Free Software Foundation, either version 3 of #
%# the License, or (at your option) any later version. #
%# #
%# eigsPlus is distributed in the hope that it will be useful, #
%# but WITHOUT ANY WARRANTY; without even the implied warranty of #
%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
%# GNU Affero General Public License for more details. #
%# #
%# You should have received a copy of the GNU Affero General Public #
%# License along with this program. If not, see #
%# <http://www.gnu.org/licenses/>. #
%##########################################################################
if isOctave()
error( 'cleanEigsPlus:octave', ...
[ 'Nothing to clean.\n' ...
'eigsPlus patching features are only supported on ' ...
'Matlab, not Octave. eigsPlus may still be used ' ...
'on Octave, but not all features will be enabled.' ]);
end
if nargin < 1
cleanEigsPlusAll();
else
version_str = varargin{1};
assertMatlabReleaseStr(version_str);
version_str = lower(version_str);
% make sure user's version is at least 2012b, the oldest version
% supported by eigsPlus
if strCompareTo('2012b',version_str) > 0
error( 'cleanEigsPlus:unsupportedMatlab', ...
'eigsPlus requires Matlab R2012b or newer.' );
end
cleanEigsPlusVersion(version_str);
end
end
\ No newline at end of file
--- /Users/tim/research/libs/matlab/eigsplus2/sources/matlab/R2012b/eigs.m 2011-07-21 16:40:32.000000000 +0200
+++ /Users/tim/research/libs/matlab/eigsplus2/sources/modified/eigsPlus_R2012b.m 2016-11-22 13:23:29.000000000 +0100
@@ -1,4 +1,26 @@
-function varargout = eigs(varargin)
+function varargout = eigsPlus_R2012b(varargin)
+%
+% eigsPlus autogenerated code
+%
+% eigsPlus modified version of eigs.m (R2012b) makes the following changes:
+%
+% 1) NaNs are used instead of zeros as padding in case not all eigenvalues
+% converge, so it is obvious to the user what has occured. This is a
+% straightforward change, mostly (but not solely) consisting of changing
+% the initialization of the relevant arrays from =zeros() to =NaN().
+%
+% 2) a warning is thrown instead of an error when none of the eigenvalues
+% converge and an array of NaN eigenvalues is returned.
+%
+% 3) The optional third output argument now returns the number of ARPACK
+% iterations. 0 is returned if a full eig call is done. Flag is no
+% longer returned as the user may check for the presence of NaNs is the
+% eigenvalue output to determine if not all k requested eigenvalues
+% converged to tolerance.
+%
+% 4) opts.isreal may be set to false to force the complex solver if A is
+% real and opts.v0 is real or if A is real and opts.v0 is complex.
+%
%EIGS Find a few eigenvalues and eigenvectors of a matrix
% D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues.
% A must be square and should be large and sparse.
@@ -166,8 +188,11 @@
aupdfun = 'dsaupd';
eupdfun = 'dseupd';
end
- lworkl = intconvert(p*(p+8));
- d = zeros(k,1,classAB);
+ lworkl = intconvert(p*(p+8));
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ d = NaN(k,1,classAB);
+ % EIGSPLUS modification block END
else % real but not symmetric
if strcmp(classAB,'single')
aupdfun = 'snaupd';
@@ -176,10 +201,13 @@
aupdfun = 'dnaupd';
eupdfun = 'dneupd';
end
- lworkl = intconvert(3*p*(p+2));
+ lworkl = intconvert(3*p*(p+2));
workev = zeros(3*p,1,classAB);
- d = zeros(k+1,1,classAB);
- di = zeros(k+1,1,classAB);
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ d = NaN(k+1,1,classAB);
+ di = NaN(k+1,1,classAB);
+ % EIGSPLUS modification block END
end
v = zeros(n,p,classAB);
workd = zeros(n,3,classAB);
@@ -198,7 +226,10 @@
lworkl = intconvert(2*(3*p^2+5*p));
workl = zeros(lworkl,1,classAB);
workev = zeros(2*2*p,1,classAB);
- zd = zeros(2*(k+1),1,classAB);
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ zd = NaN(2*(k+1),1,classAB);
+ % EIGSPLUS modification block END
rwork = zeros(p,1,classAB);
end
ldv = intconvert(n);
@@ -330,7 +361,11 @@
if rvec
d(k+1) = [];
else
- zind = find(d == 0);
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ %zind = find(d == 0);
+ zind = find(isnan(d));
+ % EIGSPLUS modification block END
if isempty(zind)
d = d(k+1:-1:2);
else
@@ -366,9 +401,13 @@
else
varargout{1} = v(:,1:k);
varargout{2} = diag(d(1:k,1));
- if (nargout >= 3)
- varargout{3} = flag;
- end
+ % EIGSPLUS modification block START
+ % third output argument will be the number of ARPACK iters so this
+ % is no longer needed
+% if (nargout >= 3)
+% varargout{3} = flag;
+% end
+ % EIGSPLUS modification block END
end
else
if (nargout <= 1)
@@ -381,9 +420,13 @@
complex(v(:,cplxd),-v(:,cplxd+1))];
varargout{1} = v(:,1:k);
varargout{2} = diag(d);
- if (nargout >= 3)
- varargout{3} = flag;
- end
+ % EIGSPLUS modification block START
+ % third output argument will be the number of ARPACK iters so this
+ % is no longer needed
+% if (nargout >= 3)
+% varargout{3} = flag;
+% end
+ % EIGSPLUS modification block END
end
end
@@ -407,6 +450,13 @@
end
end
+% EIGSPLUS modification block START
+% third output argument will be the number of ARPACK iters
+if nargout >= 3
+ varargout{3} = double(ipntr(15));
+end
+% EIGSPLUS modification block END
+
cputms(4) = cputime-t0; % end timing post-processing
cputms(5) = sum(cputms(1:4)); % total time
@@ -652,7 +702,11 @@
error(message('MATLAB:eigs:InvalidOptsIssym'));
end
end
- if isfield(opts,'isreal') && ~Amatrix
+ % EIGSPLUS modification block START
+ % allow forcing complex solver, with (real A and real v0) or
+ % (real A and complex v0)
+ if isfield(opts,'isreal') % && ~Amatrix
+ % EIGSPLUS modification block END
if (opts.isreal ~= false) && (opts.isreal ~= true)
error(message('MATLAB:eigs:InvalidOptsIsreal'));
end
@@ -1170,7 +1224,11 @@
varargout{1} = V(:,ind(range));
varargout{2} = D(ind(range),ind(range));
if (nOutputs == 3)
- % flag indicates "convergence"
+ % EIGSPLUS modification block START
+ % update to comments only
+ % third output argument is the number of ARPACK iters
+ % if full eig is called, this will be 0
+ % EIGSPLUS modification block END
varargout{3} = 0;
end
end
@@ -1326,7 +1384,11 @@
case 1
error(message('MATLAB:eigs:ARPACKroutineError01', eupdfun));
case -14
- error(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block START
+ % instead of an error when no Ritz values converge,
+ % allow a normal return, but with a warning
+ warning(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block END
otherwise
error(message('MATLAB:eigs:ARPACKroutineError', eupdfun, full(info)));
end
--- /Users/tim/research/libs/matlab/eigsplus2/sources/matlab/R2013a/eigs.m 2016-11-01 12:16:33.000000000 +0100
+++ /Users/tim/research/libs/matlab/eigsplus2/sources/modified/eigsPlus_R2013a.m 2016-11-22 13:23:41.000000000 +0100
@@ -1,4 +1,32 @@
-function varargout = eigs(varargin)
+function varargout = eigsPlus_R2013a(varargin)
+%
+% eigsPlus autogenerated code
+%
+% eigsPlus modified version of eigs.m (R2013a) makes the following changes:
+%
+% 1) NaNs are used instead of zeros as padding in case not all eigenvalues
+% converge so it is obvious to the user what has occured. The binary
+% interface arpackc changed in R2013a so that the eigenvalues are now a
+% returned output argument instead of a passed by reference input
+% argument that was modified. Thus, the initialization change from
+% zeros to NaNs is no longer viable. arpackc seems to always populate
+% converged eigenvalues in order from 1 to k so unconverged eigenvalues
+% should be represented by zeros at the end of the list. We can use the
+% number of converged eigenvalues reported by arpackc to convert the
+% the placeholder zeros to NaNs. See convertToNaNs() for more details.
+%
+% 2) a warning is thrown instead of an error when none of the eigenvalues
+% converge and an array of NaN eigenvalues is returned.
+%
+% 3) The optional third output argument now returns the number of ARPACK
+% iterations. 0 is returned if a full eig call is done. Flag is no
+% longer returned as the user may check for the presence of NaNs is the
+% eigenvalue output to determine if not all k requested eigenvalues
+% converged to tolerance.
+%
+% 4) opts.isreal may be set to false to force the complex solver if A is
+% real and opts.v0 is real or if A is real and opts.v0 is complex.
+%
%EIGS Find a few eigenvalues and eigenvectors of a matrix
% D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues.
% A must be square and should be large and sparse.
@@ -292,6 +320,10 @@
[d, info] = arpackc( eupdfun, rvec, 'A', select, v, ldv, sigma, ...
bmat, intconvert(n), whch, nev, tol, resid, ncv, v, ldv, ...
iparam, ipntr, workd, workl, lworkl, info );
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ d = convertToNaNs(d);
+ % EIGSPLUS modification block END
if strcmp(whch,'LM') || strcmp(whch,'LA')
d = flipud(d);
if (rvec == 1)
@@ -307,10 +339,18 @@
[d, info] = arpackc( eupdfun, rvec, 'A', select, v, ldv, ...
sigma, 0, workev, bmat, intconvert(n), whch, nev, tol, resid, ...
ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, info );
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ d = convertToNaNs(d);
+ % EIGSPLUS modification block END
if rvec
d(k+1) = [];
else
- zind = find(d == 0);
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+% zind = find(d == 0);
+ zind = find(isnan(d));
+ % EIGSPLUS modification block END
if isempty(zind)
d = d(k+1:-1:2);
else
@@ -324,6 +364,10 @@
[zd, info] = arpackc( eupdfun, rvec, 'A', select, zv, ldv, zsigma, ...
workev, bmat, intconvert(n), whch, nev, tol, resid, ncv, zv, ...
ldv, iparam, ipntr, zworkd, workl, lworkl, rwork, info );
+ % EIGSPLUS modification block START
+ % change zeros to NaNs so unconverged values are obvious
+ zd = convertToNaNs(zd);
+ % EIGSPLUS modification block END
if issymA
d = zd(1:2:end-1);
else
@@ -344,9 +388,13 @@
else
varargout{1} = v(:,1:k);
varargout{2} = diag(d(1:k,1));
- if (nargout >= 3)
- varargout{3} = flag;
- end
+ % EIGSPLUS modification block START
+ % third output argument will be the number of ARPACK iters so this
+ % is no longer needed
+% if (nargout >= 3)
+% varargout{3} = flag;
+% end
+ % EIGSPLUS modification block END
end
else
if (nargout <= 1)
@@ -359,9 +407,13 @@
complex(v(:,cplxd),-v(:,cplxd+1))];
varargout{1} = v(:,1:k);
varargout{2} = diag(d);
- if (nargout >= 3)
- varargout{3} = flag;
- end
+ % EIGSPLUS modification block START
+ % third output argument will be the number of ARPACK iters so this
+ % is no longer needed
+% if (nargout >= 3)
+% varargout{3} = flag;
+% end
+ % EIGSPLUS modification block END
end
end
@@ -385,6 +437,13 @@
end
end
+% EIGSPLUS modification block START
+% third output argument will be the number of ARPACK iters
+if nargout >= 3
+ varargout{3} = double(ipntr(15));
+end
+% EIGSPLUS modification block END
+
cputms(4) = cputime-t0; % end timing post-processing
cputms(5) = sum(cputms(1:4)); % total time
@@ -632,7 +691,11 @@
error(message('MATLAB:eigs:InvalidOptsIssym'));
end
end
- if isfield(opts,'isreal') && ~Amatrix
+ % EIGSPLUS modification block START
+ % allow forcing complex solver, with (real A and real v0) or
+ % (real A and complex v0)
+ if isfield(opts,'isreal') % && ~Amatrix
+ % EIGSPLUS modification block END
if (opts.isreal ~= false) && (opts.isreal ~= true)
error(message('MATLAB:eigs:InvalidOptsIsreal'));
end
@@ -1132,7 +1195,11 @@
varargout{1} = V(:,ind(range));
varargout{2} = D(ind(range),ind(range));
if (nOutputs == 3)
- % flag indicates "convergence"
+ % EIGSPLUS modification block START
+ % update to comments only
+ % third output argument is the number of ARPACK iters
+ % if full eig is called, this will be 0
+ % EIGSPLUS modification block END
varargout{3} = 0;
end
end
@@ -1288,7 +1355,11 @@
case 1
error(message('MATLAB:eigs:ARPACKroutineError01', eupdfun));
case -14
- error(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block START
+ % instead of an error when no Ritz values converge,
+ % allow a normal return, but with a warning
+ warning(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block END
otherwise
error(message('MATLAB:eigs:ARPACKroutineError', eupdfun, full(info)));
end
@@ -1340,6 +1411,27 @@
disp(ds)
end % printTimings
+ % EIGSPLUS modification block START
+ % helper function to support changing zeros to NaNs so unconverged
+ % values are obvious
+ function out_with_nans = convertToNaNs(in_with_zeros)
+ % use arpackc reported number of converged eigenvalues so we know
+ % which ones to copy out in a NaN array
+ nconv = double(iparam(5));
+ if ~isrealprob
+ % count real and imaginary parts separately since they are
+ % stored in one vector
+ nconv = 2*nconv;
+ end
+ % make array of same length with NaNs instead
+ out_with_nans = NaN(length(in_with_zeros),1);
+ % copy out the converged values only into the NaN array. The
+ % converged values seem to always be populated from the beginning
+ % of the arpackc output.
+ out_with_nans(1:nconv) = in_with_zeros(1:nconv);
+ end
+ % EIGSPLUS modification block END
+
%-------------------------------------------------------------------------%
% End of nested functions
%-------------------------------------------------------------------------%
--- /Users/tim/research/libs/matlab/eigsplus2/sources/matlab/R2013b/eigs.m 2016-11-01 12:16:47.000000000 +0100
+++ /Users/tim/research/libs/matlab/eigsplus2/sources/modified/eigsPlus_R2013b.m 2016-11-22 13:23:46.000000000 +0100
@@ -1,4 +1,21 @@
-function varargout = eigs(varargin)
+function varargout = eigsPlus_R2013b(varargin)
+%
+% eigsPlus autogenerated code
+%
+% eigsPlus modified version of eigs.m (R2013b) makes the following changes:
+%
+% 1) a warning is thrown instead of an error when none of the eigenvalues
+% converge and an array of NaN eigenvalues is returned.
+%
+% 2) The optional third output argument now returns the number of ARPACK
+% iterations. 0 is returned if a full eig call is done. Flag is no
+% longer returned as the user may check for the presence of NaNs is the
+% eigenvalue output to determine if not all k requested eigenvalues
+% converged to tolerance.
+%
+% 3) opts.isreal may be set to false to force the complex solver if A is
+% real and opts.v0 is real or if A is real and opts.v0 is complex.
+%
%EIGS Find a few eigenvalues and eigenvectors of a matrix
% D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues.
% A must be square and should be large and sparse.
@@ -369,9 +386,15 @@
varargout{1} = v;
varargout{2} = diag(d);
end
+% EIGSPLUS modification block START
+% replace third argument flag to instead be the number of ARPACK iters
+% if nargout >= 3
+% varargout{3} = flag;
+% end
if nargout >= 3
- varargout{3} = flag;
+ varargout{3} = double(ipntr(15));
end
+% EIGSPLUS modification block END
cputms(4) = cputime-t0; % end timing post-processing
@@ -620,7 +643,11 @@
error(message('MATLAB:eigs:InvalidOptsIssym'));
end
end
- if isfield(opts,'isreal') && ~Amatrix
+ % EIGSPLUS modification block START
+ % allow forcing complex solver, with (real A and real v0) or
+ % (real A and complex v0)
+ if isfield(opts,'isreal') % && ~Amatrix
+ % EIGSPLUS modification block END
if (opts.isreal ~= false) && (opts.isreal ~= true)
error(message('MATLAB:eigs:InvalidOptsIsreal'));
end
@@ -1120,7 +1147,11 @@
varargout{1} = V(:,ind(range));
varargout{2} = D(ind(range),ind(range));
if (nOutputs == 3)
- % flag indicates "convergence"
+ % EIGSPLUS modification block START
+ % update to comments only
+ % third output argument is the number of ARPACK iters
+ % if full eig is called, this will be 0
+ % EIGSPLUS modification block END
varargout{3} = 0;
end
end
@@ -1276,7 +1307,11 @@
case 1
error(message('MATLAB:eigs:ARPACKroutineError01', eupdfun));
case -14
- error(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block START
+ % instead of an error when no Ritz values converge,
+ % allow a normal return, but with a warning
+ warning(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block END
otherwise
error(message('MATLAB:eigs:ARPACKroutineError', eupdfun, full(info)));
end
--- /Users/tim/research/libs/matlab/eigsplus2/sources/matlab/R2014a/eigs.m 2016-11-01 12:17:20.000000000 +0100
+++ /Users/tim/research/libs/matlab/eigsplus2/sources/modified/eigsPlus_R2014a_R2014b.m 2016-11-22 13:23:50.000000000 +0100
@@ -1,4 +1,22 @@
-function varargout = eigs(varargin)
+function varargout = eigsPlus_R2014a_R2014b(varargin)
+%
+% eigsPlus autogenerated code
+%
+% eigsPlus modified version of eigs.m (R2014a through R2014b) makes the
+% following changes:
+%
+% 1) a warning is thrown instead of an error when none of the eigenvalues
+% converge and an array of NaN eigenvalues is returned.
+%
+% 2) The optional third output argument now returns the number of ARPACK
+% iterations. 0 is returned if a full eig call is done. Flag is no
+% longer returned as the user may check for the presence of NaNs is the
+% eigenvalue output to determine if not all k requested eigenvalues
+% converged to tolerance.
+%
+% 3) opts.isreal may be set to false to force the complex solver if A is
+% real and opts.v0 is real or if A is real and opts.v0 is complex.
+%
%EIGS Find a few eigenvalues and eigenvectors of a matrix
% D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues.
% A must be square and should be large and sparse.
@@ -369,9 +387,15 @@
varargout{1} = v;
varargout{2} = diag(d);
end
+% EIGSPLUS modification block START
+% replace third argument flag to instead be the number of ARPACK iters
+% if nargout >= 3
+% varargout{3} = flag;
+% end
if nargout >= 3
- varargout{3} = flag;
+ varargout{3} = double(ipntr(15));
end
+% EIGSPLUS modification block END
cputms(4) = cputime-t0; % end timing post-processing
@@ -620,7 +644,11 @@
error(message('MATLAB:eigs:InvalidOptsIssym'));
end
end
- if isfield(opts,'isreal') && ~Amatrix
+ % EIGSPLUS modification block START
+ % allow forcing complex solver, with (real A and real v0) or
+ % (real A and complex v0)
+ if isfield(opts,'isreal') % && ~Amatrix
+ % EIGSPLUS modification block END
if (opts.isreal ~= false) && (opts.isreal ~= true)
error(message('MATLAB:eigs:InvalidOptsIsreal'));
end
@@ -1120,7 +1148,11 @@
varargout{1} = V(:,ind(range));
varargout{2} = D(ind(range),ind(range));
if (nOutputs == 3)
- % flag indicates "convergence"
+ % EIGSPLUS modification block START
+ % update to comments only
+ % third output argument is the number of ARPACK iters
+ % if full eig is called, this will be 0
+ % EIGSPLUS modification block END
varargout{3} = 0;
end
end
@@ -1276,7 +1308,11 @@
case 1
error(message('MATLAB:eigs:ARPACKroutineError01', eupdfun));
case -14
- error(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun));
+ % EIGSPLUS modification block START
+ % instead of an error when no Ritz values converge,
+ % allow a normal return, but with a warning